Ticket #3934: resource_agnostic.patch
File resource_agnostic.patch, 81.9 KB (added by , 8 years ago) |
---|
-
new file inaries/data/mods/public/gui/common/functions_repeat_positioning.js
diff --git a/binaries/data/mods/public/gui/common/functions_repeat_positioning.js b/binaries/data/mods/public/gui/common/functions_repeat_positioning.js new file mode 100644 index 0000000..73f1109
- + 1 /* 2 DESCRIPTION : Functions related to positioning UI elements 3 NOTES : 4 */ 5 6 /** 7 * Horizontally fit objects repeated with the `<repeat>` tag within a parent object 8 * 9 * @param basename The base name of the object, such as "object[n]" or "object[a]_sub[b]" 10 * @param splitvar The var identifying the repeat count, without the square brackets 11 * @param margin The gap, in px, between the repeated objects 12 * @param limit The number of elements to fit 13 * @return The number of elements affected 14 */ 15 function horizFitRepeatedObjects(basename, splitvar="n", margin=0, limit=0) 16 { 17 basename = basename.split("["+splitvar+"]", 2); 18 19 var objObj; 20 if (limit == 0) 21 do 22 { 23 objObj = Engine.GetGUIObjectByName(basename.join("["+ ++limit +"]")); 24 } 25 while (objObj) 26 27 for (let c = 0; c < limit; ++c) 28 { 29 objObj = Engine.GetGUIObjectByName(basename.join("["+ c +"]")); 30 let objSize = objObj.size; 31 objSize.rleft = c * (100/limit); 32 objSize.rright = (c+1) * (100/limit); 33 objSize.right = -margin; 34 objObj.size = objSize; 35 } 36 37 return limit; 38 } 39 40 /** 41 * Hide all repeated elements after a certain index 42 * 43 * @param prefix The part of the element name preceeding the index 44 * @param idx The index from which to start 45 * @param prefix The part of the element name after the index 46 */ 47 function hideRemaining(prefix, idx, suffix) 48 { 49 for (;; ++idx) 50 { 51 let obj = Engine.GetGUIObjectByName(prefix+idx+suffix); 52 if (!obj) 53 return; 54 obj.hidden = true; 55 } 56 } -
binaries/data/mods/public/gui/common/l10n.js
diff --git a/binaries/data/mods/public/gui/common/l10n.js b/binaries/data/mods/public/gui/common/l10n.js index 53c16c2..efed63d 100644
a b 1 const localisedResourceNames = {2 "firstWord": {3 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.4 "food": translateWithContext("firstWord", "Food"),5 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.6 "meat": translateWithContext("firstWord", "Meat"),7 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.8 "metal": translateWithContext("firstWord", "Metal"),9 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.10 "ore": translateWithContext("firstWord", "Ore"),11 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.12 "rock": translateWithContext("firstWord", "Rock"),13 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.14 "ruins": translateWithContext("firstWord", "Ruins"),15 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.16 "stone": translateWithContext("firstWord", "Stone"),17 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.18 "treasure": translateWithContext("firstWord", "Treasure"),19 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.20 "tree": translateWithContext("firstWord", "Tree"),21 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.22 "wood": translateWithContext("firstWord", "Wood"),23 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.24 "fruit": translateWithContext("firstWord", "Fruit"),25 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.26 "grain": translateWithContext("firstWord", "Grain"),27 // Translation: Word as used at the beginning of a sentence or as a single-word sentence.28 "fish": translateWithContext("firstWord", "Fish"),29 },30 "withinSentence": {31 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).32 "food": translateWithContext("withinSentence", "Food"),33 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).34 "meat": translateWithContext("withinSentence", "Meat"),35 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).36 "metal": translateWithContext("withinSentence", "Metal"),37 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).38 "ore": translateWithContext("withinSentence", "Ore"),39 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).40 "rock": translateWithContext("withinSentence", "Rock"),41 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).42 "ruins": translateWithContext("withinSentence", "Ruins"),43 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).44 "stone": translateWithContext("withinSentence", "Stone"),45 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).46 "treasure": translateWithContext("withinSentence", "Treasure"),47 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).48 "tree": translateWithContext("withinSentence", "Tree"),49 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).50 "wood": translateWithContext("withinSentence", "Wood"),51 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).52 "fruit": translateWithContext("withinSentence", "Fruit"),53 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).54 "grain": translateWithContext("withinSentence", "Grain"),55 // Translation: Word as used in the middle of a sentence (which may require using lowercase for your language).56 "fish": translateWithContext("withinSentence", "Fish"),57 }58 };59 1 60 2 function getLocalizedResourceName(resourceCode, context) 61 3 { 62 if (!localisedResourceNames[context]) 63 { 64 warn("Internationalization: Unexpected context for resource type localization found: ‘" + context + "’. This context is not supported."); 65 return resourceCode; 66 } 67 if (!localisedResourceNames[context][resourceCode]) 68 { 69 warn("Internationalization: Unexpected resource type found with code ‘" + resourceCode + ". This resource type must be internationalized."); 70 return resourceCode; 71 } 72 return localisedResourceNames[context][resourceCode]; 4 return translateWithContext(context, resourceCode); 73 5 } 74 6 75 7 /** … … function getLocalizedResourceAmounts(resources) 81 13 .filter(type => resources[type] > 0) 82 14 .map(type => sprintf(translate("%(amount)s %(resourceType)s"), { 83 15 "amount": resources[type], 84 "resourceType": getLocalizedResourceName(type, "withinSentence")16 "resourceType": translateWithContext("withinSentence", type) 85 17 })); 86 18 87 19 if (amounts.length > 1) -
binaries/data/mods/public/gui/common/setup_resources.xml
diff --git a/binaries/data/mods/public/gui/common/setup_resources.xml b/binaries/data/mods/public/gui/common/setup_resources.xml index ffc9c4d..afbabdd 100644
a b 2 2 3 3 <setup> 4 4 <!-- Icons --> 5 <icon name="icon Food"5 <icon name="icon_food" 6 6 sprite="stretched:session/icons/resources/food_small.png" 7 7 size="16 16" 8 8 /> 9 <icon name="icon Metal"9 <icon name="icon_metal" 10 10 sprite="stretched:session/icons/resources/metal_small.png" 11 11 size="16 16" 12 12 /> 13 <icon name="icon Population"13 <icon name="icon_population" 14 14 sprite="stretched:session/icons/resources/population_small.png" 15 15 size="16 16" 16 16 /> 17 <icon name="icon Stone"17 <icon name="icon_stone" 18 18 sprite="stretched:session/icons/resources/stone_small.png" 19 19 size="16 16" 20 20 /> 21 <icon name="icon Wood"21 <icon name="icon_wood" 22 22 sprite="stretched:session/icons/resources/wood_small.png" 23 23 size="16 16" 24 24 /> 25 <icon name="icon Time"25 <icon name="icon_time" 26 26 sprite="stretched:session/icons/resources/time_small.png" 27 27 size="16 16" 28 28 /> -
binaries/data/mods/public/gui/common/tooltips.js
diff --git a/binaries/data/mods/public/gui/common/tooltips.js b/binaries/data/mods/public/gui/common/tooltips.js index 6422947..bc9e892 100644
a b 1 const g_CostDisplayIcons = {2 "food": '[icon="iconFood"]',3 "wood": '[icon="iconWood"]',4 "stone": '[icon="iconStone"]',5 "metal": '[icon="iconMetal"]',6 "population": '[icon="iconPopulation"]',7 "time": '[icon="iconTime"]'8 };9 1 10 2 const g_TooltipTextFormats = { 11 3 "unit": ['[font="sans-10"][color="orange"]', '[/color][/font]'], … … function getBuildRateTooltip(rate) 260 252 */ 261 253 function getCostComponentDisplayIcon(costComponentName) 262 254 { 263 if (costComponentName in g_CostDisplayIcons) 264 return g_CostDisplayIcons[costComponentName]; 265 266 warn(sprintf("The specified cost component, ‘%(component)s’, is not currently supported.", { "component": costComponentName })); 267 return ""; 255 return "[icon=\"icon_"+costComponentName+"\"]"; 268 256 } 269 257 270 258 /** … … function getEntityCostComponentsTooltipString(template, trainNum, entity) 291 279 totalCosts.time = Math.ceil(template.cost.time * (entity ? Engine.GuiInterfaceCall("GetBatchTime", { "entity": entity, "batchSize": trainNum }) : 1)); 292 280 293 281 let costs = []; 294 295 for (let type in g_CostDisplayIcons) 296 if (totalCosts[type]) 297 costs.push(sprintf(translate("%(component)s %(cost)s"), { 298 "component": getCostComponentDisplayIcon(type), 299 "cost": totalCosts[type] 300 })); 282 283 for (let c in template.cost) 284 if (c === "populationBonus") 285 continue; 286 else if (totalCosts[c]) 287 if (typeof GetSimState === "undefined" || GetSimState().resources.indexOf(c) > -1 || c === "time") 288 costs.push(sprintf(translate("%(component)s %(cost)s"), { 289 "component": getCostComponentDisplayIcon(c), 290 "cost": totalCosts[c] 291 })); 301 292 302 293 return costs; 303 294 } -
binaries/data/mods/public/gui/session/diplomacy_window.xml
diff --git a/binaries/data/mods/public/gui/session/diplomacy_window.xml b/binaries/data/mods/public/gui/session/diplomacy_window.xml index 1708159..f2499d8 100644
a b 11 11 </object> 12 12 13 13 <object name="diplomacyHeader" size="32 32 100%-32 64"> 14 <object name="diplomacyHeaderName" size="0 0 1 50 100%" type="text" style="chatPanel" ghost="true">14 <object name="diplomacyHeaderName" size="0 0 140 100%" type="text" style="chatPanel" ghost="true" text_align="center"> 15 15 <translatableAttribute id="caption">Name</translatableAttribute> 16 16 </object> 17 17 <object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style="chatPanel" ghost="true"> … … 23 23 <object name="diplomacyHeaderTheirs" size="300 0 360 100%" type="text" style="chatPanel" ghost="true"> 24 24 <translatableAttribute id="caption">Theirs</translatableAttribute> 25 25 </object> 26 <object name="diplomacyHeaderAlly" size=" 100%-180 0 100%-160 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">26 <object name="diplomacyHeaderAlly" size="360 0 380 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold"> 27 27 <translatableAttribute id="caption">A</translatableAttribute> 28 28 <translatableAttribute id="tooltip">Ally</translatableAttribute> 29 29 </object> 30 <object name="diplomacyHeaderNeutral" size=" 100%-160 0 100%-140 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">30 <object name="diplomacyHeaderNeutral" size="380 0 400 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold"> 31 31 <translatableAttribute id="caption">N</translatableAttribute> 32 32 <translatableAttribute id="tooltip">Neutral</translatableAttribute> 33 33 </object> 34 <object name="diplomacyHeaderEnemy" size=" 100%-140 0 100%-120 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold">34 <object name="diplomacyHeaderEnemy" size="400 0 420 100%" type="text" style="chatPanel" tooltip_style="sessionToolTipBold"> 35 35 <translatableAttribute id="caption">E</translatableAttribute> 36 36 <translatableAttribute id="tooltip">Enemy</translatableAttribute> 37 37 </object> 38 <object name="diplomacyHeaderTribute" size=" 100%-110 0 100% 100%" type="text" style="chatPanel">38 <object name="diplomacyHeaderTribute" size="430 0 100%-30 100%" type="text" style="chatPanel" text_align="center"> 39 39 <translatableAttribute id="caption">Tribute</translatableAttribute> 40 40 </object> 41 41 </object> … … 48 48 <object name="diplomacyPlayerTheirs[n]" size="300 0 360 100%" type="text" style="chatPanel" ghost="true"/> 49 49 50 50 <!-- Diplomatic stance - selection --> 51 <object name="diplomacyPlayerAlly[n]" size=" 100%-180 0 100%-160 100%" type="button" style="StoneButton" hidden="true"/>52 <object name="diplomacyPlayerNeutral[n]" size=" 100%-160 0 100%-140 100%" type="button" style="StoneButton" hidden="true"/>53 <object name="diplomacyPlayerEnemy[n]" size=" 100%-140 0 100%-120 100%" type="button" style="StoneButton" hidden="true"/>51 <object name="diplomacyPlayerAlly[n]" size="360 0 380 100%" type="button" style="StoneButton" hidden="true"/> 52 <object name="diplomacyPlayerNeutral[n]" size="380 0 400 100%" type="button" style="StoneButton" hidden="true"/> 53 <object name="diplomacyPlayerEnemy[n]" size="400 0 420 100%" type="button" style="StoneButton" hidden="true"/> 54 54 55 <!-- Tribute --> 56 <object name="diplomacyPlayerTributeFood[n]" size="100%-110 0 100%-90 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 57 <object name="diplomacyPlayerTributeFoodImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/food.png" ghost="true"/> 58 </object> 59 <object name="diplomacyPlayerTributeWood[n]" size="100%-90 0 100%-70 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 60 <object name="diplomacyPlayerTributeWoodImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/wood.png" ghost="true"/> 61 </object> 62 <object name="diplomacyPlayerTributeStone[n]" size="100%-70 0 100%-50 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 63 <object name="diplomacyPlayerTributeStoneImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/stone.png" ghost="true"/> 64 </object> 65 <object name="diplomacyPlayerTributeMetal[n]" size="100%-50 0 100%-30 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 66 <object name="diplomacyPlayerTributeMetalImage[n]" type="image" size="0 0 100% 100%" sprite="stretched:session/icons/resources/metal.png" ghost="true"/> 55 <!-- Tribute --> 56 <object size="430 0 100%-40 100%"> 57 <repeat count="8" var="r"> 58 <object name="diplomacyPlayer[n]_tribute[r]" size="0 0 20 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> 59 <object name="diplomacyPlayer[n]_tribute[r]_image" type="image" size="0 0 100% 100%" ghost="true"/> 60 </object> 61 </repeat> 67 62 </object> 68 63 69 64 <object name="diplomacyAttackRequest[n]" size="100%-20 0 100% 100%" type="button" style="iconButton" tooltip_style="sessionToolTipBold" hidden="true"> -
binaries/data/mods/public/gui/session/menu.js
diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js index f7b1de4..579d972 100644
a b const INITIAL_MENU_POSITION = "100%-164 " + MENU_TOP + " 100% " + MENU_BOTTOM; 22 22 // Number of pixels per millisecond to move 23 23 const MENU_SPEED = 1.2; 24 24 25 // Available resources in trade and tribute menu26 const RESOURCES = ["food", "wood", "stone", "metal"];27 28 25 // Trade menu: step for probability changes 29 26 const STEP = 5; 30 27 … … function openDiplomacy() 265 262 g_IsDiplomacyOpen = true; 266 263 267 264 let isCeasefireActive = GetSimState().ceasefireActive; 265 let resCodes = GetSimState().resources; 268 266 269 267 // Get offset for one line 270 268 let onesize = Engine.GetGUIObjectByName("diplomacyPlayer[0]").size; … … function openDiplomacy() 283 281 diplomacyFormatAttackRequestButton(i, myself || playerInactive || isCeasefireActive || !hasAllies || !g_Players[i].isEnemy[g_ViewedPlayer]); 284 282 } 285 283 286 Engine.GetGUIObjectByName("diplomacyDialogPanel").hidden = false; 284 let dialog = Engine.GetGUIObjectByName("diplomacyDialogPanel"); 285 let size = dialog.size; 286 let wid = resCodes.length * 10; 287 size.left = -(260 + wid); 288 size.right = (260 + wid); 289 dialog.size = size; 290 dialog.hidden = false; 287 291 } 288 292 289 293 function diplomacySetupTexts(i, rowsize) … … function diplomacyFormatStanceButtons(i, hidden) 329 333 330 334 function diplomacyFormatTributeButtons(i, hidden) 331 335 { 332 for (let resource of RESOURCES) 336 let resCodes = GetSimState().resources; 337 for (let r in resCodes) 333 338 { 334 let button = Engine.GetGUIObjectByName("diplomacyPlayerTribute"+resource[0].toUpperCase()+resource.substring(1)+"["+(i-1)+"]"); 339 let resource = resCodes[r]; 340 let button = Engine.GetGUIObjectByName("diplomacyPlayer["+(i-1)+"]_tribute["+r+"]"); 341 Engine.GetGUIObjectByName("diplomacyPlayer["+(i-1)+"]_tribute["+r+"]_image").sprite = "stretched:session/icons/resources/"+resource+".png"; 335 342 button.hidden = hidden; 343 setPanelObjectPosition(button, r, 8, 0); 336 344 if (hidden) 337 345 continue; 338 346 … … function diplomacyFormatTributeButtons(i, hidden) 351 359 } 352 360 353 361 let amounts = {}; 354 for (let type of RESOURCES)355 amounts[ type] = 0;356 amounts[resource] = 100 * multiplier ;362 for (let res of resCodes) 363 amounts[res] = 0; 364 amounts[resource] = 100 * multiplier, 357 365 358 366 button.tooltip = formatTributeTooltip(i, resource, amounts[resource]); 359 367 … … function openTrade() 424 432 425 433 var proba = Engine.GuiInterfaceCall("GetTradingGoods", g_ViewedPlayer); 426 434 var button = {}; 427 var selec = RESOURCES[0]; 428 for (var i = 0; i < RESOURCES.length; ++i) 435 let resCodes = GetSimState().resources; 436 let selec = resCodes[0]; 437 hideRemaining("tradeResource[", resCodes.length, "]"); 438 439 for (let i = 0; i < resCodes.length; ++i) 429 440 { 430 441 var buttonResource = Engine.GetGUIObjectByName("tradeResource["+i+"]"); 431 if (i > 0) 432 { 433 var size = Engine.GetGUIObjectByName("tradeResource["+(i-1)+"]").size; 434 var width = size.right - size.left; 435 size.left += width; 436 size.right += width; 437 Engine.GetGUIObjectByName("tradeResource["+i+"]").size = size; 438 } 439 var resource = RESOURCES[i]; 442 setPanelObjectPosition(buttonResource, i, 8); 443 var resource = resCodes[i]; 440 444 proba[resource] = (proba[resource] ? proba[resource] : 0); 441 445 var buttonResource = Engine.GetGUIObjectByName("tradeResourceButton["+i+"]"); 442 446 var icon = Engine.GetGUIObjectByName("tradeResourceIcon["+i+"]"); … … function openTrade() 452 456 return function() { 453 457 if (Engine.HotkeyIsPressed("session.fulltradeswap")) 454 458 { 455 for ( var ress of RESOURCES)459 for (let ress of resCodes) 456 460 proba[ress] = 0; 457 461 proba[resource] = 100; 458 462 Engine.PostNetworkCommand({"type": "set-trading-goods", "tradingGoods": proba}); … … function openTrade() 488 492 Engine.GetGUIObjectByName("landTraders").caption = getIdleLandTradersText(traderNumber); 489 493 Engine.GetGUIObjectByName("shipTraders").caption = getIdleShipTradersText(traderNumber); 490 494 491 Engine.GetGUIObjectByName("tradeDialogPanel").hidden = false; 495 let dialog = Engine.GetGUIObjectByName("tradeDialogPanel"); 496 let size = dialog.size; 497 let wid = resCodes.length * (58/2); 498 size.left = -(134 + wid); 499 size.right = (134 + wid); 500 dialog.size = size; 501 dialog.hidden = false; 492 502 } 493 503 494 504 function getIdleLandTradersText(traderNumber) -
binaries/data/mods/public/gui/session/selection_panels.js
diff --git a/binaries/data/mods/public/gui/session/selection_panels.js b/binaries/data/mods/public/gui/session/selection_panels.js index 387a5bb..f3bfa4c 100644
a b g_SelectionPanels.Alert = { 87 87 g_SelectionPanels.Barter = { 88 88 "getMaxNumberOfItems": function() 89 89 { 90 return 4;90 return 8; 91 91 }, 92 92 "rowLength": 4, 93 93 "getItems": function(unitEntState, selection) 94 94 { 95 95 if (!unitEntState.barterMarket) 96 96 return []; 97 // ["food", "wood", "stone", "metal"] 98 return BARTER_RESOURCES; 97 return GetSimState().resources; 99 98 }, 100 99 "setupButton": function(data) 101 100 { … … g_SelectionPanels.Barter = { 115 114 if (Engine.HotkeyIsPressed("session.massbarter")) 116 115 amountToSell *= BARTER_BUNCH_MULTIPLIER; 117 116 117 if (!g_BarterSell) 118 g_BarterSell = GetSimState().resources[0]; 119 118 120 amount.Sell.caption = "-" + amountToSell; 119 121 let prices = data.unitEntState.barterMarket.prices; 120 122 amount.Buy.caption = "+" + Math.round(prices.sell[g_BarterSell] / prices.buy[data.item] * amountToSell); … … g_SelectionPanels.Barter = { 158 160 button.Sell.hidden = false; 159 161 selectionIcon.hidden = !isSelected; 160 162 161 setPanelObjectPosition(button.Sell, data.i, data.rowLength); 162 setPanelObjectPosition(button.Buy, data.i + data.rowLength, data.rowLength); 163 let sellPos = data.i + (data.i >= data.rowLength ? data.rowLength : 0); 164 let buyPos = data.i + data.rowLength * (data.i >= data.rowLength ? 2 : 1); 165 setPanelObjectPosition(button.Sell, sellPos, data.rowLength); 166 setPanelObjectPosition(button.Buy, buyPos, data.rowLength); 163 167 return true; 164 168 } 165 169 }; -
binaries/data/mods/public/gui/session/selection_panels_helpers.js
diff --git a/binaries/data/mods/public/gui/session/selection_panels_helpers.js b/binaries/data/mods/public/gui/session/selection_panels_helpers.js index 681b65a..ae95910 100644
a b 2 2 // Barter constants 3 3 const BARTER_RESOURCE_AMOUNT_TO_SELL = 100; 4 4 const BARTER_BUNCH_MULTIPLIER = 5; 5 const BARTER_RESOURCES = ["food", "wood", "stone", "metal"];6 5 const BARTER_ACTIONS = ["Sell", "Buy"]; 7 6 8 7 // Gate constants … … const GATE_ACTIONS = ["lock", "unlock"]; 10 9 11 10 // ============================================== 12 11 // BARTER HELPERS 13 // Resources to sell on barter panel 14 var g_BarterSell = "food"; 12 // Resource to sell by default on barter panel 13 // ! - cannot be set as we don't know the possible resources yet 14 var g_BarterSell = null; 15 15 16 // ============================================== 16 17 // FORMATION HELPERS 17 18 // Check if the selection can move into formation, and cache the result 18 19 function canMoveSelectionIntoFormation(formationTemplate) -
binaries/data/mods/public/gui/session/selection_panels_left/barter_panel.xml
diff --git a/binaries/data/mods/public/gui/session/selection_panels_left/barter_panel.xml b/binaries/data/mods/public/gui/session/selection_panels_left/barter_panel.xml index f32e117..c28ef92 100644
a b 1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <object name="unitBarterPanel" 3 size=" 6 36100% 100%"3 size="24 12 100% 100%" 4 4 hidden="true" 5 5 > 6 <object ghost="true" style="resourceText" type="text" size="0 0 100% 20"> 7 <translatableAttribute id="tooltip">Exchange resources:</translatableAttribute>8 </object> 9 <object size="0 32 100% 124">10 < repeat count="4">11 < !-- sell -->12 <object name="unitBarterSell Button[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold">13 <object name="unitBarterSellIcon[n]" type="image" ghost="true" size="3 3 43 43"/>14 <object name="unitBarterSellAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/>15 <object name="unitBarterSellSelection[n]" hidden="true" type="image" ghost="true" size="3 3 43 43" sprite="stretched:session/icons/corners.png"/> 16 </object>17 <!-- buy -->18 <object name="unitBarterBuy Button[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottomBold">19 <object name="unitBarterBuyIcon[n]" type="image" ghost="true" size="3 3 43 43"/>20 <object name="unitBarterBuyAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/>21 </object> 22 23 </object> 6 7 <repeat count="8"> 8 9 <!-- sell --> 10 <object name="unitBarterSellButton[n]" style="iconButton" type="button" size="0 0 36 36" tooltip_style="sessionToolTipBottomBold" hidden="true"> 11 <object name="unitBarterSellIcon[n]" type="image" ghost="true" size="3 3 33 33"/> 12 <object name="unitBarterSellAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 13 <object name="unitBarterSellSelection[n]" hidden="true" type="image" ghost="true" size="3 3 33 33" sprite="stretched:session/icons/corners.png"/> 14 </object> 15 16 <!-- buy --> 17 <object name="unitBarterBuyButton[n]" style="iconButton" type="button" size="0 0 36 36" tooltip_style="sessionToolTipBottomBold" hidden="true"> 18 <object name="unitBarterBuyIcon[n]" type="image" ghost="true" size="3 3 33 33"/> 19 <object name="unitBarterBuyAmount[n]" ghost="true" style="resourceText" type="text" size="0 0 100% 50%"/> 20 </object> 21 22 </repeat> 23 24 24 </object> -
binaries/data/mods/public/gui/session/session.js
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 93fbb16..b545847 100644
a b function updateTopPanel() 418 418 Engine.GetGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[g_ViewedPlayer].civ].Emblem; 419 419 Engine.GetGUIObjectByName("civIconOverlay").tooltip = sprintf(translate("%(civ)s - Structure Tree"), { "civ": civName }); 420 420 } 421 422 let resCodes = GetSimState().resources; 423 let r = 0; 424 for (; r < resCodes.length; ++r) 425 { 426 Engine.GetGUIObjectByName("resource["+r+"]").tooltip = getLocalizedResourceName(resCodes[r], "firstWord"); 427 Engine.GetGUIObjectByName("resource["+r+"]_icon").sprite = "stretched:session/icons/resources/" + resCodes[r] + ".png"; 428 } 429 horizFitRepeatedObjects ("resource[n]", "n", 0, r); 430 hideRemaining("resource[", r, "]"); 421 431 422 432 // Hide stuff gaia/observers don't use. 423 Engine.GetGUIObjectByName("food").hidden = !isPlayer; 424 Engine.GetGUIObjectByName("wood").hidden = !isPlayer; 425 Engine.GetGUIObjectByName("stone").hidden = !isPlayer; 426 Engine.GetGUIObjectByName("metal").hidden = !isPlayer; 433 for (let r = 0; r < resCodes.length; ++r) 434 Engine.GetGUIObjectByName("resource["+r+"]").hidden = !isPlayer; 427 435 Engine.GetGUIObjectByName("population").hidden = !isPlayer; 428 436 Engine.GetGUIObjectByName("civIcon").hidden = !isPlayer; 429 437 Engine.GetGUIObjectByName("diplomacyButton1").hidden = !isPlayer; … … function leaveGame(willRejoin) 529 537 530 538 summary.gameResult = gameResult; 531 539 summary.isReplay = g_IsReplay; 540 summary.resources = GetSimState().resources; 532 541 Engine.SwitchGuiPage("page_summary.xml", summary); 533 542 } 534 543 … … function updateDebug() 920 929 921 930 function updatePlayerDisplay() 922 931 { 923 let playerState = GetSimState().players[g_ViewedPlayer]; 932 let simState = GetSimState(); 933 let playerState = simState.players[g_ViewedPlayer]; 924 934 if (!playerState) 925 935 return; 926 936 927 Engine.GetGUIObjectByName("resourceFood").caption = Math.floor(playerState.resourceCounts.food);928 Engine.GetGUIObjectByName("resourceWood").caption = Math.floor(playerState.resourceCounts.wood);929 Engine.GetGUIObjectByName("resourceStone").caption = Math.floor(playerState.resourceCounts.stone);930 Engine.GetGUIObjectByName("resourceMetal").caption = Math.floor(playerState.resourceCounts.metal); 937 let resCodes = simState.resources; 938 for (let r = 0; r < resCodes.length; ++r) 939 Engine.GetGUIObjectByName("resource["+r+"]_count").caption = Math.floor(playerState.resourceCounts[resCodes[r]]); 940 931 941 Engine.GetGUIObjectByName("resourcePop").caption = playerState.popCount + "/" + playerState.popLimit; 932 942 Engine.GetGUIObjectByName("population").tooltip = translate("Population (current / limit)") + "\n" + 933 943 sprintf(translate("Maximum population: %(popCap)s"), { "popCap": playerState.popMax }); -
binaries/data/mods/public/gui/session/session.xml
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index 8f2db00..bf12835 100644
a b 6 6 <script file="gui/common/colorFades.js"/> 7 7 <script file="gui/common/functions_civinfo.js"/> 8 8 <script file="gui/common/functions_global_object.js"/> 9 <script file="gui/common/functions_repeat_positioning.js"/> 9 10 <script file="gui/common/functions_utility.js"/> 10 11 <script file="gui/common/l10n.js"/> 11 12 <script file="gui/common/music.js"/> -
deleted file binaries/data/mods/public/gui/session/top_panel/resource_food.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resource_food.xml b/binaries/data/mods/public/gui/session/top_panel/resource_food.xml deleted file mode 100644 index c3f49a4..0000000
+ - 1 <?xml version="1.0" encoding="utf-8"?>2 <object name="food" size="10 0 100 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">3 <translatableAttribute id="tooltip">Food</translatableAttribute>4 <object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/food.png" ghost="true"/>5 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceFood"/>6 </object> -
deleted file binaries/data/mods/public/gui/session/top_panel/resource_metal.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resource_metal.xml b/binaries/data/mods/public/gui/session/top_panel/resource_metal.xml deleted file mode 100644 index 8dc01ec..0000000
+ - 1 <?xml version="1.0" encoding="utf-8"?>2 <object name="metal" size="280 0 370 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">3 <translatableAttribute id="tooltip">Metal</translatableAttribute>4 <object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/metal.png" ghost="true"/>5 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceMetal"/>6 </object> -
binaries/data/mods/public/gui/session/top_panel/resource_population.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resource_population.xml b/binaries/data/mods/public/gui/session/top_panel/resource_population.xml index 9c9dcc2..9d66e40 100644
a b 1 1 <?xml version="1.0" encoding="utf-8"?> 2 <object name="population" size=" 370 0 460100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">2 <object name="population" size="50%-90-52 0 50%-52 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold"> 3 3 <object size="0 -4 40 34" type="image" sprite="stretched:session/icons/resources/population.png" ghost="true"/> 4 4 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourcePop"/> 5 5 </object> -
deleted file binaries/data/mods/public/gui/session/top_panel/resource_stone.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resource_stone.xml b/binaries/data/mods/public/gui/session/top_panel/resource_stone.xml deleted file mode 100644 index 37d08e3..0000000
+ - 1 <?xml version="1.0" encoding="utf-8"?>2 <object name="stone" size="190 0 280 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">3 <translatableAttribute id="tooltip">Stone</translatableAttribute>4 <object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/stone.png" ghost="true"/>5 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceStone"/>6 </object> -
deleted file binaries/data/mods/public/gui/session/top_panel/resource_wood.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resource_wood.xml b/binaries/data/mods/public/gui/session/top_panel/resource_wood.xml deleted file mode 100644 index 90558af..0000000
+ - 1 <?xml version="1.0" encoding="utf-8"?>2 <object name="wood" size="100 0 190 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold">3 <translatableAttribute id="tooltip">Wood</translatableAttribute>4 <object size="0 -4 40 36" type="image" sprite="stretched:session/icons/resources/wood.png" ghost="true"/>5 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resourceWood"/>6 </object> -
new file inaries/data/mods/public/gui/session/top_panel/resources.xml
diff --git a/binaries/data/mods/public/gui/session/top_panel/resources.xml b/binaries/data/mods/public/gui/session/top_panel/resources.xml new file mode 100644 index 0000000..bcf5784
- + 1 <?xml version="1.0" encoding="utf-8"?> 2 3 <object size="10 0 50%-90-52 100%"> 4 <repeat count="8"> 5 <object name="resource[n]" size="0 0 90 100%" type="image" style="resourceCounter" tooltip_style="sessionToolTipBold"> 6 <object size="0 -4 40 36" type="image" name="resource[n]_icon" ghost="true"/> 7 <object size="32 0 100% 100%-2" type="text" style="resourceText" name="resource[n]_count"/> 8 </object> 9 </repeat> 10 </object> -
binaries/data/mods/public/gui/session/trade_window.xml
diff --git a/binaries/data/mods/public/gui/session/trade_window.xml b/binaries/data/mods/public/gui/session/trade_window.xml index 80b226c..0862bc1 100644
a b 16 16 </object> 17 17 18 18 <object size="180 0 100% 100%"> 19 <repeat count=" 4">19 <repeat count="8"> 20 20 <object name="tradeResource[n]" size="0 0 58 32"> 21 21 <object name="tradeResourceButton[n]" size="4 0 36 100%" type="button" style="StoneButton"> 22 22 <object name="tradeResourceIcon[n]" type="image" ghost="true"/> -
binaries/data/mods/public/gui/summary/counters.js
diff --git a/binaries/data/mods/public/gui/summary/counters.js b/binaries/data/mods/public/gui/summary/counters.js index f595863..0affbd5 100644
a b function calculateUnits(playerState, position) 197 197 198 198 function calculateResources(playerState, position) 199 199 { 200 let type = g_ ResourcesTypes[position];200 let type = g_GameData.resources[position]; 201 201 202 202 return formatIncome( 203 203 playerState.statistics.resourcesGathered[type], … … function calculateTotalResources(playerState) 209 209 let totalGathered = 0; 210 210 let totalUsed = 0; 211 211 212 for (let type of g_ ResourcesTypes)212 for (let type of g_GameData.resources) 213 213 { 214 214 totalGathered += playerState.statistics.resourcesGathered[type]; 215 215 totalUsed += playerState.statistics.resourcesUsed[type] - playerState.statistics.resourcesSold[type]; … … function calculateResourcesTeam(counters) 279 279 280 280 function calculateResourceExchanged(playerState, position) 281 281 { 282 let type = g_ ResourcesTypes[position];282 let type = g_GameData.resources[position]; 283 283 284 284 return formatIncome( 285 285 playerState.statistics.resourcesBought[type], -
binaries/data/mods/public/gui/summary/layout.js
diff --git a/binaries/data/mods/public/gui/summary/layout.js b/binaries/data/mods/public/gui/summary/layout.js index e987340..a45debf 100644
a b var g_ScorePanelsData = { 73 73 "resources": { 74 74 "headings": [ 75 75 { "caption": translate("Player name"), "yStart": 26, "width": 200 }, 76 { "caption": translate("Food"), "yStart": 34, "width": 100 },77 { "caption": translate("Wood"), "yStart": 34, "width": 100 },78 { "caption": translate("Stone"), "yStart": 34, "width": 100 },79 { "caption": translate("Metal"), "yStart": 34, "width": 100 },80 76 { "caption": translate("Total"), "yStart": 34, "width": 110 }, 81 77 { "caption": translate("Tributes (Sent / Received)"), "yStart": 16, "width": 121 }, 82 78 { "caption": translate("Treasures collected"), "yStart": 16, "width": 100 }, … … var g_ScorePanelsData = { 86 82 { "caption": translate("Resource Statistics (Gathered / Used)"), "yStart": 16, "width": (100 * 4 + 110) }, // width = 510 87 83 ], 88 84 "counters": [ 89 { "width": 100, "fn": calculateResources },90 { "width": 100, "fn": calculateResources },91 { "width": 100, "fn": calculateResources },92 { "width": 100, "fn": calculateResources },93 85 { "width": 110, "fn": calculateTotalResources }, 94 86 { "width": 121, "fn": calculateTributeSent }, 95 87 { "width": 100, "fn": calculateTreasureCollected }, … … var g_ScorePanelsData = { 100 92 "market": { 101 93 "headings": [ 102 94 { "caption": translate("Player name"), "yStart": 26, "width": 200 }, 103 { "caption": translate("Food exchanged"), "yStart": 16, "width": 100 },104 { "caption": translate("Wood exchanged"), "yStart": 16, "width": 100 },105 { "caption": translate("Stone exchanged"), "yStart": 16, "width": 100 },106 { "caption": translate("Metal exchanged"), "yStart": 16, "width": 100 },107 95 { "caption": translate("Barter efficiency"), "yStart": 16, "width": 100 }, 108 96 { "caption": translate("Trade income"), "yStart": 16, "width": 100 } 109 97 ], 110 98 "titleHeadings": [], 111 99 "counters": [ 112 { "width": 100, "fn": calculateResourceExchanged },113 { "width": 100, "fn": calculateResourceExchanged },114 { "width": 100, "fn": calculateResourceExchanged },115 { "width": 100, "fn": calculateResourceExchanged },116 100 { "width": 100, "fn": calculateBarterEfficiency }, 117 101 { "width": 100, "fn": calculateTradeIncome } 118 102 ], -
binaries/data/mods/public/gui/summary/summary.js
diff --git a/binaries/data/mods/public/gui/summary/summary.js b/binaries/data/mods/public/gui/summary/summary.js index 3a3a09e..b712182 100644
a b 1 const g_MaxHeadingTitle= 8;1 const g_MaxHeadingTitle= 12; 2 2 3 3 // const for filtering long collective headings 4 4 const g_LongHeadingWidth = 250; … … const g_KilledColor = '[color="196 198 255"]'; 16 16 17 17 const g_BuildingsTypes = [ "total", "House", "Economic", "Outpost", "Military", "Fortress", "CivCentre", "Wonder" ]; 18 18 const g_UnitsTypes = [ "total", "Infantry", "Worker", "Cavalry", "Champion", "Hero", "Ship", "Trader" ]; 19 const g_ResourcesTypes = [ "food", "wood", "stone", "metal" ];20 19 21 20 // Colors used for gathered and traded resources 22 21 const g_IncomeColor = '[color="201 255 200"]'; … … function init(data) 198 197 else 199 198 g_Teams = false; 200 199 200 // Resource names and counters 201 let resHeads = []; 202 let tradeHeads = []; 203 let resPanel = g_ScorePanelsData.resources; 204 let tradePanel = g_ScorePanelsData.market; 205 for (let code of g_GameData.resources) 206 { 207 resHeads.push({ 208 "caption": translateWithContext("firstWord", code), 209 "yStart": 34, "width": 100 210 }); 211 resPanel.counters.unshift({"width": 100, "fn": calculateResources}); 212 213 tradeHeads.push({ 214 "caption": translate(code+" exchanged"), 215 "yStart": 16, "width": 100, 216 }); 217 tradePanel.counters.unshift({"width": 100, "fn": calculateResourceExchanged}); 218 } 219 resPanel.headings.splice.apply(resPanel.headings, [1, 0].concat(resHeads)); 220 resPanel.titleHeadings[0].width = (100 * g_GameData.resources.length) + 110; 221 tradePanel.headings.splice.apply(tradePanel.headings, [1, 0].concat(tradeHeads)); 222 201 223 // Erase teams data if teams are not displayed 202 224 if (!g_Teams) 203 225 { -
binaries/data/mods/public/gui/summary/summary.xml
diff --git a/binaries/data/mods/public/gui/summary/summary.xml b/binaries/data/mods/public/gui/summary/summary.xml index 4a77ea6..7bfd9cb 100644
a b 107 107 <object name="playerNameHeading" type="text" style="ModernLeftTabLabelText"> 108 108 <translatableAttribute id="caption">Player name</translatableAttribute> 109 109 </object> 110 <repeat var="x" count=" 8">110 <repeat var="x" count="12"> 111 111 <object name="titleHeading[x]" type="text" style="ModernTabLabelText"> 112 112 </object> 113 113 </repeat> 114 <repeat var="x" count=" 8">114 <repeat var="x" count="12"> 115 115 <object name="Heading[x]" type="text" style="ModernTabLabelText"> 116 116 </object> 117 117 </repeat> … … 126 126 <object name="playerColorBoxt[i][n]" type="image" size="10 4 30 24"/> 127 127 <object name="playerNamet[i][n]" type="text" size="40 2 208 100%" style="ModernLeftLabelText" /> 128 128 <object name="civIcont[i][n]" type="image" size="208 0 240 32"/> 129 <repeat var="x" count=" 8">129 <repeat var="x" count="12"> 130 130 <object name="valueDataTeam[i][n][x]" type="text" style="ModernTabLabelText"> 131 131 </object> 132 132 </repeat> … … 134 134 </repeat> 135 135 </object> 136 136 <object name="teamHeadingt[i]" type="text" style="ModernLeftTabLabelText"/> 137 <repeat var="x" count=" 8">137 <repeat var="x" count="12"> 138 138 <object name="valueDataTeam[i][x]" type="text" style="ModernTabLabelText"> 139 139 </object> 140 140 </repeat> … … 149 149 </object> 150 150 <object name="playerName[n]" type="text" size="40 2 208 100%" style="ModernLeftLabelText"/> 151 151 <object name="civIcon[n]" type="image" size="208 0 240 32"/> 152 <repeat var="x" count=" 8">152 <repeat var="x" count="12"> 153 153 <object name="valueData[n][x]" type="text" style="ModernTabLabelText"> 154 154 </object> 155 155 </repeat> -
binaries/data/mods/public/simulation/ai/common-api/resources.js
diff --git a/binaries/data/mods/public/simulation/ai/common-api/resources.js b/binaries/data/mods/public/simulation/ai/common-api/resources.js index 768106b..afc3cf0 100644
a b m.Resources = function(amounts = {}, population = 0) 9 9 this.population = population > 0 ? population : 0; 10 10 }; 11 11 12 m.Resources.prototype.types = [ "food", "wood", "stone", "metal" ];12 m.Resources.prototype.types = [ ]; // Gets populated in SharedScript.init 13 13 14 14 m.Resources.prototype.reset = function() 15 15 { -
binaries/data/mods/public/simulation/ai/common-api/shared.js
diff --git a/binaries/data/mods/public/simulation/ai/common-api/shared.js b/binaries/data/mods/public/simulation/ai/common-api/shared.js index 57e2930..1c49d26 100644
a b m.SharedScript = function(settings) 27 27 28 28 // A few notes about these maps. They're updated by checking for "create" and "destroy" events for all resources 29 29 // TODO: change the map when the resource amounts change for at least stone and metal mines. 30 this.resourceMaps = {}; // Contains maps showing the density of wood, stone and metal31 this.CCResourceMaps = {}; // Contains maps showing the density of wood, stone and metal, optimized for CC placement.30 this.resourceMaps = {}; // Contains maps showing the density of resources 31 this.CCResourceMaps = {}; // Contains maps showing the density of resources, optimized for CC placement. 32 32 // Resource maps data. 33 // By how much to divide the resource amount when filling the map (ie a tree having 200 wood is "4").34 this. decreaseFactor = {"wood": 50.0, "stone": 90.0, "metal": 90.0};33 this.decreaseFactor = {}; 34 this.influenceMapGroup = {}; 35 35 }; 36 36 37 37 //Return a simple object (using no classes etc) that will be serialized into saved games … … m.SharedScript.prototype.init = function(state, deserialization) 142 142 this.mapSize = state.mapSize; 143 143 this.gameType = state.gameType; 144 144 this.barterPrices = state.barterPrices; 145 146 m.Resources.prototype.types = state.resources; 145 147 146 148 this.passabilityMap = state.passabilityMap; 147 149 if (this.mapSize % this.passabilityMap.width !== 0) … … m.SharedScript.prototype.init = function(state, deserialization) 179 181 this.accessibility = new m.Accessibility(); 180 182 this.accessibility.init(state, this.terrainAnalyzer); 181 183 182 // defined in TerrainAnalysis.js 184 // By how much to divide the resource amount when filling the map (ie a tree having 200 wood is "4"). 185 for (let res in state.aiResourceAnalysis) 186 { 187 if (!state.aiResourceAnalysis[res]) 188 continue; 189 this.decreaseFactor[res] = state.aiResourceAnalysis[res].decreaseFactor; 190 this.influenceMapGroup[res] = state.aiResourceAnalysis[res].influenceMapGroup; 191 } 192 // defined in terrain-analysis.js 183 193 this.createResourceMaps(this); 184 194 185 195 this.gameState = {}; -
binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js
diff --git a/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js b/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js index 68d8445..566bbbc 100644
a b m.Accessibility.prototype.floodFill = function(startIndex, value, onWater) 382 382 383 383 // creates a map of resource density 384 384 m.SharedScript.prototype.createResourceMaps = function(sharedScript) 385 { 385 { 386 386 for (let resource in this.decreaseFactor) 387 387 { 388 388 // if there is no resourceMap create one with an influence for everything with that resource … … m.SharedScript.prototype.createResourceMaps = function(sharedScript) 394 394 this.CCResourceMaps[resource] = new m.Map(sharedScript, "resource"); 395 395 } 396 396 } 397 let cellSize = this.resourceMaps.wood.cellSize; 397 398 398 for (let ent of sharedScript._entities.values()) 399 399 { 400 400 if (ent && ent.position() && ent.resourceSupplyType() && ent.resourceSupplyType().generic !== "treasure") { 401 401 let resource = ent.resourceSupplyType().generic; 402 402 if (!this.resourceMaps[resource]) 403 403 continue; 404 405 let cellSize = this.resourceMaps[resource].cellSize; 404 406 let x = Math.floor(ent.position()[0] / cellSize); 405 407 let z = Math.floor(ent.position()[1] / cellSize); 406 408 let strength = Math.floor(ent.resourceSupplyMax()/this.decreaseFactor[resource]); 407 if ( resource === "wood")409 if (this.influenceMapGroup[resource] === 0) 408 410 { 409 411 this.CCResourceMaps[resource].addInfluence(x, z, 60/cellSize, strength, "constant"); 410 412 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, strength/2, "constant"); 411 413 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, strength/2); 412 414 } 413 else if ( resource === "stone" || resource === "metal")415 else if (this.influenceMapGroup[resource] === 1) 414 416 { 415 417 this.CCResourceMaps[resource].addInfluence(x, z, 120/cellSize, strength, "constant"); 416 418 this.resourceMaps[resource].addInfluence(x, z, 48/cellSize, strength/2, "constant"); … … m.SharedScript.prototype.updateResourceMaps = function(sharedScript, events) 438 440 this.CCResourceMaps[resource] = new m.Map(sharedScript, "resource"); 439 441 } 440 442 } 441 let cellSize = this.resourceMaps.wood.cellSize; 443 442 444 // Look for destroy events and subtract the entities original influence from the resourceMap 443 445 // TODO: perhaps do something when dropsites appear/disappear. 444 446 let destEvents = events.Destroy; … … m.SharedScript.prototype.updateResourceMaps = function(sharedScript, events) 454 456 let resource = ent.resourceSupplyType().generic; 455 457 if (!this.resourceMaps[resource]) 456 458 continue; 459 460 let cellSize = this.resourceMaps[resource].cellSize; 457 461 let x = Math.floor(ent.position()[0] / cellSize); 458 462 let z = Math.floor(ent.position()[1] / cellSize); 459 463 let strength = Math.floor(ent.resourceSupplyMax()/this.decreaseFactor[resource]); 460 if ( resource === "wood")464 if (this.influenceMapGroup[resource] === 0) 461 465 { 462 466 this.CCResourceMaps[resource].addInfluence(x, z, 60/cellSize, -strength, "constant"); 463 467 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, -strength/2, "constant"); 464 468 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, -strength/2); 465 469 } 466 else if ( resource === "stone" || resource === "metal")470 else if (this.influenceMapGroup[resource] === 1) 467 471 { 468 472 this.CCResourceMaps[resource].addInfluence(x, z, 120/cellSize, -strength, "constant"); 469 473 this.resourceMaps[resource].addInfluence(x, z, 48/cellSize, -strength/2, "constant"); … … m.SharedScript.prototype.updateResourceMaps = function(sharedScript, events) 481 485 let resource = ent.resourceSupplyType().generic; 482 486 if (!this.resourceMaps[resource]) 483 487 continue; 488 489 let cellSize = this.resourceMaps[resource].cellSize; 484 490 let x = Math.floor(ent.position()[0] / cellSize); 485 491 let z = Math.floor(ent.position()[1] / cellSize); 486 492 let strength = Math.floor(ent.resourceSupplyMax()/this.decreaseFactor[resource]); 487 if ( resource === "wood")493 if (this.influenceMapGroup[resource] === 0) 488 494 { 489 495 this.CCResourceMaps[resource].addInfluence(x, z, 60/cellSize, strength, "constant"); 490 496 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, strength/2, "constant"); 491 497 this.resourceMaps[resource].addInfluence(x, z, 36/cellSize, strength/2); 492 498 } 493 else if ( resource === "stone" || resource === "metal")499 else if (this.influenceMapGroup[resource] === 1) 494 500 { 495 501 this.CCResourceMaps[resource].addInfluence(x, z, 120/cellSize, strength, "constant"); 496 502 this.resourceMaps[resource].addInfluence(x, z, 48/cellSize, strength/2, "constant"); -
binaries/data/mods/public/simulation/components/Barter.js
diff --git a/binaries/data/mods/public/simulation/components/Barter.js b/binaries/data/mods/public/simulation/components/Barter.js index 24c39a4..106d1e3 100644
a b 1 // T rue price of 100 units of resource (for case if some resource is more worth).1 // The "true price" is a base price of 100 units of resource (for the case of some resources being of more worth than others). 2 2 // With current bartering system only relative values makes sense 3 3 // so if for example stone is two times more expensive than wood, 4 4 // there will 2:1 exchange rate. 5 const TRUE_PRICES = { "food": 100, "wood": 100, "stone": 100, "metal": 100 }; 6 5 // 7 6 // Constant part of price difference between true price and buy/sell price. 8 7 // In percents. 9 8 // Buy price equal to true price plus constant difference. … … const DIFFERENCE_RESTORE = 0.5; 21 20 // Interval of timer which slowly restore prices after deals 22 21 const RESTORE_TIMER_INTERVAL = 5000; 23 22 24 // Array of resource names25 const RESOURCES = ["food", "wood", "stone", "metal"];26 27 23 function Barter() {} 28 24 29 25 Barter.prototype.Schema = … … Barter.prototype.Schema = 32 28 Barter.prototype.Init = function() 33 29 { 34 30 this.priceDifferences = {}; 35 for ( var resource of RESOURCES)31 for (let resource of Resources.GetCodes()) 36 32 this.priceDifferences[resource] = 0; 37 33 this.restoreTimer = undefined; 38 34 }; … … Barter.prototype.Init = function() 40 36 Barter.prototype.GetPrices = function() 41 37 { 42 38 var prices = { "buy": {}, "sell": {} }; 43 for ( var resource of RESOURCES)39 for (let resource of Resources.GetCodes()) 44 40 { 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; 41 let truePrice = Resources.GetResource(resource).truePrice; 42 prices.buy[resource] = truePrice * (100 + CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 43 prices.sell[resource] = truePrice * (100 - CONSTANT_DIFFERENCE + this.priceDifferences[resource]) / 100; 47 44 } 48 45 return prices; 49 46 }; … … Barter.prototype.ExchangeResources = function(playerEntity, resourceToSell, reso 71 68 warn("ExchangeResources: incorrect amount: " + uneval(amount)); 72 69 return; 73 70 } 74 if (RESOURCES.indexOf(resourceToSell) == -1) 71 let availResources = Resources.GetCodes(); 72 if (availResources.indexOf(resourceToSell) == -1) 75 73 { 76 74 warn("ExchangeResources: incorrect resource to sell: " + uneval(resourceToSell)); 77 75 return; 78 76 } 79 if ( RESOURCES.indexOf(resourceToBuy) == -1)77 if (availResources.indexOf(resourceToBuy) == -1) 80 78 { 81 79 warn("ExchangeResources: incorrect resource to buy: " + uneval(resourceToBuy)); 82 80 return; … … Barter.prototype.ExchangeResources = function(playerEntity, resourceToSell, reso 123 121 Barter.prototype.ProgressTimeout = function(data) 124 122 { 125 123 var needRestore = false; 126 for ( var resource of RESOURCES)124 for (let resource of Resources.GetCodes()) 127 125 { 128 126 // Calculate value to restore, it should be limited to [-DIFFERENCE_RESTORE; DIFFERENCE_RESTORE] interval 129 127 var differenceRestore = Math.min(DIFFERENCE_RESTORE, Math.max(-DIFFERENCE_RESTORE, this.priceDifferences[resource])); -
binaries/data/mods/public/simulation/components/Cost.js
diff --git a/binaries/data/mods/public/simulation/components/Cost.js b/binaries/data/mods/public/simulation/components/Cost.js index e5660ee..ab008db 100644
a b Cost.prototype.Schema = 19 19 "<element name='PopulationBonus' a:help='Population cap increase while this entity exists'>" + 20 20 "<data type='nonNegativeInteger'/>" + 21 21 "</element>" + 22 "<element name='BuildTime' a:help='Time taken to construct/train this unit(in seconds)'>" +22 "<element name='BuildTime' a:help='Time taken to construct/train this entity (in seconds)'>" + 23 23 "<ref name='nonNegativeDecimal'/>" + 24 24 "</element>" + 25 "<element name='Resources' a:help='Resource costs to construct/train this unit'>" +25 "<element name='Resources' a:help='Resource costs to construct/train this entity'>" + 26 26 "<interleave>" + 27 "<element name='food'><data type='nonNegativeInteger'/></element>" + 28 "<element name='wood'><data type='nonNegativeInteger'/></element>" + 29 "<element name='stone'><data type='nonNegativeInteger'/></element>" + 30 "<element name='metal'><data type='nonNegativeInteger'/></element>" + 27 "<oneOrMore>" + 28 "<element a:help='A particular resource cost'>" + 29 "<anyName/>" + 30 "<data type='nonNegativeInteger'/>" + 31 "</element>" + 32 "</oneOrMore>" + 31 33 "</interleave>" + 32 34 "</element>"; 33 35 … … Cost.prototype.GetResourceCosts = function(owner) 70 72 let entityTemplate = cmpTemplateManager.GetTemplate(entityTemplateName); 71 73 72 74 let costs = {}; 75 let resCodes = Resources.GetCodes(); 76 73 77 for (let r in this.template.Resources) 74 costs[r] = ApplyValueModificationsToTemplate("Cost/Resources/"+r, +this.template.Resources[r], owner, entityTemplate); 78 { 79 let cost = +this.template.Resources[r]; 80 if (resCodes.indexOf(r.toLowerCase()) < 0) 81 { 82 if (cost > 0) 83 warn("'"+r+"' has been specified as a required resource, but is not a valid resource."); 84 continue; 85 } 86 costs[r] = ApplyValueModificationsToTemplate("Cost/Resources/"+r, cost, owner, entityTemplate); 87 } 88 75 89 return costs; 76 90 }; 77 91 -
binaries/data/mods/public/simulation/components/GuiInterface.js
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index ffb28e3..88e65da 100644
a b GuiInterface.prototype.GetSimulationState = function() 151 151 let cmpBarter = Engine.QueryInterface(SYSTEM_ENTITY, IID_Barter); 152 152 ret.barterPrices = cmpBarter.GetPrices(); 153 153 154 // Add Resource Codes 155 ret.resources = Resources.GetCodes(); 156 ret.aiResourceAnalysis = {}; 157 for (let res of ret.resources) 158 ret.aiResourceAnalysis[res] = Resources.GetResource(res).aiAnalysis || null; 159 154 160 // Add basic statistics to each player 155 161 for (let i = 0; i < numPlayers; ++i) 156 162 { … … GuiInterface.prototype.SetWallPlacementPreview = function(player, cmd) 1246 1252 1247 1253 let result = { 1248 1254 "pieces": [], 1249 "cost": { "food": 0, "wood": 0, "stone": 0, "metal": 0, "population": 0, "populationBonus": 0, "time": 0},1255 "cost": {"population": 0, "populationBonus": 0, "time": 0}, 1250 1256 }; 1251 1257 for (let res of Resources.GetCodes()) 1258 result.cost[res] = 0; 1259 1252 1260 let previewEntities = []; 1253 1261 if (end.pos) 1254 1262 previewEntities = GetWallPlacement(this.placementWallEntities, wallSet, start, end); // see helpers/Walls.js … … GuiInterface.prototype.SetWallPlacementPreview = function(player, cmd) 1522 1530 // copied over, so we need to fetch it from the template instead). 1523 1531 // TODO: we should really use a Cost object or at least some utility functions for this, this is mindless 1524 1532 // boilerplate that's probably duplicated in tons of places. 1525 result.cost.food += tplData.cost.food; 1526 result.cost.wood += tplData.cost.wood; 1527 result.cost.stone += tplData.cost.stone; 1528 result.cost.metal += tplData.cost.metal; 1529 result.cost.population += tplData.cost.population; 1530 result.cost.populationBonus += tplData.cost.populationBonus; 1531 result.cost.time += tplData.cost.time; 1533 let entries = Resources.GetCodes().concat("population", "populationBonus", "time"); 1534 for (let res of entries) 1535 result.cost[res] = tplData.cost[res]; 1532 1536 } 1533 1537 1534 1538 let canAfford = true; -
binaries/data/mods/public/simulation/components/Loot.js
diff --git a/binaries/data/mods/public/simulation/components/Loot.js b/binaries/data/mods/public/simulation/components/Loot.js index 3161340..c3d47df 100644
a b 1 1 function Loot() {} 2 2 3 3 Loot.prototype.Schema = 4 "<optional>" + 5 "<element name='xp'><data type='nonNegativeInteger'/></element>" + 6 "</optional>" + 7 "<optional>" + 8 "<element name='food'><data type='nonNegativeInteger'/></element>" + 9 "</optional>" + 10 "<optional>" + 11 "<element name='wood'><data type='nonNegativeInteger'/></element>" + 12 "</optional>" + 13 "<optional>" + 14 "<element name='stone'><data type='nonNegativeInteger'/></element>" + 15 "</optional>" + 16 "<optional>" + 17 "<element name='metal'><data type='nonNegativeInteger'/></element>" + 18 "</optional>"; 4 "<a:help>Specifies the loot credited when this entity is killed.</a:help>" + 5 "<a:example>" + 6 "<xp>35</xp>" + 7 "<metal>10</metal>" + 8 "</a:example>" + 9 "<oneOrMore>" + 10 "<element a:help='A resource or xp amount to be credited'>" + 11 "<anyName/>" + 12 "<data type='nonNegativeInteger'/>" + 13 "</element>" + 14 "</oneOrMore>"; 19 15 20 16 Loot.prototype.Serialize = null; // we have no dynamic state to save 21 17 … … Loot.prototype.GetXp = function() 26 22 27 23 Loot.prototype.GetResources = function() 28 24 { 29 return { 30 "food": +(this.template.food || 0), 31 "wood": +(this.template.wood || 0), 32 "metal": +(this.template.metal || 0), 33 "stone": +(this.template.stone || 0) 34 }; 25 var ret = {}; 26 for (let res of Resources.GetCodes()) 27 ret[res] = +(this.template[res] || 0); 28 29 return ret; 35 30 }; 36 31 37 32 Engine.RegisterComponentType(IID_Loot, "Loot", Loot); -
binaries/data/mods/public/simulation/components/Player.js
diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js index c097d27..c439eb4 100644
a b Player.prototype.Init = function() 18 18 this.popBonuses = 0; // sum of population bonuses of player's entities 19 19 this.maxPop = 300; // maximum population 20 20 this.trainingBlocked = false; // indicates whether any training queue is currently blocked 21 this.resourceCount = { 22 "food": 300, 23 "wood": 300, 24 "metal": 300, 25 "stone": 300 26 }; 27 // goods for next trade-route and its proba in % (the sum of probas must be 100) 28 this.tradingGoods = [ 29 { "goods": "wood", "proba": 30 }, 30 { "goods": "stone", "proba": 35 }, 31 { "goods": "metal", "proba": 35 }, 32 ]; 21 this.resourceCount = {}; 22 this.tradingGoods = []; // goods for next trade-route and its proba in % (the sum of probas must be 100) 33 23 this.team = -1; // team number of the player, players on the same team will always have ally diplomatic status - also this is useful for team emblems, scoring, etc. 34 24 this.teamsLocked = false; 35 25 this.state = "active"; // game state - one of "active", "defeated", "won" … … Player.prototype.Init = function() 44 34 this.cheatsEnabled = false; 45 35 this.cheatTimeMultiplier = 1; 46 36 this.heroes = []; 47 this.resourceNames = { 48 "food": markForTranslation("Food"), 49 "wood": markForTranslation("Wood"), 50 "metal": markForTranslation("Metal"), 51 "stone": markForTranslation("Stone"), 52 }; 37 this.resourceNames = {}; 53 38 this.disabledTemplates = {}; 54 39 this.disabledTechnologies = {}; 55 40 this.startingTechnologies = []; 41 42 var resCodes = Resources.GetCodes(); 43 var tradeProportions = [ 0, 0 ]; 44 tradeProportions[0] = Math.floor(20 / resCodes.length); 45 tradeProportions[1] = 20 - resCodes.length * tradeProportions[0]; 46 var resPos = 0; 47 for (let res of resCodes) 48 { 49 this.resourceCount[res] = 300; 50 this.resourceNames[res] = Resources.GetResource(res).name; 51 let proportion = tradeProportions[0] + ((resPos < tradeProportions[1]) ? 1 : 0); 52 this.tradingGoods.push({ "goods": res, "proba": (proportion * 5) }); 53 resPos++; 54 } 56 55 }; 57 56 58 57 Player.prototype.SetPlayerID = function(id) … … Player.prototype.UnBlockTraining = function() 197 196 198 197 Player.prototype.SetResourceCounts = function(resources) 199 198 { 200 if (resources.food !== undefined) 201 this.resourceCount.food = resources.food; 202 if (resources.wood !== undefined) 203 this.resourceCount.wood = resources.wood; 204 if (resources.stone !== undefined) 205 this.resourceCount.stone = resources.stone; 206 if (resources.metal !== undefined) 207 this.resourceCount.metal = resources.metal; 199 for (let res in resources) 200 { 201 if (this.resourceCount[res] === undefined) 202 warn("The "+res+" resourcehas been passed to cmpPlayer, but does not exist/has been disabled by mod"); 203 this.resourceCount[res] = resources[res]; 204 } 208 205 }; 209 206 210 207 Player.prototype.GetResourceCounts = function() … … Player.prototype.SubtractResourcesOrNotify = function(amounts) 297 294 298 295 // Subtract the resources 299 296 for (var type in amounts) 300 this.resourceCount[type] -= amounts[type]; 297 if (this.resourceCount[type]) 298 this.resourceCount[type] -= amounts[type]; 301 299 302 300 return true; 303 301 }; … … Player.prototype.SetTradingGoods = function(tradingGoods) 346 344 if (sumProba != 100) // consistency check 347 345 { 348 346 error("Player.js SetTradingGoods: " + uneval(tradingGoods)); 349 tradingGoods = { "food": 20, "wood":20, "stone":30, "metal":30 }; 347 var first = true; 348 for (let res of Resources.GetCodes()) 349 if (first) 350 { 351 tradingGoods[res] = 100; 352 first = false; 353 } 354 else 355 tradingGoods[res] = 0; 350 356 } 351 357 352 358 this.tradingGoods = []; -
binaries/data/mods/public/simulation/components/ProductionQueue.js
diff --git a/binaries/data/mods/public/simulation/components/ProductionQueue.js b/binaries/data/mods/public/simulation/components/ProductionQueue.js index 185bdb6..6a6ae71 100644
a b ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat 261 261 // TODO: there should be a way for the GUI to determine whether it's going 262 262 // to be possible to add a batch (based on resource costs and length limits) 263 263 var cmpPlayer = QueryOwnerInterface(this.entity); 264 var resCodes = Resources.GetCodes(); 264 265 265 266 if (this.queue.length < MAX_QUEUE_SIZE) 266 267 { … … ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat 295 296 296 297 for (var r in template.Cost.Resources) 297 298 { 298 costs[r] = ApplyValueModificationsToTemplate("Cost/Resources/"+r, +template.Cost.Resources[r], cmpPlayer.GetPlayerID(), template); 299 let cost = +template.Cost.Resources[r]; 300 if (resCodes.indexOf(r) < 0) 301 { 302 if (cost > 0) 303 warn("'"+r+"' has been specified as a required resource, but is not a valid resource."); 304 continue; 305 } 306 costs[r] = ApplyValueModificationsToTemplate("Cost/Resources/"+r, cost, cmpPlayer.GetPlayerID(), template); 299 307 totalCosts[r] = Math.floor(count * costs[r]); 300 308 } 301 309 … … ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat 342 350 let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetCheatTimeMultiplier(); 343 351 344 352 var cost = {}; 345 for (let res in template.cost) 346 cost[res] = Math.floor(techCostMultiplier[res] * template.cost[res]); 353 for (let r in template.cost) 354 { 355 if (resCodes.indexOf(r) < 0) 356 { 357 if (Math.floor(template.cost[r]) > 0) 358 warn("'"+r+"' has been specified as a required resource, but is not a valid resource."); 359 continue; 360 } 361 cost[r] = Math.floor((techCostMultiplier[r] ? techCostMultiplier[r] : 1) * template.cost[r]);; 362 } 347 363 348 364 // TrySubtractResources should report error to player (they ran out of resources) 349 365 if (!cmpPlayer.TrySubtractResources(cost)) … … ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat 361 377 "player": cmpPlayer.GetPlayerID(), 362 378 "count": 1, 363 379 "technologyTemplate": templateName, 364 "resources": deepcopy(template.cost), // need to copy to avoid serialization problems380 "resources": cost, 365 381 "productionStarted": false, 366 382 "timeTotal": time*1000, 367 383 "timeRemaining": time*1000, … … ProductionQueue.prototype.RemoveBatch = function(id) 433 449 // Refund the resource cost for this batch 434 450 var totalCosts = {}; 435 451 var cmpStatisticsTracker = QueryPlayerIDInterface(item.player, IID_StatisticsTracker); 436 for each (var r in ["food", "wood", "stone", "metal"])452 for (let r of Resources.GetCodes()) 437 453 { 454 if (!item.resources[r]) 455 continue; 438 456 totalCosts[r] = Math.floor(item.count * item.resources[r]); 439 457 if (cmpStatisticsTracker) 440 458 cmpStatisticsTracker.IncreaseResourceUsedCounter(r, -totalCosts[r]); -
binaries/data/mods/public/simulation/components/ResourceDropsite.js
diff --git a/binaries/data/mods/public/simulation/components/ResourceDropsite.js b/binaries/data/mods/public/simulation/components/ResourceDropsite.js index 44045c0..dbaa746 100644
a b function ResourceDropsite() {} 2 2 3 3 ResourceDropsite.prototype.Schema = 4 4 "<element name='Types'>" + 5 "<list>" + 6 "<zeroOrMore>" + 7 "<choice>" + 8 "<value>food</value>" + 9 "<value>wood</value>" + 10 "<value>stone</value>" + 11 "<value>metal</value>" + 12 "</choice>" + 13 "</zeroOrMore>" + 14 "</list>" + 5 "<text/>" + 15 6 "</element>" + 16 7 "<element name='Sharable' a:help='Allows allies to use this entity.'>" + 17 8 "<data type='boolean'/>" + … … ResourceDropsite.prototype.Init = function() 28 19 */ 29 20 ResourceDropsite.prototype.GetTypes = function() 30 21 { 31 let types = ApplyValueModificationsToEntity("ResourceDropsite/Types", this.template.Types, this.entity); 32 return types ? types.split(/\s+/) : []; 22 let typesTok = ApplyValueModificationsToEntity("ResourceDropsite/Types", this.template.Types, this.entity); 23 let typesArr = []; 24 let resources = Resources.GetCodes(); 25 26 for (let type of typesTok.split(/\s+/)) 27 if (resources.indexOf(type.toLowerCase()) > -1) 28 typesArr.push(type); 29 30 return typesArr; 33 31 }; 34 32 35 33 /** -
binaries/data/mods/public/simulation/components/ResourceGatherer.js
diff --git a/binaries/data/mods/public/simulation/components/ResourceGatherer.js b/binaries/data/mods/public/simulation/components/ResourceGatherer.js index acd5fbd..58790c3 100644
a b ResourceGatherer.prototype.Schema = 26 26 "</element>" + 27 27 "<element name='Rates' a:help='Per-resource-type gather rate multipliers. If a resource type is not specified then it cannot be gathered by this unit'>" + 28 28 "<interleave>" + 29 "<optional><element name='food' a:help='Food gather rate (may be overridden by \"food.*\" subtypes)'><ref name='positiveDecimal'/></element></optional>" + 30 "<optional><element name='wood' a:help='Wood gather rate'><ref name='positiveDecimal'/></element></optional>" + 31 "<optional><element name='stone' a:help='Stone gather rate'><ref name='positiveDecimal'/></element></optional>" + 32 "<optional><element name='metal' a:help='Metal gather rate'><ref name='positiveDecimal'/></element></optional>" + 33 "<optional><element name='treasure' a:help='Treasure gather rate (only presense on value makes sense, size is only used to determine the delay before gathering, so it should be set to 1)'><ref name='positiveDecimal'/></element></optional>" + 34 "<optional><element name='food.fish' a:help='Fish gather rate (overrides \"food\")'><ref name='positiveDecimal'/></element></optional>" + 35 "<optional><element name='food.fruit' a:help='Fruit gather rate (overrides \"food\")'><ref name='positiveDecimal'/></element></optional>" + 36 "<optional><element name='food.grain' a:help='Grain gather rate (overrides \"food\")'><ref name='positiveDecimal'/></element></optional>" + 37 "<optional><element name='food.meat' a:help='Meat gather rate (overrides \"food\")'><ref name='positiveDecimal'/></element></optional>" + 38 "<optional><element name='food.milk' a:help='Milk gather rate (overrides \"food\")'><ref name='positiveDecimal'/></element></optional>" + 39 "<optional><element name='wood.tree' a:help='Tree gather rate (overrides \"wood\")'><ref name='positiveDecimal'/></element></optional>" + 40 "<optional><element name='wood.ruins' a:help='Tree gather rate (overrides \"wood\")'><ref name='positiveDecimal'/></element></optional>" + 41 "<optional><element name='stone.rock' a:help='Rock gather rate (overrides \"stone\")'><ref name='positiveDecimal'/></element></optional>" + 42 "<optional><element name='stone.ruins' a:help='Rock gather rate (overrides \"stone\")'><ref name='positiveDecimal'/></element></optional>" + 43 "<optional><element name='metal.ore' a:help='Ore gather rate (overrides \"metal\")'><ref name='positiveDecimal'/></element></optional>" + 44 "<optional><element name='treasure.food' a:help='Food treasure gather rate (overrides \"treasure\")'><ref name='positiveDecimal'/></element></optional>" + 45 "<optional><element name='treasure.wood' a:help='Wood treasure gather rate (overrides \"treasure\")'><ref name='positiveDecimal'/></element></optional>" + 46 "<optional><element name='treasure.stone' a:help='Stone treasure gather rate (overrides \"treasure\")'><ref name='positiveDecimal'/></element></optional>" + 47 "<optional><element name='treasure.metal' a:help='Metal treasure gather rate (overrides \"treasure\")'><ref name='positiveDecimal'/></element></optional>" + 29 "<oneOrMore>" + 30 "<element a:help='A particular gather rate, with the element name in the form {type} or {type}.{subtype}'>" + 31 "<anyName/>" + 32 "<ref name='positiveDecimal'/>" + 33 "</element>" + 34 "</oneOrMore>" + 48 35 "</interleave>" + 49 36 "</element>" + 50 37 "<element name='Capacities' a:help='Per-resource-type maximum carrying capacity'>" + 51 38 "<interleave>" + 52 "<element name='food' a:help='Food capacity'><ref name='positiveDecimal'/></element>" + 53 "<element name='wood' a:help='Wood capacity'><ref name='positiveDecimal'/></element>" + 54 "<element name='stone' a:help='Stone capacity'><ref name='positiveDecimal'/></element>" + 55 "<element name='metal' a:help='Metal capacity'><ref name='positiveDecimal'/></element>" + 39 "<oneOrMore>" + 40 "<element a:help='A particular resource capacity'>" + 41 "<anyName/>" + 42 "<ref name='positiveDecimal'/>" + 43 "</element>" + 44 "</oneOrMore>" + 56 45 "</interleave>" + 57 46 "</element>"; 58 47 … … ResourceGatherer.prototype.RecalculateGatherRatesAndCapacities = function() 137 126 this.rates = {}; 138 127 for (let r in this.template.Rates) 139 128 { 129 let type = r.split("."); 130 let res = Resources.GetResource(type[0]); 131 132 if (!res && type[0] !== "treasure" || (type.length > 1 && res.subtypes.indexOf(type[1]) < 0)) 133 continue; 134 140 135 let rate = ApplyValueModificationsToEntity("ResourceGatherer/Rates/" + r, +this.template.Rates[r], this.entity); 141 136 this.rates[r] = rate * this.baseSpeed; 142 137 } … … ResourceGatherer.prototype.GetRange = function() 174 169 175 170 /** 176 171 * Try to gather treasure 177 * @return 'true' if treasure is successfully gathered and 'false' i n the other case172 * @return 'true' if treasure is successfully gathered and 'false' if not 178 173 */ 179 174 ResourceGatherer.prototype.TryInstantGather = function(target) 180 175 { -
binaries/data/mods/public/simulation/components/ResourceSupply.js
diff --git a/binaries/data/mods/public/simulation/components/ResourceSupply.js b/binaries/data/mods/public/simulation/components/ResourceSupply.js index 04e95da..123621e 100644
a b ResourceSupply.prototype.Schema = 12 12 "<element name='Amount' a:help='Amount of resources available from this entity'>" + 13 13 "<choice><data type='nonNegativeInteger'/><value>Infinity</value></choice>" + 14 14 "</element>" + 15 "<element name='Type' a:help='Type of resources'>" + 16 "<choice>" + 17 "<value>wood.tree</value>" + 18 "<value>wood.ruins</value>" + 19 "<value>stone.rock</value>" + 20 "<value>stone.ruins</value>" + 21 "<value>metal.ore</value>" + 22 "<value>food.fish</value>" + 23 "<value>food.fruit</value>" + 24 "<value>food.grain</value>" + 25 "<value>food.meat</value>" + 26 "<value>food.milk</value>" + 27 "<value>treasure.wood</value>" + 28 "<value>treasure.stone</value>" + 29 "<value>treasure.metal</value>" + 30 "<value>treasure.food</value>" + 31 "</choice>" + 15 "<element name='Type' a:help='Type and Subtype of resource available from this entity, in the form of {type}.{subtype}'>" + 16 "<text/>" + 32 17 "</element>" + 33 18 "<element name='MaxGatherers' a:help='Amount of gatherers who can gather resources from this entity at the same time'>" + 34 19 "<data type='nonNegativeInteger'/>" + … … ResourceSupply.prototype.Init = function() 52 37 53 38 this.infinite = !isFinite(+this.template.Amount); 54 39 55 [this.type,this.subType] = this.template.Type.split('.'); 56 this.cachedType = { "generic" : this.type, "specific" : this.subType }; 40 [this.type, this.subtype] = this.template.Type.split('.'); 41 var resData = Resources.GetResource(this.type); 42 if (this.type === "treasure") 43 resData = { "subtypes": Resources.GetCodes() }; 57 44 45 if (!resData || resData.subtypes.indexOf(this.subtype) === -1) 46 { 47 // Display Error and Remove entity if the resource supplied is not valid. 48 error("Invalid resource type or subtype ("+this.type+"/"+this.subtype+")"); 49 Engine.DestroyEntity(this.entity); 50 } 51 this.cachedType = { "generic" : this.type, "specific" : this.subtype }; 58 52 }; 59 53 60 54 ResourceSupply.prototype.IsInfinite = function() -
binaries/data/mods/public/simulation/components/ResourceTrickle.js
diff --git a/binaries/data/mods/public/simulation/components/ResourceTrickle.js b/binaries/data/mods/public/simulation/components/ResourceTrickle.js index 5c554e7..888aa45 100644
a b function ResourceTrickle() {} 3 3 ResourceTrickle.prototype.Schema = 4 4 "<a:help>Controls the resource trickle ability of the unit.</a:help>" + 5 5 "<element name='Rates' a:help='Trickle Rates'>" + 6 "<interleave>" + 7 "<optional>" + 8 "<element name='food' a:help='Food given to the player every interval'>" + 9 "<ref name='nonNegativeDecimal'/>" + 10 "</element>" + 11 "</optional>" + 12 "<optional>" + 13 "<element name='wood' a:help='Wood given to the player every interval'>" + 14 "<ref name='nonNegativeDecimal'/>" + 15 "</element>" + 16 "</optional>" + 17 "<optional>" + 18 "<element name='stone' a:help='Stone given to the player every interval'>" + 19 "<ref name='nonNegativeDecimal'/>" + 20 "</element>" + 21 "</optional>" + 22 "<optional>" + 23 "<element name='metal' a:help='Metal given to the player every interval'>" + 24 "<ref name='nonNegativeDecimal'/>" + 25 "</element>" + 26 "</optional>" + 27 "</interleave>" + 6 "<oneOrMore>" + 7 "<element a:help='Quantity of a Resource given to the player every interval'>" + 8 "<anyName/>" + 9 "<ref name='nonNegativeDecimal'/>" + 10 "</element>" + 11 "</oneOrMore>" + 28 12 "</element>" + 29 13 "<element name='Interval' a:help='Number of miliseconds must pass for the player to gain the next trickle.'>" + 30 14 "<ref name='nonNegativeDecimal'/>" + … … ResourceTrickle.prototype.GetTimer = function() 46 30 ResourceTrickle.prototype.GetRates = function() 47 31 { 48 32 var rates = {}; 33 var resCodes = Resources.GetCodes(); 49 34 for (var resource in this.template.Rates) 35 { 36 if (resCodes.indexOf(resource) < 0) 37 continue; 50 38 rates[resource] = ApplyValueModificationsToEntity("ResourceTrickle/Rates/"+resource, +this.template.Rates[resource], this.entity); 39 } 51 40 52 41 return rates; 53 42 }; … … ResourceTrickle.prototype.GetRates = function() 55 44 // Do the actual work here 56 45 ResourceTrickle.prototype.Trickle = function(data, lateness) 57 46 { 58 var cmpPlayer = QueryOwnerInterface(this.entity); 59 if (!cmpPlayer) 60 return; 61 62 var rates = this.GetRates(); 63 for (var resource in rates) 64 cmpPlayer.AddResource(resource, rates[resource]); 47 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 48 if (cmpPlayer) 49 cmpPlayer.AddResources(this.GetRates()); 65 50 }; 66 51 67 52 Engine.RegisterComponentType(IID_ResourceTrickle, "ResourceTrickle", ResourceTrickle); -
binaries/data/mods/public/simulation/components/StatisticsTracker.js
diff --git a/binaries/data/mods/public/simulation/components/StatisticsTracker.js b/binaries/data/mods/public/simulation/components/StatisticsTracker.js index a5a060d..c27c9ed 100644
a b StatisticsTracker.prototype.Init = function() 94 94 this.enemyBuildingsDestroyedValue = 0; 95 95 96 96 this.resourcesGathered = { 97 "food": 0,98 "wood": 0,99 "metal": 0,100 "stone": 0,101 97 "vegetarianFood": 0 102 98 }; 103 this.resourcesUsed = { 104 "food": 0, 105 "wood": 0, 106 "metal": 0, 107 "stone": 0 108 }; 109 this.resourcesSold = { 110 "food": 0, 111 "wood": 0, 112 "metal": 0, 113 "stone": 0 114 }; 115 this.resourcesBought = { 116 "food": 0, 117 "wood": 0, 118 "metal": 0, 119 "stone": 0 120 }; 99 this.resourcesUsed = {}; 100 this.resourcesSold = {}; 101 this.resourcesBought = {}; 102 for (let res of Resources.GetCodes()) 103 { 104 this.resourcesGathered[res] = 0; 105 this.resourcesUsed[res] = 0; 106 this.resourcesSold[res] = 0; 107 this.resourcesBought[res] = 0; 108 } 121 109 122 110 this.tributesSent = 0; 123 111 this.tributesReceived = 0; … … StatisticsTracker.prototype.IncreaseResourceGatheredCounter = function(type, amo 314 302 */ 315 303 StatisticsTracker.prototype.IncreaseResourceUsedCounter = function(type, amount) 316 304 { 317 this.resourcesUsed[type] += amount; 305 if (typeof this.resourcesUsed[type] === "number") 306 this.resourcesUsed[type] += amount; 318 307 }; 319 308 320 309 StatisticsTracker.prototype.IncreaseTreasuresCollectedCounter = function() -
binaries/data/mods/public/simulation/components/Trader.js
diff --git a/binaries/data/mods/public/simulation/components/Trader.js b/binaries/data/mods/public/simulation/components/Trader.js index f80096a..6f33bb9 100644
a b 4 4 // Additional gain for ships for each garrisoned trader, in percents 5 5 const GARRISONED_TRADER_ADDITION = 20; 6 6 7 // Array of resource names8 const RESOURCES = ["food", "wood", "stone", "metal"];9 10 7 function Trader() {} 11 8 12 9 Trader.prototype.Schema = … … Trader.prototype.GetRequiredGoods = function() 149 146 Trader.prototype.SetRequiredGoods = function(requiredGoods) 150 147 { 151 148 // Check that argument is a correct resource name 152 if (!requiredGoods || R ESOURCES.indexOf(requiredGoods) == -1)149 if (!requiredGoods || Resources.GetCodes().indexOf(requiredGoods) == -1) 153 150 this.requiredGoods = undefined; 154 151 else 155 152 this.requiredGoods = requiredGoods; … … Trader.prototype.PerformTrade = function(currentMarket) 230 227 // if still nothing (but should never happen), choose metal 231 228 // and recomputes the gain in case it has changed (for example by technology) 232 229 var nextGoods = this.GetRequiredGoods(); 233 if (!nextGoods || RESOURCES.indexOf(nextGoods) == -1) 230 var resCodes = Resources.GetCodes(); 231 if (!nextGoods || resCodes.indexOf(nextGoods) == -1) 234 232 { 235 233 let cmpPlayer = QueryOwnerInterface(this.entity); 236 234 if (cmpPlayer) 237 235 nextGoods = cmpPlayer.GetNextTradingGoods(); 238 236 239 if (!nextGoods || RESOURCES.indexOf(nextGoods) == -1)237 if (!nextGoods || resCodes.indexOf(nextGoods) == -1) 240 238 nextGoods = "metal"; 241 239 } 242 240 this.goods.type = nextGoods; -
new file inaries/data/mods/public/simulation/data/resources/food.json
diff --git a/binaries/data/mods/public/simulation/data/resources/food.json b/binaries/data/mods/public/simulation/data/resources/food.json new file mode 100644 index 0000000..c3a7f32
- + 1 { 2 "code": "food", 3 "subtypes": [ 4 "fish", 5 "fruit", 6 "grain", 7 "meat", 8 "milk" 9 ], 10 "truePrice": 100 11 } -
new file inaries/data/mods/public/simulation/data/resources/metal.json
diff --git a/binaries/data/mods/public/simulation/data/resources/metal.json b/binaries/data/mods/public/simulation/data/resources/metal.json new file mode 100644 index 0000000..aa70686
- + 1 { 2 "code": "metal", 3 "subtypes": [ 4 "ore" 5 ], 6 "truePrice": 100, 7 "aiAnalysis": { 8 "decreaseFactor": 90.0, 9 "influenceMapGroup": 1 10 } 11 } -
new file inaries/data/mods/public/simulation/data/resources/stone.json
diff --git a/binaries/data/mods/public/simulation/data/resources/stone.json b/binaries/data/mods/public/simulation/data/resources/stone.json new file mode 100644 index 0000000..4f46cca
- + 1 { 2 "code": "stone", 3 "subtypes": [ 4 "rock", 5 "ruins" 6 ], 7 "truePrice": 100, 8 "aiAnalysis": { 9 "decreaseFactor": 90.0, 10 "influenceMapGroup": 1 11 } 12 } -
new file inaries/data/mods/public/simulation/data/resources/wood.json
diff --git a/binaries/data/mods/public/simulation/data/resources/wood.json b/binaries/data/mods/public/simulation/data/resources/wood.json new file mode 100644 index 0000000..502ccbf
- + 1 { 2 "code": "wood", 3 "subtypes": [ 4 "tree", 5 "ruins" 6 ], 7 "truePrice": 100, 8 "aiAnalysis": { 9 "decreaseFactor": 50.0, 10 "influenceMapGroup": 0 11 } 12 } -
new file inaries/data/mods/public/simulation/helpers/Resources.js
diff --git a/binaries/data/mods/public/simulation/helpers/Resources.js b/binaries/data/mods/public/simulation/helpers/Resources.js new file mode 100644 index 0000000..f6a7f6e
- + 1 /** 2 * Resource handling helper script 3 * 4 */ 5 6 var Resources = {}; 7 8 /** 9 * Returns an object containing all readable resource data 10 */ 11 Resources.LoadData = function() 12 { 13 this.resourceData = {}; 14 var jsonFiles = Engine.FindJSONFiles("resources", false); 15 16 for (let filename of jsonFiles) 17 { 18 let data = Engine.ReadJSONFile("resources/"+filename+".json"); 19 if (!data) 20 continue; 21 22 this.resourceData[data.code] = data; 23 } 24 return this.resourceData; 25 }; 26 27 Resources.GetAllData = function() 28 { 29 if (!this.resourceData) 30 return this.LoadData(); 31 else 32 return this.resourceData; 33 }; 34 35 Resources.GetResource = function(type) 36 { 37 var data = this.GetAllData(); 38 type = type.toLowerCase(); 39 40 return data[type] || false; 41 }; 42 43 /** 44 * Returns an array of codes belonging to the resources 45 */ 46 Resources.GetCodes = function() 47 { 48 return Object.keys(this.GetAllData()); 49 }; 50 51 Engine.RegisterGlobal("Resources", Resources);