Fixed formations so switching formation in-place doesn't leave entities in FORMATIONMEMBER.WALKING and short walk orders bring units into proper formation.
This was SVN commit r12563.
This commit is contained in:
parent
d98c62f00a
commit
9fcb7cc738
@ -8,6 +8,7 @@ var g_ColumnDistanceThreshold = 128; // distance at which we'll switch between c
|
||||
Formation.prototype.Init = function()
|
||||
{
|
||||
this.members = []; // entity IDs currently belonging to this formation
|
||||
this.inPosition = []; // entities that have reached their final position
|
||||
this.columnar = false; // whether we're travelling in column (vs box) formation
|
||||
this.formationName = "Line Closed";
|
||||
this.rearrange = true; // whether we should rearrange all formation members
|
||||
@ -30,6 +31,29 @@ Formation.prototype.GetPrimaryMember = function()
|
||||
return this.members[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Permits formation members to register that they've reached their
|
||||
* destination, and automatically disbands the formation if all members
|
||||
* are at their final positions and no controller orders remain.
|
||||
*/
|
||||
Formation.prototype.SetInPosition = function(ent)
|
||||
{
|
||||
if (this.inPosition.indexOf(ent) != -1)
|
||||
return;
|
||||
|
||||
// Only consider automatically disbanding if there are no orders left.
|
||||
var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI);
|
||||
if (cmpUnitAI.GetOrders().length)
|
||||
{
|
||||
this.inPosition = [];
|
||||
return;
|
||||
}
|
||||
|
||||
this.inPosition.push(ent);
|
||||
if (this.inPosition.length >= this.members.length)
|
||||
this.Disband();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether we should rearrange formation members if
|
||||
* units are removed from the formation.
|
||||
@ -67,6 +91,7 @@ Formation.prototype.SetMembers = function(ents)
|
||||
Formation.prototype.RemoveMembers = function(ents)
|
||||
{
|
||||
this.members = this.members.filter(function(e) { return ents.indexOf(e) == -1; });
|
||||
this.inPosition = this.inPosition.filter(function(e) { return ents.indexOf(e) == -1; });
|
||||
|
||||
for each (var ent in ents)
|
||||
{
|
||||
@ -102,6 +127,7 @@ Formation.prototype.Disband = function()
|
||||
}
|
||||
|
||||
this.members = [];
|
||||
this.inPosition = [];
|
||||
|
||||
Engine.DestroyEntity(this.entity);
|
||||
};
|
||||
|
@ -593,11 +593,7 @@ var UnitFsmSpec = {
|
||||
},
|
||||
|
||||
"MoveCompleted": function(msg) {
|
||||
if (this.FinishOrder())
|
||||
return;
|
||||
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
cmpFormation.Disband();
|
||||
this.FinishOrder();
|
||||
},
|
||||
},
|
||||
|
||||
@ -674,9 +670,13 @@ var UnitFsmSpec = {
|
||||
this.SelectAnimation("move");
|
||||
},
|
||||
|
||||
// (We stay in this state even if we're already in position
|
||||
// and no longer moving, because the formation controller might
|
||||
// move and we'll automatically start chasing after it again)
|
||||
// Occurs when the unit has reached its destination and the controller
|
||||
// is done moving. The controller is notified, and will disband the
|
||||
// formation if all units are in formation and no orders remain.
|
||||
"MoveCompleted": function(msg) {
|
||||
var cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
|
||||
cmpFormation.SetInPosition(this.entity);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -390,6 +390,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsMoving()
|
||||
{
|
||||
return m_State != STATE_IDLE;
|
||||
}
|
||||
|
||||
virtual fixed GetWalkSpeed()
|
||||
{
|
||||
return m_WalkSpeed;
|
||||
@ -903,9 +908,15 @@ void CCmpUnitMotion::Move(fixed dt)
|
||||
{
|
||||
if (IsFormationMember())
|
||||
{
|
||||
// If we're in formation, we've reached our assigned position.
|
||||
// so wait here.
|
||||
// (We'll try to continue following the formation next turn.)
|
||||
// We've reached our assigned position. If the controller
|
||||
// is idle, send a notification in case it should disband,
|
||||
// otherwise continue following the formation next turn.
|
||||
CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), m_TargetEntity);
|
||||
if (cmpUnitMotion && !cmpUnitMotion->IsMoving())
|
||||
{
|
||||
CMessageMotionChanged msg(false, false);
|
||||
GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1512,7 +1523,7 @@ bool CCmpUnitMotion::IsInTargetRange(entity_id_t target, entity_pos_t minRange,
|
||||
|
||||
void CCmpUnitMotion::MoveToFormationOffset(entity_id_t target, entity_pos_t x, entity_pos_t z)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), target);
|
||||
if (!cmpPosition || !cmpPosition->IsInWorld())
|
||||
return;
|
||||
|
||||
|
@ -30,6 +30,7 @@ DEFINE_INTERFACE_METHOD_3("MoveToFormationOffset", void, ICmpUnitMotion, MoveToF
|
||||
DEFINE_INTERFACE_METHOD_2("FaceTowardsPoint", void, ICmpUnitMotion, FaceTowardsPoint, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_0("StopMoving", void, ICmpUnitMotion, StopMoving)
|
||||
DEFINE_INTERFACE_METHOD_1("SetSpeed", void, ICmpUnitMotion, SetSpeed, fixed)
|
||||
DEFINE_INTERFACE_METHOD_0("IsMoving", bool, ICmpUnitMotion, IsMoving)
|
||||
DEFINE_INTERFACE_METHOD_0("GetWalkSpeed", fixed, ICmpUnitMotion, GetWalkSpeed)
|
||||
DEFINE_INTERFACE_METHOD_0("GetRunSpeed", fixed, ICmpUnitMotion, GetRunSpeed)
|
||||
DEFINE_INTERFACE_METHOD_1("SetUnitRadius", void, ICmpUnitMotion, SetUnitRadius, fixed)
|
||||
@ -76,6 +77,11 @@ public:
|
||||
m_Script.CallVoid("SetSpeed", speed);
|
||||
}
|
||||
|
||||
virtual bool IsMoving()
|
||||
{
|
||||
return m_Script.Call<bool>("IsMoving");
|
||||
}
|
||||
|
||||
virtual fixed GetWalkSpeed()
|
||||
{
|
||||
return m_Script.Call<fixed>("GetWalkSpeed");
|
||||
|
@ -83,6 +83,11 @@ public:
|
||||
*/
|
||||
virtual void SetSpeed(fixed speed) = 0;
|
||||
|
||||
/**
|
||||
* Get whether the unit is moving.
|
||||
*/
|
||||
virtual bool IsMoving() = 0;
|
||||
|
||||
/**
|
||||
* Get the default speed that this unit will have when walking, in metres per second.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user