Support order defined animation variants for formation

Allows to pass variant name when moving units to formation used by
UnitAi when formation is moving. That variant will be passed as
parameter of order FormationWalk so formationmember can set requested
variant.

This passed variant will be ignored if formation defines own variant
based on position of member.

When none of above is true, that means nor formation nor order defines
variant, member will fallback to default variant in order to show
carried resources if has some what makes it more consistant with
animation variants used in individual state.

Differential Revision: https://code.wildfiregames.com/D2550
This was SVN commit r23352.
This commit is contained in:
Angen
2020-01-09 20:53:13 +00:00
parent 2a363df67d
commit e7ab2c9b3f
2 changed files with 44 additions and 28 deletions
@@ -200,13 +200,13 @@ Formation.prototype.GetPrimaryMember = function()
* Get the formation animation for a certain member of this formation * Get the formation animation for a certain member of this formation
* @param entity The entity ID to get the animation for * @param entity The entity ID to get the animation for
* @return The name of the transformed animation as defined in the template * @return The name of the transformed animation as defined in the template
* E.g. "testudo_row1" * E.g. "testudo_row1" or undefined if does not exist
*/ */
Formation.prototype.GetFormationAnimation = function(entity) Formation.prototype.GetFormationAnimation = function(entity)
{ {
var animationGroup = this.animations; var animationGroup = this.animations;
if (!animationGroup.length || this.columnar || !this.memberPositions[entity]) if (!animationGroup.length || this.columnar || !this.memberPositions[entity])
return "formation"; return undefined;
var row = this.memberPositions[entity].row; var row = this.memberPositions[entity].row;
var column = this.memberPositions[entity].column; var column = this.memberPositions[entity].column;
for (var i = 0; i < animationGroup.length; ++i) for (var i = 0; i < animationGroup.length; ++i)
@@ -237,7 +237,7 @@ Formation.prototype.GetFormationAnimation = function(entity)
return animationGroup[i].animation; return animationGroup[i].animation;
} }
return "formation"; return undefined;
}; };
/** /**
@@ -427,12 +427,13 @@ Formation.prototype.Disband = function()
/** /**
* Set all members to form up into the formation shape. * Set all members to form up into the formation shape.
* If moveCenter is true, the formation center will be reinitialised * @param {boolean} moveCenter - The formation center will be reinitialised
* to the center of the units. * to the center of the units.
* If force is true, all individual orders of the formation units are replaced, * @param {boolean} force - All individual orders of the formation units are replaced,
* otherwise the order to walk into formation is just pushed to the front. * otherwise the order to walk into formation is just pushed to the front.
* @param {string | undefined} variant - Variant to be passed as order parameter.
*/ */
Formation.prototype.MoveMembersIntoFormation = function(moveCenter, force) Formation.prototype.MoveMembersIntoFormation = function(moveCenter, force, variant)
{ {
if (!this.members.length) if (!this.members.length)
return; return;
@@ -510,7 +511,8 @@ Formation.prototype.MoveMembersIntoFormation = function(moveCenter, force)
"target": this.entity, "target": this.entity,
"x": offset.x, "x": offset.x,
"z": offset.y, "z": offset.y,
"offsetsChanged": offsetsChanged "offsetsChanged": offsetsChanged,
"variant": variant
}; };
cmpUnitAI.AddOrder("FormationWalk", data, !force); cmpUnitAI.AddOrder("FormationWalk", data, !force);
xMax = Math.max(xMax, offset.x); xMax = Math.max(xMax, offset.x);
@@ -1142,7 +1142,7 @@ UnitAI.prototype.UnitFsmSpec = {
} }
let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
cmpFormation.SetRearrange(true); cmpFormation.SetRearrange(true);
cmpFormation.MoveMembersIntoFormation(true, true); cmpFormation.MoveMembersIntoFormation(true, true, "combat");
return false; return false;
}, },
@@ -1181,7 +1181,7 @@ UnitAI.prototype.UnitFsmSpec = {
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
// TODO fix the rearranging while attacking as formation // TODO fix the rearranging while attacking as formation
cmpFormation.SetRearrange(!this.IsAttackingAsFormation()); cmpFormation.SetRearrange(!this.IsAttackingAsFormation());
cmpFormation.MoveMembersIntoFormation(false, false); cmpFormation.MoveMembersIntoFormation(false, false, "combat");
this.StartTimer(200, 200); this.StartTimer(200, 200);
return false; return false;
}, },
@@ -1268,6 +1268,7 @@ UnitAI.prototype.UnitFsmSpec = {
} }
// No orders left, we're an individual now // No orders left, we're an individual now
this.formationAnimationVariant = undefined;
this.SetNextState("INDIVIDUAL.IDLE"); this.SetNextState("INDIVIDUAL.IDLE");
}, },
@@ -1298,7 +1299,13 @@ UnitAI.prototype.UnitFsmSpec = {
let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation); let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
if (cmpFormation) if (cmpFormation)
this.SetAnimationVariant(cmpFormation.GetFormationAnimation(this.entity)); {
this.formationAnimationVariant = cmpFormation.GetFormationAnimation(this.entity);
if (this.formationAnimationVariant)
this.SetAnimationVariant(this.formationAnimationVariant);
else
this.SetDefaultAnimationVariant();
}
return false; return false;
}, },
@@ -1321,8 +1328,14 @@ UnitAI.prototype.UnitFsmSpec = {
{ {
let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation); let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
if (cmpFormation) if (cmpFormation)
this.SetAnimationVariant(cmpFormation.GetFormationAnimation(this.entity)); this.formationAnimationVariant = cmpFormation.GetFormationAnimation(this.entity);
} }
if (this.formationAnimationVariant)
this.SetAnimationVariant(this.formationAnimationVariant);
else if (this.order.data.variant)
this.SetAnimationVariant(this.order.data.variant);
else
this.SetDefaultAnimationVariant();
return false; return false;
}, },
@@ -1368,8 +1381,6 @@ UnitAI.prototype.UnitFsmSpec = {
this.FinishOrder(); this.FinishOrder();
return true; return true;
} }
if (cmpFormation && this.order.data.offsetsChanged)
this.SetAnimationVariant(cmpFormation.GetFormationAnimation(this.entity));
return false; return false;
}, },
@@ -3048,6 +3059,10 @@ UnitAI.prototype.UnitFsmSpec = {
"leave": function() { "leave": function() {
this.StopTimer(); this.StopTimer();
this.ResetAnimation(); this.ResetAnimation();
if (this.formationAnimationVariant)
this.SetAnimationVariant(this.formationAnimationVariant)
else
this.SetDefaultAnimationVariant();
var cmpResistance = Engine.QueryInterface(this.entity, IID_Resistance); var cmpResistance = Engine.QueryInterface(this.entity, IID_Resistance);
cmpResistance.SetInvulnerability(false); cmpResistance.SetInvulnerability(false);
}, },
@@ -3295,6 +3310,8 @@ UnitAI.prototype.Init = function()
this.lastAttacked = undefined; this.lastAttacked = undefined;
this.lastHealed = undefined; this.lastHealed = undefined;
this.formationAnimationVariant = undefined;
this.SetStance(this.template.DefaultStance); this.SetStance(this.template.DefaultStance);
}; };
@@ -4302,30 +4319,27 @@ UnitAI.prototype.SetAnimationVariant = function(type)
}; };
/* /*
* Reset the animation variant to default behavior * Reset the animation variant to default behavior.
* Default behavior is to pick a resource-carrying variant if resources are being carried. * Default behavior is to pick a resource-carrying variant if resources are being carried.
* Otherwise pick nothing in particular. * Otherwise pick nothing in particular.
*/ */
UnitAI.prototype.SetDefaultAnimationVariant = function() UnitAI.prototype.SetDefaultAnimationVariant = function()
{ {
let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
if (!cmpResourceGatherer) if (cmpResourceGatherer)
{ {
this.SetAnimationVariant(""); let type = cmpResourceGatherer.GetLastCarriedType();
return; if (type)
} {
let typename = "carry_" + type.generic;
let type = cmpResourceGatherer.GetLastCarriedType(); // Special case for meat.
if (type) if (type.specific == "meat")
{ typename = "carry_" + type.specific;
let typename = "carry_" + type.generic;
// Special case for meat this.SetAnimationVariant(typename);
if (type.specific == "meat") return;
typename = "carry_" + type.specific; }
this.SetAnimationVariant(typename);
return;
} }
this.SetAnimationVariant(""); this.SetAnimationVariant("");