This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

405 lines
12 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BEAM_H
#define BEAM_H
#ifdef _WIN32
#pragma once
#endif
#include "baseentity_shared.h"
#include "baseplayer_shared.h"
#if !defined(CLIENT_DLL)
#include "entityoutput.h"
#endif
#include "beam_flags.h"
#define MAX_BEAM_WIDTH 102.3f
#define MAX_BEAM_SCROLLSPEED 100.0f
#define MAX_BEAM_NOISEAMPLITUDE 64
#define SF_BEAM_STARTON 0x0001
#define SF_BEAM_TOGGLE 0x0002
#define SF_BEAM_RANDOM 0x0004
#define SF_BEAM_RING 0x0008
#define SF_BEAM_SPARKSTART 0x0010
#define SF_BEAM_SPARKEND 0x0020
#define SF_BEAM_DECALS 0x0040
#define SF_BEAM_SHADEIN 0x0080
#define SF_BEAM_SHADEOUT 0x0100
#define SF_BEAM_TAPEROUT 0x0200 // Tapers to zero
#define SF_BEAM_TEMPORARY 0x8000
#define ATTACHMENT_INDEX_BITS 5
#define ATTACHMENT_INDEX_MASK ((1 << ATTACHMENT_INDEX_BITS) - 1)
#if defined(CLIENT_DLL)
#define CBeam C_Beam
#include "c_pixel_visibility.h"
#endif
class CBeam : public CBaseEntity {
DECLARE_CLASS(CBeam, CBaseEntity);
public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#if !defined(CLIENT_DLL)
DECLARE_DATADESC();
#endif
CBeam();
virtual void SetModel(const char *szModelName);
void Spawn(void);
void Precache(void);
#if !defined(CLIENT_DLL)
int ObjectCaps(void);
void SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
int UpdateTransmitState(void);
int ShouldTransmit(const CCheckTransmitInfo *pInfo);
#endif
virtual int DrawDebugTextOverlays(void);
// These functions are here to show the way beams are encoded as entities.
// Encoding beams as entities simplifies their management in the
// client/server architecture
void SetType(int type);
void SetBeamFlags(int flags);
void SetBeamFlag(int flag);
// NOTE: Start + End Pos are specified in *relative* coordinates
void SetStartPos(const Vector &pos);
void SetEndPos(const Vector &pos);
// This will change things so the abs position matches the requested spot
void SetAbsStartPos(const Vector &pos);
void SetAbsEndPos(const Vector &pos);
const Vector &GetAbsStartPos(void) const;
const Vector &GetAbsEndPos(void) const;
void SetStartEntity(CBaseEntity *pEntity);
void SetEndEntity(CBaseEntity *pEntity);
void SetStartAttachment(int attachment);
void SetEndAttachment(int attachment);
void SetTexture(int spriteIndex);
void SetHaloTexture(int spriteIndex);
void SetHaloScale(float haloScale);
void SetWidth(float width);
void SetEndWidth(float endWidth);
void SetFadeLength(float fadeLength);
void SetNoise(float amplitude);
void SetColor(int r, int g, int b);
void SetBrightness(int brightness);
void SetFrame(float frame);
void SetScrollRate(int speed);
void SetFireTime(float flFireTime);
void SetFrameRate(float flFrameRate) { m_flFrameRate = flFrameRate; }
void SetMinDXLevel(int nMinDXLevel) { m_nMinDXLevel = nMinDXLevel; }
void TurnOn(void);
void TurnOff(void);
int GetType(void) const;
int GetBeamFlags(void) const;
CBaseEntity *GetStartEntityPtr(void) const;
int GetStartEntity(void) const;
CBaseEntity *GetEndEntityPtr(void) const;
int GetEndEntity(void) const;
int GetStartAttachment() const;
int GetEndAttachment() const;
virtual const Vector &WorldSpaceCenter(void) const;
int GetTexture(void);
float GetWidth(void) const;
float GetEndWidth(void) const;
float GetFadeLength(void) const;
float GetNoise(void) const;
int GetBrightness(void) const;
float GetFrame(void) const;
float GetScrollRate(void) const;
float GetHDRColorScale(void) const;
void SetHDRColorScale(float flScale) { m_flHDRColorScale = flScale; }
// Call after you change start/end positions
void RelinkBeam(void);
void DoSparks(const Vector &start, const Vector &end);
CBaseEntity *RandomTargetname(const char *szName);
void BeamDamage(trace_t *ptr);
// Init after BeamCreate()
void BeamInit(const char *pSpriteName, float width);
void PointsInit(const Vector &start, const Vector &end);
void PointEntInit(const Vector &start, CBaseEntity *pEndEntity);
void EntsInit(CBaseEntity *pStartEntity, CBaseEntity *pEndEntity);
void LaserInit(CBaseEntity *pStartEntity, CBaseEntity *pEndEntity);
void HoseInit(const Vector &start, const Vector &direction);
void SplineInit(int nNumEnts, CBaseEntity **pEntList, int *attachment);
// Input handlers
static CBeam *BeamCreate(const char *pSpriteName, float width);
static CBeam *BeamCreatePredictable(const char *module, int line,
bool persist, const char *pSpriteName,
float width, CBasePlayer *pOwner);
void LiveForTime(float time);
void BeamDamageInstant(trace_t *ptr, float damage);
// Only supported in TF2 right now
#if defined(INVASION_CLIENT_DLL)
virtual bool ShouldPredict(void) { return true; }
#endif
virtual const char *GetDecalName(void) { return "BigShot"; }
#if defined(CLIENT_DLL)
// IClientEntity overrides.
public:
virtual int DrawModel(int flags);
virtual bool IsTransparent(void);
virtual bool ShouldDraw();
virtual bool IgnoresZBuffer(void) const { return true; }
virtual void OnDataChanged(DataUpdateType_t updateType);
virtual bool OnPredictedEntityRemove(bool isbeingremoved,
C_BaseEntity *predicted);
// Add beam to visible entities list?
virtual void AddEntity(void);
virtual bool ShouldReceiveProjectedTextures(int flags) { return false; }
// Beam Data Elements
private:
// Computes the bounding box of a beam local to the origin of the beam
void ComputeBounds(Vector &mins, Vector &maxs);
friend void RecvProxy_Beam_ScrollSpeed(const CRecvProxyData *pData,
void *pStruct, void *pOut);
friend class CViewRenderBeams;
#endif
protected:
CNetworkVar(float, m_flFrameRate);
CNetworkVar(float, m_flHDRColorScale);
float m_flFireTime;
float m_flDamage; // Damage per second to touchers.
CNetworkVar(int, m_nNumBeamEnts);
#if defined(CLIENT_DLL)
pixelvis_handle_t m_queryHandleHalo;
#endif
private:
#if !defined(CLIENT_DLL)
void InputNoise(inputdata_t &inputdata);
void InputWidth(inputdata_t &inputdata);
void InputColorRedValue(inputdata_t &inputdata);
void InputColorBlueValue(inputdata_t &inputdata);
void InputColorGreenValue(inputdata_t &inputdata);
#endif
// Beam Data Elements
CNetworkVar(int, m_nHaloIndex);
CNetworkVar(int, m_nBeamType);
CNetworkVar(int, m_nBeamFlags);
CNetworkArray(EHANDLE, m_hAttachEntity, MAX_BEAM_ENTS);
CNetworkArray(int, m_nAttachIndex, MAX_BEAM_ENTS);
CNetworkVar(float, m_fWidth);
CNetworkVar(float, m_fEndWidth);
CNetworkVar(float, m_fFadeLength);
CNetworkVar(float, m_fHaloScale);
CNetworkVar(float, m_fAmplitude);
CNetworkVar(float, m_fStartFrame);
CNetworkVar(float, m_fSpeed);
CNetworkVar(int, m_nMinDXLevel);
CNetworkVar(float, m_flFrame);
CNetworkVector(m_vecEndPos);
EHANDLE m_hEndEntity;
#if !defined(CLIENT_DLL)
int m_nDissolveType;
#endif
public:
#ifdef PORTAL
CNetworkVar(bool, m_bDrawInMainRender);
CNetworkVar(bool, m_bDrawInPortalRender);
#endif //#ifdef PORTAL
};
#if !defined(CLIENT_DLL)
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline int CBeam::ObjectCaps(void) {
int flags = 0;
if (HasSpawnFlags(SF_BEAM_TEMPORARY)) flags = FCAP_DONT_SAVE;
return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags;
}
#endif
inline void CBeam::SetFireTime(float flFireTime) { m_flFireTime = flFireTime; }
//-----------------------------------------------------------------------------
// NOTE: Start + End Pos are specified in *relative* coordinates
//-----------------------------------------------------------------------------
inline void CBeam::SetStartPos(const Vector &pos) {
#if defined(CLIENT_DLL)
SetNetworkOrigin(pos);
#endif
SetLocalOrigin(pos);
}
inline void CBeam::SetEndPos(const Vector &pos) { m_vecEndPos = pos; }
// center point of beam
inline const Vector &CBeam::WorldSpaceCenter(void) const {
Vector &vecResult = AllocTempVector();
VectorAdd(GetAbsStartPos(), GetAbsEndPos(), vecResult);
vecResult *= 0.5f;
return vecResult;
}
inline void CBeam::SetStartAttachment(int attachment) {
Assert((attachment & ~ATTACHMENT_INDEX_MASK) == 0);
m_nAttachIndex.Set(0, attachment);
}
inline void CBeam::SetEndAttachment(int attachment) {
Assert((attachment & ~ATTACHMENT_INDEX_MASK) == 0);
m_nAttachIndex.Set(m_nNumBeamEnts - 1, attachment);
}
inline void CBeam::SetTexture(int spriteIndex) { SetModelIndex(spriteIndex); }
inline void CBeam::SetHaloTexture(int spriteIndex) {
m_nHaloIndex = spriteIndex;
}
inline void CBeam::SetHaloScale(float haloScale) { m_fHaloScale = haloScale; }
inline void CBeam::SetWidth(float width) {
Assert(width <= MAX_BEAM_WIDTH);
m_fWidth = MIN(MAX_BEAM_WIDTH, width);
}
inline void CBeam::SetEndWidth(float endWidth) {
Assert(endWidth <= MAX_BEAM_WIDTH);
m_fEndWidth = MIN(MAX_BEAM_WIDTH, endWidth);
}
inline void CBeam::SetFadeLength(float fadeLength) {
m_fFadeLength = fadeLength;
}
inline void CBeam::SetNoise(float amplitude) { m_fAmplitude = amplitude; }
inline void CBeam::SetColor(int r, int g, int b) {
SetRenderColor(r, g, b, GetRenderColor().a);
}
inline void CBeam::SetBrightness(int brightness) {
SetRenderColorA(brightness);
}
inline void CBeam::SetFrame(float frame) { m_fStartFrame = frame; }
inline void CBeam::SetScrollRate(int speed) { m_fSpeed = speed; }
inline CBaseEntity *CBeam::GetStartEntityPtr(void) const {
return m_hAttachEntity[0].Get();
}
inline int CBeam::GetStartEntity(void) const {
CBaseEntity *pEntity = m_hAttachEntity[0].Get();
return pEntity ? pEntity->entindex() : 0;
}
inline CBaseEntity *CBeam::GetEndEntityPtr(void) const {
return m_hAttachEntity[1].Get();
}
inline int CBeam::GetEndEntity(void) const {
CBaseEntity *pEntity = m_hAttachEntity[m_nNumBeamEnts - 1].Get();
return pEntity ? pEntity->entindex() : 0;
}
inline int CBeam::GetStartAttachment() const {
return m_nAttachIndex[0] & ATTACHMENT_INDEX_MASK;
}
inline int CBeam::GetEndAttachment() const {
return m_nAttachIndex[m_nNumBeamEnts - 1] & ATTACHMENT_INDEX_MASK;
}
inline int CBeam::GetTexture(void) { return GetModelIndex(); }
inline float CBeam::GetWidth(void) const { return m_fWidth; }
inline float CBeam::GetEndWidth(void) const { return m_fEndWidth; }
inline float CBeam::GetFadeLength(void) const { return m_fFadeLength; }
inline float CBeam::GetNoise(void) const { return m_fAmplitude; }
inline int CBeam::GetBrightness(void) const { return GetRenderColor().a; }
inline float CBeam::GetFrame(void) const { return m_fStartFrame; }
inline float CBeam::GetScrollRate(void) const { return m_fSpeed; }
inline float CBeam::GetHDRColorScale(void) const { return m_flHDRColorScale; }
inline void CBeam::LiveForTime(float time) {
SetThink(&CBeam::SUB_Remove);
SetNextThink(gpGlobals->curtime + time);
}
inline void CBeam::BeamDamageInstant(trace_t *ptr, float damage) {
m_flDamage = damage;
m_flFireTime = gpGlobals->curtime - 1;
BeamDamage(ptr);
}
bool IsStaticPointEntity(CBaseEntity *pEnt);
// Macro to wrap creation
#define BEAM_CREATE_PREDICTABLE(name, width, player) \
CBeam::BeamCreatePredictable(__FILE__, __LINE__, false, name, width, player)
#define BEAM_CREATE_PREDICTABLE_PERSIST(name, width, player) \
CBeam::BeamCreatePredictable(__FILE__, __LINE__, true, name, width, player)
// Start/End Entity is encoded as 12 bits of entity index, and 4 bits of
// attachment (4:12)
#define BEAMENT_ENTITY(x) ((x)&0xFFF)
#define BEAMENT_ATTACHMENT(x) (((x) >> 12) & 0xF)
// Beam types, encoded as a byte
enum {
BEAM_POINTS = 0,
BEAM_ENTPOINT,
BEAM_ENTS,
BEAM_HOSE,
BEAM_SPLINE,
BEAM_LASER,
NUM_BEAM_TYPES
};
#endif // BEAM_H