Fixes stance change during garrison causing instant garrison. Fixes #1184.

Adds range check to garrisoning, with <LoadingRange> element added to
GarrisonHolder. Adds maximum range values to templates (2 for land
units/structures, 10 for ships).
Adds retry to garrison failure due to unreachable target.
Cleans up a few templates.

This was SVN commit r11292.
This commit is contained in:
historic_bruno 2012-03-09 23:33:55 +00:00
parent cba0c42783
commit d1ed264c9b
22 changed files with 109 additions and 65 deletions

View File

@ -1,20 +1,23 @@
function GarrisonHolder() {}
GarrisonHolder.prototype.Schema =
"<element name='Max'>" +
"<element name='Max' a:help='Maximum number of entities which can be garrisoned inside this holder'>" +
"<data type='positiveInteger'/>" +
"</element>" +
"<element name='List'>" +
"<element name='List' a:help='Classes of entities which are allowed to garrison inside this holder (from Identity)'>" +
"<attribute name='datatype'>" +
"<value>tokens</value>" +
"</attribute>" +
"<text/>" +
"</element>" +
"<element name='EjectHealth'>" +
"<element name='EjectHealth' a:help='Percentage of maximum health below which this holder no longer allows garrisoning'>" +
"<ref name='nonNegativeDecimal'/>" +
"</element>" +
"<element name='BuffHeal'>" +
"<element name='BuffHeal' a:help='Number of hit points that will be restored to this holder&apos;s garrisoned units each second'>" +
"<data type='positiveInteger'/>" +
"</element>" +
"<element name='LoadingRange' a:help='The maximum distance from this holder at which entities are allowed to garrison. Should be about 2.0 for land entities and preferably greater for ships'>" +
"<ref name='nonNegativeDecimal'/>" +
"</element>";
/**
@ -29,6 +32,15 @@ GarrisonHolder.prototype.Init = function()
this.healRate = +this.template.BuffHeal;
};
/**
* Return range at which entities can garrison here
*/
GarrisonHolder.prototype.GetLoadingRange = function()
{
var max = +this.template.LoadingRange;
return { "max": max, "min": 0 };
};
/**
* Return the list of entities garrisoned inside
*/

View File

@ -374,9 +374,7 @@ var UnitFsmSpec = {
}
else
{
// TODO: this is probably bogus if the unit was
// unable to move at all - we need to do some range checks
// before actually garrisoning
// We do a range check before actually garrisoning
this.StopMoving();
this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED");
}
@ -1232,18 +1230,36 @@ var UnitFsmSpec = {
"GARRISONED": {
"enter": function() {
var target = this.order.data.target;
// Check that we can still garrison here and that garrisoning succeeds
var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder);
if (this.CanGarrison(target) && cmpGarrisonHolder.Garrison(this.entity))
// Check that we can garrison here
if (this.CanGarrison(target))
{
this.isGarrisoned = true;
}
else
{
// Garrisoning failed for some reason, so finish the order
if (this.FinishOrder())
return;
// Check that we're in range of the garrison target
if (this.CheckGarrisonRange(target))
{
// Check that garrisoning succeeds
if (cmpGarrisonHolder.Garrison(this.entity))
{
this.isGarrisoned = true;
return;
}
}
else
{
// Unable to reach the target, try again
// (or follow if it's a moving target)
if (this.MoveToTarget(target))
{
this.SetNextState("APPROACHING");
return;
}
}
}
// Garrisoning failed for some reason, so finish the order
this.FinishOrder();
return;
},
"Order.Ungarrison": function() {
@ -2008,6 +2024,15 @@ UnitAI.prototype.CheckTargetRange = function(target, iid, type)
return cmpUnitMotion.IsInTargetRange(target, range.min, range.max);
};
UnitAI.prototype.CheckGarrisonRange = function(target)
{
var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder);
var range = cmpGarrisonHolder.GetLoadingRange();
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
return cmpUnitMotion.IsInTargetRange(target, range.min, range.max);
}
/**
* Returns true if the target entity is visible through the FoW/SoD.
*/
@ -2516,7 +2541,9 @@ UnitAI.prototype.SwitchToStance = function(stance)
this.SetHeldPosition(pos.x, pos.z);
this.SetStance(stance);
if (stance == "stand" || stance == "defensive" || stance == "passive")
// Stop moving if switching to stand ground
// TODO: Also stop existing orders in a sensible way
if (stance == "stand")
this.StopMoving();
// Reset the range query, since the range depends on stance

