Ticket #4007: selection_panels_cleanup.3.diff
File selection_panels_cleanup.3.diff, 48.9 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 … … 21 21 * "icon": gui Icon object 22 22 * "guiSelection": gui button Selection overlay 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 /* cache some formation info */ 40 var g_availableFormations = new Map(); // available formations per player 41 var g_formationsInfo = new Map(); 30 // Cache some formation info 31 // Available formations per player 32 let g_AvailableFormations = new Map(); 33 let g_FormationsInfo = new Map(); 42 34 43 varg_SelectionPanels = {};35 let g_SelectionPanels = {}; 44 36 45 37 // ALERT 46 38 g_SelectionPanels.Alert = { … … 54 46 return []; 55 47 return ["increase", "end"]; 56 48 }, 57 "set Action": function(data)49 "setupButton": function(data) 58 50 { 59 51 data.button.onPress = function() { 60 52 if (data.item == "increase") … … 62 54 else if (data.item == "end") 63 55 endOfAlert(); 64 56 }; 65 }, 66 "setTooltip": function(data) 67 { 57 68 58 if (data.item == "increase") 69 59 { 70 60 if (data.unitEntState.alertRaiser.hasRaisedAlert) … … 74 64 } 75 65 else if (data.item == "end") 76 66 data.button.tooltip = translate("End of alert."); 77 }, 78 "setGraphics": function(data) 79 { 67 80 68 if (data.item == "increase") 81 69 { 82 70 data.button.hidden = !data.unitEntState.alertRaiser.canIncreaseLevel; … … 91 79 data.icon.sprite = "stretched:session/icons/bell_level0.png"; 92 80 } 93 81 data.button.enabled = !data.button.hidden && controlsPlayer(data.unitEntState.player); 82 83 setPanelObjectPosition(data.button, data.i, data.rowLength); 84 return true; 94 85 } 95 86 }; 96 87 … … 108 99 // ["food", "wood", "stone", "metal"] 109 100 return BARTER_RESOURCES; 110 101 }, 111 " addData": function(data)102 "setupButton": function(data) 112 103 { 113 104 // data.item is the resource name in this case 114 data.button = {};115 data.icon = {};116 data.amount = {};117 for ( vara of BARTER_ACTIONS)105 let button = {}; 106 let icon = {}; 107 let amount = {}; 108 for (let a of BARTER_ACTIONS) 118 109 { 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+"]");110 button[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Button[" + data.i + "]"); 111 icon[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Icon[" + data.i + "]"); 112 amount[a] = Engine.GetGUIObjectByName("unitBarter" + a + "Amount[" + data.i + "]"); 122 113 } 123 data.selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection["+data.i+"]");114 let selectionIcon = Engine.GetGUIObjectByName("unitBarterSellSelection[" + data.i + "]"); 124 115 125 data.amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL;116 let amountToSell = BARTER_RESOURCE_AMOUNT_TO_SELL; 126 117 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 = { 118 amountToSell *= BARTER_BUNCH_MULTIPLIER; 119 120 amount.Sell.caption = "-" + amountToSell; 121 let sellPrice = data.unitEntState.barterMarket.prices.sell[g_barterSell]; 122 let buyPrice = data.unitEntState.barterMarket.prices.buy[data.item]; 123 amount.Buy.caption = "+" + Math.round(sellPrice / buyPrice * amountToSell); 124 125 let resource = getLocalizedResourceName(data.item, "withinSentence"); 126 button.Buy.tooltip = sprintf(translate("Buy %(resource)s"), { "resource": resource }); 127 button.Sell.tooltip = sprintf(translate("Sell %(resource)s"), { "resource": resource }); 128 129 button.Sell.onPress = function() { g_barterSell = data.item; }; 130 let exchangeResourcesParameters = { 148 131 "sell": g_barterSell, 149 132 "buy": data.item, 150 "amount": data.amountToSell133 "amount": amountToSell 151 134 }; 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:" : ""; 135 button.Buy.onPress = function() { exchangeResources(exchangeResourcesParameters); }; 157 136 137 let isSelected = data.item == g_barterSell; 138 let grayscale = isSelected ? "color: 0 0 0 100:grayscale:" : ""; 139 158 140 // do we have enough of this resource to sell? 159 varneededRes = {};160 neededRes[data.item] = data.amountToSell;161 varcanSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", {141 let neededRes = {}; 142 neededRes[data.item] = amountToSell; 143 let canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", { 162 144 "cost": neededRes, 163 145 "player": data.unitEntState.player 164 146 }) ? "color:255 0 0 80:" : ""; … … 165 147 166 148 // Let's see if we have enough resources to barter. 167 149 neededRes = {}; 168 neededRes[g_barterSell] = data.amountToSell;169 varcanBuyAny = Engine.GuiInterfaceCall("GetNeededResources", {150 neededRes[g_barterSell] = amountToSell; 151 let canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", { 170 152 "cost": neededRes, 171 153 "player": data.unitEntState.player 172 154 }) ? "color:255 0 0 80:" : ""; 173 155 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";156 icon.Sell.sprite = canSellCurrent + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png"; 157 icon.Buy.sprite = canBuyAny + "stretched:" + grayscale + "session/icons/resources/" + data.item + ".png"; 176 158 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); 159 button.Buy.hidden = isSelected; 160 button.Buy.enabled = controlsPlayer(data.unitEntState.player); 161 button.Sell.hidden = false; 162 selectionIcon.hidden = !isSelected; 163 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 setPanelObjectPosition(data.button, data.i, data.rowLength); 269 return true; 301 270 } 302 271 }; 303 272 … … 311 280 { 312 281 return getAllBuildableEntitiesFromSelection(); 313 282 }, 314 " addData": function(data)283 "setupButton": function(data) 315 284 { 316 data.entType = data.item; 317 data.template = GetTemplateData(data.entType); 318 if (!data.template) // abort if no template 285 let template = GetTemplateData(data.item); 286 if (!template) 319 287 return false; 320 288 321 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", {322 "tech": data.template.requiredTechnology,289 let technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 290 "tech": template.requiredTechnology, 323 291 "player": data.unitEntState.player 324 292 }); 325 293 326 if (data.template.cost) 327 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 328 "cost": multiplyEntityCosts(data.template, 1), 294 let neededResources; 295 if (template.cost) 296 neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 297 "cost": multiplyEntityCosts(template, 1), 329 298 "player": data.unitEntState.player 330 299 }); 331 300 332 data.limits = getEntityLimitAndCount(data.playerState, data.entType);301 let limits = getEntityLimitAndCount(data.playerState, data.item); 333 302 334 if ( data.template.wallSet)335 data.template.auras = GetTemplateData(data.template.wallSet.templates.long).auras;303 if (template.wallSet) 304 template.auras = GetTemplateData(template.wallSet.templates.long).auras; 336 305 337 return true;338 },339 "setAction": function(data)340 {341 306 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 307 349 if (data.template.tooltip) 350 tooltip += "\n[font=\"sans-13\"]" + data.template.tooltip + "[/font]"; 308 let tooltip = getEntityNamesFormatted(template); 309 tooltip += getVisibleEntityClassesFormatted(template); 310 tooltip += getAurasTooltip(template); 351 311 352 tooltip += "\n" + getEntityCostTooltip(data.template);353 tooltip += getPopulationBonusTooltip(data.template);312 if (template.tooltip) 313 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 354 314 355 tooltip += formatLimitString(data.limits.entLimit, data.limits.entCount, data.limits.entLimitChangers); 315 tooltip += "\n" + getEntityCostTooltip(template); 316 tooltip += getPopulationBonusTooltip(template); 356 317 357 if (!data.technologyEnabled) 318 tooltip += formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers); 319 320 if (!technologyEnabled) 358 321 tooltip += "\n" + sprintf(translate("Requires %(technology)s"), { 359 "technology": getEntityNames(GetTechnologyData( data.template.requiredTechnology))322 "technology": getEntityNames(GetTechnologyData(template.requiredTechnology)) 360 323 }); 361 324 362 if ( data.neededResources)363 tooltip += getNeededResourcesTooltip( data.neededResources);325 if (neededResources) 326 tooltip += getNeededResourcesTooltip(neededResources); 364 327 365 328 data.button.tooltip = tooltip; 366 return true; 367 }, 368 "setGraphics": function(data) 369 { 370 var modifier = ""; 371 if (!data.technologyEnabled || data.limits.canBeAddedCount == 0) 329 330 let modifier = ""; 331 if (!technologyEnabled || limits.canBeAddedCount == 0) 372 332 { 373 333 data.button.enabled = false; 374 modifier += "color: 0 0 0 127:"; 375 modifier += "grayscale:"; 334 modifier += "color:0 0 0 127:grayscale:"; 376 335 } 377 else if ( data.neededResources)336 else if (neededResources) 378 337 { 379 338 data.button.enabled = false; 380 modifier += resourcesToAlphaMask( data.neededResources) +":";339 modifier += resourcesToAlphaMask(neededResources) +":"; 381 340 } 382 341 else 383 342 data.button.enabled = controlsPlayer(data.unitEntState.player); 384 343 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(); 344 if (template.icon) 345 data.icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 346 347 let index = data.i + getNumberOfRightPanelButtons(); 391 348 setPanelObjectPosition(data.button, index, data.rowLength); 349 return true; 392 350 } 393 351 }; 394 352 … … 404 362 { 405 363 if (!hasClass(unitEntState, "Unit") || hasClass(unitEntState, "Animal")) 406 364 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);365 if (!g_AvailableFormations.has(unitEntState.player)) 366 g_AvailableFormations.set(unitEntState.player, Engine.GuiInterfaceCall("GetAvailableFormations", unitEntState.player)); 367 return g_AvailableFormations.get(unitEntState.player); 410 368 }, 411 " addData": function(data)369 "setupButton": function(data) 412 370 { 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", { 371 if (!g_FormationsInfo.has(data.item)) 372 g_FormationsInfo.set(data.item, Engine.GuiInterfaceCall("GetFormationInfoFromTemplate", { "templateName": data.item })); 373 374 let formationInfo = g_FormationsInfo.get(data.item); 375 let formationOk = canMoveSelectionIntoFormation(data.item); 376 let formationSelected = Engine.GuiInterfaceCall("IsFormationSelected", { 418 377 "ents": data.selection, 419 378 "formationTemplate": data.item 420 379 }); 421 return true; 422 }, 423 "setAction": function(data) 424 { 380 425 381 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]"; 382 383 let tooltip = translate(formationInfo.name); 384 if (!formationOk && formationInfo.tooltip) 385 tooltip += "\n" + "[color=\"red\"]" + translate(formationInfo.tooltip) + "[/color]"; 432 386 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; 387 388 data.button.enabled = formationOk && controlsPlayer(data.unitEntState.player); 389 let grayscale = formationOk ? "" : "grayscale:"; 390 data.guiSelection.hidden = !formationSelected; 391 data.icon.sprite = "stretched:" + grayscale + "session/icons/" + formationInfo.icon; 392 393 setPanelObjectPosition(data.button, data.i, data.rowLength); 394 return true; 440 395 } 441 396 }; 442 397 … … 451 406 { 452 407 if (!unitEntState.garrisonHolder) 453 408 return []; 454 vargroups = new EntityGroups();455 for ( varent of selection)409 let groups = new EntityGroups(); 410 for (let ent of selection) 456 411 { 457 varstate = GetEntityState(ent);412 let state = GetEntityState(ent); 458 413 if (state.garrisonHolder) 459 414 groups.add(state.garrisonHolder.entities); 460 415 } 461 416 return groups.getEntsGrouped(); 462 417 }, 463 " addData": function(data)418 "setupButton": function(data) 464 419 { 465 data.entType = data.item.template; 466 data.template = GetTemplateData(data.entType); 467 if (!data.template) 420 let template = GetTemplateData(data.item.template); 421 if (!template) 468 422 return false; 469 data.name = getEntityNames(data.template); 470 data.count = data.item.ents.length; 471 return true; 472 }, 473 "setAction": function(data) 474 { 423 475 424 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"; 425 426 let tooltip = sprintf(translate("Unload %(name)s"), { "name": getEntityNames(template) }) + "\n"; 480 427 tooltip += translate("Single-click to unload 1. Shift-click to unload all of this type."); 481 428 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; 429 430 data.countDisplay.caption = data.item.ents.length || ""; 431 432 let grayscale = ""; 433 let ents = data.item.ents; 434 let entplayer = GetEntityState(ents[0]).player; 492 435 data.button.sprite = "color:" + rgbToGuiColor(g_Players[entplayer].color) +":"; 493 436 494 437 if (!controlsPlayer(data.unitEntState.player) && !controlsPlayer(entplayer)) … … 497 440 grayscale = "grayscale:"; 498 441 } 499 442 500 data.icon.sprite = "stretched:" + grayscale + "session/portraits/" + data.template.icon; 443 data.icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 444 445 setPanelObjectPosition(data.button, data.i, data.rowLength); 446 return true; 501 447 } 502 448 }; 503 449 … … 510 456 "getItems": function(unitEntState, selection) 511 457 { 512 458 // Allow long wall pieces to be converted to gates 513 varlongWallTypes = {};514 varwalls = [];515 vargates = [];516 for ( varent of selection)459 let longWallTypes = {}; 460 let walls = []; 461 let gates = []; 462 for (let ent of selection) 517 463 { 518 varstate = GetEntityState(ent);464 let state = GetEntityState(ent); 519 465 if (hasClass(state, "LongWall") && !state.gate && !longWallTypes[state.template]) 520 466 { 521 vargateTemplate = getWallGateTemplate(state.id);467 let gateTemplate = getWallGateTemplate(state.id); 522 468 if (gateTemplate) 523 469 { 524 vartooltipString = GetTemplateDataWithoutLocalization(state.template).gateConversionTooltip;470 let tooltipString = GetTemplateDataWithoutLocalization(state.template).gateConversionTooltip; 525 471 if (!tooltipString) 526 472 { 527 473 warn(state.template + " is supposed to be convertable to a gate, but it's missing the GateConversionTooltip in the Identity template"); … … 554 500 } 555 501 // Show both 'locked' and 'unlocked' as active if the selected gates have both lock states. 556 502 else if (state.gate && state.gate.locked != gates[0].gate.locked) 557 for ( varj = 0; j < gates.length; ++j)503 for (let j = 0; j < gates.length; ++j) 558 504 delete gates[j].gate.locked; 559 505 } 560 506 561 507 // Place wall conversion options after gate lock/unlock icons. 562 var items = gates.concat(walls); 563 return items; 508 return gates.concat(walls); 564 509 }, 565 "set Action": function(data)510 "setupButton": function(data) 566 511 { 567 512 data.button.onPress = function() {data.item.callback(data.item); }; 568 }, 569 "setTooltip": function(data) 570 { 571 var tooltip = data.item.tooltip; 513 514 let tooltip = data.item.tooltip; 572 515 if (data.item.template) 573 516 { 574 517 data.template = GetTemplateData(data.item.template); 575 518 data.wallCount = data.selection.reduce(function (count, ent) { 576 varstate = GetEntityState(ent);519 let state = GetEntityState(ent); 577 520 if (hasClass(state, "LongWall") && !state.gate) 578 521 ++count; 579 522 return count; … … 589 532 tooltip += getNeededResourcesTooltip(data.neededResources); 590 533 } 591 534 data.button.tooltip = tooltip; 592 }, 593 "setGraphics": function(data) 594 { 535 595 536 data.button.enabled = controlsPlayer(data.unitEntState.player); 596 vargateIcon;537 let gateIcon; 597 538 if (data.item.gate) 598 539 { 599 540 // If already a gate, show locking actions … … 605 546 } 606 547 else 607 548 { 608 // otherwise show gate upgrade icon609 vartemplate = GetTemplateData(data.item.template);549 // Otherwise show gate upgrade icon 550 let template = GetTemplateData(data.item.template); 610 551 if (!template) 611 return ;552 return false; 612 553 gateIcon = data.template.icon ? "portraits/" + data.template.icon : "icons/gate_closed.png"; 613 554 data.guiSelection.hidden = true; 614 555 } 615 556 616 557 data.icon.sprite = (data.neededResources ? resourcesToAlphaMask(data.neededResources) + ":" : "") + "stretched:session/" + gateIcon; 617 }, 618 "setPosition": function(data) 619 { 620 var index = data.i + getNumberOfRightPanelButtons(); 558 559 let index = data.i + getNumberOfRightPanelButtons(); 621 560 setPanelObjectPosition(data.button, index, data.rowLength); 561 return true; 622 562 } 623 563 }; 624 564 … … 630 570 }, 631 571 "getItems": function(unitEntState, selection) 632 572 { 633 varchecks = {};634 for ( varent of selection)573 let checks = {}; 574 for (let ent of selection) 635 575 { 636 varstate = GetEntityState(ent);576 let state = GetEntityState(ent); 637 577 if (!state.pack) 638 578 continue; 639 579 if (state.pack.progress == 0) … … 652 592 checks.unpackCancelButton = true; 653 593 } 654 594 } 655 varitems = [];595 let items = []; 656 596 if (checks.packButton) 657 597 items.push({ "packing": false, "packed": false, "tooltip": translate("Pack"), "callback": function() { packUnit(true); } }); 658 598 if (checks.unpackButton) … … 663 603 items.push({ "packing": true, "packed": true, "tooltip": translate("Cancel Unpacking"), "callback": function() { cancelPackUnit(false); } }); 664 604 return items; 665 605 }, 666 "set Action": function(data)606 "setupButton": function(data) 667 607 { 668 608 data.button.onPress = function() {data.item.callback(data.item); }; 669 }, 670 "setTooltip": function(data) 671 { 609 672 610 data.button.tooltip = data.item.tooltip; 673 }, 674 "setGraphics": function(data) 675 { 611 676 612 if (data.item.packing) 677 613 data.icon.sprite = "stretched:session/icons/cancel.png"; 678 614 else if (data.item.packed) … … 681 617 data.icon.sprite = "stretched:session/icons/pack.png"; 682 618 683 619 data.button.enabled = controlsPlayer(data.unitEntState.player); 684 }, 685 "setPosition": function(data) 686 { 687 var index = data.i + getNumberOfRightPanelButtons(); 620 621 let index = data.i + getNumberOfRightPanelButtons(); 688 622 setPanelObjectPosition(data.button, index, data.rowLength); 623 return true; 689 624 } 690 625 }; 691 626 … … 701 636 }, 702 637 "resizePanel": function(numberOfItems, rowLength) 703 638 { 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;639 let numRows = Math.ceil(numberOfItems / rowLength); 640 let panel = Engine.GetGUIObjectByName("unitQueuePanel"); 641 let size = panel.size; 642 let buttonSize = Engine.GetGUIObjectByName("unitQueueButton[0]").size.bottom; 643 let margin = 4; 709 644 size.top = size.bottom - numRows*buttonSize - (numRows+2)*margin; 710 645 panel.size = size; 711 646 }, 712 " addData": function(data)647 "setupButton": function(data) 713 648 { 714 // differentiate between units and techs 649 // Differentiate between units and techs 650 let template; 715 651 if (data.item.unitTemplate) 716 { 717 data.entType = data.item.unitTemplate; 718 data.template = GetTemplateData(data.entType); 719 } 652 template = GetTemplateData(data.item.unitTemplate); 720 653 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) + "%"; 654 template = GetTechnologyData(data.item.technologyTemplate); 726 655 727 return data.template; 728 }, 729 "setAction": function(data) 730 { 656 if (!template) 657 return false; 658 731 659 data.button.onPress = function() { removeFromProductionQueue(data.item.producingEnt, data.item.id); }; 732 }, 733 "setTooltip": function(data) 734 { 735 var tooltip = getEntityNames(data.template); 660 661 let tooltip = getEntityNames(template); 736 662 if (data.item.neededSlots) 737 663 { 738 664 tooltip += "\n[color=\"red\"]" + translate("Insufficient population capacity:") + "\n[/color]"; … … 742 668 }); 743 669 } 744 670 data.button.tooltip = tooltip; 745 }, 746 "setCountDisplay": function(data) 747 { 671 748 672 data.countDisplay.caption = data.item.count > 1 ? data.item.count : ""; 749 }, 750 "setProgressDisplay": function(data) 751 { 752 // show the progress number for the first item 673 674 // Show the progress number for the first item 753 675 if (data.i == 0) 754 Engine.GetGUIObjectByName("queueProgress").caption = data.progress;676 Engine.GetGUIObjectByName("queueProgress").caption = Math.round(data.item.progress*100) + "%"; 755 677 756 varguiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider["+data.i+"]");757 varsize = guiObject.size;678 let guiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider["+data.i+"]"); 679 let size = guiObject.size; 758 680 759 681 // Buttons are assumed to be square, so left/right offsets can be used for top/bottom. 760 682 size.top = size.left + Math.round(data.item.progress * (size.right - size.left)); 761 683 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 684 685 if (template.icon) 686 data.icon.sprite = "stretched:session/portraits/" + template.icon; 687 768 688 data.button.enabled = controlsPlayer(data.unitEntState.player); 689 690 setPanelObjectPosition(data.button, data.i, data.rowLength); 691 return true; 769 692 } 770 693 }; 771 694 … … 793 716 } 794 717 return []; 795 718 }, 796 "hideItem": function(i, rowLength) // called when no item is found719 "hideItem": function(i, rowLength) // Called when no item is found 797 720 { 798 Engine.GetGUIObjectByName("unitResearchButton[" +i+"]").hidden = true;721 Engine.GetGUIObjectByName("unitResearchButton[" + i + "]").hidden = true; 799 722 // 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;723 Engine.GetGUIObjectByName("unitResearchButton[" + (i + rowLength) + "]").hidden = true; 724 Engine.GetGUIObjectByName("unitResearchPair[" + i + "]").hidden = true; 802 725 }, 803 " addData": function(data)726 "setupButton": function(data) 804 727 { 805 728 if (!data.item.tech) 806 729 { … … 807 730 g_SelectionPanels.Research.hideItem(data.i, data.rowLength); 808 731 return false; 809 732 } 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; 733 let techs = data.item.tech.pair ? [data.item.tech.bottom, data.item.tech.top] : [data.item.tech]; 815 734 816 for (let template of data.template) 817 for (let res in template.cost) 818 template.cost[res] *= data.item.techCostMultiplier[res]; 735 // Start position (start at the bottom) 736 let position = data.i + data.rowLength; 819 737 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]; 738 // Only show the top button for pairs 739 if (!data.item.tech.pair) 740 Engine.GetGUIObjectByName("unitResearchButton[" + data.i + "]").hidden = true; 824 741 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+"]")); 742 // Set up the tech connector 743 let pair = Engine.GetGUIObjectByName("unitResearchPair[" + data.i + "]"); 744 pair.hidden = data.item.tech.pair == null; 745 setPanelObjectPosition(pair, data.i, data.rowLength); 828 746 829 data.icon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchIcon["+p+"]")); 830 data.unchosenIcon = data.positions.map(p => Engine.GetGUIObjectByName("unitResearchUnchosenIcon["+p+"]")); 747 // Handle one or two techs 748 for (let i in techs) 749 { 750 let tech = techs[i]; 751 let template = GetTechnologyData(tech); 752 if (!template) 753 return false; 831 754 832 data.neededResources = data.template.map(t => Engine.GuiInterfaceCall("GetNeededResources", { 833 "cost": t.cost, 834 "player": data.unitEntState.player 835 })); 755 for (let res in template.cost) 756 template.cost[res] *= data.item.techCostMultiplier[res]; 836 757 837 data.requirementsPassed = data.entType.map(e => Engine.GuiInterfaceCall("CheckTechnologyRequirements", {838 "tech": e,839 "player": data.unitEntState.player840 }));758 let neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 759 "cost": template.cost, 760 "player": data.unitEntState.player 761 }); 841 762 842 data.pair = Engine.GetGUIObjectByName("unitResearchPair["+data.i+"]"); 763 let requirementsPassed = Engine.GuiInterfaceCall("CheckTechnologyRequirements", { 764 "tech": tech, 765 "player": data.unitEntState.player 766 }); 843 767 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]; 852 tooltip = getEntityNamesFormatted(template); 768 let button = Engine.GetGUIObjectByName("unitResearchButton[" + position + "]"); 769 let icon = Engine.GetGUIObjectByName("unitResearchIcon[" + position + "]"); 770 771 let tooltip = getEntityNamesFormatted(template); 853 772 if (template.tooltip) 854 773 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 855 774 856 775 tooltip += "\n" + getEntityCostTooltip(template); 857 if (! data.requirementsPassed[i])776 if (!requirementsPassed) 858 777 { 859 778 tooltip += "\n" + template.requirementsTooltip; 860 779 if (template.classRequirements) 861 780 { 862 varplayer = data.unitEntState.player;863 varcurrent = GetSimState().players[player].classCounts[template.classRequirements.class] || 0;864 varremaining = template.classRequirements.number - current;781 let player = data.unitEntState.player; 782 let current = GetSimState().players[player].classCounts[template.classRequirements.class] || 0; 783 let remaining = template.classRequirements.number - current; 865 784 tooltip += " " + sprintf(translatePlural("Remaining: %(number)s to build.", "Remaining: %(number)s to build.", remaining), { "number": remaining }); 866 785 } 867 786 } 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; 787 if (neededResources) 788 tooltip += getNeededResourcesTooltip(neededResources); 789 button.tooltip = tooltip; 790 791 button.onPress = function () { 792 addResearchToQueue(data.unitEntState.id, tech); 793 }; 794 795 if (data.item.tech.pair) 796 { 797 // On mouse enter, show a cross over the other icon 798 let otherPosition = (position + data.rowLength) % (2 * data.rowLength); 799 let unchosenIcon = Engine.GetGUIObjectByName("unitResearchUnchosenIcon[" + otherPosition + "]"); 800 button.onMouseEnter = function() { 801 unchosenIcon.hidden = false; 889 802 }; 890 })(others, data.unchosenIcon); 891 button.onmouseleave = (function(others, icons) { 892 return function() { 893 for (var j of others) 894 icons[j].hidden = true; 803 button.onMouseLeave = function() { 804 unchosenIcon.hidden = true; 895 805 }; 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]; 806 } 807 904 808 button.hidden = false; 905 varmodifier = "";906 if (! data.requirementsPassed[i])809 let modifier = ""; 810 if (!requirementsPassed) 907 811 { 908 812 button.enabled = false; 909 modifier += "color: 0 0 0 127:"; 910 modifier += "grayscale:"; 813 modifier += "color:0 0 0 127:grayscale:"; 911 814 } 912 else if ( data.neededResources[i])815 else if (neededResources) 913 816 { 914 817 button.enabled = false; 915 modifier += resourcesToAlphaMask( data.neededResources[i]) + ":";818 modifier += resourcesToAlphaMask(neededResources) + ":"; 916 819 } 917 820 else 918 821 button.enabled = controlsPlayer(data.unitEntState.player); 919 822 920 if (data.template[i].icon) 921 data.icon[i].sprite = modifier + "stretched:session/portraits/" + data.template[i].icon; 823 if (template.icon) 824 icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 825 826 setPanelObjectPosition(button, position, data.rowLength); 827 828 // Prepare to handle the top button (if any) 829 position -= data.rowLength; 922 830 } 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); 831 832 return true; 933 833 } 934 834 }; 935 835 … … 946 846 return []; 947 847 return g_Selection.groups.getTemplateNames(); 948 848 }, 949 " addData": function(data)849 "setupButton": function(data) 950 850 { 951 data.entType = data.item; 952 data.template = GetTemplateData(data.entType); 953 if (!data.template) 851 let template = GetTemplateData(data.item); 852 if (!template) 954 853 return false; 955 data.name = getEntityNames(data.template);956 854 957 var ents = g_Selection.groups.getEntsByName(data.item); 958 data.count = ents.length; 959 for (var ent of ents) 855 let ents = g_Selection.groups.getEntsByName(data.item); 856 for (let ent of ents) 960 857 { 961 varstate = GetEntityState(ent);858 let state = GetEntityState(ent); 962 859 963 860 if (state.resourceCarrying && state.resourceCarrying.length !== 0) 964 861 { 965 862 if (!data.carried) 966 863 data.carried = {}; 967 varcarrying = state.resourceCarrying[0];864 let carrying = state.resourceCarrying[0]; 968 865 if (data.carried[carrying.type]) 969 866 data.carried[carrying.type] += carrying.amount; 970 867 else … … 975 872 { 976 873 if (!data.carried) 977 874 data.carried = {}; 978 varamount = state.trader.goods.amount;979 vartype = state.trader.goods.type;980 vartotalGain = amount.traderGain;875 let amount = state.trader.goods.amount; 876 let type = state.trader.goods.type; 877 let totalGain = amount.traderGain; 981 878 if (amount.market1Gain) 982 879 totalGain += amount.market1Gain; 983 880 if (amount.market2Gain) … … 988 885 data.carried[type] = totalGain; 989 886 } 990 887 } 991 return true; 992 }, 993 "setTooltip": function(data) 994 { 995 let tooltip = data.name; 888 889 let tooltip = getEntityNames(template); 996 890 if (data.carried) 997 891 tooltip += "\n" + Object.keys(data.carried).map(res => 998 892 getCostComponentDisplayIcon(res) + data.carried[res] 999 893 ).join(" "); 1000 894 data.button.tooltip = tooltip; 1001 }, 1002 "setCountDisplay": function(data) 1003 { 1004 data.countDisplay.caption = data.count || ""; 1005 }, 1006 "setAction": function(data) 1007 { 1008 data.button.onpressright = function() { changePrimarySelectionGroup(data.item, true); }; 1009 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; 895 896 data.countDisplay.caption = ents.length || ""; 897 898 data.button.onPressRight = function() { changePrimarySelectionGroup(data.item, true); }; 899 data.button.onPress = function() { changePrimarySelectionGroup(data.item, false); }; 900 901 if (template.icon) 902 data.icon.sprite = "stretched:session/portraits/" + template.icon; 903 904 setPanelObjectPosition(data.button, data.i, data.rowLength); 905 return true; 1015 906 } 1016 907 }; 1017 908 … … 1027 918 return []; 1028 919 return unitEntState.unitAI.possibleStances; 1029 920 }, 1030 " addData": function(data)921 "setupButton": function(data) 1031 922 { 1032 data.stanceSelected = Engine.GuiInterfaceCall("IsStanceSelected", { 923 data.button.onPress = function() { performStance(data.unitEntState, data.item); }; 924 925 data.button.tooltip = getStanceDisplayName(data.item) + "\n" + 926 "[font=\"sans-13\"]" + getStanceTooltip(data.item) + "[/font]"; 927 928 data.guiSelection.hidden = !Engine.GuiInterfaceCall("IsStanceSelected", { 1033 929 "ents": data.selection, 1034 930 "stance": data.item 1035 931 }); 932 data.icon.sprite = "stretched:session/icons/stances/" + data.item + ".png"; 933 data.button.enabled = controlsPlayer(data.unitEntState.player); 934 935 setPanelObjectPosition(data.button, data.i, data.rowLength); 1036 936 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 937 } 1052 938 }; 1053 939 … … 1061 947 { 1062 948 return getAllTrainableEntitiesFromSelection(); 1063 949 }, 1064 " addData": function(data)950 "setupButton": function(data) 1065 951 { 1066 data.entType = data.item; 1067 data.template = GetTemplateData(data.entType); 1068 if (!data.template) 952 let template = GetTemplateData(data.item); 953 if (!template) 1069 954 return false; 1070 955 1071 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", {1072 "tech": data.template.requiredTechnology,956 let technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 957 "tech": template.requiredTechnology, 1073 958 "player": data.unitEntState.player 1074 959 }); 1075 960 1076 var[buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] =1077 getTrainingBatchStatus(data.playerState, data.unitEntState.id, data. entType, data.selection);961 let [buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] = 962 getTrainingBatchStatus(data.playerState, data.unitEntState.id, data.item, data.selection); 1078 963 1079 data.buildingsCountToTrainFullBatch = buildingsCountToTrainFullBatch; 1080 data.fullBatchSize = fullBatchSize; 1081 data.remainderBatch = remainderBatch; 1082 1083 data.trainNum = buildingsCountToTrainFullBatch || 1; // train at least one unit 964 let trainNum = buildingsCountToTrainFullBatch || 1; 1084 965 if (Engine.HotkeyIsPressed("session.batchtrain")) 1085 data.trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch;966 trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch; 1086 967 1087 if (data.template.cost) 1088 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 1089 "cost": multiplyEntityCosts(data.template, data.trainNum), 968 let neededResources; 969 if (template.cost) 970 neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 971 "cost": multiplyEntityCosts(template, trainNum), 1090 972 "player": data.unitEntState.player 1091 973 }); 1092 974 1093 return true;1094 },1095 "setAction": function(data)1096 {1097 975 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 { 976 977 data.countDisplay.caption = trainNum > 1 ? trainNum : ""; 978 1105 979 let tooltip = "[font=\"sans-bold-16\"]" + 1106 1107 "[/font]"; 980 colorizeHotkey("%(hotkey)s", "session.queueunit." + (data.i + 1)) + 981 "[/font]"; 1108 982 1109 tooltip += getEntityNamesFormatted( data.template);1110 tooltip += getVisibleEntityClassesFormatted( data.template);1111 tooltip += getAurasTooltip( data.template);983 tooltip += getEntityNamesFormatted(template); 984 tooltip += getVisibleEntityClassesFormatted(template); 985 tooltip += getAurasTooltip(template); 1112 986 1113 if ( data.template.tooltip)1114 tooltip += "\n[font=\"sans-13\"]" + data.template.tooltip + "[/font]";987 if (template.tooltip) 988 tooltip += "\n[font=\"sans-13\"]" + template.tooltip + "[/font]"; 1115 989 1116 tooltip += "\n" + getEntityCostTooltip( data.template, data.trainNum, data.unitEntState.id);990 tooltip += "\n" + getEntityCostTooltip(template, trainNum, data.unitEntState.id); 1117 991 1118 data.limits = getEntityLimitAndCount(data.playerState, data.entType);992 let limits = getEntityLimitAndCount(data.playerState, data.item); 1119 993 1120 tooltip += formatLimitString( data.limits.entLimit, data.limits.entCount, data.limits.entLimitChangers);994 tooltip += formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers); 1121 995 if (Engine.ConfigDB_GetValue("user", "showdetailedtooltips") === "true") 1122 996 { 1123 if ( data.template.health)1124 tooltip += "\n[font=\"sans-bold-13\"]" + translate("Health:") + "[/font] " + data.template.health;1125 if ( data.template.attack)1126 tooltip += "\n" + getAttackTooltip( data.template);1127 if ( data.template.armour)1128 tooltip += "\n" + getArmorTooltip( data.template.armour);1129 if ( data.template.speed)1130 tooltip += "\n" + getSpeedTooltip( data.template);997 if (template.health) 998 tooltip += "\n[font=\"sans-bold-13\"]" + translate("Health:") + "[/font] " + template.health; 999 if (template.attack) 1000 tooltip += "\n" + getAttackTooltip(template); 1001 if (template.armour) 1002 tooltip += "\n" + getArmorTooltip(template.armour); 1003 if (template.speed) 1004 tooltip += "\n" + getSpeedTooltip(template); 1131 1005 } 1132 1006 1133 1007 tooltip += "[color=\"" + g_HotkeyColor + "\"]" + 1134 formatBatchTrainingString( data.buildingsCountToTrainFullBatch, data.fullBatchSize, data.remainderBatch) +1008 formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch) + 1135 1009 "[/color]"; 1136 1010 1137 if (! data.technologyEnabled)1011 if (!technologyEnabled) 1138 1012 { 1139 var techName = getEntityNames(GetTechnologyData(data.template.requiredTechnology));1013 let techName = getEntityNames(GetTechnologyData(template.requiredTechnology)); 1140 1014 tooltip += "\n" + sprintf(translate("Requires %(technology)s"), { "technology": techName }); 1141 1015 } 1142 if ( data.neededResources)1143 tooltip += getNeededResourcesTooltip( data.neededResources);1016 if (neededResources) 1017 tooltip += getNeededResourcesTooltip(neededResources); 1144 1018 1145 1019 data.button.tooltip = tooltip; 1146 }, 1147 // disable and enable buttons in the same way as when you do for the construction 1148 "setGraphics": g_SelectionPanels.Construction.setGraphics, 1149 "setPosition": function(data) 1150 { 1151 var index = data.i + getNumberOfRightPanelButtons(); 1020 1021 let modifier = ""; 1022 if (!technologyEnabled || limits.canBeAddedCount == 0) 1023 { 1024 data.button.enabled = false; 1025 modifier = "color:0 0 0 127:grayscale:"; 1026 } 1027 else if (neededResources) 1028 { 1029 data.button.enabled = false; 1030 modifier = resourcesToAlphaMask(neededResources) +":"; 1031 } 1032 else 1033 data.button.enabled = controlsPlayer(data.unitEntState.player); 1034 1035 if (template.icon) 1036 data.icon.sprite = modifier + "stretched:session/portraits/" + template.icon; 1037 1038 let index = data.i + getNumberOfRightPanelButtons(); 1152 1039 setPanelObjectPosition(data.button, index, data.rowLength); 1040 1041 return true; 1153 1042 } 1154 1043 }; 1155 1044 … … 1161 1050 * 1162 1051 * Note that the panel needs to appear in the list to get rendered. 1163 1052 */ 1164 varg_PanelsOrder = [1053 let g_PanelsOrder = [ 1165 1054 // LEFT PANE 1166 "Barter", // must always be visible on markets1167 "Garrison", // more important than Formation, as you want to see the garrisoned units in ships1055 "Barter", // Must always be visible on markets 1056 "Garrison", // More important than Formation, as you want to see the garrisoned units in ships 1168 1057 "Alert", 1169 1058 "Formation", 1170 "Stance", // normal together with formation1059 "Stance", // Normal together with formation 1171 1060 1172 1061 // RIGHT PANE 1173 "Gate", // must always be shown on gates1174 "Pack", // must always be shown on packable entities1062 "Gate", // Must always be shown on gates 1063 "Pack", // Must always be shown on packable entities 1175 1064 "Training", 1176 1065 "Construction", 1177 "Research", // normal together with training1066 "Research", // Normal together with training 1178 1067 1179 1068 // UNIQUE PANES (importance doesn't matter) 1180 1069 "Command", -
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";