Fix bug with gather-near-position.
Use the max range for attacking. This was SVN commit r12915.
This commit is contained in:
parent
a4f27dc3e0
commit
5806ed94e1
@ -188,6 +188,23 @@ Formation.prototype.TestAllMemberFunction = function(funcname, args)
|
||||
return true;
|
||||
};
|
||||
|
||||
Formation.prototype.GetMaxAttackRangeFunction = function(target)
|
||||
{
|
||||
var result = 0;
|
||||
var range = 0;
|
||||
for each (var ent in this.members)
|
||||
{
|
||||
var cmpAttack = Engine.QueryInterface(ent, IID_Attack);
|
||||
if (!cmpAttack)
|
||||
continue;
|
||||
|
||||
range = cmpAttack.GetRange(cmpAttack.GetBestAttackAgainst(target));
|
||||
if (range.max > result)
|
||||
result = range.max;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set all members to form up into the formation shape.
|
||||
* If moveCenter is true, the formation center will be reinitialised
|
||||
|
@ -613,7 +613,14 @@ var UnitFsmSpec = {
|
||||
|
||||
// Only used by other orders to walk there in formation
|
||||
"Order.WalkToTargetRange": function(msg) {
|
||||
if(this.MoveToTargetRangeExplicit(this.order.data.target, this.order.data.min, this.order.data.max))
|
||||
if (this.MoveToTargetRangeExplicit(this.order.data.target, this.order.data.min, this.order.data.max))
|
||||
this.SetNextState("WALKING");
|
||||
else
|
||||
this.FinishOrder();
|
||||
},
|
||||
|
||||
"Order.WalkToPointRange": function(msg) {
|
||||
if (this.MoveToPointRange(this.order.data.x, this.order.data.z, this.order.data.min, this.order.data.max))
|
||||
this.SetNextState("WALKING");
|
||||
else
|
||||
this.FinishOrder();
|
||||
@ -626,20 +633,21 @@ var UnitFsmSpec = {
|
||||
},
|
||||
|
||||
"Order.Attack": function(msg) {
|
||||
// TODO: on what should we base this range?
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
|
||||
var maxRange = cmpFormation.GetMaxAttackRangeFunction(msg.data.target);
|
||||
// Check if we are already in range, otherwise walk there
|
||||
if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 20))
|
||||
if (!this.CheckTargetRangeExplicit(msg.data.target, 0, maxRange))
|
||||
{
|
||||
if (!this.TargetIsAlive(msg.data.target))
|
||||
// The target was destroyed
|
||||
this.FinishOrder();
|
||||
else
|
||||
// Out of range; move there in formation
|
||||
this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 20 });
|
||||
this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": maxRange });
|
||||
return;
|
||||
}
|
||||
|
||||
var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
|
||||
// We don't want to rearrange the formation if the individual units are carrying
|
||||
// out a task and one of the members dies/leaves the formation.
|
||||
cmpFormation.SetRearrange(false);
|
||||
@ -699,14 +707,10 @@ var UnitFsmSpec = {
|
||||
"Order.GatherNearPosition": function(msg) {
|
||||
// TODO: on what should we base this range?
|
||||
// Check if we are already in range, otherwise walk there
|
||||
if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 20))
|
||||
if (!this.CheckPointRangeExplicit(msg.data.x, msg.data.z, 0, 20))
|
||||
{
|
||||
if (!this.TargetIsAlive(msg.data.target))
|
||||
// The target was destroyed
|
||||
this.FinishOrder();
|
||||
else
|
||||
// Out of range; move there in formation
|
||||
this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 20 });
|
||||
// Out of range; move there in formation
|
||||
this.PushOrderFront("WalkToPointRange", { "x": msg.data.x, "z": msg.data.z, "min": 0, "max": 20 });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2979,6 +2983,12 @@ UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max)
|
||||
return cmpUnitMotion.MoveToTargetRange(target, min, max);
|
||||
};
|
||||
|
||||
UnitAI.prototype.CheckPointRangeExplicit = function(x, z, min, max)
|
||||
{
|
||||
var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
|
||||
return cmpUnitMotion.IsInPointRange(x, z, min, max);
|
||||
};
|
||||
|
||||
UnitAI.prototype.CheckTargetRange = function(target, iid, type)
|
||||
{
|
||||
var cmpRanged = Engine.QueryInterface(this.entity, iid);
|
||||
@ -3306,6 +3316,7 @@ UnitAI.prototype.ComputeWalkingDistance = function()
|
||||
switch (order.type)
|
||||
{
|
||||
case "Walk":
|
||||
case "WalkToPointRange":
|
||||
case "MoveIntoFormation":
|
||||
case "GatherNearPosition":
|
||||
// Add the distance to the target point
|
||||
|
@ -156,6 +156,18 @@ UnitMotionFlying.prototype.MoveToTargetRange = function(target, minRange, maxRan
|
||||
return true;
|
||||
};
|
||||
|
||||
UnitMotionFlying.prototype.IsInPointRange = function(x, y, minRange, maxRange)
|
||||
{
|
||||
var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
|
||||
var pos = cmpPosition.GetPosition2D();
|
||||
|
||||
var distFromTarget = Math.sqrt(Math.pow(x - pos.x, 2) + Math.pow(y - pos.y, 2));
|
||||
if (minRange <= distFromTarget && distFromTarget <= maxRange)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
UnitMotionFlying.prototype.IsInTargetRange = function(target, minRange, maxRange)
|
||||
{
|
||||
var cmpTargetPosition = Engine.QueryInterface(target, IID_Position);
|
||||
@ -164,14 +176,7 @@ UnitMotionFlying.prototype.IsInTargetRange = function(target, minRange, maxRange
|
||||
|
||||
var targetPos = cmpTargetPosition.GetPosition2D();
|
||||
|
||||
var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
|
||||
var pos = cmpPosition.GetPosition2D();
|
||||
|
||||
var distFromTarget = Math.sqrt(Math.pow(targetPos.x - pos.x, 2) + Math.pow(targetPos.y - pos.y, 2));
|
||||
if (minRange <= distFromTarget && distFromTarget <= maxRange)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return this.IsInPointRange(targetPos.x, targetPos.y, minRange, maxRange);
|
||||
};
|
||||
|
||||
UnitMotionFlying.prototype.GetWalkSpeed = function()
|
||||
|
@ -423,6 +423,7 @@ public:
|
||||
}
|
||||
|
||||
virtual bool MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange);
|
||||
virtual bool IsInPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange);
|
||||
virtual bool MoveToTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange);
|
||||
virtual bool IsInTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange);
|
||||
virtual void MoveToFormationOffset(entity_id_t target, entity_pos_t x, entity_pos_t z);
|
||||
@ -1320,6 +1321,55 @@ bool CCmpUnitMotion::MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCmpUnitMotion::IsInPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), GetEntityId());
|
||||
if (!cmpPosition || !cmpPosition->IsInWorld())
|
||||
return false;
|
||||
|
||||
CFixedVector2D pos = cmpPosition->GetPosition2D();
|
||||
|
||||
bool hasObstruction = false;
|
||||
CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
|
||||
ICmpObstructionManager::ObstructionSquare obstruction;
|
||||
if (cmpObstructionManager)
|
||||
hasObstruction = cmpObstructionManager->FindMostImportantObstruction(GetObstructionFilter(true), x, z, m_Radius, obstruction);
|
||||
|
||||
if (minRange.IsZero() && maxRange.IsZero() && hasObstruction)
|
||||
{
|
||||
// Handle the non-ranged mode:
|
||||
CFixedVector2D halfSize(obstruction.hw, obstruction.hh);
|
||||
entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
|
||||
|
||||
// See if we're too close to the target square
|
||||
if (distance < minRange)
|
||||
return false;
|
||||
|
||||
// See if we're close enough to the target square
|
||||
if (maxRange < entity_pos_t::Zero() || distance <= maxRange)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
entity_pos_t distance = (pos - CFixedVector2D(x, z)).Length();
|
||||
|
||||
if (distance < minRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (maxRange >= entity_pos_t::Zero() && distance > maxRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCmpUnitMotion::ShouldTreatTargetAsCircle(entity_pos_t range, entity_pos_t hw, entity_pos_t hh, entity_pos_t circleRadius)
|
||||
{
|
||||
// Given a square, plus a target range we should reach, the shape at that distance
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(UnitMotion)
|
||||
DEFINE_INTERFACE_METHOD_4("MoveToPointRange", bool, ICmpUnitMotion, MoveToPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_4("IsInPointRange", bool, ICmpUnitMotion, IsInPointRange, entity_pos_t, entity_pos_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_3("IsInTargetRange", bool, ICmpUnitMotion, IsInTargetRange, entity_id_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_3("MoveToTargetRange", bool, ICmpUnitMotion, MoveToTargetRange, entity_id_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_3("MoveToFormationOffset", void, ICmpUnitMotion, MoveToFormationOffset, entity_id_t, entity_pos_t, entity_pos_t)
|
||||
@ -47,6 +48,11 @@ public:
|
||||
return m_Script.Call<bool>("MoveToPointRange", x, z, minRange, maxRange);
|
||||
}
|
||||
|
||||
virtual bool IsInPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange)
|
||||
{
|
||||
return m_Script.Call<bool>("IsInPointRange", x, z, minRange, maxRange);
|
||||
}
|
||||
|
||||
virtual bool IsInTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange)
|
||||
{
|
||||
return m_Script.Call<bool>("IsInTargetRange", target, minRange, maxRange);
|
||||
|
@ -46,6 +46,12 @@ public:
|
||||
*/
|
||||
virtual bool MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange) = 0;
|
||||
|
||||
/**
|
||||
* Determine wether the givven point is within the given range, using the same measurement
|
||||
* as MoveToPointRange.
|
||||
*/
|
||||
virtual bool IsInPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange) = 0;
|
||||
|
||||
/**
|
||||
* Determine whether the target is within the given range, using the same measurement
|
||||
* as MoveToTargetRange.
|
||||
|
Loading…
Reference in New Issue
Block a user