Ticket #4007: selection_panels_cleanup.2.diff
File selection_panels_cleanup.2.diff, 48.9 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/common/color.js
1 let g_GuiColors = { 2 "hotkey": "255 251 131", 3 "forbidden": "255 0 0 80", 4 "limited": "0 0 0 127", 5 }; 6 1 7 /** 2 8 * Concatenate integer color values to a string (for use in GUI objects) 3 9 * … … 124 130 125 131 return [r, g, b].map(n => Math.round(n * 255)); 126 132 } 133 134 /** 135 * Colorize text for usage in the GUI 136 * @param {string} color in the form of a GUI color string 137 * @param {string} text to colorize 138 * @returns {string} 139 */ 140 function colorizeText(color, text) 141 { 142 return "[color=\"" + color + "\"]" + text + "[/color]"; 143 }; -
binaries/data/mods/public/gui/session/selection_panels.js
9 9 * the item and some other standard data is added to a data object. 10 10 * 11 11 * The standard data is 12 * var data ={12 * { 13 13 * "i": index 14 14 * "item": item coming from the getItems function 15 15 * "selection": list of currently selected items … … 23 23 * "countDisplay": gui caption space 24 24 * }; 25 25 * 26 * Then, addData is called, and can be used to abort the processing 27 * of the current item by returning false. 28 * It should return true if you want the panel to be filled. 29 * 30 * addData is used to add data to the data object on top 31 * (or instead of) the standard data. 32 * addData is not obligated, the function will just continue 33 * with the content setters if no addData is present. 34 * 35 * After the addData, all functions starting with "set" are called. 36 * These are used to set various parts of content. 26 * Then for every data object, the setupButton function is called which 27 * sets the view and handlers of the button. 37 28 */ 38 29 39 30 /* cache some formation info */ 40 var g_availableFormations = new Map(); // available formations per player41 var g_formationsInfo = new Map();31 let g_AvailableFormations = new Map(); // available formations per player 32 let g_FormationsInfo = new Map(); 42 33 43 varg_SelectionPanels = {};34 let g_SelectionPanels = {}; 44 35 45 36 // ALERT 46 37 g_SelectionPanels.Alert = { … … 54 45 return []; 55 46 return ["increase", "end"]; 56 47 }, 57 "set Action": function(data)48 "setupButton": function(data) 58 49 { 59 50 data.button.onPress = function() { 60 51 if (data.item == "increase") … … 62 53 else if (data.item == "end") 63 54 endOfAlert(); 64 55 }; 65 }, 66 "setTooltip": function(data) 67 { 56 68 57 if (data.item == "increase") 69 58 { 70 59 if (data.unitEntState.alertRaiser.hasRaisedAlert) … … 74 63 } 75 64 else if (data.item == "end") 76 65 data.button.tooltip = translate("End of alert."); 77 }, 78 "setGraphics": function(data) 79 { 66 80 67 if (data.item == "increase") 81 68 { 82 69 data.button.hidden = !data.unitEntState.alertRaiser.canIncreaseLevel; … … 91 78 data.icon.sprite = "stretched:session/icons/bell_level0.png"; 92 79 } 93 80 data.button.enabled = !data.button.hidden && controlsPlayer(data.unitEntState.player); 81 82 setPanelObjectPosition(data.button, data.i, data.rowLength); 83 return true; 94 84 } 95 85 }; 96 86 … … 108 98 // ["food", "wood", "stone", "metal"] 109 99 return BARTER_RESOURCES; 110 100 }, 111 " addData": function(data)101 "setupButton": function(data) 112 102 { 113 103 // data.item is the resource name in this case 114 data.button = {};115 data.icon = {};116 data.amount = {};117 for ( vara of BARTER_ACTIONS)104 let button = {}; 105 let icon = {}; 106 let amount = {}; 107 for (let a of BARTER_ACTIONS) 118 108 { 119 data.button[a] = Engine.GetGUIObjectByName("unitBarter"+a+"Button["+data.i+"]");120 data.icon[a] = Engine.GetGUIObjectByName("unitBarter"+a+"Icon["+data.i+"]");121 data.amount[a] = Engine.GetGUIObjectByName("unitBarter"+a+"Amount["+data.i+"]");109 button[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Button[" + data.i + "]"); 110 icon[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Icon[" + data.i + "]"); 111 amount[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Amount[" + data.i + "]"); 122 112 } 123 data.selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection["+data.i+"]");113 let selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection[" + data.i + "]"); 124 114 125 data.amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL;115 let amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; 126 116 if (Engine.HotkeyIsPressed("session.massbarter")) 127 data.amountToSell *= BARTER_BUNCH_MULTIPLIER; 128 data.isSelected = data.item == g_barterSell; 129 return true; 130 }, 131 "setCountDisplay": function(data) 132 { 133 data.amount.Sell.caption = "-" + data.amountToSell; 134 var sellPrice = data.unitEntState.barterMarket.prices.sell[g_barterSell]; 135 var buyPrice = data.unitEntState.barterMarket.prices.buy[data.item]; 136 data.amount.Buy.caption = "+" + Math.round(sellPrice / buyPrice * data.amountToSell); 137 }, 138 "setTooltip": function(data) 139 { 140 var resource = getLocalizedResourceName(data.item, "withinSentence"); 141 data.button.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource }); 142 data.button.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource }); 143 }, 144 "setAction": function(data) 145 { 146 data.button.Sell.onPress = function() { g_barterSell = data.item; }; 147 var exchangeResourcesParameters = { 117 amountToSell *= BARTER_BUNCH_MULTIPLIER; 118 119 amount.Sell.caption = "-" + amountToSell; 120 let sellPrice = data.unitEntState.barterMarket.prices.sell[g_barterSell]; 121 let buyPrice = data.unitEntState.barterMarket.prices.buy[data.item]; 122 amount.Buy.caption = "+" + Math.round(sellPrice / buyPrice * amountToSell); 123 124 let resource = getLocalizedResourceName(data.item, "withinSentence"); 125 button.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource }); 126 button.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource }); 127 128 button.Sell.onPress = function() { g_barterSell = data.item; }; 129 let exchangeResourcesParameters = { 148 130 "sell": g_barterSell, 149 131 "buy": data.item, 150 "amount": data.amountToSell132 "amount": amountToSell 151 133 }; 152 data.button.Buy.onPress = function() { exchangeResources(exchangeResourcesParameters); }; 153 }, 154 "setGraphics": function(data) 155 { 156 var grayscale = data.isSelected ? "color: 0 0 0 100:grayscale:" : ""; 134 button.Buy.onPress = function() { exchangeResources(exchangeResourcesParameters); }; 157 135 136 let isSelected = data.item == g_barterSell; 137 let grayscale = isSelected ? "color: 0 0 0 100:grayscale:" : ""; 138 158 139 // do we have enough of this resource to sell? 159 varneededRes = {};160 neededRes[data.item] = data.amountToSell;161 varcanSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {140 let neededRes = {}; 141 neededRes[data.item] = amountToSell; 142 let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", { 162 143 "cost": neededRes, 163 144 "player": data.unitEntState.player 164 }) ? "color: 255 0 0 80:" : "";145 }) ? "color:" + g_GuiColors.forbidden + ":" : ""; 165 146 166 147 // Let's see if we have enough resources to barter. 167 148 neededRes = {}; 168 neededRes[g_barterSell] = data.amountToSell;169 varcanBuyAny = Engine.GuiInterfaceCall("GetNeededResources", {149 neededRes[g_barterSell] = amountToSell; 150 let canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", { 170 151 "cost": neededRes, 171 152 "player": data.unitEntState.player 172 }) ? "color: 255 0 0 80:" : "";153 }) ? "color:" + g_GuiColors.forbidden + ":" : ""; 173 154 174 data.icon.Sell.sprite = canSellCurrent + "stretched:"+grayscale+"session/icons/resources/" + data.item + ".png";175 data.icon.Buy.sprite = canBuyAny + "stretched:"+grayscale+"session/icons/resources/" + data.item + ".png";155 icon.Sell.sprite = canSellCurrent + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png"; 156 icon.Buy.sprite = canBuyAny + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png"; 176 157 177 data.button.Buy.hidden = data.isSelected;178 data.button.Buy.enabled = controlsPlayer(data.unitEntState.player);179 data.button.Sell.hidden = false;180 data.selectionIcon.hidden = !data.isSelected;181 }, 182 "setPosition": function(data)183 {184 setPanelObjectPosition( data.button.Sell, data.i, data.rowLength);185 setPanelObjectPosition(data.button.Buy, data.i + data.rowLength, data.rowLength);158 button.Buy.hidden = isSelected; 159 button.Buy.enabled = controlsPlayer(data.unitEntState.player); 160 button.Sell.hidden = false; 161 selectionIcon.hidden = !isSelected; 162 163 // Position 164 setPanelObjectPosition(button.Sell, data.i, data.rowLength); 165 setPanelObjectPosition(button.Buy, data.i + data.rowLength, data.rowLength); 166 return true; 186 167 } 187 168 }; 188 169 … … 198 179 199 180 for (let c in g_EntityCommands) 200 181 { 201 varinfo = g_EntityCommands[c].getInfo(unitEntState);182 let info = g_EntityCommands[c].getInfo(unitEntState); 202 183 if (!info) 203 184 continue; 204 185 … … 207 188 } 208 189 return commands; 209 190 }, 210 "set Tooltip": function(data)191 "setupButton": function(data) 211 192 { 212 193 data.button.tooltip = data.item.tooltip; 213 }, 214 "setAction": function(data) 215 { 194 216 195 data.button.onPress = function() { 217 196 if (data.item.callback) 218 197 data.item.callback(data.item); … … 219 198 else 220 199 performCommand(data.unitEntState.id, data.item.name); 221 200 }; 222 }, 223 "setCountDisplay": function(data) 224 { 201 225 202 data.countDisplay.caption = data.item.count || ""; 226 }, 227 "setGraphics": function(data) 228 { 203 229 204 data.button.enabled = controlsPlayer(data.unitEntState.player); 230 205 let grayscale = data.button.enabled ? "" : "grayscale:"; 231 206 data.icon.sprite = "stretched:" + grayscale + "session/icons/" + data.item.icon; 232 }, 233 "setPosition": function(data) 234 { 235 var size = data.button.size; 207 208 let size = data.button.size; 236 209 // count on square buttons, so size.bottom is the width too 237 varspacer = size.bottom + 1;210 let spacer = size.bottom + 1; 238 211 // relative to the center ( = 50%) 239 212 size.rleft = size.rright = 50; 240 213 // offset from the center calculation … … 241 214 size.left = (data.i - data.numberOfItems/2) * spacer; 242 215 size.right = size.left + size.bottom; 243 216 data.button.size = size; 217 return true; 244 218 } 245 219 }; 246 220 … … 250 224 { 251 225 return 2; 252 226 }, 227 "conflictsWith": ["Command"], 253 228 "getItems": function(unitEntState) 254 229 { 255 varcommands = [];256 for ( varc in g_AllyEntityCommands)230 let commands = []; 231 for (let c in g_AllyEntityCommands) 257 232 { 258 varinfo = g_AllyEntityCommands[c].getInfo(unitEntState);233 let info = g_AllyEntityCommands[c].getInfo(unitEntState); 259 234 if (!info) 260 235 continue; 261 236 info.name = c; … … 263 238 } 264 239 return commands; 265 240 }, 266 "set Tooltip": function(data)241 "setupButton": function(data) 267 242 { 268 243 data.button.tooltip = data.item.tooltip; 269 }, 270 "setAction": function(data) 271 { 244 272 245 data.button.onPress = function() { 273 246 if (data.item.callback) 274 247 data.item.callback(data.item); … … 275 248 else 276 249 performAllyCommand(data.unitEntState.id, data.item.name); 277 250 }; 278 }, 279 "conflictsWith": ["Command"], 280 "setCountDisplay": function(data) 281 { 251 282 252 data.countDisplay.caption = data.item.count || ""; 283 }, 284 "setGraphics": function(data) 285 { 253 286 254 data.button.enabled = data.item.count != undefined && data.item.count > 0; 287 255 let grayscale = data.button.enabled ? "" : "grayscale:"; 288 256 data.icon.sprite = "stretched:" + grayscale + "session/icons/" + data.item.icon; 289 }, 290 "setPosition": function(data) 291 { 292 var size = data.button.size; 257 258 let size = data.button.size; 293 259 // count on square buttons, so size.bottom is the width too 294 varspacer = size.bottom + 1;260 let spacer = size.bottom + 1; 295 261 // relative to the center ( = 50%) 296 262 size.rleft = size.rright = 50; 297 263 // offset from the center calculation … … 298 264 size.left = (data.i - data.numberOfItems/2) * spacer; 299 265 size.right = size.left + size.bottom; 300 266 data.button.size = size; 267 268 // Position 269 setPanelObjectPosition(data.button, data.i, data.rowLength); 270 return true; 301 271 } 302 272 }; 303 273 … … 311 281 { 312 282 return getAllBuildableEntitiesFromSelection(); 313 283 }, 314 " addData": function(data)284 "setupButton": function(data) 315 285 { 316 data.entType = data.item; 317 data.template = GetTemplateData(data.entType); 318 if (!data.template) // abort if no template 286 let template = GetTemplateData(data.item); 287 if (!template) // abort if no template 319 288 return false; 320 289 321 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", {322 "tech": data.template.requiredTechnology,290 let technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 291 "tech": template.requiredTechnology, 323 292 "player": data.unitEntState.player 324 293 }); 325 294 326 if (data.template.cost) 327 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 328 "cost": multiplyEntityCosts(data.template, 1), 295 let neededResources; 296 if (template.cost) 297 neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 298 "cost": multiplyEntityCosts(template, 1), 329 299 "player": data.unitEntState.player 330 300 }); 331 301 332 data.limits = getEntityLimitAndCount(data.playerState, data.entType);302 let limits = getEntityLimitAndCount(data.playerState, data.item); 333 303 334 if ( data.template.wallSet)335 data.template.auras = GetTemplateData(data.template.wallSet.templates.long).auras;304 if (template.wallSet) 305 template.auras = GetTemplateData(template.wallSet.templates.long).auras; 336 306 337 return true;338 },339 "setAction": function(data)340 {341 307 data.button.onPress = function () { startBuildingPlacement(data.item, data.playerState); }; 342 },343 "setTooltip": function(data)344 {345 var tooltip = getEntityNamesFormatted(data.template);346 tooltip += getVisibleEntityClassesFormatted(data.template);347 tooltip += getAurasTooltip(data.template);348 308 349 if (data.template.tooltip) 350 tooltip += "\n[font=\"sans-13\"]" + data.template.tooltip + "[/font]"; 309 let tooltip = getEntityNamesFormatted(template); 310 tooltip += getVisibleEntityClassesFormatted(template); 311 tooltip += getAurasTooltip(template); 351 312 352 tooltip += "\n" + getEntityCostTooltip(data.template);353 tooltip += getPopulationBonusTooltip(data.template);313 if (template.tooltip) 314 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 354 315 355 tooltip += formatLimitString(data.limits.entLimit, data.limits.entCount, data.limits.entLimitChangers); 316 tooltip += "\n" + getEntityCostTooltip(template); 317 tooltip += getPopulationBonusTooltip(template); 356 318 357 if (!data.technologyEnabled) 319 tooltip += formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers); 320 321 if (!technologyEnabled) 358 322 tooltip += "\n" + sprintf(translate("Requires %(technology)s"), { 359 "technology": getEntityNames(GetTechnologyData( data.template.requiredTechnology))323 "technology": getEntityNames(GetTechnologyData(template.requiredTechnology)) 360 324 }); 361 325 362 if ( data.neededResources)363 tooltip += getNeededResourcesTooltip( data.neededResources);326 if (neededResources) 327 tooltip += getNeededResourcesTooltip(neededResources); 364 328 365 329 data.button.tooltip = tooltip; 366 return true; 367 }, 368 "setGraphics": function(data) 369 { 370 var modifier = ""; 371 if (!data.technologyEnabled || data.limits.canBeAddedCount == 0) 330 331 let modifier = ""; 332 if (!technologyEnabled || limits.canBeAddedCount == 0) 372 333 { 373 334 data.button.enabled = false; 374 modifier += "color: 0 0 0 127:";335 modifier += "color: " + g_GuiColors.limited + ":"; 375 336 modifier += "grayscale:"; 376 337 } 377 else if ( data.neededResources)338 else if (neededResources) 378 339 { 379 340 data.button.enabled = false; 380 modifier += resourcesToAlphaMask( data.neededResources) +":";341 modifier += resourcesToAlphaMask(neededResources) +":"; 381 342 } 382 343 else 383 344 data.button.enabled = controlsPlayer(data.unitEntState.player); 384 345 385 if (data.template.icon) 386 data.icon.sprite = modifier + "stretched:session/portraits/" + data.template.icon; 387 }, 388 "setPosition": function(data) 389 { 390 var index = data.i + getNumberOfRightPanelButtons(); 346 if (template.icon) 347 data.icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 348 349 let index = data.i + getNumberOfRightPanelButtons(); 391 350 setPanelObjectPosition(data.button, index, data.rowLength); 351 return true; 392 352 } 393 353 }; 394 354 … … 404 364 { 405 365 if (!hasClass(unitEntState, "Unit") || hasClass(unitEntState, "Animal")) 406 366 return []; 407 if (!g_ availableFormations.has(unitEntState.player))408 g_ availableFormations.set(unitEntState.player, Engine.GuiInterfaceCall("GetAvailableFormations", unitEntState.player));409 return g_ availableFormations.get(unitEntState.player);367 if (!g_AvailableFormations.has(unitEntState.player)) 368 g_AvailableFormations.set(unitEntState.player, Engine.GuiInterfaceCall("GetAvailableFormations", unitEntState.player)); 369 return g_AvailableFormations.get(unitEntState.player); 410 370 }, 411 " addData": function(data)371 "setupButton": function(data) 412 372 { 413 if (!g_formationsInfo.has(data.item)) 414 g_formationsInfo.set(data.item, Engine.GuiInterfaceCall("GetFormationInfoFromTemplate", { "templateName": data.item })); 415 data.formationInfo = g_formationsInfo.get(data.item); 416 data.formationOk = canMoveSelectionIntoFormation(data.item); 417 data.formationSelected = Engine.GuiInterfaceCall("IsFormationSelected", { 373 if (!g_FormationsInfo.has(data.item)) 374 g_FormationsInfo.set(data.item, Engine.GuiInterfaceCall("GetFormationInfoFromTemplate", { "templateName": data.item })); 375 376 let formationInfo = g_FormationsInfo.get(data.item); 377 let formationOk = canMoveSelectionIntoFormation(data.item); 378 let formationSelected = Engine.GuiInterfaceCall("IsFormationSelected", { 418 379 "ents": data.selection, 419 380 "formationTemplate": data.item 420 381 }); 421 return true; 422 }, 423 "setAction": function(data) 424 { 382 425 383 data.button.onPress = function() { performFormation(data.unitEntState.id, data.item); }; 426 }, 427 "setTooltip": function(data) 428 { 429 var tooltip = translate(data.formationInfo.name); 430 if (!data.formationOk && data.formationInfo.tooltip) 431 tooltip += "\n" + "[color=\"red\"]" + translate(data.formationInfo.tooltip) + "[/color]"; 384 385 let tooltip = translate(formationInfo.name); 386 if (!formationOk && formationInfo.tooltip) 387 tooltip += "\n" + "[color=\"red\"]" + translate(formationInfo.tooltip) + "[/color]"; 432 388 data.button.tooltip = tooltip; 433 }, 434 "setGraphics": function(data) 435 { 436 data.button.enabled = data.formationOk && controlsPlayer(data.unitEntState.player); 437 var grayscale = data.formationOk ? "" : "grayscale:"; 438 data.guiSelection.hidden = !data.formationSelected; 439 data.icon.sprite = "stretched:"+grayscale+"session/icons/"+data.formationInfo.icon; 389 390 data.button.enabled = formationOk && controlsPlayer(data.unitEntState.player); 391 let grayscale = formationOk ? "" : "grayscale:"; 392 data.guiSelection.hidden = !formationSelected; 393 data.icon.sprite = "stretched:" + grayscale + "session/icons/" + formationInfo.icon; 394 395 setPanelObjectPosition(data.button, data.i, data.rowLength); 396 return true; 440 397 } 441 398 }; 442 399 … … 451 408 { 452 409 if (!unitEntState.garrisonHolder) 453 410 return []; 454 vargroups = new EntityGroups();455 for ( varent of selection)411 let groups = new EntityGroups(); 412 for (let ent of selection) 456 413 { 457 varstate = GetEntityState(ent);414 let state = GetEntityState(ent); 458 415 if (state.garrisonHolder) 459 416 groups.add(state.garrisonHolder.entities); 460 417 } 461 418 return groups.getEntsGrouped(); 462 419 }, 463 " addData": function(data)420 "setupButton": function(data) 464 421 { 465 data.entType = data.item.template; 466 data.template = GetTemplateData(data.entType); 467 if (!data.template) 422 let template = GetTemplateData(data.item.template); 423 if (!template) 468 424 return false; 469 data.name = getEntityNames(data.template); 470 data.count = data.item.ents.length; 471 return true; 472 }, 473 "setAction": function(data) 474 { 425 475 426 data.button.onPress = function() { unloadTemplate(data.item.template); }; 476 }, 477 "setTooltip": function(data) 478 { 479 var tooltip = sprintf(translate("Unload %(name)s"), { "name": data.name }) + "\n"; 427 428 let tooltip = sprintf(translate("Unload %(name)s"), { "name": getEntityNames(template) }) + "\n"; 480 429 tooltip += translate("Single-click to unload 1. Shift-click to unload all of this type."); 481 430 data.button.tooltip = tooltip; 482 }, 483 "setCountDisplay": function(data) 484 { 485 data.countDisplay.caption = data.count || ""; 486 }, 487 "setGraphics": function(data) 488 { 489 var grayscale = ""; 490 var ents = data.item.ents; 491 var entplayer = GetEntityState(ents[0]).player; 431 432 data.countDisplay.caption = data.item.ents.length || ""; 433 434 let grayscale = ""; 435 let ents = data.item.ents; 436 let entplayer = GetEntityState(ents[0]).player; 492 437 data.button.sprite = "color:" + rgbToGuiColor(g_Players[entplayer].color) +":"; 493 438 494 439 if (!controlsPlayer(data.unitEntState.player) && !controlsPlayer(entplayer)) … … 497 442 grayscale = "grayscale:"; 498 443 } 499 444 500 data.icon.sprite = "stretched:" + grayscale + "session/portraits/" + data.template.icon; 445 data.icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 446 447 setPanelObjectPosition(data.button, data.i, data.rowLength); 448 return true; 501 449 } 502 450 }; 503 451 … … 510 458 "getItems": function(unitEntState, selection) 511 459 { 512 460 // Allow long wall pieces to be converted to gates 513 varlongWallTypes = {};514 varwalls = [];515 vargates = [];516 for ( varent of selection)461 let longWallTypes = {}; 462 let walls = []; 463 let gates = []; 464 for (let ent of selection) 517 465 { 518 varstate = GetEntityState(ent);466 let state = GetEntityState(ent); 519 467 if (hasClass(state, "LongWall") && !state.gate && !longWallTypes[state.template]) 520 468 { 521 vargateTemplate = getWallGateTemplate(state.id);469 let gateTemplate = getWallGateTemplate(state.id); 522 470 if (gateTemplate) 523 471 { 524 vartooltipString = GetTemplateDataWithoutLocalization(state.template).gateConversionTooltip;472 let tooltipString = GetTemplateDataWithoutLocalization(state.template).gateConversionTooltip; 525 473 if (!tooltipString) 526 474 { 527 475 warn(state.template + " is supposed to be convertable to a gate, but it's missing the GateConversionTooltip in the Identity template"); … … 554 502 } 555 503 // Show both 'locked' and 'unlocked' as active if the selected gates have both lock states. 556 504 else if (state.gate && state.gate.locked != gates[0].gate.locked) 557 for ( varj = 0; j < gates.length; ++j)505 for (let j = 0; j < gates.length; ++j) 558 506 delete gates[j].gate.locked; 559 507 } 560 508 561 509 // Place wall conversion options after gate lock/unlock icons. 562 var items = gates.concat(walls); 563 return items; 510 return gates.concat(walls); 564 511 }, 565 "set Action": function(data)512 "setupButton": function(data) 566 513 { 567 514 data.button.onPress = function() {data.item.callback(data.item); }; 568 }, 569 "setTooltip": function(data) 570 { 571 var tooltip = data.item.tooltip; 515 516 let tooltip = data.item.tooltip; 572 517 if (data.item.template) 573 518 { 574 519 data.template = GetTemplateData(data.item.template); 575 520 data.wallCount = data.selection.reduce(function (count, ent) { 576 varstate = GetEntityState(ent);521 let state = GetEntityState(ent); 577 522 if (hasClass(state, "LongWall") && !state.gate) 578 523 ++count; 579 524 return count; … … 589 534 tooltip += getNeededResourcesTooltip(data.neededResources); 590 535 } 591 536 data.button.tooltip = tooltip; 592 }, 593 "setGraphics": function(data) 594 { 537 595 538 data.button.enabled = controlsPlayer(data.unitEntState.player); 596 vargateIcon;539 let gateIcon; 597 540 if (data.item.gate) 598 541 { 599 542 // If already a gate, show locking actions … … 606 549 else 607 550 { 608 551 // otherwise show gate upgrade icon 609 vartemplate = GetTemplateData(data.item.template);552 let template = GetTemplateData(data.item.template); 610 553 if (!template) 611 return ;554 return false; 612 555 gateIcon = data.template.icon ? "portraits/" + data.template.icon : "icons/gate_closed.png"; 613 556 data.guiSelection.hidden = true; 614 557 } 615 558 616 559 data.icon.sprite = (data.neededResources ? resourcesToAlphaMask(data.neededResources) + ":" : "") + "stretched:session/" + gateIcon; 617 }, 618 "setPosition": function(data) 619 { 620 var index = data.i + getNumberOfRightPanelButtons(); 560 561 let index = data.i + getNumberOfRightPanelButtons(); 621 562 setPanelObjectPosition(data.button, index, data.rowLength); 563 return true; 622 564 } 623 565 }; 624 566 … … 630 572 }, 631 573 "getItems": function(unitEntState, selection) 632 574 { 633 varchecks = {};634 for ( varent of selection)575 let checks = {}; 576 for (let ent of selection) 635 577 { 636 varstate = GetEntityState(ent);578 let state = GetEntityState(ent); 637 579 if (!state.pack) 638 580 continue; 639 581 if (state.pack.progress == 0) … … 652 594 checks.unpackCancelButton = true; 653 595 } 654 596 } 655 varitems = [];597 let items = []; 656 598 if (checks.packButton) 657 599 items.push({ "packing": false, "packed": false, "tooltip": translate("Pack"), "callback": function() { packUnit(true); } }); 658 600 if (checks.unpackButton) … … 663 605 items.push({ "packing": true, "packed": true, "tooltip": translate("Cancel Unpacking"), "callback": function() { cancelPackUnit(false); } }); 664 606 return items; 665 607 }, 666 "set Action": function(data)608 "setupButton": function(data) 667 609 { 668 610 data.button.onPress = function() {data.item.callback(data.item); }; 669 }, 670 "setTooltip": function(data) 671 { 611 672 612 data.button.tooltip = data.item.tooltip; 673 }, 674 "setGraphics": function(data) 675 { 613 676 614 if (data.item.packing) 677 615 data.icon.sprite = "stretched:session/icons/cancel.png"; 678 616 else if (data.item.packed) … … 681 619 data.icon.sprite = "stretched:session/icons/pack.png"; 682 620 683 621 data.button.enabled = controlsPlayer(data.unitEntState.player); 684 }, 685 "setPosition": function(data) 686 { 687 var index = data.i + getNumberOfRightPanelButtons(); 622 623 let index = data.i + getNumberOfRightPanelButtons(); 688 624 setPanelObjectPosition(data.button, index, data.rowLength); 625 return true; 689 626 } 690 627 }; 691 628 … … 701 638 }, 702 639 "resizePanel": function(numberOfItems, rowLength) 703 640 { 704 varnumRows = Math.ceil(numberOfItems / rowLength);705 varpanel = Engine.GetGUIObjectByName("unitQueuePanel");706 varsize = panel.size;707 varbuttonSize = Engine.GetGUIObjectByName("unitQueueButton[0]").size.bottom;708 varmargin = 4;641 let numRows = Math.ceil(numberOfItems / rowLength); 642 let panel = Engine.GetGUIObjectByName("unitQueuePanel"); 643 let size = panel.size; 644 let buttonSize = Engine.GetGUIObjectByName("unitQueueButton[0]").size.bottom; 645 let margin = 4; 709 646 size.top = size.bottom - numRows*buttonSize - (numRows+2)*margin; 710 647 panel.size = size; 711 648 }, 712 " addData": function(data)649 "setupButton": function(data) 713 650 { 714 651 // differentiate between units and techs 652 let template; 715 653 if (data.item.unitTemplate) 716 { 717 data.entType = data.item.unitTemplate; 718 data.template = GetTemplateData(data.entType); 719 } 654 template = GetTemplateData(data.item.unitTemplate); 720 655 else if (data.item.technologyTemplate) 721 { 722 data.entType = data.item.technologyTemplate; 723 data.template = GetTechnologyData(data.entType); 724 } 725 data.progress = Math.round(data.item.progress*100) + "%"; 656 template = GetTechnologyData(data.item.technologyTemplate); 726 657 727 return data.template; 728 }, 729 "setAction": function(data) 730 { 658 if (!template) 659 return false; 660 731 661 data.button.onPress = function() { removeFromProductionQueue(data.item.producingEnt, data.item.id); }; 732 }, 733 "setTooltip": function(data) 734 { 735 var tooltip = getEntityNames(data.template); 662 663 let tooltip = getEntityNames(template); 736 664 if (data.item.neededSlots) 737 665 { 738 666 tooltip += "\n[color=\"red\"]" + translate("Insufficient population capacity:") + "\n[/color]"; … … 742 670 }); 743 671 } 744 672 data.button.tooltip = tooltip; 745 }, 746 "setCountDisplay": function(data) 747 { 673 748 674 data.countDisplay.caption = data.item.count > 1 ? data.item.count : ""; 749 }, 750 "setProgressDisplay": function(data) 751 { 675 752 676 // show the progress number for the first item 753 677 if (data.i == 0) 754 Engine.GetGUIObjectByName("queueProgress").caption = data.progress;678 Engine.GetGUIObjectByName("queueProgress").caption = Math.round(data.item.progress*100) + "%"; 755 679 756 varguiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider["+data.i+"]");757 varsize = guiObject.size;680 let guiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider["+data.i+"]"); 681 let size = guiObject.size; 758 682 759 683 // Buttons are assumed to be square, so left/right offsets can be used for top/bottom. 760 684 size.top = size.left + Math.round(data.item.progress * (size.right - size.left)); 761 685 guiObject.size = size; 762 },763 "setGraphics": function(data)764 {765 if (data.template.icon)766 data.icon.sprite = "stretched:session/portraits/" + data.template.icon;767 686 687 if (template.icon) 688 data.icon.sprite = "stretched:session/portraits/" + template.icon; 689 768 690 data.button.enabled = controlsPlayer(data.unitEntState.player); 691 692 setPanelObjectPosition(data.button, data.i, data.rowLength); 693 return true; 769 694 } 770 695 }; 771 696 … … 795 720 }, 796 721 "hideItem": function(i, rowLength) // called when no item is found 797 722 { 798 Engine.GetGUIObjectByName("unitResearchButton[" +i+"]").hidden = true;723 Engine.GetGUIObjectByName("unitResearchButton[" + i + "]").hidden = true; 799 724 // We also remove the paired tech and the pair symbol 800 Engine.GetGUIObjectByName("unitResearchButton[" +(i+rowLength)+"]").hidden = true;801 Engine.GetGUIObjectByName("unitResearchPair[" +i+"]").hidden = true;725 Engine.GetGUIObjectByName("unitResearchButton[" + (i + rowLength) + "]").hidden = true; 726 Engine.GetGUIObjectByName("unitResearchPair[" + i + "]").hidden = true; 802 727 }, 803 " addData": function(data)728 "setupButton": function(data) 804 729 { 805 730 if (!data.item.tech) 806 731 { … … 807 732 g_SelectionPanels.Research.hideItem(data.i, data.rowLength); 808 733 return false; 809 734 } 810 data.entType = data.item.tech.pair ? [data.item.tech.top, data.item.tech.bottom] : [data.item.tech]; 811 data.template = data.entType.map(GetTechnologyData); 812 // abort if no template found for any of the techs 813 if (data.template.some(v => !v)) 814 return false; 735 let techs = data.item.tech.pair ? [data.item.tech.bottom, data.item.tech.top] : [data.item.tech]; 815 736 816 for (let template of data.template) 817 for (let res in template.cost) 818 template.cost[res] *= data.item.techCostMultiplier[res]; 737 // start position (start at the bottom) 738 let position = data.i + data.rowLength; 819 739 820 // index one row below 821 var shiftedIndex = data.i + data.rowLength; 822 data.positions = data.item.tech.pair ? [data.i, shiftedIndex] : [shiftedIndex]; 823 data.positionsToHide = data.item.tech.pair ? [] : [data.i]; 740 // only show the top button for pairs 741 if (!data.item.tech.pair) 742 Engine.GetGUIObjectByName("unitResearchButton[" + data.i + "]").hidden = true; 824 743 825 // add top buttons to the data 826 data.button = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchButton["+p+"]")); 827 data.buttonsToHide = data.positionsToHide.map(p => Engine.GetGUIObjectByName("unitResearchButton["+p+"]")); 744 // set up the tech connector 745 let pair = Engine.GetGUIObjectByName("unitResearchPair[" + data.i + "]"); 746 pair.hidden = data.item.tech.pair == null; 747 setPanelObjectPosition(pair, data.i, data.rowLength); 828 748 829 data.icon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchIcon["+p+"]")); 830 data.unchosenIcon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchUnchosenIcon["+p+"]")); 749 // handle one or two techs 750 for (let i in techs) 751 { 752 let tech = techs[i]; 753 let template = GetTechnologyData(tech); 754 if (!template) 755 return false; 831 756 832 data.neededResources = data.template.map(t => Engine.GuiInterfaceCall("GetNeededResources", { 833 "cost": t.cost, 834 "player": data.unitEntState.player 835 })); 757 for (let res in template.cost) 758 template.cost[res] *= data.item.techCostMultiplier[res]; 836 759 837 data.requirementsPassed = data.entType.map(e => Engine.GuiInterfaceCall("CheckTechnologyRequirements", {838 "tech": e,839 "player": data.unitEntState.player840 }));760 let neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 761 "cost": template.cost, 762 "player": data.unitEntState.player 763 }); 841 764 842 data.pair = Engine.GetGUIObjectByName("unitResearchPair["+data.i+"]"); 765 let requirementsPassed = Engine.GuiInterfaceCall("CheckTechnologyRequirements", { 766 "tech": tech, 767 "player": data.unitEntState.player 768 }); 843 769 844 return true; 845 }, 846 "setTooltip": function(data) 847 { 848 for (var i in data.entType) 849 { 850 var tooltip = ""; 851 var template = data.template[i]; 770 let button = Engine.GetGUIObjectByName("unitResearchButton[" + position + "]"); 771 let icon = Engine.GetGUIObjectByName("unitResearchIcon[" + position + "]"); 772 773 let tooltip = ""; 852 774 tooltip = getEntityNamesFormatted(template); 853 775 if (template.tooltip) 854 776 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 855 777 856 778 tooltip += "\n" + getEntityCostTooltip(template); 857 if (! data.requirementsPassed[i])779 if (!requirementsPassed) 858 780 { 859 781 tooltip += "\n" + template.requirementsTooltip; 860 782 if (template.classRequirements) 861 783 { 862 varplayer = data.unitEntState.player;863 varcurrent = GetSimState().players[player].classCounts[template.classRequirements.class] || 0;864 varremaining = template.classRequirements.number - current;784 let player = data.unitEntState.player; 785 let current = GetSimState().players[player].classCounts[template.classRequirements.class] || 0; 786 let remaining = template.classRequirements.number - current; 865 787 tooltip += " " + sprintf(translatePlural("Remaining: %(number)s to build.", "Remaining: %(number)s to build.", remaining), { "number": remaining }); 866 788 } 867 789 } 868 if (data.neededResources[i]) 869 tooltip += getNeededResourcesTooltip(data.neededResources[i]); 870 data.button[i].tooltip = tooltip; 871 } 872 }, 873 "setAction": function(data) 874 { 875 for (var i in data.entType) 876 { 877 // array containing the indices other buttons 878 var others = Object.keys(data.template); 879 others.splice(i, 1); 880 var button = data.button[i]; 881 // as we're in a loop, we need to limit the scope with a closure 882 // else the last value of the loop will be taken, rather than the current one 883 button.onpress = (function(template) { return function () { addResearchToQueue(data.unitEntState.id, template); }; })(data.entType[i]); 884 // on mouse enter, show a cross over the other icons 885 button.onmouseenter = (function(others, icons) { 886 return function() { 887 for (var j of others) 888 icons[j].hidden = false; 790 if (neededResources) 791 tooltip += getNeededResourcesTooltip(neededResources); 792 button.tooltip = tooltip; 793 794 button.onpress = function () { 795 addResearchToQueue(data.unitEntState.id, tech); 796 }; 797 798 if (data.item.tech.pair) 799 { 800 // on mouse enter, show a cross over the other icon 801 let otherPosition = (position + data.rowLength) % (2 * data.rowLength); 802 let unchosenIcon = Engine.GetGUIObjectByName("unitResearchUnchosenIcon[" + otherPosition + "]"); 803 button.onmouseenter = function() { 804 unchosenIcon.hidden = false; 889 805 }; 890 })(others, data.unchosenIcon); 891 button.onmouseleave = (function(others, icons) { 892 return function() { 893 for (var j of others) 894 icons[j].hidden = true; 806 button.onmouseleave = function() { 807 unchosenIcon.hidden = true; 895 808 }; 896 })(others, data.unchosenIcon); 897 } 898 }, 899 "setGraphics": function(data) 900 { 901 for (var i in data.entType) 902 { 903 let button = data.button[i]; 809 } 810 904 811 button.hidden = false; 905 varmodifier = "";906 if (! data.requirementsPassed[i])812 let modifier = ""; 813 if (!requirementsPassed) 907 814 { 908 815 button.enabled = false; 909 modifier += "color: 0 0 0 127:";816 modifier += "color: " + g_GuiColors.limited + ":"; 910 817 modifier += "grayscale:"; 911 818 } 912 else if ( data.neededResources[i])819 else if (neededResources) 913 820 { 914 821 button.enabled = false; 915 modifier += resourcesToAlphaMask( data.neededResources[i]) + ":";822 modifier += resourcesToAlphaMask(neededResources) + ":"; 916 823 } 917 824 else 918 825 button.enabled = controlsPlayer(data.unitEntState.player); 919 826 920 if (data.template[i].icon) 921 data.icon[i].sprite = modifier + "stretched:session/portraits/" + data.template[i].icon; 827 if (template.icon) 828 icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 829 830 setPanelObjectPosition(button, position, data.rowLength); 831 832 // prepare to handle the top button (if any) 833 position -= data.rowLength; 922 834 } 923 for (let button of data.buttonsToHide) 924 button.hidden = true; 925 // show the tech connector 926 data.pair.hidden = data.item.tech.pair == null; 927 }, 928 "setPosition": function(data) 929 { 930 for (var i in data.button) 931 setPanelObjectPosition(data.button[i], data.positions[i], data.rowLength); 932 setPanelObjectPosition(data.pair, data.i, data.rowLength); 835 836 837 return true; 933 838 } 934 839 }; 935 840 … … 946 851 return []; 947 852 return g_Selection.groups.getTemplateNames(); 948 853 }, 949 " addData": function(data)854 "setupButton": function(data) 950 855 { 951 data.entType = data.item; 952 data.template = GetTemplateData(data.entType); 953 if (!data.template) 856 let template = GetTemplateData(data.item); 857 if (!template) 954 858 return false; 955 data.name = getEntityNames(data.template);956 859 957 var ents = g_Selection.groups.getEntsByName(data.item); 958 data.count = ents.length; 959 for (var ent of ents) 860 let ents = g_Selection.groups.getEntsByName(data.item); 861 for (let ent of ents) 960 862 { 961 varstate = GetEntityState(ent);863 let state = GetEntityState(ent); 962 864 963 865 if (state.resourceCarrying && state.resourceCarrying.length !== 0) 964 866 { 965 867 if (!data.carried) 966 868 data.carried = {}; 967 varcarrying = state.resourceCarrying[0];869 let carrying = state.resourceCarrying[0]; 968 870 if (data.carried[carrying.type]) 969 871 data.carried[carrying.type] += carrying.amount; 970 872 else … … 975 877 { 976 878 if (!data.carried) 977 879 data.carried = {}; 978 varamount = state.trader.goods.amount;979 vartype = state.trader.goods.type;980 vartotalGain = amount.traderGain;880 let amount = state.trader.goods.amount; 881 let type = state.trader.goods.type; 882 let totalGain = amount.traderGain; 981 883 if (amount.market1Gain) 982 884 totalGain += amount.market1Gain; 983 885 if (amount.market2Gain) … … 988 890 data.carried[type] = totalGain; 989 891 } 990 892 } 991 return true; 992 }, 993 "setTooltip": function(data) 994 { 995 let tooltip = data.name; 893 894 let tooltip = getEntityNames(template); 996 895 if (data.carried) 997 896 tooltip += "\n" + Object.keys(data.carried).map(res => 998 897 getCostComponentDisplayIcon(res) + data.carried[res] 999 898 ).join(" "); 1000 899 data.button.tooltip = tooltip; 1001 }, 1002 "setCountDisplay": function(data) 1003 { 1004 data.countDisplay.caption = data.count || ""; 1005 }, 1006 "setAction": function(data) 1007 { 900 901 data.countDisplay.caption = ents.length || ""; 902 1008 903 data.button.onpressright = function() { changePrimarySelectionGroup(data.item, true); }; 1009 904 data.button.onpress = function() { changePrimarySelectionGroup(data.item, false); }; 1010 }, 1011 "setGraphics": function(data) 1012 { 1013 if (data.template.icon) 1014 data.icon.sprite = "stretched:session/portraits/" + data.template.icon; 905 906 if (template.icon) 907 data.icon.sprite = "stretched:session/portraits/" + template.icon; 908 909 setPanelObjectPosition(data.button, data.i, data.rowLength); 910 return true; 1015 911 } 1016 912 }; 1017 913 … … 1027 923 return []; 1028 924 return unitEntState.unitAI.possibleStances; 1029 925 }, 1030 " addData": function(data)926 "setupButton": function(data) 1031 927 { 1032 data.stanceSelected = Engine.GuiInterfaceCall("IsStanceSelected", { 928 data.button.onPress = function() { performStance(data.unitEntState, data.item); }; 929 930 data.button.tooltip = getStanceDisplayName(data.item) + "\n" + 931 "[font=\"sans-13\"]" + getStanceTooltip(data.item) + "[/font]"; 932 933 data.guiSelection.hidden = !Engine.GuiInterfaceCall("IsStanceSelected", { 1033 934 "ents": data.selection, 1034 935 "stance": data.item 1035 936 }); 937 data.icon.sprite = "stretched:session/icons/stances/" + data.item + ".png"; 938 data.button.enabled = controlsPlayer(data.unitEntState.player); 939 940 setPanelObjectPosition(data.button, data.i, data.rowLength); 1036 941 return true; 1037 },1038 "setAction": function(data)1039 {1040 data.button.onPress = function() { performStance(data.unitEntState, data.item); };1041 },1042 "setTooltip": function(data)1043 {1044 data.button.tooltip = getStanceDisplayName(data.item) + "\n[font=\"sans-13\"]" + getStanceTooltip(data.item) + "[/font]";1045 },1046 "setGraphics": function(data)1047 {1048 data.guiSelection.hidden = !data.stanceSelected;1049 data.icon.sprite = "stretched:session/icons/stances/"+data.item+".png";1050 data.button.enabled = controlsPlayer(data.unitEntState.player);1051 942 } 1052 943 }; 1053 944 … … 1061 952 { 1062 953 return getAllTrainableEntitiesFromSelection(); 1063 954 }, 1064 " addData": function(data)955 "setupButton": function(data) 1065 956 { 1066 data.entType = data.item; 1067 data.template = GetTemplateData(data.entType); 1068 if (!data.template) 957 let template = GetTemplateData(data.item); 958 if (!template) 1069 959 return false; 1070 960 1071 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", {1072 "tech": data.template.requiredTechnology,961 let technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 962 "tech": template.requiredTechnology, 1073 963 "player": data.unitEntState.player 1074 964 }); 1075 965 1076 var[buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] =1077 getTrainingBatchStatus(data.playerState, data.unitEntState.id, data. entType, data.selection);966 let [buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] = 967 getTrainingBatchStatus(data.playerState, data.unitEntState.id, data.item, data.selection); 1078 968 1079 data.buildingsCountToTrainFullBatch = buildingsCountToTrainFullBatch; 1080 data.fullBatchSize = fullBatchSize; 1081 data.remainderBatch = remainderBatch; 1082 1083 data.trainNum = buildingsCountToTrainFullBatch || 1; // train at least one unit 969 let trainNum = buildingsCountToTrainFullBatch || 1; 1084 970 if (Engine.HotkeyIsPressed("session.batchtrain")) 1085 data.trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch;971 trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch; 1086 972 1087 if (data.template.cost) 1088 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 1089 "cost": multiplyEntityCosts(data.template, data.trainNum), 973 let neededResources; 974 if (template.cost) 975 neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 976 "cost": multiplyEntityCosts(template, trainNum), 1090 977 "player": data.unitEntState.player 1091 978 }); 1092 979 1093 return true;1094 },1095 "setAction": function(data)1096 {1097 980 data.button.onPress = function() { addTrainingToQueue(data.selection, data.item, data.playerState); }; 1098 }, 1099 "setCountDisplay": function(data) 1100 { 1101 data.countDisplay.caption = data.trainNum > 1 ? data.trainNum : ""; 1102 }, 1103 "setTooltip": function(data) 1104 { 1105 var tooltip = ""; 1106 var key = Engine.ConfigDB_GetValue("user", "hotkey.session.queueunit." + (data.i + 1)); 981 982 data.countDisplay.caption = trainNum > 1 ? trainNum : ""; 983 984 let tooltip = ""; 985 let key = Engine.ConfigDB_GetValue("user", "hotkey.session.queueunit." + (data.i + 1)); 1107 986 if (key) 1108 tooltip += "[color=\"255 251 131\"][font=\"sans-bold-16\"]\\[" + key + "][/font][/color] ";987 tooltip += colorizeText(g_GuiColors.hotkey, "[font=\"sans-bold-16\"]\\[" + key + "][/font] "); 1109 988 1110 tooltip += getEntityNamesFormatted( data.template);1111 tooltip += getVisibleEntityClassesFormatted( data.template);1112 tooltip += getAurasTooltip( data.template);989 tooltip += getEntityNamesFormatted(template); 990 tooltip += getVisibleEntityClassesFormatted(template); 991 tooltip += getAurasTooltip(template); 1113 992 1114 if ( data.template.tooltip)1115 tooltip += "\n[font=\"sans-13\"]" + data.template.tooltip + "[/font]";993 if (template.tooltip) 994 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 1116 995 1117 tooltip += "\n" + getEntityCostTooltip( data.template, data.trainNum, data.unitEntState.id);996 tooltip += "\n" + getEntityCostTooltip(template, trainNum, data.unitEntState.id); 1118 997 1119 data.limits = getEntityLimitAndCount(data.playerState, data.entType);998 let limits = getEntityLimitAndCount(data.playerState, data.item); 1120 999 1121 tooltip += formatLimitString( data.limits.entLimit, data.limits.entCount, data.limits.entLimitChangers);1122 if (Engine.ConfigDB_GetValue("user", "showdetailedtooltips") == ="true")1000 tooltip += formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers); 1001 if (Engine.ConfigDB_GetValue("user", "showdetailedtooltips") == "true") 1123 1002 { 1124 if ( data.template.health)1125 tooltip += "\n[font=\"sans-bold-13\"]" + translate("Health:") + "[/font] " + data.template.health;1126 if ( data.template.attack)1127 tooltip += "\n" + getAttackTooltip( data.template);1128 if ( data.template.armour)1129 tooltip += "\n" + getArmorTooltip( data.template.armour);1130 if ( data.template.speed)1131 tooltip += "\n" + getSpeedTooltip( data.template);1003 if (template.health) 1004 tooltip += "\n[font=\"sans-bold-13\"]" + translate("Health:") + "[/font] " + template.health; 1005 if (template.attack) 1006 tooltip += "\n" + getAttackTooltip(template); 1007 if (template.armour) 1008 tooltip += "\n" + getArmorTooltip(template.armour); 1009 if (template.speed) 1010 tooltip += "\n" + getSpeedTooltip(template); 1132 1011 } 1133 tooltip += "[color=\"255 251 131\"]" + formatBatchTrainingString(data.buildingsCountToTrainFullBatch, data.fullBatchSize, data.remainderBatch) + "[/color]";1134 if (! data.technologyEnabled)1012 tooltip += colorizeText(g_GuiColors.hotkey, formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch)); 1013 if (!technologyEnabled) 1135 1014 { 1136 var techName = getEntityNames(GetTechnologyData(data.template.requiredTechnology));1015 let techName = getEntityNames(GetTechnologyData(template.requiredTechnology)); 1137 1016 tooltip += "\n" + sprintf(translate("Requires %(technology)s"), { "technology": techName }); 1138 1017 } 1139 if ( data.neededResources)1140 tooltip += getNeededResourcesTooltip( data.neededResources);1018 if (neededResources) 1019 tooltip += getNeededResourcesTooltip(neededResources); 1141 1020 1142 1021 data.button.tooltip = tooltip; 1143 }, 1144 // disable and enable buttons in the same way as when you do for the construction 1145 "setGraphics": g_SelectionPanels.Construction.setGraphics, 1146 "setPosition": function(data) 1147 { 1148 var index = data.i + getNumberOfRightPanelButtons(); 1022 1023 let modifier = ""; 1024 if (!technologyEnabled || limits.canBeAddedCount == 0) 1025 { 1026 data.button.enabled = false; 1027 modifier += "color: " + g_GuiColors.limited + ":grayscale:"; 1028 } 1029 else if (neededResources) 1030 { 1031 data.button.enabled = false; 1032 modifier += resourcesToAlphaMask(neededResources) +":"; 1033 } 1034 else 1035 data.button.enabled = controlsPlayer(data.unitEntState.player); 1036 1037 if (template.icon) 1038 data.icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 1039 1040 let index = data.i + getNumberOfRightPanelButtons(); 1149 1041 setPanelObjectPosition(data.button, index, data.rowLength); 1042 return true; 1150 1043 } 1151 1044 }; 1152 1045 … … 1158 1051 * 1159 1052 * Note that the panel needs to appear in the list to get rendered. 1160 1053 */ 1161 varg_PanelsOrder = [1054 let g_PanelsOrder = [ 1162 1055 // LEFT PANE 1163 1056 "Barter", // must always be visible on markets 1164 1057 "Garrison", // more important than Formation, as you want to see the garrisoned units in ships -
binaries/data/mods/public/gui/session/unit_commands.js
40 40 } 41 41 let selection = g_Selection.toList(); 42 42 43 varitems = g_SelectionPanels[guiName].getItems(unitEntState, selection);43 let items = g_SelectionPanels[guiName].getItems(unitEntState, selection); 44 44 45 45 if (!items || !items.length) 46 46 return; 47 47 48 var numberOfItems = items.length; 49 var garrisonGroups = new EntityGroups(); 48 let numberOfItems = items.length; 50 49 51 50 // Determine how many buttons there should be 52 varmaxNumberOfItems = g_SelectionPanels[guiName].getMaxNumberOfItems();51 let maxNumberOfItems = g_SelectionPanels[guiName].getMaxNumberOfItems(); 53 52 if (maxNumberOfItems < numberOfItems) 54 53 numberOfItems = maxNumberOfItems; 55 54 56 varrowLength = g_SelectionPanels[guiName].rowLength || 8;55 let rowLength = g_SelectionPanels[guiName].rowLength || 8; 57 56 58 57 if (g_SelectionPanels[guiName].resizePanel) 59 58 g_SelectionPanels[guiName].resizePanel(numberOfItems, rowLength); … … 61 60 // Make buttons 62 61 for (let i = 0; i < numberOfItems; ++i) 63 62 { 64 var item = items[i];65 66 63 // STANDARD DATA 67 64 // add standard data 68 vardata = {65 let data = { 69 66 "i": i, 70 "item": item ,67 "item": items[i], 71 68 "selection": selection, 72 69 "playerState": playerState, 73 70 "unitEntState": unitEntState, … … 92 89 data.button.caption = ""; 93 90 } 94 91 95 // GENERAL DATA96 // add general data, and a chance to abort on faulty data97 if (g_SelectionPanels[guiName].addData)98 {99 var success = g_SelectionPanels[guiName].addData(data);100 if (!success)101 continue; // ignore faulty data102 }103 104 92 // SET CONTENT 105 // run all content setters 106 for (var f in g_SelectionPanels[guiName]) 107 { 108 if (f.match(/^set/)) 109 g_SelectionPanels[guiName][f](data); 110 } 93 if (g_SelectionPanels[guiName].setupButton) 94 if (!g_SelectionPanels[guiName].setupButton(data)) 95 continue; 111 96 112 // Special case: position113 if (!g_SelectionPanels[guiName].setPosition)114 setPanelObjectPosition(data.button, i, rowLength);115 116 97 // TODO: we should require all entities to have icons, so this case never occurs 117 98 if (data.icon && !data.icon.sprite) 118 99 data.icon.sprite = "bkFillBlack";