07 Jan 2009
This commit is contained in:
parent
427370f67f
commit
9a4b42440d
|
@ -52,7 +52,6 @@ inline void CL_PlaySound( int iSound, float flVolume, Vector &pos, float pitch =
|
|||
#define AngleVectors (*g_engfuncs.pfnAngleVectors)
|
||||
#define DrawCenterPrint (*g_engfuncs.pfnDrawCenterPrint)
|
||||
#define CenterPrint (*g_engfuncs.pfnCenterPrint)
|
||||
#define DrawChar (*g_engfuncs.pfnDrawCharacter)
|
||||
#define DrawString (*g_engfuncs.pfnDrawString)
|
||||
#define GetParms (*g_engfuncs.pfnGetParms)
|
||||
#define GetViewAngles (*g_engfuncs.pfnGetViewAngles)
|
||||
|
@ -73,12 +72,4 @@ inline void CL_PlaySound( int iSound, float flVolume, Vector &pos, float pitch =
|
|||
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
|
||||
#define HOST_ERROR (*g_engfuncs.pfnHostError)
|
||||
|
||||
// heavy legacy of Valve...
|
||||
// tune char size by taste
|
||||
inline void TextMessageDrawChar( int xpos, int ypos, int number, int r, int g, int b )
|
||||
{
|
||||
SetColor((r / 255.0f), (g / 255.0f), (b / 255.0f), 1.0f );
|
||||
DrawChar( xpos, ypos, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, number );
|
||||
}
|
||||
|
||||
#endif//ENGINECALLBACKS_H
|
|
@ -34,10 +34,12 @@ void HUD_StudioEvent( const dstudioevent_t *event, edict_t *entity )
|
|||
case 5004:
|
||||
// Client side sound
|
||||
CL_PlaySound( event->options, 1.0f, entity->v.attachment[0] );
|
||||
ALERT( at_console, "CL_PlaySound( %s )\n", event->options );
|
||||
break;
|
||||
case 5005:
|
||||
// Client side sound with random pitch
|
||||
pitch = 85 + RANDOM_LONG( 0, 0x1F );
|
||||
ALERT( at_console, "CL_PlaySound( %s )\n", event->options );
|
||||
CL_PlaySound( event->options, RANDOM_FLOAT( 0.7f, 0.9f ), entity->v.attachment[0], pitch );
|
||||
break;
|
||||
case 5050:
|
||||
|
|
|
@ -72,6 +72,7 @@ void CHud :: VidInit( void )
|
|||
|
||||
m_hsprCursor = 0;
|
||||
m_hHudError = 0;
|
||||
m_hHudFont = 0;
|
||||
|
||||
Draw_VidInit();
|
||||
|
||||
|
@ -143,6 +144,7 @@ void CHud :: VidInit( void )
|
|||
// loading error sprite
|
||||
m_HUD_error = GetSpriteIndex( "error" );
|
||||
m_hHudError = GetSprite( m_HUD_error );
|
||||
m_hHudFont = GetSprite( GetSpriteIndex( "hud_font" ));
|
||||
|
||||
m_Sound.VidInit();
|
||||
m_Ammo.VidInit();
|
||||
|
@ -177,10 +179,19 @@ void CHud :: Think( void )
|
|||
}
|
||||
|
||||
// think about default fov
|
||||
if( m_flFOV == 0 )
|
||||
float def_fov = CVAR_GET_FLOAT( "default_fov" );
|
||||
if( m_flFOV == 0.0f ) m_flFOV = max( CVAR_GET_FLOAT( "default_fov" ), 90 );
|
||||
|
||||
// change sensitivity
|
||||
if( m_flFOV == def_fov )
|
||||
{
|
||||
// only let players adjust up in fov, and only if they are not overriden by something else
|
||||
m_flFOV = max( CVAR_GET_FLOAT( "default_fov" ), 90 );
|
||||
m_flMouseSensitivity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set a new sensitivity that is proportional to the change from the FOV default
|
||||
m_flMouseSensitivity = CVAR_GET_FLOAT( "sensitivity" ) * ( m_flFOV / def_fov );
|
||||
m_flMouseSensitivity *= CVAR_GET_FLOAT( "zoom_sensitivity_ratio" ); // apply zoom factor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,13 +205,17 @@ int CHud :: UpdateClientData( client_data_t *cdata, float time )
|
|||
|
||||
m_iKeyBits = cdata->iKeyBits;
|
||||
m_iWeaponBits = cdata->iWeaponBits;
|
||||
m_flFOV = cdata->fov;
|
||||
|
||||
Think();
|
||||
|
||||
cdata->fov = m_flFOV;
|
||||
cdata->iKeyBits = m_iKeyBits;
|
||||
cdata->v_idlescale = m_iConcussionEffect;
|
||||
|
||||
// fov has been changed
|
||||
if( m_flFOV != cdata->fov )
|
||||
cdata->fov = m_flFOV;
|
||||
|
||||
if( m_flMouseSensitivity )
|
||||
cdata->mouse_sensitivity = m_flMouseSensitivity;
|
||||
|
||||
|
|
|
@ -634,7 +634,6 @@ public:
|
|||
int _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_Intermission( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_ViewMode( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_ScreenShake( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_RainData( const char *pszName, int iSize, void *pbuf );
|
||||
|
@ -684,6 +683,7 @@ public:
|
|||
// error sprite
|
||||
int m_HUD_error;
|
||||
HSPRITE m_hHudError;
|
||||
HSPRITE m_hHudFont;
|
||||
|
||||
void AddHudElem( CHudBase *p );
|
||||
float GetSensitivity() { return m_flMouseSensitivity; }
|
||||
|
|
|
@ -65,7 +65,8 @@ void HistoryResource :: AddToHistory( int iType, const char *szName, int iCount
|
|||
return;
|
||||
|
||||
if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) )
|
||||
{ // the pic would have to be drawn too high
|
||||
{
|
||||
// the pic would have to be drawn too high
|
||||
// so start from the bottom
|
||||
iCurrentHistorySlot = 0;
|
||||
}
|
||||
|
@ -110,7 +111,8 @@ int HistoryResource :: DrawAmmoHistory( float flTime )
|
|||
rgAmmoHistory[i].DisplayTime = min( rgAmmoHistory[i].DisplayTime, gHUD.m_flTime + HISTORY_DRAW_TIME );
|
||||
|
||||
if ( rgAmmoHistory[i].DisplayTime <= flTime )
|
||||
{ // pic drawing time has expired
|
||||
{
|
||||
// pic drawing time has expired
|
||||
memset( &rgAmmoHistory[i], 0, sizeof(HIST_ITEM) );
|
||||
CheckClearHistory();
|
||||
}
|
||||
|
|
|
@ -167,7 +167,8 @@ extern void SPR_DrawTransColor( int frame, int x, int y, int width, int height )
|
|||
extern void SPR_DrawTransColor( int frame, int x, int y, const wrect_t *prc );
|
||||
extern void SPR_DrawAdditive( int frame, int x, int y, const wrect_t *prc );
|
||||
extern void SPR_DrawAdditive( int frame, int x, int y, int width, int height );
|
||||
extern void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
|
||||
extern void TextMessageDrawChar( int xpos, int ypos, int number, int r, int g, int b );
|
||||
extern void FillRGBA( float x, float y, float width, float height, int r, int g, int b, int a );
|
||||
extern void SetCrosshair( HSPRITE hspr, wrect_t rc, int r, int g, int b );
|
||||
extern void DrawCrosshair( void );
|
||||
extern void DrawPause( void );
|
||||
|
|
|
@ -31,7 +31,6 @@ DECLARE_HUDMESSAGE( ResetHUD );
|
|||
DECLARE_HUDMESSAGE( InitHUD );
|
||||
DECLARE_HUDMESSAGE( ViewMode );
|
||||
DECLARE_HUDMESSAGE( Particle );
|
||||
DECLARE_HUDMESSAGE( SetFOV );
|
||||
DECLARE_HUDMESSAGE( Concuss );
|
||||
DECLARE_HUDMESSAGE( GameMode );
|
||||
DECLARE_HUDMESSAGE( CamData );
|
||||
|
@ -51,7 +50,6 @@ int CHud :: InitMessages( void )
|
|||
HOOK_MESSAGE( Intermission );
|
||||
HOOK_MESSAGE( InitHUD );
|
||||
HOOK_MESSAGE( ViewMode );
|
||||
HOOK_MESSAGE( SetFOV );
|
||||
HOOK_MESSAGE( Concuss );
|
||||
HOOK_MESSAGE( HUDColor );
|
||||
HOOK_MESSAGE( Particle );
|
||||
|
@ -77,9 +75,6 @@ int CHud :: InitMessages( void )
|
|||
CVAR_REGISTER( "default_fov", "90", 0, "default client fov" );
|
||||
CVAR_REGISTER( "hud_draw", "1", CVAR_ARCHIVE, "hud drawing modes" );
|
||||
CVAR_REGISTER( "hud_takesshots", "0", 0, "take screenshots at 30 fps" );
|
||||
|
||||
// UNDONE: replace all coord variables with float not int
|
||||
// FIXME: remove jitter for moving objects (flashlight beam etc)
|
||||
CVAR_REGISTER( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" );
|
||||
|
||||
// clear any old HUD list
|
||||
|
@ -160,38 +155,6 @@ int CHud :: MsgFunc_Intermission( const char *pszName, int iSize, void *pbuf )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pszName, iSize, pbuf );
|
||||
|
||||
float newfov = READ_FLOAT();
|
||||
float def_fov = CVAR_GET_FLOAT( "default_fov" );
|
||||
|
||||
if( newfov == 0.0f )
|
||||
{
|
||||
m_flFOV = def_fov;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flFOV = newfov;
|
||||
}
|
||||
|
||||
if( m_flFOV == def_fov )
|
||||
{
|
||||
m_flMouseSensitivity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set a new sensitivity that is proportional to the change from the FOV default
|
||||
m_flMouseSensitivity = CVAR_GET_FLOAT( "sensitivity" ) * ( newfov / def_fov );
|
||||
m_flMouseSensitivity *= CVAR_GET_FLOAT( "zoom_sensitivity_ratio" ); // apply zoom factor
|
||||
}
|
||||
END_READ();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int CHud::MsgFunc_HUDColor(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
BEGIN_READ( pszName, iSize, pbuf );
|
||||
|
|
|
@ -367,6 +367,46 @@ void SPR_Set( HSPRITE hPic, int r, int g, int b, int a )
|
|||
SetColor((r / 255.0f), (g / 255.0f), (b / 255.0f), (a / 255.0f));
|
||||
}
|
||||
|
||||
inline static void SPR_AdjustSize( float *x, float *y, float *w, float *h )
|
||||
{
|
||||
if( !x && !y && !w && !h ) return;
|
||||
|
||||
// scale for screen sizes
|
||||
float xscale = gHUD.m_scrinfo.iRealWidth / (float)gHUD.m_scrinfo.iWidth;
|
||||
float yscale = gHUD.m_scrinfo.iRealHeight / (float)gHUD.m_scrinfo.iHeight;
|
||||
|
||||
if( x ) *x *= xscale;
|
||||
if( y ) *y *= yscale;
|
||||
if( w ) *w *= xscale;
|
||||
if( h ) *h *= yscale;
|
||||
}
|
||||
|
||||
inline static void SPR_DrawChar( HSPRITE hFont, int xpos, int ypos, int width, int height, int ch )
|
||||
{
|
||||
float size, frow, fcol;
|
||||
float ax, ay, aw, ah;
|
||||
int fontWidth, fontHeight;
|
||||
|
||||
ch &= 255;
|
||||
|
||||
if( ch == ' ' ) return;
|
||||
if( ypos < -height ) return;
|
||||
|
||||
ax = xpos;
|
||||
ay = ypos;
|
||||
aw = width;
|
||||
ah = height;
|
||||
|
||||
SPR_AdjustSize( &ax, &ay, &aw, &ah );
|
||||
GetParms( &fontWidth, &fontHeight, NULL, 0, hFont );
|
||||
|
||||
frow = (ch >> 4) * 0.0625f + (0.5f / (float)fontWidth);
|
||||
fcol = (ch & 15) * 0.0625f + (0.5f / (float)fontHeight);
|
||||
size = 0.0625f - (1.0f / (float)fontWidth);
|
||||
|
||||
DrawImageExt( hFont, ax, ay, aw, ah, fcol, frow, fcol + size, frow + size );
|
||||
}
|
||||
|
||||
inline static void SPR_DrawGeneric( int frame, float x, float y, float width, float height, const wrect_t *prc )
|
||||
{
|
||||
float s1, s2, t1, t2;
|
||||
|
@ -395,21 +435,19 @@ inline static void SPR_DrawGeneric( int frame, float x, float y, float width, fl
|
|||
s2 = t2 = 1.0f;
|
||||
}
|
||||
|
||||
float xscale, yscale;
|
||||
|
||||
// scale for screen sizes
|
||||
xscale = gHUD.m_scrinfo.iRealWidth / (float)gHUD.m_scrinfo.iWidth;
|
||||
yscale = gHUD.m_scrinfo.iRealHeight / (float)gHUD.m_scrinfo.iHeight;
|
||||
|
||||
x *= xscale;
|
||||
y *= yscale;
|
||||
width *= xscale;
|
||||
height *= yscale;
|
||||
|
||||
SPR_AdjustSize( &x, &y, &width, &height );
|
||||
DrawImageExt( ds.hSprite, x, y, width, height, s1, t1, s2, t2 );
|
||||
}
|
||||
|
||||
void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a )
|
||||
void TextMessageDrawChar( int xpos, int ypos, int number, int r, int g, int b )
|
||||
{
|
||||
// tune char size by taste
|
||||
SetColor((r / 255.0f), (g / 255.0f), (b / 255.0f), 1.0f );
|
||||
SPR_DrawChar( gHUD.m_hHudFont, xpos, ypos, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, number );
|
||||
}
|
||||
|
||||
void FillRGBA( float x, float y, float width, float height, int r, int g, int b, int a )
|
||||
{
|
||||
Vector RGB;
|
||||
|
||||
|
@ -417,17 +455,7 @@ void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a )
|
|||
RGB.y = (float)(g / 255.0f);
|
||||
RGB.z = (float)(b / 255.0f);
|
||||
|
||||
float xscale, yscale;
|
||||
|
||||
// scale for screen sizes
|
||||
xscale = gHUD.m_scrinfo.iRealWidth / (float)gHUD.m_scrinfo.iWidth;
|
||||
yscale = gHUD.m_scrinfo.iRealHeight / (float)gHUD.m_scrinfo.iHeight;
|
||||
|
||||
x *= xscale;
|
||||
y *= yscale;
|
||||
width *= xscale;
|
||||
height *= yscale;
|
||||
|
||||
SPR_AdjustSize( &x, &y, &width, &height );
|
||||
g_engfuncs.pfnFillRGBA( x, y, width, height, RGB, (float)(a / 255.0f));
|
||||
}
|
||||
|
||||
|
@ -493,8 +521,8 @@ void DrawCrosshair( void )
|
|||
if( ds.hCrosshair == 0 ) return;
|
||||
|
||||
// FIXME: apply crosshair angles
|
||||
int x = (ScreenWidth - ds.rcCrosshair.right) / 2;
|
||||
int y = (ScreenHeight - ds.rcCrosshair.bottom) / 2;
|
||||
int x = (ScreenWidth - (ds.rcCrosshair.right - ds.rcCrosshair.left)) / 2;
|
||||
int y =(ScreenHeight - (ds.rcCrosshair.bottom - ds.rcCrosshair.top)) / 2;
|
||||
|
||||
ds.hSprite = ds.hCrosshair;
|
||||
SetParms( ds.hCrosshair, kRenderTransAlpha, 0 );
|
||||
|
|
348
client/r_main.h
348
client/r_main.h
|
@ -1,348 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) XashXT Group 2006
|
||||
//=======================================================================
|
||||
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define GLEW_STATIC
|
||||
#include "windows.h"
|
||||
#include "glew.h"
|
||||
#include <gl\glu.h>
|
||||
#include "cva.h"
|
||||
#include "ref_params.h"
|
||||
#include "com_model.h"
|
||||
|
||||
#pragma warning(disable:4244)
|
||||
|
||||
#define SAFE_GET_PROC( func, type, name) if (!func) func = (type) wglGetProcAddress( name ); \
|
||||
assert(func != NULL)
|
||||
|
||||
#define VIEWPORT_SIZE 512
|
||||
#define GL_TEXTURE_NUM_BASE (1<<25)
|
||||
|
||||
#define SURF_PLANEBACK 2
|
||||
#define SURF_DRAWTURB 0x10
|
||||
|
||||
#define SURF_MIRROR (1<<16)
|
||||
#define SURF_WARPMIRROR (1<<17)
|
||||
#define SURF_SCREEN (1<<18)
|
||||
#define SURF_PORTAL (1<<19)
|
||||
|
||||
// 0-2 are axial planes
|
||||
#define PLANE_X 0
|
||||
#define PLANE_Y 1
|
||||
#define PLANE_Z 2
|
||||
|
||||
#define MAX_CVA_VERTS 2048
|
||||
|
||||
//We need the following extensions:
|
||||
|
||||
//ARB_multitexture
|
||||
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
|
||||
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
|
||||
extern PFNGLMULTITEXCOORD1FARBPROC glMultiTexCoord1fARB;
|
||||
extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
|
||||
extern PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB;
|
||||
extern PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3fARB;
|
||||
extern PFNGLMULTITEXCOORD3FVARBPROC glMultiTexCoord3fvARB;
|
||||
extern PFNGLMULTITEXCOORD4FARBPROC glMultiTexCoord4fARB;
|
||||
extern PFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB;
|
||||
|
||||
//EXT_texture_3d
|
||||
extern PFNGLTEXIMAGE3DEXTPROC glTexImage3DEXT;
|
||||
|
||||
//ARB_texture_cube_map
|
||||
|
||||
//ARB_vertex_program
|
||||
//ARB_fragment_program
|
||||
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
|
||||
extern PFNGLBINDPROGRAMARBPROC glBindProgramARB;
|
||||
extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
|
||||
extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
|
||||
extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
|
||||
extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
|
||||
extern PFNGLISPROGRAMARBPROC glIsProgramARB;
|
||||
|
||||
//NV_register_combiners
|
||||
extern PFNGLCOMBINERPARAMETERFVNVPROC glCombinerParameterfvNV;
|
||||
extern PFNGLCOMBINERPARAMETERIVNVPROC glCombinerParameterivNV;
|
||||
extern PFNGLCOMBINERPARAMETERFNVPROC glCombinerParameterfNV;
|
||||
extern PFNGLCOMBINERPARAMETERINVPROC glCombinerParameteriNV;
|
||||
extern PFNGLCOMBINERINPUTNVPROC glCombinerInputNV;
|
||||
extern PFNGLCOMBINEROUTPUTNVPROC glCombinerOutputNV;
|
||||
extern PFNGLFINALCOMBINERINPUTNVPROC glFinalCombinerInputNV;
|
||||
|
||||
//ATI_pn_triangles
|
||||
extern PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
|
||||
extern PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
|
||||
|
||||
inline bool GLEXT_CheckExtension(const char *ext)
|
||||
{
|
||||
return (strstr((const char *)glGetString(GL_EXTENSIONS), ext) != NULL);
|
||||
}
|
||||
|
||||
bool GLEXT_Setup_ARB_multitexture();
|
||||
bool GLEXT_Setup_EXT_texture_3d();
|
||||
bool GLEXT_Setup_ARB_texture_cubemap();
|
||||
bool GLEXT_Setup_ARB_vertex_program();
|
||||
bool GLEXT_Setup_ARB_fragment_program();
|
||||
bool GLEXT_Setup_NV_register_combiners();
|
||||
bool GLEXT_Setup_ATI_pn_triangles();
|
||||
|
||||
void GL_Init( void );
|
||||
void GL_VidInit( void );
|
||||
void GL_Shutdown( void );
|
||||
void GL_PreRender( void );
|
||||
void GL_Render( bool trans );
|
||||
void GL_ExtractFrustum( void );
|
||||
void GL_MarkTextures( void );
|
||||
void R_Draw( bool transparent );
|
||||
|
||||
//Utils
|
||||
float R_SphereInFrustum( vec3_t o, float radius );
|
||||
cl_entity_t *UTIL_GetClientEntityWithServerIndex( int sv_index );
|
||||
|
||||
extern bool g_HardwareCapable;
|
||||
extern bool g_HardwareShaderCapable;
|
||||
|
||||
extern int g_iTotalMirrors;
|
||||
extern int g_iTotalVisibleMirrors;
|
||||
extern int g_iTotalScreens;
|
||||
extern int g_iTotalVisibleScreens;
|
||||
extern int g_iTotalPortals;
|
||||
extern int g_iTotalVisiblePortals;
|
||||
extern double realtime;
|
||||
|
||||
extern bool g_FirstFrame;
|
||||
extern bool g_RenderReady;
|
||||
extern bool g_bFinalPass;
|
||||
extern bool g_bEndCalc;
|
||||
extern int m_RenderRefCount; //refcounter (use for debug)
|
||||
|
||||
//passes info
|
||||
extern bool g_bMirrorShouldpass;
|
||||
extern bool g_bScreenShouldpass;
|
||||
extern bool g_bPortalShouldpass;
|
||||
extern bool g_bSkyShouldpass;
|
||||
extern bool g_bMirrorPass;
|
||||
extern bool g_bPortalPass;
|
||||
extern bool g_bScreenPass;
|
||||
extern bool g_bSkyPass;
|
||||
|
||||
//base origin and angles
|
||||
extern vec3_t g_vecBaseOrigin; //base origin - transformed always
|
||||
extern vec3_t g_vecBaseAngles; //base angles - transformed always
|
||||
extern vec3_t g_vecCurrentOrigin; //current origin
|
||||
extern vec3_t g_vecCurrentAngles; //current angles
|
||||
|
||||
extern float r_projection_matrix[16];
|
||||
extern float r_world_matrix[16];
|
||||
|
||||
extern unsigned int g_uiNoiseTex;
|
||||
extern unsigned int g_uiNoiseTexDsDt;
|
||||
extern unsigned int pTexId;
|
||||
extern unsigned int AllocateTextureIndex(void);
|
||||
|
||||
typedef struct mirror_s
|
||||
{
|
||||
int index;
|
||||
bool enabled;
|
||||
bool visible;
|
||||
float origin[3];
|
||||
float angles[3];
|
||||
float normal[3];
|
||||
float radius;
|
||||
float alpha;
|
||||
|
||||
float pr[16];
|
||||
|
||||
bool water;
|
||||
bool twoside;
|
||||
|
||||
//CVA-related
|
||||
int firstvertex;
|
||||
int numvertices;
|
||||
|
||||
unsigned int texture;
|
||||
msurface_t *surface;
|
||||
|
||||
int sv_entindex;
|
||||
cl_entity_t *ent; //for brush model mirrors
|
||||
|
||||
struct mirror_s *next;
|
||||
}mirror_t;
|
||||
|
||||
typedef struct screen_s
|
||||
{
|
||||
int index;
|
||||
bool enabled;
|
||||
bool visible;
|
||||
float origin[3];
|
||||
float radius;
|
||||
float alpha;
|
||||
|
||||
//current camera member
|
||||
int cam_idx;
|
||||
float cam_origin[3];
|
||||
float cam_angles[3];
|
||||
|
||||
float pr[16];
|
||||
|
||||
//CVA-related
|
||||
int firstvertex;
|
||||
int numvertices;
|
||||
|
||||
unsigned int texture;
|
||||
msurface_t *surface;
|
||||
|
||||
int sv_entindex;
|
||||
cl_entity_t *ent;
|
||||
bool color;
|
||||
|
||||
struct screen_s *next;
|
||||
}screen_t;
|
||||
|
||||
typedef struct portal_s
|
||||
{
|
||||
int index;
|
||||
bool enabled;
|
||||
bool visible;
|
||||
float origin[3];
|
||||
float angles[3];
|
||||
float normal[3];
|
||||
float radius;
|
||||
float alpha;
|
||||
|
||||
//current camera member
|
||||
int cam_idx;
|
||||
float cam_origin[3];
|
||||
float cam_angles[3];
|
||||
|
||||
float pr[16];
|
||||
|
||||
//CVA-related
|
||||
int firstvertex;
|
||||
int numvertices;
|
||||
|
||||
unsigned int texture;
|
||||
msurface_t *surface;
|
||||
|
||||
int sv_entindex;
|
||||
cl_entity_t *ent; //for brush model mirrors
|
||||
|
||||
struct portal_s *next;
|
||||
}portal_t;
|
||||
|
||||
typedef struct cl_sbe_s
|
||||
{
|
||||
int index;
|
||||
bool initialized;
|
||||
}cl_sbe_t;
|
||||
|
||||
extern cvar_t *r_debug; //show renderer info
|
||||
extern cvar_t *r_shadows; //original HL shadows
|
||||
extern cvar_t *r_mirrors; //mirrors
|
||||
extern cvar_t *r_screens; //screens
|
||||
extern cvar_t *r_portals; //portals
|
||||
|
||||
mirror_t *R_AllocateMirror(msurface_t *surf);
|
||||
void R_FreeMirrors(void);
|
||||
void R_InitMirrors(void);
|
||||
void R_SetupMirrorRenderPass(ref_params_t *pparams);
|
||||
void R_SetupNewMirror(ref_params_t *pparams);
|
||||
void R_NewMirrorRenderPass(void);
|
||||
void R_RenderMirrors(bool trans);
|
||||
void R_InitMirrorsForFrame(void);
|
||||
void R_ResetMirrors(void);
|
||||
void AddMirrorBrushEntity( int idx );
|
||||
void R_DrawMirror(bool trans);
|
||||
|
||||
screen_t *R_AllocateScreen(msurface_t *surf);
|
||||
void R_ResetScreens( void );
|
||||
void R_FreeScreens( void );
|
||||
void R_InitScreens( void );
|
||||
void R_RenderScreens( bool trans );
|
||||
void AddScreenBrushEntity( int idx );
|
||||
void R_SetupScreenRenderPass(ref_params_t *pparams);
|
||||
void R_SetupNewScreen(ref_params_t *pparams);
|
||||
void R_NewScreenRenderPass( void );
|
||||
void R_InitScreensForFrame(void);
|
||||
void R_DrawScreen(bool trans);
|
||||
|
||||
portal_t *R_AllocatePortal(msurface_t *surf);
|
||||
void R_FreePortals(void);
|
||||
void R_InitPortals(void);
|
||||
void R_SetupPortalRenderPass(ref_params_t *pparams);
|
||||
void R_SetupNewPortal(ref_params_t *pparams);
|
||||
void R_NewPortalRenderPass(void);
|
||||
void R_RenderPortals(bool trans);
|
||||
void R_InitPortalsForFrame(void);
|
||||
void R_ResetPortals(void);
|
||||
void AddPortalBrushEntity( int idx );
|
||||
void R_DrawPortal(bool trans);
|
||||
|
||||
//Noise
|
||||
void CreateNoiseTexture3D (float scale);
|
||||
void CreateNoiseTextureDsDt (float scale);
|
||||
|
||||
//Water
|
||||
void CreateWaterShader_ARB(void);
|
||||
void DeleteWaterShader_ARB(void);
|
||||
void BindWaterShader_ARB(mirror_t *mir);
|
||||
void UnbindWaterShader_ARB(void);
|
||||
|
||||
//Black & white screen
|
||||
void CreateScreenShader_ARB(void);
|
||||
void DeleteScreenShader_ARB(void);
|
||||
|
||||
//Logging
|
||||
void logInitLog( char *filename );
|
||||
void logCloseLog();
|
||||
void logPrintOpenGLInformation( void );
|
||||
void logPrint( char *str );
|
||||
void logPrintf( char *fmt, ...);
|
||||
|
||||
extern mirror_t *m_pCurrentMirror;
|
||||
extern screen_t *m_pCurrentScreen;
|
||||
extern portal_t *m_pCurrentPortal;
|
||||
|
||||
//GL state management
|
||||
struct glstate_curstate_t
|
||||
{
|
||||
unsigned char
|
||||
blend : 1,
|
||||
depth_test : 1,
|
||||
: 6;
|
||||
};
|
||||
|
||||
struct glstate_curstagestate_t
|
||||
{
|
||||
unsigned char
|
||||
texture2d : 1,
|
||||
texture3d : 1,
|
||||
: 6;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct glstate_curstate_t curstate;
|
||||
struct glstate_curstagestate_t curstagestate[8]; //assume 8 will be max texture stages
|
||||
unsigned int current_texture_stage;
|
||||
} glstate_t;
|
||||
|
||||
extern glstate_t glstate;
|
||||
|
||||
#define GLSTATE_ENABLE_BLEND if(!glstate.curstate.blend) { glEnable(GL_BLEND); glstate.curstate.blend=1; }
|
||||
#define GLSTATE_ENABLE_DEPTH_TEST if(!glstate.curstate.depth_test) { glEnable(GL_DEPTH_TEST); glstate.curstate.depth_test=1; }
|
||||
#define GLSTATE_ENABLE_TEXTURE if(!glstate.curstagestate[glstate.current_texture_stage].texture2d) { glEnable(GL_TEXTURE_2D); glstate.curstagestate[glstate.current_texture_stage].texture2d=1; }
|
||||
#define GLSTATE_ENABLE_TEXTURE3D if(!glstate.curstagestate[glstate.current_texture_stage].texture3d) { glEnable(GL_TEXTURE_3D); glstate.curstagestate[glstate.current_texture_stage].texture3d=1; }
|
||||
#define GLSTATE_DISABLE_BLEND if(glstate.curstate.blend) { glDisable(GL_BLEND); glstate.curstate.blend=0; }
|
||||
#define GLSTATE_DISABLE_DEPTH_TEST if(glstate.curstate.depth_test) { glDisable(GL_DEPTH_TEST); glstate.curstate.depth_test=0; }
|
||||
#define GLSTATE_DISABLE_TEXTURE if(glstate.curstagestate[glstate.current_texture_stage].texture2d) { glDisable(GL_TEXTURE_2D); glstate.curstagestate[glstate.current_texture_stage].texture2d=0; }
|
||||
#define GLSTATE_DISABLE_TEXTURE3D if(glstate.curstagestate[glstate.current_texture_stage].texture3d) { glDisable(GL_TEXTURE_3D); glstate.curstagestate[glstate.current_texture_stage].texture3d=0; }
|
||||
|
||||
void GL_SelectTexture( GLenum mode );
|
||||
|
||||
//client sprite renderer
|
||||
void R_DrawSprite ( cl_entity_t *e, HSPRITE m_hSprite );
|
||||
mspriteframe_t *R_GetSpriteFrame (model_t *mod, int frame);
|
|
@ -1,960 +0,0 @@
|
|||
#include "hud.h"
|
||||
#include "r_main.h"
|
||||
#include "r_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_state.h"
|
||||
#include "event_api.h"
|
||||
#include "cl_entity.h"
|
||||
#include "triangleapi.h"
|
||||
#include "r_particle.h"
|
||||
#include "com_model.h"
|
||||
#include "pmtrace.h" // for contents and traceline
|
||||
#include "pm_defs.h"
|
||||
|
||||
ParticleSystemManager* g_pParticleSystems = NULL;
|
||||
|
||||
void CreateAurora( int idx, char *file )
|
||||
{
|
||||
ParticleSystem *pSystem = new ParticleSystem( idx, file );
|
||||
g_pParticleSystems->AddSystem(pSystem);
|
||||
}
|
||||
|
||||
|
||||
ParticleSystemManager::ParticleSystemManager( void )
|
||||
{
|
||||
m_pFirstSystem = NULL;
|
||||
}
|
||||
|
||||
ParticleSystemManager::~ParticleSystemManager( void )
|
||||
{
|
||||
ClearSystems();
|
||||
}
|
||||
|
||||
void ParticleSystemManager::AddSystem( ParticleSystem* pNewSystem )
|
||||
{
|
||||
pNewSystem->m_pNextSystem = m_pFirstSystem;
|
||||
m_pFirstSystem = pNewSystem;
|
||||
}
|
||||
|
||||
ParticleSystem *ParticleSystemManager::FindSystem( cl_entity_t* pEntity )
|
||||
{
|
||||
for (ParticleSystem *pSys = m_pFirstSystem; pSys; pSys = pSys->m_pNextSystem)
|
||||
{
|
||||
if (pEntity->index == pSys->m_iEntIndex) return pSys;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ParticleSystemManager::UpdateSystems( void )
|
||||
{
|
||||
static float fOldTime, fTime;
|
||||
fOldTime = fTime;
|
||||
fTime = gEngfuncs.GetClientTime();
|
||||
float frametime = fTime - fOldTime;
|
||||
|
||||
ParticleSystem* pSystem;
|
||||
ParticleSystem* pLast = NULL;
|
||||
ParticleSystem*pLastSorted = NULL;
|
||||
|
||||
pSystem = m_pFirstSystem;
|
||||
while( pSystem )
|
||||
{
|
||||
if( pSystem->UpdateSystem(frametime))
|
||||
{
|
||||
pSystem->DrawSystem();
|
||||
pLast = pSystem;
|
||||
pSystem = pSystem->m_pNextSystem;
|
||||
}
|
||||
else // delete this system
|
||||
{
|
||||
if (pLast)
|
||||
{
|
||||
pLast->m_pNextSystem = pSystem->m_pNextSystem;
|
||||
delete pSystem;
|
||||
pSystem = pLast->m_pNextSystem;
|
||||
}
|
||||
else // deleting the first system
|
||||
{
|
||||
m_pFirstSystem = pSystem->m_pNextSystem;
|
||||
delete pSystem;
|
||||
pSystem = m_pFirstSystem;
|
||||
}
|
||||
}
|
||||
}
|
||||
gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
|
||||
}
|
||||
|
||||
void ParticleSystemManager::ClearSystems( void )
|
||||
{
|
||||
ParticleSystem* pSystem = m_pFirstSystem;
|
||||
ParticleSystem* pTemp;
|
||||
|
||||
while( pSystem )
|
||||
{
|
||||
pTemp = pSystem->m_pNextSystem;
|
||||
delete pSystem;
|
||||
pSystem = pTemp;
|
||||
}
|
||||
|
||||
m_pFirstSystem = NULL;
|
||||
}
|
||||
|
||||
float ParticleSystem::c_fCosTable[360 + 90];
|
||||
bool ParticleSystem::c_bCosTableInit = false;
|
||||
|
||||
ParticleType::ParticleType( ParticleType *pNext )
|
||||
{
|
||||
m_pSprayType = m_pOverlayType = NULL;
|
||||
m_StartAngle = RandomRange(45);
|
||||
m_hSprite = 0;
|
||||
m_pNext = pNext;
|
||||
m_szName[0] = 0;
|
||||
m_StartRed = m_StartGreen = m_StartBlue = m_StartAlpha = RandomRange(1);
|
||||
m_EndRed = m_EndGreen = m_EndBlue = m_EndAlpha = RandomRange(1);
|
||||
m_iRenderMode = kRenderTransAdd;
|
||||
m_iDrawCond = 0;
|
||||
m_bEndFrame = false;
|
||||
|
||||
m_bIsDefined = false;
|
||||
m_iCollision = 0;
|
||||
}
|
||||
|
||||
particle* ParticleType::CreateParticle(ParticleSystem *pSys)//particle *pPart)
|
||||
{
|
||||
if (!pSys) return NULL;
|
||||
|
||||
particle *pPart = pSys->ActivateParticle();
|
||||
if (!pPart) return NULL;
|
||||
|
||||
pPart->age = 0.0;
|
||||
pPart->age_death = m_Life.GetInstance();
|
||||
|
||||
InitParticle(pPart, pSys);
|
||||
|
||||
return pPart;
|
||||
}
|
||||
|
||||
void ParticleType::InitParticle(particle *pPart, ParticleSystem *pSys)
|
||||
{
|
||||
float fLifeRecip = 1/pPart->age_death;
|
||||
|
||||
particle *pOverlay = NULL;
|
||||
if (m_pOverlayType)
|
||||
{
|
||||
// create an overlay for this particle
|
||||
pOverlay = pSys->ActivateParticle();
|
||||
if (pOverlay)
|
||||
{
|
||||
pOverlay->age = pPart->age;
|
||||
pOverlay->age_death = pPart->age_death;
|
||||
m_pOverlayType->InitParticle(pOverlay, pSys);
|
||||
}
|
||||
}
|
||||
|
||||
pPart->m_pOverlay = pOverlay;
|
||||
|
||||
pPart->pType = this;
|
||||
pPart->velocity[0] = pPart->velocity[1] = pPart->velocity[2] = 0;
|
||||
pPart->accel[0] = pPart->accel[1] = 0;
|
||||
pPart->accel[2] = m_Gravity.GetInstance();
|
||||
pPart->m_iEntIndex = 0;
|
||||
|
||||
if (m_pSprayType)
|
||||
{
|
||||
pPart->age_spray = 1/m_SprayRate.GetInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
pPart->age_spray = 0.0f;
|
||||
}
|
||||
|
||||
pPart->m_fSize = m_StartSize.GetInstance();
|
||||
|
||||
if (m_EndSize.IsDefined())
|
||||
pPart->m_fSizeStep = m_EndSize.GetOffset(pPart->m_fSize) * fLifeRecip;
|
||||
else
|
||||
pPart->m_fSizeStep = m_SizeDelta.GetInstance();
|
||||
//pPart->m_fSizeStep = m_EndSize.GetOffset(pPart->m_fSize) * fLifeRecip;
|
||||
|
||||
pPart->frame = m_StartFrame.GetInstance();
|
||||
if (m_EndFrame.IsDefined())
|
||||
pPart->m_fFrameStep = m_EndFrame.GetOffset(pPart->frame) * fLifeRecip;
|
||||
else pPart->m_fFrameStep = m_FrameRate.GetInstance();
|
||||
|
||||
pPart->m_fAlpha = m_StartAlpha.GetInstance();
|
||||
pPart->m_fAlphaStep = m_EndAlpha.GetOffset(pPart->m_fAlpha) * fLifeRecip;
|
||||
pPart->m_fRed = m_StartRed.GetInstance();
|
||||
pPart->m_fRedStep = m_EndRed.GetOffset(pPart->m_fRed) * fLifeRecip;
|
||||
pPart->m_fGreen = m_StartGreen.GetInstance();
|
||||
pPart->m_fGreenStep = m_EndGreen.GetOffset(pPart->m_fGreen) * fLifeRecip;
|
||||
pPart->m_fBlue = m_StartBlue.GetInstance();
|
||||
pPart->m_fBlueStep = m_EndBlue.GetOffset(pPart->m_fBlue) * fLifeRecip;
|
||||
|
||||
pPart->m_fAngle = m_StartAngle.GetInstance();
|
||||
pPart->m_fAngleStep = m_AngleDelta.GetInstance();
|
||||
|
||||
pPart->m_fDrag = m_Drag.GetInstance();
|
||||
|
||||
float fWindStrength = m_WindStrength.GetInstance();
|
||||
float fWindYaw = m_WindYaw.GetInstance();
|
||||
pPart->m_vecWind.x = fWindStrength*ParticleSystem::CosLookup(fWindYaw);
|
||||
pPart->m_vecWind.y = fWindStrength*ParticleSystem::SinLookup(fWindYaw);
|
||||
pPart->m_vecWind.z = 0;
|
||||
}
|
||||
|
||||
//============================================
|
||||
|
||||
|
||||
RandomRange::RandomRange( char *szToken )
|
||||
{
|
||||
char *cOneDot = NULL;
|
||||
m_bDefined = true;
|
||||
|
||||
for (char *c = szToken; *c; c++)
|
||||
{
|
||||
if (*c == '.')
|
||||
{
|
||||
if (cOneDot != NULL)
|
||||
{
|
||||
// found two dots in a row - it's a range
|
||||
|
||||
*cOneDot = 0; // null terminate the first number
|
||||
m_fMin = atof(szToken); // parse the first number
|
||||
*cOneDot = '.'; // change it back, just in case
|
||||
c++;
|
||||
m_fMax = atof(c); // parse the second number
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cOneDot = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cOneDot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// no range, just record the number
|
||||
m_fMin = m_fMax = atof(szToken);
|
||||
}
|
||||
|
||||
//============================================
|
||||
|
||||
ParticleSystem::ParticleSystem( int iEntIndex, char *szFilename )
|
||||
{
|
||||
int iParticles = 100; // default
|
||||
|
||||
m_iEntIndex = iEntIndex;
|
||||
m_pNextSystem = NULL;
|
||||
m_pFirstType = NULL;
|
||||
if (!c_bCosTableInit)
|
||||
{
|
||||
for (int i = 0; i < 360+90; i++)
|
||||
{
|
||||
c_fCosTable[i] = cos(i*M_PI/180.0);
|
||||
}
|
||||
c_bCosTableInit = true;
|
||||
}
|
||||
|
||||
char *szFile = (char *)gEngfuncs.COM_LoadFile( szFilename, 5, NULL);
|
||||
char szToken[1024];
|
||||
|
||||
if (!szFile)
|
||||
{
|
||||
Msg("Particle %s not found.\n", szFilename );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile, szToken);
|
||||
|
||||
while (szFile)
|
||||
{
|
||||
if ( !stricmp( szToken, "particles" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
iParticles = atof(szToken);
|
||||
}
|
||||
else if ( !stricmp( szToken, "maintype" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
m_pMainType = AddPlaceholderType(szToken);
|
||||
}
|
||||
else if ( !stricmp( szToken, "attachment" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
m_iEntAttachment = atof(szToken);
|
||||
}
|
||||
else if ( !stricmp( szToken, "killcondition" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
if ( !stricmp( szToken, "empty" ) )
|
||||
{
|
||||
m_iKillCondition = CONTENTS_EMPTY;
|
||||
}
|
||||
else if ( !stricmp( szToken, "water" ) )
|
||||
{
|
||||
m_iKillCondition = CONTENTS_WATER;
|
||||
}
|
||||
else if ( !stricmp( szToken, "solid" ) )
|
||||
{
|
||||
m_iKillCondition = CONTENTS_SOLID;
|
||||
}
|
||||
}
|
||||
else if ( !stricmp( szToken, "{" ) )
|
||||
{
|
||||
// parse new type
|
||||
this->ParseType( szFile ); // parses the type, moves the file pointer
|
||||
}
|
||||
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile, szToken);
|
||||
}
|
||||
}
|
||||
|
||||
gEngfuncs.COM_FreeFile( szFile );
|
||||
AllocateParticles(iParticles);
|
||||
}
|
||||
|
||||
void ParticleSystem::AllocateParticles( int iParticles )
|
||||
{
|
||||
m_pAllParticles = new particle[iParticles];
|
||||
m_pFreeParticle = m_pAllParticles;
|
||||
m_pActiveParticle = NULL;
|
||||
m_pMainParticle = NULL;
|
||||
|
||||
// initialise the linked list
|
||||
particle *pLast = m_pAllParticles;
|
||||
particle *pParticle = pLast+1;
|
||||
|
||||
for( int i = 1; i < iParticles; i++ )
|
||||
{
|
||||
pLast->nextpart = pParticle;
|
||||
|
||||
pLast = pParticle;
|
||||
pParticle++;
|
||||
}
|
||||
pLast->nextpart = NULL;
|
||||
}
|
||||
|
||||
ParticleSystem::~ParticleSystem( void )
|
||||
{
|
||||
delete[] m_pAllParticles;
|
||||
|
||||
ParticleType *pType = m_pFirstType;
|
||||
ParticleType *pNext;
|
||||
while (pType)
|
||||
{
|
||||
pNext = pType->m_pNext;
|
||||
delete pType;
|
||||
pType = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns the ParticleType with the given name, if there is one
|
||||
ParticleType *ParticleSystem::GetType( const char *szName )
|
||||
{
|
||||
for (ParticleType *pType = m_pFirstType; pType; pType = pType->m_pNext)
|
||||
{
|
||||
if (!stricmp(pType->m_szName, szName))
|
||||
return pType;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ParticleType *ParticleSystem::AddPlaceholderType( const char *szName )
|
||||
{
|
||||
m_pFirstType = new ParticleType( m_pFirstType );
|
||||
strncpy(m_pFirstType->m_szName, szName, sizeof(m_pFirstType->m_szName) );
|
||||
return m_pFirstType;
|
||||
}
|
||||
|
||||
// creates a new particletype from the given file
|
||||
// NB: this changes the value of szFile.
|
||||
ParticleType *ParticleSystem::ParseType( char *&szFile )
|
||||
{
|
||||
ParticleType *pType = new ParticleType();
|
||||
|
||||
// parse the .aur file
|
||||
char szToken[1024];
|
||||
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile, szToken);
|
||||
while ( stricmp( szToken, "}" ) )
|
||||
{
|
||||
if (!szFile)
|
||||
break;
|
||||
|
||||
if ( !stricmp( szToken, "name" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
strncpy(pType->m_szName, szToken, sizeof(pType->m_szName) );
|
||||
|
||||
ParticleType *pTemp = GetType(szToken);
|
||||
if (pTemp)
|
||||
{
|
||||
// there's already a type with this name
|
||||
if (pTemp->m_bIsDefined)
|
||||
Msg("Warning: Particle type %s is defined more than once!\n", szToken);
|
||||
|
||||
// copy all our data into the existing type, throw away the type we were making
|
||||
*pTemp = *pType;
|
||||
delete pType;
|
||||
pType = pTemp;
|
||||
pType->m_bIsDefined = true; // record the fact that it's defined, so we won't need to add it to the list
|
||||
}
|
||||
}
|
||||
else if ( !stricmp( szToken, "gravity" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_Gravity = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "windyaw" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_WindYaw = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "windstrength" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_WindStrength = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "sprite" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_hSprite = SPR_Load( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startalpha" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartAlpha = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endalpha" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndAlpha = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startred" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartRed = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endred" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndRed = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startgreen" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartGreen = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endgreen" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndGreen = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startblue" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartBlue = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endblue" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndBlue = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startsize" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartSize = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "sizedelta" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_SizeDelta = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endsize" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndSize = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startangle" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartAngle = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "angledelta" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_AngleDelta = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "startframe" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_StartFrame = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "endframe" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_EndFrame = RandomRange( szToken );
|
||||
pType->m_bEndFrame = true;
|
||||
}
|
||||
else if ( !stricmp( szToken, "framerate" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_FrameRate = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "lifetime" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_Life = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "spraytype" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
ParticleType *pTemp = GetType(szToken);
|
||||
|
||||
if (pTemp) pType->m_pSprayType = pTemp;
|
||||
else pType->m_pSprayType = AddPlaceholderType(szToken);
|
||||
}
|
||||
else if ( !stricmp( szToken, "overlaytype" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
ParticleType *pTemp = GetType(szToken);
|
||||
|
||||
if (pTemp) pType->m_pOverlayType = pTemp;
|
||||
else pType->m_pOverlayType = AddPlaceholderType(szToken);
|
||||
}
|
||||
else if ( !stricmp( szToken, "sprayrate" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_SprayRate = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "sprayforce" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_SprayForce = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "spraypitch" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_SprayPitch = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "sprayyaw" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_SprayYaw = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "drag" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_Drag = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "bounce" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_Bounce = RandomRange( szToken );
|
||||
if (pType->m_Bounce.m_fMin != 0 || pType->m_Bounce.m_fMax != 0)
|
||||
pType->m_bBouncing = true;
|
||||
}
|
||||
else if ( !stricmp( szToken, "bouncefriction" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
pType->m_BounceFriction = RandomRange( szToken );
|
||||
}
|
||||
else if ( !stricmp( szToken, "rendermode" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
if ( !stricmp( szToken, "additive" ) )
|
||||
{
|
||||
pType->m_iRenderMode = kRenderTransAdd;
|
||||
}
|
||||
else if ( !stricmp( szToken, "solid" ) )
|
||||
{
|
||||
pType->m_iRenderMode = kRenderTransAlpha;
|
||||
}
|
||||
else if ( !stricmp( szToken, "texture" ) )
|
||||
{
|
||||
pType->m_iRenderMode = kRenderTransTexture;
|
||||
}
|
||||
else if ( !stricmp( szToken, "color" ) )
|
||||
{
|
||||
pType->m_iRenderMode = kRenderTransColor;
|
||||
}
|
||||
}
|
||||
else if ( !stricmp( szToken, "drawcondition" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
if ( !stricmp( szToken, "empty" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENTS_EMPTY;
|
||||
}
|
||||
else if ( !stricmp( szToken, "water" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENTS_WATER;
|
||||
}
|
||||
else if ( !stricmp( szToken, "solid" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENTS_SOLID;
|
||||
}
|
||||
else if ( !stricmp( szToken, "special" ) || !stricmp( szToken, "special1" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENT_SPECIAL1;
|
||||
}
|
||||
else if ( !stricmp( szToken, "special2" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENT_SPECIAL2;
|
||||
}
|
||||
else if ( !stricmp( szToken, "special3" ) )
|
||||
{
|
||||
pType->m_iDrawCond = CONTENT_SPECIAL3;
|
||||
}
|
||||
}
|
||||
else if ( !stricmp( szToken, "collision" ) )
|
||||
{
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile,szToken);
|
||||
if ( !stricmp( szToken, "none" ) )
|
||||
{
|
||||
pType->m_iCollision = COLLISION_NONE;
|
||||
}
|
||||
else if ( !stricmp( szToken, "die" ) )
|
||||
{
|
||||
pType->m_iCollision = COLLISION_DIE;
|
||||
}
|
||||
else if ( !stricmp( szToken, "bounce" ) )
|
||||
{
|
||||
pType->m_iCollision = COLLISION_BOUNCE;
|
||||
}
|
||||
}
|
||||
// get the next token
|
||||
szFile = gEngfuncs.COM_ParseFile(szFile, szToken);
|
||||
}
|
||||
|
||||
if (!pType->m_bIsDefined)
|
||||
{
|
||||
// if this is a newly-defined type, we need to add it to the list
|
||||
pType->m_pNext = m_pFirstType;
|
||||
m_pFirstType = pType;
|
||||
pType->m_bIsDefined = true;
|
||||
}
|
||||
|
||||
return pType;
|
||||
}
|
||||
|
||||
particle *ParticleSystem::ActivateParticle()
|
||||
{
|
||||
particle* pActivated = m_pFreeParticle;
|
||||
if (pActivated)
|
||||
{
|
||||
m_pFreeParticle = pActivated->nextpart;
|
||||
pActivated->nextpart = m_pActiveParticle;
|
||||
m_pActiveParticle = pActivated;
|
||||
}
|
||||
return pActivated;
|
||||
}
|
||||
|
||||
extern vec3_t v_origin;
|
||||
|
||||
void ParticleSystem::CalculateDistance()
|
||||
{
|
||||
if (!m_pActiveParticle)
|
||||
return;
|
||||
|
||||
vec3_t offset = v_origin - m_pActiveParticle->origin; // just pick one
|
||||
m_fViewerDist = offset[0]*offset[0] + offset[1]*offset[1] + offset[2]*offset[2];
|
||||
}
|
||||
|
||||
|
||||
bool ParticleSystem::UpdateSystem( float frametime )
|
||||
{
|
||||
// the entity emitting this system
|
||||
cl_entity_t *source = UTIL_GetClientEntityWithServerIndex( m_iEntIndex );
|
||||
if(!source) return false;
|
||||
|
||||
// Don't update if the system is outside the player's PVS.
|
||||
if (source->curstate.msg_time < gEngfuncs.GetClientTime())
|
||||
{ //remove particles
|
||||
enable = 0;
|
||||
}
|
||||
else enable = (source->curstate.renderfx == kRenderFxAurora);
|
||||
//check for contents to remove
|
||||
if(m_iKillCondition == gEngfuncs.PM_PointContents(source->curstate.origin, NULL))
|
||||
{
|
||||
enable = 0;
|
||||
}
|
||||
if (m_pMainParticle == NULL)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
ParticleType *pType = m_pMainType;
|
||||
if (pType)
|
||||
{
|
||||
m_pMainParticle = pType->CreateParticle(this);//m_pMainParticle);
|
||||
if (m_pMainParticle)
|
||||
{
|
||||
m_pMainParticle->m_iEntIndex = m_iEntIndex;
|
||||
m_pMainParticle->age_death = -1; // never die
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!enable)
|
||||
{
|
||||
m_pMainParticle->age_death = 0; // die now
|
||||
m_pMainParticle = NULL;
|
||||
}
|
||||
|
||||
particle* pParticle = m_pActiveParticle;
|
||||
particle* pLast = NULL;
|
||||
|
||||
while( pParticle )
|
||||
{
|
||||
if( UpdateParticle( pParticle, frametime ) )
|
||||
{
|
||||
pLast = pParticle;
|
||||
pParticle = pParticle->nextpart;
|
||||
}
|
||||
else // deactivate it
|
||||
{
|
||||
if (pLast)
|
||||
{
|
||||
pLast->nextpart = pParticle->nextpart;
|
||||
pParticle->nextpart = m_pFreeParticle;
|
||||
m_pFreeParticle = pParticle;
|
||||
pParticle = pLast->nextpart;
|
||||
}
|
||||
else // deactivate the first particle in the list
|
||||
{
|
||||
m_pActiveParticle = pParticle->nextpart;
|
||||
pParticle->nextpart = m_pFreeParticle;
|
||||
m_pFreeParticle = pParticle;
|
||||
pParticle = m_pActiveParticle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void ParticleSystem::DrawSystem()
|
||||
{
|
||||
vec3_t normal, forward, right, up;
|
||||
|
||||
if(g_HardwareCapable)//merge particle pos for openGL
|
||||
{
|
||||
double r_world_matrix[16];
|
||||
glGetDoublev (GL_MODELVIEW_MATRIX, r_world_matrix);
|
||||
|
||||
right.x = r_world_matrix[0];
|
||||
right.y = r_world_matrix[4];
|
||||
right.z = r_world_matrix[8];
|
||||
|
||||
up.x = r_world_matrix[1];
|
||||
up.y = r_world_matrix[5];
|
||||
up.z = r_world_matrix[9];
|
||||
}
|
||||
else //otherwise
|
||||
{
|
||||
gEngfuncs.GetViewAngles((float*)normal);
|
||||
AngleVectors(normal, forward, right, up);
|
||||
}
|
||||
particle* pParticle = m_pActiveParticle;
|
||||
for( pParticle = m_pActiveParticle; pParticle; pParticle = pParticle->nextpart )
|
||||
{
|
||||
DrawParticle( pParticle, right, up );
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticleSystem::ParticleIsVisible( particle* part )
|
||||
{
|
||||
float dv[3];
|
||||
bool visible = true;
|
||||
VectorSubtract(part->origin, v_origin, dv);
|
||||
float d = Length(dv);
|
||||
|
||||
if (fabs(d) > 36.0f)
|
||||
{
|
||||
visible = (R_SphereInFrustum(part->origin, 100 ) > 0);
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
bool ParticleSystem::UpdateParticle(particle *part, float frametime)
|
||||
{
|
||||
if (frametime == 0 ) return true;
|
||||
part->age += frametime;
|
||||
|
||||
cl_entity_t *source = UTIL_GetClientEntityWithServerIndex( m_iEntIndex );
|
||||
|
||||
// is this particle bound to an entity?
|
||||
if (part->m_iEntIndex)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if(m_iEntAttachment)
|
||||
{
|
||||
part->velocity = (source->attachment[m_iEntAttachment - 1] - part->origin)/frametime;
|
||||
part->origin = source->attachment[m_iEntAttachment - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
part->velocity = (source->curstate.origin - part->origin)/frametime;
|
||||
part->origin = source->curstate.origin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// entity is switched off, die
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not tied to an entity, check whether it's time to die
|
||||
if (part->age_death >= 0 && part->age > part->age_death)
|
||||
return false;
|
||||
|
||||
// apply acceleration and velocity
|
||||
vec3_t vecOldPos = part->origin;
|
||||
if (part->m_fDrag)
|
||||
VectorMA(part->velocity, -part->m_fDrag*frametime, part->velocity - part->m_vecWind, part->velocity);
|
||||
VectorMA(part->velocity, frametime, part->accel, part->velocity);
|
||||
VectorMA(part->origin, frametime, part->velocity, part->origin);
|
||||
|
||||
if (part->pType->m_bBouncing)
|
||||
{
|
||||
vec3_t vecTarget;
|
||||
VectorMA(part->origin, frametime, part->velocity, vecTarget);
|
||||
pmtrace_t *tr = gEngfuncs.PM_TraceLine( part->origin, vecTarget, PM_TRACELINE_PHYSENTSONLY, 2, -1 );
|
||||
if (tr->fraction < 1)
|
||||
{
|
||||
part->origin = tr->endpos;
|
||||
float bounceforce = DotProduct(tr->plane.normal, part->velocity);
|
||||
float newspeed = (1 - part->pType->m_BounceFriction.GetInstance());
|
||||
part->velocity = part->velocity * newspeed;
|
||||
VectorMA(part->velocity, -bounceforce*(newspeed+part->pType->m_Bounce.GetInstance()), tr->plane.normal, part->velocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// spray children
|
||||
if (part->age_spray && part->age > part->age_spray)
|
||||
{
|
||||
part->age_spray = part->age + 1/part->pType->m_SprayRate.GetInstance();
|
||||
|
||||
//particle *pChild = ActivateParticle();
|
||||
if (part->pType->m_pSprayType)
|
||||
{
|
||||
particle *pChild = part->pType->m_pSprayType->CreateParticle(this);
|
||||
if (pChild)
|
||||
{
|
||||
pChild->origin = part->origin;
|
||||
float fSprayForce = part->pType->m_SprayForce.GetInstance();
|
||||
pChild->velocity = part->velocity;
|
||||
if (fSprayForce)
|
||||
{
|
||||
float fSprayPitch = part->pType->m_SprayPitch.GetInstance() - source->curstate.angles.x;
|
||||
float fSprayYaw = part->pType->m_SprayYaw.GetInstance() - source->curstate.angles.y;
|
||||
float fSprayRoll = source->curstate.angles.z;
|
||||
float fForceCosPitch = fSprayForce*CosLookup(fSprayPitch);
|
||||
pChild->velocity.x += CosLookup(fSprayYaw) * fForceCosPitch;
|
||||
pChild->velocity.y += SinLookup(fSprayYaw) * fForceCosPitch + SinLookup(fSprayYaw) * fSprayForce * SinLookup(fSprayRoll);
|
||||
pChild->velocity.z -= SinLookup(fSprayPitch) * fSprayForce * CosLookup(fSprayRoll);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
part->m_fSize += part->m_fSizeStep * frametime;
|
||||
part->m_fAlpha += part->m_fAlphaStep * frametime;
|
||||
part->m_fRed += part->m_fRedStep * frametime;
|
||||
part->m_fGreen += part->m_fGreenStep * frametime;
|
||||
part->m_fBlue += part->m_fBlueStep * frametime;
|
||||
part->frame += part->m_fFrameStep * frametime;
|
||||
if (part->m_fAngleStep)
|
||||
{
|
||||
part->m_fAngle += part->m_fAngleStep * frametime;
|
||||
while (part->m_fAngle < 0) part->m_fAngle += 360;
|
||||
while (part->m_fAngle > 360) part->m_fAngle -= 360;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParticleSystem::DrawParticle(particle *part, vec3_t &right, vec3_t &up)
|
||||
{
|
||||
float fSize = part->m_fSize;
|
||||
vec3_t point1,point2,point3,point4;
|
||||
vec3_t origin = part->origin;
|
||||
|
||||
// nothing to draw?
|
||||
if (fSize == 0) return;
|
||||
|
||||
//frustrum visible check
|
||||
if(!ParticleIsVisible(part)) return;
|
||||
|
||||
float fCosSize = CosLookup(part->m_fAngle)*fSize;
|
||||
float fSinSize = SinLookup(part->m_fAngle)*fSize;
|
||||
|
||||
// calculate the four corners of the sprite
|
||||
VectorMA (origin, fSinSize, up, point1);
|
||||
VectorMA (point1, -fCosSize, right, point1);
|
||||
|
||||
VectorMA (origin, fCosSize, up, point2);
|
||||
VectorMA (point2, fSinSize, right, point2);
|
||||
|
||||
VectorMA (origin, -fSinSize, up, point3);
|
||||
VectorMA (point3, fCosSize, right, point3);
|
||||
|
||||
VectorMA (origin, -fCosSize, up, point4);
|
||||
VectorMA (point4, -fSinSize, right, point4);
|
||||
|
||||
struct model_s * pModel;
|
||||
int iContents = 0;
|
||||
|
||||
for (particle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay)
|
||||
{
|
||||
if (pDraw->pType->m_hSprite == 0)
|
||||
continue;
|
||||
|
||||
if (pDraw->pType->m_iDrawCond)
|
||||
{
|
||||
if (iContents == 0)
|
||||
iContents = gEngfuncs.PM_PointContents(origin, NULL);
|
||||
|
||||
if (iContents != pDraw->pType->m_iDrawCond)
|
||||
continue;
|
||||
}
|
||||
|
||||
pModel = (struct model_s *)gEngfuncs.GetSpritePointer( pDraw->pType->m_hSprite );
|
||||
|
||||
//Msg("UpdParticle %d: age %f, life %f, R:%f G:%f, B, %f \n", pDraw->pType->m_hSprite, part->age, part->age_death, pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue);
|
||||
|
||||
// if we've reached the end of the sprite's frames, loop back
|
||||
while (pDraw->frame > pModel->numframes) pDraw->frame -= pModel->numframes;
|
||||
|
||||
while (pDraw->frame < 0) pDraw->frame += pModel->numframes;
|
||||
|
||||
if ( !gEngfuncs.pTriAPI->SpriteTexture( pModel, int(pDraw->frame) ))continue;
|
||||
|
||||
gEngfuncs.pTriAPI->RenderMode(pDraw->pType->m_iRenderMode);
|
||||
gEngfuncs.pTriAPI->Color4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
|
||||
gEngfuncs.pTriAPI->TexCoord2f (0, 0);
|
||||
gEngfuncs.pTriAPI->Vertex3fv(point1);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f (1, 0);
|
||||
gEngfuncs.pTriAPI->Vertex3fv (point2);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f (1, 1);
|
||||
gEngfuncs.pTriAPI->Vertex3fv (point3);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f (0, 1);
|
||||
gEngfuncs.pTriAPI->Vertex3fv (point4);
|
||||
gEngfuncs.pTriAPI->End();
|
||||
}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
// 02/08/02 November235: Particle System
|
||||
#pragma once
|
||||
#include "r_main.h"
|
||||
|
||||
class ParticleType;
|
||||
class ParticleSystem;
|
||||
void CreateAurora( int idx, char *file ); //make new partsystem
|
||||
|
||||
#define COLLISION_NONE 0
|
||||
#define COLLISION_DIE 1
|
||||
#define COLLISION_BOUNCE 2
|
||||
|
||||
struct particle
|
||||
{
|
||||
particle* nextpart;
|
||||
|
||||
particle* m_pOverlay; // for making multi-layered particles
|
||||
|
||||
ParticleType *pType;
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
vec3_t accel;
|
||||
vec3_t m_vecWind;
|
||||
|
||||
int m_iEntIndex; // if non-zero, this particle is tied to the given entity
|
||||
|
||||
float m_fRed;
|
||||
float m_fGreen;
|
||||
float m_fBlue;
|
||||
float m_fRedStep;
|
||||
float m_fGreenStep;
|
||||
float m_fBlueStep;
|
||||
|
||||
float m_fAlpha;
|
||||
float m_fAlphaStep;
|
||||
|
||||
float frame;
|
||||
float m_fFrameStep;
|
||||
|
||||
float m_fAngle;
|
||||
float m_fAngleStep;
|
||||
|
||||
float m_fSize;
|
||||
float m_fSizeStep;
|
||||
|
||||
float m_fDrag;
|
||||
|
||||
float age;
|
||||
float age_death;
|
||||
float age_spray;
|
||||
};
|
||||
|
||||
|
||||
class RandomRange
|
||||
{
|
||||
public:
|
||||
RandomRange() { m_fMin = m_fMax = 0; m_bDefined = false; }
|
||||
RandomRange(float fValue) { m_fMin = m_fMax = fValue; m_bDefined = true; }
|
||||
RandomRange(float fMin, float fMax) { m_fMin = fMin; m_fMax = fMax; m_bDefined = true; }
|
||||
RandomRange( char *szToken );
|
||||
|
||||
float m_fMax;
|
||||
float m_fMin;
|
||||
bool m_bDefined;
|
||||
|
||||
float GetInstance()
|
||||
{ return gEngfuncs.pfnRandomFloat(m_fMin, m_fMax); }
|
||||
|
||||
float GetOffset(float fBasis)
|
||||
{ return GetInstance()-fBasis; }
|
||||
|
||||
bool IsDefined()
|
||||
{ return m_bDefined; } //(m_fMin == 0 && m_fMax == 0); }
|
||||
};
|
||||
|
||||
#define MAX_TYPENAME 30
|
||||
|
||||
class ParticleType
|
||||
{
|
||||
public:
|
||||
ParticleType( ParticleType *pNext = NULL );
|
||||
ParticleType(char *szFilename);
|
||||
|
||||
bool m_bIsDefined; // is this ParticleType just a placeholder?
|
||||
int m_iRenderMode;
|
||||
int m_iDrawCond;
|
||||
int m_iCollision;
|
||||
RandomRange m_Bounce;
|
||||
RandomRange m_BounceFriction;
|
||||
bool m_bBouncing;
|
||||
|
||||
RandomRange m_Life;
|
||||
|
||||
RandomRange m_StartAlpha;
|
||||
RandomRange m_EndAlpha;
|
||||
RandomRange m_StartRed;
|
||||
RandomRange m_EndRed;
|
||||
RandomRange m_StartGreen;
|
||||
RandomRange m_EndGreen;
|
||||
RandomRange m_StartBlue;
|
||||
RandomRange m_EndBlue;
|
||||
|
||||
RandomRange m_StartSize;
|
||||
RandomRange m_SizeDelta;
|
||||
RandomRange m_EndSize;
|
||||
|
||||
RandomRange m_StartFrame;
|
||||
RandomRange m_EndFrame;
|
||||
RandomRange m_FrameRate; // incompatible with EndFrame
|
||||
bool m_bEndFrame;
|
||||
|
||||
RandomRange m_StartAngle;
|
||||
RandomRange m_AngleDelta;
|
||||
|
||||
RandomRange m_SprayRate;
|
||||
RandomRange m_SprayForce;
|
||||
RandomRange m_SprayPitch;
|
||||
RandomRange m_SprayYaw;
|
||||
RandomRange m_SprayRoll;
|
||||
ParticleType *m_pSprayType;
|
||||
|
||||
RandomRange m_Gravity;
|
||||
RandomRange m_WindStrength;
|
||||
RandomRange m_WindYaw;
|
||||
|
||||
HSPRITE m_hSprite;
|
||||
ParticleType *m_pOverlayType;
|
||||
|
||||
RandomRange m_Drag;
|
||||
|
||||
ParticleType *m_pNext;
|
||||
|
||||
char m_szName[MAX_TYPENAME];
|
||||
|
||||
// here is a particle system. Add a (set of) particles according to this type, and initialise their values.
|
||||
particle* CreateParticle(ParticleSystem *pSys);//particle *pPart);
|
||||
|
||||
// initialise this particle. Does not define velocity or age.
|
||||
void InitParticle(particle *pPart, ParticleSystem *pSys);
|
||||
};
|
||||
|
||||
class ParticleSystem
|
||||
{
|
||||
public:
|
||||
ParticleSystem( int entindex, char *szFilename );
|
||||
~ParticleSystem( void );
|
||||
void AllocateParticles( int iParticles );
|
||||
void CalculateDistance();
|
||||
|
||||
ParticleType *GetType( const char *szName );
|
||||
ParticleType *AddPlaceholderType( const char *szName );
|
||||
ParticleType *ParseType( char *&szFile );
|
||||
|
||||
cl_entity_t *GetEntity() { return UTIL_GetClientEntityWithServerIndex(m_iEntIndex); }
|
||||
|
||||
static float c_fCosTable[360 + 90];
|
||||
static bool c_bCosTableInit;
|
||||
|
||||
// General functions
|
||||
bool UpdateSystem( float frametime ); //If this function returns false, the manager deletes the system
|
||||
void DrawSystem();
|
||||
particle *ActivateParticle(); // adds one of the free particles to the active list, and returns it for initialisation.
|
||||
|
||||
static float CosLookup(int angle) { return angle < 0? c_fCosTable[angle+360]: c_fCosTable[angle]; }
|
||||
static float SinLookup(int angle) { return angle < -90? c_fCosTable[angle+450]: c_fCosTable[angle+90]; }
|
||||
|
||||
// returns false if the particle has died
|
||||
bool UpdateParticle( particle *part, float frametime );
|
||||
void DrawParticle( particle* part, vec3_t &right, vec3_t &up );
|
||||
|
||||
// Utility functions that have to be public
|
||||
bool ParticleIsVisible( particle* part );
|
||||
|
||||
// Pointer to next system for linked list structure
|
||||
ParticleSystem* m_pNextSystem;
|
||||
|
||||
particle* m_pActiveParticle;
|
||||
float m_fViewerDist;
|
||||
int m_iEntIndex;
|
||||
int m_iEntAttachment;
|
||||
int m_iKillCondition;
|
||||
int enable;
|
||||
private:
|
||||
// the block of allocated particles
|
||||
particle* m_pAllParticles;
|
||||
// First particles in the linked list for the active particles and the dead particles
|
||||
particle* m_pFreeParticle;
|
||||
particle* m_pMainParticle; // the "source" particle.
|
||||
|
||||
ParticleType *m_pFirstType;
|
||||
|
||||
ParticleType *m_pMainType;
|
||||
};
|
||||
|
||||
class ParticleSystemManager
|
||||
{
|
||||
public:
|
||||
ParticleSystemManager( void );
|
||||
~ParticleSystemManager( void );
|
||||
ParticleSystem *FindSystem( cl_entity_t* pEntity );
|
||||
void AddSystem( ParticleSystem* );
|
||||
void UpdateSystems( void );
|
||||
void ClearSystems( void );
|
||||
ParticleSystem* m_pFirstSystem;
|
||||
};
|
||||
|
||||
extern ParticleSystemManager* g_pParticleSystems;
|
|
@ -1,818 +0,0 @@
|
|||
/***
|
||||
*
|
||||
* Copyright (c) 2001-2006, Chain Studios. All rights reserved.
|
||||
*
|
||||
* This product contains software technology that is a part of Half-Life FX (R)
|
||||
* from Chain Studios ("HLFX Technology"). All rights reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Chain Studios.
|
||||
*
|
||||
****/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "hud.h"
|
||||
#include "r_main.h"
|
||||
#include "r_util.h"
|
||||
#include <string.h>
|
||||
|
||||
vec3_t vec3_origin( 0, 0, 0 );
|
||||
|
||||
double sqrt(double x);
|
||||
|
||||
HSPRITE m_hHudFont;
|
||||
|
||||
int *GetRect( void )
|
||||
{
|
||||
RECT wrect;
|
||||
static int extent[4];
|
||||
|
||||
if(GetWindowRect( GetActiveWindow(), &wrect ))
|
||||
{
|
||||
if(!wrect.left)
|
||||
{
|
||||
extent[0] = wrect.left; //+4
|
||||
extent[1] = wrect.top; //+30
|
||||
extent[2] = wrect.right; //-4
|
||||
extent[3] = wrect.bottom; //-4
|
||||
}
|
||||
else
|
||||
{
|
||||
extent[0] = wrect.left + 4; //+4
|
||||
extent[1] = wrect.top + 30; //+30
|
||||
extent[2] = wrect.right - 4; //-4
|
||||
extent[3] = wrect.bottom - 4; //-4
|
||||
}
|
||||
}
|
||||
return extent;
|
||||
}
|
||||
|
||||
void ScaleColors( int &r, int &g, int &b, int a )
|
||||
{
|
||||
float x = (float)a / 255;
|
||||
r = (int)(r * x);
|
||||
g = (int)(g * x);
|
||||
b = (int)(b * x);
|
||||
}
|
||||
|
||||
unsigned int nextpow2(unsigned int x)
|
||||
{
|
||||
unsigned int y = 1;
|
||||
while (x > y) y = y << 1;
|
||||
return y;
|
||||
}
|
||||
|
||||
float Length(const float *v)
|
||||
{
|
||||
int i;
|
||||
float length;
|
||||
|
||||
length = 0;
|
||||
for (i=0 ; i< 3 ; i++)
|
||||
length += v[i]*v[i];
|
||||
length = sqrt (length); // FIXME
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
float Distance(const vec3_t v1, const vec3_t v2)
|
||||
{
|
||||
vec3_t d;
|
||||
VectorSubtract(v2,v1,d);
|
||||
return Length(d);
|
||||
}
|
||||
|
||||
void VectorAngles( const float *forward, float *angles )
|
||||
{
|
||||
float tmp, yaw, pitch;
|
||||
|
||||
if (forward[1] == 0 && forward[0] == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
if (forward[2] > 0)
|
||||
pitch = 90;
|
||||
else
|
||||
pitch = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = (atan2(forward[1], forward[0]) * 180 / M_PI);
|
||||
if (yaw < 0)
|
||||
yaw += 360;
|
||||
|
||||
tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]);
|
||||
pitch = (atan2(forward[2], tmp) * 180 / M_PI);
|
||||
if (pitch < 0)
|
||||
pitch += 360;
|
||||
}
|
||||
|
||||
angles[0] = pitch;
|
||||
angles[1] = yaw;
|
||||
angles[2] = 0;
|
||||
}
|
||||
|
||||
float VectorNormalize (float *v)
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
length = sqrt (length); // FIXME
|
||||
|
||||
if (length)
|
||||
{
|
||||
ilength = 1/length;
|
||||
v[0] *= ilength;
|
||||
v[1] *= ilength;
|
||||
v[2] *= ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
void VectorInverse ( float *v )
|
||||
{
|
||||
v[0] = -v[0];
|
||||
v[1] = -v[1];
|
||||
v[2] = -v[2];
|
||||
}
|
||||
|
||||
void VectorScale (const float *in, float scale, float *out)
|
||||
{
|
||||
out[0] = in[0]*scale;
|
||||
out[1] = in[1]*scale;
|
||||
out[2] = in[2]*scale;
|
||||
}
|
||||
|
||||
void VectorMA (const float *veca, float scale, const float *vecb, float *vecc)
|
||||
{
|
||||
vecc[0] = veca[0] + scale*vecb[0];
|
||||
vecc[1] = veca[1] + scale*vecb[1];
|
||||
vecc[2] = veca[2] + scale*vecb[2];
|
||||
}
|
||||
|
||||
HSPRITE LoadSprite(const char *pszName)
|
||||
{
|
||||
int i;
|
||||
char sz[256];
|
||||
|
||||
if (ScreenWidth < 640)
|
||||
i = 320;
|
||||
else
|
||||
i = 640;
|
||||
|
||||
sprintf(sz, pszName, i);
|
||||
|
||||
return SPR_Load(sz);
|
||||
}
|
||||
|
||||
float TransformColor ( float color )
|
||||
{
|
||||
float trns_clr;
|
||||
if(color >= 0 ) trns_clr = color / 255.0f;
|
||||
else trns_clr = 1.0;//default value
|
||||
return trns_clr;
|
||||
}
|
||||
|
||||
#define NOISE_SIZE 64
|
||||
|
||||
inline float fade ( float t )
|
||||
{
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
inline float lerp ( float t, float a, float b )
|
||||
{
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
inline float grad ( int hash, float x, float y, float z )
|
||||
{
|
||||
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
|
||||
float u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
|
||||
v = h<4 ? y : h==12 || h==14 ? x : z;
|
||||
|
||||
return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
int permutation [256] =
|
||||
{
|
||||
151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||
};
|
||||
|
||||
int p[512];
|
||||
|
||||
void InitImprovedNoise()
|
||||
{
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
p [ 256 + i ] = p [ i ] = permutation [i];
|
||||
}
|
||||
|
||||
float noise( float vx, float vy, float vz )
|
||||
{
|
||||
|
||||
float fx = floor ( vx ); // get floor values of coords
|
||||
float fy = floor ( vy );
|
||||
float fz = floor ( vz );
|
||||
|
||||
int X = ((int) fx) & 255, // FIND UNIT CUBE THAT
|
||||
Y = ((int) fy) & 255, // CONTAINS POINT.
|
||||
Z = ((int) fz) & 255;
|
||||
|
||||
float x = vx - fx; // FIND RELATIVE X,Y,Z
|
||||
float y = vy - fy; // OF POINT IN CUBE.
|
||||
float z = vz - fz;
|
||||
|
||||
float u = fade ( x ), // COMPUTE FADE CURVES
|
||||
v = fade ( y ), // FOR EACH OF X,Y,Z.
|
||||
w = fade ( z );
|
||||
|
||||
int a = p [X ]+Y, aa = p [a]+Z, ab = p [a+1]+Z, // HASH COORDINATES OF
|
||||
b = p [X+1]+Y, ba = p [b]+Z, bb = p [b+1]+Z; // THE 8 CUBE CORNERS,
|
||||
|
||||
return lerp(w, lerp(v, lerp(u, grad(p[aa ], x , y , z ), // AND ADD
|
||||
grad(p[ba ], x-1, y , z )), // BLENDED
|
||||
lerp(u, grad(p[ab ], x , y-1, z ), // RESULTS
|
||||
grad(p[bb ], x-1, y-1, z ))),// FROM 8
|
||||
lerp(v, lerp(u, grad(p[aa+1], x , y , z-1 ), // CORNERS
|
||||
grad(p[ba+1], x-1, y , z-1 )), // OF CUBE
|
||||
lerp(u, grad(p[ab+1], x , y-1, z-1 ),
|
||||
grad(p[bb+1], x-1, y-1, z-1 ))));
|
||||
}
|
||||
|
||||
|
||||
void CreateNoiseTexture3D (float scale)
|
||||
{
|
||||
int i;
|
||||
|
||||
GLfloat *img = new GLfloat[NOISE_SIZE * NOISE_SIZE * NOISE_SIZE * 3];
|
||||
GLfloat *p = img;
|
||||
|
||||
InitImprovedNoise();
|
||||
|
||||
for (i=0; i < NOISE_SIZE*NOISE_SIZE*NOISE_SIZE*3 ; i++)
|
||||
{
|
||||
float x = i + sin(i);
|
||||
float y = i + cos(i);
|
||||
*p++ = noise(x, y, i);
|
||||
}
|
||||
|
||||
g_uiNoiseTex = pTexId++;
|
||||
glBindTexture(GL_TEXTURE_3D, g_uiNoiseTex);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage3DEXT(GL_TEXTURE_3D, 0, 3, NOISE_SIZE, NOISE_SIZE, NOISE_SIZE, 0,
|
||||
GL_RGB, GL_FLOAT, img);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
|
||||
|
||||
delete [] img;
|
||||
}
|
||||
|
||||
//
|
||||
// R_SphereInFrustum
|
||||
//
|
||||
// Purpose: sphere visibility test
|
||||
//
|
||||
extern float frustumPlanes[6][4];
|
||||
|
||||
float R_SphereInFrustum( vec3_t o, float radius )
|
||||
{
|
||||
int p;
|
||||
float d;
|
||||
|
||||
for( p = 0; p < 6; p++ )
|
||||
{
|
||||
d = frustumPlanes[p][0] * o[0] + frustumPlanes[p][1] * o[1] + frustumPlanes[p][2] * o[2] + frustumPlanes[p][3];
|
||||
if( d <= -radius )
|
||||
return 0;
|
||||
}
|
||||
return d + radius;
|
||||
}
|
||||
|
||||
//
|
||||
// UTIL_GetClientEntityWithServerIndex
|
||||
//
|
||||
// Purpose: searches for the server entity on client
|
||||
// Assumes: colormap has server entity index
|
||||
//
|
||||
cl_entity_t *UTIL_GetClientEntityWithServerIndex( int sv_index )
|
||||
{
|
||||
cl_entity_t *e;
|
||||
|
||||
for (int ic=1;ic<MAX_EDICTS;ic++)
|
||||
{
|
||||
e = gEngfuncs.GetEntityByIndex( ic );
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
if (!e->model)
|
||||
continue;
|
||||
|
||||
if (e->curstate.colormap == sv_index)
|
||||
return e;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
AngleMatrix
|
||||
|
||||
====================
|
||||
*/
|
||||
void AngleMatrix (const float *angles, float (*matrix)[4] )
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
// matrix = (YAW * PITCH) * ROLL
|
||||
matrix[0][0] = cp*cy;
|
||||
matrix[1][0] = cp*sy;
|
||||
matrix[2][0] = -sp;
|
||||
matrix[0][1] = sr*sp*cy+cr*-sy;
|
||||
matrix[1][1] = sr*sp*sy+cr*cy;
|
||||
matrix[2][1] = sr*cp;
|
||||
matrix[0][2] = (cr*sp*cy+-sr*-sy);
|
||||
matrix[1][2] = (cr*sp*sy+-sr*cy);
|
||||
matrix[2][2] = cr*cp;
|
||||
matrix[0][3] = 0.0;
|
||||
matrix[1][3] = 0.0;
|
||||
matrix[2][3] = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
VectorCompare
|
||||
|
||||
====================
|
||||
*/
|
||||
int VectorCompare (const float *v1, const float *v2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
if (v1[i] != v2[i]) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CrossProduct
|
||||
|
||||
====================
|
||||
*/
|
||||
void CrossProduct (const float *v1, const float *v2, float *cross)
|
||||
{
|
||||
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
VectorTransform
|
||||
|
||||
====================
|
||||
*/
|
||||
void VectorTransform (const float *in1, float in2[3][4], float *out)
|
||||
{
|
||||
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
|
||||
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
|
||||
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
ConcatTransforms
|
||||
|
||||
================
|
||||
*/
|
||||
void ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
|
||||
{
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
|
||||
in1[0][2] * in2[2][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
|
||||
in1[0][2] * in2[2][1];
|
||||
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
|
||||
in1[0][2] * in2[2][2];
|
||||
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
|
||||
in1[0][2] * in2[2][3] + in1[0][3];
|
||||
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
|
||||
in1[1][2] * in2[2][0];
|
||||
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
|
||||
in1[1][2] * in2[2][1];
|
||||
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
|
||||
in1[1][2] * in2[2][2];
|
||||
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
|
||||
in1[1][2] * in2[2][3] + in1[1][3];
|
||||
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
|
||||
in1[2][2] * in2[2][0];
|
||||
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
|
||||
in1[2][2] * in2[2][1];
|
||||
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
|
||||
in1[2][2] * in2[2][2];
|
||||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
|
||||
in1[2][2] * in2[2][3] + in1[2][3];
|
||||
}
|
||||
|
||||
// angles index are not the same as ROLL, PITCH, YAW
|
||||
|
||||
/*
|
||||
====================
|
||||
AngleQuaternion
|
||||
|
||||
====================
|
||||
*/
|
||||
void AngleQuaternion( float *angles, vec4_t quaternion )
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
// FIXME: rescale the inputs to 1/2 angle
|
||||
angle = angles[2] * 0.5;
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[1] * 0.5;
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = angles[0] * 0.5;
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
quaternion[0] = sr*cp*cy-cr*sp*sy; // X
|
||||
quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
|
||||
quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
|
||||
quaternion[3] = cr*cp*cy+sr*sp*sy; // W
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
QuaternionSlerp
|
||||
|
||||
====================
|
||||
*/
|
||||
void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||
{
|
||||
int i;
|
||||
float omega, cosom, sinom, sclp, sclq;
|
||||
|
||||
// decide if one of the quaternions is backwards
|
||||
float a = 0;
|
||||
float b = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
a += (p[i]-q[i])*(p[i]-q[i]);
|
||||
b += (p[i]+q[i])*(p[i]+q[i]);
|
||||
}
|
||||
if (a > b)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
q[i] = -q[i];
|
||||
}
|
||||
}
|
||||
|
||||
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
|
||||
|
||||
if ((1.0 + cosom) > 0.000001)
|
||||
{
|
||||
if ((1.0 - cosom) > 0.000001)
|
||||
{
|
||||
omega = acos( cosom );
|
||||
sinom = sin( omega );
|
||||
sclp = sin( (1.0 - t)*omega) / sinom;
|
||||
sclq = sin( t*omega ) / sinom;
|
||||
}
|
||||
else
|
||||
{
|
||||
sclp = 1.0 - t;
|
||||
sclq = t;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
qt[i] = sclp * p[i] + sclq * q[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qt[0] = -q[1];
|
||||
qt[1] = q[0];
|
||||
qt[2] = -q[3];
|
||||
qt[3] = q[2];
|
||||
sclp = sin( (1.0 - t) * (0.5 * M_PI));
|
||||
sclq = sin( t * (0.5 * M_PI));
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
qt[i] = sclp * p[i] + sclq * qt[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
QuaternionMatrix
|
||||
|
||||
====================
|
||||
*/
|
||||
void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] )
|
||||
{
|
||||
matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2];
|
||||
matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2];
|
||||
matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1];
|
||||
|
||||
matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2];
|
||||
matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2];
|
||||
matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0];
|
||||
|
||||
matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1];
|
||||
matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0];
|
||||
matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
MatrixCopy
|
||||
|
||||
====================
|
||||
*/
|
||||
void MatrixCopy( float in[3][4], float out[3][4] )
|
||||
{
|
||||
memcpy( out, in, sizeof( float ) * 3 * 4 );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
VectorIRotate
|
||||
|
||||
====================
|
||||
*/
|
||||
void VectorIRotate (const vec3_t in1, const float in2[3][4], vec3_t out)
|
||||
{
|
||||
out[0] = in1[0]*in2[0][0] + in1[1]*in2[1][0] + in1[2]*in2[2][0];
|
||||
out[1] = in1[0]*in2[0][1] + in1[1]*in2[1][1] + in1[2]*in2[2][1];
|
||||
out[2] = in1[0]*in2[0][2] + in1[1]*in2[1][2] + in1[2]*in2[2][2];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
VectorRotateByMatrix
|
||||
VectorTransformByMatrix
|
||||
====================
|
||||
*/
|
||||
void VectorRotateByMatrix (const vec3_t &in1, const float *in2, vec3_t &out)
|
||||
{
|
||||
out[0] = in1[0]*in2[0] + in1[1]*in2[4] + in1[2]*in2[8];
|
||||
out[1] = in1[0]*in2[1] + in1[1]*in2[5] + in1[2]*in2[9];
|
||||
out[2] = in1[0]*in2[2] + in1[1]*in2[6] + in1[2]*in2[10];
|
||||
}
|
||||
|
||||
void VectorTransformByMatrix (const vec3_t &in1, const float *in2, vec3_t &out)
|
||||
{
|
||||
out[0] = in1[0]*in2[0] + in1[1]*in2[4] + in1[2]*in2[8] + in2[12];
|
||||
out[1] = in1[0]*in2[1] + in1[1]*in2[5] + in1[2]*in2[9] + in2[13];
|
||||
out[2] = in1[0]*in2[2] + in1[1]*in2[6] + in1[2]*in2[10] + in2[14];
|
||||
}
|
||||
|
||||
void VectorRotateByMatrix (const float *in1, const float *in2, float *out)
|
||||
{
|
||||
out[0] = in1[0]*in2[0] + in1[1]*in2[4] + in1[2]*in2[8];
|
||||
out[1] = in1[0]*in2[1] + in1[1]*in2[5] + in1[2]*in2[9];
|
||||
out[2] = in1[0]*in2[2] + in1[1]*in2[6] + in1[2]*in2[10];
|
||||
}
|
||||
|
||||
void VectorTransformByMatrix (const float *in1, const float *in2, float *out)
|
||||
{
|
||||
out[0] = in1[0]*in2[0] + in1[1]*in2[4] + in1[2]*in2[8] + in2[12];
|
||||
out[1] = in1[0]*in2[1] + in1[1]*in2[5] + in1[2]*in2[9] + in2[13];
|
||||
out[2] = in1[0]*in2[2] + in1[1]*in2[6] + in1[2]*in2[10] + in2[14];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
ObjectToWorldMatrix
|
||||
|
||||
====================
|
||||
*/
|
||||
void ObjectToWorldMatrix(cl_entity_t *e, float *result)
|
||||
{
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glTranslatef(e->origin[0], e->origin[1], e->origin[2]);
|
||||
glRotatef ( e->angles[1], 0, 0, 1);
|
||||
glRotatef ( e->angles[0], 0, 1, 0);
|
||||
glRotatef ( e->angles[2], 1, 0, 0);
|
||||
|
||||
glGetFloatv (GL_MODELVIEW_MATRIX, result);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SPRITE_GetList
|
||||
|
||||
====================
|
||||
*/
|
||||
|
||||
char *ParseHudSprite( char *pfile, char *psz, client_sprite_t *result )
|
||||
{
|
||||
char token[256];
|
||||
client_sprite_t *p = new client_sprite_t;
|
||||
int x = 0, y = 0, width = 0, height = 0;
|
||||
int section = 0;
|
||||
|
||||
memset( p, 0, sizeof(client_sprite_t) );
|
||||
|
||||
while( pfile )
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile( pfile, token );
|
||||
|
||||
if( !stricmp( token, psz ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile( pfile, token );
|
||||
if( !stricmp( token, "{" )) section = 1;
|
||||
}
|
||||
if(section)//parse section
|
||||
{
|
||||
if( !stricmp( token, "}" )) break;//end section
|
||||
|
||||
if ( !stricmp( token, "file" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
strcpy(p->szSprite, token );
|
||||
if( !gEngfuncs.COM_LoadFile( p->szSprite, 5, NULL )) return pfile;
|
||||
else
|
||||
{
|
||||
gEngfuncs.COM_FreeFile( p->szSprite);
|
||||
//fill structure at default
|
||||
HSPRITE m_hSprite = SPR_Load(p->szSprite);
|
||||
x = y = 0;
|
||||
width = SPR_Width( m_hSprite, 0 );
|
||||
height = SPR_Height( m_hSprite, 0 );
|
||||
}
|
||||
}
|
||||
else if ( !stricmp( token, "name" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
strcpy(p->szName, token );
|
||||
}
|
||||
else if ( !stricmp( token, "x" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
x = atoi(token);
|
||||
}
|
||||
else if ( !stricmp( token, "y" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
y = atoi(token);
|
||||
}
|
||||
else if ( !stricmp( token, "width" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
width = atoi(token);
|
||||
}
|
||||
else if ( !stricmp( token, "height" ))
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
height = atoi(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!section) return pfile;//data not found
|
||||
|
||||
//calculate sprite position
|
||||
p->rc.left = x;
|
||||
p->rc.right = x + width;
|
||||
p->rc.top = y;
|
||||
p->rc.bottom = y + height;
|
||||
|
||||
//write resolution for backward compatibility
|
||||
if (ScreenWidth < 640) p->iRes = 320;
|
||||
else p->iRes = 640;
|
||||
|
||||
memcpy( result, p, sizeof(client_sprite_t));
|
||||
return pfile;
|
||||
}
|
||||
|
||||
client_sprite_t *SPR_GetList( char *psz, int *piCount )
|
||||
{
|
||||
int iSprCount = 0;
|
||||
char *pfile = (char *)gEngfuncs.COM_LoadFile( psz, 5, NULL);
|
||||
if (!pfile)
|
||||
{
|
||||
*piCount = iSprCount;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char token[256];
|
||||
char *plist = pfile;
|
||||
|
||||
while ( pfile ) //calculate count of sprites
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
if ( !stricmp( token, "hudsprite" )) iSprCount++;
|
||||
}
|
||||
|
||||
client_sprite_t *phud = new client_sprite_t[iSprCount];
|
||||
|
||||
for(int i = 0; i < iSprCount; i++ ) //parse structures
|
||||
{
|
||||
plist = ParseHudSprite( plist, "hudsprite", &phud[i] );
|
||||
}
|
||||
|
||||
if(!iSprCount)Msg("SPR_GetList: %s don't have sprites\n", psz );
|
||||
gEngfuncs.COM_FreeFile( pfile );
|
||||
|
||||
*piCount = iSprCount;
|
||||
return phud;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Sys LoadGameDLL
|
||||
|
||||
====================
|
||||
*/
|
||||
bool Sys_LoadLibrary (const char* dllname, dllhandle_t* handle, const dllfunction_t *fcts)
|
||||
{
|
||||
const dllfunction_t *gamefunc;
|
||||
char dllpath[128];
|
||||
dllhandle_t dllhandle = 0;
|
||||
|
||||
if (handle == NULL) return false;
|
||||
|
||||
// Initializations
|
||||
for (gamefunc = fcts; gamefunc && gamefunc->name != NULL; gamefunc++)
|
||||
*gamefunc->funcvariable = NULL;
|
||||
|
||||
// Try every possible name
|
||||
|
||||
|
||||
sprintf(dllpath, "%s/cl_dlls/%s", gEngfuncs.pfnGetGameDirectory(), dllname);
|
||||
dllhandle = LoadLibrary (dllpath);
|
||||
|
||||
// No DLL found
|
||||
if (! dllhandle) return false;
|
||||
|
||||
// Get the function adresses
|
||||
for (gamefunc = fcts; gamefunc && gamefunc->name != NULL; gamefunc++)
|
||||
if (!(*gamefunc->funcvariable = (void *) Sys_GetProcAddress (dllhandle, gamefunc->name)))
|
||||
{
|
||||
Sys_UnloadLibrary (&dllhandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
Msg("%s loaded succesfully!\n", dllname);
|
||||
*handle = dllhandle;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Sys_UnloadLibrary (dllhandle_t* handle)
|
||||
{
|
||||
if (handle == NULL || *handle == NULL)
|
||||
return;
|
||||
|
||||
FreeLibrary (*handle);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
void* Sys_GetProcAddress (dllhandle_t handle, const char* name)
|
||||
{
|
||||
return (void *)GetProcAddress (handle, name);
|
||||
}
|
||||
|
1117
client/r_view.cpp
1117
client/r_view.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,45 +0,0 @@
|
|||
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VIEW_H
|
||||
#define VIEW_H
|
||||
|
||||
void V_StartPitchDrift( void );
|
||||
void V_StopPitchDrift( void );
|
||||
|
||||
//camera flags
|
||||
#define CAMERA_ON 1
|
||||
#define DRAW_HUD 2
|
||||
#define INVERSE_X 4
|
||||
#define MONSTER_VIEW 8
|
||||
|
||||
typedef struct pitchdrift_s
|
||||
{
|
||||
float pitchvel;
|
||||
int nodrift;
|
||||
float driftmove;
|
||||
double laststop;
|
||||
}pitchdrift_t;
|
||||
static pitchdrift_t pd;
|
||||
|
||||
|
||||
#define ORIGIN_BACKUP 64
|
||||
#define ORIGIN_MASK ( ORIGIN_BACKUP - 1 )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float Origins[ ORIGIN_BACKUP ][3];
|
||||
float OriginTime[ ORIGIN_BACKUP ];
|
||||
|
||||
float Angles[ ORIGIN_BACKUP ][3];
|
||||
float AngleTime[ ORIGIN_BACKUP ];
|
||||
|
||||
int CurrentOrigin;
|
||||
int CurrentAngle;
|
||||
}viewinterp_t;
|
||||
|
||||
#endif // VIEW_H
|
|
@ -1,680 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) Shambler Team 2005
|
||||
// rain.cpp - TriAPI weather effects
|
||||
// based on original code from BUzer
|
||||
//=======================================================================
|
||||
|
||||
#include "hud.h"
|
||||
#include "r_main.h"
|
||||
#include "r_util.h"
|
||||
#include "const.h"
|
||||
#include "entity_types.h"
|
||||
#include "cdll_int.h"
|
||||
#include "pm_defs.h"
|
||||
#include "event_api.h"
|
||||
#include "triangleapi.h"
|
||||
#include "r_weather.h"
|
||||
|
||||
void WaterLandingEffect(cl_drip *drip);
|
||||
void ParseRainFile( void );
|
||||
|
||||
rain_properties Rain;
|
||||
|
||||
cl_drip FirstChainDrip;
|
||||
cl_rainfx FirstChainFX;
|
||||
|
||||
double rain_curtime; // current time
|
||||
double rain_oldtime; // last time we have updated drips
|
||||
double rain_timedelta; // difference between old time and current time
|
||||
double rain_nextspawntime; // when the next drip should be spawned
|
||||
|
||||
int dripcounter = 0;
|
||||
int fxcounter = 0;
|
||||
|
||||
|
||||
/*
|
||||
=================================
|
||||
ProcessRain
|
||||
|
||||
Must think every frame.
|
||||
=================================
|
||||
*/
|
||||
void ProcessRain( void )
|
||||
{
|
||||
rain_oldtime = rain_curtime; // save old time
|
||||
rain_curtime = gEngfuncs.GetClientTime();
|
||||
rain_timedelta = rain_curtime - rain_oldtime;
|
||||
|
||||
// first frame
|
||||
if (rain_oldtime == 0)
|
||||
{
|
||||
// fix first frame bug with nextspawntime
|
||||
rain_nextspawntime = gEngfuncs.GetClientTime();
|
||||
ParseRainFile();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Rain.dripsPerSecond == 0 && FirstChainDrip.p_Next == NULL)
|
||||
{
|
||||
// keep nextspawntime correct
|
||||
rain_nextspawntime = rain_curtime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rain_timedelta == 0)
|
||||
return; // not in pause
|
||||
|
||||
double timeBetweenDrips = 1 / (double)Rain.dripsPerSecond;
|
||||
|
||||
cl_drip* curDrip = FirstChainDrip.p_Next;
|
||||
cl_drip* nextDrip = NULL;
|
||||
|
||||
cl_entity_t *player = gEngfuncs.GetLocalPlayer();
|
||||
|
||||
// save debug info
|
||||
float debug_lifetime = 0;
|
||||
int debug_howmany = 0;
|
||||
int debug_attempted = 0;
|
||||
int debug_dropped = 0;
|
||||
|
||||
while (curDrip != NULL) // go through list
|
||||
{
|
||||
nextDrip = curDrip->p_Next; // save pointer to next drip
|
||||
|
||||
if (Rain.weatherMode == 0)
|
||||
curDrip->origin.z -= rain_timedelta * DRIPSPEED; // rain
|
||||
else
|
||||
curDrip->origin.z -= rain_timedelta * SNOWSPEED; // snow
|
||||
|
||||
curDrip->origin.x += rain_timedelta * curDrip->xDelta;
|
||||
curDrip->origin.y += rain_timedelta * curDrip->yDelta;
|
||||
|
||||
// remove drip if its origin lower than minHeight
|
||||
if (curDrip->origin.z < curDrip->minHeight)
|
||||
{
|
||||
if (curDrip->landInWater/* && Rain.weatherMode == 0*/)
|
||||
WaterLandingEffect(curDrip); // create water rings
|
||||
|
||||
if (r_debug->value > 1)
|
||||
{
|
||||
debug_lifetime += (rain_curtime - curDrip->birthTime);
|
||||
debug_howmany++;
|
||||
}
|
||||
|
||||
curDrip->p_Prev->p_Next = curDrip->p_Next; // link chain
|
||||
if (nextDrip != NULL)
|
||||
nextDrip->p_Prev = curDrip->p_Prev;
|
||||
delete curDrip;
|
||||
|
||||
dripcounter--;
|
||||
}
|
||||
|
||||
curDrip = nextDrip; // restore pointer, so we can continue moving through chain
|
||||
}
|
||||
|
||||
int maxDelta; // maximum height randomize distance
|
||||
float falltime;
|
||||
if (Rain.weatherMode == 0)
|
||||
{
|
||||
maxDelta = DRIPSPEED * rain_timedelta; // for rain
|
||||
falltime = (Rain.globalHeight + 4096) / DRIPSPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxDelta = SNOWSPEED * rain_timedelta; // for snow
|
||||
falltime = (Rain.globalHeight + 4096) / SNOWSPEED;
|
||||
}
|
||||
|
||||
while (rain_nextspawntime < rain_curtime)
|
||||
{
|
||||
rain_nextspawntime += timeBetweenDrips;
|
||||
if (r_debug->value > 1) debug_attempted++;
|
||||
|
||||
if (dripcounter < MAXDRIPS) // check for overflow
|
||||
{
|
||||
float deathHeight;
|
||||
vec3_t vecStart, vecEnd;
|
||||
|
||||
vecStart[0] = gEngfuncs.pfnRandomFloat(player->origin.x - Rain.distFromPlayer, player->origin.x + Rain.distFromPlayer);
|
||||
vecStart[1] = gEngfuncs.pfnRandomFloat(player->origin.y - Rain.distFromPlayer, player->origin.y + Rain.distFromPlayer);
|
||||
vecStart[2] = Rain.globalHeight;
|
||||
|
||||
float xDelta = Rain.windX + gEngfuncs.pfnRandomFloat(Rain.randX * -1, Rain.randX);
|
||||
float yDelta = Rain.windY + gEngfuncs.pfnRandomFloat(Rain.randY * -1, Rain.randY);
|
||||
|
||||
// find a point at bottom of map
|
||||
vecEnd[0] = falltime * xDelta;
|
||||
vecEnd[1] = falltime * yDelta;
|
||||
vecEnd[2] = -4096;
|
||||
|
||||
pmtrace_t pmtrace;
|
||||
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
|
||||
gEngfuncs.pEventAPI->EV_PlayerTrace( vecStart, vecStart + vecEnd, PM_STUDIO_IGNORE, -1, &pmtrace );
|
||||
|
||||
if (pmtrace.startsolid || pmtrace.allsolid)
|
||||
{
|
||||
if (r_debug->value > 1) debug_dropped++;
|
||||
continue; // drip cannot be placed
|
||||
}
|
||||
|
||||
// falling to water?
|
||||
int contents = gEngfuncs.PM_PointContents( pmtrace.endpos, NULL );
|
||||
if (contents == CONTENTS_WATER)
|
||||
{
|
||||
int waterEntity = gEngfuncs.PM_WaterEntity( pmtrace.endpos );
|
||||
if ( waterEntity > 0 )
|
||||
{
|
||||
cl_entity_t *pwater = UTIL_GetClientEntityWithServerIndex( waterEntity );
|
||||
if ( pwater && ( pwater->model != NULL ) )
|
||||
{
|
||||
deathHeight = pwater->curstate.maxs[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg("Rain error: can't get water entity\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg("Rain error: water is not func_water entity\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deathHeight = pmtrace.endpos[2];
|
||||
}
|
||||
|
||||
// just in case..
|
||||
if (deathHeight > vecStart[2])
|
||||
{
|
||||
Msg("Rain error: can't create drip in water\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
cl_drip *newClDrip = new cl_drip;
|
||||
if (!newClDrip)
|
||||
{
|
||||
Rain.dripsPerSecond = 0; // disable rain
|
||||
Msg( "Rain error: failed to allocate object!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vecStart[2] -= gEngfuncs.pfnRandomFloat(0, maxDelta); // randomize a bit
|
||||
|
||||
newClDrip->alpha = gEngfuncs.pfnRandomFloat(0.12, 0.2);
|
||||
VectorCopy(vecStart, newClDrip->origin);
|
||||
|
||||
newClDrip->xDelta = xDelta;
|
||||
newClDrip->yDelta = yDelta;
|
||||
|
||||
newClDrip->birthTime = rain_curtime; // store time when it was spawned
|
||||
newClDrip->minHeight = deathHeight;
|
||||
|
||||
if (contents == CONTENTS_WATER)
|
||||
newClDrip->landInWater = 1;
|
||||
else
|
||||
newClDrip->landInWater = 0;
|
||||
|
||||
// add to first place in chain
|
||||
newClDrip->p_Next = FirstChainDrip.p_Next;
|
||||
newClDrip->p_Prev = &FirstChainDrip;
|
||||
if (newClDrip->p_Next != NULL)
|
||||
newClDrip->p_Next->p_Prev = newClDrip;
|
||||
FirstChainDrip.p_Next = newClDrip;
|
||||
|
||||
dripcounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "Rain error: Drip limit overflow!\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_debug->value > 1) // print debug info
|
||||
{
|
||||
Msg( "Rain info: Drips exist: %i\n", dripcounter );
|
||||
Msg( "Rain info: FX's exist: %i\n", fxcounter );
|
||||
Msg( "Rain info: Attempted/Dropped: %i, %i\n", debug_attempted, debug_dropped);
|
||||
if (debug_howmany)
|
||||
{
|
||||
float ave = debug_lifetime / (float)debug_howmany;
|
||||
Msg( "Rain info: Average drip life time: %f\n", ave);
|
||||
}
|
||||
else
|
||||
Msg( "Rain info: Average drip life time: --\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
WaterLandingEffect
|
||||
=================================
|
||||
*/
|
||||
void WaterLandingEffect(cl_drip *drip)
|
||||
{
|
||||
if (fxcounter >= MAXFX)
|
||||
{
|
||||
Msg( "Rain error: FX limit overflow!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
cl_rainfx *newFX = new cl_rainfx;
|
||||
if (!newFX)
|
||||
{
|
||||
Msg( "Rain error: failed to allocate FX object!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
newFX->alpha = gEngfuncs.pfnRandomFloat(0.6, 0.9);
|
||||
VectorCopy(drip->origin, newFX->origin);
|
||||
newFX->origin[2] = drip->minHeight; // correct position
|
||||
|
||||
newFX->birthTime = gEngfuncs.GetClientTime();
|
||||
newFX->life = gEngfuncs.pfnRandomFloat(0.7, 1);
|
||||
|
||||
// add to first place in chain
|
||||
newFX->p_Next = FirstChainFX.p_Next;
|
||||
newFX->p_Prev = &FirstChainFX;
|
||||
if (newFX->p_Next != NULL)
|
||||
newFX->p_Next->p_Prev = newFX;
|
||||
FirstChainFX.p_Next = newFX;
|
||||
|
||||
fxcounter++;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
ProcessFXObjects
|
||||
|
||||
Remove all fx objects with out time to live
|
||||
Call every frame before ProcessRain
|
||||
=================================
|
||||
*/
|
||||
void ProcessFXObjects( void )
|
||||
{
|
||||
float curtime = gEngfuncs.GetClientTime();
|
||||
|
||||
cl_rainfx* curFX = FirstChainFX.p_Next;
|
||||
cl_rainfx* nextFX = NULL;
|
||||
|
||||
while (curFX != NULL) // go through FX objects list
|
||||
{
|
||||
nextFX = curFX->p_Next; // save pointer to next
|
||||
|
||||
// delete current?
|
||||
if ((curFX->birthTime + curFX->life) < curtime)
|
||||
{
|
||||
curFX->p_Prev->p_Next = curFX->p_Next; // link chain
|
||||
if (nextFX != NULL)
|
||||
nextFX->p_Prev = curFX->p_Prev;
|
||||
delete curFX;
|
||||
fxcounter--;
|
||||
}
|
||||
curFX = nextFX; // restore pointer
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
ResetRain
|
||||
clear memory, delete all objects
|
||||
=================================
|
||||
*/
|
||||
void ResetRain( void )
|
||||
{
|
||||
// delete all drips
|
||||
cl_drip* delDrip = FirstChainDrip.p_Next;
|
||||
FirstChainDrip.p_Next = NULL;
|
||||
|
||||
while (delDrip != NULL)
|
||||
{
|
||||
cl_drip* nextDrip = delDrip->p_Next; // save pointer to next drip in chain
|
||||
delete delDrip;
|
||||
delDrip = nextDrip; // restore pointer
|
||||
dripcounter--;
|
||||
}
|
||||
|
||||
// delete all FX objects
|
||||
cl_rainfx* delFX = FirstChainFX.p_Next;
|
||||
FirstChainFX.p_Next = NULL;
|
||||
|
||||
while (delFX != NULL)
|
||||
{
|
||||
cl_rainfx* nextFX = delFX->p_Next;
|
||||
delete delFX;
|
||||
delFX = nextFX;
|
||||
fxcounter--;
|
||||
}
|
||||
|
||||
InitRain();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
InitRain
|
||||
initialze system
|
||||
=================================
|
||||
*/
|
||||
void InitRain( void )
|
||||
{
|
||||
Rain.dripsPerSecond = 0;
|
||||
Rain.distFromPlayer = 0;
|
||||
Rain.windX = 0;
|
||||
Rain.windY = 0;
|
||||
Rain.randX = 0;
|
||||
Rain.randY = 0;
|
||||
Rain.weatherMode = 0;
|
||||
Rain.globalHeight = 0;
|
||||
|
||||
FirstChainDrip.birthTime = 0;
|
||||
FirstChainDrip.minHeight = 0;
|
||||
FirstChainDrip.origin[0]=0;
|
||||
FirstChainDrip.origin[1]=0;
|
||||
FirstChainDrip.origin[2]=0;
|
||||
FirstChainDrip.alpha = 0;
|
||||
FirstChainDrip.xDelta = 0;
|
||||
FirstChainDrip.yDelta = 0;
|
||||
FirstChainDrip.landInWater = 0;
|
||||
FirstChainDrip.p_Next = NULL;
|
||||
FirstChainDrip.p_Prev = NULL;
|
||||
|
||||
FirstChainFX.alpha = 0;
|
||||
FirstChainFX.birthTime = 0;
|
||||
FirstChainFX.life = 0;
|
||||
FirstChainFX.origin[0] = 0;
|
||||
FirstChainFX.origin[1] = 0;
|
||||
FirstChainFX.origin[2] = 0;
|
||||
FirstChainFX.p_Next = NULL;
|
||||
FirstChainFX.p_Prev = NULL;
|
||||
|
||||
rain_oldtime = 0;
|
||||
rain_curtime = 0;
|
||||
rain_nextspawntime = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
===========================
|
||||
ParseRainFile
|
||||
|
||||
List of settings:
|
||||
drips - max raindrips\snowflakes
|
||||
distance - radius of rain\snow
|
||||
windx - wind shift X
|
||||
windy - wind shift Y
|
||||
randx - random shift X
|
||||
randy - random shift Y
|
||||
mode - rain = 0\snow =1
|
||||
height - max height to create raindrips\snowflakes
|
||||
===========================
|
||||
*/
|
||||
void ParseRainFile( void )
|
||||
{
|
||||
if (Rain.distFromPlayer != 0 || Rain.dripsPerSecond != 0 || Rain.globalHeight != 0)
|
||||
return;
|
||||
|
||||
char mapname[64];
|
||||
char token[64];
|
||||
char *pfile;
|
||||
|
||||
strcpy( mapname, gEngfuncs.pfnGetLevelName() );
|
||||
if (strlen(mapname) == 0)
|
||||
{
|
||||
Msg( "Rain error: unable to read map name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mapname[strlen(mapname)-4] = 0;
|
||||
sprintf(mapname, "%s.pcs", mapname);
|
||||
|
||||
pfile = (char *)gEngfuncs.COM_LoadFile( mapname, 5, NULL);
|
||||
if (!pfile)
|
||||
{
|
||||
if (r_debug->value > 1)
|
||||
Msg("Rain: couldn't open rain settings file %s\n", mapname);
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
if (!pfile)
|
||||
break;
|
||||
|
||||
if (!stricmp(token, "drips")) // dripsPerSecond
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.dripsPerSecond = atoi(token);
|
||||
}
|
||||
else if (!stricmp(token, "distance")) // distFromPlayer
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.distFromPlayer = atof(token);
|
||||
}
|
||||
else if (!stricmp(token, "windx")) // windX
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.windX = atof(token);
|
||||
}
|
||||
else if (!stricmp(token, "windy")) // windY
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.windY = atof(token);
|
||||
}
|
||||
else if (!stricmp(token, "randx")) // randX
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.randX = atof(token);
|
||||
}
|
||||
else if (!stricmp(token, "randy")) // randY
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.randY = atof(token);
|
||||
}
|
||||
else if (!stricmp(token, "mode")) // weatherMode
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.weatherMode = atoi(token);
|
||||
}
|
||||
else if (!stricmp(token, "height")) // globalHeight
|
||||
{
|
||||
pfile = gEngfuncs.COM_ParseFile(pfile, token);
|
||||
Rain.globalHeight = atof(token);
|
||||
}
|
||||
else
|
||||
Msg("Rain error: unknown token %s in file %s\n", token, mapname);
|
||||
}
|
||||
|
||||
gEngfuncs.COM_FreeFile( pfile );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
void SetPoint( float x, float y, float z, float (*matrix)[4])
|
||||
{
|
||||
vec3_t point, result;
|
||||
point[0] = x;
|
||||
point[1] = y;
|
||||
point[2] = z;
|
||||
|
||||
VectorTransform(point, matrix, result);
|
||||
gEngfuncs.pTriAPI->Vertex3f(result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
DrawRain
|
||||
|
||||
draw raindrips and snowflakes
|
||||
=================================
|
||||
*/
|
||||
void DrawRain( void )
|
||||
{
|
||||
if (FirstChainDrip.p_Next == NULL)
|
||||
return; // no drips to draw
|
||||
|
||||
HSPRITE hsprTexture;
|
||||
const model_s *pTexture;
|
||||
float visibleHeight = Rain.globalHeight - SNOWFADEDIST;
|
||||
|
||||
if (Rain.weatherMode == 0)
|
||||
hsprTexture = LoadSprite( "sprites/raindrop.spr" ); // load rain sprite
|
||||
else hsprTexture = LoadSprite( "sprites/snowflake.spr" ); // load snow sprite
|
||||
|
||||
if(!hsprTexture) return;
|
||||
// usual triapi stuff
|
||||
pTexture = gEngfuncs.GetSpritePointer( hsprTexture );
|
||||
gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)pTexture, 0 );
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd );
|
||||
gEngfuncs.pTriAPI->CullFace( TRI_NONE );
|
||||
|
||||
// go through drips list
|
||||
cl_drip* Drip = FirstChainDrip.p_Next;
|
||||
cl_entity_t *player = gEngfuncs.GetLocalPlayer();
|
||||
|
||||
if ( Rain.weatherMode == 0 ) // draw rain
|
||||
{
|
||||
while (Drip != NULL)
|
||||
{
|
||||
cl_drip* nextdDrip = Drip->p_Next;
|
||||
|
||||
Vector2D toPlayer;
|
||||
toPlayer.x = player->origin[0] - Drip->origin[0];
|
||||
toPlayer.y = player->origin[1] - Drip->origin[1];
|
||||
toPlayer = toPlayer.Normalize();
|
||||
|
||||
toPlayer.x *= DRIP_SPRITE_HALFWIDTH;
|
||||
toPlayer.y *= DRIP_SPRITE_HALFWIDTH;
|
||||
|
||||
float shiftX = (Drip->xDelta / DRIPSPEED) * DRIP_SPRITE_HALFHEIGHT;
|
||||
float shiftY = (Drip->yDelta / DRIPSPEED) * DRIP_SPRITE_HALFHEIGHT;
|
||||
|
||||
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, Drip->alpha );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_TRIANGLES );
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( Drip->origin[0]-toPlayer.y - shiftX, Drip->origin[1]+toPlayer.x - shiftY,Drip->origin[2] + DRIP_SPRITE_HALFHEIGHT );
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0.5, 1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( Drip->origin[0] + shiftX, Drip->origin[1] + shiftY, Drip->origin[2]-DRIP_SPRITE_HALFHEIGHT );
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f( Drip->origin[0]+toPlayer.y - shiftX, Drip->origin[1]-toPlayer.x - shiftY, Drip->origin[2]+DRIP_SPRITE_HALFHEIGHT);
|
||||
|
||||
gEngfuncs.pTriAPI->End();
|
||||
Drip = nextdDrip;
|
||||
}
|
||||
}
|
||||
|
||||
else // draw snow
|
||||
{
|
||||
vec3_t normal;
|
||||
gEngfuncs.GetViewAngles((float*)normal);
|
||||
|
||||
float matrix[3][4];
|
||||
AngleMatrix (normal, matrix); // calc view matrix
|
||||
|
||||
while (Drip != NULL)
|
||||
{
|
||||
cl_drip* nextdDrip = Drip->p_Next;
|
||||
|
||||
matrix[0][3] = Drip->origin[0]; // write origin to matrix
|
||||
matrix[1][3] = Drip->origin[1];
|
||||
matrix[2][3] = Drip->origin[2];
|
||||
|
||||
// apply start fading effect
|
||||
float alpha = (Drip->origin[2] <= visibleHeight) ? Drip->alpha : ((Rain.globalHeight - Drip->origin[2]) / (float)SNOWFADEDIST) * Drip->alpha;
|
||||
|
||||
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, alpha );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 );
|
||||
SetPoint(0, SNOW_SPRITE_HALFSIZE ,SNOW_SPRITE_HALFSIZE, matrix);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 );
|
||||
SetPoint(0, SNOW_SPRITE_HALFSIZE ,-SNOW_SPRITE_HALFSIZE, matrix);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 );
|
||||
SetPoint(0, -SNOW_SPRITE_HALFSIZE ,-SNOW_SPRITE_HALFSIZE, matrix);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 );
|
||||
SetPoint(0, -SNOW_SPRITE_HALFSIZE ,SNOW_SPRITE_HALFSIZE, matrix);
|
||||
|
||||
gEngfuncs.pTriAPI->End();
|
||||
Drip = nextdDrip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
DrawFXObjects
|
||||
=================================
|
||||
*/
|
||||
void DrawFXObjects( void )
|
||||
{
|
||||
if (FirstChainFX.p_Next == NULL)
|
||||
return; // no objects to draw
|
||||
|
||||
float curtime = gEngfuncs.GetClientTime();
|
||||
|
||||
// usual triapi stuff
|
||||
HSPRITE hsprTexture;
|
||||
const model_s *pTexture;
|
||||
hsprTexture = LoadSprite( "sprites/waterring.spr" ); // load water ring sprite
|
||||
if(!hsprTexture) return;
|
||||
pTexture = gEngfuncs.GetSpritePointer( hsprTexture );
|
||||
gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)pTexture, 0 );
|
||||
gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd );
|
||||
gEngfuncs.pTriAPI->CullFace( TRI_NONE );
|
||||
|
||||
// go through objects list
|
||||
cl_rainfx* curFX = FirstChainFX.p_Next;
|
||||
while (curFX != NULL)
|
||||
{
|
||||
cl_rainfx* nextFX = curFX->p_Next;
|
||||
|
||||
// fadeout
|
||||
float alpha = ((curFX->birthTime + curFX->life - curtime) / curFX->life) * curFX->alpha;
|
||||
float size = (curtime - curFX->birthTime) * MAXRINGHALFSIZE;
|
||||
|
||||
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, alpha );
|
||||
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f(curFX->origin[0] - size, curFX->origin[1] - size, curFX->origin[2]);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f(curFX->origin[0] - size, curFX->origin[1] + size, curFX->origin[2]);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 );
|
||||
gEngfuncs.pTriAPI->Vertex3f(curFX->origin[0] + size, curFX->origin[1] + size, curFX->origin[2]);
|
||||
|
||||
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 );
|
||||
gEngfuncs.pTriAPI->Vertex3f(curFX->origin[0] + size, curFX->origin[1] - size, curFX->origin[2]);
|
||||
|
||||
gEngfuncs.pTriAPI->End();
|
||||
curFX = nextFX;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================================
|
||||
DrawAll
|
||||
=================================
|
||||
*/
|
||||
|
||||
void R_DrawWeather( void )
|
||||
{
|
||||
ProcessFXObjects();
|
||||
ProcessRain();
|
||||
DrawRain();
|
||||
DrawFXObjects();
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2004, Shambler Team. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Shambler Team. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Shambler Team.
|
||||
*
|
||||
****/
|
||||
/*
|
||||
====== rain.h ========================================================
|
||||
*/
|
||||
#ifndef __RAIN_H__
|
||||
#define __RAIN_H__
|
||||
|
||||
#define DRIPSPEED 900 // speed of raindrips (pixel per secs)
|
||||
#define SNOWSPEED 200 // speed of snowflakes
|
||||
#define SNOWFADEDIST 80
|
||||
|
||||
#define MAXDRIPS 2000 // max raindrops
|
||||
#define MAXFX 3000 // max effects
|
||||
|
||||
#define DRIP_SPRITE_HALFHEIGHT 46
|
||||
#define DRIP_SPRITE_HALFWIDTH 8
|
||||
#define SNOW_SPRITE_HALFSIZE 3
|
||||
|
||||
// radius water rings
|
||||
#define MAXRINGHALFSIZE 25
|
||||
|
||||
typedef struct cl_drip
|
||||
{
|
||||
float birthTime;
|
||||
float minHeight; // minimal height to kill raindrop
|
||||
vec3_t origin;
|
||||
float alpha;
|
||||
|
||||
float xDelta; // side speed
|
||||
float yDelta;
|
||||
int landInWater;
|
||||
|
||||
cl_drip* p_Next; // next drip in chain
|
||||
cl_drip* p_Prev; // previous drip in chain
|
||||
} cl_drip_t;
|
||||
|
||||
typedef struct cl_rainfx
|
||||
{
|
||||
float birthTime;
|
||||
float life;
|
||||
vec3_t origin;
|
||||
float alpha;
|
||||
|
||||
cl_rainfx* p_Next; // next fx in chain
|
||||
cl_rainfx* p_Prev; // previous fx in chain
|
||||
} cl_rainfx_t;
|
||||
|
||||
void ProcessRain( void );
|
||||
void ProcessFXObjects( void );
|
||||
void ResetRain( void );
|
||||
void InitRain( void );
|
||||
|
||||
#endif
|
|
@ -24,7 +24,6 @@ void CL_UpdateEntityFields( edict_t *ent )
|
|||
ent->v.classname = cl.edict_classnames[ent->pvClientData->current.classname];
|
||||
ent->v.modelindex = ent->pvClientData->current.modelindex;
|
||||
ent->v.weaponmodel = ent->pvClientData->current.weaponmodel;
|
||||
ent->v.ambient = ent->pvClientData->current.soundindex;
|
||||
ent->v.model = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.modelindex] );
|
||||
ent->v.frame = ent->pvClientData->current.frame;
|
||||
ent->v.sequence = ent->pvClientData->current.sequence;
|
||||
|
@ -51,6 +50,7 @@ void CL_UpdateEntityFields( edict_t *ent )
|
|||
ent->v.solid = ent->pvClientData->current.solid;
|
||||
ent->v.movetype = ent->pvClientData->current.movetype;
|
||||
ent->v.flags = ent->pvClientData->current.flags;
|
||||
ent->v.teleport_time = ent->pvClientData->current.teleport_time;
|
||||
if( ent->v.scale == 0.0f ) ent->v.scale = 1.0f;
|
||||
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
|
|
|
@ -360,7 +360,7 @@ pfnDrawImageExt
|
|||
|
||||
=============
|
||||
*/
|
||||
void pfnDrawImageExt( HSPRITE shader, int x, int y, int w, int h, float s1, float t1, float s2, float t2 )
|
||||
void pfnDrawImageExt( HSPRITE shader, float x, float y, float w, float h, float s1, float t1, float s2, float t2 )
|
||||
{
|
||||
if( !re ) return;
|
||||
|
||||
|
@ -652,25 +652,6 @@ void pfnCenterPrint( const char *text, int y, int charWidth )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnDrawCharacter
|
||||
|
||||
=============
|
||||
*/
|
||||
int pfnDrawCharacter( int x, int y, int width, int height, int number )
|
||||
{
|
||||
if( number < 32 || number > 255 )
|
||||
{
|
||||
MsgDev( D_WARN, "SCR_DrawChar: passed non-printable character %c\n", (char )number );
|
||||
return false;
|
||||
}
|
||||
|
||||
SCR_DrawChar( x, y, width, height, number );
|
||||
if( re ) re->SetColor( NULL );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnDrawString
|
||||
|
@ -879,7 +860,6 @@ static cl_enginefuncs_t gEngfuncs =
|
|||
AngleVectors,
|
||||
pfnDrawCenterPrint,
|
||||
pfnCenterPrint,
|
||||
pfnDrawCharacter,
|
||||
pfnDrawString,
|
||||
pfnGetDrawParms,
|
||||
pfnSetDrawParms,
|
||||
|
|
|
@ -326,5 +326,5 @@ void CL_PredictMovement (void)
|
|||
|
||||
// copy results out for rendering
|
||||
VectorCopy( pmove.origin, cl.predicted_origin );
|
||||
VectorCopy( pmove.v_angle, cl.predicted_angles );
|
||||
VectorCopy( pmove.viewangles, cl.predicted_angles );
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ void SCR_DrawChar( int x, int y, float w, float h, int ch )
|
|||
|
||||
ch &= 255;
|
||||
|
||||
if( ch == ' ' )return;
|
||||
if( ch == ' ' ) return;
|
||||
if(y < -h) return;
|
||||
|
||||
ax = x;
|
||||
|
|
|
@ -29,9 +29,13 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(framerate), NET_FLOAT, false }, // custom framerate
|
||||
{ ES_FIELD(sequence), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(gaitsequence), NET_WORD, false }, // 1024 gaitsequences
|
||||
{ ES_FIELD(skin), NET_CHAR, false }, // negative skins are contents
|
||||
{ ES_FIELD(skin), NET_BYTE, false }, // 255 skins
|
||||
{ ES_FIELD(body), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(weaponmodel), NET_WORD, false }, // 4096 models
|
||||
{ ES_FIELD(weaponmodel), NET_WORD, false }, // p_model index, not name
|
||||
{ ES_FIELD(weaponanim), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(weaponbody), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(weaponskin), NET_BYTE, false }, // 255 skins
|
||||
{ ES_FIELD(teleport_time), NET_FLOAT, false }, // FIXME: use byte ?
|
||||
{ ES_FIELD(blending[0]), NET_COLOR, false },
|
||||
{ ES_FIELD(blending[1]), NET_COLOR, false }, // stateflags_t #1 (4 bytes)
|
||||
{ ES_FIELD(blending[2]), NET_COLOR, false },
|
||||
|
@ -53,10 +57,12 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(controller[8]), NET_COLOR, false },
|
||||
{ ES_FIELD(controller[9]), NET_COLOR, false },
|
||||
{ ES_FIELD(solid), NET_BYTE, false },
|
||||
{ ES_FIELD(flags), NET_LONG, false },
|
||||
{ ES_FIELD(flags), NET_INT64, false }, // misc edict flags
|
||||
{ ES_FIELD(movetype), NET_BYTE, false },
|
||||
{ ES_FIELD(gravity), NET_SHORT, false }, // gravity multiplier
|
||||
{ ES_FIELD(aiment), NET_WORD, false }, // entity index
|
||||
{ ES_FIELD(owner), NET_WORD, false }, // entity owner index
|
||||
{ ES_FIELD(groundent), NET_WORD, false }, // ground entity index, if FL_ONGROUND is set
|
||||
{ ES_FIELD(solid), NET_LONG, false }, // encoded mins/maxs
|
||||
{ ES_FIELD(mins[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(mins[1]), NET_FLOAT, false },
|
||||
|
@ -84,10 +90,11 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(viewoffset[1]), NET_SCALE, false },
|
||||
{ ES_FIELD(viewoffset[2]), NET_SCALE, false },
|
||||
{ ES_FIELD(viewmodel), NET_WORD, false },
|
||||
{ ES_FIELD(maxspeed), NET_FLOAT, false }, // client maxspeed
|
||||
{ ES_FIELD(fov), NET_FLOAT, false }, // client horizontal field of view
|
||||
{ ES_FIELD(weapons), NET_INT64, false }, // client weapon 0-32
|
||||
{ ES_FIELD(weapons), NET_INT64, false }, // client weapon 0-64
|
||||
{ ES_FIELD(health), NET_FLOAT, false }, // client health
|
||||
// revision 4. reserve for 17 fields without enlarge null_msg_size
|
||||
// revision 4. reserve for 12 fields without enlarge null_msg_size
|
||||
{ NULL }, // terminator
|
||||
};
|
||||
|
||||
|
|
|
@ -128,8 +128,11 @@ typedef struct entity_state_s
|
|||
movetype_t movetype; // entity movetype
|
||||
int gravity; // gravity multiplier
|
||||
int aiment; // attached entity
|
||||
int owner; // projectiles owner
|
||||
int groundent; // onground edict num, valid only if FL_ONGROUND is set, else -1
|
||||
vec3_t mins; // not symmetric entity bbox
|
||||
vec3_t maxs;
|
||||
float teleport_time; // time when no prediction
|
||||
|
||||
// model state
|
||||
int modelindex; // general modelindex
|
||||
|
@ -145,7 +148,7 @@ typedef struct entity_state_s
|
|||
float controller[16]; // studio bone controllers
|
||||
|
||||
// flags
|
||||
int flags; // v.flags
|
||||
int64 flags; // v.flags
|
||||
uint effects; // effect flags like q1 and hl1
|
||||
int renderfx; // render effects same as hl1
|
||||
float renderamt; // alpha value or like somewhat
|
||||
|
@ -161,6 +164,10 @@ typedef struct entity_state_s
|
|||
int gaitsequence; // client\nps\bot gaitsequence
|
||||
int viewmodel; // contains viewmodel index
|
||||
int weaponmodel; // contains weaponmodel index
|
||||
int weaponanim; // weaponmodel sequence
|
||||
int weaponbody; // weaponmodel body
|
||||
int weaponskin; // weaponmodel skin
|
||||
float maxspeed; // min( pev->maxspeed, sv_maxspeed->value )
|
||||
float health; // client health (other parms can be send by custom messages)
|
||||
int64 weapons; // weapon flags
|
||||
float fov; // horizontal field of view
|
||||
|
|
|
@ -488,18 +488,16 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
{
|
||||
// fisrt entering
|
||||
svgame.dllFuncs.pfnClientPutInServer( ent );
|
||||
ent->v.v_angle[ROLL] = 0; // cut off any camera rolling
|
||||
ent->v.viewangles[ROLL] = 0; // cut off any camera rolling
|
||||
ent->v.origin[2] += 1; // make sure off ground
|
||||
}
|
||||
|
||||
ent->pvServerData->s.fov = 90; // FIXME: get from qc
|
||||
ent->pvServerData->s.fov = bound(1, ent->pvServerData->s.fov, 160);
|
||||
ent->pvServerData->s.health = ent->v.health;
|
||||
ent->pvServerData->s.classname = SV_ClassIndex( STRING( ent->v.classname ));
|
||||
ent->pvServerData->s.weaponmodel = SV_ModelIndex( STRING( ent->v.weaponmodel ));
|
||||
VectorCopy( ent->v.origin, ent->pvServerData->s.origin );
|
||||
VectorCopy( ent->v.v_angle, ent->pvServerData->s.viewangles );
|
||||
for( i = 0; i < 3; i++ ) ent->pvServerData->s.delta_angles[i] = ANGLE2SHORT(ent->v.v_angle[i]);
|
||||
VectorCopy( ent->v.viewangles, ent->pvServerData->s.viewangles );
|
||||
for( i = 0; i < 3; i++ ) ent->pvServerData->s.delta_angles[i] = ANGLE2SHORT(ent->v.viewangles[i]);
|
||||
|
||||
SV_LinkEdict( ent ); // m_pmatrix calculated here, so we need call this before pe->CreatePlayer
|
||||
ent->pvServerData->physbody = pe->CreatePlayer( ent, SV_GetModelPtr( ent ), ent->v.origin, ent->v.m_pmatrix );
|
||||
|
@ -1025,7 +1023,7 @@ void SV_ApplyClientMove( sv_client_t *cl, usercmd_t *cmd )
|
|||
cmd->upmove *= 0.333;
|
||||
}
|
||||
|
||||
VectorCopy( ent->pvServerData->s.viewangles, cl->edict->v.v_angle );
|
||||
VectorCopy( ent->pvServerData->s.viewangles, cl->edict->v.viewangles );
|
||||
VectorCopy( ent->pvServerData->s.viewangles, cl->edict->v.angles );
|
||||
VectorCopy( ent->v.view_ofs, cl->edict->pvServerData->s.viewoffset );
|
||||
}
|
||||
|
@ -1155,7 +1153,7 @@ void SV_WaterMove( sv_client_t *cl, usercmd_t *cmd )
|
|||
float accelspeed, temp;
|
||||
|
||||
// user intentions
|
||||
AngleVectors( cl->edict->v.v_angle, forward, right, up );
|
||||
AngleVectors( cl->edict->v.viewangles, forward, right, up );
|
||||
|
||||
for( i = 0; i < 3; i++ ) wishvel[i] = forward[i] * cmd->forwardmove + right[i] * cmd->sidemove;
|
||||
|
||||
|
@ -1271,7 +1269,7 @@ Also called by bot code
|
|||
*/
|
||||
void SV_ClientThink( sv_client_t *cl, usercmd_t *cmd )
|
||||
{
|
||||
vec3_t v_angle;
|
||||
vec3_t viewangles;
|
||||
|
||||
cl->cmd = *cmd;
|
||||
cl->skipframes = 0;
|
||||
|
@ -1296,12 +1294,12 @@ void SV_ClientThink( sv_client_t *cl, usercmd_t *cmd )
|
|||
|
||||
// angles
|
||||
// show 1/3 the pitch angle and all the roll angle
|
||||
VectorAdd( cl->edict->v.v_angle, cl->edict->v.punchangle, v_angle );
|
||||
VectorAdd( cl->edict->v.viewangles, cl->edict->v.punchangle, viewangles );
|
||||
cl->edict->v.angles[ROLL] = SV_CalcRoll( cl->edict->v.angles, cl->edict->v.velocity) * 4;
|
||||
if( !cl->edict->v.fixangle )
|
||||
{
|
||||
cl->edict->v.angles[PITCH] = -v_angle[PITCH]/3;
|
||||
cl->edict->v.angles[YAW] = v_angle[YAW];
|
||||
cl->edict->v.angles[PITCH] = -viewangles[PITCH]/3;
|
||||
cl->edict->v.angles[YAW] = viewangles[YAW];
|
||||
}
|
||||
|
||||
if( cl->edict->v.flags & FL_WATERJUMP )
|
||||
|
|
|
@ -71,6 +71,7 @@ void SV_UpdateEntityState( edict_t *ent )
|
|||
ent->pvServerData->s.frame = ent->v.frame; // any model current frame
|
||||
ent->pvServerData->s.framerate = ent->v.framerate;
|
||||
ent->pvServerData->s.flags = ent->v.flags;
|
||||
ent->pvServerData->s.teleport_time = ent->v.teleport_time; // any entity may be teleported
|
||||
VectorCopy( ent->v.rendercolor, ent->pvServerData->s.rendercolor );
|
||||
|
||||
// studio model sequence
|
||||
|
@ -97,7 +98,7 @@ void SV_UpdateEntityState( edict_t *ent )
|
|||
ent->pvServerData->s.delta_angles[i] = ANGLE2SHORT( ent->pvServerData->s.angles[i] );
|
||||
VectorClear( ent->pvServerData->s.angles );
|
||||
VectorClear( ent->pvServerData->s.viewangles );
|
||||
VectorClear( ent->v.v_angle );
|
||||
VectorClear( ent->v.viewangles );
|
||||
|
||||
// and clear fixangle for the next frame
|
||||
ent->v.fixangle = 0;
|
||||
|
@ -114,6 +115,7 @@ void SV_UpdateEntityState( edict_t *ent )
|
|||
// playermodel sequence, that will be playing on a client
|
||||
ent->pvServerData->s.gaitsequence = ent->v.gaitsequence;
|
||||
ent->pvServerData->s.weapons = ent->v.weapons;
|
||||
ent->pvServerData->s.fov = bound( 1.0f, ent->v.fov, 160.0f );
|
||||
}
|
||||
else if( ent->pvServerData->s.ed_type == ED_AMBIENT )
|
||||
{
|
||||
|
@ -130,6 +132,8 @@ void SV_UpdateEntityState( edict_t *ent )
|
|||
{
|
||||
// FIXME: send mins\maxs for sound spatialization and entity prediction ?
|
||||
}
|
||||
|
||||
if( ent->v.teleport_time ) ent->v.teleport_time = 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1309,7 +1309,7 @@ void pfnChangePitch( edict_t* ent )
|
|||
}
|
||||
|
||||
current = anglemod( ent->v.angles[PITCH] );
|
||||
ent->v.angles[PITCH] = SV_AngleMod( ent->v.idealpitch, current, ent->v.pitch_speed );
|
||||
ent->v.angles[PITCH] = SV_AngleMod( ent->v.ideal_pitch, current, ent->v.pitch_speed );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1408,7 +1408,7 @@ edict_t* pfnFindEntityInSphere( edict_t *pStartEdict, const float *org, float ra
|
|||
if( DotProduct( eorg, eorg ) < radSquare )
|
||||
return ent;
|
||||
}
|
||||
return NULL; // fisrt chain
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1486,7 +1486,7 @@ edict_t* pfnEntitiesInPVS( edict_t *pplayer )
|
|||
chain = pEdict;
|
||||
}
|
||||
}
|
||||
return chain; // fisrt entry
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1514,7 +1514,7 @@ edict_t* pfnEntitiesInPHS( edict_t *pplayer )
|
|||
chain = pEdict;
|
||||
}
|
||||
}
|
||||
return chain; // fisrt entry
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -442,11 +442,11 @@ void SV_PlayerMove( edict_t *player )
|
|||
cmd = &client->lastcmd;
|
||||
body = player->pvServerData->physbody; // member body ptr
|
||||
VectorCopy( player->pvServerData->s.delta_angles, pmove.delta_angles );
|
||||
VectorCopy( player->pvServerData->s.viewangles, pmove.v_angle );
|
||||
VectorCopy( player->pvServerData->s.viewangles, pmove.viewangles );
|
||||
|
||||
pe->PlayerMove( &pmove, cmd, body, false ); // server move
|
||||
|
||||
VectorCopy( pmove.v_angle, player->pvServerData->s.viewangles );
|
||||
VectorCopy( pmove.viewangles, player->pvServerData->s.viewangles );
|
||||
|
||||
// save results of pmove
|
||||
player->v = pmove;
|
||||
|
|
|
@ -1074,13 +1074,13 @@ void SV_WallFriction( edict_t *ent, float *stepnormal )
|
|||
float d, i;
|
||||
vec3_t forward, into, side;
|
||||
|
||||
AngleVectors (ent->v.v_angle, forward, NULL, NULL);
|
||||
if ((d = DotProduct (stepnormal, forward) + 0.5) < 0)
|
||||
AngleVectors( ent->v.viewangles, forward, NULL, NULL );
|
||||
if(( d = DotProduct( stepnormal, forward ) + 0.5 ) < 0 )
|
||||
{
|
||||
// cut the tangential velocity
|
||||
i = DotProduct (stepnormal, ent->v.velocity);
|
||||
VectorScale (stepnormal, i, into);
|
||||
VectorSubtract (ent->v.velocity, into, side);
|
||||
i = DotProduct( stepnormal, ent->v.velocity );
|
||||
VectorScale( stepnormal, i, into );
|
||||
VectorSubtract( ent->v.velocity, into, side );
|
||||
ent->v.velocity[0] = side[0] * (1 + d);
|
||||
ent->v.velocity[1] = side[1] * (1 + d);
|
||||
}
|
||||
|
@ -1256,7 +1256,7 @@ void SV_Physics_Follow( edict_t *ent )
|
|||
ent->v.origin[1] = v[0] * vr[0] + v[1] * vr[1] + v[2] * vr[2] + e->v.origin[1];
|
||||
ent->v.origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->v.origin[2];
|
||||
}
|
||||
VectorAdd( e->v.angles, ent->v.v_angle, ent->v.angles );
|
||||
VectorAdd( e->v.angles, ent->v.viewangles, ent->v.angles );
|
||||
SV_LinkEdict( ent );
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,4 @@ void SV_RestoreEdict( edict_t *ent )
|
|||
SV_CreatePhysBody( ent );
|
||||
SV_SetPhysForce( ent ); // restore forces ...
|
||||
SV_SetMassCentre( ent ); // and mass force
|
||||
|
||||
if( ent->v.ambient ) // restore loopsound
|
||||
ent->pvServerData->s.soundindex = SV_SoundIndex( STRING( ent->v.ambient ));
|
||||
}
|
|
@ -353,12 +353,6 @@ void SV_LinkEdict( edict_t *ent )
|
|||
|
||||
ent->pvServerData->linkcount++;
|
||||
|
||||
// update ambient sound here
|
||||
if( ent->v.ambient )
|
||||
{
|
||||
ent->pvServerData->s.soundindex = SV_SoundIndex( STRING( ent->v.ambient ));
|
||||
}
|
||||
|
||||
// don't link not solid or rigid bodies
|
||||
if( ent->v.solid == SOLID_NOT || ent->v.solid >= SOLID_BOX )
|
||||
{
|
||||
|
|
|
@ -74,23 +74,23 @@ void CM_UpdateViewAngles( entvars_t *pev, const usercmd_t *cmd )
|
|||
}
|
||||
if( pev->teleport_time )
|
||||
{
|
||||
pev->v_angle[YAW] = SHORT2ANGLE( cmd->angles[YAW] - pev->delta_angles[YAW] );
|
||||
pev->v_angle[PITCH] = 0;
|
||||
pev->v_angle[ROLL] = 0;
|
||||
pev->viewangles[YAW] = SHORT2ANGLE( cmd->angles[YAW] - pev->delta_angles[YAW] );
|
||||
pev->viewangles[PITCH] = 0;
|
||||
pev->viewangles[ROLL] = 0;
|
||||
}
|
||||
|
||||
// circularly clamp the angles with deltas
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
temp = cmd->angles[i] + pev->delta_angles[i];
|
||||
pev->v_angle[i] = SHORT2ANGLE( temp );
|
||||
pev->viewangles[i] = SHORT2ANGLE( temp );
|
||||
}
|
||||
|
||||
// don't let the player look up or down more than 90 degrees
|
||||
if( pev->v_angle[PITCH] > 89 && pev->v_angle[PITCH] < 180 )
|
||||
pev->v_angle[PITCH] = 89;
|
||||
else if( pev->v_angle[PITCH] < 271 && pev->v_angle[PITCH] >= 180 )
|
||||
pev->v_angle[PITCH] = 271;
|
||||
if( pev->viewangles[PITCH] > 89 && pev->viewangles[PITCH] < 180 )
|
||||
pev->viewangles[PITCH] = 89;
|
||||
else if( pev->viewangles[PITCH] < 271 && pev->viewangles[PITCH] >= 180 )
|
||||
pev->viewangles[PITCH] = 271;
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ void CM_ServerMove( entvars_t *pmove, usercmd_t *cmd, physbody_t *body )
|
|||
pml.cmd = cmd;
|
||||
|
||||
CM_UpdateViewAngles( pmove, cmd );
|
||||
AngleVectors( pml.pev->v_angle, pml.forward, pml.right, pml.up );
|
||||
AngleVectors( pml.pev->viewangles, pml.forward, pml.right, pml.up );
|
||||
CM_CmdUpdateForce(); // get movement direction
|
||||
|
||||
// Get the current world timestep
|
||||
|
|
|
@ -168,7 +168,7 @@ typedef struct cl_enginefuncs_s
|
|||
// screen handlers
|
||||
HSPRITE (*pfnLoadShader)( const char *szShaderName );
|
||||
void (*pfnFillRGBA)( int x, int y, int width, int height, const float *color, float alpha );
|
||||
void (*pfnDrawImageExt)( HSPRITE shader, int x, int y, int w, int h, float s1, float t1, float s2, float t2 );
|
||||
void (*pfnDrawImageExt)( HSPRITE shader, float x, float y, float w, float h, float s1, float t1, float s2, float t2 );
|
||||
void (*pfnSetColor)( float r, float g, float b, float a );
|
||||
|
||||
// cvar handlers
|
||||
|
@ -198,7 +198,6 @@ typedef struct cl_enginefuncs_s
|
|||
|
||||
void (*pfnDrawCenterPrint)( void );
|
||||
void (*pfnCenterPrint)( const char *text, int y, int charWidth );
|
||||
int (*pfnDrawCharacter)( int x, int y, int width, int height, int number );
|
||||
void (*pfnDrawString)( int x, int y, int width, int height, const char *text );
|
||||
void (*pfnGetParms)( int *w, int *h, int *frames, int frame, shader_t shader );
|
||||
void (*pfnSetParms)( shader_t handle, kRenderMode_t rendermode, int frame );
|
||||
|
|
|
@ -9,134 +9,140 @@ typedef struct cl_priv_s cl_priv_t; // cl.engine private data
|
|||
typedef struct sv_priv_s sv_priv_t; // sv.engine private data
|
||||
typedef struct edict_s edict_t; // generic entity
|
||||
|
||||
// TODO: move to CBaseEntity all fields which doesn't existing on client side
|
||||
// TODO: generic edict must have all fields as valid on client side too
|
||||
// Legend:
|
||||
// ENG - engine can modify this variable for some reasons [only
|
||||
// NET - field that shared on client across network
|
||||
// Modifiers:
|
||||
// [player] - all notify for this field is valid only for client entity
|
||||
// [all] - valid for all ents
|
||||
// [phys] - valid only for rigid bodies
|
||||
// [solid] - only for solid entities
|
||||
// [push] - only ents with SOLID_BSP and MOVETYPE_PUSH have affect on this field
|
||||
|
||||
typedef struct entvars_s
|
||||
{
|
||||
string_t classname;
|
||||
string_t globalname;
|
||||
edict_t *chain; // entity pointer when linked into a linked list
|
||||
string_t classname; // ENG [all], NET [all]
|
||||
string_t globalname; // global entity name transmitted across levels
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t angles; // model angles
|
||||
int modelindex;
|
||||
vec3_t oldorigin; // interpolated values
|
||||
vec3_t oldangles;
|
||||
|
||||
vec3_t m_pmatrix[3]; // rotational matrix
|
||||
vec3_t m_pcentre[3]; // physical centre of mass
|
||||
|
||||
vec3_t origin; // ENG [all], NET [all]
|
||||
vec3_t oldorigin; // ENG [all], NET [all]
|
||||
vec3_t velocity;
|
||||
vec3_t avelocity; // angular velocity (degrees per second)
|
||||
|
||||
vec3_t movedir;
|
||||
vec3_t force; // linear physical impulse vector
|
||||
vec3_t torque; // angular physical impulse vector
|
||||
|
||||
string_t model;
|
||||
string_t weaponmodel; // monster or player weaponmodel
|
||||
vec3_t angles; // ENG [all], NET [all]
|
||||
vec3_t oldangles; // ENG [all], NET [all]
|
||||
vec3_t avelocity; // angular velocity (degrees per second)
|
||||
vec3_t punchangle; // NET [player], auto-decaying view angle adjustment
|
||||
vec3_t viewangles; // NET [player], viewing angle (old name was v_angle)
|
||||
vec3_t delta_angles; // ENG [player], NET [player], viewangles - cmd.angles
|
||||
|
||||
vec3_t absmin; // bbox max translated to world coord
|
||||
vec3_t absmax; // bbox max translated to world coord
|
||||
vec3_t mins; // local bbox min
|
||||
vec3_t maxs; // local bbox max
|
||||
vec3_t size; // maxs - mins
|
||||
float mass; // physobject mass
|
||||
|
||||
float ltime;
|
||||
float nextthink;
|
||||
|
||||
int movetype;
|
||||
int solid;
|
||||
|
||||
int skin; //
|
||||
int body; // sub-model selection for studiomodels
|
||||
int effects;
|
||||
float gravity; // % of "normal" gravity
|
||||
float friction; // inverse elasticity of MOVETYPE_BOUNCE
|
||||
|
||||
int sequence; // animation sequence
|
||||
float frame; // % playback position in animation sequences (0..255)
|
||||
float animtime; // world time when frame was set
|
||||
float framerate; // animation playback rate (-8x to 8x)
|
||||
vec3_t attachment[16]; // server-client attachment actual coords
|
||||
float controller[16]; // bone controller setting (0..255)
|
||||
float blending[16]; // blending amount between sub-sequences (0..255)
|
||||
|
||||
float scale; // model rendering scale (0..255)
|
||||
int waterlevel;
|
||||
int watertype;
|
||||
int contents;
|
||||
|
||||
float idealpitch;
|
||||
int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity
|
||||
float ideal_pitch;
|
||||
float pitch_speed;
|
||||
float ideal_yaw;
|
||||
float yaw_speed;
|
||||
|
||||
int rendermode;
|
||||
float renderamt;
|
||||
vec3_t rendercolor;
|
||||
int renderfx;
|
||||
int modelindex; // ENG [all], NET [all]
|
||||
|
||||
float health;
|
||||
string_t model; // model name
|
||||
string_t viewmodel; // player's viewmodel (no network updates)
|
||||
string_t weaponmodel; // NET [all] - sending weaponmodel index, not name
|
||||
|
||||
vec3_t absmin; // ENG [all] - pfnSetAbsBox passed to modify this values
|
||||
vec3_t absmax; // ENG [all] - pfnSetAbsBox passed to modify this values
|
||||
vec3_t mins; // ENG [all], NET [solid]
|
||||
vec3_t maxs; // ENG [all], NET [solid]
|
||||
vec3_t size; // ENG [all], restored on client-side from mins-maxs
|
||||
|
||||
// physic decsription
|
||||
vec3_t m_pmatrix[3]; // ENG [phys]
|
||||
vec3_t m_pcentre[3]; // ENG [phys]
|
||||
vec3_t force; // ENG [phys], linear physical impulse vector
|
||||
vec3_t torque; // ENG [phys], angular physical impulse vector
|
||||
float mass; // [phys], physobject mass
|
||||
|
||||
float ltime; // [push]
|
||||
float nextthink; // time to next call of think function
|
||||
|
||||
int movetype; // ENG [all], NET [all]
|
||||
int solid; // ENG [all], NET [all]
|
||||
|
||||
int skin; // NET [all]
|
||||
int body; // NET [all], sub-model selection for studiomodels
|
||||
int weaponbody; // NET [all], sub-model selection for weaponmodel
|
||||
int weaponskin; // NET [all],
|
||||
int effects; // ENG [all], NET [all]
|
||||
float gravity; // % of "normal" gravity
|
||||
float friction; // inverse elasticity of MOVETYPE_BOUNCE
|
||||
float speed;
|
||||
|
||||
int sequence; // ENG [all], NET [all], animation sequence
|
||||
int gaitsequence; // NET [player], movement animation sequence for player (0 for none)
|
||||
int weaponanim; // NET [all], weaponmodel animation sequencs
|
||||
float frame; // NET [all], % playback position in animation sequences (0..255)
|
||||
float animtime; // NET [all], world time when frame was set
|
||||
float framerate; // NET [all], animation playback rate (-8x to 8x)
|
||||
float controller[16]; // NET [all], bone controller setting (0..255)
|
||||
float blending[16]; // NET [all], blending amount between sub-sequences (0..255)
|
||||
vec3_t attachment[16]; // ENG [all], filled by engine on the client-side
|
||||
|
||||
float scale; // NET [all], sprites and models rendering scale (0..255)
|
||||
int rendermode; // NET [all]
|
||||
float renderamt; // NET [all]
|
||||
vec3_t rendercolor; // NET [all]
|
||||
int renderfx; // NET [all]
|
||||
|
||||
float fov; // NET [player], client fov, used instead m_iFov
|
||||
float health; // NET [player]
|
||||
float frags;
|
||||
int64 weapons; // bit mask for available weapons
|
||||
int64 weapons; // NET [player], bit mask for available weapons
|
||||
int64 items; // from Q1, can use for holdable items or user flags
|
||||
float takedamage;
|
||||
float maxspeed; // NET [player], uses to limit speed for current client
|
||||
|
||||
int deadflag;
|
||||
vec3_t view_ofs; // eye position
|
||||
vec3_t view_ofs; // NET [player], eye position
|
||||
|
||||
int button;
|
||||
int impulse;
|
||||
|
||||
|
||||
edict_t *chain; // linked list for EntitiesInPHS\PVS
|
||||
edict_t *dmg_inflictor;
|
||||
edict_t *enemy;
|
||||
edict_t *aiment; // entity pointer when MOVETYPE_FOLLOW
|
||||
edict_t *owner;
|
||||
edict_t *groundentity;
|
||||
edict_t *aiment; // NET [all], entity pointer when MOVETYPE_FOLLOW
|
||||
edict_t *owner; // NET [all]
|
||||
edict_t *groundentity; // NET [all], only if FL_ONGROUND is set
|
||||
|
||||
int spawnflags; // spwanflags are used only during level loading
|
||||
int flags; // generic flags that can be send to client
|
||||
|
||||
// player specific only
|
||||
vec3_t punchangle; // auto-decaying view angle adjustment
|
||||
vec3_t v_angle; // viewing angle (player only)
|
||||
vec3_t delta_angles; // viewangles - cmd.angles
|
||||
int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity
|
||||
string_t viewmodel; // player's viewmodel
|
||||
int gaitsequence; // movement animation sequence for player (0 for none)
|
||||
int64 flags; // generic flags that can be send to client
|
||||
|
||||
short colormap; // lowbyte topcolor, highbyte bottomcolor
|
||||
int playerclass;
|
||||
int team; // for teamplay
|
||||
int weaponanim;
|
||||
int team; // ENG [player], NET [player], for teamplay
|
||||
|
||||
float max_health;
|
||||
float teleport_time;
|
||||
float teleport_time; // ENG [all], NET [all], engine will be reset value on next frame
|
||||
int armortype;
|
||||
float armorvalue;
|
||||
int waterlevel; // ENG [all]
|
||||
int watertype; // ENG [all]
|
||||
int contents; // hl-coders: use this instead of pev->skin, to set entity contents
|
||||
|
||||
string_t target;
|
||||
string_t target; // various server strings
|
||||
string_t targetname;
|
||||
string_t netname;
|
||||
string_t message;
|
||||
|
||||
float dmg_take;
|
||||
float dmg_save;
|
||||
float dmgtime;
|
||||
float dmg;
|
||||
|
||||
string_t noise;
|
||||
string_t noise1;
|
||||
string_t noise2;
|
||||
string_t noise3;
|
||||
string_t ambient;
|
||||
|
||||
float speed;
|
||||
float air_finished;
|
||||
float pain_finished;
|
||||
float radsuit_finished;
|
||||
|
||||
edict_t *pContainingEntity; // ptr to class for consistency
|
||||
|
||||
float dmg_take;
|
||||
float dmg_save;
|
||||
float dmg;
|
||||
float dmgtime;
|
||||
|
||||
edict_t *pContainingEntity; // for upcasting. Filled by engine, don't save, don't modifiy
|
||||
} entvars_t;
|
||||
|
||||
struct edict_s
|
||||
|
|
|
@ -279,6 +279,8 @@ typedef enum _fieldtypes
|
|||
FIELD_MODELNAME, // engine string that is a model name (needs precache)
|
||||
FIELD_SOUNDNAME, // engine string that is a sound name (needs precache)
|
||||
FIELD_RANGE, // Min and Max range for generate random value
|
||||
FIELD_INTEGER64, // long integer
|
||||
FIELD_DOUBLE, // float with double precision
|
||||
|
||||
FIELD_TYPECOUNT, // MUST BE LAST
|
||||
} FIELDTYPE;
|
||||
|
|
|
@ -381,12 +381,7 @@ int R_StudioGetEvent( dstudioevent_t *pcurrent, float flStart, float flEnd, int
|
|||
if( pseqdesc->numevents == 0 || index > pseqdesc->numevents )
|
||||
return 0;
|
||||
|
||||
if( pseqdesc->numframes > 1 )
|
||||
{
|
||||
flStart *= (pseqdesc->numframes - 1) / 256.0;
|
||||
flEnd *= (pseqdesc->numframes - 1) / 256.0;
|
||||
}
|
||||
else
|
||||
if( pseqdesc->numframes == 1 )
|
||||
{
|
||||
flStart = 0;
|
||||
flEnd = 1.0;
|
||||
|
@ -938,7 +933,7 @@ StudioSetupBones
|
|||
|
||||
====================
|
||||
*/
|
||||
void R_StudioSetupBones( void )
|
||||
float R_StudioSetupBones( void )
|
||||
{
|
||||
int i;
|
||||
double f;
|
||||
|
@ -1061,7 +1056,7 @@ void R_StudioSetupBones( void )
|
|||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
{
|
||||
// g-cont. hey, what a hell ?
|
||||
if(!com.strcmp( pbones[i].name, "Bip01 Spine"))
|
||||
if( !com.strcmp( pbones[i].name, "Bip01 Spine" ))
|
||||
break;
|
||||
Mem_Copy( pos[i], pos2[i], sizeof( pos[i] ));
|
||||
Mem_Copy( q[i], q2[i], sizeof( q[i] ));
|
||||
|
@ -1085,6 +1080,7 @@ void R_StudioSetupBones( void )
|
|||
Matrix4x4_ConcatTransforms( m_plighttransform[i], m_plighttransform[pbones[i].parent], bonematrix );
|
||||
}
|
||||
}
|
||||
return (float)f;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1181,15 +1177,15 @@ void R_StudioCalcAttachments( void )
|
|||
int i;
|
||||
dstudioattachment_t *pattachment;
|
||||
|
||||
if ( m_pStudioHeader->numattachments > MAXSTUDIOATTACHMENTS )
|
||||
if( m_pStudioHeader->numattachments > MAXSTUDIOATTACHMENTS )
|
||||
{
|
||||
Msg("Warning: Too many attachments on %s\n", m_pCurrentEntity->model->name );
|
||||
m_pStudioHeader->numattachments = MAXSTUDIOATTACHMENTS; //reduce it
|
||||
MsgDev( D_WARN, "Too many attachments on %s\n", m_pCurrentEntity->model->name );
|
||||
m_pStudioHeader->numattachments = MAXSTUDIOATTACHMENTS; // reduce it
|
||||
}
|
||||
|
||||
// calculate attachment points
|
||||
pattachment = (dstudioattachment_t *)((byte *)m_pStudioHeader + m_pStudioHeader->attachmentindex);
|
||||
for (i = 0; i < m_pStudioHeader->numattachments; i++)
|
||||
for( i = 0; i < m_pStudioHeader->numattachments; i++ )
|
||||
{
|
||||
Matrix4x4_Transform( m_plighttransform[pattachment[i].bone], pattachment[i].org, m_pCurrentEntity->attachment[i] );
|
||||
}
|
||||
|
@ -1760,6 +1756,8 @@ StudioDrawModel
|
|||
*/
|
||||
bool R_StudioDrawModel( int pass, int flags )
|
||||
{
|
||||
float curframe;
|
||||
|
||||
//if( !mirror_render && m_pCurrentEntity->ent_type == ED_CLIENT )
|
||||
// return 0;
|
||||
|
||||
|
@ -1792,7 +1790,7 @@ bool R_StudioDrawModel( int pass, int flags )
|
|||
}
|
||||
else
|
||||
{
|
||||
R_StudioSetupBones();
|
||||
curframe = R_StudioSetupBones();
|
||||
}
|
||||
R_StudioSaveBones();
|
||||
|
||||
|
@ -1801,16 +1799,16 @@ bool R_StudioDrawModel( int pass, int flags )
|
|||
|
||||
if( flags & STUDIO_EVENTS )
|
||||
{
|
||||
float flStart = m_pCurrentEntity->frame + m_pCurrentEntity->framerate;
|
||||
float flEnd = m_pCurrentEntity->frame + m_pCurrentEntity->framerate * 1.5f;
|
||||
edict_t *ent = ri.GetClientEdict( m_pCurrentEntity->index );
|
||||
float flStart = curframe + m_pCurrentEntity->framerate;
|
||||
float flEnd = flStart + 0.4f;
|
||||
dstudioevent_t event;
|
||||
int index = 0;
|
||||
|
||||
|
||||
R_StudioCalcAttachments();
|
||||
Mem_Set( &event, 0, sizeof( event ));
|
||||
|
||||
// copy attachments into global entity array
|
||||
// copy attachments back to client entity
|
||||
Mem_Copy( ent->v.attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * MAXSTUDIOATTACHMENTS );
|
||||
while(( index = R_StudioGetEvent( &event, flStart, flEnd, index )) != 0 )
|
||||
{
|
||||
|
|
|
@ -110,63 +110,6 @@ public:
|
|||
CLASSIFY_EDICT( ENT( pev ), m_iClassType );
|
||||
}
|
||||
|
||||
// auto-classify edict on spawn
|
||||
virtual void ClassifyEdict( void )
|
||||
{
|
||||
// already classified ?
|
||||
if( m_iClassType != ED_SPAWNED ) return;
|
||||
|
||||
if( !strnicmp( "worldspawn", STRING( pev->classname ), 10 ))
|
||||
{
|
||||
SetObjectClass( ED_WORLDSPAWN );
|
||||
return;
|
||||
}
|
||||
|
||||
// first pass: determine type by explicit parms
|
||||
if( !strnicmp( "ambient_", STRING( pev->classname ), 8 ))
|
||||
{
|
||||
SetObjectClass( ED_AMBIENT );
|
||||
return;
|
||||
}
|
||||
else if( pev->solid == SOLID_TRIGGER )
|
||||
{
|
||||
if( pev->ambient ) SetObjectClass( ED_NORMAL );
|
||||
else SetObjectClass( ED_TRIGGER ); // never sending to client
|
||||
}
|
||||
else if( pev->movetype == MOVETYPE_PHYSIC )
|
||||
{
|
||||
SetObjectClass( ED_RIGIDBODY );
|
||||
}
|
||||
else if( pev->solid == SOLID_BSP || pev->origin == g_vecZero )
|
||||
{
|
||||
if( pev->movetype == MOVETYPE_CONVEYOR )
|
||||
SetObjectClass( ED_MOVER );
|
||||
else if( pev->flags & FL_WORLDBRUSH )
|
||||
SetObjectClass( ED_BSPBRUSH );
|
||||
else if( pev->movetype == MOVETYPE_PUSH )
|
||||
SetObjectClass( ED_MOVER );
|
||||
else if( pev->movetype == MOVETYPE_NONE )
|
||||
SetObjectClass( ED_BSPBRUSH );
|
||||
}
|
||||
else if( pev->flags & FL_MONSTER )
|
||||
SetObjectClass( ED_MONSTER );
|
||||
else if( pev->flags & FL_CLIENT )
|
||||
SetObjectClass( ED_CLIENT );
|
||||
else if( !pev->modelindex && !pev->weaponmodel )
|
||||
{
|
||||
if( pev->ambient ) SetObjectClass( ED_AMBIENT );
|
||||
else SetObjectClass( ED_STATIC ); // never sending to client
|
||||
}
|
||||
|
||||
// second pass: check sound and model indexes
|
||||
if( m_iClassType == ED_SPAWNED )
|
||||
{
|
||||
// mark as normal
|
||||
if( pev->modelindex || pev->ambient )
|
||||
SetObjectClass( ED_NORMAL );
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
|
||||
virtual void SetObjectCollisionBox( void );
|
||||
|
||||
|
|
|
@ -714,9 +714,9 @@ void CFuncTeleport :: Touch( CBaseEntity *pOther )
|
|||
|
||||
// set new angle to face
|
||||
pOther->pev->angles.y += ydiff;
|
||||
if (pOther->IsPlayer())
|
||||
if( pOther->IsPlayer())
|
||||
{
|
||||
pOther->pev->angles.x = pOther->pev->v_angle.x;
|
||||
pOther->pev->angles.x = pOther->pev->viewangles.x;
|
||||
pOther->pev->fixangle = TRUE;
|
||||
}
|
||||
|
||||
|
@ -743,24 +743,25 @@ void CFuncTeleport :: Touch( CBaseEntity *pOther )
|
|||
{
|
||||
Vector tmp = pTarget->pev->origin;
|
||||
|
||||
if ( pOther->IsPlayer()) tmp.z -= pOther->pev->mins.z; // make origin adjustments
|
||||
if( pOther->IsPlayer( ))
|
||||
tmp.z -= pOther->pev->mins.z; // make origin adjustments
|
||||
tmp.z++;
|
||||
UTIL_SetOrigin( pOther, tmp );
|
||||
|
||||
pOther->pev->angles = pTarget->pev->angles;
|
||||
pOther->pev->velocity = g_vecZero;
|
||||
if ( pOther->IsPlayer() )
|
||||
if( pOther->IsPlayer( ))
|
||||
{
|
||||
pOther->pev->v_angle = pTarget->pev->angles;
|
||||
pOther->pev->viewangles = pTarget->pev->angles;
|
||||
pOther->pev->fixangle = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeCamera( pev->target );//update PVS
|
||||
ChangeCamera( pev->target ); // update PVS
|
||||
pevToucher->flags &= ~FL_ONGROUND;
|
||||
pevToucher->fixangle = TRUE;
|
||||
|
||||
UTIL_FireTargets( pev->netname, pOther, this, USE_TOGGLE );//fire target
|
||||
UTIL_FireTargets( pev->netname, pOther, this, USE_TOGGLE ); // fire target
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
|
|
@ -390,12 +390,12 @@ void CEnvZoom::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
|
|||
if( m_iState == STATE_ON ) return;
|
||||
if( useType == USE_TOGGLE || useType == USE_ON ) SetFadeTime();
|
||||
else if( useType == USE_OFF )
|
||||
((CBasePlayer *)pActivator)->m_flFOV = CVAR_GET_FLOAT( "default_fov" );
|
||||
((CBasePlayer *)pActivator)->pev->fov = CVAR_GET_FLOAT( "default_fov" );
|
||||
else if( useType == USE_SHOWINFO )
|
||||
{
|
||||
DEBUGHEAD;
|
||||
ALERT( at_console, "State: %s, Fade time %.00f\n", GetStringForState( GetState()), pev->takedamage );
|
||||
ALERT( at_console, "Current FOV: %g, Final FOV: %g\n", ((CBasePlayer *)pActivator)->m_flFOV, pev->button );
|
||||
ALERT( at_console, "Current FOV: %g, Final FOV: %g\n", ((CBasePlayer *)pActivator)->pev->fov, pev->frags );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,14 +406,14 @@ void CEnvZoom::SetFadeTime( void )
|
|||
|
||||
if( pev->takedamage == 0 ) // instant apply fov
|
||||
{
|
||||
((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV = pev->frags;
|
||||
((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov = pev->frags;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV;
|
||||
CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov;
|
||||
if( CurFOV == 0.0f )
|
||||
CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV = CVAR_GET_FLOAT( "default_fov" );
|
||||
CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov = CVAR_GET_FLOAT( "default_fov" );
|
||||
|
||||
if( CurFOV > pev->frags ) Length = CurFOV - pev->frags;
|
||||
else if( CurFOV < pev->frags )
|
||||
|
@ -430,7 +430,7 @@ void CEnvZoom::SetFadeTime( void )
|
|||
|
||||
void CEnvZoom::Think( void )
|
||||
{
|
||||
if( Q_rint(((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV ) == Q_rint( pev->frags ))
|
||||
if( Q_rint(((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov ) == Q_rint( pev->frags ))
|
||||
{
|
||||
// time is expired
|
||||
SetThink( NULL );
|
||||
|
@ -442,8 +442,8 @@ void CEnvZoom::Think( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( pev->body ) ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV += gpGlobals->frametime;
|
||||
else ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV -= gpGlobals->frametime;
|
||||
if( pev->body ) ((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov += 0.5f;
|
||||
else ((CBasePlayer *)(CBaseEntity *)m_hActivator)->pev->fov -= 0.5f;
|
||||
}
|
||||
m_iState = STATE_ON;
|
||||
SetNextThink ( pev->health );
|
||||
|
@ -628,7 +628,7 @@ void CSprite::Think( void )
|
|||
{
|
||||
SetNextThink( 0 );
|
||||
|
||||
if( pev->spawnflags & SF_TEMPSPRITE && gpGlobals->time > pev->pain_finished ) UTIL_Remove(this);
|
||||
if( pev->spawnflags & SF_TEMPSPRITE && gpGlobals->time > pev->dmg_take ) UTIL_Remove(this);
|
||||
else if( pev->framerate ) Animate( pev->framerate * (gpGlobals->time - pev->dmgtime) );
|
||||
|
||||
Move();
|
||||
|
@ -1763,7 +1763,7 @@ CBaseEntity *CEnvShooter :: CreateGib ( Vector vecPos, Vector vecVel )
|
|||
if (pShot->pev->framerate && pShot->Frames() > 1.0)
|
||||
{
|
||||
pShot->AnimateAndDie( 10 );
|
||||
pShot->pev->pain_finished = gpGlobals->time + pev->health;
|
||||
pShot->pev->dmg_take = gpGlobals->time + pev->health;
|
||||
pShot->SetNextThink( 0 );
|
||||
pShot->pev->dmgtime = gpGlobals->time;
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ void CLaserSpot::Update( CBasePlayer *m_pPlayer )
|
|||
{
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->viewangles );
|
||||
UTIL_TraceLine( m_pPlayer->GetGunPosition(), m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 8192, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr );
|
||||
UTIL_SetOrigin( this, tr.vecEndPos + tr.vecPlaneNormal * 10 );
|
||||
|
||||
|
@ -266,7 +266,8 @@ void CLaserSpot::Update( CBasePlayer *m_pPlayer )
|
|||
int brightness = (1 / log( SpotDistance / 0.3 )) * 1300;
|
||||
pev->scale = SpotDistance / 2500 + RANDOM_FLOAT( 0.01, SpotDistance / 2750 );
|
||||
|
||||
if(pev->renderamt >= 255) pev->renderamt = brightness + RANDOM_LONG(1, SpotDistance/400);
|
||||
if( pev->renderamt >= 255 )
|
||||
pev->renderamt = brightness + RANDOM_LONG( 1, SpotDistance / 400 );
|
||||
else pev->renderamt += 5;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -750,11 +750,11 @@ void CWHRocket :: FollowThink( void )
|
|||
|
||||
if(pev->button)//controllable rocket
|
||||
{
|
||||
UTIL_MakeVectorsPrivate( m_pPlayer->pev->v_angle, forward, NULL, NULL );
|
||||
UTIL_MakeVectorsPrivate( m_pPlayer->pev->viewangles, forward, NULL, NULL );
|
||||
|
||||
angles = m_pPlayer->pev->v_angle;
|
||||
angles = m_pPlayer->pev->viewangles;
|
||||
angles[0] = 0 - angles[0];
|
||||
float steer = WARHEAD_MAX_SPEED / pev->speed;//steer factor
|
||||
float steer = WARHEAD_MAX_SPEED / pev->speed; // steer factor
|
||||
|
||||
angles.x = m_Center.x + UTIL_AngleDistance( angles.x, m_Center.x );
|
||||
angles.y = m_Center.y + UTIL_AngleDistance( angles.y, m_Center.y );
|
||||
|
@ -770,9 +770,9 @@ void CWHRocket :: FollowThink( void )
|
|||
pev->avelocity.z = distY * -steer + distZ * steer;
|
||||
|
||||
pev->velocity = forward * pev->speed + pev->avelocity;
|
||||
if(m_pLauncher && m_pLauncher->m_iOnControl == 2)
|
||||
if( m_pLauncher && m_pLauncher->m_iOnControl == 2 )
|
||||
{
|
||||
Detonate();//check for himself destroy
|
||||
Detonate(); // check for himself destroy
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
{
|
||||
SetBits( pev->spawnflags, SF_TEMPSPRITE );
|
||||
pev->framerate = framerate;
|
||||
pev->pain_finished = gpGlobals->time + (Frames() / framerate);
|
||||
pev->dmg_take = gpGlobals->time + (Frames() / framerate);
|
||||
SetNextThink( 0 );
|
||||
}
|
||||
static CSprite *SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
|
||||
|
|
|
@ -447,13 +447,14 @@ void CFuncTank::TrackTarget( void )
|
|||
pController->pev->viewmodel = 0;
|
||||
SetNextThink(0.05);
|
||||
|
||||
if (pev->spawnflags & SF_TANK_MATCHTARGET)
|
||||
if( pev->spawnflags & SF_TANK_MATCHTARGET )
|
||||
{
|
||||
// "Match target" mode:
|
||||
// first, get the player's angles
|
||||
angles = pController->pev->v_angle;
|
||||
// Work out what point the player is looking at
|
||||
UTIL_MakeVectorsPrivate(angles, direction, NULL, NULL);
|
||||
angles = pController->pev->viewangles;
|
||||
|
||||
// work out what point the player is looking at
|
||||
UTIL_MakeVectorsPrivate( angles, direction, NULL, NULL );
|
||||
|
||||
targetPosition = pController->EyePosition() + direction * 1000;
|
||||
|
||||
|
@ -483,11 +484,11 @@ void CFuncTank::TrackTarget( void )
|
|||
{
|
||||
// "Match angles" mode
|
||||
// just get the player's angles
|
||||
angles = pController->pev->v_angle;
|
||||
angles = pController->pev->viewangles;
|
||||
angles[0] = 0 - angles[0];
|
||||
|
||||
UpdateSpot();
|
||||
SetNextThink(0.05);//G-Cont.For more smoothing motion a laser spot
|
||||
SetNextThink( 0.05 ); // g-cont. for more smoothing motion a laser spot
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1082,7 +1082,7 @@ void CTriggerHurt :: Touch ( CBaseEntity *pOther )
|
|||
{
|
||||
if ( pev->dmgtime > gpGlobals->time )
|
||||
{
|
||||
if ( gpGlobals->time != pev->pain_finished )
|
||||
if ( gpGlobals->time != pev->dmg_take )
|
||||
{
|
||||
// too early to hurt again, and not same frame with a different entity
|
||||
if ( pOther->IsPlayer() )
|
||||
|
@ -1104,14 +1104,14 @@ void CTriggerHurt :: Touch ( CBaseEntity *pOther )
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) return;
|
||||
else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->dmg_take ) return;
|
||||
|
||||
fldmg = pev->dmg * 0.5; // 0.5 seconds worth of damage, pev->dmg is damage/second
|
||||
|
||||
if ( fldmg < 0 ) pOther->TakeHealth( -fldmg, pev->button );
|
||||
else pOther->TakeDamage( pev, pev, fldmg, pev->button );
|
||||
|
||||
pev->pain_finished = gpGlobals->time;
|
||||
pev->dmg_take = gpGlobals->time;
|
||||
pev->dmgtime = gpGlobals->time + 0.5;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) Shambler Team 2004
|
||||
// util_.cpp - utility entities: util_fade,
|
||||
// util_shake, util_fov etc
|
||||
// util_shake, util_changehud etc
|
||||
//=======================================================================
|
||||
|
||||
#include "extdll.h"
|
||||
|
|
|
@ -1376,22 +1376,22 @@ int CBasePlayerWeapon :: Launch ( const char *ammo, int type )
|
|||
if ( !stricmp( ammo, "m203" ))
|
||||
{
|
||||
// we don't add in player velocity anymore.
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle );
|
||||
CGrenade::ShootContact( m_pPlayer->pev, m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16, gpGlobals->v_forward * 800 );
|
||||
}
|
||||
else if( !stricmp( ammo, "rockets" ))
|
||||
{
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->viewangles );
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8;
|
||||
|
||||
CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );// RpgRocket::Create stomps on globals, so remake.
|
||||
CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->viewangles );// RpgRocket::Create stomps on globals, so remake.
|
||||
pRocket->pev->velocity = pRocket->pev->velocity + gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward );
|
||||
}
|
||||
else if( !stricmp( ammo, "bolts" ))
|
||||
{
|
||||
// we don't add in player velocity anymore.
|
||||
Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle;
|
||||
UTIL_MakeVectors( anglesAim );
|
||||
|
||||
anglesAim.x = -anglesAim.x;
|
||||
|
@ -1404,13 +1404,13 @@ int CBasePlayerWeapon :: Launch ( const char *ammo, int type )
|
|||
}
|
||||
else if( !stricmp( ammo, "nuke" ))
|
||||
{
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
|
||||
UTIL_MakeVectors( m_pPlayer->pev->viewangles );
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 125 + gpGlobals->v_up * 2;
|
||||
CWHRocket *pRocket = CWHRocket::Create ( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this, type );
|
||||
CWHRocket *pRocket = CWHRocket::Create ( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this, type );
|
||||
}
|
||||
else if( !stricmp( ammo, "grenade" ))
|
||||
{
|
||||
Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle;
|
||||
Vector angThrow = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle;
|
||||
|
||||
if ( angThrow.x < 0 ) angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 );
|
||||
else angThrow.x = -10 + angThrow.x * ( ( 90 + 10 ) / 90.0 );
|
||||
|
@ -1460,7 +1460,7 @@ int CBasePlayerWeapon::Swing( int fFirst )
|
|||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3;
|
||||
|
||||
UTIL_MakeVectors (m_pPlayer->pev->v_angle);
|
||||
UTIL_MakeVectors (m_pPlayer->pev->viewangles);
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition( );
|
||||
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;
|
||||
|
||||
|
@ -1583,15 +1583,15 @@ void CBasePlayerWeapon::ZoomUpdate( void )
|
|||
}
|
||||
if( m_iZoom == 1 )
|
||||
{
|
||||
m_pPlayer->m_flFOV = 50.0f;
|
||||
m_pPlayer->pev->fov = 50.0f;
|
||||
m_pPlayer->pev->viewmodel = NULL;
|
||||
m_iZoom = 2; // ready to zooming, wait for 0.8 secs
|
||||
}
|
||||
if( m_iZoom == 2 && m_pPlayer->m_flFOV > MAX_ZOOM )
|
||||
if( m_iZoom == 2 && m_pPlayer->pev->fov > MAX_ZOOM )
|
||||
{
|
||||
if( m_flTimeUpdate < UTIL_WeaponTimeBase( ))
|
||||
{
|
||||
m_pPlayer->m_flFOV -= 1.2;//gpGlobals->frametime;
|
||||
m_pPlayer->pev->fov -= 1.2; // gpGlobals->frametime;
|
||||
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.002;
|
||||
}
|
||||
}
|
||||
|
@ -1611,7 +1611,7 @@ void CBasePlayerWeapon::ZoomReset( void )
|
|||
{
|
||||
m_pPlayer->pev->viewmodel = iViewModel();
|
||||
m_flHoldTime = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_pPlayer->m_flFOV = 90;
|
||||
m_pPlayer->pev->fov = 90;
|
||||
m_iZoom = 0; // clear zoom
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsg.ZoomHUD, NULL, m_pPlayer->pev );
|
||||
WRITE_BYTE( m_iZoom );
|
||||
|
@ -1850,7 +1850,7 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer )
|
|||
}
|
||||
|
||||
// if the ammo, state, or fov has changed, update the weapon
|
||||
if( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_flFOV != pPlayer->m_flClientFOV )
|
||||
if( m_iClip != m_iClientClip || state != m_iClientWeaponState )
|
||||
{
|
||||
bSend = TRUE;
|
||||
}
|
||||
|
|
|
@ -61,19 +61,17 @@ edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
|||
{
|
||||
edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer );
|
||||
|
||||
pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1);
|
||||
pPlayer->pev->v_angle = g_vecZero;
|
||||
pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector( 0, 0, 1 );
|
||||
pPlayer->pev->viewangles = g_vecZero;
|
||||
pPlayer->pev->velocity = g_vecZero;
|
||||
pPlayer->pev->angles = VARS(pentSpawnSpot)->angles;
|
||||
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
|
||||
pPlayer->pev->punchangle = g_vecZero;
|
||||
pPlayer->pev->fixangle = TRUE;
|
||||
|
||||
//LRC
|
||||
if (pentSpawnSpot->v.spawnflags & 1) // the START WITH SUIT flag
|
||||
if( pentSpawnSpot->v.spawnflags & 1 ) // the START WITH SUIT flag
|
||||
{
|
||||
g_startSuit = TRUE;
|
||||
}
|
||||
|
||||
return pentSpawnSpot;
|
||||
}
|
||||
|
||||
|
|
|
@ -449,19 +449,19 @@ void ClientCommand( edict_t *pEntity )
|
|||
ALERT(at_console, "Syntax: hud_color RRR GGG BBB\n");
|
||||
}
|
||||
}
|
||||
else if ( FStrEq(pcmd, "fire") ) //LRC - trigger entities manually
|
||||
else if( FStrEq( pcmd, "fire" )) //LRC - trigger entities manually
|
||||
{
|
||||
if (g_flWeaponCheat)
|
||||
if( g_flWeaponCheat )
|
||||
{
|
||||
CBaseEntity *pPlayer = CBaseEntity::Instance(pEntity);
|
||||
if (CMD_ARGC() > 1)
|
||||
if( CMD_ARGC() > 1 )
|
||||
{
|
||||
UTIL_FireTargets(CMD_ARGV(1), pPlayer, pPlayer, USE_TOGGLE);
|
||||
UTIL_FireTargets( CMD_ARGV( 1 ), pPlayer, pPlayer, USE_TOGGLE );
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_MakeVectors(pev->v_angle);
|
||||
UTIL_MakeVectors( pev->viewangles );
|
||||
UTIL_TraceLine(
|
||||
pev->origin + pev->view_ofs,
|
||||
pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000,
|
||||
|
@ -480,20 +480,19 @@ void ClientCommand( edict_t *pEntity )
|
|||
}
|
||||
}
|
||||
}
|
||||
else if ( FStrEq(pcmd, "debug") )
|
||||
else if( FStrEq( pcmd, "debug" ))
|
||||
{
|
||||
Msg("debug called\n" );
|
||||
if (g_flWeaponCheat)
|
||||
if( g_flWeaponCheat )
|
||||
{
|
||||
CBaseEntity *pPlayer = CBaseEntity::Instance(pEntity);
|
||||
if (CMD_ARGC() > 1)
|
||||
CBaseEntity *pPlayer = CBaseEntity::Instance( pEntity );
|
||||
if( CMD_ARGC() > 1 )
|
||||
{
|
||||
UTIL_FireTargets(CMD_ARGV(1), pPlayer, pPlayer, USE_SHOWINFO);
|
||||
UTIL_FireTargets( CMD_ARGV( 1 ), pPlayer, pPlayer, USE_SHOWINFO );
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_MakeVectors(pev->v_angle);
|
||||
UTIL_MakeVectors( pev->viewangles );
|
||||
UTIL_TraceLine(
|
||||
pev->origin + pev->view_ofs,
|
||||
pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000,
|
||||
|
@ -554,11 +553,11 @@ void ClientCommand( edict_t *pEntity )
|
|||
{
|
||||
if( g_flWeaponCheat && CMD_ARGC() > 1 )
|
||||
{
|
||||
GetClassPtr((CBasePlayer *)pev)->m_flFOV = atof( CMD_ARGV( 1 ));
|
||||
GetClassPtr((CBasePlayer *)pev)->pev->fov = atof( CMD_ARGV( 1 ));
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "\"fov\" is \"%g\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_flFOV ) );
|
||||
ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "\"fov\" is \"%g\"\n", (int)GetClassPtr((CBasePlayer *)pev)->pev->fov ));
|
||||
}
|
||||
}
|
||||
else if ( FStrEq(pcmd, "use" ) )
|
||||
|
@ -870,7 +869,6 @@ void ServerPostActivate( void )
|
|||
if( pClass && !( pClass->pev->flags & FL_DORMANT ))
|
||||
{
|
||||
pClass->PostActivate();
|
||||
pClass->ClassifyEdict();
|
||||
}
|
||||
}
|
||||
MSGSended = TRUE;//messages sucessfully sended
|
||||
|
@ -1045,7 +1043,6 @@ void LinkUserMessages( void )
|
|||
gmsg.RoomType = REG_USER_MSG( "RoomType", 2 );
|
||||
gmsg.HideWeapon = REG_USER_MSG( "HideWeapon", 1 );
|
||||
gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 );
|
||||
gmsg.SetFOV = REG_USER_MSG( "SetFOV", 4 );
|
||||
gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 );
|
||||
gmsg.Shake = REG_USER_MSG("ScreenShake", 13 );
|
||||
gmsg.Fade = REG_USER_MSG("ScreenFade", sizeof(ScreenFade));
|
||||
|
|
|
@ -92,7 +92,6 @@ typedef struct user_messages_s
|
|||
int WeaponAnim;
|
||||
int RoomType;
|
||||
int SayText;
|
||||
int SetFOV;
|
||||
int ShowMenu;
|
||||
int GeigerRange;
|
||||
int TeamNames;
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
#include "gamerules.h"
|
||||
#include "client.h"
|
||||
|
||||
#define ENTVARS_COUNT (sizeof(gEntvarsDescription)/sizeof(gEntvarsDescription[0]))
|
||||
#define ENTVARS_COUNT ( sizeof(gEntvarsDescription) / sizeof(gEntvarsDescription[0]) )
|
||||
CGlobalState gGlobalState;
|
||||
|
||||
TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
TYPEDESCRIPTION gEntvarsDescription[] =
|
||||
{
|
||||
DEFINE_ENTITY_FIELD( classname, FIELD_STRING ),
|
||||
DEFINE_ENTITY_GLOBAL_FIELD( globalname, FIELD_STRING ),
|
||||
|
@ -31,9 +31,9 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( fixangle, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( ideal_pitch, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ),
|
||||
|
@ -78,7 +78,7 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
|
||||
DEFINE_ENTITY_FIELD( health, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( frags, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( weapons, FIELD_INTEGER ),
|
||||
DEFINE_ENTITY_FIELD( weapons, FIELD_INTEGER64 ),
|
||||
DEFINE_ENTITY_FIELD( takedamage, FIELD_FLOAT ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( deadflag, FIELD_FLOAT ),
|
||||
|
@ -94,7 +94,7 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
DEFINE_ENTITY_FIELD( groundentity, FIELD_EDICT ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( spawnflags, FIELD_INTEGER ),
|
||||
DEFINE_ENTITY_FIELD( flags, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( flags, FIELD_INTEGER64 ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( colormap, FIELD_INTEGER ),
|
||||
DEFINE_ENTITY_FIELD( team, FIELD_INTEGER ),
|
||||
|
@ -116,15 +116,13 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
DEFINE_ENTITY_FIELD( dmg_save, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( dmg, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( dmgtime, FIELD_TIME ),
|
||||
DEFINE_ENTITY_FIELD( fov, FIELD_FLOAT ),
|
||||
|
||||
DEFINE_ENTITY_FIELD( noise, FIELD_SOUNDNAME ),
|
||||
DEFINE_ENTITY_FIELD( noise1, FIELD_SOUNDNAME ),
|
||||
DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ),
|
||||
DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ),
|
||||
DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ),
|
||||
DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ),
|
||||
DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ),
|
||||
DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ),
|
||||
};
|
||||
|
||||
|
||||
|
@ -344,12 +342,20 @@ void CSave :: WriteInt( const char *pname, const int *data, int count )
|
|||
BufferField( pname, sizeof(int) * count, (const char *)data );
|
||||
}
|
||||
|
||||
void CSave :: WriteInt64( const char *pname, const int64 *data, int count )
|
||||
{
|
||||
BufferField( pname, sizeof(int64) * count, (const char *)data );
|
||||
}
|
||||
|
||||
void CSave :: WriteFloat( const char *pname, const float *data, int count )
|
||||
{
|
||||
BufferField( pname, sizeof(float) * count, (const char *)data );
|
||||
}
|
||||
|
||||
void CSave :: WriteDouble( const char *pname, const double *data, int count )
|
||||
{
|
||||
BufferField( pname, sizeof( double ) * count, (const char *)data );
|
||||
}
|
||||
|
||||
void CSave :: WriteTime( const char *pname, const float *data, int count )
|
||||
{
|
||||
|
@ -363,11 +369,10 @@ void CSave :: WriteTime( const char *pname, const float *data, int count )
|
|||
|
||||
// Always encode time as a delta from the current time so it can be re-based if loaded in a new level
|
||||
// Times of 0 are never written to the file, so they will be restored as 0, not a relative time
|
||||
if ( m_pdata )
|
||||
tmp -= m_pdata->time;
|
||||
if( m_pdata ) tmp -= m_pdata->time;
|
||||
|
||||
BufferData( (const char *)&tmp, sizeof(float) );
|
||||
data ++;
|
||||
BufferData( (const char *)&tmp, sizeof( float ));
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,11 +506,15 @@ void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd )
|
|||
case FIELD_FLOAT:
|
||||
(*(float *)((char *)pev + pField->fieldOffset)) = atof( pkvd->szValue );
|
||||
break;
|
||||
|
||||
case FIELD_DOUBLE:
|
||||
(*(double *)((char *)pev + pField->fieldOffset)) = atof( pkvd->szValue );
|
||||
break;
|
||||
case FIELD_INTEGER:
|
||||
(*(int *)((char *)pev + pField->fieldOffset)) = atoi( pkvd->szValue );
|
||||
break;
|
||||
|
||||
case FIELD_INTEGER64:
|
||||
(*(int64 *)((char *)pev + pField->fieldOffset)) = _atoi64( pkvd->szValue );
|
||||
break;
|
||||
case FIELD_POSITION_VECTOR:
|
||||
case FIELD_VECTOR:
|
||||
UTIL_StringToVector( (float *)((char *)pev + pField->fieldOffset), pkvd->szValue );
|
||||
|
@ -572,77 +581,80 @@ int CSave :: WriteFields( const char *cname, const char *pname, void *pBaseData,
|
|||
{
|
||||
case FIELD_FLOAT:
|
||||
WriteFloat( pTest->fieldName, (float *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_DOUBLE:
|
||||
WriteDouble( pTest->fieldName, (double *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
case FIELD_TIME:
|
||||
WriteTime( pTest->fieldName, (float *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_MODELNAME:
|
||||
case FIELD_SOUNDNAME:
|
||||
case FIELD_STRING:
|
||||
WriteString( pTest->fieldName, (int *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_CLASSPTR:
|
||||
case FIELD_EVARS:
|
||||
case FIELD_EDICT:
|
||||
case FIELD_ENTITY:
|
||||
case FIELD_EHANDLE:
|
||||
if ( pTest->fieldSize > MAX_ENTITYARRAY )
|
||||
if( pTest->fieldSize > MAX_ENTITYARRAY )
|
||||
ALERT( at_error, "Can't save more than %d entities in an array!!!\n", MAX_ENTITYARRAY );
|
||||
for ( j = 0; j < pTest->fieldSize; j++ )
|
||||
for( j = 0; j < pTest->fieldSize; j++ )
|
||||
{
|
||||
switch( pTest->fieldType )
|
||||
{
|
||||
case FIELD_EVARS:
|
||||
entityArray[j] = EntityIndex( ((entvars_t **)pOutputData)[j] );
|
||||
case FIELD_EVARS:
|
||||
entityArray[j] = EntityIndex( ((entvars_t **)pOutputData)[j] );
|
||||
break;
|
||||
case FIELD_CLASSPTR:
|
||||
entityArray[j] = EntityIndex( ((CBaseEntity **)pOutputData)[j] );
|
||||
case FIELD_CLASSPTR:
|
||||
entityArray[j] = EntityIndex( ((CBaseEntity **)pOutputData)[j] );
|
||||
break;
|
||||
case FIELD_EDICT:
|
||||
entityArray[j] = EntityIndex( ((edict_t **)pOutputData)[j] );
|
||||
case FIELD_EDICT:
|
||||
entityArray[j] = EntityIndex( ((edict_t **)pOutputData)[j] );
|
||||
break;
|
||||
case FIELD_ENTITY:
|
||||
entityArray[j] = EntityIndex( ((EOFFSET *)pOutputData)[j] );
|
||||
case FIELD_ENTITY:
|
||||
entityArray[j] = EntityIndex( ((EOFFSET *)pOutputData)[j] );
|
||||
break;
|
||||
case FIELD_EHANDLE:
|
||||
entityArray[j] = EntityIndex( (CBaseEntity *)(((EHANDLE *)pOutputData)[j]) );
|
||||
case FIELD_EHANDLE:
|
||||
entityArray[j] = EntityIndex( (CBaseEntity *)(((EHANDLE *)pOutputData)[j]) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
WriteInt( pTest->fieldName, entityArray, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_POSITION_VECTOR:
|
||||
WritePositionVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_VECTOR:
|
||||
WriteVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_RANGE:
|
||||
WriteRange( pTest->fieldName, (float *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
case FIELD_BOOLEAN:
|
||||
case FIELD_INTEGER:
|
||||
WriteInt( pTest->fieldName, (int *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_INTEGER64:
|
||||
WriteInt64( pTest->fieldName, (int64 *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
case FIELD_SHORT:
|
||||
WriteData( pTest->fieldName, 2 * pTest->fieldSize, ((char *)pOutputData) );
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_CHARACTER:
|
||||
WriteData( pTest->fieldName, pTest->fieldSize, ((char *)pOutputData) );
|
||||
break;
|
||||
|
||||
break;
|
||||
// For now, just write the address out, we're not going to change memory while doing this yet!
|
||||
case FIELD_POINTER:
|
||||
WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_FUNCTION:
|
||||
WriteFunction( cname, pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
ALERT( at_error, "Bad field type\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -748,26 +760,29 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
|
|||
{
|
||||
case FIELD_TIME:
|
||||
timeData = *(float *)pInputData;
|
||||
// Re-base time variables
|
||||
// re-base time variables
|
||||
timeData += time;
|
||||
*((float *)pOutputData) = timeData;
|
||||
break;
|
||||
break;
|
||||
case FIELD_FLOAT:
|
||||
*((float *)pOutputData) = *(float *)pInputData;
|
||||
break;
|
||||
break;
|
||||
case FIELD_DOUBLE:
|
||||
*((double *)pOutputData) = *(double *)pInputData;
|
||||
break;
|
||||
case FIELD_MODELNAME:
|
||||
case FIELD_SOUNDNAME:
|
||||
case FIELD_STRING:
|
||||
// Skip over j strings
|
||||
// skip over j strings
|
||||
pString = (char *)pData;
|
||||
for ( stringCount = 0; stringCount < j; stringCount++ )
|
||||
{
|
||||
while (*pString)
|
||||
while( *pString )
|
||||
pString++;
|
||||
pString++;
|
||||
}
|
||||
pInputData = pString;
|
||||
if ( strlen( (char *)pInputData ) == 0 )
|
||||
if( strlen((char *)pInputData ) == 0 )
|
||||
*((int *)pOutputData) = 0;
|
||||
else
|
||||
{
|
||||
|
@ -785,15 +800,13 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
|
|||
UTIL_PrecacheSound( string );
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case FIELD_EVARS:
|
||||
entityIndex = *( int *)pInputData;
|
||||
pent = EntityFromIndex( entityIndex );
|
||||
if ( pent )
|
||||
*((entvars_t **)pOutputData) = VARS(pent);
|
||||
else
|
||||
*((entvars_t **)pOutputData) = NULL;
|
||||
break;
|
||||
if ( pent ) *((entvars_t **)pOutputData) = VARS(pent);
|
||||
else *((entvars_t **)pOutputData) = NULL;
|
||||
break;
|
||||
case FIELD_CLASSPTR:
|
||||
entityIndex = *( int *)pInputData;
|
||||
pent = EntityFromIndex( entityIndex );
|
||||
|
@ -804,12 +817,12 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
|
|||
*((CBaseEntity **)pOutputData) = NULL;
|
||||
if (entityIndex != -1) ALERT(at_console, "## Restore: invalid entitynum %d\n", entityIndex);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case FIELD_EDICT:
|
||||
entityIndex = *( int *)pInputData;
|
||||
pent = EntityFromIndex( entityIndex );
|
||||
*((edict_t **)pOutputData) = pent;
|
||||
break;
|
||||
break;
|
||||
case FIELD_EHANDLE:
|
||||
// Input and Output sizes are different!
|
||||
pOutputData = (char *)pOutputData + j*(sizeof(EHANDLE) - gSizes[pTest->fieldType]);
|
||||
|
@ -819,7 +832,7 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
|
|||
*((EHANDLE *)pOutputData) = CBaseEntity::Instance(pent);
|
||||
else
|
||||
*((EHANDLE *)pOutputData) = NULL;
|
||||
break;
|
||||
break;
|
||||
case FIELD_ENTITY:
|
||||
entityIndex = *( int *)pInputData;
|
||||
pent = EntityFromIndex( entityIndex );
|
||||
|
@ -827,47 +840,46 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
|
|||
*((EOFFSET *)pOutputData) = OFFSET(pent);
|
||||
else
|
||||
*((EOFFSET *)pOutputData) = 0;
|
||||
break;
|
||||
break;
|
||||
case FIELD_RANGE:
|
||||
((float *)pOutputData)[0] = ((float *)pInputData)[0];
|
||||
((float *)pOutputData)[1] = ((float *)pInputData)[1];
|
||||
break;
|
||||
break;
|
||||
case FIELD_VECTOR:
|
||||
((float *)pOutputData)[0] = ((float *)pInputData)[0];
|
||||
((float *)pOutputData)[1] = ((float *)pInputData)[1];
|
||||
((float *)pOutputData)[2] = ((float *)pInputData)[2];
|
||||
break;
|
||||
break;
|
||||
case FIELD_POSITION_VECTOR:
|
||||
((float *)pOutputData)[0] = ((float *)pInputData)[0] + position.x;
|
||||
((float *)pOutputData)[1] = ((float *)pInputData)[1] + position.y;
|
||||
((float *)pOutputData)[2] = ((float *)pInputData)[2] + position.z;
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_BOOLEAN:
|
||||
case FIELD_INTEGER:
|
||||
*((int *)pOutputData) = *( int *)pInputData;
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_INTEGER64:
|
||||
*((int64 *)pOutputData) = *( int64 *)pInputData;
|
||||
break;
|
||||
case FIELD_SHORT:
|
||||
*((short *)pOutputData) = *( short *)pInputData;
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_CHARACTER:
|
||||
*((char *)pOutputData) = *( char *)pInputData;
|
||||
break;
|
||||
|
||||
break;
|
||||
case FIELD_POINTER:
|
||||
*((int *)pOutputData) = *( int *)pInputData;
|
||||
break;
|
||||
break;
|
||||
case FIELD_FUNCTION:
|
||||
if ( strlen( (char *)pInputData ) == 0 )
|
||||
*((int *)pOutputData) = 0;
|
||||
else
|
||||
*((int *)pOutputData) = FUNCTION_FROM_NAME( (char *)pInputData );
|
||||
break;
|
||||
|
||||
break;
|
||||
default:
|
||||
ALERT( at_error, "Bad field type\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@ public:
|
|||
|
||||
void WriteShort( const char *pname, const short *value, int count );
|
||||
void WriteInt( const char *pname, const int *value, int count ); // Save an int
|
||||
void WriteInt64( const char *pname, const int64 *value, int count ); // Save an int64
|
||||
void WriteFloat( const char *pname, const float *value, int count ); // Save a float
|
||||
void WriteDouble( const char *pname, const double *value, int count ); // Save a double
|
||||
void WriteTime( const char *pname, const float *value, int count ); // Save a float (timevalue)
|
||||
void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block
|
||||
void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string
|
||||
|
|
|
@ -500,9 +500,9 @@ CBaseEntity *UTIL_FindEntityForward( CBaseEntity *pMe )
|
|||
{
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_MakeVectors(pMe->pev->v_angle);
|
||||
UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192,dont_ignore_monsters, pMe->edict(), &tr );
|
||||
if ( tr.flFraction != 1.0 && !FNullEnt( tr.pHit) )
|
||||
UTIL_MakeVectors( pMe->pev->viewangles );
|
||||
UTIL_TraceLine( pMe->pev->origin + pMe->pev->view_ofs, pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192, dont_ignore_monsters, pMe->edict(), &tr );
|
||||
if( tr.flFraction != 1.0 && !FNullEnt( tr.pHit ))
|
||||
{
|
||||
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
|
||||
return pHit;
|
||||
|
@ -2731,18 +2731,18 @@ BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//LRC - moved here from barney.cpp
|
||||
BOOL UTIL_IsFacing( entvars_t *pevTest, const Vector &reference )
|
||||
{
|
||||
Vector vecDir = (reference - pevTest->origin);
|
||||
vecDir.z = 0;
|
||||
vecDir = vecDir.Normalize();
|
||||
Vector forward, angle;
|
||||
angle = pevTest->v_angle;
|
||||
angle = pevTest->viewangles;
|
||||
angle.x = 0;
|
||||
|
||||
UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL );
|
||||
// He's facing me, he meant it
|
||||
if ( DotProduct( forward, vecDir ) > 0.96 ) // +/- 15 degrees or so
|
||||
if( DotProduct( forward, vecDir ) > 0.96 ) // +/- 15 degrees or so
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,8 @@ extern BOOL FNullEnt(entvars_t* pev);
|
|||
extern BOOL FNullEnt( CBaseEntity *ent );
|
||||
|
||||
// Testing strings for nullity
|
||||
// g-cont. radnomize hull nullity yep!
|
||||
// and Doom3 colloisation
|
||||
#define iStringNull 0
|
||||
inline BOOL FStringNull(int iString) { return iString == iStringNull; }
|
||||
inline BOOL FStringNull(Vector vString) { return vString == Vector(0,0,0); }
|
||||
|
@ -216,9 +218,9 @@ inline BOOL FStringNull(Vector vString) { return vString == Vector(0,0,0); }
|
|||
|
||||
// Dot products for view cone checking
|
||||
#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees
|
||||
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
|
||||
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
|
||||
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
|
||||
#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks
|
||||
#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks
|
||||
#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks
|
||||
|
||||
// All monsters need this data
|
||||
#define DONT_BLEED -1
|
||||
|
|
|
@ -549,25 +549,6 @@ void CBarney :: TalkInit()
|
|||
m_voicePitch = 100;
|
||||
}
|
||||
|
||||
|
||||
static BOOL IsFacing( entvars_t *pevTest, const Vector &reference )
|
||||
{
|
||||
Vector vecDir = (reference - pevTest->origin);
|
||||
vecDir.z = 0;
|
||||
vecDir = vecDir.Normalize();
|
||||
Vector forward, angle;
|
||||
angle = pevTest->v_angle;
|
||||
angle.x = 0;
|
||||
UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL );
|
||||
// He's facing me, he meant it
|
||||
if ( DotProduct( forward, vecDir ) > 0.96 ) // +/- 15 degrees or so
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int CBarney :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType)
|
||||
{
|
||||
// make sure friends talk about it if player hurts talkmonsters...
|
||||
|
@ -584,10 +565,10 @@ int CBarney :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
|
|||
|
||||
// This is a heurstic to determine if the player intended to harm me
|
||||
// If I have an enemy, we can't establish intent (may just be crossfire)
|
||||
if ( m_hEnemy == NULL )
|
||||
if( m_hEnemy == NULL )
|
||||
{
|
||||
// If the player was facing directly at me, or I'm already suspicious, get mad
|
||||
if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || IsFacing( pevAttacker, pev->origin ) )
|
||||
if(( m_afMemory & bits_MEMORY_SUSPICIOUS) || UTIL_IsFacing( pevAttacker, pev->origin ))
|
||||
{
|
||||
// Alright, now I'm pissed!
|
||||
if (m_iszSpeakAs)
|
||||
|
|
|
@ -91,6 +91,8 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
|
|||
DEFINE_FIELD( CBasePlayer, m_flDuckTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBasePlayer, m_flWallJumpTime, FIELD_TIME ),
|
||||
|
||||
DEFINE_FIELD( CBasePlayer, m_fAirFinished, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBasePlayer, m_fPainFinished, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBasePlayer, m_flSuitUpdate, FIELD_TIME ),
|
||||
DEFINE_ARRAY( CBasePlayer, m_rgSuitPlayList, FIELD_INTEGER, CSUITPLAYLIST ),
|
||||
DEFINE_FIELD( CBasePlayer, m_iSuitPlayNext, FIELD_INTEGER ),
|
||||
|
@ -123,7 +125,6 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
|
|||
DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ), // NB: this points to a CFuncTank*Controls* now. --LRC
|
||||
DEFINE_FIELD( CBasePlayer, m_pMonitor, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CBasePlayer, m_flFOV, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( CBasePlayer, pViewEnt, FIELD_CLASSPTR),
|
||||
DEFINE_FIELD( CBasePlayer, viewFlags, FIELD_INTEGER),
|
||||
DEFINE_FIELD( CBasePlayer, m_iSndRoomtype, FIELD_INTEGER ),
|
||||
|
@ -897,20 +898,16 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib )
|
|||
MESSAGE_END();
|
||||
|
||||
// reset FOV
|
||||
m_flFOV = m_flClientFOV = 90.0f;
|
||||
pev->fov = 90.0f;
|
||||
|
||||
pViewEnt = 0;
|
||||
viewFlags = 0;
|
||||
viewNeedsUpdate = 1;
|
||||
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsg.SetFOV, NULL, pev );
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
|
||||
//death fading
|
||||
m_FadeColor = Vector(128, 0, 0);
|
||||
// death fading
|
||||
m_FadeColor = Vector( 128, 0, 0 );
|
||||
m_FadeAlpha = 240;
|
||||
m_iFadeFlags = FFADE_OUT | FFADE_MODULATE | FFADE_STAYOUT;
|
||||
m_iFadeFlags = FFADE_OUT|FFADE_MODULATE|FFADE_STAYOUT;
|
||||
m_iFadeTime = 6;
|
||||
fadeNeedsUpdate = TRUE;
|
||||
|
||||
|
@ -1131,12 +1128,12 @@ void CBasePlayer::WaterMove()
|
|||
// not underwater
|
||||
|
||||
// play 'up for air' sound
|
||||
if (pev->air_finished < gpGlobals->time)
|
||||
if (m_fAirFinished < gpGlobals->time)
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM);
|
||||
else if (pev->air_finished < gpGlobals->time + 9)
|
||||
else if (m_fAirFinished < gpGlobals->time + 9)
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM);
|
||||
|
||||
pev->air_finished = gpGlobals->time + AIRTIME;
|
||||
m_fAirFinished = gpGlobals->time + AIRTIME;
|
||||
pev->dmg = 2;
|
||||
|
||||
// if we took drowning damage, give it back slowly
|
||||
|
@ -1161,16 +1158,16 @@ void CBasePlayer::WaterMove()
|
|||
m_bitsDamageType &= ~DMG_DROWNRECOVER;
|
||||
m_rgbTimeBasedDamage[itbd_DrownRecover] = 0;
|
||||
|
||||
if (pev->air_finished < gpGlobals->time) // drown!
|
||||
if (m_fAirFinished < gpGlobals->time) // drown!
|
||||
{
|
||||
if (pev->pain_finished < gpGlobals->time)
|
||||
if (m_fPainFinished < gpGlobals->time)
|
||||
{
|
||||
// take drowning damage
|
||||
pev->dmg += 1;
|
||||
if (pev->dmg > 5)
|
||||
pev->dmg = 5;
|
||||
TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN);
|
||||
pev->pain_finished = gpGlobals->time + 1;
|
||||
m_fPainFinished = gpGlobals->time + 1;
|
||||
|
||||
// track drowning damage, give it back when
|
||||
// player finally takes a breath
|
||||
|
@ -1204,7 +1201,7 @@ void CBasePlayer::WaterMove()
|
|||
|
||||
// make bubbles
|
||||
|
||||
air = (int)(pev->air_finished - gpGlobals->time);
|
||||
air = (int)(m_fAirFinished - gpGlobals->time);
|
||||
if (!RANDOM_LONG(0,0x1f) && RANDOM_LONG(0,AIRTIME-1) >= air)
|
||||
{
|
||||
switch (RANDOM_LONG(0,3))
|
||||
|
@ -1414,7 +1411,7 @@ void CBasePlayer::StartDeathCam( void )
|
|||
}
|
||||
|
||||
CopyToBodyQue( pev );
|
||||
StartObserver( pSpot->pev->origin, pSpot->pev->v_angle );
|
||||
StartObserver( pSpot->pev->origin, pSpot->pev->viewangles );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1432,7 +1429,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle )
|
|||
m_afPhysicsFlags |= PFLAG_OBSERVER;
|
||||
|
||||
pev->view_ofs = g_vecZero;
|
||||
pev->angles = pev->v_angle = vecViewAngle;
|
||||
pev->angles = pev->viewangles = vecViewAngle;
|
||||
pev->fixangle = TRUE;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
|
@ -1501,7 +1498,7 @@ void CBasePlayer::PlayerUse ( void )
|
|||
TraceResult tr;
|
||||
int caps;
|
||||
|
||||
UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing
|
||||
UTIL_MakeVectors ( pev->viewangles );// so we know which way we are facing
|
||||
|
||||
//LRC- try to get an exact entity to use.
|
||||
// (is this causing "use-buttons-through-walls" problems? Surely not!)
|
||||
|
@ -1837,7 +1834,7 @@ void CBasePlayer::UpdateStatusBar()
|
|||
|
||||
// Find an ID Target
|
||||
TraceResult tr;
|
||||
UTIL_MakeVectors( pev->v_angle + pev->punchangle );
|
||||
UTIL_MakeVectors( pev->viewangles + pev->punchangle );
|
||||
Vector vecSrc = EyePosition();
|
||||
Vector vecEnd = vecSrc + (gpGlobals->v_forward * MAX_ID_RANGE);
|
||||
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr);
|
||||
|
@ -2279,7 +2276,7 @@ void CBasePlayer::PreThink(void)
|
|||
if ( g_fGameOver )
|
||||
return; // intermission or finale
|
||||
|
||||
UTIL_MakeVectors(pev->v_angle); // is this still used?
|
||||
UTIL_MakeVectors(pev->viewangles); // is this still used?
|
||||
|
||||
ItemPreFrame( );
|
||||
WaterMove();
|
||||
|
@ -3247,7 +3244,7 @@ void CBasePlayer::Spawn( void )
|
|||
pev->movetype = MOVETYPE_WALK;
|
||||
pev->max_health = pev->health;
|
||||
pev->flags = FL_CLIENT;
|
||||
pev->air_finished = gpGlobals->time + 12;
|
||||
m_fAirFinished = gpGlobals->time + 12;
|
||||
pev->dmg = 2; // initial water damage
|
||||
pev->effects = 0;
|
||||
pev->deadflag = DEAD_NO;
|
||||
|
@ -3276,8 +3273,7 @@ void CBasePlayer::Spawn( void )
|
|||
Rain_nextFadeUpdate = 0;
|
||||
GiveOnlyAmmo = FALSE;
|
||||
|
||||
m_flFOV = 90.0f;// init field of view.
|
||||
m_flClientFOV = -1; // make sure fov reset is sent
|
||||
pev->fov = 90.0f; // init field of view.
|
||||
//m_iAcessLevel = 2;
|
||||
|
||||
m_flNextDecalTime = 0; // let this player decal as soon as he spawns.
|
||||
|
@ -3428,8 +3424,8 @@ int CBasePlayer::Restore( CRestore &restore )
|
|||
pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1);
|
||||
pev->angles = VARS(pentSpawnSpot)->angles;
|
||||
}
|
||||
pev->v_angle.z = 0; // Clear out roll
|
||||
pev->angles = pev->v_angle;
|
||||
pev->viewangles.z = 0; // Clear out roll
|
||||
pev->angles = pev->viewangles;
|
||||
|
||||
pev->fixangle = TRUE; // turn this way immediately
|
||||
|
||||
|
@ -3614,7 +3610,7 @@ public:
|
|||
void CSprayCan::Spawn ( entvars_t *pevOwner )
|
||||
{
|
||||
pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 );
|
||||
pev->angles = pevOwner->v_angle;
|
||||
pev->angles = pevOwner->viewangles;
|
||||
pev->owner = ENT(pevOwner);
|
||||
pev->frame = 0;
|
||||
|
||||
|
@ -3670,7 +3666,7 @@ public:
|
|||
void CBloodSplat::Spawn ( entvars_t *pevOwner )
|
||||
{
|
||||
pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 );
|
||||
pev->angles = pevOwner->v_angle;
|
||||
pev->angles = pevOwner->viewangles;
|
||||
pev->owner = ENT(pevOwner);
|
||||
|
||||
SetThink(&CBloodSplat:: Spray );
|
||||
|
@ -3829,7 +3825,7 @@ void CBasePlayer::ImpulseCommands( )
|
|||
case 201: // paint decal
|
||||
if( gpGlobals->time < m_flNextDecalTime ) break;
|
||||
|
||||
UTIL_MakeVectors(pev->v_angle);
|
||||
UTIL_MakeVectors(pev->viewangles);
|
||||
UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr);
|
||||
|
||||
if ( tr.flFraction != 1.0 )
|
||||
|
@ -4250,16 +4246,7 @@ void CBasePlayer :: UpdateClientData( void )
|
|||
m_iClientHideHUD = m_iHideHUD;
|
||||
}
|
||||
|
||||
if ( m_flFOV != m_flClientFOV )
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsg.SetFOV, NULL, pev );
|
||||
WRITE_FLOAT( m_flFOV );
|
||||
MESSAGE_END();
|
||||
|
||||
// cache FOV change at end of function, so weapon updates can see that FOV has changed
|
||||
}
|
||||
|
||||
if (viewNeedsUpdate != 0)
|
||||
if( viewNeedsUpdate != 0 )
|
||||
{
|
||||
int indexToSend;
|
||||
|
||||
|
@ -4635,7 +4622,6 @@ void CBasePlayer :: UpdateClientData( void )
|
|||
|
||||
// Cache and client weapon change
|
||||
m_pClientActiveItem = m_pActiveItem;
|
||||
m_flClientFOV = m_flFOV;
|
||||
|
||||
// update Status Bar
|
||||
if( m_flNextSBarUpdateTime < gpGlobals->time )
|
||||
|
@ -4784,7 +4770,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta )
|
|||
|
||||
// ALERT( at_console, "%f %f\n", angles.x, angles.y );
|
||||
|
||||
UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim );
|
||||
UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim );
|
||||
return gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
|
@ -4804,7 +4790,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD
|
|||
return g_vecZero;
|
||||
}
|
||||
|
||||
UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim );
|
||||
UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim );
|
||||
|
||||
// try all possible entities
|
||||
bestdir = gpGlobals->v_forward;
|
||||
|
@ -4899,7 +4885,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD
|
|||
{
|
||||
bestdir = UTIL_VecToAngles (bestdir);
|
||||
bestdir.x = -bestdir.x;
|
||||
bestdir = bestdir - pev->v_angle - pev->punchangle;
|
||||
bestdir = bestdir - pev->viewangles - pev->punchangle;
|
||||
|
||||
if (bestent->v.takedamage == DAMAGE_AIM)
|
||||
m_fOnTarget = TRUE;
|
||||
|
|
|
@ -159,9 +159,11 @@ public:
|
|||
int m_iTrain; // Train control position
|
||||
BOOL m_fWeapon; // Set this to FALSE to force a reset of the current weapon HUD info
|
||||
|
||||
EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank
|
||||
EHANDLE m_pMonitor;
|
||||
float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink())
|
||||
EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank
|
||||
EHANDLE m_pMonitor;
|
||||
float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink())
|
||||
float m_fAirFinished; // moved here from progdefs.h
|
||||
float m_fPainFinished; // moved here from progdefs.h
|
||||
|
||||
BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true.
|
||||
BOOL m_fLongJump; // does this player have the longjump module?
|
||||
|
@ -172,8 +174,6 @@ public:
|
|||
int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new
|
||||
int m_iHideHUD; // the players hud weapon info is to be hidden
|
||||
int m_iClientHideHUD;
|
||||
float m_flFOV; // field of view
|
||||
float m_flClientFOV; // client's known FOV
|
||||
|
||||
// usable player items
|
||||
CBasePlayerWeapon *m_rgpPlayerItems[MAX_ITEM_TYPES];
|
||||
|
|
|
@ -271,7 +271,7 @@ void CBaseTurret::Spawn()
|
|||
|
||||
if (m_iOrientation == 1)
|
||||
{
|
||||
pev->idealpitch = 180;
|
||||
pev->ideal_pitch = 180;
|
||||
pev->angles.x = 180;
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ void CBaseTurret::Initialize(void)
|
|||
m_flStartYaw = pev->angles.y;
|
||||
if (m_iOrientation == 1)
|
||||
{
|
||||
// pev->idealpitch = 180; //This is moved to CBaseTurret::Spawn for fix old bug in original HL. G-Cont.
|
||||
// pev->ideal_pitch = 180; //This is moved to CBaseTurret::Spawn for fix old bug in original HL. G-Cont.
|
||||
// pev->angles.x = 180;
|
||||
pev->view_ofs.z = -pev->view_ofs.z;
|
||||
pev->effects |= EF_INVLIGHT;
|
||||
|
|
6
todo.log
6
todo.log
|
@ -41,10 +41,12 @@ Beta 13.12.08
|
|||
20.render custom models OK
|
||||
21.zoom_hud and warhead hud OK
|
||||
22.entity_state_t revision 4 OK
|
||||
23.entvars_t revision 1
|
||||
23.entvars_t revision 1 OK
|
||||
24.UpdateClientData - move call to cl_input.c OK
|
||||
25.wrote HUD_StudioEvents
|
||||
25.wrote HUD_StudioEvents OK
|
||||
16.register cmd->buttons OK
|
||||
17.pfnSetKeyDest in client.dll
|
||||
18.IMPLEMENT SAVERESTORE
|
||||
|
||||
|
||||
Ñïèñîê äîñòóïíûõ ðåíäåðåðîâ: ×òî â íèõ èíòåðåñíîãî
|
||||
|
|
Reference in New Issue