mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Heal HP → Health, Rate → Interval
Patch By: Nescio Differential Revision: D2842 This was SVN commit r23863.
This commit is contained in:
parent
98108be43e
commit
47d5422e64
11 changed files with 51 additions and 51 deletions
|
|
@ -323,9 +323,9 @@ function GetTemplateDataHelper(template, player, auraTemplates, modifiers = {})
|
|||
|
||||
if (template.Heal)
|
||||
ret.heal = {
|
||||
"hp": getEntityValue("Heal/HP"),
|
||||
"health": getEntityValue("Heal/Health"),
|
||||
"range": getEntityValue("Heal/Range"),
|
||||
"rate": getEntityValue("Heal/Rate")
|
||||
"interval": getEntityValue("Heal/Interval")
|
||||
};
|
||||
|
||||
if (template.ResourceGatherer)
|
||||
|
|
|
|||
|
|
@ -826,26 +826,25 @@ function getHealerTooltip(template)
|
|||
if (!template.heal)
|
||||
return "";
|
||||
|
||||
let hp = +(template.heal.hp.toFixed(1));
|
||||
let health = +(template.heal.health.toFixed(1));
|
||||
let range = +(template.heal.range.toFixed(0));
|
||||
let rate = +((template.heal.rate / 1000).toFixed(1));
|
||||
let interval = +((template.heal.interval / 1000).toFixed(1));
|
||||
|
||||
return [
|
||||
sprintf(translatePlural("%(label)s %(val)s %(unit)s", "%(label)s %(val)s %(unit)s", hp), {
|
||||
sprintf(translatePlural("%(label)s %(val)s %(unit)s", "%(label)s %(val)s %(unit)s", health), {
|
||||
"label": headerFont(translate("Heal:")),
|
||||
"val": hp,
|
||||
// Translation: Short for hit points (or health points) that are healed in one healing action
|
||||
"unit": unitFont(translatePlural("HP", "HP", hp))
|
||||
"val": health,
|
||||
"unit": unitFont(translate("Health"))
|
||||
}),
|
||||
sprintf(translatePlural("%(label)s %(val)s %(unit)s", "%(label)s %(val)s %(unit)s", range), {
|
||||
"label": headerFont(translate("Range:")),
|
||||
"val": range,
|
||||
"unit": unitFont(translatePlural("meter", "meters", range))
|
||||
}),
|
||||
sprintf(translatePlural("%(label)s %(val)s %(unit)s", "%(label)s %(val)s %(unit)s", rate), {
|
||||
"label": headerFont(translate("Rate:")),
|
||||
"val": rate,
|
||||
"unit": unitFont(translatePlural("second", "seconds", rate))
|
||||
sprintf(translatePlural("%(label)s %(val)s %(unit)s", "%(label)s %(val)s %(unit)s", interval), {
|
||||
"label": headerFont(translate("Interval:")),
|
||||
"val": interval,
|
||||
"unit": unitFont(translatePlural("second", "seconds", interval))
|
||||
})
|
||||
].join(translate(", "));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,9 +501,9 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
|
|||
let cmpHeal = Engine.QueryInterface(ent, IID_Heal);
|
||||
if (cmpHeal)
|
||||
ret.heal = {
|
||||
"hp": cmpHeal.GetHP(),
|
||||
"health": cmpHeal.GetHealth(),
|
||||
"range": cmpHeal.GetRange().max,
|
||||
"rate": cmpHeal.GetRate(),
|
||||
"interval": cmpHeal.GetInterval(),
|
||||
"unhealableClasses": cmpHeal.GetUnhealableClasses(),
|
||||
"healableClasses": cmpHeal.GetHealableClasses()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ Heal.prototype.Schema =
|
|||
"<LineTextureMask>heal_overlay_range_mask.png</LineTextureMask>" +
|
||||
"<LineThickness>0.35</LineThickness>" +
|
||||
"</RangeOverlay>" +
|
||||
"<HP>5</HP>" +
|
||||
"<Rate>2000</Rate>" +
|
||||
"<Health>5</Health>" +
|
||||
"<Interval>2000</Interval>" +
|
||||
"<UnhealableClasses datatype=\"tokens\">Cavalry</UnhealableClasses>" +
|
||||
"<HealableClasses datatype=\"tokens\">Support Infantry</HealableClasses>" +
|
||||
"</a:example>" +
|
||||
"<element name='Range' a:help='Range (in metres) where healing is possible'>" +
|
||||
"<element name='Range' a:help='Range (in metres) where healing is possible.'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<optional>" +
|
||||
|
|
@ -26,19 +26,19 @@ Heal.prototype.Schema =
|
|||
"</interleave>" +
|
||||
"</element>" +
|
||||
"</optional>" +
|
||||
"<element name='HP' a:help='Hitpoints healed per Rate'>" +
|
||||
"<element name='Health' a:help='Health healed per Interval.'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='Rate' a:help='A heal is performed every Rate ms'>" +
|
||||
"<element name='Interval' a:help='A heal is performed every Interval ms.'>" +
|
||||
"<ref name='nonNegativeDecimal'/>" +
|
||||
"</element>" +
|
||||
"<element name='UnhealableClasses' a:help='If the target has any of these classes it can not be healed (even if it has a class from HealableClasses)'>" +
|
||||
"<element name='UnhealableClasses' a:help='If the target has any of these classes it can not be healed (even if it has a class from HealableClasses).'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"<element name='HealableClasses' a:help='The target must have one of these classes to be healable'>" +
|
||||
"<element name='HealableClasses' a:help='The target must have one of these classes to be healable.'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
|
|
@ -49,24 +49,25 @@ Heal.prototype.Init = function()
|
|||
{
|
||||
};
|
||||
|
||||
Heal.prototype.Serialize = null; // we have no dynamic state to save
|
||||
// We have no dynamic state to save.
|
||||
Heal.prototype.Serialize = null;
|
||||
|
||||
Heal.prototype.GetTimers = function()
|
||||
{
|
||||
return {
|
||||
"prepare": 1000,
|
||||
"repeat": this.GetRate()
|
||||
"repeat": this.GetInterval()
|
||||
};
|
||||
};
|
||||
|
||||
Heal.prototype.GetHP = function()
|
||||
Heal.prototype.GetHealth = function()
|
||||
{
|
||||
return ApplyValueModificationsToEntity("Heal/HP", +this.template.HP, this.entity);
|
||||
return ApplyValueModificationsToEntity("Heal/Health", +this.template.Health, this.entity);
|
||||
};
|
||||
|
||||
Heal.prototype.GetRate = function()
|
||||
Heal.prototype.GetInterval = function()
|
||||
{
|
||||
return ApplyValueModificationsToEntity("Heal/Rate", +this.template.Rate, this.entity);
|
||||
return ApplyValueModificationsToEntity("Heal/Interval", +this.template.Interval, this.entity);
|
||||
};
|
||||
|
||||
Heal.prototype.GetRange = function()
|
||||
|
|
@ -138,14 +139,14 @@ Heal.prototype.PerformHeal = function(target)
|
|||
if (!cmpHealth)
|
||||
return;
|
||||
|
||||
let targetState = cmpHealth.Increase(this.GetHP());
|
||||
let targetState = cmpHealth.Increase(this.GetHealth());
|
||||
|
||||
// Add XP
|
||||
// Add experience.
|
||||
let cmpLoot = Engine.QueryInterface(target, IID_Loot);
|
||||
let cmpPromotion = Engine.QueryInterface(this.entity, IID_Promotion);
|
||||
if (targetState !== undefined && cmpLoot && cmpPromotion)
|
||||
{
|
||||
// HP healed * XP per HP
|
||||
// Health healed times experience per health.
|
||||
cmpPromotion.IncreaseXp((targetState.new - targetState.old) / cmpHealth.GetMaxHitpoints() * cmpLoot.GetXp());
|
||||
}
|
||||
// TODO we need a sound file
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ let template = {
|
|||
"LineTextureMask": "heal_overlay_range_mask.png",
|
||||
"LineThickness": 0.35
|
||||
},
|
||||
"HP": 5,
|
||||
"Rate": 2000,
|
||||
"Health": 5,
|
||||
"Interval": 2000,
|
||||
"UnhealableClasses": { "_string": "Cavalry" },
|
||||
"HealableClasses": { "_string": "Support Infantry" },
|
||||
};
|
||||
|
|
@ -47,9 +47,9 @@ ApplyValueModificationsToEntity = function(value, stat, ent)
|
|||
return stat;
|
||||
switch (value)
|
||||
{
|
||||
case "Heal/HP":
|
||||
case "Heal/Health":
|
||||
return stat + 100;
|
||||
case "Heal/Rate":
|
||||
case "Heal/Interval":
|
||||
return stat + 200;
|
||||
case "Heal/Range":
|
||||
return stat + 300;
|
||||
|
|
@ -61,11 +61,11 @@ ApplyValueModificationsToEntity = function(value, stat, ent)
|
|||
let cmpHeal = ConstructComponent(60, "Heal", template);
|
||||
|
||||
// Test Getters
|
||||
TS_ASSERT_EQUALS(cmpHeal.GetRate(), 2000 + 200);
|
||||
TS_ASSERT_EQUALS(cmpHeal.GetInterval(), 2000 + 200);
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpHeal.GetTimers(), { "prepare": 1000, "repeat": 2000 + 200 });
|
||||
|
||||
TS_ASSERT_EQUALS(cmpHeal.GetHP(), 5 + 100);
|
||||
TS_ASSERT_EQUALS(cmpHeal.GetHealth(), 5 + 100);
|
||||
|
||||
TS_ASSERT_UNEVAL_EQUALS(cmpHeal.GetRange(), { "min": 0, "max": 20 + 300 });
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ AddMock(entity, IID_UnitAI, {
|
|||
}
|
||||
});
|
||||
|
||||
cmpHeal.OnValueModification({ "component": "Heal", "valueNames": ["Heal/HP"] });
|
||||
cmpHeal.OnValueModification({ "component": "Heal", "valueNames": ["Heal/Health"] });
|
||||
TS_ASSERT(!updated);
|
||||
|
||||
cmpHeal.OnValueModification({ "component": "Heal", "valueNames": ["Heal/Range"] });
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
"requirementsTooltip": "Unlocked in Town Phase.",
|
||||
"icon": "healing_rate.png",
|
||||
"researchTime": 40,
|
||||
"tooltip": "Healers +25% healing rate.",
|
||||
"tooltip": "Healers −20% healing time.",
|
||||
"modifications": [
|
||||
{ "value": "Heal/Rate", "multiply": 0.8 }
|
||||
{ "value": "Heal/Interval", "multiply": 0.8 }
|
||||
],
|
||||
"affects": ["Healer"],
|
||||
"soundComplete": "interface/alarm/alarm_upgradearmory.xml"
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
"requirementsTooltip": "Unlocked in City Phase.",
|
||||
"icon": "healing_rate.png",
|
||||
"researchTime": 40,
|
||||
"tooltip": "Healers +25% healing rate.",
|
||||
"tooltip": "Healers −20% healing time.",
|
||||
"modifications": [
|
||||
{ "value": "Heal/Rate", "multiply": 0.8 }
|
||||
{ "value": "Heal/Interval", "multiply": 0.8 }
|
||||
],
|
||||
"affects": ["Healer"],
|
||||
"soundComplete": "interface/alarm/alarm_upgradearmory.xml"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
{ "value": "Cost/BuildTime", "multiply": 1.2 },
|
||||
{ "value": "Health/Max", "multiply": 1.1 },
|
||||
{ "value": "Heal/Range", "add": 3, "affects": "Healer" },
|
||||
{ "value": "Heal/HP", "add": 5, "affects": "Healer" },
|
||||
{ "value": "Heal/Health", "add": 5, "affects": "Healer" },
|
||||
{ "value": "Loot/food", "multiply": 1.2 },
|
||||
{ "value": "Loot/wood", "multiply": 1.2 },
|
||||
{ "value": "Loot/stone", "multiply": 1.2 },
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
{ "value": "Cost/BuildTime", "multiply": 1.2 },
|
||||
{ "value": "Health/Max", "multiply": 1.1 },
|
||||
{ "value": "Heal/Range", "add": 3, "affects": "Healer" },
|
||||
{ "value": "Heal/HP", "add": 5, "affects": "Healer" },
|
||||
{ "value": "Heal/Health", "add": 5, "affects": "Healer" },
|
||||
{ "value": "Loot/food", "multiply": 1.2 },
|
||||
{ "value": "Loot/wood", "multiply": 1.2 },
|
||||
{ "value": "Loot/stone", "multiply": 1.2 },
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@
|
|||
</Cost>
|
||||
<Heal>
|
||||
<Range>20</Range>
|
||||
<HP>6</HP>
|
||||
<Rate>2000</Rate>
|
||||
<UnhealableClasses datatype="tokens"/>
|
||||
<HealableClasses datatype="tokens">Human</HealableClasses>
|
||||
<RangeOverlay>
|
||||
<LineTexture>heal_overlay_range.png</LineTexture>
|
||||
<LineTextureMask>heal_overlay_range_mask.png</LineTextureMask>
|
||||
<LineThickness>0.35</LineThickness>
|
||||
</RangeOverlay>
|
||||
<Health>6</Health>
|
||||
<Interval>2000</Interval>
|
||||
<UnhealableClasses datatype="tokens"/>
|
||||
<HealableClasses datatype="tokens">Human</HealableClasses>
|
||||
</Heal>
|
||||
<Health>
|
||||
<Max>1000</Max>
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@
|
|||
</Cost>
|
||||
<Heal>
|
||||
<Range>12</Range>
|
||||
<HP>5</HP>
|
||||
<Rate>2000</Rate>
|
||||
<UnhealableClasses datatype="tokens"/>
|
||||
<HealableClasses datatype="tokens">Human</HealableClasses>
|
||||
<RangeOverlay>
|
||||
<LineTexture>heal_overlay_range.png</LineTexture>
|
||||
<LineTextureMask>heal_overlay_range_mask.png</LineTextureMask>
|
||||
<LineThickness>0.35</LineThickness>
|
||||
</RangeOverlay>
|
||||
<Health>5</Health>
|
||||
<Interval>2000</Interval>
|
||||
<UnhealableClasses datatype="tokens"/>
|
||||
<HealableClasses datatype="tokens">Human</HealableClasses>
|
||||
</Heal>
|
||||
<Health>
|
||||
<Max>85</Max>
|
||||
|
|
|
|||
Loading…
Reference in a new issue