Changeset View
Standalone View
binaries/data/mods/public/gui/session/selection_panels.js
Show First 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | "setupButton": function(data) | ||||
let neededResources; | let neededResources; | ||||
if (template.cost) | if (template.cost) | ||||
neededResources = Engine.GuiInterfaceCall("GetNeededResources", { | neededResources = Engine.GuiInterfaceCall("GetNeededResources", { | ||||
"cost": multiplyEntityCosts(template, 1), | "cost": multiplyEntityCosts(template, 1), | ||||
"player": data.player | "player": data.player | ||||
}); | }); | ||||
data.button.onPress = function () { startBuildingPlacement(data.item, data.playerState); }; | data.button.onPress = function () { startBuildingPlacement(data.item, data.playerState); }; | ||||
data.button.onPressRight = function () { showTemplateDetails(data.item, data.playerState.civ); }; | |||||
let tooltips = [ | let tooltips = [ | ||||
getEntityNamesFormatted, | getEntityNamesFormatted, | ||||
getVisibleEntityClassesFormatted, | getVisibleEntityClassesFormatted, | ||||
getAurasTooltip, | getAurasTooltip, | ||||
getEntityTooltip, | getEntityTooltip, | ||||
getEntityCostTooltip, | getEntityCostTooltip, | ||||
getGarrisonTooltip, | getGarrisonTooltip, | ||||
getPopulationBonusTooltip | getPopulationBonusTooltip | ||||
].map(func => func(template)); | ].map(func => func(template)); | ||||
tooltips.push(templateViewerOnClickMessage(true)); | |||||
elexis: The push breaks the symmetry here and in more than one place below. Suggesting… | |||||
let limits = getEntityLimitAndCount(data.playerState, data.item); | let limits = getEntityLimitAndCount(data.playerState, data.item); | ||||
tooltips.push( | tooltips.push( | ||||
formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers), | formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers), | ||||
getRequiredTechnologyTooltip(technologyEnabled, template.requiredTechnology, GetSimState().players[data.player].civ), | getRequiredTechnologyTooltip(technologyEnabled, template.requiredTechnology, GetSimState().players[data.player].civ), | ||||
getNeededResourcesTooltip(neededResources)); | getNeededResourcesTooltip(neededResources)); | ||||
data.button.tooltip = tooltips.filter(tip => tip).join("\n"); | data.button.tooltip = tooltips.filter(tip => tip).join("\n"); | ||||
▲ Show 20 Lines • Show All 480 Lines • ▼ Show 20 Lines | for (let i in techs) | ||||
let button = Engine.GetGUIObjectByName("unitResearchButton[" + position + "]"); | let button = Engine.GetGUIObjectByName("unitResearchButton[" + position + "]"); | ||||
let icon = Engine.GetGUIObjectByName("unitResearchIcon[" + position + "]"); | let icon = Engine.GetGUIObjectByName("unitResearchIcon[" + position + "]"); | ||||
let tooltips = [ | let tooltips = [ | ||||
getEntityNamesFormatted, | getEntityNamesFormatted, | ||||
getEntityTooltip, | getEntityTooltip, | ||||
getEntityCostTooltip | getEntityCostTooltip | ||||
].map(func => func(template)); | ].map(func => func(template)); | ||||
tooltips.push(templateViewerOnClickMessage(true)); | |||||
if (!requirementsPassed) | if (!requirementsPassed) | ||||
{ | { | ||||
let tip = template.requirementsTooltip; | let tip = template.requirementsTooltip; | ||||
let reqs = template.reqs; | let reqs = template.reqs; | ||||
for (let req of reqs) | for (let req of reqs) | ||||
{ | { | ||||
if (!req.entities) | if (!req.entities) | ||||
Show All 33 Lines | for (let i in techs) | ||||
} | } | ||||
tooltips.push(getNeededResourcesTooltip(neededResources)); | tooltips.push(getNeededResourcesTooltip(neededResources)); | ||||
button.tooltip = tooltips.filter(tip => tip).join("\n"); | button.tooltip = tooltips.filter(tip => tip).join("\n"); | ||||
button.onPress = function () { | button.onPress = function () { | ||||
addResearchToQueue(data.item.researchFacilityId, tech); | addResearchToQueue(data.item.researchFacilityId, tech); | ||||
}; | }; | ||||
button.onPressRight = function () { | |||||
Done Inline Actions\n\n elexis: \n\n | |||||
let researcherTemplate; | |||||
for (let selectedEntity of data.unitEntStates) | |||||
if (selectedEntity.id == data.item.researchFacilityId) | |||||
researcherTemplate = selectedEntity.template; | |||||
showTemplateDetails("tech/"+data.item.tech, data.playerState.civ, researcherTemplate); | |||||
Done Inline Actionsspaces between operators elexis: spaces between operators | |||||
}; | |||||
if (data.item.tech.pair) | if (data.item.tech.pair) | ||||
{ | { | ||||
// On mouse enter, show a cross over the other icon | // On mouse enter, show a cross over the other icon | ||||
let otherPosition = (position + data.rowLength) % (2 * data.rowLength); | let otherPosition = (position + data.rowLength) % (2 * data.rowLength); | ||||
let unchosenIcon = Engine.GetGUIObjectByName("unitResearchUnchosenIcon[" + otherPosition + "]"); | let unchosenIcon = Engine.GetGUIObjectByName("unitResearchUnchosenIcon[" + otherPosition + "]"); | ||||
button.onMouseEnter = function() { | button.onMouseEnter = function() { | ||||
unchosenIcon.hidden = false; | unchosenIcon.hidden = false; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | if (template.cost) | ||||
neededResources = Engine.GuiInterfaceCall("GetNeededResources", { | neededResources = Engine.GuiInterfaceCall("GetNeededResources", { | ||||
"cost": multiplyEntityCosts(template, trainNum), | "cost": multiplyEntityCosts(template, trainNum), | ||||
"player": data.player | "player": data.player | ||||
}); | }); | ||||
data.button.onPress = function() { | data.button.onPress = function() { | ||||
addTrainingToQueue(data.unitEntStates.map(state => state.id), data.item, data.playerState); | addTrainingToQueue(data.unitEntStates.map(state => state.id), data.item, data.playerState); | ||||
}; | }; | ||||
data.button.onPressRight = function() { | |||||
showTemplateDetails(data.item, data.playerState.civ); | |||||
}; | |||||
data.countDisplay.caption = trainNum > 1 ? trainNum : ""; | data.countDisplay.caption = trainNum > 1 ? trainNum : ""; | ||||
let tooltips = [ | let tooltips = [ | ||||
"[font=\"sans-bold-16\"]" + | "[font=\"sans-bold-16\"]" + | ||||
colorizeHotkey("%(hotkey)s", "session.queueunit." + (data.i + 1)) + | colorizeHotkey("%(hotkey)s", "session.queueunit." + (data.i + 1)) + | ||||
"[/font]" + " " + getEntityNamesFormatted(template), | "[/font]" + " " + getEntityNamesFormatted(template), | ||||
getVisibleEntityClassesFormatted(template), | getVisibleEntityClassesFormatted(template), | ||||
Show All 12 Lines | if (Engine.ConfigDB_GetValue("user", "showdetailedtooltips") === "true") | ||||
getSplashDamageTooltip, | getSplashDamageTooltip, | ||||
getHealerTooltip, | getHealerTooltip, | ||||
getArmorTooltip, | getArmorTooltip, | ||||
getGarrisonTooltip, | getGarrisonTooltip, | ||||
getProjectilesTooltip, | getProjectilesTooltip, | ||||
getSpeedTooltip | getSpeedTooltip | ||||
].map(func => func(template))); | ].map(func => func(template))); | ||||
tooltips.push(templateViewerOnClickMessage(true)); | |||||
Not Done Inline Actionsit doesn't consume an argument, but we could stil add that to the array above. not so relevant here because we push custom things below too. elexis: it doesn't consume an argument, but we could stil add that to the array above. not so relevant… | |||||
Not Done Inline ActionsThe above array is used conditionally. Use of the viewer is not conditional on whether "showdetailedtooltips" is "true". s0600204: The above array is used conditionally. Use of the viewer is not conditional on whether… | |||||
Not Done Inline ActionsOh yes elexis: Oh yes | |||||
tooltips.push( | tooltips.push( | ||||
"[color=\"" + g_HotkeyColor + "\"]" + | "[color=\"" + g_HotkeyColor + "\"]" + | ||||
formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch) + | formatBatchTrainingString(buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch) + | ||||
"[/color]", | "[/color]", | ||||
getRequiredTechnologyTooltip(technologyEnabled, template.requiredTechnology, GetSimState().players[data.player].civ), | getRequiredTechnologyTooltip(technologyEnabled, template.requiredTechnology, GetSimState().players[data.player].civ), | ||||
getNeededResourcesTooltip(neededResources)); | getNeededResourcesTooltip(neededResources)); | ||||
data.button.tooltip = tooltips.filter(tip => tip).join("\n"); | data.button.tooltip = tooltips.filter(tip => tip).join("\n"); | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (!progress) | ||||
tooltips.push(sprintf(translate("Upgrade into a %(name)s."), { | tooltips.push(sprintf(translate("Upgrade into a %(name)s."), { | ||||
"name": template.name.generic | "name": template.name.generic | ||||
})); | })); | ||||
tooltips.push( | tooltips.push( | ||||
getEntityCostComponentsTooltipString(data.item, undefined, data.unitEntStates.length), | getEntityCostComponentsTooltipString(data.item, undefined, data.unitEntStates.length), | ||||
formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers), | formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers), | ||||
getRequiredTechnologyTooltip(technologyEnabled, data.item.requiredTechnology, GetSimState().players[data.player].civ), | getRequiredTechnologyTooltip(technologyEnabled, data.item.requiredTechnology, GetSimState().players[data.player].civ), | ||||
getNeededResourcesTooltip(neededResources)); | getNeededResourcesTooltip(neededResources), | ||||
templateViewerOnClickMessage(true)); | |||||
tooltip = tooltips.filter(tip => tip).join("\n"); | tooltip = tooltips.filter(tip => tip).join("\n"); | ||||
data.button.onPress = function() { upgradeEntity(data.item.entity); }; | data.button.onPress = function() { upgradeEntity(data.item.entity); }; | ||||
} | } | ||||
else if (isUpgrading) | else if (isUpgrading) | ||||
{ | { | ||||
tooltip = translate("Cancel Upgrading"); | tooltip = translate("Cancel Upgrading"); | ||||
data.button.onPress = function() { cancelUpgradeEntity(); }; | data.button.onPress = function() { cancelUpgradeEntity(); }; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
tooltip = translate("Cannot upgrade when the entity is already upgrading."); | tooltip = translate("Cannot upgrade when the entity is already upgrading."); | ||||
data.button.onPress = function() {}; | data.button.onPress = function() {}; | ||||
} | } | ||||
data.button.enabled = controlsPlayer(data.player); | data.button.enabled = controlsPlayer(data.player); | ||||
data.button.tooltip = tooltip; | data.button.tooltip = tooltip; | ||||
data.button.onPressRight = function() { | |||||
showTemplateDetails(data.item.entity, data.playerState.civ); | |||||
}; | |||||
let modifier = ""; | let modifier = ""; | ||||
if (!isUpgrading) | if (!isUpgrading) | ||||
{ | { | ||||
if (progress || !technologyEnabled || limits.canBeAddedCount == 0 && | if (progress || !technologyEnabled || limits.canBeAddedCount == 0 && | ||||
!hasSameRestrictionCategory(data.item.entity, data.unitEntStates[0].template)) | !hasSameRestrictionCategory(data.item.entity, data.unitEntStates[0].template)) | ||||
{ | { | ||||
data.button.enabled = false; | data.button.enabled = false; | ||||
modifier = "color:0 0 0 127:grayscale:"; | modifier = "color:0 0 0 127:grayscale:"; | ||||
Show All 21 Lines | "setupButton" : function(data) | ||||
let index = data.i + getNumberOfRightPanelButtons(); | let index = data.i + getNumberOfRightPanelButtons(); | ||||
setPanelObjectPosition(data.button, index, data.rowLength); | setPanelObjectPosition(data.button, index, data.rowLength); | ||||
return true; | return true; | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* Pauses game and opens the template details viewer for a selected entity or technology. | |||||
* | |||||
* Arguably, we shouldn't have to pass a civcode, as that should be derivable from the | |||||
* template page. However, the palisade walls and trainable animals have a set civ of | |||||
Not Done Inline ActionsIf technologies don't have a civ, then code parsing techs requiring a civ would be technically wrong, no? elexis: If technologies don't have a civ, then code parsing techs requiring a civ would be technically… | |||||
Not Done Inline ActionsUh, no. Techs don't "have a civ" because they can belong to (or have) one or more civs. We don't know which of them we're looking at (and we need to know to get/use the correct specific name, cost, civ-bonus/penalty modifiers, etc). s0600204: Uh, no.
Techs don't "have a civ" because they can belong to (or have) one or more civs. We… | |||||
* gaia, so we pass the civcode of the currently owning civ. | |||||
Not Done Inline ActionsIf it were only for the walls, that would have sounded like a TODO. elexis: If it were only for the walls, that would have sounded like a TODO.
But the case for animals… | |||||
* | |||||
* And technologies don't have a set civ, so we pass along the name of the template of | |||||
* the entity that's researching it so as to derive the civcode from that, if we can. | |||||
elexisUnsubmitted Not Done Inline Actionscurrently owning civ = civ of the player that owns the entity. What's the issue with passing the gaia civ in these few special cases? Palisades should be played owned to begin with as fatherbushido always stated. So don't fix a template bug in the GUI code but leave it open and bleeding, and fix or let someone fix the template bug eventually. (Nescio likes these sorts of things). The JSdoc comments don't seem needed either, its obvious that a templateName is a string. (However if we add comments, they should be in JSdoc) -> researcherTemplateName if we actually need both arguments Werid to pass a civ and sometimes it doesnt use the civ but the civ from the researcherTemplateName. templateName sometimes is the one of a tech and sometimes the one of an entity? (If we can't unify this cleanly, perhaps two functions and two page_view init paths might be cleaner. Would have to see it written.) elexis: currently owning civ = civ of the player that owns the entity.
Doesn't that imply that a player… | |||||
* | |||||
* @param {string} templateName | |||||
* @param {string} civ - Civ code of the current owner of the entity selected. | |||||
* @param {string} [researcherName] - The template name of the entity that researches a selected technology. | |||||
*/ | |||||
function showTemplateDetails(templateName, civ, researcherName) | |||||
{ | |||||
pauseGame(); | |||||
Engine.PushGuiPage("page_viewer.xml", { | |||||
"templateName": templateName, | |||||
"callback": "resumeGame", | |||||
"civ": civ, | |||||
"researcherName": researcherName | |||||
}); | |||||
} | |||||
/** | |||||
* If two panels need the same space, so they collide, | * If two panels need the same space, so they collide, | ||||
* the one appearing first in the order is rendered. | * the one appearing first in the order is rendered. | ||||
* | * | ||||
Not Done Inline ActionsNot really a use case for the civ default. Is it actually a good idea to pass the Civ here instead of getting that from the template? elexis: Not really a use case for the civ default.
Is it actually a good idea to pass the Civ here… | |||||
Not Done Inline ActionsInteresting question. Thing is, there's no guarantee that the civ set inside a template is the same as the civ that builds it. For example:
And that's before we start on the weird and wonderful world of mods... 😉 The downside to this approach is that when a structure is captured, the civ code passed changes, resulting in changed text:
And... then there's the case of technology templates that don't have a specific civ, and thus a civ code has to be passed so we can display the correct specific name. (Which... changes depending on who owns the structure the technology you've selected is researched at.) ... I suppose we could try to work out how to acquire and pass the civcode of the player who built a given structure, including when clicking on technologies in production queues. Would require messing around with the simulation so as to get it to store who originally built a structure, and then passing it to the correct places. And even then there'd be some odd edge-cases. (Scenario maps where civs are given buildings that can't usually be built by them. Mods that play fast and loose with who can build what.) Alternatively, we could load and use the civcode from the template file - so long as its not a technology, and the civ set in the file is not gaia. Possible but messy. Maybe if it is a technology, get the civcode from the template file of the structure/unit that is researching it. s0600204: Interesting question.
Thing is, there's no guarantee that the civ set inside a template is the… | |||||
* Note that the panel needs to appear in the list to get rendered. | * Note that the panel needs to appear in the list to get rendered. | ||||
*/ | */ | ||||
let g_PanelsOrder = [ | let g_PanelsOrder = [ | ||||
// LEFT PANE | // LEFT PANE | ||||
"Barter", // Must always be visible on markets | "Barter", // Must always be visible on markets | ||||
"Garrison", // More important than Formation, as you want to see the garrisoned units in ships | "Garrison", // More important than Formation, as you want to see the garrisoned units in ships | ||||
"Alert", | "Alert", | ||||
"Formation", | "Formation", | ||||
Done Inline Actionsdata should be inlined like the other GUI pages do elexis: data should be inlined like the other GUI pages do | |||||
"Stance", // Normal together with formation | "Stance", // Normal together with formation | ||||
// RIGHT PANE | // RIGHT PANE | ||||
"Gate", // Must always be shown on gates | "Gate", // Must always be shown on gates | ||||
"Pack", // Must always be shown on packable entities | "Pack", // Must always be shown on packable entities | ||||
"Upgrade", // Must always be shown on upgradable entities | "Upgrade", // Must always be shown on upgradable entities | ||||
"Training", | "Training", | ||||
"Construction", | "Construction", | ||||
"Research", // Normal together with training | "Research", // Normal together with training | ||||
// UNIQUE PANES (importance doesn't matter) | // UNIQUE PANES (importance doesn't matter) | ||||
"Command", | "Command", | ||||
"AllyCommand", | "AllyCommand", | ||||
"Queue", | "Queue", | ||||
"Selection", | "Selection", | ||||
]; | ]; |
The push breaks the symmetry here and in more than one place below. Suggesting
templateViewerRightclickTooltip
templateViewerLeftclickTooltip