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