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 @@ -258,7 +258,7 @@ return Object.keys(damageTemplate).filter(dmgType => damageTemplate[dmgType]).map( dmgType => sprintf(translate("%(damage)s %(damageType)s"), { - "damage": damageTemplate[dmgType].toFixed(1), + "damage": (+damageTemplate[dmgType]).toFixed(1), "damageType": unitFont(translateWithContext("damage type", dmgType)) })).join(commaFont(translate(", "))); } @@ -269,11 +269,21 @@ return ""; return sprintf(translate("%(amount)s %(name)s"), { - "amount": captureTemplate.toFixed(1), + "amount": (+captureTemplate).toFixed(1), "name": unitFont(translateWithContext("damage type", "Capture")) }); } +function giveStatusDetails(giveStatusTemplate) +{ + if (!giveStatusTemplate) + return ""; + + return sprintf(translate("gives %(name)s"), { + "name": Object.keys(giveStatusTemplate).map(x => unitFont(translateWithContext("status effect", x))).join(', '), + }); +} + function attackEffectsDetails(attackTypeTemplate) { if (!attackTypeTemplate) @@ -281,7 +291,8 @@ let effects = [ captureDetails(attackTypeTemplate.Capture || undefined), - damageDetails(attackTypeTemplate.Damage || undefined) + damageDetails(attackTypeTemplate.Damage || undefined), + giveStatusDetails(attackTypeTemplate.GiveStatus || undefined) ]; return effects.filter(effect => effect).join(commaFont(translate(", "))); } @@ -351,6 +362,16 @@ return tooltips.join("\n"); } +function getStatusEffectsTooltip(name, template) +{ + return sprintf(translate("%(statusName)s: %(effects)s, %(rate)s, Duration: %(duration)s"), { + "statusName": headerFont(translateWithContext("status effect", name)), + "effects": attackEffectsDetails(template), + "duration": getSecondsString((template.timeElapsed ? template.duration - template.timeElapsed : template.duration) / 1000), + "rate": attackRateDetails(+template.interval, 1) + }); +} + function getGarrisonTooltip(template) { if (!template.garrisonHolder) 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 @@ -93,6 +93,25 @@ Engine.GetGUIObjectByName("rankIcon").tooltip = ""; } + if (entState.statusEffects) + { + let i = 0; + for (let effectName in entState.statusEffects) + { + let obj = Engine.GetGUIObjectByName("statusEffectsIcon[" + i + "]"); + obj.hidden = false; + obj.sprite = "stretched:session/icons/kill.png"; + obj.tooltip = getStatusEffectsTooltip(effectName, entState.statusEffects[effectName]); + let size = obj.size; + size.top = i * 18; + size.bottom = i * 18 + 16; + obj.size = size; + i++; + } + for (; i < 5; ++i) + Engine.GetGUIObjectByName("statusEffectsIcon[" + i + "]").hidden = true; + } + let showHealth = entState.hitpoints; let showResource = entState.resourceSupply; 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 @@ -82,9 +82,18 @@ Rank + + + + + + + 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 @@ -291,6 +291,10 @@ "template": cmpUpgrade.GetUpgradingTo() }; + let cmpStatusEffects = Engine.QueryInterface(ent, IID_StatusEffectsReceiver); + if (cmpStatusEffects) + ret.statusEffects = cmpStatusEffects.GetActiveStatuses(); + let cmpProductionQueue = Engine.QueryInterface(ent, IID_ProductionQueue); if (cmpProductionQueue) ret.production = { Index: binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js =================================================================== --- binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js +++ binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js @@ -5,6 +5,11 @@ this.activeStatusEffects = {}; }; +StatusEffectsReceiver.prototype.GetActiveStatuses = function() +{ + return this.activeStatusEffects; +}; + // Called by attacking effects. StatusEffectsReceiver.prototype.GiveStatus = function(effectData, attacker, attackerOwner, bonusMultiplier) { @@ -25,7 +30,7 @@ let status = this.activeStatusEffects[statusName]; status.duration = +data.Duration; status.interval = +data.Interval; - status.damage = +data.Damage; + status.Damage = data.Damage; status.timeElapsed = 0; status.firstTime = true; @@ -39,7 +44,7 @@ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); cmpTimer.CancelTimer(this.activeStatusEffects[statusName].timer); - this.activeStatusEffects[statusName] = undefined; + delete this.activeStatusEffects[statusName]; }; StatusEffectsReceiver.prototype.ExecuteEffect = function(statusName, lateness) @@ -56,7 +61,7 @@ else status.timeElapsed += status.interval + lateness; - Attacking.HandleAttackEffects(statusName, { "Damage": { [statusName]: status.damage } }, this.entity, -1, -1); + Attacking.HandleAttackEffects(statusName, status, this.entity, -1, -1); if (status.timeElapsed >= status.duration) this.RemoveStatus(statusName); Index: binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js +++ binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js @@ -31,6 +31,7 @@ Engine.LoadComponentScript("interfaces/Trader.js"); Engine.LoadComponentScript("interfaces/Timer.js"); Engine.LoadComponentScript("interfaces/StatisticsTracker.js"); +Engine.LoadComponentScript("interfaces/StatusEffectsReceiver.js"); Engine.LoadComponentScript("interfaces/UnitAI.js"); Engine.LoadComponentScript("interfaces/Upgrade.js"); Engine.LoadComponentScript("interfaces/BuildingAI.js"); Index: binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js +++ binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js @@ -28,7 +28,9 @@ cmpStatusReceiver.AddStatus(statusName, { "Duration": 20000, "Interval": 10000, - "Damage": 1 + "Damage": { + [statusName]: 1 + } }); cmpTimer.OnUpdate({ "turnLength": 1 }); @@ -65,12 +67,16 @@ "Burn": { "Duration": 20000, "Interval": 10000, - "Damage": 10 + "Damage": { + "Burn": 10 + } }, "Poison": { "Duration": 3000, "Interval": 1000, - "Damage": 1 + "Damage": { + "Poison": 1 + } } }); @@ -102,7 +108,9 @@ cmpStatusReceiver.AddStatus(statusName, { "Duration": 20000, "Interval": 10000, - "Damage": 1 + "Damage": { + [statusName]: 1 + } }); cmpTimer.OnUpdate({ "turnLength": 1 }); Index: binaries/data/mods/public/simulation/helpers/Attacking.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Attacking.js +++ binaries/data/mods/public/simulation/helpers/Attacking.js @@ -5,38 +5,41 @@ /** * Builds a RelaxRNG schema of possible attack effects. - * Currently harcoded to "Damage", "Capture" and "StatusEffects". + * See globalscripts/AttackEffects.js for possible elements. * Attacks may also have a "Bonuses" element. * * @return {string} - RelaxNG schema string */ +const DamageSchema = "" + + "" + + "" + + "" + + // Armour requires Foundation to not be a damage type. + "Foundation" + + "" + + "" + + "" + + ""; + Attacking.prototype.BuildAttackEffectsSchema = function() { return "" + "" + "" + "" + - "" + - "" + - "" + - // Armour requires Foundation to not be a damage type. - "Foundation" + - "" + - "" + - "" + - "" + + DamageSchema + "" + "" + "" + "" + - "" + + "" + "" + "" + "" + "" + "" + "" + - "" + + "" + DamageSchema + "" + "" + "" + "" + @@ -79,8 +82,8 @@ if (template.Capture) ret.Capture = ApplyValueModificationsToEntity(valueModifRoot + "/Capture", +(template.Capture || 0), entity); - if (template.StatusEffects) - ret.StatusEffects = template.StatusEffects; + if (template.GiveStatus) + ret.GiveStatus = template.GiveStatus; if (template.Bonuses) ret.Bonuses = template.Bonuses; Index: binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml +++ binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml @@ -11,6 +11,16 @@ 6.0 0 + + + 10000 + 1000 + + 3 + 4 + + + 72.0 0.0 600