diff --git a/binaries/data/mods/public/simulation/components/TerritoryDecay.js b/binaries/data/mods/public/simulation/components/TerritoryDecay.js index 6786421f74..a5a8aae0f2 100644 --- a/binaries/data/mods/public/simulation/components/TerritoryDecay.js +++ b/binaries/data/mods/public/simulation/components/TerritoryDecay.js @@ -61,6 +61,12 @@ TerritoryDecay.prototype.OnTerritoriesChanged = function(msg) this.UpdateDecayState(); }; +TerritoryDecay.prototype.OnTerritoryPositionChanged = function(msg) +{ + warn(uneval(msg)); + this.UpdateDecayState(); +}; + TerritoryDecay.prototype.OnOwnershipChanged = function(msg) { this.UpdateDecayState(); diff --git a/source/simulation2/MessageTypes.h b/source/simulation2/MessageTypes.h index 76079afe0c..80e9e2297f 100644 --- a/source/simulation2/MessageTypes.h +++ b/source/simulation2/MessageTypes.h @@ -258,6 +258,21 @@ public: entity_angle_t a; }; +/*Sent whenever the territory type (neutral,own,enemy) differs from the former type*/ +class CMessageTerritoryPositionChanged : public CMessage +{ +public: + DEFAULT_MESSAGE_IMPL(TerritoryPositionChanged) + + CMessageTerritoryPositionChanged(entity_id_t entity, player_id_t newTerritory) : + entity(entity), newTerritory(newTerritory) + { + } + + entity_id_t entity; + player_id_t newTerritory; +}; + /** * Sent by CCmpUnitMotion during Update, whenever the motion status has changed * since the previous update. diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index 8183c2f00e..6107bd1936 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -42,6 +42,7 @@ MESSAGE(Create) MESSAGE(Destroy) MESSAGE(OwnershipChanged) MESSAGE(PositionChanged) +MESSAGE(TerritoryPositionChanged) MESSAGE(MotionChanged) MESSAGE(RangeUpdate) MESSAGE(TerrainChanged) diff --git a/source/simulation2/components/CCmpPosition.cpp b/source/simulation2/components/CCmpPosition.cpp index eac930251c..1d15cd02be 100644 --- a/source/simulation2/components/CCmpPosition.cpp +++ b/source/simulation2/components/CCmpPosition.cpp @@ -32,6 +32,7 @@ #include "maths/Vector3D.h" #include "maths/Vector2D.h" #include "ps/CLogger.h" +#include "ICmpTerritoryManager.h" /** * Basic ICmpPosition implementation. @@ -43,6 +44,7 @@ public: { componentManager.SubscribeToMessageType(MT_TurnStart); componentManager.SubscribeToMessageType(MT_Interpolate); + componentManager.SubscribeToMessageType(MT_TerritoriesChanged); // TODO: if this component turns out to be a performance issue, it should // be optimised by creating a new PositionStatic component that doesn't subscribe @@ -76,6 +78,8 @@ public: entity_angle_t m_RotX, m_RotY, m_RotZ; + player_id_t m_Territory; + // not serialized: float m_InterpolatedRotX, m_InterpolatedRotY, m_InterpolatedRotZ; float m_LastInterpolatedRotX, m_LastInterpolatedRotZ; // not serialized @@ -134,6 +138,7 @@ public: m_RotX = m_RotY = m_RotZ = entity_angle_t::FromInt(0); m_InterpolatedRotX = m_InterpolatedRotY = m_InterpolatedRotZ = 0.f; m_LastInterpolatedRotX = m_LastInterpolatedRotZ = 0.f; + m_Territory = INVALID_PLAYER; m_NeedInitialXZRotation = false; } @@ -152,6 +157,7 @@ public: serialize.NumberFixed_Unbounded("last x", m_LastX); serialize.NumberFixed_Unbounded("last z", m_LastZ); } + serialize.NumberI32_Unbounded("territory", m_Territory); serialize.NumberFixed_Unbounded("rot x", m_RotX); serialize.NumberFixed_Unbounded("rot y", m_RotY); serialize.NumberFixed_Unbounded("rot z", m_RotZ); @@ -197,6 +203,7 @@ public: deserialize.NumberFixed_Unbounded("last x", m_LastX); deserialize.NumberFixed_Unbounded("last z", m_LastZ); } + deserialize.NumberI32_Unbounded("territory", m_Territory); deserialize.NumberFixed_Unbounded("rot x", m_RotX); deserialize.NumberFixed_Unbounded("rot y", m_RotY); deserialize.NumberFixed_Unbounded("rot z", m_RotZ); @@ -558,6 +565,20 @@ public: break; } + case MT_TerritoriesChanged: + { + if (!m_InWorld) + break; + CmpPtr cmpTerritoryManager(GetSystemEntity()); + player_id_t newTerritory = cmpTerritoryManager->GetOwner(m_X, m_Z); + if (newTerritory != m_Territory) + { + m_Territory = newTerritory; + CMessageTerritoryPositionChanged msg(GetEntityId(), m_Territory); + GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); + } + break; + } } }; @@ -568,11 +589,29 @@ private: { CMessagePositionChanged msg(GetEntityId(), true, m_X, m_Z, m_RotY); GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); + + player_id_t newTerritory; + CmpPtr cmpTerritoryManager(GetSystemEntity()); + if (cmpTerritoryManager) + newTerritory = cmpTerritoryManager->GetOwner(m_X, m_Z); + else + newTerritory = INVALID_PLAYER; + if (newTerritory != m_Territory) + { + m_Territory = newTerritory; + CMessageTerritoryPositionChanged msg(GetEntityId(), m_Territory); + GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); + } } else { CMessagePositionChanged msg(GetEntityId(), false, entity_pos_t::Zero(), entity_pos_t::Zero(), entity_angle_t::Zero()); GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); + if (m_Territory != INVALID_PLAYER) + { + CMessageTerritoryPositionChanged msg(GetEntityId(), m_Territory); + GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg); + } } } diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp index a2180de468..400507aa48 100644 --- a/source/simulation2/scripting/MessageTypeConversions.cpp +++ b/source/simulation2/scripting/MessageTypeConversions.cpp @@ -216,6 +216,24 @@ CMessage* CMessagePositionChanged::FromJSVal(ScriptInterface& scriptInterface, j //////////////////////////////// +jsval CMessageTerritoryPositionChanged::ToJSVal(ScriptInterface& scriptInterface) const +{ + TOJSVAL_SETUP(); + SET_MSG_PROPERTY(entity); + SET_MSG_PROPERTY(newTerritory); + return OBJECT_TO_JSVAL(obj); +} + +CMessage* CMessageTerritoryPositionChanged::FromJSVal(ScriptInterface& scriptInterface, jsval val) +{ + FROMJSVAL_SETUP(); + GET_MSG_PROPERTY(entity_id_t, entity); + GET_MSG_PROPERTY(player_id_t, newTerritory); + return new CMessageTerritoryPositionChanged(entity, newTerritory); +} + +//////////////////////////////// + jsval CMessageMotionChanged::ToJSVal(ScriptInterface& scriptInterface) const { TOJSVAL_SETUP();