parent
ddee36e0a8
commit
298115f4c5
@ -602,7 +602,7 @@ var UnitFsmSpec = {
|
|||||||
|
|
||||||
"Order.ReturnResource": function(msg) {
|
"Order.ReturnResource": function(msg) {
|
||||||
// Try to move to the dropsite
|
// 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
|
// We've started walking to the target
|
||||||
this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING");
|
this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING");
|
||||||
@ -1706,31 +1706,32 @@ var UnitFsmSpec = {
|
|||||||
// Check the target is still alive and attackable
|
// Check the target is still alive and attackable
|
||||||
if (this.TargetIsAlive(target) && this.CanAttack(target, this.order.data.forceResponse || null))
|
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 (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)
|
if (this.resyncAnimation)
|
||||||
{
|
{
|
||||||
this.SetAnimationSync(this.attackTimers.repeat, this.attackTimers.repeat);
|
this.SetAnimationSync(this.attackTimers.repeat, this.attackTimers.repeat);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<Pierce>10.0</Pierce>
|
<Pierce>10.0</Pierce>
|
||||||
<Crush>0.0</Crush>
|
<Crush>0.0</Crush>
|
||||||
<MaxRange>16.0</MaxRange>
|
<MaxRange>16.0</MaxRange>
|
||||||
<MinRange>0.0</MinRange>
|
<MinRange>20.0</MinRange>
|
||||||
<ProjectileSpeed>25.0</ProjectileSpeed>
|
<ProjectileSpeed>25.0</ProjectileSpeed>
|
||||||
<PrepareTime>900</PrepareTime>
|
<PrepareTime>900</PrepareTime>
|
||||||
<RepeatTime>1500</RepeatTime>
|
<RepeatTime>1500</RepeatTime>
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
<Pierce>20.0</Pierce>
|
<Pierce>20.0</Pierce>
|
||||||
<Crush>0.0</Crush>
|
<Crush>0.0</Crush>
|
||||||
<MaxRange>56.0</MaxRange>
|
<MaxRange>56.0</MaxRange>
|
||||||
<MinRange>0.0</MinRange>
|
|
||||||
<ProjectileSpeed>75.0</ProjectileSpeed>
|
<ProjectileSpeed>75.0</ProjectileSpeed>
|
||||||
<PrepareTime>1200</PrepareTime>
|
<PrepareTime>1200</PrepareTime>
|
||||||
<RepeatTime>2000</RepeatTime>
|
<RepeatTime>2000</RepeatTime>
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
<Pierce>25.0</Pierce>
|
<Pierce>25.0</Pierce>
|
||||||
<Crush>0.0</Crush>
|
<Crush>0.0</Crush>
|
||||||
<MaxRange>44</MaxRange>
|
<MaxRange>44</MaxRange>
|
||||||
<MinRange>0.0</MinRange>
|
|
||||||
<ProjectileSpeed>50.0</ProjectileSpeed>
|
<ProjectileSpeed>50.0</ProjectileSpeed>
|
||||||
<PrepareTime>1200</PrepareTime>
|
<PrepareTime>1200</PrepareTime>
|
||||||
<RepeatTime>2000</RepeatTime>
|
<RepeatTime>2000</RepeatTime>
|
||||||
|
@ -442,7 +442,17 @@ public:
|
|||||||
return m_Tag;
|
return m_Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
|
||||||
|
{
|
||||||
|
return GetObstructionSquare(out, true);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
|
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
|
||||||
|
{
|
||||||
|
return GetObstructionSquare(out, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out, bool previousPosition)
|
||||||
{
|
{
|
||||||
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
|
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
|
||||||
if (!cmpPosition)
|
if (!cmpPosition)
|
||||||
@ -455,7 +465,11 @@ public:
|
|||||||
if (!cmpPosition->IsInWorld())
|
if (!cmpPosition->IsInWorld())
|
||||||
return false; // no obstruction square
|
return false; // no obstruction square
|
||||||
|
|
||||||
CFixedVector2D pos = cmpPosition->GetPosition2D();
|
CFixedVector2D pos;
|
||||||
|
if (previousPosition)
|
||||||
|
pos = cmpPosition->GetPreviousPosition2D();
|
||||||
|
else
|
||||||
|
pos = cmpPosition->GetPosition2D();
|
||||||
if (m_Type == STATIC)
|
if (m_Type == STATIC)
|
||||||
out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1);
|
out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1);
|
||||||
else if (m_Type == UNIT)
|
else if (m_Type == UNIT)
|
||||||
|
@ -995,10 +995,19 @@ void CCmpUnitMotion::Move(fixed dt)
|
|||||||
}
|
}
|
||||||
else
|
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
|
// Not in formation, so just finish moving
|
||||||
|
|
||||||
StopMoving();
|
StopMoving();
|
||||||
|
m_State = STATE_IDLE;
|
||||||
|
MoveSucceeded();
|
||||||
|
|
||||||
if (m_FacePointAfterMove)
|
if (m_FacePointAfterMove)
|
||||||
FaceTowardsPointFromPos(pos, m_FinalGoal.x, m_FinalGoal.z);
|
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);
|
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
|
// 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.hw = obstruction.hw + delta;
|
||||||
goal.hh = obstruction.hh + 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
|
// We're already in range - no need to move anywhere
|
||||||
if (m_FacePointAfterMove)
|
if (m_FacePointAfterMove)
|
||||||
@ -1554,6 +1568,17 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange
|
|||||||
return false;
|
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;
|
entity_pos_t goalDistance = maxRange - g_GoalDelta;
|
||||||
|
|
||||||
goal.type = ICmpPathfinder::Goal::CIRCLE;
|
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);
|
CFixedVector2D halfSize(obstruction.hw, obstruction.hh);
|
||||||
entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
|
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
|
// See if we're too close to the target square
|
||||||
if (distance < minRange)
|
if (distance < minRange && previousDistance < minRange)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// See if we're close enough to the target square
|
// 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;
|
return true;
|
||||||
|
|
||||||
entity_pos_t circleRadius = halfSize.Length();
|
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;
|
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)
|
if (circleDistance <= maxRange)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1655,14 +1690,12 @@ bool CCmpUnitMotion::IsInTargetRange(entity_id_t target, entity_pos_t minRange,
|
|||||||
if (!cmpTargetPosition || !cmpTargetPosition->IsInWorld())
|
if (!cmpTargetPosition || !cmpTargetPosition->IsInWorld())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CFixedVector2D targetPos = cmpTargetPosition->GetPosition2D();
|
CFixedVector2D targetPos = cmpTargetPosition->GetPreviousPosition2D();
|
||||||
|
|
||||||
entity_pos_t distance = (pos - targetPos).Length();
|
entity_pos_t distance = (pos - targetPos).Length();
|
||||||
|
|
||||||
if (minRange <= distance && (maxRange < entity_pos_t::Zero() || distance <= maxRange))
|
return minRange <= distance &&
|
||||||
return true;
|
(maxRange < entity_pos_t::Zero() || distance <= maxRange);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
|
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 entity_pos_t GetUnitRadius() = 0;
|
||||||
|
|
||||||
virtual bool IsControlPersistent() = 0;
|
virtual bool IsControlPersistent() = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user