parent
ddee36e0a8
commit
298115f4c5
@ -602,7 +602,7 @@ var UnitFsmSpec = {
|
||||
|
||||
"Order.ReturnResource": function(msg) {
|
||||
// Try to move to the dropsite
|
||||
if (this.MoveToTarget(this.order.data.target))
|
||||
if (this.MoveToTargetRange(this.order.data.target, IID_ResourceGatherer))
|
||||
{
|
||||
// We've started walking to the target
|
||||
this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING");
|
||||
@ -1706,31 +1706,32 @@ var UnitFsmSpec = {
|
||||
// Check the target is still alive and attackable
|
||||
if (this.TargetIsAlive(target) && this.CanAttack(target, this.order.data.forceResponse || null))
|
||||
{
|
||||
// Check we can still reach the target
|
||||
// If we are hunting, first update the target position of the gather order so we know where will be the killed animal
|
||||
if (this.order.data.hunting && this.orderQueue[1] && this.orderQueue[1].data.lastPos)
|
||||
{
|
||||
var cmpPosition = Engine.QueryInterface(this.order.data.target, IID_Position);
|
||||
if (cmpPosition && cmpPosition.IsInWorld())
|
||||
{
|
||||
// Store the initial position, so that we can find the rest of the herd later
|
||||
if (!this.orderQueue[1].data.initPos)
|
||||
this.orderQueue[1].data.initPos = this.orderQueue[1].data.lastPos;
|
||||
this.orderQueue[1].data.lastPos = cmpPosition.GetPosition();
|
||||
// We still know where the animal is, so we shouldn't give up before going there
|
||||
this.orderQueue[1].data.secondTry = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
this.lastAttacked = cmpTimer.GetTime() - msg.lateness;
|
||||
|
||||
this.FaceTowardsTarget(target);
|
||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||
cmpAttack.PerformAttack(this.order.data.attackType, target);
|
||||
|
||||
|
||||
// Check we can still reach the target for the next attack
|
||||
if (this.CheckTargetAttackRange(target, IID_Attack, this.order.data.attackType))
|
||||
{
|
||||
// If we are hunting, first update the target position of the gather order so we know where will be the killed animal
|
||||
if (this.order.data.hunting && this.orderQueue[1] && this.orderQueue[1].data.lastPos)
|
||||
{
|
||||
var cmpPosition = Engine.QueryInterface(this.order.data.target, IID_Position);
|
||||
if (cmpPosition && cmpPosition.IsInWorld())
|
||||
{
|
||||
// Store the initial position, so that we can find the rest of the herd later
|
||||
if (!this.orderQueue[1].data.initPos)
|
||||
this.orderQueue[1].data.initPos = this.orderQueue[1].data.lastPos;
|
||||
this.orderQueue[1].data.lastPos = cmpPosition.GetPosition();
|
||||
// We still know where the animal is, so we shouldn't give up before going there
|
||||
this.orderQueue[1].data.secondTry = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
this.lastAttacked = cmpTimer.GetTime() - msg.lateness;
|
||||
|
||||
this.FaceTowardsTarget(target);
|
||||
var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
|
||||
cmpAttack.PerformAttack(this.order.data.attackType, target);
|
||||
|
||||
if (this.resyncAnimation)
|
||||
{
|
||||
this.SetAnimationSync(this.attackTimers.repeat, this.attackTimers.repeat);
|
||||
|
@ -11,7 +11,7 @@
|
||||
<Pierce>10.0</Pierce>
|
||||
<Crush>0.0</Crush>
|
||||
<MaxRange>16.0</MaxRange>
|
||||
<MinRange>0.0</MinRange>
|
||||
<MinRange>20.0</MinRange>
|
||||
<ProjectileSpeed>25.0</ProjectileSpeed>
|
||||
<PrepareTime>900</PrepareTime>
|
||||
<RepeatTime>1500</RepeatTime>
|
||||
|
@ -6,7 +6,6 @@
|
||||
<Pierce>20.0</Pierce>
|
||||
<Crush>0.0</Crush>
|
||||
<MaxRange>56.0</MaxRange>
|
||||
<MinRange>0.0</MinRange>
|
||||
<ProjectileSpeed>75.0</ProjectileSpeed>
|
||||
<PrepareTime>1200</PrepareTime>
|
||||
<RepeatTime>2000</RepeatTime>
|
||||
|
@ -6,7 +6,6 @@
|
||||
<Pierce>25.0</Pierce>
|
||||
<Crush>0.0</Crush>
|
||||
<MaxRange>44</MaxRange>
|
||||
<MinRange>0.0</MinRange>
|
||||
<ProjectileSpeed>50.0</ProjectileSpeed>
|
||||
<PrepareTime>1200</PrepareTime>
|
||||
<RepeatTime>2000</RepeatTime>
|
||||
|
@ -442,7 +442,17 @@ public:
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
|
||||
{
|
||||
return GetObstructionSquare(out, true);
|
||||
}
|
||||
|
||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
|
||||
{
|
||||
return GetObstructionSquare(out, false);
|
||||
}
|
||||
|
||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out, bool previousPosition)
|
||||
{
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
|
||||
if (!cmpPosition)
|
||||
@ -455,7 +465,11 @@ public:
|
||||
if (!cmpPosition->IsInWorld())
|
||||
return false; // no obstruction square
|
||||
|
||||
CFixedVector2D pos = cmpPosition->GetPosition2D();
|
||||
CFixedVector2D pos;
|
||||
if (previousPosition)
|
||||
pos = cmpPosition->GetPreviousPosition2D();
|
||||
else
|
||||
pos = cmpPosition->GetPosition2D();
|
||||
if (m_Type == STATIC)
|
||||
out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1);
|
||||
else if (m_Type == UNIT)
|
||||
|
@ -995,10 +995,19 @@ void CCmpUnitMotion::Move(fixed dt)
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if target was reached in case of a moving target
|
||||
CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), m_TargetEntity);
|
||||
if
|
||||
(
|
||||
cmpUnitMotion && cmpUnitMotion->IsMoving() &&
|
||||
MoveToTargetRange(m_TargetEntity, m_TargetMinRange, m_TargetMaxRange)
|
||||
)
|
||||
return;
|
||||
|
||||
// Not in formation, so just finish moving
|
||||
|
||||
StopMoving();
|
||||
|
||||
m_State = STATE_IDLE;
|
||||
MoveSucceeded();
|
||||
|
||||
if (m_FacePointAfterMove)
|
||||
FaceTowardsPointFromPos(pos, m_FinalGoal.x, m_FinalGoal.z);
|
||||
@ -1508,7 +1517,12 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange
|
||||
|
||||
entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
|
||||
|
||||
if (distance < minRange)
|
||||
// compare with previous obstruction
|
||||
ICmpObstructionManager::ObstructionSquare previousObstruction;
|
||||
cmpObstruction->GetPreviousObstructionSquare(previousObstruction);
|
||||
entity_pos_t previousDistance = Geometry::DistanceToSquare(pos - CFixedVector2D(previousObstruction.x, previousObstruction.z), obstruction.u, obstruction.v, halfSize);
|
||||
|
||||
if (distance < minRange && previousDistance < minRange)
|
||||
{
|
||||
// Too close to the square - need to move away
|
||||
|
||||
@ -1523,7 +1537,7 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange
|
||||
goal.hw = obstruction.hw + delta;
|
||||
goal.hh = obstruction.hh + delta;
|
||||
}
|
||||
else if (maxRange < entity_pos_t::Zero() || distance < maxRange)
|
||||
else if (maxRange < entity_pos_t::Zero() || distance < maxRange || previousDistance < maxRange)
|
||||
{
|
||||
// We're already in range - no need to move anywhere
|
||||
if (m_FacePointAfterMove)
|
||||
@ -1554,6 +1568,17 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange
|
||||
return false;
|
||||
}
|
||||
|
||||
entity_pos_t previousCircleDistance = (pos - CFixedVector2D(previousObstruction.x, previousObstruction.z)).Length() - circleRadius;
|
||||
|
||||
if (previousCircleDistance < maxRange)
|
||||
{
|
||||
// We're already in range - no need to move anywhere
|
||||
if (m_FacePointAfterMove)
|
||||
FaceTowardsPointFromPos(pos, goal.x, goal.z);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
entity_pos_t goalDistance = maxRange - g_GoalDelta;
|
||||
|
||||
goal.type = ICmpPathfinder::Goal::CIRCLE;
|
||||
@ -1626,12 +1651,17 @@ bool CCmpUnitMotion::IsInTargetRange(entity_id_t target, entity_pos_t minRange,
|
||||
CFixedVector2D halfSize(obstruction.hw, obstruction.hh);
|
||||
entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
|
||||
|
||||
// compare with previous obstruction
|
||||
ICmpObstructionManager::ObstructionSquare previousObstruction;
|
||||
cmpObstruction->GetPreviousObstructionSquare(previousObstruction);
|
||||
entity_pos_t previousDistance = Geometry::DistanceToSquare(pos - CFixedVector2D(previousObstruction.x, previousObstruction.z), obstruction.u, obstruction.v, halfSize);
|
||||
|
||||
// See if we're too close to the target square
|
||||
if (distance < minRange)
|
||||
if (distance < minRange && previousDistance < minRange)
|
||||
return false;
|
||||
|
||||
// See if we're close enough to the target square
|
||||
if (maxRange < entity_pos_t::Zero() || distance <= maxRange)
|
||||
if (maxRange < entity_pos_t::Zero() || distance <= maxRange || previousDistance <= maxRange)
|
||||
return true;
|
||||
|
||||
entity_pos_t circleRadius = halfSize.Length();
|
||||
@ -1643,6 +1673,11 @@ bool CCmpUnitMotion::IsInTargetRange(entity_id_t target, entity_pos_t minRange,
|
||||
|
||||
entity_pos_t circleDistance = (pos - CFixedVector2D(obstruction.x, obstruction.z)).Length() - circleRadius;
|
||||
|
||||
if (circleDistance <= maxRange)
|
||||
return true;
|
||||
// also check circle around previous position
|
||||
circleDistance = (pos - CFixedVector2D(previousObstruction.x, previousObstruction.z)).Length() - circleRadius;
|
||||
|
||||
if (circleDistance <= maxRange)
|
||||
return true;
|
||||
}
|
||||
@ -1655,14 +1690,12 @@ bool CCmpUnitMotion::IsInTargetRange(entity_id_t target, entity_pos_t minRange,
|
||||
if (!cmpTargetPosition || !cmpTargetPosition->IsInWorld())
|
||||
return false;
|
||||
|
||||
CFixedVector2D targetPos = cmpTargetPosition->GetPosition2D();
|
||||
CFixedVector2D targetPos = cmpTargetPosition->GetPreviousPosition2D();
|
||||
|
||||
entity_pos_t distance = (pos - targetPos).Length();
|
||||
|
||||
if (minRange <= distance && (maxRange < entity_pos_t::Zero() || distance <= maxRange))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return minRange <= distance &&
|
||||
(maxRange < entity_pos_t::Zero() || distance <= maxRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,11 @@ public:
|
||||
*/
|
||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
|
||||
|
||||
/**
|
||||
* Same as the method above, but returns an obstruction shape for the previous turn
|
||||
*/
|
||||
virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
|
||||
|
||||
virtual entity_pos_t GetUnitRadius() = 0;
|
||||
|
||||
virtual bool IsControlPersistent() = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user