Fix aura/overlay visibility in FOW

This commit is contained in:
Lancelot de Ferrière 2024-12-16 21:31:24 +01:00 committed by wraitii
parent f27afa5c17
commit f3f695b90e

View file

@ -19,8 +19,8 @@
#include "simulation2/system/Component.h"
#include "ICmpOverlayRenderer.h"
#include "ICmpPosition.h"
#include "ICmpRangeManager.h"
#include "simulation2/MessageTypes.h"
@ -32,9 +32,21 @@
class CCmpOverlayRenderer final : public ICmpOverlayRenderer
{
public:
static void ClassInit(CComponentManager& UNUSED(componentManager))
enum class LocalLosVisibility : u8
{
HIDDEN = 0,
FOGGED = 1,
VISIBLE = 2,
DIRTY = 3,
};
static_assert(LocalLosVisibility::HIDDEN == static_cast<LocalLosVisibility>(LosVisibility::HIDDEN), "Desynced");
static_assert(LocalLosVisibility::FOGGED == static_cast<LocalLosVisibility>(LosVisibility::FOGGED), "Desynced");
static_assert(LocalLosVisibility::VISIBLE == static_cast<LocalLosVisibility>(LosVisibility::VISIBLE), "Desynced");
public:
static void ClassInit(CComponentManager &componentManager)
{
componentManager.SubscribeToMessageType(MT_VisibilityChanged);
}
DEFAULT_COMPONENT_ALLOCATOR(OverlayRenderer)
@ -49,12 +61,16 @@ public:
// Whether the sprites should be drawn (only valid between Interpolate and RenderSubmit)
bool m_Enabled;
// NOT SAFE TO SERIALIZE - used to hide status bars/auras of entities invisible to the player.
// We also can't just deserialize it because annoyingly the range manager computes LOS data on deserialize...
LocalLosVisibility m_VisibilityToCurrentPlayer = LocalLosVisibility::DIRTY;
static std::string GetSchema()
{
return "<empty/>";
}
void Init(const CParamNode& UNUSED(paramNode)) override
void Init(const CParamNode &UNUSED(paramNode)) override
{
}
@ -62,36 +78,43 @@ public:
{
}
void Serialize(ISerializer& UNUSED(serialize)) override
void Serialize(ISerializer &UNUSED(serialize)) override
{
// TODO: should we do anything here?
// or should we expect other components to reinitialise us
// after deserialization?
}
void Deserialize(const CParamNode& paramNode, IDeserializer& UNUSED(deserialize)) override
void Deserialize(const CParamNode &paramNode, IDeserializer &UNUSED(deserialize)) override
{
Init(paramNode);
}
void HandleMessage(const CMessage& msg, bool UNUSED(global)) override
void HandleMessage(const CMessage &msg, bool UNUSED(global)) override
{
switch (msg.GetType())
{
case MT_Interpolate:
{
PROFILE("OverlayRenderer::Interpolate");
const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
const CMessageInterpolate &msgData = static_cast<const CMessageInterpolate &>(msg);
Interpolate(msgData.deltaSimTime, msgData.offset);
break;
}
case MT_RenderSubmit:
{
PROFILE("OverlayRenderer::RenderSubmit");
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
const CMessageRenderSubmit &msgData = static_cast<const CMessageRenderSubmit &>(msg);
RenderSubmit(msgData.collector);
break;
}
case MT_VisibilityChanged:
{
const CMessageVisibilityChanged &msgData = static_cast<const CMessageVisibilityChanged &>(msg);
if (msgData.player == GetSimContext().GetCurrentDisplayedPlayer())
m_VisibilityToCurrentPlayer = static_cast<LocalLosVisibility>(msgData.newVisibility);
break;
}
}
}
@ -115,7 +138,7 @@ public:
UpdateMessageSubscriptions();
}
void AddSprite(const VfsPath& textureName, const CFixedVector2D& corner0, const CFixedVector2D& corner1, const CFixedVector3D& position, const std::string& color) override
void AddSprite(const VfsPath &textureName, const CFixedVector2D &corner0, const CFixedVector2D &corner1, const CFixedVector3D &position, const std::string &color) override
{
CColor colorObj(1.0f, 1.0f, 1.0f, 1.0f);
if (!colorObj.ParseString(color, 1))
@ -134,13 +157,19 @@ public:
m_Sprites.push_back(sprite);
m_SpriteOffsets.push_back(CVector3D(position));
if (m_VisibilityToCurrentPlayer == LocalLosVisibility::DIRTY)
{
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSystemEntity());
m_VisibilityToCurrentPlayer = static_cast<LocalLosVisibility>(cmpRangeManager->GetLosVisibility(GetEntityHandle(), GetSimContext().GetCurrentDisplayedPlayer()));
}
UpdateMessageSubscriptions();
}
void Interpolate(float UNUSED(frameTime), float frameOffset)
{
// Skip all the following computations if we have no sprites
if (m_Sprites.empty())
if (m_Sprites.empty() || m_VisibilityToCurrentPlayer == LocalLosVisibility::HIDDEN)
{
m_Enabled = false;
return;
@ -165,7 +194,7 @@ public:
m_Enabled = true;
}
void RenderSubmit(SceneCollector& collector)
void RenderSubmit(SceneCollector &collector)
{
if (!m_Enabled || !ICmpOverlayRenderer::m_OverrideVisible)
return;