View File

@ -39,9 +39,7 @@
</Footprint>
<GarrisonHolder>
<Max>20</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
<BuffHeal>1</BuffHeal>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
</GarrisonHolder>
<Health>
<Max>3500</Max>

View File

@ -45,9 +45,10 @@
</Footprint>
<GarrisonHolder>
<Max>20</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>3000</Max>

View File

@ -27,9 +27,10 @@
</Footprint>
<GarrisonHolder>
<Max>15</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>2</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>2</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>2000</Max>

View File

@ -37,9 +37,10 @@
</Footprint>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>1200</Max>

View File

@ -23,9 +23,10 @@
</Footprint>
<GarrisonHolder>
<Max>1</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>800</Max>

View File

@ -36,9 +36,10 @@
</Footprint>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>2500</Max>

View File

@ -20,9 +20,10 @@
</Footprint>
<GarrisonHolder>
<Max>10</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>2000</Max>

View File

@ -38,9 +38,10 @@
</Footprint>
<GarrisonHolder>
<Max>20</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>4200</Max>

View File

@ -17,9 +17,10 @@
</Footprint>
<GarrisonHolder>
<Max>10</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Animal</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Animal</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>500</Max>

View File

@ -18,9 +18,10 @@
</Footprint>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>2000</Max>

View File

@ -33,6 +33,7 @@
<EjectHealth>0</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>10</LoadingRange>
</GarrisonHolder>
<Health>
<Max>800</Max>

View File

@ -23,6 +23,7 @@
<EjectHealth>0</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>10</LoadingRange>
</GarrisonHolder>
<Identity>
<GenericName>Fishing Boat</GenericName>

View File

@ -16,6 +16,7 @@
<EjectHealth>0</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>10</LoadingRange>
</GarrisonHolder>
<Health>
<Max>400</Max>

View File

@ -33,6 +33,7 @@
<EjectHealth>0</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>10</LoadingRange>
</GarrisonHolder>
<Health>
<Max>2000</Max>

View File

@ -37,6 +37,7 @@
<EjectHealth>0</EjectHealth>
<List datatype="tokens">Support Infantry Cavalry Siege</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>10</LoadingRange>
</GarrisonHolder>
<Health>
<Max>1400</Max>

View File

@ -48,6 +48,13 @@
<metal>100</metal>
</Resources>
</Cost>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>200</Max>
</Health>

View File

@ -25,9 +25,10 @@
</Cost>
<GarrisonHolder>
<Max>20</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
<LoadingRange>2</LoadingRange>
</GarrisonHolder>
<Health>
<Max>800</Max>

View File

@ -16,9 +16,6 @@
</Footprint>
<GarrisonHolder>
<Max>10</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
</GarrisonHolder>
<Health>
<Max>250</Max>

View File

@ -4,12 +4,6 @@
<Square width="6.75" depth="9.0"/>
<Height>3.0</Height>
</Footprint>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
</GarrisonHolder>
<Identity>
<Civ>iber</Civ>
<SpecificName>Ariete</SpecificName>

View File

@ -20,12 +20,6 @@
<Square width="8.0" depth="12.0"/>
<Height>3.0</Height>
</Footprint>
<GarrisonHolder>
<Max>5</Max>
<EjectHealth>0.1</EjectHealth>
<List datatype="tokens">Support Infantry</List>
<BuffHeal>1</BuffHeal>
</GarrisonHolder>
<Identity>
<Civ>rome</Civ>
<SpecificName>Aries</SpecificName>