csgo-2018-source/game/client/c_func_breakablesurf.h
2021-07-24 21:11:47 -07:00

184 lines
5.2 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef C_FUNC_BREAKABLESURF_H
#define C_FUNC_BREAKABLESURF_H
#ifdef _WIN32
#pragma once
#endif
#include "iviewrender.h"
#include "proxyentity.h"
#define MAX_NUM_PANELS 16
#define NUM_EDGE_TYPES 4
#define NUM_EDGE_STYLES 3
extern IVDebugOverlay *debugoverlay;
enum WinSide_t
{
WIN_SIDE_BOTTOM,
WIN_SIDE_RIGHT,
WIN_SIDE_TOP,
WIN_SIDE_LEFT,
};
enum WinEdge_t
{
EDGE_NOT = -1, // No edge
EDGE_NONE, /* No edge on both sides /##\ */
EDGE_FULL, // Edge on both sides |##|
EDGE_LEFT, /* Edge is on left only |##\ */
EDGE_RIGHT, // Edge is on right only /##|
};
#define STYLE_HIGHLIGHT = -1;
//-----------------------------------------------------------------------------
// All the information associated with a particular handle
//-----------------------------------------------------------------------------
struct Panel_t
{
char m_nWidth;
char m_nHeight;
char m_nSide;
char m_nEdgeType;
char m_nStyle;
};
struct EdgeTexture_t
{
int m_nRenderIndex;
int m_nStyle;
CMaterialReference m_pMaterialEdge;
CTextureReference m_pMaterialEdgeTexture;
};
class C_BreakableSurface : public C_BaseEntity, public IBrushRenderer
{
public:
DECLARE_CLASS( C_BreakableSurface, C_BaseEntity );
DECLARE_DATADESC();
DECLARE_CLIENTCLASS();
int m_nNumWide;
int m_nNumHigh;
float m_flPanelWidth;
float m_flPanelHeight;
Vector m_vNormal;
Vector m_vCorner;
bool m_bIsBroken;
int m_nSurfaceType;
// This is the texture we're going to use to multiply by the cracked base texture
ITexture* m_pCurrentDetailTexture;
// Stores linked list of edges to render
CUtlLinkedList< Panel_t, unsigned short > m_RenderList;
C_BreakableSurface();
~C_BreakableSurface();
public:
void InitMaterial(WinEdge_t nEdgeType, int nEdgeStyle, char const* pMaterialName);
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual void OnPreDataChanged( DataUpdateType_t updateType );
RenderableTranslucencyType_t ComputeTranslucencyType( void );
bool HavePanel(int nWidth, int nHeight);
bool RenderBrushModelSurface( IClientEntity* pBaseEntity, IBrushSurface* pBrushSurface );
int DrawModel( int flags, const RenderableInstance_t &instance );
void DrawSolidBlocks( IBrushSurface* pBrushSurface );
virtual void OnRestore();
virtual bool ShouldReceiveProjectedTextures( int flags );
private:
// One bit per pane
CNetworkArray( bool, m_RawPanelBitVec, MAX_NUM_PANELS * MAX_NUM_PANELS );
bool m_PrevRawPanelBitVec[ MAX_NUM_PANELS * MAX_NUM_PANELS ];
// 2 bits of flags and 2 bits of edge type
byte m_nPanelBits[MAX_NUM_PANELS][MAX_NUM_PANELS]; //UNDONE: allocate this dynamically?
CMaterialReference m_pMaterialBox;
EdgeTexture_t m_pSolid;
EdgeTexture_t m_pEdge[NUM_EDGE_TYPES][NUM_EDGE_STYLES];
inline bool InLegalRange(int nWidth, int nHeight);
inline bool IsPanelSolid(int nWidth, int nHeight);
inline bool IsPanelStale(int nWidth, int nHeight);
inline void SetPanelSolid(int nWidth, int nHeight, bool value);
inline void SetPanelStale(int nWidth, int nHeight, bool value);
void DrawOneEdge( IBrushSurface* pBrushSurface, IMesh* pMesh,
CMeshBuilder *pMeshBuilder, const Vector &vStartPos,
const Vector &vWStep, const Vector &vHstep, WinSide_t nEdge);
void DrawOneHighlight( IBrushSurface* pBrushSurface, IMesh* pMesh,
CMeshBuilder *pMeshBuilder, const Vector &vStartPos,
const Vector &vWStep, const Vector &vHstep, WinSide_t nEdge);
void DrawOneBlock(IBrushSurface* pBrushSurface, IMesh* pMesh,
CMeshBuilder *pMeshBuilder, const Vector &vPosition,
const Vector &vWidth, const Vector &vHeight);
void DrawRenderList( IBrushSurface* pBrushSurface);
void DrawRenderListHighlights( IBrushSurface* pBrushSurface );
int FindRenderPanel(int nWidth, int nHeight, WinSide_t nSide);
void AddToRenderList(int nWidth, int nHeight, WinSide_t nSide, WinEdge_t nEdgeType, int forceStyle);
int FindFirstRenderTexture(WinEdge_t nEdgeType, int nStyle);
inline void SetStyleType( int w, int h, int type )
{
Assert( type < NUM_EDGE_STYLES );
Assert( type >= 0 );
// Clear old value
m_nPanelBits[ w ][ h ] &= ( ~0x03 << 2 );
// Insert new value
m_nPanelBits[ w ][ h ] |= ( type << 2 );
}
inline int GetStyleType( int w, int h )
{
int value = m_nPanelBits[ w ][ h ];
value = ( value >> 2 ) & 0x03;
Assert( value < NUM_EDGE_STYLES );
return value;
}
// Gets at the cracked version of the material
void FindCrackedMaterial();
CMaterialReference m_pCrackedMaterial;
CTextureReference m_pMaterialBoxTexture;
void UpdateEdgeType(int nWidth, int nHeight, int forceStyle = -1 );
};
class CBreakableSurfaceProxy : public CEntityMaterialProxy
{
public:
CBreakableSurfaceProxy();
virtual ~CBreakableSurfaceProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( C_BaseEntity *pC_BaseEntity );
virtual IMaterial *GetMaterial();
private:
// get at the material whose texture we're going to steal
void AcquireSourceMaterial( C_BaseEntity* pEnt );
IMaterialVar* m_BaseTextureVar;
};
#endif // C_FUNC_BREAKABLESURF_H