Index: binaries/data/mods/public/gui/common/tooltips.js
===================================================================
--- binaries/data/mods/public/gui/common/tooltips.js
+++ binaries/data/mods/public/gui/common/tooltips.js
@@ -488,6 +488,23 @@
}
/**
+ * Returns the resources this entity supplies in the specified entity's tooltip
+ */
+function getResourceSupplyTooltip(template)
+{
+ if (!template.supply)
+ return "";
+
+ let supply = template.supply;
+ let type = (supply.type[0] === "treasure") ? supply.type[1] : supply.type[0];
+
+ let txt = g_TooltipTextFormats.header[0] + translate("Resource Supply:") + g_TooltipTextFormats.header[1] + " ";
+ txt += sprintf(translate("%(component)s %(amount)s"), { component: resourceIcon(type), amount: supply.amount });
+
+ return txt;
+}
+
+/**
* Returns the population bonus information to display in the specified entity's construction button tooltip.
*/
function getPopulationBonusTooltip(template)
Index: binaries/data/mods/public/gui/encyclopedia/common/core.js
===================================================================
--- binaries/data/mods/public/gui/encyclopedia/common/core.js
+++ binaries/data/mods/public/gui/encyclopedia/common/core.js
@@ -2,6 +2,21 @@
var g_SelectedCiv = "";
var g_CallbackSet = false;
+var g_EntityStatFunctions = [
+ getHealthTooltip,
+ getHealerTooltip,
+ getAttackTooltip,
+ getSplashDamageTooltip,
+ getArmorTooltip,
+ getGarrisonTooltip,
+ getProjectilesTooltip,
+ getSpeedTooltip,
+ getGatherTooltip,
+ getResourceSupplyTooltip,
+ getPopulationBonusTooltip,
+ getLootTooltip
+];
+
function init_civs ()
{
g_CivData = loadCivData(true);
@@ -175,3 +190,18 @@
return entityLists;
}
+function setViewerOnPress(ele, entity)
+{
+ if (typeof ele === "string")
+ ele = Engine.GetGUIObjectByName(ele);
+
+ ele.onpressright = function () { Engine.PushGuiPage("page_viewer.xml", {
+ "entity": entity,
+ "civ": g_SelectedCiv,
+ }); };
+}
+
+function unsetViewerOnPress(ele)
+{
+ ele.onPressRight = function () {};
+}
Index: binaries/data/mods/public/gui/encyclopedia/common/draw.js
===================================================================
--- binaries/data/mods/public/gui/encyclopedia/common/draw.js
+++ binaries/data/mods/public/gui/encyclopedia/common/draw.js
@@ -5,19 +5,8 @@
getEntityNamesFormatted,
getEntityCostTooltip,
getEntityTooltip,
- getAurasTooltip,
- getHealthTooltip,
- getHealerTooltip,
- getAttackTooltip,
- getSplashDamageTooltip,
- getArmorTooltip,
- getGarrisonTooltip,
- getProjectilesTooltip,
- getSpeedTooltip,
- getGatherTooltip,
- getPopulationBonusTooltip,
- getLootTooltip
-];
+ getAurasTooltip
+].concat(g_EntityStatFunctions);
/**
* Assemble a tooltip text
Index: binaries/data/mods/public/gui/encyclopedia/common/load.js
===================================================================
--- binaries/data/mods/public/gui/encyclopedia/common/load.js
+++ binaries/data/mods/public/gui/encyclopedia/common/load.js
@@ -29,7 +29,7 @@
{
// We need to clone the template because we want to perform some translations.
let data = clone(Engine.GetTemplate(templateName));
- translateObjectKeys(data, ["GenericName", "SpecificName", "Tooltip"]);
+ translateObjectKeys(data, ["GenericName", "SpecificName", "Tooltip", "History"]);
if (data.Auras)
for (let auraID of data.Auras._string.split(/\s+/))
@@ -54,7 +54,7 @@
if (!(templateName in g_TechnologyData))
{
let data = Engine.ReadJSONFile(g_TechnologyPath + templateName + ".json");
- translateObjectKeys(data, ["genericName", "tooltip"]);
+ translateObjectKeys(data, ["genericName", "tooltip", "description"]);
g_TechnologyData[templateName] = data;
}
@@ -97,6 +97,8 @@
let template = loadTemplate(templateName);
let unit = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData);
+ unit.history = template.Identity.History;
+
if (template.ProductionQueue)
{
unit.production = {};
@@ -114,6 +116,12 @@
}
}
+ if (template.Identity.Rank)
+ unit.promotion = {
+ "current_rank": template.Identity.Rank,
+ "entity": (template.Promotion) ? template.Promotion.Entity : null
+ };
+
if (template.Builder && template.Builder.Entities._string)
{
unit.builder = [];
@@ -139,6 +147,8 @@
let template = loadTemplate(templateName);
let structure = GetTemplateDataHelper(template, null, g_AuraData, g_ResourceData);
+ structure.history = template.Identity.History;
+
structure.production = {
"technology": [],
"units": []
@@ -202,6 +212,21 @@
return structure;
}
+function loadResource(templateName)
+{
+ let template = loadTemplate(templateName);
+ let resource = GetTemplateDataHelper(template);
+
+ resource.history = template.Identity.History;
+
+ resource.supply = {
+ "type": template.ResourceSupply.Type.split("."),
+ "amount": template.ResourceSupply.Amount,
+ };
+
+ return resource;
+}
+
/**
* Load and parse technology from json template.
*
Index: binaries/data/mods/public/gui/encyclopedia/structree/draw.js
===================================================================
--- binaries/data/mods/public/gui/encyclopedia/structree/draw.js
+++ binaries/data/mods/public/gui/encyclopedia/structree/draw.js
@@ -50,6 +50,7 @@
Engine.GetGUIObjectByName("phase["+i+"]_struct["+s+"]_name").caption =
translate(stru.name.specific);
+ setViewerOnPress("phase["+i+"]_struct["+s+"]_icon", stru);
thisEle.hidden = false;
for (let r in g_DrawLimits[pha].prodQuant)
@@ -150,6 +151,7 @@
trainer = g_ParsedData.units[trainer];
Engine.GetGUIObjectByName("trainer["+t+"]_icon").sprite = "stretched:session/portraits/"+trainer.icon;
Engine.GetGUIObjectByName("trainer["+t+"]_icon").tooltip = assembleTooltip(trainer);
+ setViewerOnPress("trainer["+t+"]_icon", trainer);
Engine.GetGUIObjectByName("trainer["+t+"]_name").caption = translate(trainer.name.specific);
thisEle.hidden = false;
@@ -217,6 +219,7 @@
prodEle.sprite = "stretched:session/portraits/"+prod.icon;
prodEle.tooltip = assembleTooltip(prod);
prodEle.hidden = false;
+ setViewerOnPress(prodEle, prod);
return true;
}
Index: binaries/data/mods/public/gui/encyclopedia/viewer/setup.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/encyclopedia/viewer/setup.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
Index: binaries/data/mods/public/gui/encyclopedia/viewer/sprites.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/encyclopedia/viewer/sprites.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/encyclopedia/viewer/styles.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/encyclopedia/viewer/styles.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/encyclopedia/viewer/viewer.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/encyclopedia/viewer/viewer.js
@@ -0,0 +1,160 @@
+
+/* Globals */
+var g_SelectedCiv = "gaia"; // fallback default
+var g_Template = {};
+
+/**
+ * Page initialisation. May also eventually pre-draw/arrange objects.
+ *
+ * @arg template The object or the template name of the entity to be displayed
+ */
+function init (data = null)
+{
+ if (!data || !data.entity)
+ {
+ error("Viewer: No template provided");
+ closePage();
+ return;
+ }
+
+ if (data.callback)
+ g_CallbackSet = true;
+
+ if (data.civ)
+ g_SelectedCiv = data.civ;
+
+ if (typeof data.entity === "string")
+ {
+ data.entity = data.entity.slice(data.entity.lastIndexOf("&")+1);
+ g_Template = loadTemplateFromName(data.entity);
+ if (!g_Template)
+ {
+ error("Viewer: unable to recognise or load template (" + data.entity + ")");
+ closePage();
+ return;
+ }
+ }
+ else
+ g_Template = data.entity;
+
+ draw();
+}
+
+/**
+ * Populate the UI elements.
+ */
+function draw ()
+{
+ let iconObject = Engine.GetGUIObjectByName("entityIcon")
+ Engine.GetGUIObjectByName("entityName").caption = getEntityNamesFormatted(g_Template);
+ iconObject.sprite = "stretched:session/portraits/" + g_Template.icon;
+
+ let statsObject = Engine.GetGUIObjectByName("entityStats");
+ let statFunctions = [
+ getEntityCostTooltip
+ ].concat(g_EntityStatFunctions);
+ statsObject.caption = buildText(g_Template, statFunctions);
+
+ // This is something of a crude hack. Ideally, it would be better to
+ // acquire the height of the rendered text from the text object, but
+ // that is not currently implemented (needs c++ change)
+ let infoObject = Engine.GetGUIObjectByName("entityInfo");
+ let lines = statsObject.caption.split("\n").length;
+ let fontSize = +statsObject.font.substr(statsObject.font.indexOf("-")+1) + 4;
+ let infoSize = infoObject.size;
+ infoSize.top = Math.max(iconObject.size.bottom, lines * fontSize + statsObject.size.top) + 8;
+ infoObject.size = infoSize;
+
+ let infoFunctions = [
+ getEntityTooltip,
+ getHistoryTooltip,
+ getDescriptionTooltip,
+ getAurasTooltip,
+ getVisibleEntityClassesFormatted
+ ];
+ infoObject.caption = buildText(g_Template, infoFunctions, "\n\n");
+
+ if (g_Template.promotion)
+ Engine.GetGUIObjectByName("entityRankGlyph").sprite = "stretched:" + getRankGlyph(g_Template.promotion.current_rank);
+ Engine.GetGUIObjectByName("entityRankGlyph").hidden = !(g_Template.promotion);
+}
+
+/**
+ * Determines the requested template and loads it
+ *
+ * @arg templateName The template name. If loading a technology, then `tech/` must be prefixed.
+ * @return The entity object if successful, false if not
+ */
+function loadTemplateFromName(templateName)
+{
+ if (templateName.indexOf("|") > -1)
+ templateName = templateName.slice(templateName.indexOf("|")+1);
+ let prefix = templateName.slice(0, templateName.indexOf("/"));
+
+ switch (prefix)
+ {
+ case "structures":
+ case "other":
+ return loadStructure(templateName);
+ break;
+
+ case "units":
+ return loadUnit(templateName);
+ break;
+
+ case "gaia":
+ return loadResource(templateName);
+ break;
+
+ case "tech":
+ return loadTechnology(templateName.substr(templateName.indexOf("/")+1));
+ break;
+
+ default:
+ // do nothing (error message is given elsewhere)
+ }
+
+ return false;
+}
+
+/**
+ * Overrides near-identical function in gui/common/tooltips.js
+ * (Just so we can get slightly bigger text)
+ */
+function getEntityNamesFormatted(template)
+{
+ var names = "";
+ var generic = template.name.generic;
+ var specific = template.name.specific;
+ if (specific)
+ {
+ // drop caps for specific name
+ names += '[font="sans-bold-20"]' + specific[0] + '[/font]' +
+ '[font="sans-bold-16"]' + specific.slice(1).toUpperCase() + '[/font]';
+
+ if (generic)
+ names += '[font="sans-bold-16"] (' + generic + ')[/font]';
+ }
+ else if (generic)
+ names = '[font="sans-bold-20"]' + generic + "[/font]";
+ else
+ names = "???";
+
+ return names;
+}
+
+/**
+ * Returns the appropriate promotion rank glyph for a given rank
+ *
+ * TODO: Don't hardcode ranks.
+ *
+ * @param rank The rank
+ * @return Path to the image
+ */
+function getRankGlyph(rank)
+{
+ var ranks = [ "Basic", "Advanced", "Elite" ];
+ if (!ranks.indexOf(rank) < 0)
+ return null;
+ return "session/icons/rank" + (ranks.indexOf(rank) + 1) + ".png";
+}
Index: binaries/data/mods/public/gui/encyclopedia/viewer/viewer.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/encyclopedia/viewer/viewer.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/gui/page_viewer.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/page_viewer.xml
@@ -0,0 +1,20 @@
+
+
+ common/modern/setup.xml
+ common/modern/styles.xml
+ common/modern/sprites.xml
+
+ common/setup_resources.xml
+ common/sprites.xml
+ common/styles.xml
+
+ encyclopedia/common/sprites.xml
+ encyclopedia/common/styles.xml
+
+ encyclopedia/viewer/styles.xml
+ encyclopedia/viewer/sprites.xml
+ encyclopedia/viewer/viewer.xml
+ encyclopedia/viewer/setup.xml
+
+ encyclopedia/common/setup.xml
+
Index: binaries/data/mods/public/gui/session/selection_details.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_details.js
+++ binaries/data/mods/public/gui/session/selection_details.js
@@ -286,6 +286,8 @@
// TODO: we should require all entities to have icons
Engine.GetGUIObjectByName("icon").sprite = template.icon ? ("stretched:session/portraits/" + template.icon) : "BackgroundBlack";
+ if (template.icon)
+ Engine.GetGUIObjectByName("iconBorder").onpressright = function () { showEntityDetails(entState.template, playerState.civ); };
Engine.GetGUIObjectByName("attackAndArmorStats").tooltip = [
getAttackTooltip,
Index: binaries/data/mods/public/gui/session/selection_panels.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels.js
+++ binaries/data/mods/public/gui/session/selection_panels.js
@@ -267,6 +267,7 @@
template.auras = GetTemplateData(template.wallSet.templates.long).auras;
data.button.onPress = function () { startBuildingPlacement(data.item, data.playerState); };
+ data.button.onPressRight = function () { showEntityDetails(data.item, data.playerState.civ); };
let tooltips = [
getEntityNamesFormatted,
@@ -816,6 +817,8 @@
addResearchToQueue(data.item.researchFacilityId, tech);
};
+ button.onPressRight = function () { showEntityDetails("tech/"+data.item, data.playerState.civ); };
+
if (data.item.tech.pair)
{
// On mouse enter, show a cross over the other icon
@@ -1005,6 +1008,7 @@
data.button.onPress = function() {
addTrainingToQueue(data.unitEntStates.map(state => state.id), data.item, data.playerState);
};
+ data.button.onPressRight = function () { showEntityDetails(data.item, data.playerState.civ); };
data.countDisplay.caption = trainNum > 1 ? trainNum : "";
@@ -1147,6 +1151,8 @@
data.button.enabled = controlsPlayer(data.player);
data.button.tooltip = tooltip;
+ data.button.onPressRight = function () { showEntityDetails(data.item.entity, data.playerState.civ); };
+
let modifier = "";
if (!isUpgrading)
{
@@ -1184,6 +1190,20 @@
};
/**
+ * Pauses game and opens the entity details viewer on a given entity
+ */
+function showEntityDetails(entityName, civ = "athen")
+{
+ pauseGame();
+ let data = {
+ "entity" : entityName,
+ "callback": "resumeGame",
+ "civ": civ,
+ };
+ Engine.PushGuiPage("page_viewer.xml", data);
+}
+
+/**
* If two panels need the same space, so they collide,
* the one appearing first in the order is rendered.
*
Index: binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml
+++ binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml
@@ -61,7 +61,7 @@
-
+
Index: binaries/data/mods/public/l10n/messages.json
===================================================================
--- binaries/data/mods/public/l10n/messages.json
+++ binaries/data/mods/public/l10n/messages.json
@@ -374,6 +374,7 @@
"keywords": {
"GenericName": {},
"SpecificName": {},
+ "History": {},
"VisibleClasses": {
"splitOnWhitespace": true
},
@@ -405,6 +406,7 @@
"keywords": {
"GenericName": {},
"SpecificName": {},
+ "History": {},
"VisibleClasses": {
"splitOnWhitespace": true
},
@@ -443,6 +445,7 @@
"keywords": {
"GenericName": {},
"SpecificName": {},
+ "History": {},
"VisibleClasses": {
"splitOnWhitespace": true
},