Ticket #23: barter_2011_10_17.diff
File barter_2011_10_17.diff, 20.3 KB (added by , 13 years ago) |
---|
-
source/simulation2/Simulation2.cpp
101 101 LOGERROR(L"Can't find component type " L##name); \ 102 102 m_ComponentManager.AddComponent(SYSTEM_ENTITY, cid, noParam) 103 103 104 LOAD_SCRIPTED_COMPONENT("Barter"); 104 105 LOAD_SCRIPTED_COMPONENT("AIInterface"); 105 106 LOAD_SCRIPTED_COMPONENT("EndGameManager"); 106 107 LOAD_SCRIPTED_COMPONENT("GuiInterface"); -
binaries/data/mods/public/gui/session/session.xml
493 493 </object> 494 494 </object> 495 495 496 <object name="unitBarterPanel" hidden="true" 497 size="5 5 100% 100%" 498 > 499 <object ghost="true" style="resourceText" type="text" size="0 0 100% 18">Exchange resources:</object> 500 <object size="0 18 100% 64"> 501 <repeat count="4"> 502 <object name="unitBarterSellButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold" z="100"> 503 <object name="unitBarterSellIcon[n]" type="image" ghost="true" size="3 3 43 43"/> 504 <object name="unitBarterSellAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 505 </object> 506 </repeat> 507 </object> 508 <object size="0 64 100% 110"> 509 <repeat count="4"> 510 <object name="unitBarterBuyButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold" z="100"> 511 <object name="unitBarterBuyIcon[n]" type="image" ghost="true" size="3 3 43 43"/> 512 <object name="unitBarterBuyAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 513 </object> 514 </repeat> 515 </object> 516 <object name="PerformDealButton" type="button" style="StoneButton" size="2 112 100%-7 142" z="100"> 517 <object ghost="true" style="statsText" type="text" size="0 0 100% 100%">Perform deal</object> 518 </object> 519 </object> 520 496 521 <!-- Stance Selection --> 497 522 <object name="unitStancePanel" 498 523 style="TranslucentPanel" -
binaries/data/mods/public/gui/session/input.js
1008 1008 inputState = INPUT_BUILDING_PLACEMENT; 1009 1009 } 1010 1010 1011 // Called by GUI when user clicks exchange resources button 1012 function exchangeResources(command) 1013 { 1014 Engine.PostNetworkCommand({"type": "barter", "sell": command.sell, "buy": command.buy, "amount": command.amount }); 1015 } 1016 1017 1011 1018 // Batch training: 1012 1019 // When the user shift-clicks, we set these variables and switch to INPUT_BATCHTRAINING 1013 1020 // When the user releases shift, or clicks on a different training button, we create the batched units -
binaries/data/mods/public/gui/session/unit_commands.js
13 13 const UNIT_PANEL_BASE = -52; // QUEUE: The offset above the main panel (will often be negative) 14 14 const UNIT_PANEL_HEIGHT = 44; // QUEUE: The height needed for a row of buttons 15 15 16 // Barter constants 17 const BARTER_RESOURCE_AMOUNT_TO_SELL = 100; 18 const BARTER_BUNCH_MULTIPLIER = 5; 19 const BARTER_RESOURCES = ["food", "wood", "stone", "metal"]; 20 const BARTER_ACTIONS = ["Sell", "Buy"]; 21 16 22 // The number of currently visible buttons (used to optimise showing/hiding) 17 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, " Training": 0, "Construction": 0, "Command": 0, "Stance": 0};23 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Barter": 0, "Training": 0, "Construction": 0, "Command": 0, "Stance": 0}; 18 24 19 25 // Unit panels are panels with row(s) of buttons 20 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", " Training", "Construction", "Research", "Stance", "Command"];26 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Barter", "Training", "Construction", "Research", "Stance", "Command"]; 21 27 28 // Indexes of resources to sell and buy on barter panel 29 var g_barterSell = 0; 30 var g_barterBuy = 1; 31 22 32 // Lay out a row of centered buttons (does not work inside a loop like the other function) 23 33 function layoutButtonRowCentered(rowNumber, guiName, startIndex, endIndex, width) 24 34 { … … 108 118 } 109 119 } 110 120 121 function selectBarterResourceToSell(resourceIndex) 122 { 123 g_barterSell = resourceIndex; 124 // g_barterBuy should be set to different value in case if it is the same as g_barterSell 125 // (it is no make sense to exchange resource to the same one). 126 // We change it cyclic to next value. 127 if (g_barterBuy == g_barterSell) 128 g_barterBuy = (g_barterBuy + 1) % BARTER_RESOURCES.length; 129 } 130 111 131 // Sets up "unit panels" - the panels with rows of icons (Helper function for updateUnitDisplay) 112 132 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback) 113 133 { 114 134 usedPanels[guiName] = 1; 135 136 // Use separate logic for bartering panel 137 if (guiName == "Barter") 138 { 139 setupUnitBarterPanel(unitEntState); 140 return; 141 } 142 115 143 var numberOfItems = items.length; 116 144 var selection = g_Selection.toList(); 117 145 var garrisonGroups = new EntityGroups(); … … 354 382 g_unitPanelButtons[guiName] = numButtons; 355 383 } 356 384 385 // Sets up "unit barter panel" - special case for setupUnitPanel 386 function setupUnitBarterPanel(unitEntState) 387 { 388 // Amount of player's resource to exchange 389 var amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; 390 if (Engine.HotkeyIsPressed("session.massbarter")) 391 amountToSell *= BARTER_BUNCH_MULTIPLIER; 392 // One pass for each resource 393 for (var i = 0; i < BARTER_RESOURCES.length; i++) 394 { 395 var resource = BARTER_RESOURCES[i]; 396 // One pass for 'sell' row and another for 'buy' 397 for (var j = 0; j < BARTER_ACTIONS.length; j++) 398 { 399 var selectedResourceIndex = [g_barterSell, g_barterBuy][j]; 400 var action = BARTER_ACTIONS[j]; 401 402 var imageNameSuffix = (i == selectedResourceIndex) ? "selected" : "inactive"; 403 var icon = getGUIObjectByName("unitBarter" + action + "Icon["+i+"]"); 404 405 var button = getGUIObjectByName("unitBarter" + action + "Button["+i+"]"); 406 button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46"; 407 var amountToBuy; 408 // In 'buy' row show black icon in place corresponding to selected resource in 'sell' row 409 if (j == 1 && i == g_barterSell) 410 { 411 button.enabled = false; 412 button.tooltip = ""; 413 icon.sprite = ""; 414 amountToBuy = ""; 415 } 416 else 417 { 418 button.enabled = true; 419 button.tooltip = action + " " + resource; 420 icon.sprite = "stretched:session/resources/" + resource + "_" + imageNameSuffix + ".png"; 421 var sellPrice = unitEntState.barterMarket.prices["sell"][BARTER_RESOURCES[g_barterSell]]; 422 var buyPrice = unitEntState.barterMarket.prices["buy"][resource]; 423 amountToBuy = "+" + Math.round(sellPrice / buyPrice * amountToSell); 424 } 425 var amount; 426 if (j == 0) 427 { 428 button.onpress = (function(e){ return function() { selectBarterResourceToSell(e); } })(i); 429 amount = (i == g_barterSell) ? "-" + amountToSell : ""; 430 } 431 else 432 { 433 button.onpress = (function(e){ return function() { g_barterBuy = e; } })(i); 434 amount = amountToBuy 435 } 436 getGUIObjectByName("unitBarter" + action + "Amount["+i+"]").caption = amount; 437 } 438 } 439 performDealButton = getGUIObjectByName("PerformDealButton"); 440 var exchangeResourcesParameters = { "sell": BARTER_RESOURCES[g_barterSell], "buy": BARTER_RESOURCES[g_barterBuy], "amount": amountToSell }; 441 performDealButton.onpress = (function(e){ return function() { exchangeResources(e) } })(exchangeResourcesParameters); 442 } 443 357 444 // Updates right Unit Commands Panel - runs in the main session loop via updateSelectionDetails() 358 445 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection) 359 446 { … … 410 497 function (item) { performStance(entState.id, item); } ); 411 498 } 412 499 500 getGUIObjectByName("unitBarterPanel").hidden = !entState.barterMarket; 501 if (entState.barterMarket) 502 { 503 setupUnitPanel("Barter", usedPanels, entState, [], null); 504 } 505 413 506 if (entState.buildEntities && entState.buildEntities.length) 414 507 { 415 508 setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement); -
binaries/data/mods/public/simulation/helpers/Commands.js
323 323 } 324 324 break; 325 325 326 case "barter": 327 var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); 328 cmpBarter.ExchangeResources(playerEnt, cmd.sell, cmd.buy, cmd.amount); 329 break; 330 326 331 default: 327 332 error("Ignoring unrecognised command type '" + cmd.type + "'"); 328 333 } -
binaries/data/mods/public/simulation/components/GuiInterface.js
252 252 }; 253 253 } 254 254 255 if (!cmpFoundation && cmpIdentity.HasClass("BarterMarket")) 256 { 257 var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); 258 ret.barterMarket = { "prices": cmpBarter.GetPrices() }; 259 } 260 255 261 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 256 262 ret.visibility = cmpRangeManager.GetLosVisibility(ent, player); 257 263 -
binaries/data/mods/public/simulation/components/interfaces/Barter.js
1 Engine.RegisterInterface("Barter"); -
binaries/data/mods/public/simulation/components/Barter.js
1 // True price of 100 units of resource (for case if some resource is more worth). 2 // With current bartering system only relative values makes sense 3 // so if for example stone is two times more expensive than wood, 4 // there will 2:1 exchange rate. 5 const TRUE_PRICES = { "food": 100, "wood": 100, "stone": 100, "metal": 100 }; 6 7 // Constant part of price difference between true price and buy/sell price. 8 // In percents. 9 // Buy price equal to true price plus constant difference. 10 // Sell price equal to true price minus constant difference. 11 const CONSTANT_DIFFERENCE = 10; 12 13 // Additional difference of prices, added after each deal to specified resource price. 14 // In percents. 15 const DIFFERENCE_PER_DEAL = 5; 16 17 // Price difference which restored each restore timer tick 18 // In percents. 19 const DIFFERENCE_RESTORE = 2; 20 21 // Interval of timer which slowly restore prices after deals 22 const RESTORE_TIMER_INTERVAL = 5000; 23 24 // Array of resource names 25 const RESOURCES = ["food", "wood", "stone", "metal"]; 26 27 function Barter() {} 28 29 Barter.prototype.Schema = 30 "<a:component type='system'/><empty/>"; 31 32 Barter.prototype.Init = function() 33 { 34 this.priceDifferences = {}; 35 for each (var resource in RESOURCES) 36 this.priceDifferences[resource] = 0; 37 this.restoreTimer = undefined; 38 }; 39 40 Barter.prototype.GetPrices = function() 41 { 42 var prices = { "buy": {}, "sell": {} }; 43 for each (var resource in RESOURCES) 44 { 45 prices["buy"][resource] = TRUE_PRICES[resource] * (100 + CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 46 prices["sell"][resource] = TRUE_PRICES[resource] * (100 - CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 47 } 48 return prices; 49 }; 50 51 Barter.prototype.ExchangeResources = function(playerEntity, resourceToSell, resourceToBuy, amount) 52 { 53 var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player); 54 55 var prices = this.GetPrices(); 56 57 var amountsToSubtract = {}; 58 amountsToSubtract[resourceToSell] = amount; 59 if (cmpPlayer.TrySubtractResources(amountsToSubtract)) 60 { 61 var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount); 62 cmpPlayer.AddResource(resourceToBuy, amountToAdd); 63 var numberOfDeals = Math.round(amount / 100); 64 65 // Increase price difference for both exchange resources. 66 // Overal price difference (constant + dynamic) can't exceed +-99% 67 // so both buy/sell prices limited to [1%; 199%] interval. 68 this.priceDifferences[resourceToSell] -= DIFFERENCE_PER_DEAL * numberOfDeals; 69 this.priceDifferences[resourceToSell] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToSell])); 70 this.priceDifferences[resourceToBuy] += DIFFERENCE_PER_DEAL * numberOfDeals; 71 this.priceDifferences[resourceToBuy] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToBuy])); 72 } 73 74 if (this.restoreTimer == undefined) 75 { 76 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 77 this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_Barter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, {}); 78 } 79 }; 80 81 Barter.prototype.ProgressTimeout = function(data) 82 { 83 this.restoreTimer = undefined; 84 85 var needRestore = false; 86 for each (var resource in RESOURCES) 87 { 88 // Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval 89 var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-DIFFERENCE_RESTORE, this.priceDifferences[resource])); 90 differenceRestore = -differenceRestore; 91 this.priceDifferences[resource] += differenceRestore; 92 // If price difference still exists then set flag to run timer again 93 if (this.priceDifferences[resource] != 0) 94 needRestore = true; 95 } 96 97 if (needRestore) 98 { 99 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 100 this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_Barter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, data); 101 } 102 } 103 104 Engine.RegisterComponentType(IID_Barter, "Barter", Barter); 105 -
binaries/data/mods/public/simulation/components/Identity.js
82 82 "<value>CivCentre</value>" + 83 83 "<value>Economic</value>" + 84 84 "<value>Defensive</value>" + 85 "<value>BarterMarket</value>" + 85 86 "<value>Village</value>" + 86 87 "<value>Town</value>" + 87 88 "<value>City</value>" + -
binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml
23 23 </Health> 24 24 <Identity> 25 25 <GenericName>Market</GenericName> 26 <Tooltip>Create Trade units and Barter resources. (Currently a useless structure)</Tooltip>27 <Classes datatype="tokens">Town </Classes>26 <Tooltip>Create Trade units and Barter resources.</Tooltip> 27 <Classes datatype="tokens">Town BarterMarket</Classes> 28 28 <Icon>structures/market.png</Icon> 29 29 </Identity> 30 30 <Obstruction> -
binaries/data/config/default.cfg
Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/food_selected.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/wood_selected.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/stone_selected.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/metal_inactive.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/food_inactive.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/wood_inactive.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/stone_inactive.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/metal_selected.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream
176 176 hotkey.session.garrison = Ctrl ; Modifier to garrison when clicking on building 177 177 hotkey.session.queue = Shift ; Modifier to queue unit orders instead of replacing 178 178 hotkey.session.batchtrain = Shift ; Modifier to train units in batches 179 hotkey.session.massbarter = Shift ; Modifier to barter bunch of resources 179 180 hotkey.session.deselectgroup = Ctrl ; Modifier to deselect units when clicking group icon, instead of selecting 180 181 hotkey.session.rotate.cw = RightBracket ; Rotate building placement preview clockwise 181 182 hotkey.session.rotate.ccw = LeftBracket ; Rotate building placement preview anticlockwise