From 343ec21e75b38cb3108ecc122a90915e2c25adc1 Mon Sep 17 00:00:00 2001 From: elexis Date: Wed, 9 Aug 2017 11:19:14 +0000 Subject: [PATCH] Update the color of the selection ring, rallypoints and territory outline when the playercolor is changed in atlas. Merge duplicate Selectable component playercolor code. Differential Revision: https://code.wildfiregames.com/D687 Fixes #4643 Refs D623 Patch in cooperation with: Stan This was SVN commit r19965. --- .../public/simulation/components/Player.js | 10 ++- source/simulation2/MessageTypes.h | 16 ++++ source/simulation2/TypeList.h | 1 + .../components/CCmpRallyPointRenderer.cpp | 13 +++ .../simulation2/components/CCmpSelectable.cpp | 81 ++++++++++--------- .../components/CCmpTerritoryManager.cpp | 6 ++ .../scripting/MessageTypeConversions.cpp | 16 ++++ 7 files changed, 105 insertions(+), 38 deletions(-) diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js index 728bffd742..6c8555727b 100644 --- a/binaries/data/mods/public/simulation/components/Player.js +++ b/binaries/data/mods/public/simulation/components/Player.js @@ -31,7 +31,7 @@ Player.prototype.Init = function() this.playerID = undefined; this.name = undefined; // define defaults elsewhere (supporting other languages) this.civ = undefined; - this.color = { "r": 0.0, "g": 0.0, "b": 0.0, "a": 1.0 }; + this.color = undefined; this.popUsed = 0; // population of units owned or trained by this player this.popBonuses = 0; // sum of population bonuses of player's entities this.maxPop = 300; // maximum population @@ -120,7 +120,15 @@ Player.prototype.GetCiv = function() Player.prototype.SetColor = function(r, g, b) { + var colorInitialized = !!this.color; + this.color = { "r": r/255.0, "g": g/255.0, "b": b/255.0, "a": 1.0 }; + + // Used in Atlas + if (colorInitialized) + Engine.BroadcastMessage(MT_PlayerColorChanged, { + "player": this.playerID + }); }; Player.prototype.GetColor = function() diff --git a/source/simulation2/MessageTypes.h b/source/simulation2/MessageTypes.h index 4a2587dfe0..a99d625353 100644 --- a/source/simulation2/MessageTypes.h +++ b/source/simulation2/MessageTypes.h @@ -489,6 +489,22 @@ public: std::vector valueNames; }; +/** + * Sent by atlas if the playercolor has been changed. + */ +class CMessagePlayerColorChanged : public CMessage +{ +public: + DEFAULT_MESSAGE_IMPL(PlayerColorChanged) + + CMessagePlayerColorChanged(player_id_t player) : + player(player) + { + } + + player_id_t player; +}; + /** * Sent by aura and tech managers when a value of a certain template's component is changed */ diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index 2395eaf91e..9b87f10807 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -60,6 +60,7 @@ MESSAGE(VisionSharingChanged) MESSAGE(MinimapPing) MESSAGE(CinemaPathEnded) MESSAGE(CinemaQueueEnded) +MESSAGE(PlayerColorChanged) // TemplateManager must come before all other (non-test) components, // so that it is the first to be (de)serialized diff --git a/source/simulation2/components/CCmpRallyPointRenderer.cpp b/source/simulation2/components/CCmpRallyPointRenderer.cpp index 85d3cb9afe..36d73ed200 100644 --- a/source/simulation2/components/CCmpRallyPointRenderer.cpp +++ b/source/simulation2/components/CCmpRallyPointRenderer.cpp @@ -77,6 +77,7 @@ class CCmpRallyPointRenderer : public ICmpRallyPointRenderer public: static void ClassInit(CComponentManager& componentManager) { + componentManager.SubscribeGloballyToMessageType(MT_PlayerColorChanged); componentManager.SubscribeToMessageType(MT_OwnershipChanged); componentManager.SubscribeToMessageType(MT_TurnStart); componentManager.SubscribeToMessageType(MT_Destroy); @@ -204,6 +205,18 @@ public: { switch (msg.GetType()) { + case MT_PlayerColorChanged: + { + const CMessagePlayerColorChanged& msgData = static_cast (msg); + + CmpPtr cmpOwnership(GetEntityHandle()); + if (!cmpOwnership || msgData.player != cmpOwnership->GetOwner()) + break; + + UpdateLineColor(); + ConstructAllOverlayLines(); + } + break; case MT_RenderSubmit: { PROFILE("RallyPoint::RenderSubmit"); diff --git a/source/simulation2/components/CCmpSelectable.cpp b/source/simulation2/components/CCmpSelectable.cpp index 0cd66a166c..4e2205ce5b 100644 --- a/source/simulation2/components/CCmpSelectable.cpp +++ b/source/simulation2/components/CCmpSelectable.cpp @@ -55,6 +55,7 @@ public: static void ClassInit(CComponentManager& componentManager) { componentManager.SubscribeToMessageType(MT_OwnershipChanged); + componentManager.SubscribeToMessageType(MT_PlayerColorChanged); componentManager.SubscribeToMessageType(MT_PositionChanged); componentManager.SubscribeToMessageType(MT_TerrainChanged); componentManager.SubscribeToMessageType(MT_WaterChanged); @@ -263,6 +264,11 @@ public: */ void ResetRangeOverlays(); + /** + * Set the color of the current owner. + */ + void UpdatePlayerColor(); + private: SOverlayDescriptor m_OverlayDescriptor; SOverlayTexturedLine* m_BuildingOverlay; @@ -362,23 +368,21 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global)) if (msgData.to == INVALID_PLAYER) break; - // update the selection highlight color - CmpPtr cmpPlayerManager(GetSystemEntity()); - if (!cmpPlayerManager) - break; - - CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(msgData.to)); - if (!cmpPlayer) - break; - - // Update the highlight color, while keeping the current alpha target value intact - // (i.e. baseline + delta), so that any ongoing fades simply continue with the new color. - CColor color = cmpPlayer->GetColor(); - SetSelectionHighlight(CColor(color.r, color.g, color.b, m_FadeBaselineAlpha + m_FadeDeltaAlpha), m_Selected); - + UpdatePlayerColor(); InvalidateStaticOverlay(); break; } + case MT_PlayerColorChanged: + { + const CMessagePlayerColorChanged& msgData = static_cast (msg); + + CmpPtr cmpOwnership(GetEntityHandle()); + if (!cmpOwnership || msgData.player != cmpOwnership->GetOwner()) + break; + + UpdatePlayerColor(); + break; + } case MT_PositionChanged: { if (m_AlwaysVisible) @@ -409,6 +413,31 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global)) } } +void CCmpSelectable::UpdatePlayerColor() +{ + CmpPtr cmpOwnership(GetEntityHandle()); + + CmpPtr cmpPlayerManager(GetSystemEntity()); + if (!cmpPlayerManager) + return; + + // Default to white if there's no owner (e.g. decorative, editor-only actors) + CColor color(1.0, 1.0, 1.0, 1.0); + + if (cmpOwnership) + { + CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(cmpOwnership->GetOwner())); + if (cmpPlayer) + color = cmpPlayer->GetColor(); + } + + // Update the highlight color, while keeping the current alpha target value intact + // (i.e. baseline + delta), so that any ongoing fades simply continue with the new color. + color.a = m_FadeBaselineAlpha + m_FadeDeltaAlpha; + + SetSelectionHighlight(color, m_Selected); +} + void CCmpSelectable::ResetRangeOverlays() { for (RangeOverlayData& rangeOverlay : m_RangeOverlayData) @@ -616,29 +645,7 @@ void CCmpSelectable::RenderSubmit(SceneCollector& collector) { if (!m_Cached) { - // Default to white if there's no owner (e.g. decorative, editor-only actors) - CColor color = CColor(1.0, 1.0, 1.0, 1.0); - CmpPtr cmpOwnership(GetEntityHandle()); - if (cmpOwnership) - { - player_id_t owner = cmpOwnership->GetOwner(); - if (owner == INVALID_PLAYER) - return; - - // Try to initialize m_Color to the owning player's color. - CmpPtr cmpPlayerManager(GetSystemEntity()); - if (!cmpPlayerManager) - return; - - CmpPtr cmpPlayer(GetSimContext(), cmpPlayerManager->GetPlayerByID(owner)); - if (!cmpPlayer) - return; - - color = cmpPlayer->GetColor(); - } - color.a = m_FadeBaselineAlpha + m_FadeDeltaAlpha; - - SetSelectionHighlight(color, m_Selected); + UpdatePlayerColor(); m_Cached = true; } diff --git a/source/simulation2/components/CCmpTerritoryManager.cpp b/source/simulation2/components/CCmpTerritoryManager.cpp index 6c9e9ff43b..14151ffa13 100644 --- a/source/simulation2/components/CCmpTerritoryManager.cpp +++ b/source/simulation2/components/CCmpTerritoryManager.cpp @@ -60,6 +60,7 @@ public: static void ClassInit(CComponentManager& componentManager) { componentManager.SubscribeGloballyToMessageType(MT_OwnershipChanged); + componentManager.SubscribeGloballyToMessageType(MT_PlayerColorChanged); componentManager.SubscribeGloballyToMessageType(MT_PositionChanged); componentManager.SubscribeGloballyToMessageType(MT_ValueModification); componentManager.SubscribeToMessageType(MT_ObstructionMapShapeChanged); @@ -172,6 +173,11 @@ public: MakeDirtyIfRelevantEntity(msgData.entity); break; } + case MT_PlayerColorChanged: + { + MakeDirty(); + break; + } case MT_PositionChanged: { const CMessagePositionChanged& msgData = static_cast (msg); diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp index 8f2a602153..74eb7a06d1 100644 --- a/source/simulation2/scripting/MessageTypeConversions.cpp +++ b/source/simulation2/scripting/MessageTypeConversions.cpp @@ -519,6 +519,22 @@ CMessage* CMessageCinemaQueueEnded::FromJSVal(ScriptInterface& scriptInterface, //////////////////////////////////////////////////////////////// +JS::Value CMessagePlayerColorChanged::ToJSVal(ScriptInterface& scriptInterface) const +{ + TOJSVAL_SETUP(); + SET_MSG_PROPERTY(player); + return JS::ObjectValue(*obj); +} + +CMessage* CMessagePlayerColorChanged::FromJSVal(ScriptInterface& scriptInterface, JS::HandleValue val) +{ + FROMJSVAL_SETUP(); + GET_MSG_PROPERTY(player_id_t, player); + return new CMessagePlayerColorChanged(player); +} + +//////////////////////////////////////////////////////////////// + CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, JS::HandleValue val) { switch (mtid)