Ticket #23: barter_2011_09_20_v2.diff
File barter_2011_09_20_v2.diff, 21.0 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("GlobalBarter"); 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
14 14 const UNIT_PANEL_HEIGHT = 44; // QUEUE: The height needed for a row of buttons 15 15 16 16 // 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};17 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Barter": 0, "Training": 0, "Construction": 0, "Command": 0, "Stance": 0}; 18 18 19 19 // Unit panels are panels with row(s) of buttons 20 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", " Training", "Construction", "Research", "Stance", "Command"];20 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Barter", "Training", "Construction", "Research", "Stance", "Command"]; 21 21 22 // Indexes of resources to sell and buy on barter panel 23 var g_barterSell = 0; 24 var g_barterBuy = 1; 25 22 26 // Lay out a row of centered buttons (does not work inside a loop like the other function) 23 27 function layoutButtonRowCentered(rowNumber, guiName, startIndex, endIndex, width) 24 28 { … … 108 112 } 109 113 } 110 114 115 function selectBarterResourceToSell(resourceIndex) 116 { 117 g_barterSell = resourceIndex; 118 // barter to should be set to different value in case if it is the same 119 // we change cyclic it to next value 120 if (g_barterBuy == g_barterSell) 121 g_barterBuy = (g_barterBuy + 5) % 4; 122 } 123 111 124 // Sets up "unit panels" - the panels with rows of icons (Helper function for updateUnitDisplay) 112 125 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback) 113 126 { … … 323 336 else if (guiName == "Formation" || guiName == "Garrison" || guiName == "Command") 324 337 rowLength = 4; 325 338 326 var numRows = Math.ceil(numButtons / rowLength); 327 var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom; 328 var buttonSpacer = buttonSideLength+1; 339 if (guiName == "Barter") 340 { 341 // amount of player's resource to exchange 342 var amountToSell = Engine.HotkeyIsPressed("session.massbarter") ? 500 : 100; 343 // for each resource 344 for (var i = 0; i < 4; i++) 345 { 346 var resources = ["food", "wood", "stone", "metal"]; 347 var resource = resources[i%4]; 348 // one pass for 'sell' row and another for 'buy' 349 for (var j = 0; j < 2; j++) 350 { 351 var selectedResourceIndex = [g_barterSell, g_barterBuy][j%2]; 352 var action = ["Sell", "Buy"][j%2]; 329 353 330 // Layout buttons 331 if (guiName == "Command") 332 { 333 layoutButtonRowCentered(0, guiName, 0, numButtons, COMMANDS_PANEL_WIDTH); 354 var button = getGUIObjectByName("unitBarter" + action + "Button["+i+"]"); 355 356 button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46"; 357 if (j == 0) 358 button.onpress = (function(e){ return function() { selectBarterResourceToSell(e); } })(i); 359 else 360 button.onpress = (function(e){ return function() { g_barterBuy = e; } })(i); 361 362 var imageNameSuffix = (i == selectedResourceIndex) ? "selected" : "inactive"; 363 var icon = getGUIObjectByName("unitBarter" + action + "Icon["+i+"]"); 364 365 getGUIObjectByName("unitBarterSellAmount["+i+"]").caption = (i == g_barterSell) ? "-" + amountToSell : ""; 366 var amountToBuy; 367 // in 'buy' row show black icon in place corresponding to selected resource in 'sell' row 368 if (j == 1 && i == g_barterSell) 369 { 370 button.enabled = false; 371 button.tooltip = ""; 372 icon.sprite = ""; 373 amountToBuy = ""; 374 } 375 else 376 { 377 button.enabled = true; 378 button.tooltip = action + " " + resource; 379 icon.sprite = "stretched:session/resources/" + resource + "_" + imageNameSuffix + ".png"; 380 amountToBuy = "+" + Math.round(unitEntState.barterPrices["sell"][resources[g_barterSell]] / unitEntState.barterPrices["buy"][resource] * amountToSell); 381 } 382 getGUIObjectByName("unitBarterBuyAmount["+i+"]").caption = amountToBuy; 383 } 384 385 performDealButton = getGUIObjectByName("PerformDealButton"); 386 performDealButton.onpress = (function(e){ return function() { exchangeResources(e) } })({"sell": resources[g_barterSell], "buy": resources[g_barterBuy], "amount": amountToSell}); 387 } 334 388 } 335 389 else 336 390 { 337 for (var i = 0; i < numRows; i++)338 layoutButtonRow(i, guiName, buttonSideLength, buttonSpacer, rowLength*i, rowLength*(i+1) );339 }391 var numRows = Math.ceil(numButtons / rowLength); 392 var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom; 393 var buttonSpacer = buttonSideLength+1; 340 394 341 // Resize Queue panel if needed 342 if (guiName == "Queue") // or garrison 343 { 344 var panel = getGUIObjectByName("unitQueuePanel"); 345 var size = panel.size; 346 size.top = (UNIT_PANEL_BASE - ((numRows-1)*UNIT_PANEL_HEIGHT)); 347 panel.size = size; 395 // Layout buttons 396 if (guiName == "Command") 397 { 398 layoutButtonRowCentered(0, guiName, 0, numButtons, COMMANDS_PANEL_WIDTH); 399 } 400 else 401 { 402 for (var i = 0; i < numRows; i++) 403 layoutButtonRow(i, guiName, buttonSideLength, buttonSpacer, rowLength*i, rowLength*(i+1) ); 404 } 405 406 // Resize Queue panel if needed 407 if (guiName == "Queue") // or garrison 408 { 409 var panel = getGUIObjectByName("unitQueuePanel"); 410 var size = panel.size; 411 size.top = (UNIT_PANEL_BASE - ((numRows-1)*UNIT_PANEL_HEIGHT)); 412 panel.size = size; 413 } 348 414 } 349 350 415 // Hide any buttons we're no longer using 351 416 for (i = numButtons; i < g_unitPanelButtons[guiName]; ++i) 352 417 getGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true; … … 410 475 function (item) { performStance(entState.id, item); } ); 411 476 } 412 477 478 getGUIObjectByName("unitBarterPanel").hidden = !entState.barterMarket; 479 if (entState.barterMarket) 480 { 481 setupUnitPanel("Barter", usedPanels, entState, [], null); 482 } 483 413 484 if (entState.buildEntities && entState.buildEntities.length) 414 485 { 415 486 setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement); -
binaries/data/mods/public/simulation/helpers/Commands.js
319 319 } 320 320 break; 321 321 322 case "barter": 323 var cmpGlobalBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_GlobalBarter); 324 cmpGlobalBarter.ExchangeResources(playerEnt, cmd.sell, cmd.buy, cmd.amount); 325 break; 326 322 327 default: 323 328 error("Ignoring unrecognised command type '" + cmd.type + "'"); 324 329 } -
binaries/data/mods/public/simulation/components/GuiInterface.js
135 135 "classes": cmpIdentity.GetClassesList(), 136 136 "selectionGroupName": cmpIdentity.GetSelectionGroupName() 137 137 }; 138 139 if (cmpIdentity.GetClassesList().indexOf("BarterMarket") != -1) 140 { 141 ret.barterMarket = true; 142 var cmpGlobalBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_GlobalBarter); 143 ret.barterPrices = cmpGlobalBarter.GetPrices(); 144 } 138 145 } 139 146 140 147 var cmpPosition = Engine.QueryInterface(ent, IID_Position); -
binaries/data/mods/public/simulation/components/interfaces/GlobalBarter.js
1 Engine.RegisterInterface("GlobalBarter"); -
binaries/data/mods/public/simulation/components/Identity.js
81 81 "<value>Civic</value>" + 82 82 "<value>CivCentre</value>" + 83 83 "<value>Economic</value>" + 84 "<value>BarterMarket</value>" + 84 85 "<value>Defensive</value>" + 85 86 "<value>Village</value>" + 86 87 "<value>Town</value>" + -
binaries/data/mods/public/simulation/components/GlobalBarter.js
1 // true price of 100 units of resource (for case if some resource is more worth) 2 // with current bartering system only relarive 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 function GlobalBarter() {} 25 26 GlobalBarter.prototype.Schema = 27 "<a:component type='system'/><empty/>"; 28 29 GlobalBarter.prototype.Init = function() 30 { 31 this.priceDifferences = {}; 32 for each (var resource in ["food", "wood", "stone", "metal"]) 33 this.priceDifferences[resource] = 0; 34 this.restoreTimer = undefined; 35 }; 36 37 GlobalBarter.prototype.GetPrices = function() 38 { 39 var prices = { "buy": {}, "sell": {} }; 40 for each (var resource in ["food", "wood", "stone", "metal"]) 41 { 42 prices["buy"][resource] = TRUE_PRICES[resource] * (100 + CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 43 prices["sell"][resource] = TRUE_PRICES[resource] * (100 - CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 44 } 45 return prices; 46 }; 47 48 GlobalBarter.prototype.ExchangeResources = function(playerEntity, resourceToSell, resourceToBuy, amount) 49 { 50 var cmpPlayer = Engine.QueryInterface(playerEntity, IID_Player); 51 var amountsToSubtract = { 52 "food": 0, 53 "wood": 0, 54 "stone": 0, 55 "metal": 0 56 }; 57 58 var prices = this.GetPrices(); 59 60 amountsToSubtract[resourceToSell] = amount; 61 if (cmpPlayer.TrySubtractResources(amountsToSubtract)) 62 { 63 var amountToAdd = Math.round(prices["sell"][resourceToSell] / prices["buy"][resourceToBuy] * amount); 64 cmpPlayer.AddResource(resourceToBuy, amountToAdd); 65 var numberOfDeals = Math.round(amount / 100); 66 67 // increase price difference for both exchange resources 68 // overal price difference (constant + dynamic) can exceed +-99% 69 // so both buy/sell prices limited to [1%; 199%] interval 70 this.priceDifferences[resourceToSell] -= DIFFERENCE_PER_DEAL * numberOfDeals; 71 this.priceDifferences[resourceToSell] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToSell])); 72 this.priceDifferences[resourceToBuy] += DIFFERENCE_PER_DEAL * numberOfDeals; 73 this.priceDifferences[resourceToBuy] = Math.min(99-CONSTANT_DIFFERENCE, Math.max(CONSTANT_DIFFERENCE-99, this.priceDifferences[resourceToBuy])); 74 } 75 76 if (this.restoreTimer == undefined) 77 { 78 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 79 this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_GlobalBarter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, {}); 80 } 81 }; 82 83 GlobalBarter.prototype.ProgressTimeout = function(data) 84 { 85 this.restoreTimer = undefined; 86 87 var needRestore = false; 88 for each (var resource in ["food", "wood", "stone", "metal"]) 89 { 90 // calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval 91 var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-DIFFERENCE_RESTORE, this.priceDifferences[resource])); 92 differenceRestore = -differenceRestore; 93 this.priceDifferences[resource] += differenceRestore; 94 // if price difference still exists then set flag to run timer again 95 if (this.priceDifferences[resource] != 0) 96 needRestore = true; 97 } 98 99 if (needRestore) 100 { 101 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 102 this.restoreTimer = cmpTimer.SetTimeout(this.entity, IID_GlobalBarter, "ProgressTimeout", RESTORE_TIMER_INTERVAL, data); 103 } 104 } 105 106 Engine.RegisterComponentType(IID_GlobalBarter, "GlobalBarter", GlobalBarter); 107 -
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/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/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/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/metal_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_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
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