Seaside/SpyCustom/flashlighteffect.h
2021-06-16 16:10:20 +03:00

320 lines
7.6 KiB
C++

#ifndef FLASHLIGHTEFFECT_H
#define FLASHLIGHTEFFECT_H
#ifdef _WIN32
#pragma once
#endif
#include "MaterialSystemUtil.h"
class CountdownTimer
{
public:
#ifdef CLIENT_DLL
DECLARE_PREDICTABLE();
#endif
DECLARE_CLASS_NOBASE(CountdownTimer);
DECLARE_EMBEDDED_NETWORKVAR();
CountdownTimer(void);
void Reset(void)
{
m_timestamp = Now() + m_duration;
}
void Start(float duration)
{
m_timestamp = Now() + duration;
m_duration = duration;
}
void StartFromTime(float startTime, float duration)
{
m_timestamp = startTime + duration;
m_duration = duration;
}
void Invalidate(void)
{
m_timestamp = -1.0f;
}
bool HasStarted(void) const
{
return (m_timestamp > 0.0f);
}
bool IsElapsed(void) const
{
return (Now() > m_timestamp);
}
float GetElapsedTime(void) const
{
return Now() - m_timestamp + m_duration;
}
float GetRemainingTime(void) const
{
return (m_timestamp - Now());
}
float GetCountdownDuration(void) const
{
return (m_timestamp > 0.0f) ? m_duration : 0.0f;
}
float GetRemainingRatio(void) const
{
if (HasStarted())
{
float left = GetRemainingTime() / m_duration;
if (left < 0.0f)
return 0.0f;
if (left > 1.0f)
return 1.0f;
return left;
}
return 0.0f;
}
private:
CNetworkVar(float, m_duration);
CNetworkVar(float, m_timestamp);
float Now(void) const;
};
struct dlight_t;
class CFlashlightEffect
{
public:
CFlashlightEffect(int nEntIndex = 0, const char* pszTextureName = NULL, float flFov = 0.0f, float flFarZ = 0.0f, float flLinearAtten = 0.0f);
~CFlashlightEffect();
void UpdateLight(int nEntIdx, const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp, float flFov,
float flFarZ, float flLinearAtten, bool castsShadows, const char* pTextureName);
void UpdateLight(int nEntIdx, const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp, float flFov,
bool castsShadows, ITexture* pFlashlightTexture, const Vector& vecBrightness, bool bTracePlayers = true);
void TurnOn();
void TurnOff();
void SetMuzzleFlashEnabled(bool bEnabled, float flBrightness);
bool IsOn(void) { return m_bIsOn; }
ClientShadowHandle_t GetFlashlightHandle(void) { return m_FlashlightHandle; }
void SetFlashlightHandle(ClientShadowHandle_t Handle) { m_FlashlightHandle = Handle; }
const char* GetFlashlightTextureName(void) const
{
return m_textureName;
}
int GetEntIndex(void) const
{
return m_nEntIndex;
}
bool UpdateDefaultFlashlightState(FlashlightState_t& state, const Vector& vecPos, const Vector& vecDir, const Vector& vecRight,
const Vector& vecUp, bool castsShadows, bool bTracePlayers = true);
bool ComputeLightPosAndOrientation(const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp,
Vector& vecFinalPos, Quaternion& quatOrientation, bool bTracePlayers);
void LightOff();
void UpdateFlashlightTexture(const char* pTextureName);
void UpdateLightTopDown(const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp);
bool m_bIsOn;
int m_nEntIndex;
ClientShadowHandle_t m_FlashlightHandle;
bool m_bMuzzleFlashEnabled;
float m_flMuzzleFlashBrightness;
float m_flFov;
float m_flFarZ;
float m_flLinearAtten;
bool m_bCastsShadows;
float m_flCurrentPullBackDist;
CTextureReference m_FlashlightTexture;
CTextureReference m_MuzzleFlashTexture;
char m_textureName[64];
};
class CHeadlightEffect : public CFlashlightEffect
{
public:
CHeadlightEffect();
~CHeadlightEffect();
virtual void UpdateLight(const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp, int nDistance);
};
class CFlashlightEffectManager
{
private:
CFlashlightEffect* m_pFlashlightEffect;
const char* m_pFlashlightTextureName;
int m_nFlashlightEntIndex;
float m_flFov;
float m_flFarZ;
float m_flLinearAtten;
int m_nMuzzleFlashFrameCountdown;
CountdownTimer m_muzzleFlashTimer;
float m_flMuzzleFlashBrightness;
bool m_bFlashlightOn;
int m_nFXComputeFrame;
bool m_bFlashlightOverride;
public:
CFlashlightEffectManager() : m_pFlashlightEffect(NULL), m_pFlashlightTextureName(NULL), m_nFlashlightEntIndex(-1), m_flFov(0.0f),
m_flFarZ(0.0f), m_flLinearAtten(0.0f), m_nMuzzleFlashFrameCountdown(0), m_flMuzzleFlashBrightness(1.0f),
m_bFlashlightOn(false), m_nFXComputeFrame(-1), m_bFlashlightOverride(false) {}
void TurnOnFlashlight(int nEntIndex = 0, const char* pszTextureName = NULL, float flFov = 0.0f, float flFarZ = 0.0f, float flLinearAtten = 0.0f)
{
m_pFlashlightTextureName = pszTextureName;
m_nFlashlightEntIndex = nEntIndex;
m_flFov = flFov;
m_flFarZ = flFarZ;
m_flLinearAtten = flLinearAtten;
m_bFlashlightOn = true;
if (m_bFlashlightOverride)
{
return;
}
if (!m_pFlashlightEffect)
{
if (pszTextureName)
{
m_pFlashlightEffect = new CFlashlightEffect(m_nFlashlightEntIndex, pszTextureName, flFov, flFarZ, flLinearAtten);
}
else
{
m_pFlashlightEffect = new CFlashlightEffect(m_nFlashlightEntIndex);
}
if (!m_pFlashlightEffect)
{
return;
}
}
m_pFlashlightEffect->TurnOn();
}
void TurnOffFlashlight(bool bForce = false)
{
m_pFlashlightTextureName = NULL;
m_bFlashlightOn = false;
if (bForce)
{
m_bFlashlightOverride = false;
m_nMuzzleFlashFrameCountdown = 0;
m_muzzleFlashTimer.Invalidate();
delete m_pFlashlightEffect;
m_pFlashlightEffect = NULL;
return;
}
if (m_bFlashlightOverride)
{
return;
}
if (m_nMuzzleFlashFrameCountdown == 0 && m_muzzleFlashTimer.IsElapsed())
{
delete m_pFlashlightEffect;
m_pFlashlightEffect = NULL;
}
}
bool IsFlashlightOn() const { return m_bFlashlightOn; }
void UpdateFlashlight(const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp, float flFov, bool castsShadows,
float flFarZ, float flLinearAtten, const char* pTextureName = NULL);
void SetEntityIndex(int index)
{
m_nFlashlightEntIndex = index;
}
void TriggerMuzzleFlash()
{
}
const char* GetFlashlightTextureName(void) const
{
return m_pFlashlightTextureName;
}
int GetFlashlightEntIndex(void) const
{
return m_nFlashlightEntIndex;
}
void EnableFlashlightOverride(bool bEnable)
{
m_bFlashlightOverride = bEnable;
if (!m_bFlashlightOverride)
{
if (m_bFlashlightOn && m_pFlashlightEffect == NULL)
{
TurnOnFlashlight(m_nFlashlightEntIndex, m_pFlashlightTextureName, m_flFov, m_flFarZ, m_flLinearAtten);
}
else if (!m_bFlashlightOn && m_pFlashlightEffect)
{
delete m_pFlashlightEffect;
m_pFlashlightEffect = NULL;
}
}
}
void UpdateFlashlightOverride(bool bFlashlightOn, const Vector& vecPos, const Vector& vecDir, const Vector& vecRight, const Vector& vecUp,
float flFov, bool castsShadows, ITexture* pFlashlightTexture, const Vector& vecBrightness)
{
Assert(m_bFlashlightOverride);
if (!m_bFlashlightOverride)
{
return;
}
if (bFlashlightOn && !m_pFlashlightEffect)
{
m_pFlashlightEffect = new CFlashlightEffect(m_nFlashlightEntIndex);
}
else if (!bFlashlightOn && m_pFlashlightEffect)
{
delete m_pFlashlightEffect;
m_pFlashlightEffect = NULL;
}
if (m_pFlashlightEffect)
{
m_pFlashlightEffect->UpdateLight(m_nFlashlightEntIndex, vecPos, vecDir, vecRight, vecUp, flFov, castsShadows, pFlashlightTexture, vecBrightness, false);
}
}
};
#endif