Ticket #23: barter_2011_11_23.diff
File barter_2011_11_23.diff, 21.0 KB (added by , 12 years ago) |
---|
-
source/simulation2/Simulation2.cpp
120 120 componentManager.AddComponent(SYSTEM_ENTITY, cid, noParam) 121 121 122 122 LOAD_SCRIPTED_COMPONENT("AIInterface"); 123 LOAD_SCRIPTED_COMPONENT("Barter"); 123 124 LOAD_SCRIPTED_COMPONENT("EndGameManager"); 124 125 LOAD_SCRIPTED_COMPONENT("GuiInterface"); 125 126 LOAD_SCRIPTED_COMPONENT("PlayerManager"); -
binaries/data/mods/public/gui/session/session.xml
524 524 </object> 525 525 </object> 526 526 527 <object name="unitBarterPanel" hidden="true" 528 size="5 5 100% 100%" 529 > 530 <object ghost="true" style="resourceText" type="text" size="0 0 100% 18">Exchange resources:</object> 531 <object size="0 18 100% 64"> 532 <repeat count="4"> 533 <object name="unitBarterSellButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold"> 534 <object name="unitBarterSellIcon[n]" type="image" ghost="true" size="3 3 43 43"/> 535 <object name="unitBarterSellAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 536 </object> 537 </repeat> 538 </object> 539 <object size="0 64 100% 110"> 540 <repeat count="4"> 541 <object name="unitBarterBuyButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold"> 542 <object name="unitBarterBuyIcon[n]" type="image" ghost="true" size="3 3 43 43"/> 543 <object name="unitBarterBuyAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 544 </object> 545 </repeat> 546 </object> 547 <object name="PerformDealButton" type="button" style="StoneButton" size="2 112 100%-7 142"> 548 <object ghost="true" style="statsText" type="text" size="0 0 100% 100%">Barter</object> 549 </object> 550 </object> 551 527 552 <!-- Stance Selection --> 528 553 <object name="unitStancePanel" 529 554 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 { … … 368 388 g_unitPanelButtons[guiName] = numButtons; 369 389 } 370 390 391 // Sets up "unit barter panel" - special case for setupUnitPanel 392 function setupUnitBarterPanel(unitEntState) 393 { 394 // Amount of player's resource to exchange 395 var amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; 396 if (Engine.HotkeyIsPressed("session.massbarter")) 397 amountToSell *= BARTER_BUNCH_MULTIPLIER; 398 // One pass for each resource 399 for (var i = 0; i < BARTER_RESOURCES.length; i++) 400 { 401 var resource = BARTER_RESOURCES[i]; 402 // One pass for 'sell' row and another for 'buy' 403 for (var j = 0; j < 2; j++) 404 { 405 var selectedResourceIndex = [g_barterSell, g_barterBuy][j]; 406 var action = BARTER_ACTIONS[j]; 407 408 var imageNameSuffix = (i == selectedResourceIndex) ? "selected" : "inactive"; 409 var icon = getGUIObjectByName("unitBarter" + action + "Icon["+i+"]"); 410 411 var button = getGUIObjectByName("unitBarter" + action + "Button["+i+"]"); 412 button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46"; 413 var amountToBuy; 414 // In 'buy' row show black icon in place corresponding to selected resource in 'sell' row 415 if (j == 1 && i == g_barterSell) 416 { 417 button.enabled = false; 418 button.tooltip = ""; 419 icon.sprite = ""; 420 amountToBuy = ""; 421 } 422 else 423 { 424 button.enabled = true; 425 button.tooltip = action + " " + resource; 426 icon.sprite = "stretched:session/resources/" + resource + "_" + imageNameSuffix + ".png"; 427 var sellPrice = unitEntState.barterMarket.prices["sell"][BARTER_RESOURCES[g_barterSell]]; 428 var buyPrice = unitEntState.barterMarket.prices["buy"][resource]; 429 amountToBuy = "+" + Math.round(sellPrice / buyPrice * amountToSell); 430 } 431 var amount; 432 if (j == 0) 433 { 434 button.onpress = (function(i){ return function() { selectBarterResourceToSell(i); } })(i); 435 amount = (i == g_barterSell) ? "-" + amountToSell : ""; 436 } 437 else 438 { 439 button.onpress = (function(i){ return function() { g_barterBuy = i; } })(i); 440 amount = amountToBuy; 441 } 442 getGUIObjectByName("unitBarter" + action + "Amount["+i+"]").caption = amount; 443 } 444 } 445 var performDealButton = getGUIObjectByName("PerformDealButton"); 446 var exchangeResourcesParameters = { "sell": BARTER_RESOURCES[g_barterSell], "buy": BARTER_RESOURCES[g_barterBuy], "amount": amountToSell }; 447 performDealButton.onpress = (function(exchangeResourcesParameters){ return function() { exchangeResources(exchangeResourcesParameters) } })(exchangeResourcesParameters); 448 } 449 371 450 // Updates right Unit Commands Panel - runs in the main session loop via updateSelectionDetails() 372 451 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection) 373 452 { … … 424 503 function (item) { performStance(entState.id, item); } ); 425 504 } 426 505 506 getGUIObjectByName("unitBarterPanel").hidden = !entState.barterMarket; 507 if (entState.barterMarket) 508 { 509 usedPanels["Barter"] = 1; 510 setupUnitBarterPanel(entState); 511 } 512 427 513 if (entState.buildEntities && entState.buildEntities.length) 428 514 { 429 515 setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement); -
binaries/data/mods/public/simulation/helpers/Commands.js
392 392 } 393 393 break; 394 394 395 case "barter": 396 var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); 397 cmpBarter.ExchangeResources(playerEnt, cmd.sell, cmd.buy, cmd.amount); 398 break; 399 395 400 default: 396 401 error("Invalid command: unknown command type: "+uneval(cmd)); 397 402 } -
binaries/data/mods/public/simulation/components/GuiInterface.js
254 254 }; 255 255 } 256 256 257 if (!cmpFoundation && cmpIdentity.HasClass("BarterMarket")) 258 { 259 var cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); 260 ret.barterMarket = { "prices": cmpBarter.GetPrices() }; 261 } 262 257 263 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 258 264 ret.visibility = cmpRangeManager.GetLosVisibility(ent, player); 259 265 -
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.PlayerHasMarket = function(playerEntity) 52 { 53 var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player); 54 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 55 var entities = cmpRangeManager.GetEntitiesByPlayer(cmpPlayer.GetPlayerID()); 56 for each (var entity in entities) 57 { 58 var cmpFoundation = Engine.QueryInterface(entity, IID_Foundation); 59 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 60 if (!cmpFoundation && cmpIdentity.HasClass("BarterMarket")) 61 return true; 62 } 63 return false; 64 } 65 66 Barter.prototype.ExchangeResources = function(playerEntity, resourceToSell, resourceToBuy, amount) 67 { 68 // Data verification 69 if (amount <= 0) 70 { 71 warn("ExchangeResources: incorrect amount: " + uneval(amount)); 72 return; 73 } 74 if (RESOURCES.indexOf(resourceToSell) == -1) 75 { 76 warn("ExchangeResources: incorrect resource to sell: " + uneval(resourceToSell)); 77 return; 78 } 79 if (RESOURCES.indexOf(resourceToBuy) == -1) 80 { 81 warn("ExchangeResources: incorrect resource to buy: " + uneval(resourceToBuy)); 82 return; 83 } 84 if (!this.PlayerHasMarket(playerEntity)) 85 { 86 warn("ExchangeResources: player has no markets"); 87 return; 88 } 89 90 var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player); 91 var prices = this.GetPrices(); 92 var amountsToSubtract = {}; 93 amountsToSubtract[resourceToSell] = amount; 94 if (cmpPlayer.TrySubtractResources(amountsToSubtract)) 95 { 96 var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount); 97 cmpPlayer.AddResource(resourceToBuy, amountToAdd); 98 var numberOfDeals = Math.round(amount / 100); 99 100 // Increase price difference for both exchange resources. 101 // Overal price difference (constant + dynamic) can't exceed +-99% 102 // so both buy/sell prices limited to [1%; 199%] interval. 103 this.priceDifferences[resourceToSell] -= DIFFERENCE_PER_DEAL * numberOfDeals; 104 this.priceDifferences[resourceToSell] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToSell])); 105 this.priceDifferences[resourceToBuy] += DIFFERENCE_PER_DEAL * numberOfDeals; 106 this.priceDifferences[resourceToBuy] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToBuy])); 107 } 108 109 if (this.restoreTimer == undefined) 110 { 111 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 112 this.restoreTimer = cmpTimer.SetInterval(this.entity, IID_Barter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, RESTORE_TIMER_INTERVAL, {}); 113 } 114 }; 115 116 Barter.prototype.ProgressTimeout = function(data) 117 { 118 var needRestore = false; 119 for each (var resource in RESOURCES) 120 { 121 // Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval 122 var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-DIFFERENCE_RESTORE, this.priceDifferences[resource])); 123 differenceRestore = -differenceRestore; 124 this.priceDifferences[resource] += differenceRestore; 125 // If price difference still exists then set flag to run timer again 126 if (this.priceDifferences[resource] != 0) 127 needRestore = true; 128 } 129 130 if (!needRestore) 131 { 132 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 133 cmpTimer.CancelTimer(this.restoreTimer); 134 } 135 } 136 137 Engine.RegisterComponentType(IID_Barter, "Barter", Barter); 138 -
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
179 179 hotkey.session.garrison = Ctrl ; Modifier to garrison when clicking on building 180 180 hotkey.session.queue = Shift ; Modifier to queue unit orders instead of replacing 181 181 hotkey.session.batchtrain = Shift ; Modifier to train units in batches 182 hotkey.session.massbarter = Shift ; Modifier to barter bunch of resources 182 183 hotkey.session.deselectgroup = Ctrl ; Modifier to deselect units when clicking group icon, instead of selecting 183 184 hotkey.session.rotate.cw = RightBracket ; Rotate building placement preview clockwise 184 185 hotkey.session.rotate.ccw = LeftBracket ; Rotate building placement preview anticlockwise