Index: binaries/data/config/default.cfg =================================================================== --- binaries/data/config/default.cfg +++ binaries/data/config/default.cfg @@ -370,6 +370,7 @@ aurasrange = true ; Display aura range overlays of selected units and structures healrange = true ; Display heal range overlays of selected units rankabovestatusbar = true ; Show rank icons above status bars +experiencestatusbar = true ; Show an experience status bar above each selected unit respoptooltipsort = 0 ; Sorting players in the resources and population tooltip by value (0 - no sort, -1 - ascending, 1 - descending) [gui.session.minimap] Index: binaries/data/mods/public/gui/options/options.json =================================================================== --- binaries/data/mods/public/gui/options/options.json +++ binaries/data/mods/public/gui/options/options.json @@ -492,6 +492,12 @@ }, { "type": "boolean", + "label": "Experience status bar", + "tooltip": "Show an experience status bar above each selected unit.", + "config": "gui.session.experiencestatusbar" + }, + { + "type": "boolean", "label": "Detailed Tooltips", "tooltip": "Show detailed tooltips for trainable units in unit-producing buildings.", "config": "showdetailedtooltips" Index: binaries/data/mods/public/gui/session/selection.js =================================================================== --- binaries/data/mods/public/gui/session/selection.js +++ binaries/data/mods/public/gui/session/selection.js @@ -19,7 +19,8 @@ Engine.GuiInterfaceCall("SetStatusBars", { "entities": ents, "enabled": enabled, - "showRank": Engine.ConfigDB_GetValue("user", "gui.session.rankabovestatusbar") == "true" + "showRank": Engine.ConfigDB_GetValue("user", "gui.session.rankabovestatusbar") == "true", + "showExperience": Engine.ConfigDB_GetValue("user", "gui.session.experiencestatusbar") == "true" }); } Index: binaries/data/mods/public/gui/session/session.js =================================================================== --- binaries/data/mods/public/gui/session/session.js +++ binaries/data/mods/public/gui/session/session.js @@ -1366,7 +1366,8 @@ Engine.GuiInterfaceCall("SetStatusBars", { "entities": entities, "enabled": g_ShowAllStatusBars && !remove, - "showRank": Engine.ConfigDB_GetValue("user", "gui.session.rankabovestatusbar") == "true" + "showRank": Engine.ConfigDB_GetValue("user", "gui.session.rankabovestatusbar") == "true", + "showExperience": Engine.ConfigDB_GetValue("user", "gui.session.experiencestatusbar") == "true" }); } Index: binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/GuiInterface.js +++ binaries/data/mods/public/simulation/components/GuiInterface.js @@ -851,7 +851,7 @@ let cmpStatusBars = Engine.QueryInterface(ent, IID_StatusBars); if (!cmpStatusBars) continue; - cmpStatusBars.SetEnabled(cmd.enabled, cmd.showRank); + cmpStatusBars.SetEnabled(cmd.enabled, cmd.showRank, cmd.showExperience); let cmpAuras = Engine.QueryInterface(ent, IID_Auras); if (!cmpAuras) Index: binaries/data/mods/public/simulation/components/Promotion.js =================================================================== --- binaries/data/mods/public/simulation/components/Promotion.js +++ binaries/data/mods/public/simulation/components/Promotion.js @@ -166,6 +166,8 @@ } this.Promote(promotedTemplateName); } + + Engine.PostMessage(this.entity, MT_ExperienceChanged, {}); }; Promotion.prototype.OnValueModification = function(msg) Index: binaries/data/mods/public/simulation/components/StatusBars.js =================================================================== --- binaries/data/mods/public/simulation/components/StatusBars.js +++ binaries/data/mods/public/simulation/components/StatusBars.js @@ -6,7 +6,7 @@ "" + "" + "" + - "" + + "" + "" + "" + "" + @@ -21,6 +21,7 @@ * provide the right methods. */ StatusBars.prototype.Sprites = [ + "ExperienceBar", "PackBar", "ResourceSupplyBar", "CaptureBar", @@ -33,6 +34,7 @@ { this.enabled = false; this.showRank = false; + this.showExperience = false; // Whether the status bars used the player colors anywhere (e.g. in the capture bar) this.usedPlayerColors = false; @@ -54,14 +56,15 @@ this.auraSources = data.auraSources; }; -StatusBars.prototype.SetEnabled = function(enabled, showRank) +StatusBars.prototype.SetEnabled = function(enabled, showRank, showExperience) { // Quick return if no change - if (enabled == this.enabled && showRank == this.showRank) + if (enabled == this.enabled && showRank == this.showRank && showExperience == this.showExperience) return; this.enabled = enabled; this.showRank = showRank; + this.showExperience = showExperience; // Update the displayed sprites this.RegenerateSprites(); @@ -107,6 +110,12 @@ this.RegenerateSprites(); }; +StatusBars.prototype.OnExperienceChanged = function() +{ + if (this.enabled) + this.RegenerateSprites(); +}; + StatusBars.prototype.UpdateColor = function() { if (this.usedPlayerColors) @@ -127,11 +136,11 @@ /** * Generic piece of code to add a bar. */ -StatusBars.prototype.AddBar = function(cmpOverlayRenderer, yoffset, type, amount) +StatusBars.prototype.AddBar = function(cmpOverlayRenderer, yoffset, type, amount, heightMultiplier = 1) { // Size of health bar (in world-space units) let width = +this.template.BarWidth; - let height = +this.template.BarHeight; + let height = +this.template.BarHeight * heightMultiplier; // World-space offset from the unit's position let offset = { "x": 0, "y": +this.template.HeightOffset, "z": 0 }; @@ -157,6 +166,18 @@ return height * 1.2; }; +StatusBars.prototype.AddExperienceBar = function(cmpOverlayRenderer, yoffset) +{ + if (!this.enabled || !this.showExperience) + return 0; + + let cmpPromotion = Engine.QueryInterface(this.entity, IID_Promotion); + if (!cmpPromotion || !cmpPromotion.GetCurrentXp() || !cmpPromotion.GetRequiredXp()) + return 0; + + return this.AddBar(cmpOverlayRenderer, yoffset, "pack", cmpPromotion.GetCurrentXp() / cmpPromotion.GetRequiredXp(), 2/3); +}; + StatusBars.prototype.AddPackBar = function(cmpOverlayRenderer, yoffset) { if (!this.enabled) Index: binaries/data/mods/public/simulation/components/interfaces/Promotion.js =================================================================== --- binaries/data/mods/public/simulation/components/interfaces/Promotion.js +++ binaries/data/mods/public/simulation/components/interfaces/Promotion.js @@ -1 +1,7 @@ Engine.RegisterInterface("Promotion"); + +/** + * Message of the form {} + * sent from Promotion component whenever the experience changes. + */ +Engine.RegisterMessageType("ExperienceChanged");