diff --git a/binaries/data/mods/public/simulation/components/Foundation.js b/binaries/data/mods/public/simulation/components/Foundation.js index dbfb4bc4c5..72fa29b294 100644 --- a/binaries/data/mods/public/simulation/components/Foundation.js +++ b/binaries/data/mods/public/simulation/components/Foundation.js @@ -99,7 +99,7 @@ Foundation.prototype.Build = function(builderEnt, work) if (!this.committed) { var cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction); - if (cmpObstruction) + if (cmpObstruction && cmpObstruction.GetBlockMovementFlag()) { // If there's any units in the way, ask them to move away // and return early from this method. diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index 24a52f2b48..d93305fb4f 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -407,6 +407,25 @@ var UnitFsmSpec = { this.SetNextState("INDIVIDUAL.IDLE"); }, + // Override the LeaveFoundation order since we're not doing + // anything more important (and we might be stuck in the WALKING + // state forever and need to get out of foundations in that case) + "Order.LeaveFoundation": function(msg) { + // Move a tile outside the building + var range = 4; + var ok = this.MoveToTargetRangeExplicit(msg.data.target, range, range); + if (ok) + { + // We've started walking to the given point + this.SetNextState("WALKING"); + } + else + { + // We are already at the target, or can't move at all + this.FinishOrder(); + } + }, + "IDLE": { "enter": function() { this.SelectAnimation("idle"); @@ -417,6 +436,10 @@ var UnitFsmSpec = { "enter": function () { 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) }, }, diff --git a/source/simulation2/components/CCmpObstruction.cpp b/source/simulation2/components/CCmpObstruction.cpp index 5372e15869..0a7b1460cd 100644 --- a/source/simulation2/components/CCmpObstruction.cpp +++ b/source/simulation2/components/CCmpObstruction.cpp @@ -289,6 +289,11 @@ public: } } + virtual bool GetBlockMovementFlag() + { + return (m_TemplateFlags & ICmpObstructionManager::FLAG_BLOCK_MOVEMENT) != 0; + } + virtual ICmpObstructionManager::tag_t GetObstruction() { return m_Tag; diff --git a/source/simulation2/components/ICmpObstruction.cpp b/source/simulation2/components/ICmpObstruction.cpp index 429d73e300..d1a629aac7 100644 --- a/source/simulation2/components/ICmpObstruction.cpp +++ b/source/simulation2/components/ICmpObstruction.cpp @@ -27,5 +27,6 @@ DEFINE_INTERFACE_METHOD_0("CheckFoundationCollisions", bool, ICmpObstruction, Ch DEFINE_INTERFACE_METHOD_0("GetConstructionCollisions", std::vector, ICmpObstruction, GetConstructionCollisions) DEFINE_INTERFACE_METHOD_1("SetActive", void, ICmpObstruction, SetActive, bool) DEFINE_INTERFACE_METHOD_1("SetDisableBlockMovementPathfinding", void, ICmpObstruction, SetDisableBlockMovementPathfinding, bool) +DEFINE_INTERFACE_METHOD_0("GetBlockMovementFlag", bool, ICmpObstruction, GetBlockMovementFlag) DEFINE_INTERFACE_METHOD_1("SetControlGroup", void, ICmpObstruction, SetControlGroup, entity_id_t) END_INTERFACE_WRAPPER(Obstruction) diff --git a/source/simulation2/components/ICmpObstruction.h b/source/simulation2/components/ICmpObstruction.h index 6d84e5f2ac..89de14a71c 100644 --- a/source/simulation2/components/ICmpObstruction.h +++ b/source/simulation2/components/ICmpObstruction.h @@ -56,6 +56,8 @@ public: virtual void SetDisableBlockMovementPathfinding(bool disabled) = 0; + virtual bool GetBlockMovementFlag() = 0; + /** * Change the control group that the entity belongs to. * Control groups are used to let units ignore collisions with other units from