Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -137,7 +137,7 @@ // Default event handlers: - "MoveCompleted": function() { + "MovementUpdate": function(msg) { // ignore spurious movement messages // (these can happen when stopping moving at the same time // as switching states) @@ -897,8 +897,8 @@ this.StopMoving(); }, - "MoveCompleted": function(msg) { - if (this.FinishOrder()) + "MovementUpdate": function(msg) { + if (this.CheckRange(this.order.data) && this.FinishOrder()) this.CallMemberFunction("ResetFinishOrder", []); }, }, @@ -926,8 +926,8 @@ this.FindWalkAndFightTargets(); }, - "MoveCompleted": function(msg) { - if (this.FinishOrder()) + "MovementUpdate": function(msg) { + if (this.CheckRange(this.order.data) && this.FinishOrder()) this.CallMemberFunction("ResetFinishOrder", []); }, }, @@ -971,7 +971,9 @@ delete this.patrolStartPosOrder; }, - "MoveCompleted": function() { + "MovementUpdate": function() { + if (!this.CheckRange(this.order.data)) + return; /** * A-B-A-B-..: * if the user only commands one patrol order, the patrol will be between @@ -1027,7 +1029,7 @@ this.StopMoving(); }, - "MoveCompleted": function(msg) { + "MovementUpdate": function(msg) { this.SetNextState("GARRISONING"); }, }, @@ -1062,7 +1064,9 @@ this.StopMoving(); }, - "MoveCompleted": function(msg) { + "MovementUpdate": function(msg) { + if (!this.CheckRange(this.order.data)) + return; if (this.FinishOrder()) { @@ -1092,8 +1096,8 @@ this.StopMoving(); }, - "MoveCompleted": function(msg) { - var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); + "MovementUpdate": function(msg) { + let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); this.CallMemberFunction("Attack", [this.order.data.target, this.order.data.allowCapture, false]); if (cmpAttack.CanAttackAsFormation()) this.SetNextState("COMBAT.ATTACKING"); @@ -1268,18 +1272,22 @@ // Occurs when the unit has reached its destination and the controller // is done moving. The controller is notified. - "MoveCompleted": function(msg) { + "MovementUpdate": function(msg) { // We can only finish this order if the move was really completed. - if (!msg.data.error && this.FinishOrder()) + if (!this.CheckRange(this.order.data) || msg.error) return; - var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); + + if (this.FinishOrder()) + return; + + let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); if (cmpVisual) { cmpVisual.ResetMoveAnimation("walk"); cmpVisual.ResetMoveAnimation("run"); } - var cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation); + let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation); if (cmpFormation) cmpFormation.SetInPosition(this.entity); }, @@ -1299,7 +1307,9 @@ this.SelectAnimation("move"); }, - "MoveCompleted": function() { + "MovementUpdate": function() { + if (!this.CheckRange(this.order.data)) + return; this.StopMoving(); this.FinishOrder(); }, @@ -1482,8 +1492,9 @@ this.StopMoving(); }, - "MoveCompleted": function() { - this.FinishOrder(); + "MovementUpdate": function() { + if (this.CheckRange(this.order.data)) + this.FinishOrder(); }, }, @@ -1511,8 +1522,9 @@ this.SetDefaultAnimationVariant(); }, - "MoveCompleted": function() { - this.FinishOrder(); + "MovementUpdate": function() { + if (this.CheckRange(this.order.data)) + this.FinishOrder(); }, }, @@ -1550,7 +1562,10 @@ this.FindWalkAndFightTargets(); }, - "MoveCompleted": function() { + "MovementUpdate": function() { + if (!this.CheckRange(this.order.data)) + return; + if (this.orderQueue.length == 1) this.PushOrder("Patrol", this.patrolStartPosOrder); @@ -1613,8 +1628,7 @@ this.SetDefaultAnimationVariant(); }, - "MoveCompleted": function() { - this.ResetSpeedMultiplier(); + "MovementUpdate": function() { if (this.CheckTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) this.SetNextState("GUARDING"); }, @@ -1698,9 +1712,10 @@ this.StopMoving(); }, - "MoveCompleted": function() { + "MovementUpdate": function() { // When we've run far enough, stop fleeing - this.FinishOrder(); + if (this.CheckRange(this.order.data)) + this.FinishOrder(); }, // TODO: what if we run into more enemies while fleeing? @@ -1753,31 +1768,16 @@ } }, - "MoveCompleted": function() { - - if (this.CheckTargetAttackRange(this.order.data.target, this.order.data.attackType)) + "MovementUpdate": function() { + if (!this.CheckTargetAttackRange(this.order.data.target, this.order.data.attackType)) + return; + // If the unit needs to unpack, do so + if (this.CanUnpack()) { - // If the unit needs to unpack, do so - if (this.CanUnpack()) - { - this.PushOrderFront("Unpack", { "force": true }); - return; - } - else - this.SetNextState("ATTACKING"); - } - else - { - if (this.MoveToTargetAttackRange(this.order.data.target, this.order.data.attackType)) - { - this.SetNextState("APPROACHING"); - } - else - { - // Give up - this.FinishOrder(); - } + this.PushOrderFront("Unpack", { "force": true }); + return; } + this.SetNextState("ATTACKING"); }, }, @@ -2019,7 +2019,7 @@ } }, - "MoveCompleted": function() { + "MovementUpdate": function() { this.SetNextState("ATTACKING"); }, }, @@ -2046,9 +2046,8 @@ return false; }, - "MoveCompleted": function(msg) { - // We either reached the target, or we will let the timer logic in GATHERING - // handle finding a new resource. + "MovementUpdate": function(msg) { + // If we failed, the GATHERING timer will handle finding a valid resource. this.SetNextState("GATHERING"); }, @@ -2082,8 +2081,8 @@ this.StopMoving(); }, - "MoveCompleted": function(msg) { - // The GATHERING timer will handle finding a valid resource. + "MovementUpdate": function(msg) { + // If we failed, the GATHERING timer will handle finding a valid resource. this.SetNextState("GATHERING"); }, }, @@ -2338,7 +2337,7 @@ } }, - "MoveCompleted": function() { + "MovementUpdate": function() { this.SetNextState("HEALING"); }, }, @@ -2440,7 +2439,7 @@ this.SelectAnimation("idle"); }, - "MoveCompleted": function() { + "MovementUpdate": function() { // Check the dropsite is in range and we can return our resource there // (we didn't get stopped before reaching it) if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer) && this.CanReturnResource(this.order.data.target, true)) @@ -2503,7 +2502,10 @@ this.StopMoving(); }, - "MoveCompleted": function() { + "MovementUpdate": function() { + if (!this.CheckTargetRange(this.order.data.target, IID_Trader)) + return; + if (this.waypoints && this.waypoints.length) { if (!this.MoveToMarket(this.order.data.target)) @@ -2540,8 +2542,9 @@ this.StopMoving(); }, - "MoveCompleted": function() { - this.SetNextState("REPAIRING"); + "MovementUpdate": function() { + if (this.CheckRange(this.order.data)) + this.SetNextState("REPAIRING"); }, }, @@ -2749,8 +2752,9 @@ this.StopMoving(); }, - "MoveCompleted": function() { - this.SetNextState("GARRISONED"); + "MovementUpdate": function() { + if (this.CheckRange(this.order.data)) + this.SetNextState("GARRISONED"); }, }, @@ -2932,8 +2936,9 @@ this.StopMoving(); }, - "MoveCompleted": function() { - this.SetNextState("LOADING"); + "MovementUpdate": function() { + if (this.CheckRange(this.order.data)) + this.SetNextState("LOADING"); }, "PickupCanceled": function() { @@ -3048,7 +3053,7 @@ this.SetNextState("FEEDING"); }, - "MoveCompleted": function() { + "MovementUpdate": function() { this.MoveRandomly(+this.template.RoamDistance); }, }, @@ -3081,8 +3086,6 @@ } }, - "MoveCompleted": function() { }, - "Timer": function(msg) { this.SetNextState("ROAMING"); }, @@ -3788,7 +3791,7 @@ UnitAI.prototype.OnMotionChanged = function(msg) { - this.UnitFsm.ProcessMessage(this, { "type": "MoveCompleted", "data": msg }); + this.UnitFsm.ProcessMessage(this, { "type": "MovementUpdate", "error": msg.error }); }; UnitAI.prototype.OnGlobalConstructionFinished = function(msg) @@ -4129,26 +4132,20 @@ */ UnitAI.prototype.MoveTo = function(data, iid, type) { - if (data["target"]) + if (data.target) { - if (data["min"] || data["max"]) + if (data.min || data.max) return this.MoveToTargetRangeExplicit(data.target, data.min || -1, data.max || -1); - else - { - if (!iid) - return this.MoveToTarget(data.target); - else - return this.MoveToTargetRange(data.target, iid, type); - } + else if (!iid) + return this.MoveToTarget(data.target); + + return this.MoveToTargetRange(data.target, iid, type); } - else - { - if (data["min"] || data["max"]) - return this.MoveToPointRange(data.x, data.z, data.min || -1, data.max || -1); - else - return this.MoveToPoint(data.x, data.z); - } -} + else if (data.min || data.max) + return this.MoveToPointRange(data.x, data.z, data.min || -1, data.max || -1); + + return this.MoveToPoint(data.x, data.z); +}; UnitAI.prototype.MoveToPoint = function(x, z) { @@ -4268,6 +4265,28 @@ return cmpUnitMotion.MoveToTargetRange(target, range.min, range.max); }; +/** + * Generic dispatcher for other Check...Range functions. + * @param iid - Interface ID (optional) implementing GetRange + * @param type - Range type for the interface call + */ +UnitAI.prototype.CheckRange = function(data, iid, type) +{ + if (data.target) + { + if (data.min || data.max) + return this.CheckTargetRangeExplicit(data.target, data.min || -1, data.max || -1); + else if (!iid) + return this.CheckTargetRangeExplicit(data.target, 0, 0); + + return this.CheckTargetRange(data.target, iid, type); + } + else if (data.min || data.max) + return this.CheckPointRangeExplicit(data.x, data.z, data.min || -1, data.max || -1); + + return this.CheckPointRangeExplicit(data.x, data.z, 0, 0); +}; + UnitAI.prototype.CheckPointRangeExplicit = function(x, z, min, max) { let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager); Index: source/simulation2/components/CCmpUnitMotion.cpp =================================================================== --- source/simulation2/components/CCmpUnitMotion.cpp +++ source/simulation2/components/CCmpUnitMotion.cpp @@ -548,8 +548,6 @@ void MoveFailed() { - StopMoving(); - CmpPtr cmpObstruction(GetEntityHandle()); if (cmpObstruction) cmpObstruction->SetMovingFlag(false); @@ -690,10 +688,8 @@ CmpPtr cmpPosition(GetEntityHandle()); if (!cmpPosition || !cmpPosition->IsInWorld()) { - if (m_PathState == PATHSTATE_WAITING_REQUESTING_LONG || m_PathState == PATHSTATE_WAITING_REQUESTING_SHORT) - MoveFailed(); - else if (m_PathState == PATHSTATE_FOLLOWING_REQUESTING_LONG || m_PathState == PATHSTATE_FOLLOWING_REQUESTING_SHORT) - StopMoving(); + // We will probably fail to move so inform components but keep on trying anyways. + MoveFailed(); return; } @@ -752,7 +748,6 @@ if (CloseEnoughFromDestinationToStop(pos)) { - StopMoving(); MoveSucceeded(); if (m_FacePointAfterMove) @@ -935,7 +930,6 @@ // check if we've arrived. if (CloseEnoughFromDestinationToStop(pos)) { - StopMoving(); MoveSucceeded(); if (m_FacePointAfterMove) @@ -1027,8 +1021,6 @@ CmpPtr cmpUnitMotion(GetSimContext(), m_TargetEntity); if (!cmpUnitMotion || cmpObstructionManager->IsInTargetRange(GetEntityId(), m_TargetEntity, m_TargetMinRange, m_TargetMaxRange, false)) { - // Not in formation, so just finish moving - StopMoving(); m_State = STATE_IDLE; MoveSucceeded();