07 Jan 2009

This commit is contained in:
g-cont 2009-01-07 00:00:00 +03:00 committed by Alibek Omarov
parent 427370f67f
commit 9a4b42440d
56 changed files with 462 additions and 4785 deletions

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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; }

View File

@ -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();
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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 );

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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++ )

View File

@ -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,

View File

@ -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 );
}

View File

@ -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;

View File

@ -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
};

View File

@ -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

View File

@ -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 )

View File

@ -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;
}
/*

View File

@ -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;
}
/*

View File

@ -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;

View File

@ -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 );
}

View File

@ -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 ));
}

View File

@ -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 )
{

View File

@ -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

View File

@ -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 );

View File

@ -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

View File

@ -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;

View File

@ -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 )
{

View File

@ -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 );

View File

@ -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
}
//=======================================================================

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 )

View File

@ -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

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));

View File

@ -92,7 +92,6 @@ typedef struct user_messages_s
int WeaponAnim;
int RoomType;
int SayText;
int SetFOV;
int ShowMenu;
int GeigerRange;
int TeamNames;

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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
Ñïèñîê äîñòóïíûõ ðåíäåðåðîâ: ×òî â íèõ èíòåðåñíîãî