From db39d742f02f775e7d6421ec334baaeb4dd2f66f Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Tue, 3 Jun 2014 22:35:40 +0000 Subject: [PATCH] Fix units falling off the edge of the world. I guess changes to the map loading sequence caused the TerrainChanged message to be sent before the map was switched from square to circular instead of after. The pathfinder didn't notice the switch, so it continued treating the map as if it were square, allowing units to walk into the permanent map-corner SOD and vanish, and allowing territories to expand into the SOD. Tell the pathfinder explicitly when the map shape changes, so it can discard its cached data correctly. This was SVN commit r15277. --- source/simulation2/MessageTypes.h | 14 ++++++++++++++ source/simulation2/TypeList.h | 1 + .../components/CCmpObstructionManager.cpp | 3 +++ source/simulation2/components/CCmpPathfinder.cpp | 6 +----- .../simulation2/components/CCmpPathfinder_Common.h | 1 + .../scripting/MessageTypeConversions.cpp | 13 +++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/source/simulation2/MessageTypes.h b/source/simulation2/MessageTypes.h index ade0b5fc33..4a2c47ab49 100644 --- a/source/simulation2/MessageTypes.h +++ b/source/simulation2/MessageTypes.h @@ -361,6 +361,20 @@ public: int32_t i0, j0, i1, j1; // inclusive lower bound, exclusive upper bound, in tiles }; +/** + * Sent when ObstructionManager's view of the shape of the world has changed + * (changing the TILE_OUTOFBOUNDS tiles returned by Rasterise). + */ +class CMessageObstructionMapShapeChanged : public CMessage +{ +public: + DEFAULT_MESSAGE_IMPL(ObstructionMapShapeChanged) + + CMessageObstructionMapShapeChanged() + { + } +}; + /** * Sent when territory assignments have changed. */ diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index d96a408633..0c0f38237b 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -49,6 +49,7 @@ MESSAGE(MotionChanged) MESSAGE(RangeUpdate) MESSAGE(TerrainChanged) MESSAGE(WaterChanged) +MESSAGE(ObstructionMapShapeChanged) MESSAGE(TerritoriesChanged) MESSAGE(PathResult) MESSAGE(ValueModification) diff --git a/source/simulation2/components/CCmpObstructionManager.cpp b/source/simulation2/components/CCmpObstructionManager.cpp index fe843e89fb..6494284442 100644 --- a/source/simulation2/components/CCmpObstructionManager.cpp +++ b/source/simulation2/components/CCmpObstructionManager.cpp @@ -443,6 +443,9 @@ public: { m_PassabilityCircular = enabled; MakeDirtyAll(); + + CMessageObstructionMapShapeChanged msg; + GetSimContext().GetComponentManager().BroadcastMessage(msg); } virtual void SetDebugOverlay(bool enabled) diff --git a/source/simulation2/components/CCmpPathfinder.cpp b/source/simulation2/components/CCmpPathfinder.cpp index 1271700958..b2a321cf88 100644 --- a/source/simulation2/components/CCmpPathfinder.cpp +++ b/source/simulation2/components/CCmpPathfinder.cpp @@ -219,6 +219,7 @@ void CCmpPathfinder::HandleMessage(const CMessage& msg, bool UNUSED(global)) } case MT_TerrainChanged: case MT_WaterChanged: + case MT_ObstructionMapShapeChanged: { // TODO: we ought to only bother updating the dirtied region m_TerrainDirty = true; @@ -339,11 +340,6 @@ void CCmpPathfinder::UpdateGrid() // Since terrain hasn't changed we only need to update the obstruction bits // and can skip the rest of the data - // TODO: if ObstructionManager::SetPassabilityCircular was called at runtime - // (which should probably never happen, but that's not guaranteed), - // then TILE_OUTOFBOUNDS will change and we can't use this fast path, but - // currently it'll just set obstructionsDirty and we won't notice - for (u16 j = 0; j < m_MapSize; ++j) { for (u16 i = 0; i < m_MapSize; ++i) diff --git a/source/simulation2/components/CCmpPathfinder_Common.h b/source/simulation2/components/CCmpPathfinder_Common.h index 9e38a0529b..53c9562f27 100644 --- a/source/simulation2/components/CCmpPathfinder_Common.h +++ b/source/simulation2/components/CCmpPathfinder_Common.h @@ -175,6 +175,7 @@ public: componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays componentManager.SubscribeToMessageType(MT_TerrainChanged); componentManager.SubscribeToMessageType(MT_WaterChanged); + componentManager.SubscribeToMessageType(MT_ObstructionMapShapeChanged); componentManager.SubscribeToMessageType(MT_TurnStart); } diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp index 658cef82ce..0f4ad3399e 100644 --- a/source/simulation2/scripting/MessageTypeConversions.cpp +++ b/source/simulation2/scripting/MessageTypeConversions.cpp @@ -323,6 +323,19 @@ CMessage* CMessageWaterChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterfac //////////////////////////////// +jsval CMessageObstructionMapShapeChanged::ToJSVal(ScriptInterface& scriptInterface) const +{ + TOJSVAL_SETUP(); + return OBJECT_TO_JSVAL(obj); +} + +CMessage* CMessageObstructionMapShapeChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val)) +{ + return new CMessageObstructionMapShapeChanged(); +} + +//////////////////////////////// + jsval CMessageTerritoriesChanged::ToJSVal(ScriptInterface& scriptInterface) const { TOJSVAL_SETUP();