improve rearrange of idle formation when units are tasked away from the formation + fix formation-settable idle animations

This was SVN commit r14544.
This commit is contained in:
sanderd17 2014-01-08 10:55:44 +00:00
parent e8c4031bea
commit f9b950aa96
3 changed files with 27 additions and 23 deletions

View File

@ -495,7 +495,7 @@ Formation.prototype.MoveMembersIntoFormation = function(moveCenter, force)
this.offsets = undefined;
}
var newOrientation = this.GetTargetOrientation(avgpos);
var newOrientation = this.GetEstimatedOrientation(avgpos);
var dSin = Math.abs(newOrientation.sin - this.oldOrientation.sin);
var dCos = Math.abs(newOrientation.cos - this.oldOrientation.cos);
// If the formation existed, only recalculate positions if the turning agle is somewhat biggish
@ -807,7 +807,7 @@ Formation.prototype.TakeClosestOffset = function(entPos, realPositions)
Formation.prototype.GetRealOffsetPositions = function(offsets, pos)
{
var offsetPositions = [];
var {sin, cos} = this.GetTargetOrientation(pos);
var {sin, cos} = this.GetEstimatedOrientation(pos);
// calculate the world positions
for each (var o in offsets)
offsetPositions.push({
@ -822,27 +822,37 @@ Formation.prototype.GetRealOffsetPositions = function(offsets, pos)
/**
* calculate the estimated rotation of the formation
* based on the first unitAI target position
* based on the first unitAI target position when ordered to walk,
* based on the current rotation in other cases
* Return the sine and cosine of the angle
*/
Formation.prototype.GetTargetOrientation = function(pos)
Formation.prototype.GetEstimatedOrientation = function(pos)
{
var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
var targetPos = cmpUnitAI.GetTargetPositions();
var sin = 0;
var cos = 1;
if (targetPos.length)
var r = {"sin": 0, "cos": 1};
if (cmpUnitAI.GetCurrentState() == "FORMATIONCONTROLLER.WALKING")
{
var targetPos = cmpUnitAI.GetTargetPositions();
if (!targetPos.length)
return r;
var dx = targetPos[0].x - pos.x;
var dz = targetPos[0].z - pos.z;
if (dx || dz)
{
var dist = Math.sqrt(dx * dx + dz * dz);
cos = dz / dist;
sin = dx / dist;
}
if (!dx && !dz)
return r;
var dist = Math.sqrt(dx * dx + dz * dz);
r.cos = dz / dist;
r.sin = dx / dist;
}
return {"sin": sin, "cos": cos};
else
{
var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
if (!cmpPosition)
return r;
var rot = cmpPosition.GetRotation().y;
r.sin = Math.sin(rot);
r.cos = Math.cos(rot);
}
return r;
};
Formation.prototype.ComputeAveragePosition = function(positions)

View File

@ -1224,13 +1224,10 @@ var UnitFsmSpec = {
this.SetNextState("INDIVIDUAL.IDLE");
return true;
}
var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
if (cmpVisual)
cmpVisual.ReplaceMoveAnimation("idle", cmpFormation.GetFormationAnimation(this.entity, "idle"));
// Switch back to idle animation to guarantee we won't
// get stuck with an incorrect animation
this.SelectAnimation("idle");
this.SelectAnimation(cmpFormation.GetFormationAnimation(this.entity, "idle"));
// If the unit is guarding/escorting, go back to its duty
if (this.isGuardOf)
@ -1277,10 +1274,6 @@ var UnitFsmSpec = {
if (this.losHealRangeQuery)
rangeMan.DisableActiveQuery(this.losHealRangeQuery);
var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
if (cmpVisual)
cmpVisual.ResetMoveAnimation("idle");
this.StopTimer();
if (this.isIdle)

View File

@ -4,5 +4,6 @@
<RequiredMemberCount>9</RequiredMemberCount>
<DisabledTooltip>9 melee infantry units required</DisabledTooltip>
<FormationName>Testudo</FormationName>
<UnitSeparationWidthMultiplier>0.7</UnitSeparationWidthMultiplier>
</Formation>
</Entity>