Index: binaries/data/mods/public/globalscripts/Templates.js
===================================================================
--- binaries/data/mods/public/globalscripts/Templates.js
+++ binaries/data/mods/public/globalscripts/Templates.js
@@ -220,11 +220,11 @@
},
"minRange": getAttackStat("MinRange"),
"maxRange": getAttackStat("MaxRange"),
- "elevationBonus": getAttackStat("ElevationBonus")
+ "yOrigin": getAttackStat("Origin/Y")
};
ret.attack[type].elevationAdaptedRange = Math.sqrt(ret.attack[type].maxRange *
- (2 * ret.attack[type].elevationBonus + ret.attack[type].maxRange));
+ (2 * ret.attack[type].yOrigin + ret.attack[type].maxRange));
ret.attack[type].repeatTime = getAttackStat("RepeatTime");
if (template.Attack[type].Projectile)
Index: binaries/data/mods/public/gui/session/input.js
===================================================================
--- binaries/data/mods/public/gui/session/input.js
+++ binaries/data/mods/public/gui/session/input.js
@@ -180,14 +180,14 @@
if (placementSupport.attack && placementSupport.attack.Ranged)
{
- let cmd = {
+ const cmd = {
"x": placementSupport.position.x,
"z": placementSupport.position.z,
"range": placementSupport.attack.Ranged.maxRange,
- "elevationBonus": placementSupport.attack.Ranged.elevationBonus
+ "origin": placementSupport.attack.Ranged.yOrigin
};
- let averageRange = Math.round(Engine.GuiInterfaceCall("GetAverageRangeForBuildings", cmd) - cmd.range);
- let range = Math.round(cmd.range);
+ const averageRange = Math.round(Engine.GuiInterfaceCall("GetAverageRangeForBuildings", cmd) - cmd.range);
+ const range = Math.round(cmd.range);
placementSupport.tooltipMessage = sprintf(translatePlural("Basic range: %(range)s meter", "Basic range: %(range)s meters", range), { "range": range }) + "\n" +
sprintf(translatePlural("Average bonus range: %(range)s meter", "Average bonus range: %(range)s meters", averageRange), { "range": averageRange });
}
Index: binaries/data/mods/public/simulation/components/Attack.js
===================================================================
--- binaries/data/mods/public/simulation/components/Attack.js
+++ binaries/data/mods/public/simulation/components/Attack.js
@@ -57,10 +57,14 @@
"" +
"44.0" +
"20.0" +
- "15.0" +
+ "" +
+ "0" +
+ "10.0" +
+ "0" +
+ "" +
"800" +
"1600" +
- "1000" +
+ "1000" +
"" +
"" +
"Cavalry" +
@@ -115,7 +119,19 @@
"" +
"" +
""+
- "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
"" +
"" +
"" +
@@ -135,7 +151,7 @@
"" +
"" +
"" +
- "" +
+ "" +
"" +
"" +
"" +
@@ -438,10 +454,14 @@
let min = +(this.template[type].MinRange || 0);
min = ApplyValueModificationsToEntity("Attack/" + type + "/MinRange", min, this.entity);
- let elevationBonus = +(this.template[type].ElevationBonus || 0);
- elevationBonus = ApplyValueModificationsToEntity("Attack/" + type + "/ElevationBonus", elevationBonus, this.entity);
+ return { "max": max, "min": min };
+};
- return { "max": max, "min": min, "elevationBonus": elevationBonus };
+Attack.prototype.GetAttackYOrigin = function(type)
+{
+ if (!this.template[type].Origin)
+ return 0;
+ return ApplyValueModificationsToEntity("Attack/" + type + "/Origin/Y", +this.template[type].Origin.Y, this.entity);
};
/**
@@ -604,7 +624,7 @@
"target": target,
};
- let delay = +(this.template[type].Delay || 0);
+ let delay = +(this.template[type].EffectDelay || 0);
if (this.template[type].Projectile)
{
@@ -733,7 +753,7 @@
let positionSelf = cmpPositionSelf.GetPosition();
let positionTarget = cmpPositionTarget.GetPosition();
- let heightDifference = positionSelf.y + range.elevationBonus - positionTarget.y;
+ const heightDifference = positionSelf.y + this.GetAttackYOrigin() - positionTarget.y;
range.max = Math.sqrt(Math.square(range.max) + 2 * range.max * heightDifference);
if (range.max < 0)
Index: binaries/data/mods/public/simulation/components/BuildingAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/BuildingAI.js
+++ binaries/data/mods/public/simulation/components/BuildingAI.js
@@ -123,10 +123,11 @@
if (!enemies.length)
return;
- var range = cmpAttack.GetRange(attackType);
+ const range = cmpAttack.GetRange(attackType);
+ const yOriginAttack = cmpAttack.GetAttackYOrigin(attackType);
// This takes entity sizes into accounts, so no need to compensate for structure size.
this.enemyUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(
- this.entity, range.min, range.max, range.elevationBonus,
+ this.entity, range.min, range.max, yOriginAttack,
enemies, IID_Resistance, cmpRangeManager.GetEntityFlagMask("normal"));
cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery);
@@ -151,12 +152,13 @@
if (!cmpPlayer || !cmpPlayer.IsEnemy(0))
return;
- var range = cmpAttack.GetRange(attackType);
+ const range = cmpAttack.GetRange(attackType);
+ const yOriginAttack = cmpAttack.GetAttackYOrigin(attackType);
// This query is only interested in Gaia entities that can attack.
// This takes entity sizes into accounts, so no need to compensate for structure size.
this.gaiaUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(
- this.entity, range.min, range.max, range.elevationBonus,
+ this.entity, range.min, range.max, yOriginAttack,
[0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal"));
cmpRangeManager.EnableActiveQuery(this.gaiaUnitsQuery);
@@ -331,7 +333,8 @@
// so we need to verify them here.
// TODO: perhaps an optional 'precise' mode to range queries would be more performant.
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager);
- let range = cmpAttack.GetRange(attackType);
+ const range = cmpAttack.GetRange(attackType);
+ const yOriginAttack = cmpAttack.GetAttackYOrigin(attackType);
let thisCmpPosition = Engine.QueryInterface(this.entity, IID_Position);
if (!thisCmpPosition.IsInWorld())
@@ -348,7 +351,7 @@
{
// Parabolic range compuation is the same as in UnitAI's MoveToTargetAttackRange.
// h is positive when I'm higher than the target.
- let h = s.y - targetCmpPosition.GetPosition().y + range.elevationBonus;
+ let h = s.y - targetCmpPosition.GetPosition().y + yOriginAttack;
if (h > -range.max / 2 && cmpObstructionManager.IsInTargetRange(
this.entity,
selectedTarget,
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
@@ -474,6 +474,7 @@
let range = cmpAttack.GetRange(type);
ret.attack[type].minRange = range.min;
ret.attack[type].maxRange = range.max;
+ ret.attack[type].yOrigin = cmpAttack.GetAttackYOrigin(type);
let timers = cmpAttack.GetTimers(type);
ret.attack[type].prepareTime = timers.prepare;
@@ -481,18 +482,14 @@
if (type != "Ranged")
{
- // Not a ranged attack, set some defaults.
- ret.attack[type].elevationBonus = 0;
ret.attack[type].elevationAdaptedRange = ret.attack.maxRange;
continue;
}
- ret.attack[type].elevationBonus = range.elevationBonus;
-
if (cmpPosition && cmpPosition.IsInWorld())
// For units, take the range in front of it, no spread, so angle = 0,
// else, take the average elevation around it: angle = 2 * pi.
- ret.attack[type].elevationAdaptedRange = cmpRangeManager.GetElevationAdaptedRange(cmpPosition.GetPosition(), cmpPosition.GetRotation(), range.max, range.elevationBonus, cmpUnitAI ? 0 : 2 * Math.PI);
+ ret.attack[type].elevationAdaptedRange = cmpRangeManager.GetElevationAdaptedRange(cmpPosition.GetPosition(), cmpPosition.GetRotation(), range.max, ret.attack[type].yOrigin, cmpUnitAI ? 0 : 2 * Math.PI);
else
// Not in world, set a default?
ret.attack[type].elevationAdaptedRange = ret.attack.maxRange;
@@ -616,10 +613,10 @@
"z": cmd.z
};
- let elevationBonus = cmd.elevationBonus || 0;
+ const yOrigin = cmd.yOrigin || 0;
let range = cmd.range;
- return cmpRangeManager.GetElevationAdaptedRange(pos, rot, range, elevationBonus, 2 * Math.PI);
+ return cmpRangeManager.GetElevationAdaptedRange(pos, rot, range, yOrigin, 2 * Math.PI);
};
GuiInterface.prototype.GetTemplateData = function(player, data)
Index: binaries/data/mods/public/simulation/components/UnitAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/UnitAI.js
+++ binaries/data/mods/public/simulation/components/UnitAI.js
@@ -4728,7 +4728,7 @@
// Parabolic range compuation is the same as in BuildingAI's FireArrows.
let t = targetCmpPosition.GetPosition();
// h is positive when I'm higher than the target
- let h = s.y - t.y + range.elevationBonus;
+ const h = s.y - t.y + Engine.QueryInterface(this.entity, IID_Attack).GetAttackYOrigin();
let parabolicMaxRange = Math.sqrt(Math.square(range.max) + 2 * range.max * h);
// No negative roots please
@@ -6215,7 +6215,6 @@
* @param {string} type - [Optional]
* @return {Object | undefined} - The range in the form
* { "min": number, "max": number }
- * Object."elevationBonus": number may be present when iid == IID_Attack.
* Returns undefined when the entity does not have the requested component.
*/
UnitAI.prototype.GetRange = function(iid, type, target)
Index: binaries/data/mods/public/simulation/components/tests/test_Damage.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Damage.js
+++ binaries/data/mods/public/simulation/components/tests/test_Damage.js
@@ -44,7 +44,7 @@
},
"MaxRange": 50,
"MinRange": 0,
- "Delay": 0,
+ "EffectDelay": 0,
"Projectile": {
"Speed": 75.0,
"Spread": 0.5,
Index: binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_artillery.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_artillery.xml
+++ binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_artillery.xml
@@ -9,7 +9,11 @@
80
40
- 15
+
+ 0
+ 15
+ 0
+
4500
5000
Index: binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_bolt.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_bolt.xml
+++ binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_bolt.xml
@@ -8,7 +8,11 @@
90
30
- 15
+
+ 0
+ 15
+ 0
+
500
4000
Index: binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_sentry.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_sentry.xml
+++ binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_sentry.xml
@@ -2,7 +2,11 @@
- 9
+
+ 0
+ 9
+ 0
+
Index: binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_stone.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_stone.xml
+++ binaries/data/mods/public/simulation/templates/template_structure_defensive_tower_stone.xml
@@ -2,7 +2,11 @@
- 15
+
+ 0
+ 15
+ 0
+
Index: binaries/data/mods/public/simulation/templates/template_unit_siege_tower.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_siege_tower.xml
+++ binaries/data/mods/public/simulation/templates/template_unit_siege_tower.xml
@@ -9,7 +9,11 @@
55
10
- 10
+
+ 0
+ 10
+ 0
+
1200
2000