09 Jul 2010

This commit is contained in:
g-cont 2010-07-09 00:00:00 +04:00 committed by Alibek Omarov
parent 9f9228adc4
commit a9a5a22d06
190 changed files with 1251 additions and 79132 deletions

View File

@ -10,7 +10,7 @@ backup.lst
backup.bat
release.bat
launchers.bat
todo.log
change.log
baserc\
bshift\
@ -42,7 +42,6 @@ server\game\
server\global\
server\monsters\
spirit\
snd_al\
snd_dx\
vid_gl\
xtools\

View File

@ -18,7 +18,7 @@
#include "extdll.h"
#include "const.h"
#include "studio_ref.h"
#include "studio.h"
#include "util.h"
#include "activitymap.h"
@ -33,15 +33,15 @@
int ExtractBbox( void *pmodel, int sequence, Vector &mins, Vector &maxs )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return 0;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
mins[0] = pseqdesc[ sequence ].bbmin[0];
mins[1] = pseqdesc[ sequence ].bbmin[1];
@ -57,15 +57,15 @@ int ExtractBbox( void *pmodel, int sequence, Vector &mins, Vector &maxs )
int LookupActivity( void *pmodel, entvars_t *pev, int activity )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return 0;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
int weighttotal = 0;
int seq = ACTIVITY_NOT_AVAILABLE;
@ -85,15 +85,15 @@ int LookupActivity( void *pmodel, entvars_t *pev, int activity )
int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if ( !pstudiohdr )
return 0;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
int weight = 0;
int seq = ACTIVITY_NOT_AVAILABLE;
@ -114,9 +114,9 @@ int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity )
void GetEyePosition ( void *pmodel, Vector &vecEyePosition )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if ( !pstudiohdr )
{
@ -129,15 +129,15 @@ void GetEyePosition ( void *pmodel, Vector &vecEyePosition )
int LookupSequence( void *pmodel, const char *label )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return 0;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
for (int i = 0; i < pstudiohdr->numseq; i++)
{
@ -162,17 +162,17 @@ void SequencePrecache( void *pmodel, const char *pSequenceName )
int index = LookupSequence( pmodel, pSequenceName );
if ( index >= 0 )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if ( !pstudiohdr || index >= pstudiohdr->numseq )
return;
dstudioseqdesc_t *pseqdesc;
dstudioevent_t *pevent;
mstudioseqdesc_t *pseqdesc;
mstudioevent_t *pevent;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + index;
pevent = (dstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + index;
pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex);
for (int i = 0; i < pseqdesc->numevents; i++)
{
@ -199,13 +199,13 @@ void SequencePrecache( void *pmodel, const char *pSequenceName )
void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
if (pev->sequence >= pstudiohdr->numseq)
{
@ -214,7 +214,7 @@ void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *
return;
}
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
if (pseqdesc->numframes > 1)
{
@ -232,14 +232,14 @@ void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *
int GetSequenceFlags( void *pmodel, entvars_t *pev )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq )
return 0;
dstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
return pseqdesc->flags;
}
@ -247,19 +247,19 @@ int GetSequenceFlags( void *pmodel, entvars_t *pev )
int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq || !pMonsterEvent )
return 0;
int events = 0;
dstudioseqdesc_t *pseqdesc;
dstudioevent_t *pevent;
mstudioseqdesc_t *pseqdesc;
mstudioevent_t *pevent;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
pevent = (dstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex);
if (pseqdesc->numevents == 0 || index > pseqdesc->numevents )
return 0;
@ -294,13 +294,13 @@ int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEve
float SetController( void *pmodel, entvars_t *pev, int iController, float flValue )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return flValue;
dstudiobonecontroller_t *pbonecontroller = (dstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex);
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex);
// find first controller that matches the index
for (int i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
@ -348,15 +348,15 @@ float SetController( void *pmodel, entvars_t *pev, int iController, float flValu
float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return flValue;
dstudioseqdesc_t *pseqdesc;
mstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence;
if (pseqdesc->blendtype[iBlender] == 0)
return flValue;
@ -392,14 +392,14 @@ float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue )
int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return iGoalAnim;
dstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
// bail if we're going to or from a node 0
if (pseqdesc[iEndingAnim].entrynode == 0 || pseqdesc[iGoalAnim].entrynode == 0)
@ -459,16 +459,16 @@ int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir )
void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return;
if (iGroup > pstudiohdr->numbodyparts)
return;
dstudiobodyparts_t *pbodypart = (dstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup;
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup;
if (iValue >= pbodypart->nummodels)
return;
@ -481,16 +481,16 @@ void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue )
int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup )
{
dstudiohdr_t *pstudiohdr;
studiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t *)pmodel;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
return 0;
if (iGroup > pstudiohdr->numbodyparts)
return 0;
dstudiobodyparts_t *pbodypart = (dstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup;
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup;
if (pbodypart->nummodels <= 1)
return 0;

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /GB /MD /W3 /GX /O2 /I "..\bshift" /I "..\common" /I "..\game_shared" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\bshift" /I "..\common" /I "..\game_shared" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /Fr /YX
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32

View File

@ -46,7 +46,7 @@ CBaseEntity
#include "saverestore.h"
#include "schedule.h"
#include "studio_ref.h"
#include "studio.h"
#ifndef MONSTEREVENT_H
#include "monsterevent.h"

View File

@ -3133,6 +3133,17 @@ int CBasePlayer::Restore( CRestore &restore )
UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX);
}
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "hl", "1" );
if ( m_fLongJump )
{
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "slj", "1" );
}
else
{
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "slj", "0" );
}
RenewItems();
return status;

14
change.log Normal file
View File

@ -0,0 +1,14 @@
build ????
SoundLib: ogg loop points (LOOP_START comment)
Client: recalc fov y for more matched with original HL
build 1249
ImageLib: added support for 4-bits and monochrome uncompressed BMPs.
ImageLib: fix data align for NPOT textures in menu (e.g. slider.bmp).
StdLib: skip empty symbols in numerical string for atoi and atof.
Render: implement LoadSprite for custom client sprites (e.g. hud)
Sound: fixed bug with background music looping
Fonts: implement Half-Life creditfonts
Client: move client.dll to valve folder

View File

@ -61,8 +61,8 @@ TargetDir=\Xash3D\src_main\temp\client\!release
InputPath=\Xash3D\src_main\temp\client\!release\client.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetDir)\client.dll "D:\Xash3D\bin\client.dll"
"D:\Xash3D\valve\bin\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetDir)\client.dll "D:\Xash3D\valve\bin\client.dll"
# End Custom Build
@ -101,8 +101,8 @@ TargetDir=\Xash3D\src_main\temp\client\!debug
InputPath=\Xash3D\src_main\temp\client\!debug\client.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetDir)\client.dll "D:\Xash3D\bin\client.dll"
"D:\Xash3D\valve\bin\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetDir)\client.dll "D:\Xash3D\valve\bin\client.dll"
# End Custom Build
@ -213,14 +213,6 @@ SOURCE=.\hud\hud_train.cpp
# End Source File
# Begin Source File
SOURCE=.\hud\hud_warhead.cpp
# End Source File
# Begin Source File
SOURCE=.\hud\hud_zoom.cpp
# End Source File
# Begin Source File
SOURCE=.\global\input.cpp
# End Source File
# Begin Source File

View File

@ -6,7 +6,7 @@
#include "extdll.h"
#include "utils.h"
#include "ref_params.h"
#include "studio_ref.h"
#include "studio.h"
#include "hud.h"
#include "aurora.h"
#include "r_particle.h"
@ -165,18 +165,15 @@ int HUD_Redraw( float flTime, int state )
{
switch( state )
{
case CL_LOADING:
DrawProgressBar();
break;
case CL_ACTIVE:
gHUD.Redraw( flTime );
break;
case CL_PAUSED:
gHUD.Redraw( flTime );
DrawPause();
break;
case CL_LOADING:
// called while map is loading
break;
case CL_CHANGELEVEL:
DrawImageBar( 100, "m_loading" );
// called once when changelevel in-action
break;
}
return 1;
@ -342,6 +339,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
// g-cont. moved here because we may needs apply null scale to skyportal
if( ent->v.scale == 0.0f && ent->v.skin >= 0 ) ent->v.scale = 1.0f;
if( ent->v.scale >= 100.0f ) ent->v.scale = 1.0f; // original HL issues
ent->v.pContainingEntity = ent;
}

View File

@ -12,6 +12,7 @@
#define FREE( x ) (*g_engfuncs.pfnMemFree)( x, __FILE__, __LINE__ )
// screen handlers
#define SPR_GetList (*g_engfuncs.pfnSPR_GetList)
#define SPR_Frames (*g_engfuncs.pfnSPR_Frames)
#define SPR_Width (*g_engfuncs.pfnSPR_Width)
#define SPR_Height (*g_engfuncs.pfnSPR_Height)

View File

@ -33,7 +33,7 @@ void EV_DrawBeam ( void )
//======================
// Eject Shell
//======================
void EV_EjectShell( const dstudioevent_t *event, edict_t *entity )
void EV_EjectShell( const mstudioevent_t *event, edict_t *entity )
{
vec3_t view_ofs, ShellOrigin, ShellVelocity, forward, right, up;
vec3_t origin = entity->v.origin;
@ -67,7 +67,7 @@ void EV_EjectShell( const dstudioevent_t *event, edict_t *entity )
EV_EjectBrass ( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL );
}
void HUD_StudioEvent( const dstudioevent_t *event, edict_t *entity )
void HUD_StudioEvent( const mstudioevent_t *event, edict_t *entity )
{
float pitch;
Vector pos;

View File

@ -213,131 +213,6 @@ void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, int hullNumb
g_engfuncs.pfnTraceModel( vecStart, vecEnd, pentModel, ptr );
}
/*
==============================================================================
HUD-SPRITES PARSING
==============================================================================
*/
/*
====================
ParseHudSprite
====================
*/
void ParseHudSprite( const char **pfile, char *psz, client_sprite_t *result )
{
int x = 0, y = 0, width = 0, height = 0;
client_sprite_t p;
int section = 0;
char *token;
memset( &p, 0, sizeof( client_sprite_t ));
while(( token = COM_ParseToken( pfile )) != NULL )
{
if( !stricmp( token, psz ))
{
token = COM_ParseToken( pfile );
if( !stricmp( token, "{" )) section = 1;
}
if( section ) // parse section
{
if( !stricmp( token, "}" )) break; // end section
if( !stricmp( token, "file" ))
{
token = COM_ParseToken( pfile );
strncpy( p.szSprite, token, 64 );
// fill structure at default
p.hSprite = SPR_Load( p.szSprite );
width = SPR_Width( p.hSprite, 0 );
height = SPR_Height( p.hSprite, 0 );
x = y = 0;
}
else if ( !stricmp( token, "name" ))
{
token = COM_ParseToken( pfile );
strncpy( p.szName, token, 64 );
}
else if ( !stricmp( token, "x" ))
{
token = COM_ParseToken( pfile );
x = atoi( token );
}
else if ( !stricmp( token, "y" ))
{
token = COM_ParseToken( pfile );
y = atoi( token );
}
else if ( !stricmp( token, "width" ))
{
token = COM_ParseToken( pfile );
width = atoi( token );
}
else if ( !stricmp( token, "height" ))
{
token = COM_ParseToken( pfile );
height = atoi( token );
}
}
}
if( !section ) return; // data not found
// calculate sprite position
p.rc.left = x;
p.rc.right = x + width;
p.rc.top = y;
p.rc.bottom = y + height;
memcpy( result, &p, sizeof( client_sprite_t ));
}
client_sprite_t *SPR_GetList( const char *psz, int *piCount )
{
char *pfile = (char *)LOAD_FILE( psz, NULL );
int iSprCount = 0;
if( !pfile )
{
*piCount = iSprCount;
return NULL;
}
char *token;
const char *plist = pfile;
int depth = 0;
while(( token = COM_ParseToken( &plist )) != NULL ) // calculate count of sprites
{
if( !stricmp( token, "{" )) depth++;
else if( !stricmp( token, "}" )) depth--;
else if( depth == 0 && !strcmp( token, "hudsprite" ))
iSprCount++;
}
client_sprite_t *phud;
plist = pfile;
phud = new client_sprite_t[iSprCount];
if( depth != 0 ) ALERT( at_console, "%s EOF without closing brace\n", psz );
for( int i = 0; i < iSprCount; i++ ) //parse structures
{
ParseHudSprite( &plist, "hudsprite", &phud[i] );
}
if( !iSprCount ) ALERT( at_console, "SPR_GetList: %s doesn't have sprites\n", psz );
FREE_FILE( pfile );
*piCount = iSprCount;
return phud;
}
/*
==============================================================================
@ -345,16 +220,6 @@ client_sprite_t *SPR_GetList( const char *psz, int *piCount )
==============================================================================
*/
void Draw_VidInit( void )
{
}
void DrawPause( void )
{
// pause image
DrawImageBar( 100, "m_pause" ); // HACKHACK
}
void DrawImageBar( float percent, const char *szSpriteName )
{
int m_loading = gHUD.GetSpriteIndex( szSpriteName );
@ -383,18 +248,6 @@ void DrawImageBar( float percent, const char *szSpriteName, int x, int y )
SPR_DrawAdditive( 0, x, y, &rcBar ); // progress bar
}
//
// 27/12/08 moved here from cl_view.c
//
void DrawProgressBar( void )
{
if( !gHUD.m_iDrawPlaque ) return;
DrawImageBar( CVAR_GET_FLOAT( "scr_loading" ), "m_loading" );
if( !CVAR_GET_FLOAT( "scr_download" )) return;
DrawImageBar( CVAR_GET_FLOAT( "scr_download" ), "m_download", (ScreenWidth - 128)>>1, ScreenHeight - 60 );
}
void AngleMatrix( const vec3_t angles, float (*matrix)[4] )
{
float angle;
@ -592,7 +445,7 @@ void RotatePointAroundVector( Vector &dst, const Vector &dir, const Vector &poin
float angle, c, s, d;
Vector vr, vu, vf;
angle = degrees * (M_PI / 180.f);
angle = DEG2RAD( degrees );
s = sin( angle );
c = cos( angle );
@ -755,6 +608,21 @@ const char *UTIL_FileExtension( const char *in )
return dot + 1;
}
HSPRITE LoadSprite( const char *pszName )
{
int i;
char sz[256];
if ( ActualWidth < 640 )
i = 320;
else
i = 640;
sprintf( sz, pszName, i );
return SPR_Load( sz );
}
/*
====================
VGui_ConsolePrint

View File

@ -44,7 +44,7 @@ extern void HUD_Shutdown( void );
extern void HUD_RenderCallback( int fTrans );
extern void HUD_CreateEntities( void );
extern int HUD_AddVisibleEntity( edict_t *pEnt, int ed_type );
extern void HUD_StudioEvent( const dstudioevent_t *event, edict_t *entity );
extern void HUD_StudioEvent( const mstudioevent_t *event, edict_t *entity );
extern void HUD_StudioFxTransform( edict_t *ent, float transform[4][4] );
extern int HUD_StudioDoInterp( edict_t *e );
extern void HUD_ParseTempEntity( void );
@ -198,19 +198,18 @@ extern float UTIL_Probe( const Vector &origin, Vector *vecDirection, float stren
extern void UTIL_GetForceDirection( const Vector &origin, float magnitude, Vector *resultDirection, float *resultForce );
extern void RotatePointAroundVector( Vector &dst, const Vector &dir, const Vector &point, float degrees );
// drawing stuff
extern client_sprite_t *SPR_GetList( const char *name, int *count );
extern void ParseHudSprite( const char **pfile, char *psz, client_sprite_t *result );
extern void DrawPause( void );
// client fade
extern void SetScreenFade( Vector fadeColor, float alpha, float duration, float holdTime, int fadeFlags );
extern void ClearAllFades( void );
extern void ClearPermanentFades( void );
extern void DrawScreenFade( void );
// drawing progress bar (image must be grayscale)
extern void DrawImageBar( float percent, const char *szSpriteName );
extern void DrawImageBar( float percent, const char *szSpriteName, int x, int y );
extern void DrawGenericBar( float percent, int w, int h );
extern void DrawGenericBar( float percent, int x, int y, int w, int h );
extern void Draw_VidInit( void );
// sprite loading
extern HSPRITE LoadSprite( const char *pszName );
// mathlib
extern void AngleMatrix( const vec3_t angles, float (*matrix)[4] );

View File

@ -8,7 +8,7 @@
#include "ref_params.h"
#include "triangle_api.h"
#include "pm_movevars.h"
#include "studio_ref.h"
#include "studio.h"
#include "usercmd.h"
#include "hud.h"
@ -65,27 +65,6 @@ cvar_t *v_iroll_level;
cvar_t *v_ipitch_level;
cvar_t *v_dark;
//==============================================================================
// PASS MANAGER GLOBALS
//==============================================================================
// render manager global variables
bool g_FirstFrame = false;
bool g_bFinalPass = false;
bool g_bEndCalc = false;
int m_RenderRefCount = 0; // refcounter (use for debug)
// passes info
bool g_bSkyShouldpass = false;
bool g_bSkyPass = false;
// base origin and angles
Vector g_vecBaseOrigin; // base origin - transformed always
Vector g_vecBaseAngles; // base angles - transformed always
Vector g_vecCurrentOrigin; // current origin
Vector g_vecCurrentAngles; // current angles
//==============================================================================
// VIEW RENDERING
//==============================================================================
@ -240,18 +219,16 @@ void V_DriftPitch( ref_params_t *pparams )
//==========================
float V_CalcFov( float fov_x, float width, float height )
{
float fov_y, x, rad = 360.0f * M_PI;
// check to avoid division by zero
if( fov_x == 0 ) HOST_ERROR( "V_CalcFov: null fov!\n" );
if( fov_x < 1 || fov_x > 179 )
{
ALERT( at_error, "V_CalcFov: invalid fov %g!\n", fov_x );
fov_x = 90;
}
// make sure that fov in-range
fov_x = bound( 1, fov_x, 179 );
x = width / tan( fov_x / rad );
fov_y = atan2( height, x );
fov_y = (fov_y * rad);
return fov_y;
float x = width / tan( DEG2RAD( fov_x ) * 0.5f );
float half_fov_y = atan( height / x );
return RAD2DEG( half_fov_y ) * 2;
}
//==========================
@ -369,6 +346,8 @@ void V_PreRender( ref_params_t *pparams )
pparams->fov_x = gHUD.m_flFOV; // this is a final fov value
pparams->fov_y = V_CalcFov( pparams->fov_x, pparams->viewport[2], pparams->viewport[3] );
memset( pparams->blend, 0, sizeof( pparams->blend ));
}
//==========================
@ -456,9 +435,9 @@ void V_CalcViewRoll( ref_params_t *pparams )
}
//==========================
// V_SetViewportRefdef
// V_SetViewport
//==========================
void V_SetViewportRefdef( ref_params_t *pparams )
void V_SetViewport( ref_params_t *pparams )
{
pparams->viewport[0] = 0;
pparams->viewport[1] = 0;
@ -467,20 +446,9 @@ void V_SetViewportRefdef( ref_params_t *pparams )
}
//==========================
// V_KillViewportRefdef
// V_ResetViewport
//==========================
void V_KillViewportRefdef( ref_params_t *pparams )
{
pparams->viewport[0] = 0;
pparams->viewport[1] = 0;
pparams->viewport[2] = 1;
pparams->viewport[3] = 1;
}
//==========================
// V_ResetViewportRefdef
//==========================
void V_ResetViewportRefdef( ref_params_t *pparams )
void V_ResetViewport( ref_params_t *pparams )
{
pparams->viewport[0] = 0;
pparams->viewport[1] = 0;
@ -562,25 +530,6 @@ void V_GetChasePos( ref_params_t *pparams, edict_t *ent, float *cl_angles, Vecto
V_GetChaseOrigin( angles, origin, cl_chasedist->value, origin );
}
//==========================
// V_CalcNextView
//==========================
void V_CalcNextView( ref_params_t *pparams )
{
if( g_FirstFrame ) // first time not actually
{
g_FirstFrame = false;
// first time in this function
V_PreRender( pparams );
g_bSkyShouldpass = (gHUD.m_iSkyMode ? true : false);
m_RenderRefCount = 0; // reset debug counter
g_bSkyPass = false;
g_bFinalPass = false;
}
}
//==========================
// V_CalcCameraRefdef
//==========================
@ -594,7 +543,7 @@ void V_CalcCameraRefdef( ref_params_t *pparams )
edict_t *viewentity = GetEntityByIndex( gHUD.viewEntityIndex );
if( viewentity )
{
dstudiohdr_t *viewmonster = (dstudiohdr_t *)GetModelPtr( viewentity );
studiohdr_t *viewmonster = (studiohdr_t *)GetModelPtr( viewentity );
float m_fLerp = GetLerpFrac();
if( viewentity->v.movetype == MOVETYPE_STEP )
@ -624,7 +573,7 @@ void V_CalcCameraRefdef( ref_params_t *pparams )
edict_t *viewentity = GetEntityByIndex( pparams->viewentity );
if( viewentity )
{
dstudiohdr_t *viewmonster = (dstudiohdr_t *)GetModelPtr( viewentity );
studiohdr_t *viewmonster = (studiohdr_t *)GetModelPtr( viewentity );
float m_fLerp = GetLerpFrac();
if( viewentity->v.movetype == MOVETYPE_STEP )
@ -781,16 +730,6 @@ void V_ApplyShake( Vector& origin, Vector& angles, float factor )
angles.z += gHUD.m_Shake.appliedAngle * factor;
}
//==========================
// V_CalcFinalPass
//==========================
void V_CalcFinalPass( ref_params_t *pparams )
{
g_FirstFrame = true; // enable calc next passes
V_ResetViewportRefdef( pparams ); // reset view port as default
m_RenderRefCount++; // increase counter
}
//==========================
// V_CalcThirdPersonRefdef
//==========================
@ -982,7 +921,7 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
edict_t *view = GetViewModel();
int i;
if( g_bFinalPass ) V_DriftPitch( pparams );
V_DriftPitch( pparams );
bob = V_CalcBob( pparams );
// refresh the position
@ -1102,57 +1041,15 @@ void V_CalcScreenBlend( ref_params_t *pparams )
#endif
}
//==========================
// V_CalcMainRefdef
//==========================
void V_CalcMainRefdef( ref_params_t *pparams )
void V_CalcRefdef( ref_params_t *pparams )
{
memset( pparams->blend, 0, sizeof( pparams->blend ));
if( g_FirstFrame ) g_bFinalPass = true;
V_PreRender( pparams );
V_CalcGlobalFog( pparams );
V_ResetViewport( pparams );
V_CalcFirstPersonRefdef( pparams );
V_CalcThirdPersonRefdef( pparams );
V_CalcIntermisionRefdef( pparams );
V_CalcCameraRefdef( pparams );
V_CalcScreenBlend( pparams );
g_vecBaseOrigin = pparams->vieworg;
g_vecBaseAngles = pparams->viewangles;
}
//==========================
// V_CalcSkyRefdef
//==========================
bool V_CalcSkyRefdef( ref_params_t *pparams )
{
if( g_bSkyShouldpass )
{
g_bSkyShouldpass = false;
V_CalcMainRefdef( pparams ); // refresh position
pparams->vieworg = gHUD.m_vecSkyPos;
V_ResetViewportRefdef( pparams );
pparams->nextView = 1;
g_bSkyPass = true;
m_RenderRefCount++;
return true;
}
if( g_bSkyPass )
{
pparams->nextView = 0;
g_bSkyPass = false;
return false;
}
return false;
}
void V_CalcRefdef( ref_params_t *pparams )
{
V_CalcNextView( pparams );
if( V_CalcSkyRefdef( pparams ))
return;
V_CalcGlobalFog( pparams );
V_CalcFinalPass ( pparams );
V_CalcMainRefdef( pparams );
}

View File

@ -7,10 +7,18 @@
#include "hud.h"
#include "triangle_api.h"
#define MAX_LOGO_FRAMES 56
int grgLogoFrame[MAX_LOGO_FRAMES] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 14, 15,
16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
29, 29, 29, 29, 29, 28, 27, 26, 25, 24, 30, 31
};
void CHud :: Init( void )
{
InitMessages();
m_Zoom.Init(); // must be first
m_Ammo.Init();
m_Health.Init();
m_SayText.Init();
@ -18,7 +26,6 @@ void CHud :: Init( void )
m_Train.Init();
m_Battery.Init();
m_Flash.Init();
m_Redeemer.Init();
m_Message.Init();
m_Scoreboard.Init();
m_StatusBar.Init();
@ -71,11 +78,11 @@ void CHud :: VidInit( void )
// Load Sprites
// ---------
m_hsprLogo = 0;
m_hsprCursor = 0;
m_hHudError = 0;
spot = NULL; // clear intermission spot
Draw_VidInit ();
ClearAllFades ();
if( CVAR_GET_FLOAT( "hud_scale" ))
@ -85,25 +92,47 @@ void CHud :: VidInit( void )
// setup screen info
GetScreenInfo( &m_scrinfo );
if( ActualWidth < 640 )
m_iRes = 320;
else m_iRes = 640;
// Only load this once
if ( !m_pSpriteList )
{
// we need to load the hud.txt, and all sprites within
m_pSpriteList = SPR_GetList( "scripts/hud.txt", &m_iSpriteCount );
m_pSpriteList = SPR_GetList( "sprites/hud.txt", &m_iSpriteCountAllRes );
if( m_pSpriteList )
{
// count the number of sprites of the appropriate res
m_iSpriteCount = 0;
client_sprite_t *p = m_pSpriteList;
for ( int j = 0; j < m_iSpriteCountAllRes; j++ )
{
if ( p->iRes == m_iRes )
m_iSpriteCount++;
p++;
}
// allocated memory for sprite handle arrays
m_rghSprites = new HSPRITE[m_iSpriteCount];
m_rgrcRects = new wrect_t[m_iSpriteCount];
m_rgszSpriteNames = new char[m_iSpriteCount * MAX_SPRITE_NAME_LENGTH];
client_sprite_t *p = m_pSpriteList;
for ( int j = 0; j < m_iSpriteCount; j++ )
p = m_pSpriteList;
int index = 0;
for ( j = 0; j < m_iSpriteCountAllRes; j++ )
{
m_rghSprites[j] = SPR_Load( p->szSprite );
m_rgrcRects[j] = p->rc;
strncpy( &m_rgszSpriteNames[j * MAX_SPRITE_NAME_LENGTH], p->szName, MAX_SPRITE_NAME_LENGTH );
if ( p->iRes == m_iRes )
{
char sz[256];
sprintf(sz, "sprites/%s.spr", p->szSprite);
m_rghSprites[index] = SPR_Load(sz);
m_rgrcRects[index] = p->rc;
strncpy( &m_rgszSpriteNames[index * MAX_SPRITE_NAME_LENGTH], p->szName, MAX_SPRITE_NAME_LENGTH );
index++;
}
p++;
}
}
@ -116,12 +145,20 @@ void CHud :: VidInit( void )
}
else
{
// engine may be release unused shaders after reloading map or change level
// loading them again here
// we have already have loaded the sprite reference from hud.txt, but
// we need to make sure all the sprites have been loaded (we've gone through a transition, or loaded a save game)
client_sprite_t *p = m_pSpriteList;
for( int j = 0; j < m_iSpriteCount; j++ )
int index = 0;
for ( int j = 0; j < m_iSpriteCountAllRes; j++ )
{
m_rghSprites[j] = SPR_Load( p->szSprite );
if ( p->iRes == m_iRes )
{
char sz[256];
sprintf( sz, "sprites/%s.spr", p->szSprite );
m_rghSprites[index] = SPR_Load(sz);
index++;
}
p++;
}
}
@ -141,8 +178,6 @@ void CHud :: VidInit( void )
m_Train.VidInit();
m_Battery.VidInit();
m_Flash.VidInit();
m_Redeemer.VidInit();
m_Zoom.VidInit();
m_MOTD.VidInit();
m_Message.VidInit();
m_Scoreboard.VidInit();
@ -224,20 +259,10 @@ int CHud :: Redraw( float flTime )
DrawScreenFade();
// take a screenshot if the client's got the cvar set
if( CVAR_GET_FLOAT( "hud_takesshots" ))
if( m_flShotTime && m_flShotTime < flTime )
{
if( m_flTime > m_flShotTime )
{
CLIENT_COMMAND( "screenshot\n" );
m_flShotTime = m_flTime + 0.04f;
}
}
// redeemer hud stuff
if( m_Redeemer.m_iHudMode > 0 )
{
m_Redeemer.Draw( flTime );
return 1;
CLIENT_COMMAND( "screenshot\n" );
m_flShotTime = 0;
}
// custom view active, and flag "draw hud" isn't set
@ -265,6 +290,28 @@ int CHud :: Redraw( float flTime )
pList = pList->pNext;
}
}
// are we in demo mode? do we need to draw the logo in the top corner?
if (m_iLogo)
{
int x, y, i;
if (m_hsprLogo == 0)
m_hsprLogo = LoadSprite("sprites/%d_logo.spr");
SPR_Set(m_hsprLogo, 250, 250, 250 );
x = SPR_Width(m_hsprLogo, 0);
x = ScreenWidth - x;
y = SPR_Height(m_hsprLogo, 0)/2;
// Draw the logo at 20 fps
int iFrame = (int)(flTime * 20) % MAX_LOGO_FRAMES;
i = grgLogoFrame[iFrame] - 1;
SPR_DrawAdditive(i, x, y, NULL);
}
return 1;
}

View File

@ -426,36 +426,6 @@ private:
int m_iWidth; // width of the battery innards
};
class CHudRedeemer: public CHudBase
{
public:
int Init( void );
int VidInit( void );
int Draw( float flTime );
int MsgFunc_WarHUD( const char *pszName, int iSize, void *pbuf );
int m_iHudMode;
int m_iOldHudMode;
private:
HSPRITE m_hSprite;
HSPRITE m_hCrosshair;
HSPRITE m_hStatic;
HSPRITE m_hCamera;
HSPRITE m_hCamRec;
};
class CHudZoom: public CHudBase
{
public:
int Init( void );
int VidInit( void );
int Draw( float flTime );
int MsgFunc_ZoomHUD( const char *pszName, int iSize, void *pbuf );
int m_iHudMode;
private:
HSPRITE m_hCrosshair;
HSPRITE m_hLines;
};
//
//-----------------------------------------------------
//
@ -519,7 +489,8 @@ private:
message_parms_t m_parms;
float m_gameTitleTime;
client_textmessage_t *m_pGameTitle;
int HUD_Logo; // display logo
int m_HUD_title_life;
int m_HUD_title_half;
};
//
@ -561,16 +532,15 @@ private:
//
//-----------------------------------------------------
//
#define SKY_OFF 0
#define SKY_ON 1
class CHud
{
private:
HUDLIST *m_pHudList;
HSPRITE m_hsprLogo;
int m_iLogo;
client_sprite_t *m_pSpriteList;
int m_iSpriteCount;
int m_iSpriteCountAllRes;
float m_flMouseSensitivity;
int m_iConcussionEffect;
int m_iNoClip;
@ -586,8 +556,6 @@ public:
float m_flFOV;
int m_Teamplay;
int m_iRes;
Vector m_vecSkyPos;
int m_iSkyMode;
int m_iCameraMode;
int m_iLastCameraMode;
int m_iFontHeight;
@ -618,8 +586,6 @@ public:
CHudBattery m_Battery;
CHudTrain m_Train;
CHudFlashlight m_Flash;
CHudRedeemer m_Redeemer;
CHudZoom m_Zoom;
CHudMessage m_Message;
CHudScoreboard m_Scoreboard;
CHudStatusBar m_StatusBar;
@ -644,6 +610,7 @@ public:
// user messages
int _cdecl MsgFunc_Damage( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Logo( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf );
@ -656,18 +623,14 @@ public:
int _cdecl MsgFunc_RainData( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_HUDColor( const char *pszName, int iSize, void *pbuf);
int _cdecl MsgFunc_SetFog( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetSky( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_CamData( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_AddScreen( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_AddMirror( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_AddPortal( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Particle( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_TempEntity( const char *pszName, int iSize, void *pbuf );
// user commansds
// user commands
void _cdecl UserCmd_ChangeLevel( void );
// Screen information

View File

@ -25,7 +25,7 @@
WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise
WEAPON *gpLastSel; // Last weapon menu selection
client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iCount );
client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iRes, int iCount );
WeaponsResource gWR;
int g_weaponselect = 0;
@ -60,10 +60,17 @@ int WeaponsResource :: HasAmmo( WEAPON *p )
void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
{
if( !pWeapon ) return;
int i, iRes;
int i;
char sz[256];
if (ActualWidth < 640)
iRes = 320;
else
iRes = 640;
char sz[128];
if ( !pWeapon )
return;
memset( &pWeapon->rcActive, 0, sizeof( wrect_t ));
memset( &pWeapon->rcInactive, 0, sizeof( wrect_t ));
@ -74,33 +81,36 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
pWeapon->hAmmo = 0;
pWeapon->hAmmo2 = 0;
sprintf( sz, "scripts/items/%s.txt", pWeapon->szName );
sprintf( sz, "sprites/%s.txt", pWeapon->szName );
client_sprite_t *pList = SPR_GetList( sz, &i );
if( !pList ) return;
client_sprite_t *p;
p = GetSpriteList( pList, "crosshair", i );
p = GetSpriteList( pList, "crosshair", iRes, i );
if( p )
{
pWeapon->hCrosshair = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hCrosshair = SPR_Load(sz);
pWeapon->rcCrosshair = p->rc;
}
else pWeapon->hCrosshair = 0;
p = GetSpriteList( pList, "autoaim", i );
p = GetSpriteList( pList, "autoaim", iRes, i );
if( p )
{
pWeapon->hAutoaim = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAutoaim = SPR_Load(sz);
pWeapon->rcAutoaim = p->rc;
}
else pWeapon->hAutoaim = 0;
p = GetSpriteList( pList, "zoom", i );
p = GetSpriteList( pList, "zoom", iRes, i );
if( p )
{
pWeapon->hZoomedCrosshair = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hZoomedCrosshair = SPR_Load(sz);
pWeapon->rcZoomedCrosshair = p->rc;
}
else
@ -109,10 +119,11 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
pWeapon->rcZoomedCrosshair = pWeapon->rcCrosshair;
}
p = GetSpriteList( pList, "zoom_autoaim", i );
p = GetSpriteList( pList, "zoom_autoaim", iRes, i );
if( p )
{
pWeapon->hZoomedAutoaim = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hZoomedAutoaim = SPR_Load(sz);
pWeapon->rcZoomedAutoaim = p->rc;
}
else
@ -121,10 +132,11 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
pWeapon->rcZoomedAutoaim = pWeapon->rcZoomedCrosshair;
}
p = GetSpriteList( pList, "weapon", i );
p = GetSpriteList( pList, "weapon", iRes, i );
if( p )
{
pWeapon->hInactive = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hInactive = SPR_Load(sz);
pWeapon->rcInactive = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
@ -135,10 +147,11 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
p = GetSpriteList( pList, "weapon_s", i );
p = GetSpriteList( pList, "weapon_s", iRes, i );
if( p )
{
pWeapon->hActive = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hActive = SPR_Load(sz);
pWeapon->rcActive = p->rc;
}
else
@ -147,24 +160,28 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
pWeapon->rcActive = gHUD.GetSpriteRect( gHUD.m_HUD_error );
}
p = GetSpriteList( pList, "ammo", i );
p = GetSpriteList( pList, "ammo", iRes, i );
if( p )
{
pWeapon->hAmmo = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAmmo = SPR_Load(sz);
pWeapon->rcAmmo = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
else pWeapon->hAmmo = 0;
p = GetSpriteList( pList, "ammo2", i );
p = GetSpriteList( pList, "ammo2", iRes, i );
if( p )
{
pWeapon->hAmmo2 = SPR_Load( p->szSprite );
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAmmo2 = SPR_Load(sz);
pWeapon->rcAmmo2 = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
else pWeapon->hAmmo2 = 0;
// in original Half-Life this was a leak
FREE( pList );
}
// Returns the first weapon for a given slot.
@ -1264,7 +1281,7 @@ sprite name 'psz' in the given sprite list 'pList'
iCount is the number of items in the pList
=================================
*/
client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iCount )
client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iRes, int iCount )
{
if( !pList ) return NULL;
@ -1273,7 +1290,7 @@ client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iCo
while( i-- )
{
if( !strcmp( psz, p->szName ))
if ((!strcmp(psz, p->szName)) && (p->iRes == iRes))
return p;
p++;
}

View File

@ -17,7 +17,7 @@
#define __AMMO_H__
#define MAX_WEAPON_NAME 128
#define MAX_WEAPON_SLOTS 6 // hud item selection slots
#define MAX_WEAPON_SLOTS 5 // hud item selection slots
#define WEAPON_FLAGS_SELECTONEMPTY 1
#define WEAPON_IS_ONTARGET 0x40

View File

@ -25,7 +25,8 @@
DECLARE_MESSAGE( m_Health, Health )
DECLARE_MESSAGE( m_Health, Damage )
#define PAIN_NAME "sprites/pain.spr"
#define PAIN_NAME "sprites/%d_pain.spr"
#define DAMAGE_NAME "sprites/%d_dmg.spr"
int giDmgHeight, giDmgWidth;
@ -39,7 +40,10 @@ int giDmgFlags[NUM_DMG_TYPES] =
DMG_NERVEGAS,
DMG_RADIATION,
DMG_SHOCK,
DMG_NUCLEAR
DMG_CALTROP,
DMG_TRANQ,
DMG_CONCUSS,
DMG_HALLUC
};
int CHudHealth :: Init( void )
@ -160,7 +164,7 @@ int CHudHealth :: Draw( float flTime )
return 1;
if( !m_hSprite )
m_hSprite = SPR_Load( PAIN_NAME );
m_hSprite = LoadSprite( PAIN_NAME );
// has health changed? Flash the health #
if( m_fFade )

View File

@ -64,8 +64,27 @@
#define DMG_SLOWBURN (1 << 21) // in an oven
#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer
#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar)
#define DMG_NUCLEAR (1 << 24) // Players hit by this begin to burn
//TF ADDITIONS
#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn
#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance
#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius.
#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor
#define DMG_AIMED (1 << 28) // Does Hit location damage
#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls
#define DMG_CALTROP (1<<30)
#define DMG_HALLUC (1<<31)
// TF Healing Additions for TakeHealth
#define DMG_IGNORE_MAXHEALTH DMG_IGNITE
// TF Redefines since we never use the originals
#define DMG_NAIL DMG_SLASH
#define DMG_NOT_SELF DMG_FREEZE
#define DMG_TRANQ DMG_MORTAR
#define DMG_CONCUSS DMG_SONIC
typedef struct
{

View File

@ -43,7 +43,8 @@ int CHudMessage :: Init( void )
int CHudMessage :: VidInit( void )
{
HUD_Logo = gHUD.GetSpriteIndex( "logo" );
m_HUD_title_half = gHUD.GetSpriteIndex( "title_half" );
m_HUD_title_life = gHUD.GetSpriteIndex( "title_life" );
return 1;
}
@ -305,31 +306,34 @@ int CHudMessage :: Draw( float fTime )
drawn = 0;
if( m_gameTitleTime > 0 )
if ( m_gameTitleTime > 0 )
{
float localTime = gHUD.m_flTime - m_gameTitleTime;
float brightness;
// Maybe timer isn't set yet
if( m_gameTitleTime > gHUD.m_flTime )
if ( m_gameTitleTime > gHUD.m_flTime )
m_gameTitleTime = gHUD.m_flTime;
if( localTime > ( m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout ))
{
if ( localTime > (m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout) )
m_gameTitleTime = 0;
}
else
{
brightness = FadeBlend( m_pGameTitle->fadein, m_pGameTitle->fadeout, m_pGameTitle->holdtime, localTime );
int fullWidth = gHUD.GetSpriteRect(HUD_Logo).right - gHUD.GetSpriteRect(HUD_Logo).left;
int fullHeight = gHUD.GetSpriteRect(HUD_Logo).bottom - gHUD.GetSpriteRect(HUD_Logo).top;
int halfWidth = gHUD.GetSpriteRect(m_HUD_title_half).right - gHUD.GetSpriteRect(m_HUD_title_half).left;
int fullWidth = halfWidth + gHUD.GetSpriteRect(m_HUD_title_life).right - gHUD.GetSpriteRect(m_HUD_title_life).left;
int fullHeight = gHUD.GetSpriteRect(m_HUD_title_half).bottom - gHUD.GetSpriteRect(m_HUD_title_half).top;
int x = XPosition( m_pGameTitle->x, fullWidth, fullWidth );
int y = YPosition( m_pGameTitle->y, fullHeight);
int y = YPosition( m_pGameTitle->y, fullHeight );
SPR_Set( gHUD.GetSprite( HUD_Logo ), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 );
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect( HUD_Logo ));
SPR_Set( gHUD.GetSprite(m_HUD_title_half), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 );
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(m_HUD_title_half) );
SPR_Set( gHUD.GetSprite(m_HUD_title_life), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 );
SPR_DrawAdditive( 0, x + halfWidth, y, &gHUD.GetSpriteRect(m_HUD_title_life) );
drawn = 1;
}

View File

@ -24,10 +24,10 @@
extern ref_params_t *gpViewParams;
// CHud message handlers
DECLARE_HUDMESSAGE( Logo );
DECLARE_HUDMESSAGE( HUDColor );
DECLARE_HUDMESSAGE( SetFog );
DECLARE_HUDMESSAGE( RoomType );
DECLARE_HUDMESSAGE( SetSky );
DECLARE_HUDMESSAGE( RainData );
DECLARE_HUDMESSAGE( SetBody );
DECLARE_HUDMESSAGE( SetSkin );
@ -40,9 +40,6 @@ DECLARE_HUDMESSAGE( Particle );
DECLARE_HUDMESSAGE( Concuss );
DECLARE_HUDMESSAGE( GameMode );
DECLARE_HUDMESSAGE( CamData );
DECLARE_HUDMESSAGE( AddMirror );
DECLARE_HUDMESSAGE( AddScreen );
DECLARE_HUDMESSAGE( AddPortal );
DECLARE_HUDMESSAGE( TempEntity );
DECLARE_HUDMESSAGE( ServerName );
DECLARE_HUDMESSAGE( ScreenShake );
@ -51,6 +48,7 @@ DECLARE_HUDCOMMAND( ChangeLevel );
int CHud :: InitMessages( void )
{
HOOK_MESSAGE( Logo );
HOOK_MESSAGE( ResetHUD );
HOOK_MESSAGE( GameMode );
HOOK_MESSAGE( ServerName );
@ -63,15 +61,11 @@ int CHud :: InitMessages( void )
HOOK_MESSAGE( Particle );
HOOK_MESSAGE( TempEntity );
HOOK_MESSAGE( SetFog );
HOOK_MESSAGE( SetSky );
HOOK_MESSAGE( CamData );
HOOK_MESSAGE( RainData );
HOOK_MESSAGE( WeaponAnim );
HOOK_MESSAGE( SetBody );
HOOK_MESSAGE( SetSkin );
HOOK_MESSAGE( AddMirror);
HOOK_MESSAGE( AddScreen );
HOOK_MESSAGE( AddPortal );
HOOK_MESSAGE( ScreenFade );
HOOK_MESSAGE( ScreenShake );
@ -116,6 +110,18 @@ void CHud :: UserCmd_ChangeLevel( void )
m_Shake.duration = 0;
}
int CHud :: MsgFunc_Logo( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
// update Train data
m_iLogo = READ_BYTE();
END_READ();
return 1;
}
int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf )
{
// clear all hud data
@ -172,7 +178,6 @@ int CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
{
m_flStartDist = 0;
m_flEndDist = 0;
m_iSkyMode = SKY_OFF;
m_iIntermission = 0;
// prepare all hud data
@ -223,20 +228,6 @@ int CHud :: MsgFunc_SetFog( const char *pszName, int iSize, void *pbuf )
return 1;
}
int CHud :: MsgFunc_SetSky( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
m_iSkyMode = READ_BYTE();
m_vecSkyPos[0] = READ_COORD();
m_vecSkyPos[1] = READ_COORD();
m_vecSkyPos[2] = READ_COORD();
END_READ();
return 1;
}
int CHud :: MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
@ -365,39 +356,6 @@ int CHud :: MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf )
return 1;
}
int CHud :: MsgFunc_AddScreen( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
// AddScreenBrushEntity( READ_BYTE() );
END_READ();
return 1;
}
int CHud :: MsgFunc_AddMirror( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
// AddMirrorBrushEntity( READ_BYTE() );
END_READ();
return 1;
}
int CHud :: MsgFunc_AddPortal( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
// AddPortalBrushEntity( READ_BYTE() );
END_READ();
return 1;
}
int CHud :: MsgFunc_Particle( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );

View File

@ -43,8 +43,8 @@ int CHudTrain::VidInit( void )
int CHudTrain::Draw(float fTime)
{
if( !m_hSprite )
m_hSprite = SPR_Load( "sprites/train.spr" );
if ( !m_hSprite )
m_hSprite = LoadSprite("sprites/%d_train.spr");
if( m_iPos )
{

View File

@ -1,157 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// warhead.cpp - hud for weapon_redeemer
//
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "hud.h"
#define GUIDE_S SPR_Width( m_hCrosshair, 0 )
#define READOUT_S 192
DECLARE_MESSAGE( m_Redeemer, WarHUD )
int CHudRedeemer::Init( void )
{
m_iHudMode = 0;
HOOK_MESSAGE( WarHUD );
m_iFlags |= HUD_ACTIVE;
gHUD.AddHudElem( this );
return 1;
}
int CHudRedeemer :: VidInit( void )
{
m_hCrosshair = SPR_Load( "sprites/guidedx.spr" );
m_hSprite = SPR_Load( "sprites/readout.spr" );
m_hCamRec = SPR_Load( "sprites/cam_rec.spr" );
m_hStatic = SPR_Load( "sprites/static.spr" );
m_hCamera = SPR_Load( "sprites/camera.spr" );
m_iHudMode = m_iOldHudMode = 0;
return 1;
}
int CHudRedeemer :: MsgFunc_WarHUD( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
m_iHudMode = READ_BYTE();
m_iOldHudMode = -1; // force to update
ClearPermanentFades ();
END_READ();
return 1;
}
int CHudRedeemer :: Draw( float flTime )
{
int x, y, w, h;
wrect_t rc;
int frame;
// setup screen rectangle
rc.left = rc.top = 0;
rc.right = ScreenWidth;
rc.bottom = ScreenHeight;
if( m_iHudMode == 1 ) // draw warhead screen (controllable rocket)
{
y = (ScreenWidth - GUIDE_S) / 2;
x = (ScreenHeight - GUIDE_S) / 2;
SPR_Set( m_hCrosshair, 255, 128, 128 );
SPR_DrawAdditive( 0, y, x, NULL);
int yOffset = ScreenHeight;
yOffset -= ((int)(flTime * 650) % READOUT_S) - READOUT_S;
SPR_Set( m_hSprite, 255, 128, 128 );
while( yOffset > -READOUT_S )
{
SPR_DrawAdditive( 0, 0, yOffset, READOUT_S>>1, READOUT_S );
yOffset -= READOUT_S;
}
if( m_iOldHudMode != m_iHudMode )
{
// enable red fade
SetScreenFade( Vector( 255, 0, 0 ), 64, 0, 0, FFADE_STAYOUT );
}
}
else if( m_iHudMode == 2 ) // draw warhead screen with alpha noise (underwater)
{
// play at 15fps
frame = (int)(flTime * 15) % SPR_Frames( m_hStatic );
y = x = 0;
w = SPR_Width( m_hStatic, 0 );
h = SPR_Height( m_hStatic, 0 );
for( y = -(RANDOM_LONG( 0, h )); y < ScreenHeight; y += h )
{
for( x = -(RANDOM_LONG( 0, w )); x < ScreenWidth; x += w )
{
SPR_Set( m_hStatic, 255, 255, 255, 100 );
SPR_DrawAdditive( frame, x, y, NULL );
}
}
y = (ScreenWidth - GUIDE_S) / 2;
x = (ScreenHeight - GUIDE_S) / 2;
SPR_Set( m_hCrosshair, 255, 128, 128 );
SPR_DrawAdditive( 0, y, x, NULL );
int yOffset = ScreenHeight;
yOffset -= ((int)(flTime * 650) % READOUT_S) - READOUT_S;
SPR_Set( m_hSprite, 255, 128, 128 );
while( yOffset > -READOUT_S )
{
SPR_DrawAdditive( 0, 0, yOffset, READOUT_S>>1, READOUT_S );
yOffset -= READOUT_S;
}
if( m_iOldHudMode != m_iHudMode )
{
// enable red fade
SetScreenFade( Vector( 255, 0, 0 ), 64, 0, 0, FFADE_STAYOUT );
}
}
else if( m_iHudMode == 3 ) // draw static noise (self destroyed)
{
// play at 15fps
frame = (int)(flTime * 15) % SPR_Frames( m_hStatic );
SPR_Set( m_hStatic, 255, 255, 255 );
SPR_Draw( frame, 0, 0, ScreenWidth, ScreenHeight );
}
else if( m_iHudMode == 4 )
{
// HACKHACK draw videocamera screen
// g-cont. i'm lazy same as BUzer, i won't to create new class :)
// play at 1.5 fps
frame = (int)(flTime * 1.5f) % SPR_Frames( m_hCamRec );
// draw interlaces
SPR_Set( m_hCamera, 16, 96, 16, 64 ); // give this value from breaklight.bsp (xash03)
SPR_DrawAdditive( 0, 0, 0, ScreenWidth, ScreenHeight );
// draw recorder icon
SPR_Set( m_hCamRec, 255, 0, 0, 255 ); // give this value from breaklight.bsp (xash03)
float scale = 2.5f; // REC[*] sprite scale
// calculating pos for different resolutions
w = SPR_Width( m_hCamRec, 0 ) * scale;
h = SPR_Height( m_hCamRec, 0 ) * scale;
x = ScreenWidth - (w * 1.5f);
y = w * 0.4f;
SPR_DrawAdditive( frame, x, y, w, h );
}
m_iOldHudMode = m_iHudMode;
return 1;
}

View File

@ -1,75 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// warhead.cpp - hud for sniper rifle
//=======================================================================
#include "extdll.h"
#include "triangle_api.h"
#include "utils.h"
#include "hud.h"
void DrawQuad(float xmin, float ymin, float xmax, float ymax)
{
//top left
g_engfuncs.pTriAPI->TexCoord2f(0,0);
g_engfuncs.pTriAPI->Vertex3f(xmin, ymin, 0);
//bottom left
g_engfuncs.pTriAPI->TexCoord2f(0,1);
g_engfuncs.pTriAPI->Vertex3f(xmin, ymax, 0);
//bottom right
g_engfuncs.pTriAPI->TexCoord2f(1,1);
g_engfuncs.pTriAPI->Vertex3f(xmax, ymax, 0);
//top right
g_engfuncs.pTriAPI->TexCoord2f(1,0);
g_engfuncs.pTriAPI->Vertex3f(xmax, ymin, 0);
}
DECLARE_MESSAGE( m_Zoom, ZoomHUD )
int CHudZoom :: Init( void )
{
m_iHudMode = 0;
HOOK_MESSAGE( ZoomHUD );
m_iFlags |= HUD_ACTIVE;
gHUD.AddHudElem( this );
return 1;
}
int CHudZoom::VidInit( void )
{
m_hLines = SPR_Load( "sprites/snlines.spr" );
m_hCrosshair = SPR_Load( "sprites/snzoom.spr" );
m_iHudMode = 0;
return 1;
}
int CHudZoom :: MsgFunc_ZoomHUD( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
m_iHudMode = READ_BYTE();
END_READ();
return 1;
}
int CHudZoom :: Draw( float flTime )
{
if( !m_hLines || !m_hCrosshair ) return 0;
if( !m_iHudMode ) return 0; // draw scope
float left = (float)(ScreenWidth - ScreenHeight) / 2;
float right = left + ScreenHeight;
// draw crosshair
SPR_Set( m_hCrosshair, 255, 255, 255 );
SPR_DrawTransColor( 0, left, 0, ScreenHeight, ScreenHeight );
// draw side-lines
SPR_Set( m_hLines, 255, 255, 255 );
SPR_Draw( 0, 0, 0, left, ScreenHeight );
SPR_Draw( 0, right, 0, left, ScreenHeight );
return 1;
}

View File

@ -29,7 +29,6 @@ typedef unsigned long CRC32_t;
typedef float vec_t;
#define DLLEXPORT __declspec( dllexport )
#define NUMVERTEXNORMALS 162 // quake avertex normals
#ifndef NULL
#define NULL ((void *)0)

View File

@ -15,7 +15,7 @@ typedef struct usercmd_s usercmd_t;
typedef struct particle_s particle_t;
typedef struct skyportal_s skyportal_t;
typedef struct ref_params_s ref_params_t;
typedef struct dstudioevent_s dstudioevent_t;
typedef struct mstudioevent_s mstudioevent_t;
typedef void (*ENTCALLBACK)( TEMPENTITY *ent );
typedef void (*HITCALLBACK)( TEMPENTITY *ent, TraceResult *ptr );
typedef int (*pfnUserMsgHook)( const char *pszName, int iSize, void *pbuf ); // user message handle
@ -245,7 +245,7 @@ typedef struct
void (*pfnDrawTriangles)( int fTrans );
void (*pfnCreateEntities)( void );
int (*pfnAddVisibleEntity)( edict_t *pEnt, int ed_type );
void (*pfnStudioEvent)( const dstudioevent_t *event, edict_t *entity );
void (*pfnStudioEvent)( const mstudioevent_t *event, edict_t *entity );
void (*pfnStudioFxTransform)( edict_t *pEdict, float transform[4][4] );
void (*pfnCalcRefdef)( ref_params_t *parms );
void (*pfnPM_Move)( playermove_t *ppmove, int server );

View File

@ -12,6 +12,9 @@
#define LM_STYLES 4 // MAXLIGHTMAPS
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
// worldcraft predefined angles
#define ANGLE_UP -1
#define ANGLE_DOWN -2

View File

@ -1,9 +1,9 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// studio_ref.h - studio model reference
// studio.h - studio model reference
//=======================================================================
#ifndef STUDIO_REF_H
#define STUDIO_REF_H
#ifndef STUDIO_H
#define STUDIO_H
/*
==============================================================================
@ -140,7 +140,7 @@ typedef struct
int numtransitions; // animation node to animation node transition graph
int transitionindex;
} dstudiohdr_t;
} studiohdr_t;
// header for demand loaded sequence group data
typedef struct
@ -150,7 +150,7 @@ typedef struct
char name[64];
int length;
} dstudioseqhdr_t;
} mstudioseqhdr_t;
// bones
typedef struct
@ -161,7 +161,7 @@ typedef struct
int bonecontroller[6]; // bone controller index, -1 == none
float value[6]; // default DoF values
float scale[6]; // scale for delta DoF values
} dstudiobone_t;
} mstudiobone_t;
// bone controllers
typedef struct
@ -172,7 +172,7 @@ typedef struct
float end;
int rest; // byte index value at rest
int index; // 0-3 user set controller, 4 mouth
} dstudiobonecontroller_t;
} mstudiobonecontroller_t;
// intersection boxes
typedef struct
@ -181,7 +181,7 @@ typedef struct
int group; // intersection group
vec3_t bbmin; // bounding box
vec3_t bbmax;
} dstudiobbox_t;
} mstudiobbox_t;
// demand loaded sequence groups
typedef struct
@ -190,7 +190,7 @@ typedef struct
char name[64]; // file name
void *cache; // cache index pointer (only in memory)
int data; // hack for group 0
} dstudioseqgroup_t;
} mstudioseqgroup_t;
// sequence descriptions
typedef struct
@ -236,7 +236,7 @@ typedef struct
int nodeflags; // transition rules
int nextseq; // auto advancing sequences
} dstudioseqdesc_t;
} mstudioseqdesc_t;
// events
#include "studio_event.h"
@ -247,7 +247,7 @@ typedef struct
vec3_t org; // pivot point
int start;
int end;
} dstudiopivot_t;
} mstudiopivot_t;
// attachment
typedef struct
@ -257,12 +257,12 @@ typedef struct
int bone;
vec3_t org; // attachment point
vec3_t vectors[3];
} dstudioattachment_t;
} mstudioattachment_t;
typedef struct
{
unsigned short offset[6];
} dstudioanim_t;
} mstudioanim_t;
// animation frames
typedef union
@ -273,7 +273,7 @@ typedef union
byte total;
} num;
short value;
} dstudioanimvalue_t;
} mstudioanimvalue_t;
// body part index
@ -283,7 +283,7 @@ typedef struct
int nummodels;
int base;
int modelindex; // index into models array
} dstudiobodyparts_t;
} mstudiobodyparts_t;
// skin info
typedef struct
@ -298,7 +298,7 @@ typedef struct
int index; // disk: offset at start of buffer
shader_t shader; // ref: shader number
};
} dstudiotexture_t;
} mstudiotexture_t;
// skin families
// short index[skinfamilies][skinref] // skingroup info
@ -323,7 +323,7 @@ typedef struct
int numgroups; // deformation groups
int groupindex;
} dstudiomodel_t;
} mstudiomodel_t;
// meshes
typedef struct
@ -333,11 +333,11 @@ typedef struct
int skinref;
int numnorms; // per mesh normals
int normindex; // normal vec3_t
} dstudiomesh_t;
} mstudiomesh_t;
typedef struct
{
void *data;
} cache_user_t;
#endif//STUDIO_REF_H
#endif//STUDIO_H

View File

@ -5,12 +5,12 @@
#ifndef STUDIO_EVENT_H
#define STUDIO_EVENT_H
typedef struct dstudioevent_s
typedef struct mstudioevent_s
{
int frame;
int event;
int type;
char options[64];
} dstudioevent_t;
} mstudioevent_t;
#endif//STUDIO_EVENT_H

View File

@ -29,15 +29,9 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% spirit/spirit.dsp %CONFIG%"spirit - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% snd_al/snd_al.dsp %CONFIG%"snd_al - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% snd_dx/snd_dx.dsp %CONFIG%"snd_dx - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
@ -69,11 +63,9 @@ if exist client\client.plg del /f /q client\client.plg
if exist engine\engine.plg del /f /q engine\engine.plg
if exist launch\launch.plg del /f /q launch\launch.plg
if exist physic\physic.plg del /f /q physic\physic.plg
if exist server\server.plg del /f /q server\server.plg
if exist spirit\spirit.plg del /f /q spirit\spirit.plg
if exist vid_gl\vid_gl.plg del /f /q vid_gl\vid_gl.plg
if exist viewer\viewer.plg del /f /q viewer\viewer.plg
if exist snd_al\snd_al.plg del /f /q snd_al\snd_al.plg
if exist snd_dx\snd_dx.plg del /f /q snd_dx\snd_dx.plg
if exist xtools\xtools.plg del /f /q xtools\xtools.plg

View File

@ -317,6 +317,8 @@ struct particle_s
rgba_t pColor[4];
};
#define NUMVERTEXNORMALS 162 // quake avertex normals
float cl_avertexnormals[NUMVERTEXNORMALS][3] =
{
#include "anorms.h"

View File

@ -110,7 +110,7 @@ StudioEvent
Event callback for studio models
====================
*/
void CL_StudioEvent( dstudioevent_t *event, edict_t *pEdict )
void CL_StudioEvent( mstudioevent_t *event, edict_t *pEdict )
{
clgame.dllFuncs.pfnStudioEvent( event, pEdict );
}
@ -545,6 +545,61 @@ void CL_DrawCrosshair( void )
SPR_DrawGeneric( 0, x - 0.5f * width, y - 0.5f * height, -1, -1, &clgame.ds.rcCrosshair );
}
/*
=============
CL_DrawLoading
draw loading progress bar
=============
*/
void CL_DrawLoading( float percent )
{
int x, y, width, height, right;
float xscale, yscale, step, s2;
rgba_t color;
re->GetParms( &width, &height, NULL, 0, cls.loadingBar );
x = ( SCREEN_WIDTH - width )>>1;
y = ( SCREEN_HEIGHT - height )>>1;
xscale = scr_width->integer / 640.0f;
yscale = scr_height->integer / 480.0f;
x *= xscale;
y *= yscale;
width *= xscale;
height *= yscale;
MakeRGBA( color, 128, 128, 128, 255 );
re->SetColor( color );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.loadingBar );
step = (float)width / 100.0f;
right = (int)ceil( percent * step );
s2 = (float)right / width;
width = right;
MakeRGBA( color, 208, 152, 0, 255 );
re->SetColor( color );
re->DrawStretchPic( x, y, width, height, 0, 0, s2, 1, cls.loadingBar );
re->SetColor( NULL );
}
/*
=============
CL_DrawPause
draw pause sign
=============
*/
void CL_DrawPause( void )
{
int w, h;
re->GetParms( &w, &h, NULL, 0, cls.pauseIcon );
SCR_DrawPic((SCREEN_WIDTH - w)>>1, ( SCREEN_HEIGHT - h )>>1, w, h, cls.pauseIcon );
}
void CL_DrawHUD( int state )
{
if( state == CL_ACTIVE && !cl.video_prepped )
@ -555,10 +610,21 @@ void CL_DrawHUD( int state )
clgame.dllFuncs.pfnRedraw( cl.time, state );
if( state == CL_ACTIVE || state == CL_PAUSED )
switch( state )
{
case CL_PAUSED:
CL_DrawPause();
// intentionally fallthrough
case CL_ACTIVE:
CL_DrawCrosshair ();
CL_DrawCenterPrint ();
break;
case CL_LOADING:
CL_DrawLoading( scr_loading->value );
break;
case CL_CHANGELEVEL:
CL_DrawLoading( 100.0f );
break;
}
}
@ -809,11 +875,10 @@ static HSPRITE pfnSPR_Load( const char *szPicName )
if( !re ) return 0; // render not initialized
if( !szPicName || !*szPicName )
{
MsgDev( D_ERROR, "CL_SpriteLoad: invalid spritename\n" );
return -1;
MsgDev( D_ERROR, "CL_LoadSprite: bad name!\n" );
return 0;
}
return re->RegisterShader( szPicName, SHADER_NOMIP ); // replace with SHADER_GENERIC ?
return re->RegisterShader( szPicName, SHADER_SPRITE );
}
/*
@ -983,24 +1048,27 @@ for parsing half-life scripts - hud.txt etc
static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
{
client_sprite_t *pList;
int numSprites = 0;
int index, iTemp;
int numSprites;
script_t *script;
token_t token;
if( piCount ) *piCount = 0;
if( !clgame.itemspath[0] )
FS_ExtractFilePath( psz, clgame.itemspath );
script = Com_OpenScript( psz, NULL, 0 );
if( !script ) return NULL;
Com_ReadUlong( script, false, &numSprites );
Com_ReadUlong( script, SC_ALLOW_NEWLINES, &numSprites );
// name, res, pic, x, y, w, h
pList = Mem_Alloc( clgame.mempool, sizeof( *pList ) * numSprites );
for( index = 0; index < numSprites; index++ )
{
if( !Com_ReadToken( script, SC_ALLOW_NEWLINES, &token ))
if( !Com_ReadToken( script, SC_ALLOW_NEWLINES|SC_PARSE_GENERIC, &token ))
break;
com.strncpy( pList[index].szName, token.string, sizeof( pList[index].szName ));
@ -1010,7 +1078,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
pList[index].iRes = iTemp;
// read spritename
Com_ReadToken( script, false, &token );
Com_ReadToken( script, SC_PARSE_GENERIC, &token );
com.strncpy( pList[index].szSprite, token.string, sizeof( pList[index].szSprite ));
// parse rectangle
@ -1066,8 +1134,6 @@ get actual screen info
*/
static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
{
int i;
// setup screen info
clgame.scrInfo.iRealWidth = scr_width->integer;
clgame.scrInfo.iRealHeight = scr_height->integer;
@ -1087,12 +1153,6 @@ static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
clgame.scrInfo.iFlags &= ~SCRINFO_VIRTUALSPACE;
}
// TODO: build real table of fonts widthInChars
// TODO: load half-life credits font from wad
for( i = 0; i < 256; i++ )
clgame.scrInfo.charWidths[i] = SMALLCHAR_WIDTH;
clgame.scrInfo.iCharHeight = SMALLCHAR_HEIGHT;
if( !pscrinfo ) return 0;
*pscrinfo = clgame.scrInfo; // copy screeninfo out
@ -1278,35 +1338,45 @@ returns drawed chachter width (in real screen pixels)
*/
static int pfnDrawCharacter( int x, int y, int number, int r, int g, int b )
{
float size, frow, fcol;
float ax, ay, aw, ah;
int fontWidth, fontHeight;
rgba_t color;
number &= 255;
if( !re ) return 0;
if( number <= ' ' ) return 0;
if( number < 32 ) return 0;
if( y < -clgame.scrInfo.iCharHeight )
return 0;
ax = x;
ay = y;
aw = clgame.scrInfo.charWidths[number];
ah = clgame.scrInfo.iCharHeight;
SPR_AdjustSize( &ax, &ay, &aw, &ah );
re->GetParms( &fontWidth, &fontHeight, NULL, 0, clgame.ds.hHudFont );
if( clgame.use_qfont )
{
pfnSPR_Set( clgame.hHudFont, r, g, b, 255 );
pfnSPR_DrawAdditive( 0, x, y, -1, -1, &clgame.fontRc[number] );
}
else
{
float size, frow, fcol;
float ax, ay, aw, ah;
int fontWidth, fontHeight;
rgba_t color;
MakeRGBA( color, r, g, b, 255 );
re->SetColor( color );
ax = x;
ay = y;
aw = clgame.scrInfo.charWidths[number];
ah = clgame.scrInfo.iCharHeight;
re->GetParms( &fontWidth, &fontHeight, NULL, 0, clgame.hHudFont );
SPR_AdjustSize( &ax, &ay, &aw, &ah );
MakeRGBA( color, r, g, b, 255 );
re->SetColor( color );
frow = (number >> 4)*0.0625f + (0.5f / (float)fontWidth);
fcol = (number & 15)*0.0625f + (0.5f / (float)fontHeight);
size = 0.0625f - (1.0f / (float)fontWidth);
frow = (number >> 4) * 0.0625f + (0.5f / (float)fontWidth);
fcol = (number & 15) * 0.0625f + (0.5f / (float)fontHeight);
size = 0.0625f - (1.0f / (float)fontWidth);
re->SetParms( clgame.hHudFont, kRenderTransAdd, 0 );
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, clgame.hHudFont );
}
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, clgame.ds.hHudFont );
re->SetColor( NULL ); // don't forget reset color
return clgame.scrInfo.charWidths[number];
}

View File

@ -5,6 +5,7 @@
#include "common.h"
#include "client.h"
#include "byteorder.h"
cvar_t *scr_viewsize;
cvar_t *scr_centertime;
@ -77,7 +78,9 @@ void SCR_DrawPic( float x, float y, float width, float height, string_t shader )
re->GetParms( &w, &h, NULL, 0, shader );
width = w, height = h;
}
SCR_AdjustSize( &x, &y, &width, &height );
re->SetParms( shader, kRenderNormal, 0 );
re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, shader );
}
@ -108,6 +111,7 @@ void SCR_DrawChar( int x, int y, float w, float h, int ch )
fcol = (ch & 15)*0.0625f + (0.5f / 256.0f);
size = 0.0625f - (1.0f / 256.0f);
re->SetParms( cls.clientFont, kRenderNormal, 0 );
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, cls.clientFont );
}
@ -133,6 +137,7 @@ void SCR_DrawSmallChar( int x, int y, int ch )
fcol = (ch & 15)*0.0625f + (0.5f / 256.0f);
size = 0.0625f - (1.0f / 256.0f);
re->SetParms( cls.consoleFont, kRenderNormal, 0 );
re->DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, fcol, frow, fcol + size, frow + size, cls.consoleFont );
}
@ -435,6 +440,66 @@ void SCR_UpdateScreen( void )
clgame.dllFuncs.pfnFrame( cl.time );
}
void SCR_LoadCreditsFont( void )
{
int fontWidth, fontHeight;
if( !re ) return;
re->GetParms( &fontWidth, &fontHeight, NULL, 0, clgame.hHudFont );
// setup creditsfont
if( fontWidth != fontHeight )
{
byte *buffer;
size_t length;
qfont_t *src;
// half-life font with variable chars witdh
buffer = FS_LoadFile( "gfx/creditsfont.fnt", &length );
if( buffer && length >= sizeof( qfont_t ))
{
int i;
src = (qfont_t *)buffer;
clgame.scrInfo.iCharHeight = LittleLong( src->rowheight );
clgame.use_qfont = true;
// build rectangles
for( i = 0; i < 256; i++ )
{
clgame.fontRc[i].left = LittleShort( src->fontinfo[i].startoffset ) % fontWidth;
clgame.fontRc[i].right = clgame.fontRc[i].left + LittleShort( src->fontinfo[i].charwidth );
clgame.fontRc[i].top = LittleShort( src->fontinfo[i].startoffset ) / fontWidth;
clgame.fontRc[i].bottom = clgame.fontRc[i].top + LittleLong( src->rowheight );
clgame.scrInfo.charWidths[i] = LittleLong( src->fontinfo[i].charwidth );
}
}
if( buffer ) Mem_Free( buffer );
}
else
{
// quake font
int i, w;
// all quake fonts like quad 16x16 fields
clgame.scrInfo.iCharHeight = fontHeight / 16;
clgame.use_qfont = false;
w = fontWidth / 16;
for( i = 0; i < 256; i++ )
{
// ugly hack to adjust fat and thin letters
if( i == 'm' || i == 'M' || i == 'w' || i == 'W' )
clgame.scrInfo.charWidths[i] = w;
else if( i == '!' || i == '.' || i == 'i' || i == 'I' || i == 'l' || i == '|' || i == ',' )
clgame.scrInfo.charWidths[i] = w * 0.5f;
else clgame.scrInfo.charWidths[i] = w * 0.75f;
}
}
}
void SCR_RegisterShaders( void )
{
if( re )
@ -443,16 +508,17 @@ void SCR_RegisterShaders( void )
cls.consoleFont = re->RegisterShader( va( "gfx/fonts/%s", con_font->string ), SHADER_FONT );
cls.clientFont = re->RegisterShader( va( "gfx/fonts/%s", cl_font->string ), SHADER_FONT );
cls.netIcon = re->RegisterShader( "#net.png", SHADER_NOMIP ); // FIXME: INTRESOURCE
cls.pauseIcon = re->RegisterShader( "gfx/paused", SHADER_NOMIP ); // FIXME: INTRESOURCE
cls.fillShader = re->RegisterShader( "*white", SHADER_FONT ); // used for FillRGBA
cls.particle = re->RegisterShader( "*particle", SHADER_FONT ); // Q1 particlefont
cls.loadingBar = re->RegisterShader( "gfx/lambda", SHADER_NOMIP ); // FIXME: INTRESOURCE
clgame.hHudFont = re->RegisterShader( "gfx/creditsfont", SHADER_NOMIP );
if( host.developer )
cls.consoleBack = re->RegisterShader( "gfx/conback", SHADER_NOMIP );
else cls.consoleBack = re->RegisterShader( "gfx/loading", SHADER_NOMIP );
cls.consoleBack = re->RegisterShader( "cached/conback", SHADER_NOMIP );
else cls.consoleBack = re->RegisterShader( "cached/loading", SHADER_NOMIP );
// TODO: load a font with a variable charwidths
Mem_Set( &clgame.ds, 0, sizeof( clgame.ds )); // reset a draw state
clgame.ds.hHudFont = re->RegisterShader( "gfx/creditsfont", SHADER_NOMIP );
}
// vid_state has changed
@ -494,7 +560,10 @@ void SCR_Init( void )
Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" );
SCR_RegisterShaders();
SCR_LoadCreditsFont();
UI_Init();
if( host.developer && FS_CheckParm( "-toconsole" ))
Cbuf_AddText( "toggleconsole\n" );
else UI_SetActiveMenu( UI_MAINMENU );

View File

@ -216,8 +216,6 @@ typedef struct
char centerPrint[2048];
int centerPrintLines;
HSPRITE hHudFont;
// crosshair members
HSPRITE hCrosshair;
wrect_t rcCrosshair;
@ -231,6 +229,7 @@ typedef struct
byte *mempool; // client edicts pool
byte *private; // client.dll private pool
string maptitle; // display map title
string itemspath; // path to items description for auto-complete func
union
{
@ -252,6 +251,10 @@ typedef struct
draw_stuff_t ds; // draw2d stuff (hud, weaponmenu etc)
SCREENINFO scrInfo; // actual screen info
HSPRITE hHudFont; // handle to creditsfont
wrect_t fontRc[256]; // rectangles
bool use_qfont; // use half-life creditsfont with variable charWidth
client_textmessage_t *titles; // title messages, not network messages
int numTitles;
@ -280,14 +283,17 @@ typedef struct
netchan_t netchan;
int serverProtocol; // in case we are doing some kind of version hack
int challenge; // from the server to use for connecting
// internal shaders
shader_t consoleFont; // current console font
shader_t clientFont; // current client font
shader_t consoleBack; // console background
shader_t fillShader; // used for emulate FillRGBA to avoid wrong draw-sort
shader_t particle; // used for drawing quake1 particles (SV_ParticleEffect)
shader_t netIcon; // netIcon displayed bad network connection
shader_t pauseIcon; // draw 'paused' when game in-pause
shader_t loadingBar; // 'loading' progress bar
file_t *download; // file transfer from server
string downloadname;

View File

@ -225,7 +225,7 @@ void CL_StudioFxTransform( edict_t *ent, float transform[4][4] );
void CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity );
bool CL_GetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
bool CL_SetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
void CL_StudioEvent( dstudioevent_t *event, edict_t *ent );
void CL_StudioEvent( mstudioevent_t *event, edict_t *ent );
bool CL_GetComment( const char *demoname, char *comment );
trace_t CL_TraceLine( const vec3_t start, const vec3_t end );
lerpframe_t *CL_GetLerpFrame( int entityIndex );

View File

@ -468,7 +468,8 @@ bool Cmd_GetItemsList( const char *s, char *completedname, int length )
string matchbuf;
int i, numitems;
t = FS_Search( va( "scripts/items/%s*.txt", s ), true );
if( !clgame.itemspath[0] ) return false; // not in game yet
t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true );
if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf );

View File

@ -2328,14 +2328,19 @@ int pfnRegUserMsg( const char *pszName, int iSize )
return svc_bad;
}
if( sv.state == ss_active )
Host_Error( "REG_USER_MSG can only be done in spawn functions\n" );
// register new message
com.strncpy( svgame.msg[i].name, pszName, sizeof( svgame.msg[i].name ));
svgame.msg[i].size = iSize;
svgame.msg[i].number = i; // paranoid mode :-)
if( sv.state == ss_active )
{
MSG_WriteByte( &sv.multicast, svc_usermessage );
MSG_WriteString( &sv.multicast, pszName );
MSG_WriteByte( &sv.multicast, i );
MSG_WriteByte( &sv.multicast, (byte)iSize );
MSG_Send( MSG_ALL, vec3_origin, NULL );
}
return i;
}

View File

@ -50,11 +50,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define UI_CHECKBOX_PRESSED "gfx/shell/cb_down"
#define UI_CHECKBOX_ENABLED "gfx/shell/cb_checked"
#define UI_CURSOR_SIZE 40
#define UI_MAX_MENUDEPTH 8
#define UI_MAX_MENUITEMS 64
#define UI_CURSOR_SIZE 40
#define UI_PULSE_DIVISOR 75
#define UI_BLINK_TIME 250
#define UI_BLINK_MASK 499

View File

@ -161,33 +161,6 @@ typedef struct flat_s
short desc[2]; // probably not used
} flat_t;
#define QCHAR_WIDTH 16
#define QFONT_WIDTH 16 // valve fonts used contant sizes
#define QFONT_HEIGHT ((128 - 32) / 16)
/*
========================================================================
.QFONT image format
========================================================================
*/
typedef struct
{
short startoffset;
short charwidth;
} charset_t;
typedef struct
{
int width;
int height;
int rowcount;
int rowheight;
charset_t fontinfo[256];
byte data[4]; // variable sized
} qfont_t;
/*
========================================================================

View File

@ -68,11 +68,11 @@ bool Image_LoadFNT( const char *name, const byte *buffer, size_t filesize )
return false;
Mem_Copy( &font, buffer, sizeof( font ));
// swap lumps
font.width = LittleShort( font.width );
font.height = LittleShort( font.height );
font.rowcount = LittleShort( font.rowcount );
font.rowheight = LittleShort( font.rowheight );
// swap header
font.width = LittleLong( font.width );
font.height = LittleLong( font.height );
font.rowcount = LittleLong( font.rowcount );
font.rowheight = LittleLong( font.rowheight );
for( i = 0; i < 256; i++ )
{
@ -81,7 +81,7 @@ bool Image_LoadFNT( const char *name, const byte *buffer, size_t filesize )
}
// last sixty four bytes - what the hell ????
size = sizeof(qfont_t) - 4 + (128 * font.width * QCHAR_WIDTH) + sizeof( short ) + 768 + 64;
size = sizeof( qfont_t ) - 4 + ( 128 * font.width * QCHAR_WIDTH ) + sizeof( short ) + 768 + 64;
if( size != filesize )
{
@ -96,14 +96,10 @@ bool Image_LoadFNT( const char *name, const byte *buffer, size_t filesize )
image.height = font.height;
}
image.depth = 1;
image.type = PF_INDEXED_32; // 32-bit palette
if(!Image_LumpValidSize( name )) return false;
fin = buffer + sizeof( font ) - 4;
image.size = image.width * image.height;
pal = fin + image.size;
pal = fin + (image.width * image.height);
numcolors = BuffLittleShort( pal ), pal += sizeof( short );
image.flags |= IMAGE_HAS_ALPHA; // fonts always have transparency
@ -124,6 +120,9 @@ bool Image_LoadFNT( const char *name, const byte *buffer, size_t filesize )
return false;
}
image.depth = 1;
image.type = PF_INDEXED_32; // 32-bit palette
return FS_AddMipmapToPack( fin, image.width, image.height );
}
@ -136,10 +135,10 @@ bool Image_LoadMDL( const char *name, const byte *buffer, size_t filesize )
{
byte *fin;
size_t pixels;
dstudiotexture_t *pin;
mstudiotexture_t *pin;
int i, flags;
pin = (dstudiotexture_t *)buffer;
pin = (mstudiotexture_t *)buffer;
flags = LittleLong( pin->flags );
// Valve never used endian functions for studiomodels...

View File

@ -1411,7 +1411,9 @@ void _mem_printlist( size_t minallocationsize )
for( pool = poolchain; pool; pool = pool->next )
{
// poolnames can contain color symbols, make sure what color is reset
Msg( "%5luk (%5luk actual) %s (^7%+3li byte change)\n", (dword) ((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name, (long)pool->totalsize - pool->lastchecksize );
if( ((long)pool->totalsize - pool->lastchecksize ) != 0 )
Msg( "%5luk (%5luk actual) %s (^7%+3li byte change)\n", (dword)((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name, (long)pool->totalsize - pool->lastchecksize );
else Msg( "%5luk (%5luk actual) %s\n", (dword)((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name );
pool->lastchecksize = pool->totalsize;
for( mem = pool->chain; mem; mem = mem->next )
if( mem->size >= minallocationsize )

View File

@ -308,7 +308,6 @@ bool Sound_LoadOGG( const char *name, const byte *buffer, size_t filesize )
ov_decode_t ov_decode;
ov_callbacks_t ov_callbacks = { ovcm_read, ovcm_seek, ovc_close, ovcm_tell };
long done = 0, ret;
const char *comm;
int dummy;
// load the file
@ -361,14 +360,41 @@ bool Sound_LoadOGG( const char *name, const byte *buffer, size_t filesize )
if( vc )
{
comm = vorbis_comment_query( vc, "LOOP_START", 0 );
if( comm )
const char *start, *end, *looplength;
start = vorbis_comment_query( vc, "LOOP_START", 0 ); // DarkPlaces, and some Japanese app
if( start )
{
// FXIME: implement
Msg( "ogg 'cue' %d\n", com.atoi(comm) );
//sound.loopstart = bound( 0, com.atoi( comm ), sound.samples );
}
}
end = vorbis_comment_query( vc, "LOOP_END", 0 );
if( !end ) looplength = vorbis_comment_query( vc, "LOOP_LENGTH", 0 );
}
else
{
// RPG Maker VX
start = vorbis_comment_query( vc, "LOOPSTART", 0 );
if( start )
{
looplength = vorbis_comment_query( vc, "LOOPLENGTH", 0 );
if( !looplength ) end = vorbis_comment_query( vc, "LOOPEND", 0 );
}
else
{
// Sonic Robo Blast 2
start = vorbis_comment_query( vc, "LOOPPOINT", 0 );
}
}
if( start )
{
sound.loopstart = (uint)bound( 0, com.atof( start ), sound.samples );
if( end ) sound.samples = (uint)bound( 0, com.atof( end ), sound.samples );
else if( looplength )
{
size_t length = com.atof( looplength );
sound.samples = (uint)bound( 0, sound.loopstart + length, sound.samples );
}
}
}
// close file
ov_clear( &vf );

View File

@ -11,9 +11,9 @@
struct
{
dstudiohdr_t *hdr;
dstudiomodel_t *submodel;
dstudiobodyparts_t *bodypart;
studiohdr_t *hdr;
mstudiomodel_t *submodel;
mstudiobodyparts_t *bodypart;
matrix4x4 rotmatrix;
matrix4x4 bones[MAXSTUDIOBONES];
cplane_t planes[12];
@ -27,10 +27,10 @@ struct
===============================================================================
*/
int CM_StudioExtractBbox( dstudiohdr_t *phdr, int sequence, float *mins, float *maxs )
int CM_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs )
{
dstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
if( sequence == -1 ) return 0;
VectorCopy( pseqdesc[sequence].bbmin, mins );
@ -41,15 +41,15 @@ int CM_StudioExtractBbox( dstudiohdr_t *phdr, int sequence, float *mins, float *
int CM_StudioBodyVariations( model_t handle )
{
dstudiohdr_t *pstudiohdr;
dstudiobodyparts_t *pbodypart;
studiohdr_t *pstudiohdr;
mstudiobodyparts_t *pbodypart;
int i, count;
pstudiohdr = (dstudiohdr_t *)CM_Extradata( handle );
pstudiohdr = (studiohdr_t *)CM_Extradata( handle );
if( !pstudiohdr ) return 0;
count = 1;
pbodypart = (dstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex);
pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex);
// each body part has nummodels variations so there are as many total variations as there
// are in a matrix of each part by each other part
@ -87,9 +87,9 @@ void CM_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, con
{
int i, j;
float value;
dstudiobonecontroller_t *pbonecontroller;
mstudiobonecontroller_t *pbonecontroller;
pbonecontroller = (dstudiobonecontroller_t *)((byte *)studio.hdr + studio.hdr->bonecontrollerindex);
pbonecontroller = (mstudiobonecontroller_t *)((byte *)studio.hdr + studio.hdr->bonecontrollerindex);
for( j = 0; j < studio.hdr->numbonecontrollers; j++ )
{
@ -145,12 +145,12 @@ CM_StudioCalcBoneQuaterion
====================
*/
void CM_StudioCalcBoneQuaterion( int frame, float s, dstudiobone_t *pbone, dstudioanim_t *panim, float *adj, float *q )
void CM_StudioCalcBoneQuaterion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q )
{
int j, k;
vec4_t q1, q2;
vec3_t angle1, angle2;
dstudioanimvalue_t *panimvalue;
mstudioanimvalue_t *panimvalue;
for( j = 0; j < 3; j++ )
{
@ -160,7 +160,7 @@ void CM_StudioCalcBoneQuaterion( int frame, float s, dstudiobone_t *pbone, dstud
}
else
{
panimvalue = (dstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
k = frame;
// debug
@ -232,17 +232,17 @@ CM_StudioCalcBonePosition
====================
*/
void CM_StudioCalcBonePosition( int frame, float s, dstudiobone_t *pbone, dstudioanim_t *panim, float *adj, float *pos )
void CM_StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos )
{
int j, k;
dstudioanimvalue_t *panimvalue;
mstudioanimvalue_t *panimvalue;
for( j = 0; j < 3; j++ )
{
pos[j] = pbone->value[j]; // default;
if( panim->offset[j] != 0.0f )
{
panimvalue = (dstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
@ -298,11 +298,11 @@ CM_StudioCalcRotations
====================
*/
void CM_StudioCalcRotations( edict_t *e, float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdesc, dstudioanim_t *panim, float f )
void CM_StudioCalcRotations( edict_t *e, float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f )
{
int i;
int frame;
dstudiobone_t *pbone;
mstudiobone_t *pbone;
float adj[MAXSTUDIOCONTROLLERS];
float s, dadt = 1.0f; // noInterp
@ -315,7 +315,7 @@ void CM_StudioCalcRotations( edict_t *e, float pos[][3], vec4_t *q, dstudioseqde
s = (f - frame);
// add in programtic controllers
pbone = (dstudiobone_t *)((byte *)studio.hdr + studio.hdr->boneindex);
pbone = (mstudiobone_t *)((byte *)studio.hdr + studio.hdr->boneindex);
CM_StudioCalcBoneAdj( dadt, adj, e->v.controller, e->v.controller );
@ -342,7 +342,7 @@ StudioEstimateFrame
====================
*/
float CM_StudioEstimateFrame( edict_t *e, dstudioseqdesc_t *pseqdesc )
float CM_StudioEstimateFrame( edict_t *e, mstudioseqdesc_t *pseqdesc )
{
double f;
@ -417,16 +417,16 @@ CM_StudioGetAnim
====================
*/
dstudioanim_t *CM_StudioGetAnim( cmodel_t *m_pSubModel, dstudioseqdesc_t *pseqdesc )
mstudioanim_t *CM_StudioGetAnim( cmodel_t *m_pSubModel, mstudioseqdesc_t *pseqdesc )
{
dstudioseqgroup_t *pseqgroup;
mstudioseqgroup_t *pseqgroup;
cache_user_t *paSequences;
size_t filesize;
byte *buf;
pseqgroup = (dstudioseqgroup_t *)((byte *)studio.hdr + studio.hdr->seqgroupindex) + pseqdesc->seqgroup;
pseqgroup = (mstudioseqgroup_t *)((byte *)studio.hdr + studio.hdr->seqgroupindex) + pseqdesc->seqgroup;
if( pseqdesc->seqgroup == 0 )
return (dstudioanim_t *)((byte *)studio.hdr + pseqgroup->data + pseqdesc->animindex);
return (mstudioanim_t *)((byte *)studio.hdr + pseqgroup->data + pseqdesc->animindex);
paSequences = (cache_user_t *)m_pSubModel->submodels;
@ -455,7 +455,7 @@ dstudioanim_t *CM_StudioGetAnim( cmodel_t *m_pSubModel, dstudioseqdesc_t *pseqde
Mem_Copy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
Mem_Free( buf );
}
return (dstudioanim_t *)((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
return (mstudioanim_t *)((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
}
/*
@ -468,9 +468,9 @@ void CM_StudioSetupBones( edict_t *e )
int i, oldseq;
double f;
dstudiobone_t *pbones;
dstudioseqdesc_t *pseqdesc;
dstudioanim_t *panim;
mstudiobone_t *pbones;
mstudioseqdesc_t *pseqdesc;
mstudioanim_t *panim;
static float pos[MAXSTUDIOBONES][3];
static vec4_t q[MAXSTUDIOBONES];
@ -486,7 +486,7 @@ void CM_StudioSetupBones( edict_t *e )
oldseq = e->v.sequence; // TraceCode can't change sequence
if( e->v.sequence >= studio.hdr->numseq ) e->v.sequence = 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)studio.hdr + studio.hdr->seqindex) + e->v.sequence;
pseqdesc = (mstudioseqdesc_t *)((byte *)studio.hdr + studio.hdr->seqindex) + e->v.sequence;
f = CM_StudioEstimateFrame( e, pseqdesc );
@ -521,7 +521,7 @@ void CM_StudioSetupBones( edict_t *e )
}
}
pbones = (dstudiobone_t *)((byte *)studio.hdr + studio.hdr->boneindex);
pbones = (mstudiobone_t *)((byte *)studio.hdr + studio.hdr->boneindex);
for( i = 0; i < studio.hdr->numbones; i++ )
{
@ -543,7 +543,7 @@ StudioCalcAttachments
static void CM_StudioCalcAttachments( edict_t *e, int iAttachment, float *org, float *ang )
{
int i;
dstudioattachment_t *pAtt;
mstudioattachment_t *pAtt;
vec3_t axis[3];
vec3_t localOrg, localAng;
@ -556,7 +556,7 @@ static void CM_StudioCalcAttachments( edict_t *e, int iAttachment, float *org, f
iAttachment = bound( 0, iAttachment, studio.hdr->numattachments );
// calculate attachment points
pAtt = (dstudioattachment_t *)((byte *)studio.hdr + studio.hdr->attachmentindex);
pAtt = (mstudioattachment_t *)((byte *)studio.hdr + studio.hdr->attachmentindex);
for( i = 0; i < studio.hdr->numattachments; i++ )
{
@ -623,7 +623,7 @@ bool CM_StudioSetup( edict_t *e )
if( mod && mod->type == mod_studio && mod->extradata )
{
studio.hdr = (dstudiohdr_t *)mod->extradata;
studio.hdr = (studiohdr_t *)mod->extradata;
CM_StudioSetUpTransform( e );
CM_StudioSetupBones( e );
return true;
@ -740,7 +740,7 @@ bool CM_StudioTrace( edict_t *e, const vec3_t start, const vec3_t end, trace_t *
for( i = 0; i < studio.hdr->numhitboxes; i++ )
{
dstudiobbox_t *phitbox = (dstudiobbox_t *)((byte*)studio.hdr + studio.hdr->hitboxindex) + i;
mstudiobbox_t *phitbox = (mstudiobbox_t *)((byte*)studio.hdr + studio.hdr->hitboxindex) + i;
Matrix4x4_Invert_Simple( m, studio.bones[phitbox->bone] );
Matrix4x4_VectorTransform( m, start, start_l );
@ -776,7 +776,7 @@ bool CM_StudioTrace( edict_t *e, const vec3_t start, const vec3_t end, trace_t *
}
else
{
dstudiobone_t *pbone = (dstudiobone_t *)((byte*)studio.hdr + studio.hdr->boneindex) + outBone;
mstudiobone_t *pbone = (mstudiobone_t *)((byte*)studio.hdr + studio.hdr->boneindex) + outBone;
// MsgDev( D_INFO, "Bone name %s\n", pbone->name ); // debug
VectorLerp( start, tr->flFraction, end, tr->vecEndPos );
@ -821,10 +821,10 @@ void CM_GetBonePosition( edict_t* e, int iBone, float *org, float *ang )
void CM_StudioModel( cmodel_t *mod, byte *buffer )
{
dstudiohdr_t *phdr;
dstudioseqdesc_t *pseqdesc;
studiohdr_t *phdr;
mstudioseqdesc_t *pseqdesc;
phdr = (dstudiohdr_t *)buffer;
phdr = (studiohdr_t *)buffer;
if( phdr->version != STUDIO_VERSION )
{
MsgDev( D_ERROR, "CM_StudioModel: %s has wrong version number (%i should be %i)\n", loadmodel->name, phdr->version, STUDIO_VERSION );
@ -832,7 +832,7 @@ void CM_StudioModel( cmodel_t *mod, byte *buffer )
}
loadmodel->type = mod_studio;
pseqdesc = (dstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
loadmodel->numframes = pseqdesc[0].numframes;
loadmodel->registration_sequence = cm.registration_sequence;

View File

@ -30,39 +30,26 @@
#define PLANE_Z 2
#define PLANE_NONAXIAL 3
#define METERS_PER_INCH 0.0254f
#define EQUAL_EPSILON 0.001f
#define STOP_EPSILON 0.1f
#define ON_EPSILON 0.1f
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
#define METER2INCH(x) (float)(x * (1.0f/METERS_PER_INCH))
#define INCH2METER(x) (float)(x * (METERS_PER_INCH/1.0f))
#define RAD_TO_STUDIO (32768.0 / M_PI)
#define STUDIO_TO_RAD (M_PI / 32768.0)
#define nanmask (255<<23)
#define Q_rint(x) ((x) < 0 ? ((int)((x)-0.5f)) : ((int)((x)+0.5f)))
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define RANDOM_LONG(MIN, MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN))
#define RANDOM_FLOAT(MIN,MAX) (((float)rand() / RAND_MAX) * ((MAX)-(MIN)) + (MIN))
#define NUMVERTEXNORMALS 162 // quake avertex normals
#define VectorIsNAN(v) (IS_NAN(v[0]) || IS_NAN(v[1]) || IS_NAN(v[2]))
#define VectorToPhysic(v) { v[0] = INCH2METER(v[0]), v[1] = INCH2METER(v[1]), v[2] = INCH2METER(v[2]); }
#define VectorToServer(v) { v[0] = METER2INCH(v[0]), v[1] = METER2INCH(v[1]), v[2] = METER2INCH(v[2]); }
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
#define Vector4Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3])
#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
#define Vector2Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])
#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
#define VectorScale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale))
#define Vector4Scale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale),(out)[3] = (in)[3] * (scale))
#define VectorMultiply(a,b,c) ((c)[0]=(a)[0]*(b)[0],(c)[1]=(a)[1]*(b)[1],(c)[2]=(a)[2]*(b)[2])
#define VectorCompare(v1,v2) ((v1)[0]==(v2)[0] && (v1)[1]==(v2)[1] && (v1)[2]==(v2)[2])
#define VectorDivide( in, d, out ) VectorScale( in, (1.0f / (d)), out )
#define VectorMax(a) ( max((a)[0], max((a)[1], (a)[2])) )
@ -76,45 +63,18 @@
#define VectorSet(v, x, y, z) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z))
#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3] = (d))
#define VectorClear(x) ((x)[0]=(x)[1]=(x)[2]=0)
#define Vector4Clear(x) ((x)[0]=(x)[1]=(x)[2]=(x)[3]=0)
#define Vector2Lerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]))
#define VectorLerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
#define VectorNormalize( v ) { float ilength = (float)com.sqrt(DotProduct(v, v));if (ilength) ilength = 1.0f / ilength;v[0] *= ilength;v[1] *= ilength;v[2] *= ilength; }
#define VectorNormalize2( v, dest ) {float ilength = (float)com.sqrt(DotProduct(v,v));if (ilength) ilength = 1.0f / ilength;dest[0] = v[0] * ilength;dest[1] = v[1] * ilength;dest[2] = v[2] * ilength; }
#define VectorNormalizeFast( v ) {float ilength = (float)rsqrt(DotProduct(v,v)); v[0] *= ilength; v[1] *= ilength; v[2] *= ilength; }
#define VectorNormalizeLength( v ) VectorNormalizeLength2((v), (v))
#define VectorNegate(x, y) ((y)[0] = -(x)[0], (y)[1] = -(x)[1], (y)[2] = -(x)[2])
#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2])
#define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2])
#define VectorMAM(scale1, b1, scale2, b2, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2])
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2])
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0] + (scale4) * (b4)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1] + (scale4) * (b4)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2] + (scale4) * (b4)[2])
#define VectorReflect( a, r, b, c ) do{ double d; d = DotProduct((a), (b)) * -(1.0 + (r)); VectorMA((a), (d), (b), (c)); } while( 0 )
#define BoxesOverlap(a,b,c,d) ((a)[0] <= (d)[0] && (b)[0] >= (c)[0] && (a)[1] <= (d)[1] && (b)[1] >= (c)[1] && (a)[2] <= (d)[2] && (b)[2] >= (c)[2])
#define BoxInsideBox(a,b,c,d) ((a)[0] >= (c)[0] && (b)[0] <= (d)[0] && (a)[1] >= (c)[1] && (b)[1] <= (d)[1] && (a)[2] >= (c)[2] && (b)[2] <= (d)[2])
#define TriangleOverlapsBox( a, b, c, d, e ) (min((a)[0], min((b)[0], (c)[0])) < (e)[0] && max((a)[0], max((b)[0], (c)[0])) > (d)[0] && min((a)[1], min((b)[1], (c)[1])) < (e)[1] && max((a)[1], max((b)[1], (c)[1])) > (d)[1] && min((a)[2], min((b)[2], (c)[2])) < (e)[2] && max((a)[2], max((b)[2], (c)[2])) > (d)[2])
#define TriangleNormal( a, b, c, n) ((n)[0] = ((a)[1] - (b)[1]) * ((c)[2] - (b)[2]) - ((a)[2] - (b)[2]) * ((c)[1] - (b)[1]), (n)[1] = ((a)[2] - (b)[2]) * ((c)[0] - (b)[0]) - ((a)[0] - (b)[0]) * ((c)[2] - (b)[2]), (n)[2] = ((a)[0] - (b)[0]) * ((c)[1] - (b)[1]) - ((a)[1] - (b)[1]) * ((c)[0] - (b)[0]))
#define MakeRGBA( out, x, y, z, w ) Vector4Set( out, x, y, z, w )
#define Square(x) ((x)*(x))
_inline float anglemod(const float a){ return(360.0/65536) * ((int)(a*(65536/360.0)) & 65535); }
// NOTE: this code contain bug, what may invoked infinity loop
_inline int nearest_pow( int size )
{
int i = 2;
while( 1 )
{
i <<= 1;
if( size == i ) return i;
if( size > i && size < (i <<1))
{
if( size >= ((i+(i<<1))/2))
return i<<1;
else return i;
}
}
}
/*
=================
rsqrt
@ -137,48 +97,6 @@ _inline float rsqrt( float number )
return y;
}
// remap a value in the range [A,B] to [C,D].
_inline float RemapVal( float val, float A, float B, float C, float D )
{
return C + (D - C) * (val - A) / (B - A);
}
_inline float ApproachVal( float target, float value, float speed )
{
float delta = target - value;
if( delta > speed )
value += speed;
else if( delta < -speed )
value -= speed;
else value = target;
return value;
}
_inline static bool VectorCompareEpsilon( const vec3_t v1, const vec3_t v2, const float epsilon )
{
vec3_t d;
VectorSubtract( v1, v2, d );
d[0] = fabs( d[0] );
d[1] = fabs( d[1] );
d[2] = fabs( d[2] );
if( d[0] > epsilon || d[1] > epsilon || d[2] > epsilon )
return false;
return true;
}
_inline void VectorBound( const float min, vec3_t v, const float max )
{
v[0] = bound(min, v[0], max);
v[1] = bound(min, v[1], max);
v[2] = bound(min, v[2], max);
}
// FIXME: convert to #define
_inline float VectorNormalizeLength2( const vec3_t v, vec3_t out )
{
float length, ilength;
@ -197,16 +115,17 @@ _inline float VectorNormalizeLength2( const vec3_t v, vec3_t out )
return length;
}
#define VectorNormalizeLength( v ) VectorNormalizeLength2((v), (v))
_inline bool VectorIsNull( const vec3_t v )
{
int i;
float result = 0;
int i;
float result = 0.0f;
if(!v) return true;
for (i = 0; i< 3; i++) result += v[i];
if(result != 0) return false;
if( !v ) return true;
for( i = 0; i< 3; i++ )
result += v[i];
if( result != 0.0f )
return false;
return true;
}
@ -391,36 +310,6 @@ _inline void AngleVectorsFLU(const vec3_t angles, vec3_t forward, vec3_t left, v
}
}
// FIXME: get rid of this
_inline void MatrixAngles( matrix3x3 matrix, vec3_t angles )
{
vec3_t forward, right, up;
float xyDist;
forward[0] = matrix[0][0];
forward[1] = matrix[0][2];
forward[2] = matrix[0][1];
right[0] = matrix[1][0];
right[1] = matrix[1][2];
right[2] = matrix[1][1];
up[2] = matrix[2][1];
xyDist = com.sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
if ( xyDist > EQUAL_EPSILON ) // enough here to get angles?
{
angles[1] = RAD2DEG( com.atan2( forward[1], forward[0] ));
angles[0] = RAD2DEG( com.atan2( -forward[2], xyDist ));
angles[2] = RAD2DEG( com.atan2( -right[2], up[2] ));
}
else
{
angles[1] = RAD2DEG( com.atan2( right[0], -right[1] ) );
angles[0] = RAD2DEG( com.atan2( -forward[2], xyDist ) );
angles[2] = 0;
}
}
/*
====================
AngleQuaternion
@ -429,8 +318,8 @@ AngleQuaternion
*/
_inline void AngleQuaternion( float *angles, vec4_t q )
{
float angle;
float sr, sp, sy, cr, cp, cy;
float angle;
float sr, sp, sy, cr, cp, cy;
// FIXME: rescale the inputs to 1/2 angle
angle = angles[2] * 0.5;
@ -454,21 +343,22 @@ QuaternionSlerp
*/
_inline void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
{
int i;
float omega, cosom, sinom, sclp, sclq;
int i;
// decide if one of the quaternions is backwards
float a = 0;
float b = 0;
for (i = 0; i < 4; i++)
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)
if( a > b )
{
for (i = 0; i < 4; i++)
for( i = 0; i < 4; i++ )
{
q[i] = -q[i];
}
@ -476,21 +366,23 @@ _inline void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
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 )
{
if ((1.0 - cosom) > 0.000001)
if(( 1.0 - cosom ) > 0.000001 )
{
omega = com.acos( cosom );
sinom = com.sin( omega );
sclp = com.sin( (1.0 - t)*omega) / sinom;
sclq = com.sin( t*omega ) / sinom;
sclp = com.sin(( 1.0 - t ) * omega ) / sinom;
sclq = com.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];
for( i = 0; i < 4; i++ )
qt[i] = sclp * p[i] + sclq * q[i];
}
else
{
@ -498,12 +390,11 @@ _inline void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
qt[1] = q[0];
qt[2] = -q[3];
qt[3] = q[2];
sclp = com.sin( (1.0 - t) * (0.5 * M_PI));
sclq = com.sin( t * (0.5 * M_PI));
for (i = 0; i < 3; i++)
{
sclp = com.sin(( 1.0 - t ) * ( 0.5 * M_PI ));
sclq = com.sin( t * ( 0.5 * M_PI ));
for( i = 0; i < 3; i++ )
qt[i] = sclp * p[i] + sclq * qt[i];
}
}
}
@ -535,26 +426,6 @@ _inline bool BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, con
return true;
}
_inline bool PlaneIntersect( vec3_t p_n, vec_t p_d, vec3_t l_o, vec3_t l_n, vec3_t out )
{
float dot, t;
dot = DotProduct( p_n, l_n );
if( dot > -0.001 )
return false;
t = (p_d - (l_o[0] * p_n[0]) - (l_o[1] * p_n[1]) - (l_o[2] * p_n[2])) / dot;
if( out )
{
out[0] = l_o[0] + (t * l_n[0]);
out[1] = l_o[1] + (t * l_n[1]);
out[2] = l_o[2] + (t * l_n[2]);
}
return true;
}
_inline static int PlaneTypeForNormal( const vec3_t normal )
{
if( normal[0] == 1.0 ) return PLANE_X;
@ -579,40 +450,9 @@ _inline static int SignbitsForPlane( const vec3_t normal )
return bits;
}
#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
#define NUM_HULL_ROUNDS (sizeof(hull_table) / sizeof(word))
#define HULL_PRECISION 4
static word hull_table[] = { 0, 4, 8, 16, 18, 24, 28, 30, 32, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
_inline void CM_RoundUpHullSize( vec3_t size )
{
int i, j;
for(i = 0; i < 3; i++)
{
bool negative = false;
float result, value;
value = ceil(size[i] + 0.5f); // round it
if(value < 0) negative = true;
value = fabs( value ); // make positive
// lookup hull table
for(j = 0; j < NUM_HULL_ROUNDS; j++)
{
result = value - hull_table[j];
if(result <= HULL_PRECISION)
{
result = negative ? -hull_table[j] : hull_table[j];
break;
}
}
size[i] = result; // copy new value
}
}
/*
=================
RadiusFromBounds
@ -630,91 +470,6 @@ _inline float RadiusFromBounds( vec3_t mins, vec3_t maxs )
return VectorLength( corner );
}
/*
====================
RotatePointAroundVector
====================
*/
_inline void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
{
float t0, t1;
float angle, c, s;
vec3_t vr, vu, vf;
angle = DEG2RAD( degrees );
com.sincos( angle, &s, &c );
VectorCopy( dir, vf );
VectorVectors( vf, vr, vu );
t0 = vr[0] * c + vu[0] * -s;
t1 = vr[0] * s + vu[0] * c;
dst[0] = (t0 * vr[0] + t1 * vu[0] + vf[0] * vf[0]) * point[0]
+ (t0 * vr[1] + t1 * vu[1] + vf[0] * vf[1]) * point[1]
+ (t0 * vr[2] + t1 * vu[2] + vf[0] * vf[2]) * point[2];
t0 = vr[1] * c + vu[1] * -s;
t1 = vr[1] * s + vu[1] * c;
dst[1] = (t0 * vr[0] + t1 * vu[0] + vf[1] * vf[0]) * point[0]
+ (t0 * vr[1] + t1 * vu[1] + vf[1] * vf[1]) * point[1]
+ (t0 * vr[2] + t1 * vu[2] + vf[1] * vf[2]) * point[2];
t0 = vr[2] * c + vu[2] * -s;
t1 = vr[2] * s + vu[2] * c;
dst[2] = (t0 * vr[0] + t1 * vu[0] + vf[2] * vf[0]) * point[0]
+ (t0 * vr[1] + t1 * vu[1] + vf[2] * vf[1]) * point[1]
+ (t0 * vr[2] + t1 * vu[2] + vf[2] * vf[2]) * point[2];
}
// assumes "src" is normalized
_inline void PerpendicularVector( vec3_t dst, const vec3_t src )
{
// LordHavoc: optimized to death and beyond
int pos;
float minelem;
if( src[0] )
{
dst[0] = 0;
if( src[1] )
{
dst[1] = 0;
if( src[2] )
{
dst[2] = 0;
pos = 0;
minelem = fabs( src[0] );
if( fabs(src[1]) < minelem )
{
pos = 1;
minelem = fabs( src[1] );
}
if( fabs( src[2]) < minelem )
pos = 2;
dst[pos] = 1;
dst[0] -= src[pos] * src[0];
dst[1] -= src[pos] * src[1];
dst[2] -= src[pos] * src[2];
// normalize the result
VectorNormalize( dst );
}
else dst[2] = 1;
}
else
{
dst[1] = 1;
dst[2] = 0;
}
}
else
{
dst[0] = 1;
dst[1] = 0;
dst[2] = 0;
}
}
/*
=================
SimpleSpline

View File

@ -41,6 +41,33 @@ infotable dlumpinfo_t[dwadinfo_t->numlumps]
#define TYPE_STRDATA 72 // stringdata type (stringtable marked as TYPE_BINDATA)
#define TYPE_SCRIPT 73 // .qc scripts (xash ext)
/*
========================================================================
.QFONT image format
========================================================================
*/
#define QCHAR_WIDTH 16
#define QFONT_WIDTH 16 // valve fonts used contant sizes
#define QFONT_HEIGHT ((128 - 32) / 16)
typedef struct
{
short startoffset;
short charwidth;
} charset_t;
typedef struct
{
int width;
int height;
int rowcount;
int rowheight;
charset_t fontinfo[256];
byte data[4]; // variable sized
} qfont_t;
/*
==============================================================================
@ -153,7 +180,7 @@ typedef struct mip_s
uint offsets[4]; // four mip maps stored
} mip_t;
#include "studio_ref.h"
#include "studio.h"
/*
========================================================================

View File

@ -13,6 +13,7 @@
#define SHADER_NOMIP 3 // 2d images
#define SHADER_GENERIC 4 // generic shader
#define SHADER_DECAL 5
#define SHADER_SPRITE 6
// dlight flags
#define DLIGHT_ONLYENTS BIT( 0 )
@ -220,7 +221,7 @@ typedef struct render_imp_s
// client fundamental callbacks
void (*UpdateScreen)( void ); // update screen while loading
void (*StudioEvent)( dstudioevent_t *event, edict_t *ent );
void (*StudioEvent)( mstudioevent_t *event, edict_t *ent );
void (*StudioFxTransform)( edict_t *ent, float matrix[4][4] );
void (*ShowCollision)( cmdraw_t callback ); // debug
long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam );

View File

@ -29,15 +29,9 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% spirit/spirit.dsp %CONFIG%"spirit - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% snd_al/snd_al.dsp %CONFIG%"snd_al - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% snd_dx/snd_dx.dsp %CONFIG%"snd_dx - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
@ -70,9 +64,7 @@ if exist engine\engine.plg del /f /q engine\engine.plg
if exist launch\launch.plg del /f /q launch\launch.plg
if exist physic\physic.plg del /f /q physic\physic.plg
if exist vid_gl\vid_gl.plg del /f /q vid_gl\vid_gl.plg
if exist server\server.plg del /f /q server\server.plg
if exist spirit\spirit.plg del /f /q spirit\spirit.plg
if exist snd_al\snd_al.plg del /f /q snd_al\snd_al.plg
if exist snd_dx\snd_dx.plg del /f /q snd_dx\snd_dx.plg
if exist xtools\xtools.plg del /f /q xtools\xtools.plg

View File

@ -1,38 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
// stdafx.h
//=======================================================================
#ifndef CBASE_H
#define CBASE_H
class CBaseEntity;
class CBaseLogic;
class CBaseBrush;
class CBaseAnimating;
class CBaseMonster;
class CBasePlayerWeapon;
class CSquadMonster;
class CBaseMonster;
class CCineMonster;
class CBasePlayer;
class CSound;
#include "hierarchy.h"
#include "globals.h"
#include "utils.h"
#include "saverestore.h"
#include "schedule.h"
#include "studio_ref.h"
#include "defaults.h"
#include "monsterevent.h"
#include "baseentity.h"
#include "baselogic.h"
#include "basesprite.h"
#include "baseinfo.h"
#include "baseanimating.h"
#include "baseitem.h"
#include "basebrush.h"
#include "basemonster.h"
#include "baseworld.h"
#endif //CBASE_H

View File

@ -1,115 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASEBEAMS_H
#define BASEBEAMS_H
#include "beam_def.h"
#define SF_BEAM_TEMPORARY 0x8000
#define SF_BEAM_TRIPPED 0x80000 // bit who indicated "trip" action
class CBeam : public CBaseLogic
{
public:
void Spawn( void );
int ObjectCaps( void )
{
int flags = 0;
if ( pev->spawnflags & SF_BEAM_TEMPORARY )
flags = FCAP_DONT_SAVE;
return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags;
}
void Touch( CBaseEntity *pOther );
// These functions are here to show the way beams are encoded as entities.
// Encoding beams as entities simplifies their management in the client/server architecture
inline void SetType( int type ) { pev->rendermode = type; }
inline void SetFlags( int flags ) { pev->renderfx |= flags; }
inline void SetStartPos( const Vector& pos ) { pev->origin = pos; }
inline void SetEndPos( const Vector& pos ) { pev->oldorigin = pos; }
inline void SetStartEntity( edict_t *pEnt ) { pev->aiment = pEnt; }
inline void SetEndEntity( edict_t *pEnt ) { pev->owner = pEnt; }
inline void SetStartAttachment( int attachment ) { pev->colormap = (pev->colormap & 0xFF00)>>8 | attachment; }
inline void SetEndAttachment( int attachment ) { pev->colormap = (pev->colormap & 0xFF) | (attachment<<8); }
inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; }
inline void SetWidth( int width ) { pev->scale = width; }
inline void SetNoise( int amplitude ) { pev->body = amplitude; }
inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; }
inline void SetBrightness( int brightness ) { pev->renderamt = brightness; }
inline void SetFrame( float frame ) { pev->frame = frame; }
inline void SetScrollRate( int speed ) { pev->animtime = speed; }
inline int GetType( void ) { return pev->rendermode; }
inline int GetFlags( void ) { return pev->renderfx; }
inline edict_t *GetStartEntity( void ) { return pev->owner; }
inline edict_t *GetEndEntity( void ) { return pev->aiment; }
const Vector &GetStartPos( void );
const Vector &GetEndPos( void );
Vector Center( void ) { return (GetStartPos() + GetEndPos()) * 0.5; }; // center point of beam
inline int GetTexture( void ) { return pev->modelindex; }
inline int GetWidth( void ) { return pev->scale; }
inline int GetNoise( void ) { return pev->body; }
inline Vector GetColor( void ) { return Vector( pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z ); }
inline int GetBrightness( void ) { return pev->renderamt; }
inline int GetFrame( void ) { return pev->frame; }
inline int GetScrollRate( void ) { return pev->animtime; }
CBaseEntity* GetTripEntity( TraceResult *ptr );
// Call after you change start/end positions
void RelinkBeam( void );
void SetObjectCollisionBox( void );
void DoSparks( const Vector &start, const Vector &end );
CBaseEntity *RandomTargetname( const char *szName );
void BeamDamage( TraceResult *ptr );
// Init after BeamCreate()
void BeamInit( const char *pSpriteName, int width );
void PointsInit( const Vector &start, const Vector &end );
void PointEntInit( const Vector &start, edict_t *pEnd );
void EntsInit( edict_t *pStart, edict_t *pEnd );
void HoseInit( const Vector &start, const Vector &direction );
static CBeam *BeamCreate( const char *pSpriteName, int width );
inline void LiveForTime( float time ) { SetThink( Remove ); SetNextThink( time ); }
inline void BeamDamageInstant( TraceResult *ptr, float damage )
{
pev->dmg = damage;
pev->dmgtime = gpGlobals->time - 1;
BeamDamage(ptr);
}
};
class CLaser : public CBeam
{
public:
void Spawn( void );
void PostSpawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void Activate( void );
void SetObjectCollisionBox( void );
void TurnOn( void );
void TurnOff( void );
void FireAtPoint( Vector startpos, TraceResult &point );
void Think( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CSprite *m_pStartSprite;
CSprite *m_pEndSprite;
};
#endif //BASEBEAMS_H

View File

@ -1,861 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// basebreak.cpp - base for all brush
// entities.
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "sfx.h"
#include "cbase.h"
#include "decals.h"
#include "client.h"
#include "soundent.h"
#include "saverestore.h"
#include "gamerules.h"
#include "basebrush.h"
#include "defaults.h"
#include "player.h"
//=======================================================================
// STATIC BREACABLE BRUSHES
//=======================================================================
#define DAMAGE_SOUND(x, y, z)EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, x[RANDOM_LONG(0, ARRAYSIZE(x)-1)], y, ATTN_NORM, 0, z)
//spawn objects
const char *CBaseBrush::pSpawnObjects[] =
{
NULL, // 0
"item_battery", // 1
"item_healthkit", // 2
"weapon_9mmhandgun", // 3
"ammo_9mmclip", // 4
"weapon_9mmAR", // 5
"ammo_9mmAR", // 6
"ammo_m203", // 7
"weapon_shotgun", // 8
"ammo_buckshot", // 9
"weapon_crossbow", // 10
"ammo_crossbow", // 11
"weapon_357", // 12
"ammo_357", // 13
"weapon_rpg", // 14
"ammo_rpgclip", // 15
"ammo_gaussclip", // 16
"weapon_handgrenade", // 17
"weapon_gauss", // 18
};
//material sounds
const char *CBaseBrush::pSoundsWood[] =
{
"materials/wood/wood1.wav",
"materials/wood/wood2.wav",
"materials/wood/wood3.wav",
"materials/wood/wood4.wav",
};
const char *CBaseBrush::pSoundsFlesh[] =
{
"materials/flesh/flesh1.wav",
"materials/flesh/flesh2.wav",
"materials/flesh/flesh3.wav",
"materials/flesh/flesh4.wav",
"materials/flesh/flesh5.wav",
"materials/flesh/flesh6.wav",
"materials/flesh/flesh7.wav",
"materials/flesh/flesh8.wav",
};
const char *CBaseBrush::pSoundsMetal[] =
{
"materials/metal/metal1.wav",
"materials/metal/metal2.wav",
"materials/metal/metal3.wav",
"materials/metal/metal4.wav",
"materials/metal/metal5.wav",
};
const char *CBaseBrush::pSoundsCrete[] =
{
"materials/crete/concrete1.wav",
"materials/crete/concrete2.wav",
"materials/crete/concrete3.wav",
"materials/crete/concrete4.wav",
"materials/crete/concrete5.wav",
"materials/crete/concrete6.wav",
"materials/crete/concrete7.wav",
"materials/crete/concrete8.wav",
};
const char *CBaseBrush::pSoundsGlass[] =
{
"materials/glass/glass1.wav",
"materials/glass/glass2.wav",
"materials/glass/glass3.wav",
"materials/glass/glass4.wav",
"materials/glass/glass5.wav",
"materials/glass/glass6.wav",
"materials/glass/glass7.wav",
"materials/glass/glass8.wav",
};
const char *CBaseBrush::pSoundsCeil[] =
{
"materials/ceil/ceiling1.wav",
"materials/ceil/ceiling2.wav",
"materials/ceil/ceiling3.wav",
"materials/ceil/ceiling4.wav",
};
const char **CBaseBrush::MaterialSoundList( Materials precacheMaterial, int &soundCount )
{
const char **pSoundList = NULL;
switch ( precacheMaterial )
{
case None:
soundCount = 0;
break;
case Bones:
case Flesh:
pSoundList = pSoundsFlesh;
soundCount = ARRAYSIZE(pSoundsFlesh);
break;
case CinderBlock:
case Concrete:
case Rocks:
pSoundList = pSoundsCrete;
soundCount = ARRAYSIZE(pSoundsCrete);
break;
case Glass:
case Computer:
case UnbreakableGlass:
pSoundList = pSoundsGlass;
soundCount = ARRAYSIZE(pSoundsGlass);
break;
case MetalPlate:
case AirDuct:
case Metal:
pSoundList = pSoundsMetal;
soundCount = ARRAYSIZE(pSoundsMetal);
break;
case CeilingTile:
pSoundList = pSoundsCeil;
soundCount = ARRAYSIZE(pSoundsCeil);
break;
case Wood:
pSoundList = pSoundsWood;
soundCount = ARRAYSIZE(pSoundsWood);
break;
default:
soundCount = 0;
break;
}
return pSoundList;
}
void CBaseBrush::MaterialSoundPrecache( Materials precacheMaterial )
{
const char **pSoundList;
int i, soundCount = 0;
pSoundList = MaterialSoundList( precacheMaterial, soundCount );
for ( i = 0; i < soundCount; i++ ) UTIL_PrecacheSound( (char *)pSoundList[i] );
}
void CBaseBrush::PlayRandomSound( edict_t *pEdict, Materials soundMaterial, float volume )
{
const char **pSoundList;
int soundCount = 0;
pSoundList = MaterialSoundList( soundMaterial, soundCount );
if ( soundCount ) EMIT_SOUND( pEdict, CHAN_BODY, pSoundList[ RANDOM_LONG(0, soundCount-1) ], volume, 1.0 );
}
void CBaseBrush :: AxisDir( void )
{
// make backward compatibility
if( pev->movedir != g_vecZero ) return;
// don't change this!
if( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS ))
pev->movedir = Vector ( 0, 0, 1 ); // around z-axis
else if( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS ))
pev->movedir = Vector ( 1, 0, 0 ); // around x-axis
else pev->movedir = Vector ( 0, 1, 0 ); // around y-axis
// check for reverse rotation
if( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_BACKWARDS ))
pev->movedir *= -1;
}
void CBaseBrush::KeyValue( KeyValueData* pkvd )
{
// as default all brushes can select material
// and set strength (0 = unbreakable)
if( FStrEq( pkvd->szKeyName, "material" ))
{
int i = atoi( pkvd->szValue);
if ((i < 0) || (i >= LastMaterial))
m_Material = Wood;
else m_Material = (Materials)i;
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "strength" ))
{
pev->health = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "spawnobject" ))
{
int namelen = strlen(pkvd->szValue) - 1;
int obj = atoi( pkvd->szValue );
// custom spawn object
if( namelen > 2 ) m_iSpawnObject = ALLOC_STRING( pkvd->szValue );
else if ( obj > 0 && obj < ARRAYSIZE(pSpawnObjects))
m_iSpawnObject = MAKE_STRING( pSpawnObjects[obj] );
pkvd->fHandled = TRUE;
}
else if (FStrEq( pkvd->szKeyName, "gibmodel" ))
{
m_iGibModel = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "volume"))
{
// 0.0 - silence, 1.0 - loudest( obsolete )
m_flVolume = atof( pkvd->szValue );
if( m_flVolume > 1.0 ) m_flVolume = 1.0;
if( m_flVolume < 0.0 ) m_flVolume = 0.0;
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "radius"))
{
m_flRadius = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "movesound" ) || FStrEq( pkvd->szKeyName, "sounds" ))
{
m_iMoveSound = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "stopsound" ))
{
m_iStopSound = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "contents" ))
{
pev->skin = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else CBaseLogic::KeyValue( pkvd );
}
//Base functions
TYPEDESCRIPTION CBaseBrush::m_SaveData[] =
{
DEFINE_FIELD( CBaseBrush, m_flVolume, FIELD_FLOAT ), // volume of sounds
DEFINE_FIELD( CBaseBrush, m_pitch, FIELD_FLOAT ), // pitch of sound
DEFINE_FIELD( CBaseBrush, m_Material, FIELD_INTEGER ), // brush material
DEFINE_FIELD( CBaseBrush, m_iMagnitude, FIELD_INTEGER ), // explosion magnitude
DEFINE_FIELD( CBaseBrush, m_iMoveSound, FIELD_STRING ), // sound scheme like Quake
DEFINE_FIELD( CBaseBrush, m_iStartSound, FIELD_STRING ), // sound scheme like Quake
DEFINE_FIELD( CBaseBrush, m_iStopSound, FIELD_STRING ), // sound scheme like Quake
DEFINE_FIELD( CBaseBrush, m_iSpawnObject, FIELD_STRING ), // spawnobject index
DEFINE_FIELD( CBaseBrush, m_iGibModel, FIELD_STRING ), // custom gibname
DEFINE_FIELD( CBaseBrush, m_vecPlayerPos, FIELD_VECTOR ), // for controllable entity like tank
DEFINE_FIELD( CBaseBrush, m_pController, FIELD_CLASSPTR ), // for controllable entity like tank
DEFINE_FIELD( CBaseBrush, m_flRadius, FIELD_FLOAT ), // volume of sounds
DEFINE_FIELD( CBaseBrush, m_flAccel, FIELD_FLOAT ), // volume of sounds
DEFINE_FIELD( CBaseBrush, m_flDecel, FIELD_FLOAT ), // volume of sounds
};
IMPLEMENT_SAVERESTORE( CBaseBrush, CBaseLogic );
void CBaseBrush::Spawn( void )
{
Precache();
if( !m_flVolume ) m_flVolume = 1.0; // just enable full volume
// breacable brush (if mapmaker just set material - just play material sound)
if( IsBreakable())
pev->takedamage = DAMAGE_YES;
else pev->takedamage = DAMAGE_NO;
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
if( !m_pParent ) pev->flags |= FL_WORLDBRUSH;
}
void CBaseBrush::Precache( void )
{
const char *pGibName = "";
switch (m_Material)
{
case Bones:
pGibName = "models/gibs/bones.mdl";
break;
case Flesh:
pGibName = "models/gibs/flesh.mdl";
UTIL_PrecacheSound("materials/flesh/bustflesh1.wav");
UTIL_PrecacheSound("materials/flesh/bustflesh2.wav");
break;
case Concrete:
pGibName = "models/gibs/concrete.mdl";
UTIL_PrecacheSound("materials/crete/bustcrete1.wav");
UTIL_PrecacheSound("materials/crete/bustcrete2.wav");
break;
case Rocks:
pGibName = "models/gibs/rock.mdl";
UTIL_PrecacheSound("materials/crete/bustcrete1.wav");
UTIL_PrecacheSound("materials/crete/bustcrete2.wav");
break;
case CinderBlock:
pGibName = "models/gibs/cinder.mdl";
UTIL_PrecacheSound("materials/crete/bustcrete1.wav");
UTIL_PrecacheSound("materials/crete/bustcrete2.wav");
break;
case Computer:
pGibName = "models/gibs/computer.mdl";
UTIL_PrecacheSound("materials/metal/bustmetal1.wav");
UTIL_PrecacheSound("materials/metal/bustmetal2.wav");
break;
case Glass:
case UnbreakableGlass:
pGibName = "models/gibs/glass.mdl";
UTIL_PrecacheSound("materials/glass/bustglass1.wav");
UTIL_PrecacheSound("materials/glass/bustglass2.wav");
break;
case MetalPlate:
pGibName = "models/gibs/metalplate.mdl";
UTIL_PrecacheSound("materials/metal/bustmetal1.wav");
UTIL_PrecacheSound("materials/metal/bustmetal2.wav");
break;
case Metal:
pGibName = "models/gibs/metal.mdl";
UTIL_PrecacheSound("materials/metal/bustmetal1.wav");
UTIL_PrecacheSound("materials/metal/bustmetal2.wav");
break;
case AirDuct:
pGibName = "models/gibs/vent.mdl";
UTIL_PrecacheSound("materials/metal/bustmetal1.wav");
UTIL_PrecacheSound("materials/metal/bustmetal2.wav");
break;
case CeilingTile:
pGibName = "models/gibs/ceiling.mdl";
UTIL_PrecacheSound("materials/ceil/bustceiling1.wav");
UTIL_PrecacheSound("materials/ceil/bustceiling2.wav");
break;
case Wood:
pGibName = "models/gibs/wood.mdl";
UTIL_PrecacheSound("materials/wood/bustcrate1.wav");
UTIL_PrecacheSound("materials/wood/bustcrate2.wav");
break;
case None:
default:
if( pev->health > 0 ) // mapmaker forget set material ?
{
DevMsg("\n======/Xash SmartField System/======\n\n");
DevMsg("Please set material for %s,\n", STRING(pev->classname));
DevMsg("if we want make this breakable\n");
}
break;
}
MaterialSoundPrecache( m_Material );
if(IsBreakable( ))
{
if( !FStringNull( m_iGibModel ) || !FStringNull( pGibName ))
m_idShard = UTIL_PrecacheModel( m_iGibModel, pGibName ); // precache model
if( m_iSpawnObject ) UTIL_PrecacheEntity( m_iSpawnObject );
}
UTIL_PrecacheModel( pev->model ); // can use *.mdl for any brush
}
void CBaseBrush :: DamageSound( void )
{
float fvol;
int pitch;
if (RANDOM_LONG(0,2)) pitch = PITCH_NORM;
else pitch = 95 + RANDOM_LONG(0,34);
fvol = RANDOM_FLOAT(m_flVolume/1.5, m_flVolume);
switch (m_Material)
{
case None: break;
case Bones:
case Flesh:
DAMAGE_SOUND(pSoundsFlesh, fvol, pitch );
break;
case CinderBlock:
case Concrete:
case Rocks:
DAMAGE_SOUND(pSoundsCrete, fvol, pitch );
break;
case Computer:
case Glass:
case UnbreakableGlass:
DAMAGE_SOUND(pSoundsGlass, fvol, pitch );
break;
case MetalPlate:
case AirDuct:
case Metal:
DAMAGE_SOUND(pSoundsMetal, fvol, pitch );
break;
case CeilingTile:
DAMAGE_SOUND(pSoundsCeil, fvol, pitch );
break;
case Wood:
DAMAGE_SOUND(pSoundsWood, fvol, pitch );
break;
default: break;
}
}
void CBaseBrush::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
switch( m_Material )//apply effects for some materials (may be extended in future)
{
case Computer:
{
if(RANDOM_LONG(0,1))UTIL_Sparks( ptr->vecEndPos );
float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range
switch ( RANDOM_LONG(0,1) )
{
case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "materials/spark5.wav", flVolume, ATTN_NORM); break;
case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "materials/spark6.wav", flVolume, ATTN_NORM); break;
}
}
break;
case Glass:
{
if(pev->health == 0)//unbreakable glass
{
if( RANDOM_LONG(0,1))UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) );
UTIL_DecalTrace(ptr, DECAL_BPROOF1);
}
else UTIL_DecalTrace(ptr, DECAL_GLASSBREAK1 + RANDOM_LONG(0, 2));//breakable glass
}
break;
case UnbreakableGlass:
UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) );
break;
}
CBaseLogic::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType );
}
int CBaseBrush :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
Vector vecTemp;
if ( pevAttacker == pevInflictor )
{
vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) );
if((pevAttacker->flags & FL_CLIENT) && (pev->spawnflags & SF_BREAK_CROWBAR) && (bitsDamageType & DMG_CLUB))
flDamage = pev->health; //old valve flag
}
else vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) );
if (!IsBreakable())
{
DamageSound();
return 0;
}
// Breakables take double damage from the crowbar
if ( bitsDamageType & DMG_CLUB ) flDamage *= 1.2;
else if( bitsDamageType & DMG_CRUSH ) flDamage *= 2;
else if( bitsDamageType & DMG_BLAST ) flDamage *= 3;
else if( bitsDamageType & DMG_BULLET && m_Material == Glass )flDamage *= 0.5;
else if( bitsDamageType & DMG_BULLET && m_Material == Wood )flDamage *= 0.7;
else flDamage = 0; //don't give any other damage
DmgType = bitsDamageType;//member damage type
g_vecAttackDir = vecTemp.Normalize();
pev->health -= flDamage;
if (pev->health <= 0)
{
Killed( pevAttacker, GIB_NORMAL );
Die();
return 0;
}
DamageSound();
return 1;
}
void CBaseBrush :: Blocked( CBaseEntity *pOther )
{
if(m_pParent && m_pParent->edict() && pFlags & PF_PARENTMOVE)//tell parent
m_pParent->Blocked( pOther );
if(!pOther->IsPlayer() && !pOther->IsMonster())//crash breakable
{
if(IsBreakable())TakeDamage( pev, pev, 5, DMG_CRUSH );
}
}
BOOL CBaseBrush :: IsBreakable( void )
{
return (pev->health > 0 && m_Material != UnbreakableGlass);
}
void CBaseBrush::Die( void )
{
Vector vecSpot, vecVelocity;
char cFlag = 0;
int pitch, soundbits = NULL;
float fvol;
pitch = 95 + RANDOM_LONG( 0, 29 );
if( pitch > 97 && pitch < 103 ) pitch = PITCH_NORM;
fvol = RANDOM_FLOAT(0.85, 1.0) + (abs( pev->health ) / 100.0);
if( fvol > 1.0 ) fvol = 1.0;
switch (m_Material)
{
case None: break; //just in case
case Bones:
case Flesh:
if(RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/flesh/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/flesh/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_FLESH;
soundbits = bits_SOUND_MEAT;
break;
case CinderBlock:
case Concrete:
case Rocks:
if(RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/crete/bustcrete1.wav", fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/crete/bustcrete2.wav", fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_CONCRETE;
soundbits = bits_SOUND_WORLD;
break;
case Computer:
case Metal:
case AirDuct:
case MetalPlate:
if(RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/metal/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/metal/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_METAL;
soundbits = bits_SOUND_WORLD;
break;
case Glass:
if( RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/glass/bustglass1.wav", fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/glass/bustglass2.wav", fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_GLASS;
soundbits = bits_SOUND_WORLD;
break;
case Wood:
if( RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/wood/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/wood/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_WOOD;
soundbits = bits_SOUND_WORLD;
break;
case CeilingTile:
if( RANDOM_LONG(0,1) )
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/ceil/bustceiling1.wav",fvol, ATTN_NORM, 0, pitch);
else EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "materials/ceil/bustceiling1.wav",fvol, ATTN_NORM, 0, pitch);
cFlag = BREAK_CONCRETE;
soundbits = bits_SOUND_GARBAGE;
break;
}
if (DmgType & DMG_CLUB)//direction from crowbar
vecVelocity = g_vecAttackDir * clamp(pev->dmg * -10, -1024, 1024);
else vecVelocity = UTIL_RandomVector() * clamp(pev->dmg * 10, 1, 240);
vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5;
float time = RANDOM_FLOAT(25, 100);
if(soundbits) CSoundEnt::InsertSound(soundbits, pev->origin, 128, 0.5);//make noise for ai
SFX_MakeGibs( m_idShard, vecSpot, pev->size, vecVelocity, time, cFlag);
//what the hell does this ?
UTIL_FindBreakable( this );
// If I'm getting removed, don't fire something that could fire myself
pev->targetname = 0;
pev->solid = SOLID_NOT;
UTIL_FireTargets( pev->target, NULL, NULL, USE_TOGGLE );
pev->target = 0;
SetThink( Remove );
SetNextThink( 0.1 );
pev->effects |= EF_NODRAW;
pev->takedamage = DAMAGE_NO;
//make explosion
if( m_iMagnitude ) UTIL_Explode( Center(), edict(), m_iMagnitude );
if( m_iSpawnObject ) CBaseEntity::Create( (char *)STRING(m_iSpawnObject), Center(), pev->angles, edict() );
// Fire targets on break
UTIL_Remove( this );
}
int CBaseBrush :: DamageDecal( int bitsDamageType )
{
if ( m_Material == Glass )
return DECAL_GLASSBREAK1 + RANDOM_LONG(0,2);
if ( m_Material == Glass && pev->health <= 0)
return DECAL_BPROOF1;
if ( m_Material == UnbreakableGlass )
return DECAL_BPROOF1;
if ( m_Material == Wood )
return DECAL_GUNSHOT1 + RANDOM_LONG(0,4);
if ( m_Material == Computer )
return DECAL_BIGSHOT1 + RANDOM_LONG(0,4);
return CBaseEntity::DamageDecal( bitsDamageType );
}
//=======================================================================
// moving breakable brushes
//=======================================================================
//material moving sounds
const char *CPushable::pPushWood[] =
{
"materials/wood/pushwood1.wav",
"materials/wood/pushwood2.wav",
"materials/wood/pushwood3.wav",
};
const char *CPushable::pPushFlesh[] =
{
"materials/flesh/pushflesh1.wav",
"materials/flesh/pushflesh2.wav",
"materials/flesh/pushflesh3.wav",
};
const char *CPushable::pPushMetal[] =
{
"materials/metal/pushmetal1.wav",
"materials/metal/pushmetal2.wav",
"materials/metal/pushmetal3.wav",
};
const char *CPushable::pPushCrete[] =
{
"materials/crete/pushstone1.wav",
"materials/crete/pushstone2.wav",
"materials/crete/pushstone3.wav",
};
const char *CPushable::pPushGlass[] =
{
"materials/glass/pushglass1.wav",
"materials/glass/pushglass2.wav",
"materials/glass/pushglass3.wav",
};
const char *CPushable::pPushCeil[] =
{
"materials/ceil/ceiling1.wav",
"materials/ceil/ceiling2.wav",
"materials/ceil/ceiling3.wav",
};
void CPushable :: Spawn( void )
{
Precache();
pev->movetype = MOVETYPE_PUSHSTEP;
pev->solid = SOLID_BBOX;
UTIL_SetModel( ENT(pev), pev->model );
UTIL_SetSize( pev, pev->absmin, pev->absmax );
if (!m_flVolume)m_flVolume = 1.0;//just enable full volume
//breacable brush (if mapmaker just set material - just play material sound)
if(m_Material != None)
pev->takedamage = DAMAGE_YES;
else pev->takedamage = DAMAGE_NO;
pev->speed = MatFrictionTable( m_Material );
SetBits( pev->flags, FL_FLOAT );
pev->origin.z += 1; // Pick up off of the floor
UTIL_SetOrigin( this, pev->origin );
// Multiply by area of the box's cross-section (assume 1000 units^3 standard volume)
pev->skin = MatByoancyTable( pev, m_Material );
pev->frags = 0;
}
void CPushable :: Precache( void )
{
CBaseBrush::Precache();
PushSoundPrecache( m_Material );
}
const char **CPushable::PushSoundList( Materials precacheMaterial, int &soundCount )
{
const char **pSoundList = NULL;
switch ( precacheMaterial )
{
case None:
soundCount = 0;
break;
case Bones:
case Flesh:
pSoundList = pPushFlesh;
soundCount = ARRAYSIZE(pPushFlesh);
break;
case CinderBlock:
case Concrete:
case Rocks:
pSoundList = pPushCrete;
soundCount = ARRAYSIZE(pPushCrete);
break;
case Computer:
case Glass:
pSoundList = pPushGlass;
soundCount = ARRAYSIZE(pPushGlass);
break;
case MetalPlate:
case AirDuct:
case Metal:
pSoundList = pPushMetal;
soundCount = ARRAYSIZE(pPushMetal);
break;
case CeilingTile:
pSoundList = pPushCeil;
soundCount = ARRAYSIZE(pPushCeil);
break;
case Wood:
pSoundList = pPushWood;
soundCount = ARRAYSIZE(pPushWood);
break;
default:
soundCount = 0;
break;
}
return pSoundList;
}
void CPushable::PushSoundPrecache( Materials precacheMaterial )
{
const char **pPushList;
int i, soundCount = 0;
pPushList = PushSoundList( precacheMaterial, soundCount );
for ( i = 0; i < soundCount; i++ ) UTIL_PrecacheSound( (char *)pPushList[i] );
}
int CPushable::PlayPushSound( edict_t *pEdict, Materials soundMaterial, float volume )
{
const char **pPushList;
int soundCount = 0;
int m_lastPushSnd = 0;
pPushList = PushSoundList( soundMaterial, soundCount );
if ( soundCount )
{
m_lastPushSnd = RANDOM_LONG(0, soundCount-1);
EMIT_SOUND( pEdict, CHAN_WEAPON, pPushList[ m_lastPushSnd ], volume, 1.0 );
}
return m_lastPushSnd;
}
void CPushable::StopPushSound( edict_t *pEdict, Materials soundMaterial, int m_lastPushSnd )
{
const char **pPushList;
int soundCount = 0;
pPushList = PushSoundList( soundMaterial, soundCount );
if ( soundCount ) STOP_SOUND( pEdict, CHAN_WEAPON, pPushList[ m_lastPushSnd ] );
}
void CPushable :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if(useType == USE_SHOWINFO)
{
DEBUGHEAD;
}
else if ( pActivator && pActivator->IsPlayer() && pActivator->pev->velocity != g_vecZero )
Move( pActivator, 0 );
}
void CPushable :: Touch( CBaseEntity *pOther )
{
if ( pOther == g_pWorld ) return;
Move( pOther, 1 );
}
void CPushable :: Move( CBaseEntity *pOther, int push )
{
entvars_t* pevToucher = pOther->pev;
int playerTouch = 0;
// Is entity standing on this pushable ?
if ( FBitSet(pevToucher->flags, FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev )
{
// Only push if floating
if ( pev->waterlevel > 0 && pev->watertype > CONTENTS_FLYFIELD )
pev->velocity.z += pevToucher->velocity.z * 0.1;
return;
}
if ( pOther->IsPlayer() )
{
// Don't push unless the player is pushing forward and NOT use (pull)
if ( push && !(pevToucher->button & (IN_FORWARD|IN_MOVERIGHT|IN_MOVELEFT|IN_BACK)) )
return;
if ( !push && !(pevToucher->button & IN_BACK) )
return;
playerTouch = 1;
}
float factor;
if ( playerTouch )
{
// Don't push away from jumping/falling players unless in water
if( !(pevToucher->flags & FL_ONGROUND) )
{
if ( pev->waterlevel < 1 || pev->watertype <= CONTENTS_FLYFIELD )
return;
else factor = 0.1;
}
else factor = 1;
}
else factor = 0.25;
if (!push) factor = factor*0.5;
pev->velocity.x += pevToucher->velocity.x * factor;
pev->velocity.y += pevToucher->velocity.y * factor;
float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y );
if ( push && (length > MaxSpeed()) )
{
pev->velocity.x = (pev->velocity.x * MaxSpeed() / length );
pev->velocity.y = (pev->velocity.y * MaxSpeed() / length );
}
if ( playerTouch )
{
pevToucher->velocity.x = pev->velocity.x;
pevToucher->velocity.y = pev->velocity.y;
if ( (gpGlobals->time - pev->frags) > 0.7 )
{
pev->frags = gpGlobals->time;
if ( length > 0 && FBitSet(pev->flags, FL_ONGROUND) )
m_lastSound = PlayPushSound( edict(), m_Material, m_flVolume );
else StopPushSound( edict(), m_Material, m_lastSound );
}
}
}
LINK_ENTITY_TO_CLASS( func_pushable, CPushable );

View File

@ -1,210 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// basebrush.h - base for all brush
// entities.
//=======================================================================
#ifndef BASEBRUSH_H
#define BASEBRUSH_H
//ANY BRUSH MAY BE SET MATERIAL
typedef enum {
Glass = 0, //glass.mdl
Wood, //wood.mdl
Metal, //metal.mdl
Flesh, //flesh.mdl
CinderBlock, //cinder.mdl
CeilingTile, //ceiling.mdl
Computer, //computer.mdl
UnbreakableGlass, //galss.mdl
Rocks, //rock.mdl
Bones, //bones.mdl
Concrete, //concrete.mdl
MetalPlate, //metalplate.mdl
AirDuct, //vent.mdl
None, //very strange pos
LastMaterial, //just in case
}Materials;
//gibs physics
typedef enum {
Bounce = 0, // bounce at collision
Noclip, // no collisions
Sticky, // sticky physic
Fly, // fly
Toss, // toss
WalkStep, // monsters walk
} Physics;
static float MatFrictionTable( Materials mat)
{
float friction = 0;
switch(mat)
{
case CinderBlock:
case Concrete:
case Rocks: friction = 300; break;
case Glass: friction = 200; break;
case MetalPlate:
case Metal: friction = 60; break;
case Wood: friction = 250; break;
case None:
default: friction = 100; break;
}
return friction;
}
static float MatByoancyTable( entvars_t *pev, Materials mat)
{
float byoancy = 0;
switch(mat)
{
case CinderBlock:
case Concrete:
case Rocks: byoancy = 0; break;
case Glass: byoancy = 5; break;
case MetalPlate:
case Metal: byoancy = 1; break;
case Wood: byoancy = 30; break;
case None:
default: byoancy = 100; break;
}
return ( byoancy * (pev->maxs.x - pev->mins.x) * (pev->maxs.y - pev->mins.y) ) * 0.0005;
}
static float MatMassTable( entvars_t *pev, Materials mat)
{
float mass = 0;
switch(mat)
{
case CinderBlock:
case Concrete:
case Rocks: mass = 2; break;
case Glass: mass = 1.2; break;
case MetalPlate:
case Metal: mass = 1.5; break;
case Wood: mass = 0.8; break;
case None:
default: mass = 1; break;
}
return (pev->size.Length() * mass);
}
static float MatVolume( Materials mat )
{
float volume = 0;
switch(mat)
{
case None: volume = 0.9; //unbreakable
case Bones: //bones.mdl
case Flesh: volume = 0.2; break; //flesh.mdl
case CinderBlock: //cinder.mdl
case Concrete: //concrete.mdl
case Rocks: volume = 0.25; break; //rock.mdl
case Computer: //computer.mdl
case Glass: volume = 0.3; break; //glass.mdl
case MetalPlate: //metalplate.mdl
case Metal: //metal.mdl
case AirDuct: volume = 0.1; break; //vent.mdl
case CeilingTile: //ceiling.mdl
case Wood: volume = 0.15; break; //wood.mdl
default: volume = 0.2; break;
}
return volume;
}
extern DLL_GLOBAL Vector g_vecAttackDir;
#define SetMoveDone( a ) m_pfnCallWhenMoveDone = static_cast <void (CBaseMover::*)(void)> (a)
class CBaseBrush : public CBaseLogic
{
public:
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData* pkvd);
void Blocked( CBaseEntity *pOther );
virtual void AxisDir( void );
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
int DamageDecal( int bitsDamageType );
BOOL IsBreakable( void );
void EXPORT Die( void );
virtual CBaseBrush *MyBrushPointer( void ) { return this; }
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
static TYPEDESCRIPTION m_SaveData[];
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static void MaterialSoundPrecache( Materials precacheMaterial );
static void PlayRandomSound( edict_t *pEdict, Materials soundMaterial, float volume );
static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount );
static const char *pSoundsWood[];
static const char *pSoundsFlesh[];
static const char *pSoundsMetal[];
static const char *pSoundsCrete[];
static const char *pSoundsGlass[];
static const char *pSoundsCeil[];
//spawnobject name
static const char *pSpawnObjects[];
void DamageSound( void );
Materials m_Material;
CBasePlayer* m_pController; // player pointer
Vector m_vecPlayerPos; // player position
int m_iMoveSound; // move sound or preset
int m_iStartSound; // start sound or preset
int m_iStopSound; // stop sound or preset
int m_idShard; // index of gibs
int m_iMagnitude; // explosion magnitude
int m_iSpawnObject; // spawnobject name
int m_iGibModel; // custom gib model
int DmgType; // temp container for right calculate damage
float m_flVolume; // moving brushes has volume of move sound
float m_flBlockedTime; // don't save this
float m_flRadius; // sound radius or pendulum radius
float m_flAccel; // declared here because rotating brushes use this
float m_flDecel; // declared here because rotating brushes use this
int m_pitch; // sound pitch
};
class CPushable : public CBaseBrush
{
public:
void Spawn ( void );
void Precache( void );
void Touch ( CBaseEntity *pOther );
void Move( CBaseEntity *pMover, int push );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void ) { return (CBaseBrush :: ObjectCaps() | FCAP_CONTINUOUS_USE); }
virtual BOOL IsPushable( void ) { return TRUE; }
inline float MaxSpeed( void ) { return pev->speed; }
static const char *pPushWood[];
static const char *pPushFlesh[];
static const char *pPushMetal[];
static const char *pPushCrete[];
static const char *pPushGlass[];
static const char *pPushCeil[]; //fixme
static void PushSoundPrecache( Materials precacheMaterial );
static int PlayPushSound( edict_t *pEdict, Materials soundMaterial, float volume );
static void StopPushSound( edict_t *pEdict, Materials soundMaterial, int m_lastPushSnd );
static const char **PushSoundList( Materials precacheMaterial, int &soundCount );
int m_lastSound; // no need to save/restore, just keeps the same sound from playing twice in a row
};
#include "basemover.h"
#endif // BASEBRUSH_H

View File

@ -1,921 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2005
// baseentity.cpp - base class
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "saverestore.h"
#include "client.h"
#include "nodes.h"
#include "decals.h"
#include "gamerules.h"
#include "game.h"
#include "damage.h"
#include "defaults.h"
#include "bullets.h"
extern Vector VecBModelOrigin( entvars_t* pevBModel );
extern DLL_GLOBAL Vector g_vecAttackDir;
extern void SetObjectCollisionBox( entvars_t *pev );
extern BOOL NewLevel;
extern CGraph WorldGraph;
//=======================================================================
// decent mechanisms
//=======================================================================
void CBaseEntity::DontThink( void )
{
m_fNextThink = 0;
if ( m_pParent == NULL && m_pChild == NULL )
{
pev->nextthink = 0;
m_fPevNextThink = 0;
}
}
void CBaseEntity :: SetEternalThink( void )
{
if ( pev->movetype == MOVETYPE_PUSH )
{
pev->nextthink = pev->ltime + 1E6;
m_fPevNextThink = pev->nextthink;
}
CBaseEntity *pChild;
for ( pChild = m_pChild; pChild != NULL; pChild = pChild->m_pNextChild )
pChild->SetEternalThink( );
}
void CBaseEntity :: SetNextThink( float delay, BOOL correctSpeed )
{
if ( m_pParent || m_pChild )
{
if ( pev->movetype == MOVETYPE_PUSH )
m_fNextThink = pev->ltime + delay;
else m_fNextThink = gpGlobals->time + delay;
SetEternalThink( );
UTIL_MarkChild( this, correctSpeed, FALSE );
}
else
{
// set nextthink as normal.
if ( pev->movetype == MOVETYPE_PUSH )
pev->nextthink = pev->ltime + delay;
else pev->nextthink = gpGlobals->time + delay;
m_fPevNextThink = m_fNextThink = pev->nextthink;
}
}
void CBaseEntity :: AbsoluteNextThink( float time, BOOL correctSpeed )
{
if ( m_pParent || m_pChild )
{
m_fNextThink = time;
SetEternalThink( );
UTIL_MarkChild( this, correctSpeed, FALSE );
}
else
{
// set nextthink as normal.
pev->nextthink = time;
m_fPevNextThink = m_fNextThink = pev->nextthink;
}
}
void CBaseEntity :: ThinkCorrection( void )
{
if ( pev->nextthink != m_fPevNextThink )
{
m_fNextThink += pev->nextthink - m_fPevNextThink;
m_fPevNextThink = pev->nextthink;
}
}
//=======================================================================
// set parent (void ) dinamically link parents
//=======================================================================
void CBaseEntity :: SetParent( int m_iNewParent, int m_iAttachment )
{
if( !m_iNewParent ) // unlink entity from chain
{
ResetParent();
return;
}
CBaseEntity* pParent;
if(!m_iAttachment) //try to extract aiment from name
{
char *name = (char*)STRING(m_iNewParent);
for (char *c = name; *c; c++)
{
if (*c == '.')
{
m_iAttachment = atoi(c+1);
name[strlen(name)-2] = 0;
pParent = UTIL_FindEntityByTargetname( NULL, name);
SetParent( pParent, m_iAttachment);
return;
}
}
}
pParent = UTIL_FindEntityByTargetname( NULL, STRING(m_iNewParent));
SetParent( pParent, m_iAttachment );
}
//=======================================================================
// set parent main function
//=======================================================================
void CBaseEntity :: SetParent( CBaseEntity* pParent, int m_iAttachment )
{
m_pParent = pParent;
if( !m_pParent )
{
ALERT( at_console, "=========/Xash Parent System Info:/=========\n" );
if( pev->targetname )
ALERT( at_warning, "Not found parent for %s with name %s\n", STRING( pev->classname ), STRING( pev->targetname ));
else ALERT( at_warning, "Not found parent for %s\n", STRING( pev->classname ));
ResetParent(); // lose parent or not found parent
return;
}
// check for himself parent
if( m_pParent == this )
{
ALERT( at_console, "=========/Xash Parent System Info:/=========\n");
if( pev->targetname ) ALERT( at_error, "%s with name %s has illegal parent\n", STRING(pev->classname), STRING(pev->targetname) );
else ALERT( at_error, "%s has illegal parent\n", STRING(pev->classname) );
SHIFT;
ResetParent();//clear parent
return;
}
CBaseEntity *pCurChild = m_pParent->m_pChild;
while ( pCurChild ) //check that this entity isn't already in the list of children
{
if( pCurChild == this ) break;
pCurChild = pCurChild->m_pNextChild;
}
if( !pCurChild )
{
m_pNextChild = m_pParent->m_pChild; // may be null: that's fine by me.
m_pParent->m_pChild = this;
if( m_iAttachment )
{
if( pFlags & PF_POINTENTITY || pev->flags & FL_MONSTER )
{
pev->colormap = ((pev->colormap & 0xFF00)>>8) | m_iAttachment;
pev->aiment = m_pParent->edict();
pev->movetype = MOVETYPE_FOLLOW;
}
else //error
{
ALERT(at_console, "=========/Xash Parent System Info:/=========\n");
if( pev->targetname )
ALERT( at_error, "%s with name %s not following with aiment %d!(yet)\n", STRING(pev->classname), STRING(pev->targetname), m_iAttachment );
else ALERT( at_error, "%s not following with aiment %d!(yet)\n", STRING(pev->classname), m_iAttachment );
SHIFT;
}
return;
}
else//appllayed to origin
{
if (pev->movetype == MOVETYPE_NONE)
{
if (pev->solid == SOLID_BSP)
pev->movetype = MOVETYPE_PUSH;
else pev->movetype = MOVETYPE_NOCLIP;
SetBits (pFlags, PF_MOVENONE);//member movetype
}
if(m_pParent->pev->movetype == MOVETYPE_WALK)//parent is walking monster?
{
SetBits (pFlags, PF_POSTORG);//copy pos from parent every frame
pev->solid = SOLID_NOT;//set non solid
}
pParentOrigin = m_pParent->pev->origin;
pParentAngles = m_pParent->pev->angles;
}
if (m_pParent->m_vecSpawnOffset != g_vecZero)
{
UTIL_AssignOrigin(this, pev->origin + m_pParent->m_vecSpawnOffset);
m_vecSpawnOffset = m_vecSpawnOffset + m_pParent->m_vecSpawnOffset;
}
OffsetOrigin = pev->origin - pParentOrigin;
OffsetAngles = pev->angles - pParentAngles;
if((m_pParent->pFlags & PF_ANGULAR && OffsetOrigin != g_vecZero) || m_pParent->pFlags & PF_POINTENTITY)
{
SetBits (pFlags, PF_POSTORG);//magic stuff
//GetPInfo( this );
}
if(g_serveractive)//maybe parent is moving ?
{
pev->velocity += m_pParent->pev->velocity;
pev->avelocity += m_pParent->pev->avelocity;
}
}
}
//=======================================================================
// reset parent (void ) dinamically unlink parents
//=======================================================================
void CBaseEntity :: ResetParent( void )
{
if( pFlags & PF_MOVENONE ) // this entity was static e.g. func_wall
{
ClearBits( pFlags, PF_MOVENONE );
pev->movetype = MOVETYPE_NONE;
}
if( !g_pWorld ) return; //???
CBaseEntity* pTemp;
for( pTemp = g_pWorld; pTemp->m_pLinkList != NULL; pTemp = pTemp->m_pLinkList )
{
if( this == pTemp->m_pLinkList )
{
pTemp->m_pLinkList = this->m_pLinkList; // save pointer
this->m_pLinkList = NULL;
break;
}
}
if ( m_pParent )
{
pTemp = m_pParent->m_pChild;
if ( pTemp == this )
{
m_pParent->m_pChild = this->m_pNextChild;
}
else
{
while ( pTemp->m_pNextChild )
{
if ( pTemp->m_pNextChild == this )
{
pTemp->m_pNextChild = this->m_pNextChild;
break;
}
pTemp = pTemp->m_pNextChild;
}
}
}
if (m_pNextChild)
{
CBaseEntity* pCur = m_pChild;
CBaseEntity* pNext;
while (pCur != NULL)
{
pNext = pCur->m_pNextChild;
//bring children to a stop
UTIL_SetChildVelocity (pCur, g_vecZero, MAX_CHILDS);
UTIL_SetChildAvelocity(pCur, g_vecZero, MAX_CHILDS);
pCur->m_pParent = NULL;
pCur->m_pNextChild = NULL;
pCur = pNext;
}
}
}
//=======================================================================
// setup physics (execute once at spawn)
//=======================================================================
void CBaseEntity :: SetupPhysics( void )
{
// rebuild all parents
if ( pFlags & PF_LINKCHILD ) LinkChild( this );
if ( gpGlobals->changelevel )
m_physinit = FALSE; // rebuild parents on next level
if ( m_physinit ) return;
SetParent(); //set all parents
m_physinit = true;
if ( !gpGlobals->changelevel )
{
PostSpawn();//post spawn
}
}
void CBaseEntity :: RestorePhysics( void )
{
if( m_iParent ) SetParent();
}
void CBaseEntity :: ClearPointers( void )
{
m_pParent = NULL;
m_pChild = NULL;
m_pNextChild = NULL;
m_pLinkList = NULL;
}
//=========================================================
// FVisible - returns true if a line can be traced from
// the caller's eyes to the target vector
//=========================================================
BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin )
{
TraceResult tr;
Vector vecLookerOrigin;
vecLookerOrigin = EyePosition(); // look through the caller's 'eyes'
UTIL_TraceLine( vecLookerOrigin, vecOrigin, ignore_monsters, ignore_glass, ENT( pev ), &tr );
if (tr.flFraction != 1.0)
return FALSE;
return TRUE;// line of sight is valid.
}
//=========================================================
// FVisible - returns true if a line can be traced from
// the caller's eyes to the target
//=========================================================
BOOL CBaseEntity :: FVisible( CBaseEntity *pEntity )
{
TraceResult tr;
Vector vecLookerOrigin;
Vector vecTargetOrigin;
if( FBitSet( pEntity->pev->flags, FL_NOTARGET ))
return FALSE;
// don't look through water
if(( pev->waterlevel != 3 && pEntity->pev->waterlevel == 3 ) || ( pev->waterlevel == 3 && pEntity->pev->waterlevel != 3 ))
return FALSE;
vecLookerOrigin = pev->origin + pev->view_ofs; // look through the caller's 'eyes'
vecTargetOrigin = pEntity->EyePosition();
UTIL_TraceLine( vecLookerOrigin, vecTargetOrigin, ignore_monsters, ignore_glass, ENT( pev ), &tr );
if( tr.flFraction != 1.0 && tr.pHit != ENT( pEntity->pev ))
return FALSE;
return TRUE;
}
//=======================================================================
// fire bullets
//=======================================================================
void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker )
{
static int tracerCount;
int tracer;
TraceResult tr;
Vector vecRight = gpGlobals->v_right;
Vector vecUp = gpGlobals->v_up;
if ( pevAttacker == NULL )
pevAttacker = pev; // the default attacker is ourselves
ClearMultiDamage();
gMultiDamage.type = DMG_BULLET | DMG_NEVERGIB;
for (ULONG iShot = 1; iShot <= cShots; iShot++)
{
// get circular gaussian spread
float x, y, z;
do {
x = RANDOM_FLOAT( -0.5f, 0.5f ) + RANDOM_FLOAT( -0.5f, 0.5f );
y = RANDOM_FLOAT( -0.5f, 0.5f ) + RANDOM_FLOAT( -0.5f, 0.5f );
z = x*x+y*y;
} while ( z > 1 );
Vector vecDir = vecDirShooting + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;
Vector vecEnd;
vecEnd = vecSrc + vecDir * flDistance;
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( pev )/*pentIgnore*/, &tr );
tracer = 0;
if( iTracerFreq != 0 && (tracerCount++ % iTracerFreq) == 0 )
{
Vector vecTracerSrc;
if ( IsPlayer() )
{
// adjust tracer position for player
vecTracerSrc = vecSrc + Vector ( 0 , 0 , -4 ) + gpGlobals->v_right * 2 + gpGlobals->v_forward * 16;
}
else
{
vecTracerSrc = vecSrc;
}
if ( iTracerFreq != 1 ) // guns that always trace also always decal
tracer = 1;
switch( iBulletType )
{
case BULLET_MP5:
case BULLET_9MM:
case BULLET_12MM:
case BULLET_357:
case BULLET_556:
case BULLET_762:
case BULLET_BUCKSHOT:
default:
MESSAGE_BEGIN( MSG_PAS, gmsg.TempEntity, vecTracerSrc );
WRITE_BYTE( TE_TRACER );
WRITE_COORD( vecTracerSrc.x );
WRITE_COORD( vecTracerSrc.y );
WRITE_COORD( vecTracerSrc.z );
WRITE_COORD( tr.vecEndPos.x );
WRITE_COORD( tr.vecEndPos.y );
WRITE_COORD( tr.vecEndPos.z );
MESSAGE_END();
break;
}
}
// do damage, paint decals
if ( tr.flFraction != 1.0 )
{
CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit );
if ( iDamage )
{
pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET | ((iDamage > 16) ? DMG_ALWAYSGIB : DMG_NEVERGIB) );
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
else switch(iBulletType)
{
default:
case BULLET_9MM:
pEntity->TraceAttack(pevAttacker, _9MM_DMG, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
break;
case BULLET_MP5:
pEntity->TraceAttack(pevAttacker, _MP5_DMG, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
break;
case BULLET_12MM:
pEntity->TraceAttack(pevAttacker, _12MM_DMG, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_556:
pEntity->TraceAttack(pevAttacker, _556_DMG, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_762:
pEntity->TraceAttack(pevAttacker, _762_DMG, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_BUCKSHOT:
pEntity->TraceAttack(pevAttacker, BUCKSHOT_DMG, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_357:
pEntity->TraceAttack(pevAttacker, _357_DMG, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_NONE: // FIX
pEntity->TraceAttack(pevAttacker, 50, vecDir, &tr, DMG_CLUB);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
// only decal glass
if ( !FNullEnt(tr.pHit) && VARS(tr.pHit)->rendermode != 0)
{
UTIL_DecalTrace( &tr, DECAL_GLASSBREAK1 + RANDOM_LONG(0,2) );
}
break;
}
}
// make bullet trails
UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (flDistance * tr.flFraction) / 64.0 );
}
ApplyMultiDamage(pev, pevAttacker);
}
//=======================================================================
// traceing operations
//=======================================================================
void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
{
if (BloodColor() == DONT_BLEED)
return;
if (flDamage == 0)
return;
if (!(bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR)))
return;
// make blood decal on the wall!
TraceResult Bloodtr;
Vector vecTraceDir;
float flNoise;
int cCount;
int i;
if (flDamage < 10)
{
flNoise = 0.1;
cCount = 1;
}
else if (flDamage < 25)
{
flNoise = 0.2;
cCount = 2;
}
else
{
flNoise = 0.3;
cCount = 4;
}
for ( i = 0 ; i < cCount ; i++ )
{
vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going)
vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise );
vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise );
vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise );
UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172, ignore_monsters, ENT(pev), &Bloodtr);
if ( Bloodtr.flFraction != 1.0 )
{
UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
}
}
}
void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{
Vector vecOrigin = ptr->vecEndPos - vecDir * 4;
if ( pev->takedamage )
{
AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType );
int blood = BloodColor();
if ( blood != DONT_BLEED )
{
SpawnBlood(vecOrigin, blood, flDamage);// a little surface blood.
TraceBleed( flDamage, vecDir, ptr, bitsDamageType );
}
}
}
//=======================================================================
// take damage\health
//=======================================================================
int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType )
{
if( !pev->takedamage ) return 0;
if ( pev->health >= pev->max_health ) return 0;
pev->health += flHealth;
pev->health = min(pev->health, pev->max_health);
return 1;
}
int CBaseEntity :: TakeArmor( float flArmor, int suit )
{
if(!pev->takedamage) return 0;
if (pev->armorvalue >= MAX_NORMAL_BATTERY) return 0;
pev->armorvalue += flArmor;
pev->armorvalue = min(pev->armorvalue, MAX_NORMAL_BATTERY);
return 1;
}
int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
Vector vecTemp;
if (!pev->takedamage) return 0;
// if Attacker == Inflictor, the attack was a melee or other instant-hit attack.
// (that is, no actual entity projectile was involved in the attack so use the shooter's origin).
if ( pevAttacker == pevInflictor )
{
vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) );
}
else // an actual missile was involved.
{
vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) );
}
// this global is still used for glass and other non-monster killables, along with decals.
g_vecAttackDir = vecTemp.Normalize();
// save damage based on the target's armor level
// figure momentum add (don't let hurt brushes or other triggers move player)
if ((!FNullEnt(pevInflictor)) && (pev->movetype == MOVETYPE_WALK || pev->movetype == MOVETYPE_STEP) && (pevAttacker->solid != SOLID_TRIGGER) )
{
Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
vecDir = vecDir.Normalize();
float flForce = flDamage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5;
if (flForce > 1000.0) flForce = 1000.0;
pev->velocity = pev->velocity + vecDir * flForce;
}
// do the damage
pev->health -= flDamage;
if (pev->health <= 0)
{
Killed( pevAttacker, GIB_NORMAL );
return 0;
}
return 1;
}
int CBaseEntity :: DamageDecal( int bitsDamageType )
{
if ( pev->rendermode == kRenderTransAlpha )
return -1;
if ( pev->rendermode != kRenderNormal )
return DECAL_BPROOF1;
return DECAL_GUNSHOT1 + RANDOM_LONG(0, 4);
}
//=======================================================================
// killed/create operations
//=======================================================================
CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner )
{
edict_t *pent;
int istr = ALLOC_STRING(szName);
CBaseEntity *pEntity;
pent = CREATE_NAMED_ENTITY( istr );
if( FNullEnt( pent )) return NULL;
pEntity = Instance( pent );
pEntity->SetObjectClass( );
pEntity->pev->owner = pentOwner;
pEntity->pev->origin = vecOrigin;
pEntity->pev->angles = vecAngles;
DispatchSpawn( pEntity->edict() );
return pEntity;
}
CBaseEntity * CBaseEntity::CreateGib( char *szName, char *szModel )
{
edict_t *pent;
CBaseEntity *pEntity;
string_t model = MAKE_STRING( szModel );
int istr = ALLOC_STRING(szName);
pent = CREATE_NAMED_ENTITY( istr );
if( FNullEnt( pent )) return NULL;
pEntity = Instance( pent );
DispatchSpawn( pEntity->edict() );
pEntity->SetObjectClass( ED_NORMAL );
if( !FStringNull( model ))
{
UTIL_SetModel( pEntity->edict(), szModel );
Msg( "szModel %s\n", szModel );
}
return pEntity;
}
void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib )
{
pev->takedamage = DAMAGE_NO;
pev->deadflag = DEAD_DEAD;
UTIL_Remove( this );
}
void CBaseEntity::UpdateOnRemove( void )
{
ResetParent();
if ( FBitSet( pev->flags, FL_GRAPHED ) )
{
for (int i = 0 ; i < WorldGraph.m_cLinks ; i++ )
{
if ( WorldGraph.m_pLinkPool [ i ].m_pLinkEnt == pev )
WorldGraph.m_pLinkPool [ i ].m_pLinkEnt = NULL;
}
}
if( pev->globalname ) gGlobalState.EntitySetState( pev->globalname, GLOBAL_DEAD );
}
//=======================================================================
// three methods of remove entity
//=======================================================================
void CBaseEntity :: Remove( void )
{
UpdateOnRemove();
if( pev->health > 0 )
pev->health = 0;
REMOVE_ENTITY( ENT( pev ));
}
void CBaseEntity :: PVSRemove( void )
{
if ( FNullEnt( FIND_CLIENT_IN_PVS( edict()))) SetThink( Remove );
SetNextThink( 0.1 );
}
void CBaseEntity :: Fadeout( void )
{
if (pev->rendermode == kRenderNormal)
{
pev->renderamt = 255;
pev->rendermode = kRenderTransTexture;
}
pev->solid = SOLID_NOT;
pev->avelocity = g_vecZero;
if ( pev->renderamt > 7 )
{
pev->renderamt -= 7;
SetNextThink( 0.1 );
}
else
{
pev->renderamt = 0;
SetNextThink( 0.2 );
SetThink( Remove );
}
}
//=======================================================================
// global save\restore data
//=======================================================================
TYPEDESCRIPTION CBaseEntity::m_SaveData[] =
{
DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ),
//parent system saves
DEFINE_FIELD( CBaseEntity, m_iParent, FIELD_STRING ),
DEFINE_FIELD( CBaseEntity, m_pParent, FIELD_CLASSPTR ),
DEFINE_FIELD( CBaseEntity, m_pChild, FIELD_CLASSPTR ),
DEFINE_FIELD( CBaseEntity, m_pNextChild, FIELD_CLASSPTR ),
DEFINE_FIELD( CBaseEntity, OffsetOrigin, FIELD_VECTOR ),
DEFINE_FIELD( CBaseEntity, OffsetAngles, FIELD_VECTOR ),
DEFINE_FIELD( CBaseEntity, pFlags, FIELD_INTEGER ),
DEFINE_FIELD( CBaseEntity, m_physinit, FIELD_BOOLEAN ),
//local child coordinates
DEFINE_FIELD( CBaseEntity, PostOrigin, FIELD_VECTOR ),
DEFINE_FIELD( CBaseEntity, PostAngles, FIELD_VECTOR ),
DEFINE_FIELD( CBaseEntity, PostVelocity, FIELD_VECTOR ),
DEFINE_FIELD( CBaseEntity, PostAvelocity, FIELD_VECTOR ),
//think time
DEFINE_FIELD( CBaseEntity, m_fNextThink, FIELD_TIME ),
DEFINE_FIELD( CBaseEntity, m_fPevNextThink, FIELD_TIME ),
DEFINE_FIELD( CBaseEntity, m_iStyle, FIELD_INTEGER ),
DEFINE_FIELD( CBaseEntity, m_iClassType, FIELD_INTEGER ),
DEFINE_FIELD( CBaseEntity, m_iAcessLevel, FIELD_INTEGER ),
DEFINE_FIELD( CBaseEntity, m_pfnThink, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnTouch, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnUse, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnBlocked, FIELD_FUNCTION ),
};
int CBaseEntity::Save( CSave &save )
{
ThinkCorrection();
if ( save.WriteEntVars( "ENTVARS", pev ) )
{
if (pev->targetname)
return save.WriteFields( STRING(pev->targetname), "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) );
else return save.WriteFields( STRING(pev->classname ), "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) );
}
return 0;
}
int CBaseEntity :: Restore( CRestore &restore )
{
int status;
status = restore.ReadEntVars( "ENTVARS", pev );
if( status ) status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE( m_SaveData ));
// restore edict class here
SetObjectClass( m_iClassType );
if( pev->modelindex != 0 && !FStringNull( pev->model ))
{
Vector mins = pev->mins;
Vector maxs = pev->maxs; // Set model is about to destroy these
UTIL_PrecacheModel( pev->model );
UTIL_SetModel( ENT( pev ), pev->model );
UTIL_SetSize( pev, mins, maxs );
}
return status;
}
//=======================================================================
// collisoin boxes
//=======================================================================
void CBaseEntity::SetObjectCollisionBox( void )
{
::SetObjectCollisionBox( pev );
}
int CBaseEntity :: Intersects( CBaseEntity *pOther )
{
if ( pOther->pev->absmin.x > pev->absmax.x ||
pOther->pev->absmin.y > pev->absmax.y ||
pOther->pev->absmin.z > pev->absmax.z ||
pOther->pev->absmax.x < pev->absmin.x ||
pOther->pev->absmax.y < pev->absmin.y ||
pOther->pev->absmax.z < pev->absmin.z )
return FALSE;
return TRUE;
}
//=======================================================================
// Dormant operations
//=======================================================================
void CBaseEntity :: MakeDormant( void )
{
SetBits( pev->flags, FL_DORMANT );
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
SetBits( pev->effects, EF_NODRAW );
DontThink();
UTIL_SetOrigin( this, pev->origin );
}
int CBaseEntity :: IsDormant( void )
{
return FBitSet( pev->flags, FL_DORMANT );
}
BOOL CBaseEntity :: IsInWorld( void )
{
if (pev->origin.x >= MAP_HALFSIZE) return FALSE;
if (pev->origin.y >= MAP_HALFSIZE) return FALSE;
if (pev->origin.z >= MAP_HALFSIZE) return FALSE;
if (pev->origin.x <= -MAP_HALFSIZE) return FALSE;
if (pev->origin.y <= -MAP_HALFSIZE) return FALSE;
if (pev->origin.z <= -MAP_HALFSIZE) return FALSE;
if (pev->velocity.x >= MAX_VELOCITY) return FALSE;
if (pev->velocity.y >= MAX_VELOCITY) return FALSE;
if (pev->velocity.z >= MAX_VELOCITY) return FALSE;
if (pev->velocity.x <= -MAX_VELOCITY) return FALSE;
if (pev->velocity.y <= -MAX_VELOCITY) return FALSE;
if (pev->velocity.z <= -MAX_VELOCITY) return FALSE;
return TRUE;
}

View File

@ -1,335 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASEENTITY_H
#define BASEENTITY_H
#include "entity_state.h"
class CBaseEntity
{
public:
// Constructor. Set engine to use C/C++ callback functions
// pointers to engine data
entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it
// path corners
CBaseEntity *m_pGoalEnt;// path corner we are heading towards
CBaseEntity *m_pLink;// used for temporary link-list operations.
float m_fNextThink;
float m_fPevNextThink;
float flTravelTime; // time to moving brushes
int m_iClassType; // edict classtype
int m_iStyle;
int m_iAcessLevel;// acess level for retinal sacners
//===================================================================================================
// Xash BaseEntity
//===================================================================================================
// Gets the interface to the collideable representation of the entity
virtual void SetModelIndex( int index );
virtual int GetModelIndex( void ) const;
// Returns a CBaseAnimating if the entity is derived from CBaseAnimating.
virtual CBaseAnimating* GetBaseAnimating() { return NULL; }
void SetName( string_t newTarget );
void SetParent( string_t newParent, CBaseEntity *pActivator );
virtual void ChangeCamera( string_t newcamera ) {}
public:
//===================================================================================================
// Xash Parent System 0.2 beta
//===================================================================================================
Vector PostOrigin; //child postorigin
Vector PostAngles; //child postangles
Vector PostVelocity; //child postvelocity
Vector PostAvelocity; //child postavelocity
Vector OffsetOrigin; //spawn offset origin
Vector OffsetAngles; //spawn offset angles
Vector pParentAngles; //temp container
Vector pParentOrigin; //temp container
Vector m_vecSpawnOffset; //temp container
int pFlags; //xash flags
BOOL m_physinit; //physics initializator
virtual void SetParent ( void ) { SetParent(m_iParent); }
void SetParent ( int m_iNewParent, int m_iAttachment = 0 );
void SetParent ( CBaseEntity* pParent, int m_iAttachment = 0 );
void ResetParent( void );
virtual void SetupPhysics( void ); // setup parent system and physics
CBaseEntity *m_pParent; // pointer to parent entity
CBaseEntity *m_pChild; // pointer to children(may be this)
CBaseEntity *m_pNextChild; // link to next chlidren
CBaseEntity *m_pLinkList; // list of linked childrens
string_t m_iParent;//name of parent
virtual void SetNextThink( float delay, BOOL correctSpeed = FALSE );
virtual void AbsoluteNextThink( float time, BOOL correctSpeed = FALSE );
void SetEternalThink( void );
void DontThink( void );
virtual void ThinkCorrection( void );
//phys metods
virtual void SetAngularImpulse( float impulse ){}
virtual void SetLinearImpulse( float impulse ) {}
// initialization functions
virtual void Spawn( void ) { return; }
virtual void Precache( void ) { return; }
virtual void KeyValue( KeyValueData* pkvd)
{
if (FStrEq(pkvd->szKeyName, "parent"))
{
m_iParent = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "style"))
{
m_iStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "angle"))
{
// quake legacy
if( pev->angles == g_vecZero )
pev->angles[1] = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else pkvd->fHandled = FALSE;
}
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
virtual int ObjectCaps( void ) { return m_pParent?m_pParent->ObjectCaps()&FCAP_ACROSS_TRANSITION:FCAP_ACROSS_TRANSITION; }
virtual void Activate( void ) {}
virtual void PostActivate( void ) {}
virtual void PostSpawn( void ) {}
virtual void DesiredAction( void ) {}
virtual void StartMessage( CBasePlayer *pPlayer ) {}
virtual void SetObjectClass( int iClassType = ED_SPAWNED )
{
m_iClassType = iClassType;
}
virtual BOOL IsItem( void ) { return FALSE; }
virtual BOOL IsAmmo( void ) { return FALSE; }
virtual BOOL IsWeapon( void ) { return FALSE; }
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
virtual void SetObjectCollisionBox( void );
void UTIL_AutoSetSize( void )//automatically set collision box
{
dstudiohdr_t *pstudiohdr;
pstudiohdr = (dstudiohdr_t*)GET_MODEL_PTR( ENT(pev) );
if (pstudiohdr == NULL)
{
ALERT(at_console,"Unable to fetch model pointer!\n");
return;
}
dstudioseqdesc_t *pseqdesc;
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
UTIL_SetSize(pev,pseqdesc[ pev->sequence ].bbmin,pseqdesc[ pev->sequence ].bbmax);
}
// Classify - returns the type of group (e.g., "alien monster", or "human military" so that monsters
// on the same side won't attack each other, even if they have different classnames.
virtual int Classify ( void ) { return CLASS_NONE; };
virtual void DeathNotice ( entvars_t *pevChild ) {}// monster maker children use this to tell the monster maker that they have died.
// global concept of "entities with states", so that state_watchers and
// mastership (mastery? masterhood?) can work universally.
virtual STATE GetState ( void ) { return STATE_OFF; };
// For team-specific doors in multiplayer, etc: a master's state depends on who wants to know.
virtual STATE GetState ( CBaseEntity* pEnt ) { return GetState(); };
static TYPEDESCRIPTION m_SaveData[];
virtual void ClearPointers( void );
virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
virtual int TakeHealth( float flHealth, int bitsDamageType );
virtual int TakeArmor( float flArmor, int suit = 0 );
virtual int TakeItem( int iItem ) { return 0; }
virtual void Killed( entvars_t *pevAttacker, int iGib );
virtual int BloodColor( void ) { return DONT_BLEED; }
virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
virtual CBaseMonster *MyMonsterPointer( void ) { return NULL;}
virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL;}
virtual CBaseBrush *MyBrushPointer( void ) { return NULL; }
virtual void AddPoints( int score, BOOL bAllowNegativeScore ) {}
virtual void AddPointsToTeam( int score, BOOL bAllowNegativeScore ) {}
virtual BOOL AddPlayerItem( CBasePlayerWeapon *pItem ) { return 0; }
virtual BOOL RemovePlayerItem( CBasePlayerWeapon *pItem ) { return 0; }
virtual int GiveAmmo( int iAmount, char *szName, int iMax ) { return -1; };
virtual float GetDelay( void ) { return 0; }
virtual int IsMoving( void ) { return pev->velocity != g_vecZero; }
virtual void RestorePhysics( void );
virtual void OverrideReset( void ) {}
virtual int DamageDecal( int bitsDamageType );
// This is ONLY used by the node graph to test movement through a door
virtual void SetToggleState( int state ) {}
virtual void StartSneaking( void ) {}
virtual void StopSneaking( void ) {}
virtual BOOL OnControls( entvars_t *pev ) { return FALSE; }
virtual BOOL IsSneaking( void ) { return FALSE; }
virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; }
virtual BOOL IsBSPModel( void ) { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; }
virtual BOOL ReflectGauss( void ) { return ( IsBSPModel() && !pev->takedamage ); }
virtual BOOL HasTarget( string_t targetname ) { return FStrEq(STRING(targetname), STRING(pev->targetname) ); }
virtual BOOL IsInWorld( void );
virtual BOOL IsPlayer( void ) { return FALSE; }
virtual BOOL IsPushable( void ) { return FALSE; }
virtual BOOL IsMonster( void ) { return (pev->flags & FL_MONSTER ? TRUE : FALSE); }
virtual BOOL IsNetClient( void ) { return FALSE; }
virtual BOOL IsFuncScreen( void ) { return FALSE; }
virtual const char *TeamID( void ) { return ""; }
virtual CBaseEntity *GetNext( void ) { return NULL; }
virtual CBaseEntity *GetPrev( void ) { return NULL; }
// fundamental callbacks
void (CBaseEntity ::*m_pfnThink)(void);
void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther );
void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther );
virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)(); };
virtual void Touch( CBaseEntity *pOther ) { if (m_pfnTouch) (this->*m_pfnTouch)( pOther ); };
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (m_pfnUse) (this->*m_pfnUse)( pActivator, pCaller, useType, value );
}
virtual void Blocked( CBaseEntity *pOther ) { if (m_pfnBlocked) (this->*m_pfnBlocked)( pOther ); };
// allow engine to allocate instance data
void *operator new( size_t stAllocateBlock, entvars_t *pev )
{
return (void *)ALLOC_PRIVATE(ENT(pev), stAllocateBlock);
};
// don't use this.
#if _MSC_VER >= 1200 // only build this code if MSVC++ 6.0 or higher
void operator delete(void *pMem, entvars_t *pev)
{
pev->flags |= FL_KILLME;
};
#endif
virtual void UpdateOnRemove( void );
// common member functions
void EXPORT Remove( void );
void EXPORT Fadeout( void );
void EXPORT PVSRemove( void );
void EXPORT SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); }
void FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL );
virtual CBaseEntity *Respawn( void ) { return NULL; }
// Do the bounding boxes of these two intersect?
int Intersects( CBaseEntity *pOther );
void MakeDormant( void );
int IsDormant( void );
BOOL IsLockedByMaster( void ) { return FALSE; }
static CBaseEntity *Instance( edict_t *pent )
{
if ( !pent ) pent = ENT(0);
CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent);
return pEnt;
}
static CBaseEntity *Instance( entvars_t *pev ) { return Instance( ENT( pev ) ); }
static CBaseEntity *Instance( int eoffset) { return Instance( ENT( eoffset) ); }
CBaseMonster *GetMonsterPointer( entvars_t *pevMonster )
{
CBaseEntity *pEntity = Instance( pevMonster );
if ( pEntity ) return pEntity->MyMonsterPointer();
return NULL;
}
CBaseMonster *GetMonsterPointer( edict_t *pentMonster )
{
CBaseEntity *pEntity = Instance( pentMonster );
if ( pEntity ) return pEntity->MyMonsterPointer();
return NULL;
}
// Ugly code to lookup all functions to make sure they are exported when set.
#ifdef _DEBUG
void FunctionCheck( void *pFunction, char *name )
{
if (pFunction && !NAME_FOR_FUNCTION((unsigned long)(pFunction)) )
ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, (unsigned long)pFunction );
}
BASEPTR ThinkSet( BASEPTR func, char *name )
{
m_pfnThink = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name );
return func;
}
ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name )
{
m_pfnTouch = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name );
return func;
}
USEPTR UseSet( USEPTR func, char *name )
{
m_pfnUse = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name );
return func;
}
ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name )
{
m_pfnBlocked = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name );
return func;
}
#endif
// used by monsters that are created by the MonsterMaker
virtual void UpdateOwner( void ) { return; };
static CBaseEntity *Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL );
static CBaseEntity *CBaseEntity::CreateGib( char *szName, char *szModel );
virtual BOOL FBecomeProne( void ) {return FALSE;};
edict_t *edict() { return ENT( pev ); };
EOFFSET eoffset( ) { return OFFSET( pev ); };
int entindex( ) { return ENTINDEX( edict() ); };
virtual Vector Center( ) { return (pev->absmax + pev->absmin) * 0.5; }; // center point of entity
virtual Vector EyePosition( ) { return pev->origin + pev->view_ofs; }; // position of eyes
virtual Vector EarPosition( ) { return pev->origin + pev->view_ofs; }; // position of ears
virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ); }; // position to shoot at
virtual int Illumination( ) { return GETENTITYILLUM( ENT( pev ) ); };
virtual BOOL FVisible ( CBaseEntity *pEntity );
virtual BOOL FVisible ( const Vector &vecOrigin );
};
inline void CBaseEntity::SetModelIndex( int index )
{
pev->modelindex = index;
}
inline int CBaseEntity::GetModelIndex( void ) const
{
return pev->modelindex;
}
#endif //BASEENTITY_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,449 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// baseinfo.cpp - point info entities.
// e.g. info_target
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "player.h"
#include "client.h"
//=======================================================================
// info_target (target entity)
//=======================================================================
class CInfoTarget : public CPointEntity
{
public:
void Spawn( void )
{
pev->solid = SOLID_NOT;
UTIL_SetModel(ENT(pev),"models/common/null.mdl");
UTIL_SetSize(pev, g_vecZero, g_vecZero);
SetBits( pFlags, PF_POINTENTITY );
}
};
void CBaseDMStart::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "master"))
{
pev->netname = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
STATE CBaseDMStart::GetState( CBaseEntity *pEntity )
{
if (UTIL_IsMasterTriggered( pev->netname, pEntity ))
return STATE_ON;
else return STATE_OFF;
}
class CWallTorch : public CBaseEntity
{
public:
void Precache( void )
{
PRECACHE_SOUND( "ambience/fire1.wav" );
UTIL_PrecacheModel( "models/props/torch1.mdl" );
UTIL_EmitAmbientSound( ENT(pev), pev->origin, "ambience/fire1.wav", 1.0f, ATTN_NORM, 0, PITCH_NORM );
}
void Spawn( void )
{
Precache ();
// SetObjectClass( ED_NORMAL );
pev->flags |= FL_PHS_FILTER; // allow phs filter instead pvs
// setup attenuation radius
pev->armorvalue = 384.0f * ATTN_STATIC;
UTIL_SetModel( ENT( pev ), "models/props/torch1.mdl" );
UTIL_SetSize(pev, g_vecZero, g_vecZero);
SetBits( pFlags, PF_POINTENTITY );
pev->animtime = gpGlobals->time + 0.2; // enable animation
pev->framerate = 0.5f;
}
};
LINK_ENTITY_TO_CLASS( light_torch_small_walltorch, CWallTorch );
//=========================================================
// static infodecal
//=========================================================
class CDecal : public CBaseEntity
{
public:
void KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "texture"))
{
pev->skin = DECAL_INDEX( pkvd->szValue );
if ( pev->skin >= 0 ) return;
Msg( "Can't find decal %s\n", pkvd->szValue );
}
}
void PostSpawn( void )
{
if ( pev->skin < 0 ) { REMOVE_ENTITY(ENT(pev)); return; }
TraceResult trace;
int entityIndex, modelIndex;
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
entityIndex = (short)ENTINDEX(trace.pHit);
if ( entityIndex > 0 )
modelIndex = (int)VARS(trace.pHit)->modelindex;
else modelIndex = 0;
g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
SetThink( Remove );
SetNextThink( 0.3 );
}
};
//=========================================================
// Multiplayer intermission spots.
//=========================================================
class CInfoIntermission : public CPointEntity
{
void Spawn( void );
void Think( void );
void PostActivate( void );
CBaseEntity *pTarget;
void KeyValue( KeyValueData *pkvd );
};
void CInfoIntermission :: Spawn( void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
UTIL_SetOrigin( this, pev->origin );
UTIL_SetModel( ENT( pev ), "sprites/null.spr" );
SetNextThink( 1 );// let targets spawn!
}
void CInfoIntermission::PostActivate( void )
{
if( FStrEq( STRING( pev->classname ), "info_intermission" ))
pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
if( !pev->speed ) pev->speed = 100;
}
void CInfoIntermission::KeyValue( KeyValueData *pkvd )
{
if( FStrEq( pkvd->szKeyName, "mangle" ))
{
Vector tmp;
// Quake1 intermission angles
UTIL_StringToVector( tmp, pkvd->szValue );
if( tmp != g_vecZero ) pev->angles = tmp;
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "roll" ))
{
// Quake3 portal camera
pev->v_angle[ROLL] = atof( pkvd->szValue ) / 360.0f;
pkvd->fHandled = TRUE;
}
else CBaseEntity::KeyValue( pkvd );
}
void CInfoIntermission::Think ( void )
{
if( pTarget )
{
UTIL_WatchTarget( this, pTarget );
SetNextThink( 0 );
}
}
//=========================================================
// portal surfaces
//=========================================================
class CPortalSurface : public CPointEntity
{
void Spawn( void );
void Think( void );
void PostActivate( void );
};
void CPortalSurface :: Spawn( void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
pev->flags |= FL_PHS_FILTER; // use phs so can collect portal sounds
SetObjectClass( ED_PORTAL );
UTIL_SetOrigin( this, pev->origin );
pev->modelindex = 1; // world
SetNextThink( 1 );// let targets spawn!
}
void CPortalSurface :: Think( void )
{
if( FNullEnt( pev->owner ))
pev->oldorigin = pev->origin;
else pev->oldorigin = pev->owner->v.origin;
SetNextThink( 0.1f );
}
void CPortalSurface :: PostActivate( void )
{
CBaseEntity *pTarget, *pOwner;
SetNextThink( 0 );
if( FStringNull( pev->target ))
return; // mirror
pOwner = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
if( !pOwner )
{
ALERT( at_warning, "Couldn't find target for %s\n", STRING( pev->classname ));
UTIL_Remove( this );
return;
}
pev->owner = pOwner->edict();
// q3a swinging camera support
if( pOwner->pev->spawnflags & 1 )
pev->framerate = 25;
else if( pOwner->pev->spawnflags & 2 )
pev->framerate = 75;
if( pOwner->pev->spawnflags & 4 )
pev->effects &= ~EF_ROTATE;
else pev->effects |= EF_ROTATE;
pev->frame = pOwner->pev->v_angle[ROLL]; // rollangle
// see if the portal_camera has a target
if( !FStringNull( pOwner->pev->target ))
pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pOwner->pev->target ));
else pTarget = NULL;
if( pTarget )
{
pev->movedir = pTarget->pev->origin - pOwner->pev->origin;
pev->movedir.Normalize();
}
else
{
pev->angles = pOwner->pev->angles;
UTIL_LinearVector( this );
}
}
//=========================================================
// info_path - train node path.
//=========================================================
void CInfoPath :: KeyValue( KeyValueData *pkvd )
{
if ( FStrEq( pkvd->szKeyName, "wait" ))
{
m_flDelay = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if ( FStrEq (pkvd->szKeyName, "newspeed" ))
{
if ( pkvd->szValue[0] == '+' ) pev->button = SPEED_INCREMENT; //increase speed
else if ( pkvd->szValue[0] == '-' ) pev->button = SPEED_DECREMENT; //decrease speed
else if ( pkvd->szValue[0] == '*' ) pev->button = SPEED_MULTIPLY; //multiply speed by
else if ( pkvd->szValue[0] == ':' ) pev->button = SPEED_DIVIDE; //divide speed by
else pev->button = SPEED_MASTER; // just set new speed
if( pev->button ) pkvd->szValue++;
pev->speed = atof( pkvd->szValue );
ALERT( at_console, "pev->button %d, pev->speed %g\n", pev->button, pev->speed );
pkvd->fHandled = TRUE;
}
else if ( !FClassnameIs( pev, "path_corner" ) && m_cPaths < MAX_MULTI_TARGETS )
{
char tmp[128];
UTIL_StripToken( pkvd->szKeyName, tmp );
m_iPathName[m_cPaths] = ALLOC_STRING( tmp );
m_iPathWeight[m_cPaths] = atof( pkvd->szValue );
m_cPaths++;
pkvd->fHandled = TRUE;
}
else CBaseEntity::KeyValue( pkvd );
}
TYPEDESCRIPTION CInfoPath::m_SaveData[] =
{ DEFINE_FIELD( CInfoPath, m_cPaths, FIELD_INTEGER ),
DEFINE_FIELD( CInfoPath, m_index, FIELD_INTEGER ),
DEFINE_ARRAY( CInfoPath, m_iPathName, FIELD_STRING, MAX_MULTI_TARGETS ),
DEFINE_ARRAY( CInfoPath, m_iPathWeight, FIELD_INTEGER, MAX_MULTI_TARGETS ),
DEFINE_ARRAY( CInfoPath, m_pNextPath, FIELD_CLASSPTR, MAX_MULTI_TARGETS ),
DEFINE_FIELD( CInfoPath, m_pPrevPath, FIELD_CLASSPTR ),
};IMPLEMENT_SAVERESTORE( CInfoPath, CBaseLogic );
LINK_ENTITY_TO_CLASS( info_path, CInfoPath );
LINK_ENTITY_TO_CLASS( path_corner, CInfoPath );
void CInfoPath :: Spawn( void )
{
if( FClassnameIs( pev, "path_corner" ))
{
// compatible mode
m_iPathName[m_cPaths] = pev->target;
m_iPathWeight[m_cPaths] = 0;
m_cPaths++;
}
int r_index = 0;
int w_index = m_cPaths - 1;
while( r_index < w_index )
{
// we store target with right index in tempname
int name = m_iPathName [r_index];
int weight = m_iPathWeight[r_index];
// target with right name is free, record new value from wrong name
m_iPathName [r_index] = m_iPathName [w_index];
m_iPathWeight[r_index] = m_iPathWeight[w_index];
// ok, we can swap targets
m_iPathName [w_index] = name;
m_iPathWeight[w_index] = weight;
r_index++;
w_index--;
}
m_iState = STATE_ON;
m_index = 0;
SetBits( pFlags, PF_POINTENTITY );
pev->scale = 0.1f;
}
void CInfoPath :: PostActivate( void )
{
// find all paths and save into array
for(int i = 0; i < m_cPaths; i++ )
{
CBaseEntity *pNext = UTIL_FindEntityByTargetname( NULL, STRING( m_iPathName[i] ));
if( pNext ) // found path
{
m_pNextPath[i] = (CInfoPath*)pNext; // valid path
m_pNextPath[i]->SetPrev( this );
}
}
}
CBaseEntity *CInfoPath::GetNext( void )
{
int total = 0;
for ( int i = 0; i < m_cPaths; i++ )
{
total += m_iPathWeight[i];
}
if ( total ) // weighted random choose
{
int chosen = RANDOM_LONG( 0, total );
int curpos = 0;
for ( i = 0; i < m_cPaths; i++ )
{
curpos += m_iPathWeight[i];
if ( curpos >= chosen )
{
m_index = i;
break;
}
}
}
// validate path
ASSERTSZ( m_pNextPath[m_index] != this, "GetNext: self path!\n");
if( m_pNextPath[m_index] && m_pNextPath[m_index]->edict() && m_pNextPath[m_index] != this && m_pNextPath[m_index]->m_iState == STATE_ON )
return m_pNextPath[m_index];
return NULL;
}
CBaseEntity *CInfoPath::GetPrev( void )
{
// validate path
ASSERTSZ( m_pPrevPath != this, "GetPrev: self path!\n");
if(m_pPrevPath && m_pPrevPath->edict() && m_pPrevPath != this && m_pPrevPath->m_iState == STATE_ON )
return m_pPrevPath;
return NULL;
}
void CInfoPath::SetPrev( CInfoPath *pPrev )
{
if( pPrev && pPrev->edict() && pPrev != this )
m_pPrevPath = pPrev;
}
void CInfoPath :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
m_hActivator = pActivator;
if ( useType == USE_TOGGLE )
{
if( m_iState == STATE_ON )
useType = USE_OFF;
else useType = USE_ON;
}
if ( useType == USE_ON )
{
m_iState = STATE_ON;
}
else if ( useType == USE_OFF )
{
m_iState = STATE_OFF;
}
if ( useType == USE_SET ) // set new path
{
if( value > 0.0f )
{
m_index = (value - 1);
if( m_index >= m_cPaths )
m_index = 0;
}
}
else if ( useType == USE_RESET )
{
m_index = 0;
}
else if ( useType == USE_SHOWINFO )
{
ALERT( at_console, "======/Xash Debug System/======\n");
ALERT( at_console, "classname: %s\n", STRING(pev->classname));
ALERT( at_console, "State: %s, number of targets %d, path weight %d\n", GetStringForState( GetState()), m_cPaths- 1, m_iPathWeight[m_index]);
if( m_pPrevPath && m_pPrevPath->edict( ))
ALERT( at_console, "Prev path %s", STRING( m_pPrevPath->pev->targetname ));
if( m_pNextPath[m_index] && m_pNextPath[m_index]->edict( ))
ALERT( at_console, "Prev path %s", STRING( m_pNextPath[m_index]->pev->targetname ));
ALERT( at_console, "\n" );
}
}
LINK_ENTITY_TO_CLASS( infodecal, CDecal );
LINK_ENTITY_TO_CLASS( info_target, CInfoTarget );
LINK_ENTITY_TO_CLASS( target_position, CPointEntity );
LINK_ENTITY_TO_CLASS( target_location, CPointEntity );
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
LINK_ENTITY_TO_CLASS( info_portal, CPortalSurface );
LINK_ENTITY_TO_CLASS( misc_portal_surface, CPortalSurface );
LINK_ENTITY_TO_CLASS( info_player_intermission, CPointEntity );
LINK_ENTITY_TO_CLASS( info_notnull, CPointEntity );
LINK_ENTITY_TO_CLASS( info_null, CNullEntity );
LINK_ENTITY_TO_CLASS( info_texlights, CNullEntity);
LINK_ENTITY_TO_CLASS( info_compile_parameters, CNullEntity);
LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission );
LINK_ENTITY_TO_CLASS( info_camera, CInfoIntermission );
LINK_ENTITY_TO_CLASS( misc_portal_camera, CInfoIntermission );
LINK_ENTITY_TO_CLASS( info_player_deathmatch, CBaseDMStart );
LINK_ENTITY_TO_CLASS( info_player_start, CPointEntity );
LINK_ENTITY_TO_CLASS( info_landmark, CPointEntity );

View File

@ -1,108 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASEINFO_H
#define BASEINFO_H
class CPointEntity : public CBaseEntity
{
public:
void Spawn( void ){ SetBits( pFlags, PF_POINTENTITY ); pev->solid = SOLID_NOT; }
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
};
class CNullEntity : public CBaseEntity
{
public:
void Spawn( void ){ REMOVE_ENTITY( ENT( pev )); }
};
class CBaseDMStart : public CPointEntity
{
public:
void KeyValue( KeyValueData *pkvd );
STATE GetState( CBaseEntity *pEntity );
private:
};
#define SPEED_MASTER 0
#define SPEED_INCREMENT 1
#define SPEED_DECREMENT 2
#define SPEED_MULTIPLY 3
#define SPEED_DIVIDE 4
#define SF_CORNER_WAITFORTRIG 0x1
#define SF_CORNER_TELEPORT 0x2
#define SF_CORNER_FIREONCE 0x4
class CInfoPath : public CBaseLogic
{
public:
void Spawn( );
void KeyValue( KeyValueData* pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void PostActivate( void );
float GetDelay( void ) { return m_flDelay; }
void GetSpeed( float *speed )
{
if( !pev->speed ) return;
float curspeed = *speed; // save our speed
// operate
if( pev->button == SPEED_INCREMENT ) curspeed += pev->speed;
if( pev->button == SPEED_DECREMENT ) curspeed -= pev->speed;
if( pev->button == SPEED_MULTIPLY ) curspeed *= pev->speed;
if( pev->button == SPEED_DIVIDE ) curspeed /= pev->speed;
if( pev->button == SPEED_MASTER ) curspeed = pev->speed;
// check validate speed
if( curspeed <= -MAX_VELOCITY || curspeed >= MAX_VELOCITY )
{
curspeed = *speed; // set old value
ALERT( at_console, "\n======/Xash SmartField System/======\n\n" );
ALERT( at_console, "%s: %s contains invalid speed operation! Check it!\n Speed not changed!\n", STRING( pev->classname ), STRING( pev->targetname ));
}
*speed = curspeed;
}
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
int m_cPaths; // the total number of targets in this manager's fire list.
int m_index; // Current target
int m_iPathName[MAX_MULTI_TARGETS]; // list if indexes into global string array
int m_iPathWeight[MAX_MULTI_TARGETS]; // list if weight into global string array
CInfoPath *Instance( edict_t *pent )
{
if ( FClassnameIs( pent, "info_path" ))
return (CInfoPath *)GET_PRIVATE( pent );
return NULL;
}
CInfoPath *m_pNextPath[MAX_MULTI_TARGETS];
CInfoPath *m_pPrevPath;
CBaseEntity *GetNext( void );
CBaseEntity *GetPrev( void );
void SetPrev( CInfoPath *pPrev );
};
class CLaserSpot : public CBaseEntity // laser spot for different weapons
{
void Spawn( void );
void Precache( void );
int ObjectCaps( void ) { return FCAP_DONT_SAVE; }
public:
void Suspend( float flSuspendTime );
void Update( CBasePlayer *m_pPlayer );
void EXPORT Revive( void );
void UpdateOnRemove( void );
void Killed( void ){ UTIL_Remove( this ); }
static CLaserSpot *CreateSpot( entvars_t *pevOwner = NULL );
};
#endif //BASEINFO_H

View File

@ -1,635 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// item_.cpp - items entities: suit,
// helmet, lighter, etc
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "saverestore.h"
#include "baseweapon.h"
#include "client.h"
#include "player.h"
#include "gamerules.h"
#include "defaults.h"
extern int gEvilImpulse101;
//***********************************************************
// main functions ()
//***********************************************************
void CItem::Spawn( void )
{
Precache();
pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_BBOX;
UTIL_SetOrigin( this, pev->origin );
UTIL_SetSize(pev, g_vecZero, g_vecZero );
SetObjectClass( ED_NORMAL );
SetTouch( ItemTouch );
SetThink( ItemFall );
UTIL_SetModel(ENT(pev), pev->model, Model() );
SetNextThink( 0.1 );
}
void CItem::Precache( void )
{
UTIL_PrecacheModel( pev->model, Model() );
UTIL_PrecacheSound( PickSound());
UTIL_PrecacheSound( FallSound());
}
void CItem::ItemTouch( CBaseEntity *pOther )
{
//removed this limitation for monsters
if ( !pOther->IsPlayer() ) return;
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
if (!UTIL_IsMasterTriggered(m_sMaster, pPlayer)) return;
if (pPlayer->pev->deadflag != DEAD_NO) return;
if (AddItem( pPlayer ) != -1 )
{
UTIL_FireTargets( pev->target, pOther, this, USE_TOGGLE );
SetTouch( NULL );
if( IsItem() && gmsg.ItemPickup )
{
//show icon for item
MESSAGE_BEGIN( MSG_ONE, gmsg.ItemPickup, NULL, pPlayer->pev );
WRITE_STRING( STRING(pev->classname) );
MESSAGE_END();
}
// play pickup sound
EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, (char *)PickSound(), 1, ATTN_NORM );
// tell the owner item was taken
if (!FNullEnt( pev->owner )) pev->owner->v.impulse = 0;
// enable respawn in multiplayer
if ( g_pGameRules->IsMultiplayer() && !FBitSet( pev->spawnflags, SF_NORESPAWN ))
Respawn();
else UTIL_Remove( this );
}
else if ( gEvilImpulse101 ) UTIL_Remove( this );
}
void CItem::ItemFall ( void )
{
SetNextThink( 0.1 );
if ( pev->flags & FL_ONGROUND )
{
// clatter if we have an owner (i.e., dropped by someone)
// don't clatter if the item is waiting to respawn (if it's waiting, it is invisible!)
if ( !FNullEnt( pev->owner ))
{
EMIT_SOUND( ENT( pev ), CHAN_ITEM, (char *)FallSound(), 1, ATTN_NORM);
ItemOnGround(); //do somewhat if needed
}
// lie flat
pev->angles.x = 0;
pev->angles.z = 0;
pev->solid = SOLID_TRIGGER;
if( IsAmmo( )) UTIL_SetSize( pev, Vector( -8, -8, -8 ), Vector( 8, 8, 8 ));
if( IsItem( )) UTIL_SetSize( pev, Vector( -8, -8, -8 ), Vector( 8, 8, 8 ));
else UTIL_AutoSetSize();
UTIL_SetOrigin( this, pev->origin ); // link into world.
SetTouch( ItemTouch );
SetThink( NULL );
}
}
CBaseEntity* CItem::Respawn( void )
{
SetTouch( NULL );
pev->effects |= EF_NODRAW;
SetThink( Materialize );
AbsoluteNextThink( ItemRespawnTime( this ) );
return this;
}
float CItem::ItemRespawnTime( CItem *pItem )
{
//makes different time to respawn for weapons and items
float flRespawnTime;
if (IsAmmo()) flRespawnTime = RESPAWN_TIME_30SEC;
if (IsItem()) flRespawnTime = RESPAWN_TIME_120SEC;
return gpGlobals->time + flRespawnTime;
}
void CItem::Materialize( void )
{
if ( pev->effects & EF_NODRAW )
{
// changing from invisible state to visible.
pev->effects &= ~EF_NODRAW;
pev->renderfx = kRenderFxGlowShell;
pev->renderamt = 40;
pev->frags = 0;
pev->rendercolor.x = RANDOM_LONG(25, 255);
pev->rendercolor.y = RANDOM_LONG(25, 255);
pev->rendercolor.z = RANDOM_LONG(25, 255);
pev->scale = 0.01;
SetNextThink (0.001);
}
if( pev->scale > 1.2 ) pev->frags = 1;
if ( pev->frags == 1 )
{ //set effects for respawn item
if(pev->scale > 1.0) pev->scale -= 0.05;
else
{
pev->renderfx = kRenderFxNone;
pev->frags = 0;
SetTouch( ItemTouch );
EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "items/respawn.wav", 1, ATTN_NORM, 0, 150 );
SetThink( NULL );
DontThink();
}
}
else pev->scale += 0.05;
SetNextThink (0.001);
}
//***********************************************************
// generic item
//***********************************************************
class CGenericItem : public CItem
{
const char *Model( void ){ return "models/items/w_adrenaline.mdl"; }
int AddItem( CBaseEntity *pOther )
{
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
if( pPlayer->pev->deadflag != DEAD_NO ) return -1;
if( pOther->GiveAmmo( AMMO_GLOCKCLIP_GIVE, "9mm", _9MM_MAX_CARRY ) != -1 )
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/glock/clip_in.wav", 1, ATTN_NORM);
return 0;
}
MESSAGE_BEGIN( MSG_ONE, gmsg.ItemPickup, NULL, pPlayer->pev );
WRITE_STRING( STRING(pev->classname) );
MESSAGE_END();
return -1;
}
};
LINK_ENTITY_TO_CLASS( item_generic, CGenericItem );
//***********************************************************
// items
//***********************************************************
class CItemSuit : public CItem
{
const char *Model( void ){ return "models/items/w_suit.mdl"; }
int AddItem( CBaseEntity *pOther )
{
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
if ( pPlayer->pev->deadflag != DEAD_NO )
return -1;
if ( pPlayer->pev->weapons & ITEM_SUIT )
return -1;
if( pev->spawnflags & 1 ) // SF_SUIT_SHORTLOGON
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon,
else EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon
pPlayer->pev->weapons |= ITEM_SUIT;
return 0;
}
};
LINK_ENTITY_TO_CLASS( item_suit, CItemSuit );
class CItemLongJump : public CItem
{
const char *Model( void ){ return "models/items/w_longjump.mdl"; }
const char *PickSound( void ){ return "buttons/bell1.wav"; }
int AddItem( CBaseEntity *pOther )
{
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
if( pPlayer->pev->weapons & ITEM_SUIT && !pPlayer->m_fLongJump )
{
pPlayer->m_fLongJump = TRUE;// player now has longjump module
g_engfuncs.pfnSetPhysicsKeyValue( pPlayer->edict(), "slj", "1" );
EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A1" );
return 0;
}
return -1;
}
};
LINK_ENTITY_TO_CLASS( item_longjump, CItemLongJump );
class CItemBattery : public CItem
{
const char *Model( void ){ return "models/items/w_battery.mdl"; }
const char *PickSound( void ){ return "items/gunpickup2.wav"; }
int AddItem( CBaseEntity *pOther ) { return (pOther->TakeArmor( BATTERY_CHARGE, TRUE )) ? 0 : -1; }
};
LINK_ENTITY_TO_CLASS(item_battery, CItemBattery);
class CHealthKit : public CItem
{
const char *Model( void ){ return "models/items/w_medkit.mdl"; }
const char *PickSound( void ){ return "items/smallmedkit1.wav"; }
int AddItem( CBaseEntity *pOther ) { return (pOther->TakeHealth( MEDKIT_CAP, DMG_GENERIC )) ? 0 : -1; }
};
LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit );
class CItemSoda : public CItem
{
public:
const char *Model( void ){ return "models/can.mdl"; }
const char *FallSound( void ){ return "weapons/g_bounce3.wav"; }
int AddItem( CBaseEntity *pOther ) { pOther->TakeHealth( pev->skin * 1, DMG_GENERIC ); return 1; }
};
LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda );
class CItemSecurity : public CItem
{
const char *Model( void ){ return "models/items/w_security.mdl"; }
const char *PickSound( void ){ return "items/gunpickup2.wav"; }
int AddItem( CBaseEntity *pOther ) { return TRUE; }
};
LINK_ENTITY_TO_CLASS(item_security, CItemSecurity);
class CItemArmorVest : public CItem
{
const char *Model( void ){ return "models/items/w_vest.mdl"; }
const char *PickSound( void ){ return "items/gunpickup2.wav"; }
int AddItem( CBaseEntity *pOther ) { return (pOther->TakeArmor( 60 )) ? 0 : -1; }
};
LINK_ENTITY_TO_CLASS(item_armorvest, CItemArmorVest);
class CItemHelmet : public CItem
{
const char *Model( void ){ return "models/items/w_helmet.mdl"; }
const char *PickSound( void ){ return "items/gunpickup2.wav"; }
int AddItem( CBaseEntity *pOther ) { return (pOther->TakeArmor( 40 )) ? 0 : -1; }
};
LINK_ENTITY_TO_CLASS(item_helmet, CItemHelmet);
//***********************************************************
// ammo
//***********************************************************
class CGlockAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_9mmclip.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_GLOCKCLIP_GIVE, "9mm", 250 ); }
};
LINK_ENTITY_TO_CLASS( ammo_9mmclip, CGlockAmmo );
LINK_ENTITY_TO_CLASS( ammo_glockclip, CGlockAmmo );
class CPythonAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_357ammobox.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_357BOX_GIVE, "357", 21 ); }
};
LINK_ENTITY_TO_CLASS( ammo_357, CPythonAmmo );
class CSniperAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_m40a1clip.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_357BOX_GIVE, "762", 21 ); }
};
LINK_ENTITY_TO_CLASS( ammo_762, CSniperAmmo );
class CRpgAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_rpgammo.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_RPGCLIP_GIVE, "rockets", 3 ); }
};
LINK_ENTITY_TO_CLASS( ammo_rpgclip, CRpgAmmo );
class CMP5AmmoClip : public CItem
{
const char *Model( void ){ return "models/ammo/w_9mmARclip.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_MP5CLIP_GIVE, "9mm", 250); }
};
LINK_ENTITY_TO_CLASS( ammo_9mmAR, CMP5AmmoClip );
LINK_ENTITY_TO_CLASS( ammo_mp5clip, CMP5AmmoClip );
class CSawAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_saw_clip.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_CHAINBOX_GIVE, "556", SAW_MAX_CLIP); }
};
LINK_ENTITY_TO_CLASS( ammo_556, CSawAmmo );
class CMP5AmmoGrenade : public CItem
{
const char *Model( void ){ return "models/ammo/w_argrenade.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_M203BOX_GIVE, "m203", 10 ); }
};
LINK_ENTITY_TO_CLASS( ammo_m203, CMP5AmmoGrenade );
class CGaussAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_gaussammo.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( AMMO_URANIUMBOX_GIVE, "uranium", 100 ); }
};
LINK_ENTITY_TO_CLASS( ammo_gaussclip, CGaussAmmo );
class CShotgunAmmoBox : public CItem
{
const char *Model( void ){ return "models/ammo/w_shotbox.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( 12, "buckshot", 125 ); }
};
LINK_ENTITY_TO_CLASS( ammo_buckshot, CShotgunAmmoBox );
class CCrossbowAmmo : public CItem
{
const char *Model( void ){ return "models/ammo/w_crossbow_clip.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( 5, "bolts", 50 ); }
};
LINK_ENTITY_TO_CLASS( ammo_crossbow, CCrossbowAmmo );
class CShotgunAmmoShell : public CItem
{
const char *Model( void ){ return "models/shellBuck.mdl"; }
const char *PickSound( void ){ return "weapons/glock/clip_in.wav"; }
int AddItem( CBaseEntity *pOther ) { return pOther->GiveAmmo( 1, "buckshot", 125 ); }
};
LINK_ENTITY_TO_CLASS( ammo_buckshell, CShotgunAmmoShell );
//***********************************************************
// item_weaponbox - a single entity that can store weapons
// and ammo.
//***********************************************************
LINK_ENTITY_TO_CLASS( item_weaponbox, CWeaponBox );
TYPEDESCRIPTION CWeaponBox::m_SaveData[] =
{
DEFINE_ARRAY( CWeaponBox, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
DEFINE_ARRAY( CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ),
DEFINE_ARRAY( CWeaponBox, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ),
DEFINE_FIELD( CWeaponBox, m_cAmmoTypes, FIELD_INTEGER ),
}; IMPLEMENT_SAVERESTORE( CWeaponBox, CBaseEntity );
void CWeaponBox::Precache( void )
{
UTIL_PrecacheModel( "models/items/w_weaponbox.mdl" );
}
void CWeaponBox :: KeyValue( KeyValueData *pkvd )
{
if ( m_cAmmoTypes < MAX_AMMO_SLOTS )
{
PackAmmo( ALLOC_STRING(pkvd->szKeyName), atoi(pkvd->szValue) );
m_cAmmoTypes++;// count this new ammo type.
pkvd->fHandled = TRUE;
}
else Msg( "WeaponBox too full! only %d ammotypes allowed\n", MAX_AMMO_SLOTS );
}
void CWeaponBox::Spawn( void )
{
Precache( );
pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_TRIGGER;
UTIL_SetSize( pev, g_vecZero, g_vecZero );
UTIL_SetModel( ENT(pev), "models/items/w_weaponbox.mdl" );
}
void CWeaponBox::Kill( void )
{
CBasePlayerWeapon *pWeapon;
int i;
// destroy the weapons
for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ )
{
pWeapon = m_rgpPlayerItems[ i ];
while ( pWeapon )
{
pWeapon->SetThink( Remove );
pWeapon->SetNextThink( 0.1 );
pWeapon = pWeapon->m_pNext;
}
}
// remove the box
UTIL_Remove( this );
}
void CWeaponBox::Touch( CBaseEntity *pOther )
{
if ( !(pev->flags & FL_ONGROUND ) ) return;
if ( !pOther->IsPlayer() ) return;
if ( !pOther->IsAlive() ) return;
CBasePlayer *pPlayer = (CBasePlayer *)pOther;
int i;
// dole out ammo
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ )
{
if ( !FStringNull( m_rgiszAmmo[ i ] ) )
{
// there's some ammo of this type.
pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ), MaxAmmoCarry( m_rgiszAmmo[ i ] ) );
// now empty the ammo from the weaponbox since we just gave it to the player
m_rgiszAmmo[ i ] = iStringNull;
m_rgAmmo[ i ] = 0;
}
}
// go through my weapons and try to give the usable ones to the player.
// it's important the the player be given ammo first, so the weapons code doesn't refuse
// to deploy a better weapon that the player may pick up because he has no ammo for it.
for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ )
{
if ( m_rgpPlayerItems[ i ] )
{
CBasePlayerWeapon *pItem;
// have at least one weapon in this slot
while ( m_rgpPlayerItems[i] )
{
pItem = m_rgpPlayerItems[i];
m_rgpPlayerItems[i] = m_rgpPlayerItems[i]->m_pNext; // unlink this weapon from the box
if( pPlayer->AddPlayerItem( pItem ))
pItem->AttachToPlayer( pPlayer );
}
}
}
EMIT_SOUND( pOther->edict(), CHAN_BODY, "items/gunpickup2.wav", 1, ATTN_NORM );
SetTouch( NULL );
UTIL_Remove( this );
}
int CWeaponBox::MaxAmmoCarry( int iszName )
{
for( int i = 0; i < MAX_WEAPONS; i++ )
{
if( CBasePlayerWeapon::ItemInfoArray[i].iszAmmo1 == iszName )
return CBasePlayerWeapon::ItemInfoArray[i].iMaxAmmo1;
if( CBasePlayerWeapon::ItemInfoArray[i].iszAmmo2 == iszName )
return CBasePlayerWeapon::ItemInfoArray[i].iMaxAmmo2;
}
ALERT( at_error, "MaxAmmoCarry() doesn't recognize '%s'!\n", STRING( iszName ));
return -1;
}
BOOL CWeaponBox::PackWeapon( CBasePlayerWeapon *pWeapon )
{
// is one of these weapons already packed in this box?
if ( HasWeapon( pWeapon ) ) return FALSE;// box can only hold one of each weapon type
if ( pWeapon->m_pPlayer )
{
// failed to unhook the weapon from the player!
if ( !pWeapon->m_pPlayer->RemovePlayerItem( pWeapon ) ) return FALSE;
}
int iWeaponSlot = pWeapon->iItemSlot();
if ( m_rgpPlayerItems[ iWeaponSlot ] )
{
// there's already one weapon in this slot, so link this into the slot's column
pWeapon->m_pNext = m_rgpPlayerItems[ iWeaponSlot ];
m_rgpPlayerItems[ iWeaponSlot ] = pWeapon;
}
else
{
// first weapon we have for this slot
m_rgpPlayerItems[ iWeaponSlot ] = pWeapon;
pWeapon->m_pNext = NULL;
}
pWeapon->pev->spawnflags |= SF_NORESPAWN;// never respawn
pWeapon->pev->movetype = MOVETYPE_NONE;
pWeapon->pev->solid = SOLID_NOT;
pWeapon->pev->effects = EF_NODRAW;
pWeapon->pev->modelindex = 0;
pWeapon->pev->model = iStringNull;
pWeapon->pev->owner = edict();
pWeapon->SetThink( NULL );// crowbar may be trying to swing again, etc.
pWeapon->SetTouch( NULL );
pWeapon->m_pPlayer = NULL;
return TRUE;
}
BOOL CWeaponBox::PackAmmo( int iszName, int iCount )
{
int iMaxCarry;
if ( FStringNull( iszName ) )
{
// error here
Msg( "NULL String in PackAmmo!\n" );
return FALSE;
}
iMaxCarry = MaxAmmoCarry( iszName );
if ( iMaxCarry != -1 && iCount > 0 )
{
GiveAmmo( iCount, (char *)STRING( iszName ), iMaxCarry );
return TRUE;
}
return FALSE;
}
int CWeaponBox::GiveAmmo( int iCount, char *szName, int iMax, int *pIndex/* = NULL*/ )
{
int i;
for (i = 1; i < MAX_AMMO_SLOTS && !FStringNull( m_rgiszAmmo[i] ); i++)
{
if (stricmp( szName, STRING( m_rgiszAmmo[i])) == 0)
{
if (pIndex) *pIndex = i;
int iAdd = min( iCount, iMax - m_rgAmmo[i]);
if (iCount == 0 || iAdd > 0)
{
m_rgAmmo[i] += iAdd;
return i;
}
return -1;
}
}
if ( i < MAX_AMMO_SLOTS )
{
if (pIndex) *pIndex = i;
m_rgiszAmmo[i] = MAKE_STRING( szName );
m_rgAmmo[i] = iCount;
return i;
}
Msg("out of named ammo slots\n");
return i;
}
BOOL CWeaponBox::HasWeapon( CBasePlayerWeapon *pCheckItem )
{
CBasePlayerWeapon *pItem = m_rgpPlayerItems[pCheckItem->iItemSlot()];
while( pItem )
{
if( FClassnameIs( pItem->pev, STRING( pCheckItem->pev->classname )))
return TRUE;
pItem = pItem->m_pNext;
}
return FALSE;
}
BOOL CWeaponBox::IsEmpty( void )
{
int i;
for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ )
{
if ( m_rgpPlayerItems[ i ] )
return FALSE;
}
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ )
{
if ( !FStringNull( m_rgiszAmmo[ i ] ))
return FALSE; // still have a bit of this type of ammo
}
return TRUE;
}
void CWeaponBox::SetObjectCollisionBox( void )
{
pev->absmin = pev->origin + Vector( -16, -16, 0);
pev->absmax = pev->origin + Vector( 16, 16, 16 );
}

View File

@ -1,69 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef ITEMS_H
#define ITEMS_H
class CItem : public CBaseLogic
{
public:
void Spawn( void );
void Precache( void );
CBaseEntity* Respawn( void );
void EXPORT ItemTouch( CBaseEntity *pOther );
void EXPORT Materialize( void );
void EXPORT ItemFall( void );
virtual int AddItem( CBaseEntity *pOther ) { return -1; };
virtual void ItemOnGround( void ) {};
float ItemRespawnTime( CItem *pItem );
virtual BOOL IsItem( void ) { return !strncmp( STRING(pev->classname), "item_", 5 ); }
virtual BOOL IsAmmo( void ) { return !strncmp( STRING(pev->classname), "ammo_", 5 ); }
virtual BOOL IsWeapon( void ) { return FALSE; }
//item_generic
virtual const char *Model( void ){ return NULL; }
virtual const char *PickSound( void ){ return "common/null.wav"; }
virtual const char *FallSound( void ){ return "common/null.wav"; }
};
class CWeaponBox : public CBaseEntity
{
void Precache( void );
void Spawn( void );
void Touch( CBaseEntity *pOther );
void KeyValue( KeyValueData *pkvd );
BOOL IsEmpty( void );
int GiveAmmo( int iCount, char *szName, int iMax, int *pIndex = NULL );
void SetObjectCollisionBox( void );
public:
void EXPORT Kill ( void );
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BOOL HasWeapon( CBasePlayerWeapon *pCheckItem );
BOOL PackWeapon( CBasePlayerWeapon *pWeapon );
BOOL PackAmmo( int iszName, int iCount );
CBasePlayerWeapon *m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each
int MaxAmmoCarry( int iszName );
int m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names
int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
int m_cAmmoTypes;// how many ammo types packed into this box (if packed by a level designer)
};
#endif // ITEMS_H

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASELOGIC_H
#define BASELOGIC_H
#define MAX_MULTI_TARGETS 32 // maximum number of targets that can be added in a list
class CBaseLogic : public CBaseEntity
{
public:
BOOL IsLockedByMaster( void );
BOOL IsLockedByMaster( USE_TYPE useType );
BOOL IsLockedByMaster( CBaseEntity *pActivator );
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
virtual void KeyValue( KeyValueData* pkvd);
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
virtual STATE GetState( void ) { return m_iState; };
float m_flDelay;
float m_flWait;
EHANDLE m_hActivator;
EHANDLE m_hTarget;
STATE m_iState;
string_t m_sMaster;
string_t m_sSet; // used for logic_usetype
string_t m_sReset; // used for logic_usetype
float m_flMin, m_flMax;
};
#include "baseinfo.h"
class CEnvRainModify : public CPointEntity
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
int drips;
RandomRange windXY;
RandomRange randXY;
float fadeTime;
};
#endif //BASELOGIC_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASEMOVER_H
#define BASEMOVER_H
class CBaseMover : public CBaseBrush
{
public:
void KeyValue( KeyValueData *pkvd );
virtual void AxisDir( void );
void (CBaseMover::*m_pfnCallWhenMoveDone)(void); // custom movedone function
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
virtual int IsWater( void ){ return pev->skin != 0; };
static TYPEDESCRIPTION m_SaveData[];
float m_flMoveDistance; // rotating distance
float m_flBlockedTime; // set blocked refresh time
int m_iMode; // style of working
float m_flValue; // value to send
float m_flHeight;
float m_flWait;
float m_flLip;
Vector m_vecPosition1; // startpos
Vector m_vecPosition2; // endpos
Vector m_vecAngle1; // startangle
Vector m_vecAngle2; // endangle
Vector m_vecFinalDest; // basemover finalpos
Vector m_vecFinalAngle; // basemover finalangle
Vector m_vecFloor; // basemover dest floor
float m_flLinearMoveSpeed; // member linear speed
float m_flAngularMoveSpeed; // member angular speed
// common member functions
void LinearMove ( Vector vecInput, float flSpeed );
void AngularMove( Vector vecDestAngle, float flSpeed );
void ComplexMove( Vector vecInput, Vector vecDestAngle, float flSpeed );
void EXPORT LinearMoveNow( void );
void EXPORT AngularMoveNow( void );
void EXPORT ComplexMoveNow( void );
void EXPORT LinearMoveDone( void );
void EXPORT AngularMoveDone( void );
void EXPORT ComplexMoveDone( void );
void EXPORT LinearMoveDoneNow( void );
void EXPORT AngularMoveDoneNow( void );
void EXPORT ComplexMoveDoneNow( void );
};
class CBaseDoor : public CBaseMover
{
public:
void Spawn( void );
void Precache( void );
virtual void PostSpawn( void );
void EXPORT DoorUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT ShowInfo( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT DoorTouch( CBaseEntity *pOther );
virtual void Blocked( CBaseEntity *pOther );
virtual void SetToggleState( int state );
virtual int ObjectCaps( void )
{
if ( FStringNull( pev->targetname ) && m_iMode != 1 ) // door without name player can direct using
return (CBaseMover::ObjectCaps() & ~FCAP_ACROSS_TRANSITION | FCAP_IMPULSE_USE | FCAP_ONLYDIRECT_USE);
return (CBaseMover::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
};
// local functions
void EXPORT DoorGoUp( void );
void EXPORT DoorGoDown( void );
void EXPORT DoorHitTop( void );
void EXPORT DoorHitBottom( void );
virtual BOOL IsRotatingDoor( void ){ return FALSE; };
};
class CRotDoor : public CBaseDoor
{
public:
void Spawn( void );
virtual void PostSpawn( void ) {}
virtual void SetToggleState( int state );
virtual BOOL IsRotatingDoor( void ){ return TRUE; };
};
class CMomentaryDoor : public CBaseMover
{
public:
void Spawn( void );
void Precache( void );
void PostSpawn( void );
void EXPORT MomentaryMoveDone( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void ) { return CBaseMover :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
};
class CBasePlatform : public CBaseMover
{
public:
void Precache( void );
void Spawn( void );
void PostSpawn( void );
void Setup( void );
void PostActivate( void );
virtual void Blocked( CBaseEntity *pOther );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
float CalcFloor( void )
{
float curfloor = ((pev->origin.z - m_vecPosition1.z) / step()) + 1;
if (curfloor - floor(curfloor) > 0.5) return ceil(curfloor);
else return floor(curfloor);
}
float step( void ) { return pev->size.z + m_flHeight - 2; }
float ftime( void ) { return step() / pev->speed; } //time to moving between floors
void EXPORT GoUp( void );
void EXPORT GoDown( void );
void GoToFloor( float floor );
void EXPORT HitTop( void );
void EXPORT HitBottom( void );
void EXPORT HitFloor( void );
virtual BOOL IsMovingPlatform( void ) { return m_flHeight != 0 && m_flMoveDistance == 0; }
virtual BOOL IsRotatingPlatform( void ){ return m_flHeight == 0 && m_flMoveDistance != 0; }
virtual BOOL IsComplexPlatform( void ) { return m_flHeight != 0 && m_flMoveDistance != 0; }
};
class CFuncTrain : public CBasePlatform
{
public:
void Spawn( void );
void PostSpawn( void );
void OverrideReset( void );
void PostActivate( void );
void ClearPointers( void );
BOOL Stop( float flWait = -1 );
BOOL Teleport( void );
void Blocked( CBaseEntity *pOther );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
Vector TrainOrg( void ) { return (pev->mins + pev->maxs) * 0.5; }
void EXPORT Wait( void );
void EXPORT Next( void );
//path operations
BOOL FindPath( void );
BOOL FindNextPath( void );
void UpdateTargets( void );
void UpdateSpeed( float value = 0 );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CBaseEntity *pPath, *pNextPath;
};
#endif //BASEMOVER_H

View File

@ -1,286 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2007
// misc temporary entities
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "player.h"
#include "client.h"
//=======================================================================
// sparkleent - explode post sparks
//=======================================================================
class CEnvShower : public CBaseEntity
{
void Spawn( void );
void Think( void );
void Touch( CBaseEntity *pOther );
int ObjectCaps( void ) { return FCAP_DONT_SAVE; }
};
LINK_ENTITY_TO_CLASS( sparkleent, CEnvShower );
void CEnvShower::Spawn( void )
{
pev->velocity = RANDOM_FLOAT( 200, 300 ) * pev->angles;
pev->velocity.x += RANDOM_FLOAT( -100.0f, 100.0f );
pev->velocity.y += RANDOM_FLOAT( -100.0f, 100.0f );
if ( pev->velocity.z >= 0 ) pev->velocity.z += 200;
else pev->velocity.z -= 200;
pev->movetype = MOVETYPE_BOUNCE;
pev->gravity = 0.5;
SetNextThink( 0.1 );
pev->solid = SOLID_NOT;
UTIL_SetModel( edict(), "models/common/null.mdl");
UTIL_SetSize( pev, g_vecZero, g_vecZero );
pev->effects |= EF_NODRAW;
pev->speed = RANDOM_FLOAT( 0.5f, 1.5f );
pev->angles = g_vecZero;
}
void CEnvShower::Think( void )
{
UTIL_Sparks( pev->origin );
pev->speed -= 0.1;
if ( pev->speed > 0 )
SetNextThink( 0.1 );
else UTIL_Remove( this );
pev->flags &= ~FL_ONGROUND;
}
void CEnvShower::Touch( CBaseEntity *pOther )
{
if( pev->flags & FL_ONGROUND )
pev->velocity = pev->velocity * 0.1f;
else pev->velocity = pev->velocity * 0.6f;
if(( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y ) < 10.0f )
pev->speed = 0;
}
//====================================================================
// ChangeLevelFire
//====================================================================
class ChangeLevelFire : public CBaseLogic
{
public:
void PostActivate( void ) { UTIL_FireTargets( pev->target, this, this, USE_TOGGLE ); UTIL_Remove( this ); }
int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() | FCAP_FORCE_TRANSITION; }
};
LINK_ENTITY_TO_CLASS( fireent, ChangeLevelFire );
//=======================================================================
// faderent - rendering time effects
//=======================================================================
class CRenderFxFader : public CBaseLogic
{
public:
void Spawn ( void ) { m_hTarget = CBaseEntity::Instance( pev->owner ); }
void Think ( void )
{
if (((CBaseEntity*)m_hTarget) == NULL)
{
UTIL_Remove( this );
return;
}
float flDegree = (gpGlobals->time - pev->dmgtime)/pev->speed;
if (flDegree >= 1)
{
m_hTarget->pev->renderamt = pev->renderamt + pev->health;
m_hTarget->pev->rendercolor = pev->rendercolor + pev->movedir;
m_hTarget->pev->scale = pev->scale + pev->frags;
m_hTarget->pev->framerate = pev->framerate + pev->max_health;
UTIL_FireTargets( pev->target, m_hTarget, this, USE_TOGGLE );
m_hTarget = NULL;
SetNextThink( 0.1 );
SetThink(Remove);
}
else
{
m_hTarget->pev->renderamt = pev->renderamt + pev->health * flDegree;
m_hTarget->pev->rendercolor.x = pev->rendercolor.x + pev->movedir.x * flDegree;
m_hTarget->pev->rendercolor.y = pev->rendercolor.y + pev->movedir.y * flDegree;
m_hTarget->pev->rendercolor.z = pev->rendercolor.z + pev->movedir.z * flDegree;
m_hTarget->pev->scale = pev->scale + pev->frags * flDegree;
m_hTarget->pev->framerate = pev->framerate + pev->max_health * flDegree;
SetNextThink( 0.01 );//fader step
}
}
};
LINK_ENTITY_TO_CLASS( faderent, CRenderFxFader );
//=======================================================================
// smokeent - temporary smoke
//=======================================================================
class CSmokeEnt : public CBaseAnimating
{
void Spawn( void );
void Think( void );
};
LINK_ENTITY_TO_CLASS( smokeent, CSmokeEnt );
void CSmokeEnt::Spawn( void )
{
pev->solid = SOLID_BBOX;
pev->movetype = MOVETYPE_NONE;
pev->armorvalue = gpGlobals->time;
if( !pev->team ) pev->team = 50;
if( pev->team > 250 ) pev->team = 250; // normalize and remember about random value 0 - 5
}
void CSmokeEnt::Think( void )
{
if( pev->dmgtime )
{
if( pev->dmgtime < gpGlobals->time )
{
UTIL_Remove( this );
return;
}
else if( RANDOM_FLOAT( 0, pev->dmgtime - pev->armorvalue ) > pev->dmgtime - gpGlobals->time )
{
SetNextThink( 0.2 );
return;
}
}
Vector VecSrc = UTIL_RandomVector( pev->absmin, pev->absmax );
MESSAGE_BEGIN( MSG_PVS, gmsg.TempEntity, VecSrc );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( VecSrc.x );
WRITE_COORD( VecSrc.y );
WRITE_COORD( VecSrc.z );
WRITE_SHORT( g_sModelIndexSmoke );
WRITE_BYTE( RANDOM_LONG( 0, 5 ) + pev->impulse ); // scale * 10
WRITE_BYTE( RANDOM_LONG( 0, 3 ) + 8 ); // framerate
MESSAGE_END();
StudioFrameAdvance( );//animate model if present
SetNextThink( 0.2 );
}
//=========================================================
// func_platform floor indicator
//=========================================================
class CFloorEnt:public CPointEntity
{
void Think( void );
void PostActivate( void );
CBasePlatform *pElevator; // no need to save - PostActivate will be restore this
};
void CFloorEnt::PostActivate( void )
{
pElevator = (CBasePlatform*)CBasePlatform::Instance( pev->owner );
SetNextThink( 0 );
}
void CFloorEnt::Think ( void )
{
if(pElevator && (pElevator->GetState() == STATE_TURN_ON || pElevator->GetState() == STATE_TURN_OFF) )
{
UTIL_FireTargets( pev->target, pElevator, this, USE_SET, pElevator->CalcFloor());
SetNextThink( 0.01 );
}
else UTIL_Remove( this );
}
LINK_ENTITY_TO_CLASS( floorent, CFloorEnt );
//====================================================================
// Laser pointer target
//====================================================================
CLaserSpot *CLaserSpot::CreateSpot( entvars_t *pevOwner )
{
CLaserSpot *pSpot = GetClassPtr( (CLaserSpot *)NULL );
pSpot->Spawn();
pSpot->pev->classname = MAKE_STRING( "misc_laserdot" );
if( pevOwner )
{
// predictable laserspot (cl_lw must be set to 1)
pSpot->pev->flags |= FL_SKIPLOCALHOST;
pSpot->pev->owner = ENT( pevOwner );
pevOwner->effects |= EF_LASERSPOT;
}
return pSpot;
}
void CLaserSpot::Precache( void )
{
UTIL_PrecacheModel( "sprites/laserdot.spr" );
UTIL_PrecacheSound( "weapons/spot_on.wav" );
UTIL_PrecacheSound( "weapons/spot_off.wav" );
}
void CLaserSpot::Spawn( void )
{
Precache( );
// laser dot settings
pev->movetype = MOVETYPE_NONE;
pev->solid = SOLID_NOT;
pev->rendermode = kRenderGlow;
pev->renderfx = kRenderFxNoDissipation;
pev->renderamt = 255;
pev->rendercolor = Vector( 200, 12, 12 );
UTIL_SetModel( ENT( pev ), "sprites/laserdot.spr" );
UTIL_SetOrigin( this, pev->origin );
}
void CLaserSpot::Suspend( float flSuspendTime )
{
pev->effects |= EF_NODRAW;
if( !FNullEnt( pev->owner ))
pev->owner->v.effects &= ~EF_LASERSPOT;
// -1 means suspend indefinitely
if( flSuspendTime == -1 ) SetThink( NULL );
else
{
SetThink( Revive );
SetNextThink( flSuspendTime );
}
}
void CLaserSpot::Revive( void )
{
if( !FNullEnt( pev->owner ))
pev->owner->v.effects |= EF_LASERSPOT;
pev->effects &= ~EF_NODRAW;
SetThink( NULL );
}
void CLaserSpot::UpdateOnRemove( void )
{
// tell the owner about laserspot
if( !FNullEnt( pev->owner ))
pev->owner->v.effects &= ~EF_LASERSPOT;
CBaseEntity :: UpdateOnRemove ();
}
void CLaserSpot::Update( CBasePlayer *m_pPlayer )
{
TraceResult tr;
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
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 );
if( UTIL_PointContents( tr.vecEndPos ) == CONTENTS_SKY && VARS( tr.pHit )->solid == SOLID_BSP )
pev->effects |= EF_NODRAW;
else pev->effects &= ~EF_NODRAW;
}
LINK_ENTITY_TO_CLASS( misc_laserdot, CLaserSpot );

View File

@ -1,34 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2008
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "client.h"
class CPhysEntity : public CBaseEntity
{
public:
void Precache( void )
{
UTIL_PrecacheModel( pev->model, Model() );
}
void Spawn( void )
{
Precache();
pev->movetype = MOVETYPE_PHYSIC;
pev->solid = SolidType();
pev->owner = ENT( pev ); // g-cont. i'm forget why needs this stuff :)
UTIL_SetOrigin( this, pev->origin );
UTIL_SetModel( ENT( pev ), pev->model, (char *)Model() );
SetObjectClass( ED_RIGIDBODY );
}
virtual const char *Model( void ){ return NULL; }
virtual int SolidType( void ){ return SOLID_MESH; } // generic but slow
void PostActivate( void ) { } // stub
};
LINK_ENTITY_TO_CLASS( func_physbox, CPhysEntity );

View File

@ -1,982 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2006
// rockets.cpp - projectiles code
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "monsters.h"
#include "baseweapon.h"
#include "nodes.h"
#include "client.h"
#include "soundent.h"
#include "decals.h"
#include "defaults.h"
//===========================
//
// Grenade code
//
//===========================
void CGrenade::Explode( Vector vecPos, int bitsDamageType, int contents )
{
float flRndSound;// sound randomizer
pev->model = iStringNull;//invisible
pev->solid = SOLID_NOT;// intangible
pev->takedamage = DAMAGE_NO;
if( contents != CONTENTS_SKY )
{
// silent remove in sky
UTIL_Explode( vecPos, pev->owner, pev->impulse, pev->classname );
flRndSound = RANDOM_FLOAT( 0 , 1 );
switch ( RANDOM_LONG( 0, 2 ))
{
case 0: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM ); break;
case 1: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM ); break;
case 2: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM ); break;
}
}
pev->effects |= EF_NODRAW;
SetThink( Remove );
pev->velocity = g_vecZero;
SetNextThink( 0.3 );
}
void CGrenade::Killed( entvars_t *pevAttacker, int iGib )
{
Detonate( );
}
// Timed grenade, this think is called when time runs out.
void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetThink( Detonate );
SetNextThink( 0 );
}
void CGrenade::PreDetonate( void )
{
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, 400, 0.3 );
SetThink( Detonate );
SetNextThink( 1 );
}
void CGrenade::Detonate( void )
{
Vector vecPos = pev->origin - pev->velocity.Normalize() * 32; // set expolsion pos
int contents = UTIL_PointContents( pev->origin + pev->velocity.Normalize() * 8 );
Explode( vecPos, DMG_BLAST, contents );
}
void CGrenade::ExplodeTouch( CBaseEntity *pOther )
{
pev->enemy = pOther->edict();
Vector vecPos = pev->origin - pev->velocity.Normalize() * 32; // set expolsion pos
int contents = UTIL_PointContents( pev->origin + pev->velocity.Normalize() * 8 );
Explode( vecPos, DMG_BLAST, contents );
}
void CGrenade::DangerSoundThink( void )
{
if (!IsInWorld())
{
UTIL_Remove( this );
return;
}
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length( ), 0.2 );
SetNextThink( 0.2 );
if( pev->waterlevel != 0 && pev->watertype > CONTENTS_FLYFIELD )
{
pev->velocity = pev->velocity * 0.5;
}
}
void CGrenade::BounceTouch( CBaseEntity *pOther )
{
// don't hit the guy that launched this grenade
if ( pOther->edict() == pev->owner )
return;
// only do damage if we're moving fairly fast
if (m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100)
{
entvars_t *pevOwner = VARS( pev->owner );
if( pevOwner )
{
TraceResult tr = UTIL_GetGlobalTrace( );
ClearMultiDamage( );
pOther->TraceAttack(pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB );
ApplyMultiDamage( pev, pevOwner);
}
m_flNextAttack = gpGlobals->time + 1.0; // debounce
}
Vector vecTestVelocity;
// pev->avelocity = Vector (300, 300, 300);
// this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical
// or thrown very far tend to slow down too quickly for me to always catch just by testing velocity.
// trimming the Z velocity a bit seems to help quite a bit.
vecTestVelocity = pev->velocity;
vecTestVelocity.z *= 0.45;
if ( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 )
{
//ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() );
// grenade is moving really slow. It's probably very close to where it will ultimately stop moving.
// go ahead and emit the danger sound.
// register a radius louder than the explosion, so we make sure everyone gets out of the way
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 );
m_fRegisteredSound = TRUE;
}
if ( pev->flags & FL_ONGROUND )
{
// add a bit of static friction
pev->velocity = pev->velocity * 0.8;
pev->sequence = 1;
}
else
{
// play bounce sound
BounceSound();
}
pev->framerate = pev->velocity.Length() / 200.0;
if( pev->framerate > 1.0 ) pev->framerate = 1;
else if( pev->framerate < 0.5 ) pev->framerate = 0;
}
void CGrenade::SlideTouch( CBaseEntity *pOther )
{
// don't hit the guy that launched this grenade
if ( pOther->edict() == pev->owner )
return;
// pev->avelocity = Vector (300, 300, 300);
if (pev->flags & FL_ONGROUND)
{
// add a bit of static friction
pev->velocity = pev->velocity * 0.95;
if( pev->velocity.x != 0 || pev->velocity.y != 0 )
{
// maintain sliding sound
}
}
else BounceSound();
}
void CGrenade :: BounceSound( void )
{
switch( RANDOM_LONG( 0, 2 ))
{
case 0: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade/hit1.wav", 0.25, ATTN_NORM ); break;
case 1: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade/hit2.wav", 0.25, ATTN_NORM ); break;
case 2: EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/grenade/hit3.wav", 0.25, ATTN_NORM ); break;
}
}
void CGrenade :: TumbleThink( void )
{
if( !IsInWorld( ))
{
UTIL_Remove( this );
return;
}
StudioFrameAdvance( );
SetNextThink( 0.1 );
if ( pev->dmgtime - 1 < gpGlobals->time )
{
CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * (pev->dmgtime - gpGlobals->time), 400, 0.1 );
}
if (pev->dmgtime <= gpGlobals->time)
{
SetThink( Detonate );
}
if( pev->waterlevel != 0 && pev->watertype > CONTENTS_FLYFIELD )
{
pev->velocity = pev->velocity * 0.5;
pev->framerate = 0.2;
}
}
void CGrenade:: Spawn( void )
{
pev->movetype = MOVETYPE_BOUNCE;
pev->classname = MAKE_STRING( "grenade" );
pev->solid = SOLID_BBOX;
SetObjectClass( ED_NORMAL );
UTIL_SetModel( ENT( pev ), "models/props/hgrenade.mdl");
pev->dmg = 100;
m_fRegisteredSound = FALSE;
}
CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity )
{
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
pGrenade->Spawn();
// contact grenades arc lower
pGrenade->pev->gravity = 0.5;// lower gravity since grenade is aerodynamic and engine doesn't know it.
UTIL_SetOrigin( pGrenade, vecStart );
pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles (pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner);
pGrenade->pev->flags |= FL_PROJECTILE;
// make monsters afaid of it while in the air
pGrenade->SetThink( DangerSoundThink );
pGrenade->SetNextThink( 0 );
// Tumble in air
pGrenade->pev->avelocity.x = RANDOM_FLOAT ( -100, -500 );
// Explode on contact
pGrenade->SetTouch( ExplodeTouch );
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/grenade.mdl");
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
pGrenade->pev->dmg = M203_DMG;
return pGrenade;
}
CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time )
{
CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL );
pGrenade->pev->sequence = RANDOM_LONG( 3, 6 );
pGrenade->pev->origin = vecStart;
pGrenade->Spawn();
pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles( pGrenade->pev->velocity );
pGrenade->pev->owner = ENT(pevOwner);
pGrenade->SetTouch( BounceTouch ); // Bounce if touched
// Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate
// will insert a DANGER sound into the world sound list and delay detonation for one second so that
// the grenade explodes after the exact amount of time specified in the call to ShootTimed().
pGrenade->pev->dmgtime = gpGlobals->time + time;
pGrenade->SetThink( TumbleThink );
pGrenade->SetNextThink( 0.1 );
if( time < 0.1f )
{
pGrenade->SetNextThink( 0 );
pGrenade->pev->velocity = Vector( 0, 0, 0 );
}
pGrenade->pev->framerate = 1.0;
pGrenade->pev->flags |= FL_PROJECTILE;
// Tumble through the air
pGrenade->pev->avelocity.x = -400;
pGrenade->pev->gravity = 0.5;
pGrenade->pev->friction = 0.8;
pGrenade->pev->scale = 0.5; // original Valve model is too big :)
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/hgrenade.mdl" );
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
pGrenade->pev->dmg = 100;
return pGrenade;
}
LINK_ENTITY_TO_CLASS( grenade, CGrenade );
//===========================
//
// Rocket code
//
//===========================
CRpgRocket *CRpgRocket::Create ( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CBasePlayerWeapon *pLauncher )
{
CRpgRocket *pRocket = GetClassPtr( (CRpgRocket *)NULL );
pRocket->pev->origin = vecOrigin;
pRocket->pev->angles = vecAngles;
pRocket->Spawn();
pRocket->SetTouch( RocketTouch );
pRocket->m_pLauncher = pLauncher;// remember what RPG fired me.
pRocket->m_pLauncher->m_cActiveRocket++;// register this missile as active for the launcher
pRocket->pev->owner = pOwner->edict();
pRocket->pev->flags |= FL_PROJECTILE;
return pRocket;
}
TYPEDESCRIPTION CRpgRocket::m_SaveData[] =
{
DEFINE_FIELD( CRpgRocket, m_flIgniteTime, FIELD_TIME ),
DEFINE_FIELD( CRpgRocket, m_pLauncher, FIELD_CLASSPTR ),
};
IMPLEMENT_SAVERESTORE( CRpgRocket, CGrenade );
void CRpgRocket :: Spawn( void )
{
Precache( );
// motor
pev->movetype = MOVETYPE_BOUNCE;
pev->solid = SOLID_BBOX;
UTIL_SetModel(ENT(pev), "models/props/rocket.mdl");
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, pev->origin );
pev->classname = MAKE_STRING( "rpg_rocket" );
SetThink( IgniteThink );
SetTouch( RocketTouch );
pev->angles.x -= 30;
UTIL_MakeVectors( pev->angles );
pev->angles.x = -(pev->angles.x + 30);
pev->velocity = gpGlobals->v_forward * 250;
pev->gravity = 0.5;
SetNextThink( 0.4 );
pev->dmg = RPG_ROCKET_DMG;
}
void CRpgRocket :: RocketTouch ( CBaseEntity *pOther )
{
CBaseEntity *pPlayer = CBaseEntity::Instance(pev->owner);
if ( m_pLauncher ) m_pLauncher->m_cActiveRocket--;
STOP_SOUND( edict(), CHAN_VOICE, "weapons/rpg/rocket1.wav" );
ExplodeTouch( pOther );
}
void CRpgRocket::Detonate( void )
{
CBaseEntity *pPlayer = CBaseEntity::Instance(pev->owner);
if ( m_pLauncher ) m_pLauncher->m_cActiveRocket--;
STOP_SOUND( edict(), CHAN_VOICE, "weapons/rpg/rocket1.wav" );
CGrenade :: Detonate();
}
void CRpgRocket :: Precache( void )
{
UTIL_PrecacheModel( "models/props/rocket.mdl" );
UTIL_PrecacheSound( "weapons/rpg/rocket1.wav" );
UTIL_PrecacheSound( "weapons/rpg/beep.wav" );
UTIL_PrecacheSound( "weapons/rpg/beep2.wav" );
m_iTrail = UTIL_PrecacheModel( "sprites/smoke.spr" );
}
void CRpgRocket :: IgniteThink( void )
{
pev->movetype = MOVETYPE_FLY;
pev->effects |= EF_LIGHT;
CreateTrail();
m_flIgniteTime = gpGlobals->time;
// set to follow laser spot
SetThink( FollowThink );
SetNextThink( 0.1 );
}
void CRpgRocket :: CreateTrail( void )
{
if( b_setup ) return;
// make rocket sound after save\load
EMIT_SOUND( ENT(pev), CHAN_VOICE, "weapons/rpg/rocket1.wav", 1, 0.5 );
// restore rocket trail
SFX_Trail( entindex(), m_iTrail );
b_setup = TRUE;
}
void CRpgRocket :: FollowThink( void )
{
CBaseEntity *pOther = NULL;
Vector vecTarget;
Vector vecDir;
float flDist, flMax, flDot;
TraceResult tr;
UTIL_MakeAimVectors( pev->angles );
CreateTrail();
vecTarget = gpGlobals->v_forward;
flMax = 4096;
// Examine all entities within a reasonable radius
while ((pOther = UTIL_FindEntityByClassname( pOther, "misc_laserdot" )) != NULL)
{
UTIL_TraceLine ( pev->origin, pOther->pev->origin, dont_ignore_monsters, ENT(pev), &tr );
// Msg( "%f\n", tr.flFraction );
if (tr.flFraction >= 0.90)
{
vecDir = pOther->pev->origin - pev->origin;
flDist = vecDir.Length( );
vecDir = vecDir.Normalize( );
flDot = DotProduct( gpGlobals->v_forward, vecDir );
if ((flDot > 0) && (flDist * (1 - flDot) < flMax))
{
flMax = flDist * (1 - flDot);
vecTarget = vecDir;
}
}
}
pev->angles = UTIL_VecToAngles( vecTarget );
// this acceleration and turning math is totally wrong, but it seems to respond well so don't change it.
float flSpeed = pev->velocity.Length();
if (gpGlobals->time - m_flIgniteTime < 1.0)
{
pev->velocity = pev->velocity * 0.2 + vecTarget * (flSpeed * 0.8 + 400);
if ( pev->waterlevel == 3 && pev->watertype > CONTENTS_FLYFIELD )
{
// go slow underwater
if (pev->velocity.Length() > 300)
{
pev->velocity = pev->velocity.Normalize() * 300;
}
UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 4 );
}
else
{
if (pev->velocity.Length() > 2000)
{
pev->velocity = pev->velocity.Normalize() * 2000;
}
}
}
else
{
if (pev->effects & EF_LIGHT)
{
pev->effects = 0;
STOP_SOUND( ENT(pev), CHAN_VOICE, "weapons/rpg/rocket1.wav" );
}
pev->velocity = pev->velocity * 0.2 + vecTarget * flSpeed * 0.798;
if ((pev->waterlevel == 0 || pev->watertype == CONTENTS_FOG) && pev->velocity.Length() < 1500)
{
Detonate( );
}
}
//Msg( "%.0f\n", flSpeed );
SetNextThink( 0.05 );
}
LINK_ENTITY_TO_CLASS( rpg_rocket, CRpgRocket );
//===========================
// apache HVR rocket
//===========================
void CApacheHVR :: Spawn( void )
{
Precache( );
// motor
pev->movetype = MOVETYPE_FLY;
pev->solid = SOLID_BBOX;
UTIL_SetModel(ENT(pev), "models/HVR.mdl");
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, pev->origin );
SetThink( IgniteThink );
SetTouch( ExplodeTouch );
UTIL_MakeAimVectors( pev->angles );
pev->movedir = gpGlobals->v_forward;
pev->gravity = 0.5;
SetNextThink( 0.1 );
pev->dmg = 150;
}
void CApacheHVR :: Precache( void )
{
UTIL_PrecacheModel("models/HVR.mdl");
m_iTrail = UTIL_PrecacheModel("sprites/smoke.spr");
UTIL_PrecacheSound("weapons/rocket1.wav");
}
void CApacheHVR :: IgniteThink( void )
{
// pev->movetype = MOVETYPE_TOSS;
// pev->movetype = MOVETYPE_FLY;
pev->effects |= EF_LIGHT;
// make rocket sound
EMIT_SOUND( ENT(pev), CHAN_VOICE, "weapons/rocket1.wav", 1, 0.5 );
// rocket trail
MESSAGE_BEGIN( MSG_BROADCAST, gmsg.TempEntity );
WRITE_BYTE( TE_BEAMFOLLOW );
WRITE_SHORT(entindex()); // entity
WRITE_SHORT(m_iTrail ); // model
WRITE_BYTE( 15 ); // life
WRITE_BYTE( 5 ); // width
WRITE_BYTE( 224 ); // r, g, b
WRITE_BYTE( 224 ); // r, g, b
WRITE_BYTE( 255 ); // r, g, b
WRITE_BYTE( 255 ); // brightness
MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS)
// set to accelerate
SetThink( AccelerateThink );
SetNextThink( 0.1 );
}
void CApacheHVR :: AccelerateThink( void )
{
// check world boundaries
if(!IsInWorld())
{
UTIL_Remove( this );
return;
}
// accelerate
float flSpeed = pev->velocity.Length();
if (flSpeed < 1800)
{
pev->velocity = pev->velocity + pev->movedir * 200;
}
// re-aim
pev->angles = UTIL_VecToAngles( pev->velocity );
SetNextThink( 0.1 );
}
LINK_ENTITY_TO_CLASS( hvr_rocket, CApacheHVR );
//===========================
// Nuclear explode code
//===========================
#define REDEEMER_ROCKET_DMG 500
CNukeExplode *CNukeExplode::Create ( Vector vecOrigin, CBaseEntity *pOwner )
{
CNukeExplode *pNuke = GetClassPtr( (CNukeExplode *)NULL );
pNuke->pev->origin = vecOrigin;
pNuke->Spawn();
pNuke->pev->classname = MAKE_STRING( "nuclear_explode" );
pNuke->pevOwner = pOwner->pev;
return pNuke;
}
void CNukeExplode :: Spawn( void )
{
Precache();
UTIL_SetModel( ENT( pev ), "models/props/nexplode.mdl" );
TraceResult tr;
UTIL_TraceLine ( pev->origin, pev->origin + Vector ( 0, 0, -32 ), ignore_monsters, ENT(pev), &tr);
UTIL_ScreenShake( pev->origin, 16, 1, 2, 1700 );
pev->oldorigin = tr.vecEndPos + (tr.vecPlaneNormal * 30); // save normalized position
// create first explode sprite
SFX_Explode( m_usExplodeSprite, pev->origin, 70, TE_EXPLFLAG_NOPARTICLES|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NODLIGHTS );
EMIT_SOUND( edict(), CHAN_VOICE, "weapons/warhead/whexplode.wav", 1, ATTN_NONE );
pev->movetype = MOVETYPE_NONE;
pev->solid = SOLID_NOT;
pev->rendermode = kRenderTransAdd;
pev->renderamt = 190;
pev->scale = 0.5;
UTIL_SetOrigin( this, pev->origin );
SetThink( ExplodeThink );
pev->dmg = REDEEMER_ROCKET_DMG;
SetNextThink( 0 );
}
void CNukeExplode :: Precache( void )
{
m_usExplodeSprite = UTIL_PrecacheModel( "sprites/war_explo01.spr" );
m_usExplodeSprite2 = UTIL_PrecacheModel( "sprites/war_explo02.spr" );
UTIL_PrecacheModel( "models/props/nexplode.mdl" );
UTIL_PrecacheSound( "weapons/warhead/whexplode.wav" );
}
void CNukeExplode :: ExplodeThink( void )
{
pev->renderamt = UTIL_Approach( 0, pev->renderamt, 200 * gpGlobals->frametime );
pev->scale = UTIL_Approach( 30, pev->scale, 30 * gpGlobals->frametime );
if( pev->scale > 8.0f && m_usExplodeSprite2 ) // create second explode sprite
{
SFX_Explode( m_usExplodeSprite2, pev->origin, 70, TE_EXPLFLAG_NOPARTICLES|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NODLIGHTS );
m_usExplodeSprite2 = 0; // fire once
}
pev->owner = NULL; // can't traceline attack owner if this is set
::RadiusDamage( pev->origin, pev, pevOwner, pev->renderamt/2, pev->scale * 30, CLASS_NONE, DMG_BLAST|DMG_NUCLEAR );
if( pev->scale == 30 ) UTIL_Remove( this );
SetNextThink( 0.01 );
}
LINK_ENTITY_TO_CLASS( nuclear_explode, CNukeExplode );
//===========================
// Nuke rocket code
//===========================
// redeemder settings (weapon_redeemer)
#define WARHEAD_SPEED 500
#define WARHEAD_SPEED_UNDERWATER 300
#define WARHEAD_MAX_SPEED 1200
CWHRocket *CWHRocket::Create( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CBasePlayerWeapon *pLauncher, BOOL Controllable )
{
CWHRocket *pRocket = GetClassPtr( (CWHRocket *)NULL );
pRocket->pev->origin = vecOrigin;
pRocket->pev->angles = vecAngles;
pRocket->m_pLauncher = pLauncher; // remember what RPG fired me.
pRocket->pev->owner = pOwner->edict();
pRocket->pev->button = Controllable; // memeber rocket type
pRocket->pev->classname = MAKE_STRING( "nuke_rocket" );
pRocket->m_pLauncher->m_cActiveRocket++;// register rocket
pRocket->Spawn();
pRocket->pev->flags |= FL_PROJECTILE;
return pRocket;
}
TYPEDESCRIPTION CWHRocket::m_SaveData[] =
{
DEFINE_FIELD( CWHRocket, m_pLauncher, FIELD_CLASSPTR ),
DEFINE_FIELD( CWHRocket, m_pPlayer, FIELD_CLASSPTR ),
};
IMPLEMENT_SAVERESTORE( CWHRocket, CBaseAnimating );
void CWHRocket :: Spawn( void )
{
Precache( );
m_pPlayer = (CBasePlayer*)CBasePlayer::Instance( pev->owner );
if( !m_pPlayer ) // leveldesigner may put rocket on a map
{
if( !IsMultiplayer())
{
ALERT( at_warning, "player pointer is not valid\n" );
m_pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( 1 );
}
else
{
UTIL_Remove( this );
return;
}
}
pev->movetype = MOVETYPE_FLY;
pev->solid = SOLID_SLIDEBOX;
pev->takedamage = DAMAGE_YES;
pev->health = 10;
pev->speed = WARHEAD_SPEED; // set initial speed
UTIL_SetModel( ENT( pev ), "models/props/whrocket.mdl" );
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/warhead/launch.wav", 1, 0.5 );
UTIL_SetOrigin( this, pev->origin );
SetThink( FollowThink );
SetTouch( NukeTouch );
UTIL_MakeVectors( pev->angles );
pev->angles.x = -(pev->angles.x);
pev->velocity = gpGlobals->v_forward * pev->speed;
m_Center = pev->angles;
if( pev->button )
{
UTIL_SetView( m_pPlayer, this, CAMERA_ON|INVERSE_X );
m_pLauncher->m_iOnControl = 1; // start controlling
m_pPlayer->m_iWarHUD = 1; // enable warhead HUD
}
SetNextThink( 0.1 );
}
void CWHRocket :: Precache( void )
{
UTIL_PrecacheModel("models/props/whrocket.mdl");
UTIL_PrecacheSound("weapons/warhead/launch.wav");
UTIL_PrecacheSound("weapons/warhead/whfly.wav");
UTIL_PrecacheEntity( "nuclear_explode" );//explode
m_iTrail = UTIL_PrecacheAurora("whtrail");
m_iBurst = UTIL_PrecacheAurora("whburst");
b_setup = FALSE;
}
void CWHRocket :: CreateTrail( void )
{
if( b_setup ) return; // restore function
EMIT_SOUND( ENT(pev), CHAN_VOICE, "weapons/warhead/whfly.wav", 1, 0.5 );
UTIL_SetAurora( this, m_iTrail );
UTIL_SetAurora( this, m_iBurst );
pev->renderfx = kRenderFxAurora;
b_setup = TRUE;
}
void CWHRocket :: FollowThink( void )
{
Vector angles, velocity;//private angles & velocity to transform
CreateTrail();
if( pev->button ) // controllable rocket
{
UTIL_MakeVectorsPrivate( m_pPlayer->pev->v_angle, forward, NULL, NULL );
angles = m_pPlayer->pev->v_angle;
angles.x = -angles.x;
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 );
angles.z = m_Center.z + UTIL_AngleDistance( angles.z, m_Center.z );
float distX = UTIL_AngleDistance( angles.x, pev->angles.x );
pev->avelocity.x = distX * steer;
float distY = UTIL_AngleDistance( angles.y, pev->angles.y );
pev->avelocity.y = distY * steer;
float distZ = UTIL_AngleDistance( angles.z, pev->angles.z );
pev->avelocity.z = distY * -steer + distZ * steer;
pev->velocity = forward * pev->speed + pev->avelocity;
if( m_pLauncher && m_pLauncher->m_iOnControl == 2 )
{
Detonate(); // check for himself destroy
return;
}
}
CalculateVelocity();
//Msg("Speed %.f\n", pev->velocity.Length());
SetNextThink( 0.1 );
}
void CWHRocket::CalculateVelocity ( void )
{
if(pev->waterlevel == 3)//go slow underwater
{
if (pev->speed > WARHEAD_SPEED_UNDERWATER) pev->speed -= 30;
GetAttachment( 0, pev->oldorigin, pev->movedir );
UTIL_BubbleTrail( pev->oldorigin - pev->velocity * 0.1, pev->oldorigin, 4 );
if( pev->button ) m_pPlayer->m_iWarHUD = 2;
}
else
{
pev->speed += 5; // accelerate rocket
if( pev->button ) m_pPlayer->m_iWarHUD = 1;
}
if( pev->speed > WARHEAD_SPEED )
pev->velocity = pev->velocity.Normalize() * WARHEAD_SPEED;
}
int CWHRocket::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
pev->health -= flDamage;//calculate health
if (pev->health <= 0) Detonate();
return 1;
}
void CWHRocket :: NukeTouch ( CBaseEntity *pOther )
{
pev->enemy = pOther->edict(); //save enemy
Vector vecAngles( pev->angles );
vecAngles.x = -vecAngles.x;
UTIL_MakeVectors( vecAngles );
// check for sky
if( UTIL_PointContents( pev->origin + gpGlobals->v_forward * 32 ) == CONTENTS_SKY )
Detonate( FALSE ); // silent remove in sky
else Detonate();
SetNextThink( 0.7f );
}
void CWHRocket :: Detonate ( bool explode )
{
// NOTE: Player can controlled one rocket at moment
// but non controlled rocket don't reset this indicator
if( pev->button ) m_pPlayer->m_iWarHUD = 3; // make static noise
// launcher callback
if( m_pLauncher ) m_pLauncher->m_cActiveRocket--;
pev->takedamage = DAMAGE_NO;
pev->renderfx = kRenderFxNone; // disable trail
pev->velocity = g_vecZero;
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects |= EF_NODRAW;
pev->model = iStringNull; // invisible
STOP_SOUND( edict(), CHAN_VOICE, "weapons/warhead/whfly.wav" );//stop flying sound
if( explode )
{
// make nuclear explosion if needed
CNukeExplode::Create( pev->origin, m_pPlayer );
SetThink( RemoveRocket );
SetNextThink( 2.5 ); // let the smoke continue moving
}
else
{
SetThink( RemoveRocket );
SetNextThink( 2.5 );
}
}
void CWHRocket :: RemoveRocket ( void )
{
if( m_pLauncher )
m_pLauncher->m_iOnControl = 0; //stop controlling
if( pev->button )
{
m_pPlayer->m_iWarHUD = 0;//reset HUD
UTIL_SetView( m_pPlayer, iStringNull, 0 );//reset view
}
SetThink( Remove );
SetNextThink( 0.1 );
}
LINK_ENTITY_TO_CLASS( nuke_rocket, CWHRocket );
//===========================
// crossbow bolt
//===========================
CBolt *CBolt::Create( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner )
{
// Create a new entity with CBolt private data
CBolt *pBolt = GetClassPtr( (CBolt *)NULL );
pBolt->pev->classname = MAKE_STRING("bolt");
pBolt->Spawn();
pBolt->pev->origin = vecOrigin;
pBolt->pev->angles = vecAngles;
pBolt->pev->owner = pOwner->edict();
pBolt->pev->avelocity.z = 10;
return pBolt;
}
void CBolt::Spawn( )
{
Precache( );
pev->movetype = MOVETYPE_FLY;
pev->solid = SOLID_BBOX;
pev->gravity = 0.5;
UTIL_SetModel(ENT(pev), "models/crossbow_bolt.mdl");
UTIL_SetOrigin( this, pev->origin );
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_fire1.wav", 1, ATTN_NORM);
SetThink( BubbleThink );
SetNextThink( 0.2 );
}
void CBolt::Precache( )
{
UTIL_PrecacheModel("models/crossbow_bolt.mdl");
UTIL_PrecacheSound("weapons/xbow_hitbod1.wav");
UTIL_PrecacheSound("weapons/xbow_hitbod2.wav");
UTIL_PrecacheSound("weapons/xbow_hit1.wav");
UTIL_PrecacheSound("weapons/xbow_fire1.wav");
}
void CBolt::Touch( CBaseEntity *pOther )
{
SetTouch( NULL );
if (pOther->IsMonster() || pOther->IsPlayer())
{
TraceResult tr = UTIL_GetGlobalTrace( );
entvars_t *pevOwner;
pevOwner = VARS( pev->owner );
ClearMultiDamage( );
pOther->TraceAttack(pevOwner, BOLT_DMG, pev->velocity.Normalize(), &tr, DMG_NEVERGIB );
ApplyMultiDamage( pev, pevOwner );
pev->velocity = Vector( 0, 0, 0 );
// play body "thwack" sound
switch( RANDOM_LONG(0,1) )
{
case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_hitbod1.wav", 1, ATTN_NORM); break;
case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM); break;
}
Killed( pev, GIB_NEVER );
}
else
{
EMIT_SOUND_DYN(ENT(pev), CHAN_BODY, "weapons/xbow_hit1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 98 + RANDOM_LONG(0,7));
SetNextThink( 0 );
Vector vecDir = pev->velocity.Normalize( );
UTIL_SetOrigin( this, pev->origin - vecDir * 12 );
pev->angles = UTIL_VecToAngles( vecDir );
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_FLY;
pev->velocity = Vector( 0, 0, 0 );
pev->avelocity.z = 0;
pev->angles.z = RANDOM_LONG(0, 360);
if ( pOther == g_pWorld ) SetThink( PVSRemove );
else if( pOther->IsBSPModel())
{
SetParent( pOther );//glue bolt with parent system
SetThink( PVSRemove );
}
else SetThink( Remove );
if( UTIL_PointContents( pev->origin ) != CONTENTS_WATER )
UTIL_Sparks( pev->origin );
}
}
void CBolt::BubbleThink( void )
{
if (pev->waterlevel == 3) UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 1 );
SetNextThink( 0.1 );
}
LINK_ENTITY_TO_CLASS( bolt, CBolt );

View File

@ -1,111 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2006
// rockets.h - projectiles code
//=======================================================================
#include "baseweapon.h"
class CGrenade : public CBaseMonster
{
public:
void Spawn( void );
static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time );
static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
void Explode( Vector vecPos, int bitsDamageType, int contents );
void EXPORT BounceTouch( CBaseEntity *pOther );
void EXPORT SlideTouch( CBaseEntity *pOther );
void EXPORT ExplodeTouch( CBaseEntity *pOther );
void EXPORT DangerSoundThink( void );
void EXPORT PreDetonate( void );
void EXPORT Detonate( void );
void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT TumbleThink( void );
virtual void BounceSound( void );
virtual int BloodColor( void ) { return DONT_BLEED; }
virtual void Killed( entvars_t *pevAttacker, int iGib );
BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet.
};
class CRpgRocket : public CGrenade
{
public:
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void Spawn( void );
void Precache( void );
void EXPORT FollowThink( void );
void EXPORT IgniteThink( void );
void EXPORT RocketTouch( CBaseEntity *pOther );
void Detonate( void );
void CreateTrail( void );
static CRpgRocket *Create ( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CBasePlayerWeapon *pLauncher );
int m_iTrail;
float m_flIgniteTime;
CBasePlayerWeapon *m_pLauncher;// pointer back to the launcher that fired me.
BOOL b_setup;
};
class CApacheHVR : public CGrenade
{
void Spawn( void );
void Precache( void );
void EXPORT IgniteThink( void );
void EXPORT AccelerateThink( void );
int m_iTrail;
};
class CNukeExplode : public CBaseLogic
{
public:
void Spawn( void );
void Precache( void );
void EXPORT ExplodeThink( void );
static CNukeExplode *Create ( Vector vecOrigin, CBaseEntity *pOwner );
short m_usExplodeSprite;
short m_usExplodeSprite2;
entvars_t *pevOwner; // keep pointer to rocket owner
};
class CWHRocket : public CBaseAnimating
{
public:
int Save( CSave &save );
int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void Spawn( void );
void Precache( void );
void CreateTrail( void );
void EXPORT FollowThink( void );
void EXPORT NukeTouch( CBaseEntity *pOther );
void EXPORT RemoveRocket ( void );
void CalculateVelocity ( void );
void Detonate ( bool explode = 1 );
static CWHRocket *Create ( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CBasePlayerWeapon *pLauncher, BOOL Control );
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
int m_iTrail, m_iBurst;// rocket trail
CBasePlayerWeapon *m_pLauncher;// pointer back to the launcher that fired me.
CBasePlayer *m_pPlayer;
Vector m_Center, forward;
BOOL b_setup;
};
class CBolt : public CBaseAnimating
{
public:
void Spawn( void );
void Precache( void );
int ObjectCaps( void ) { return FCAP_DONT_SAVE; }
void EXPORT BubbleThink( void );
void Touch( CBaseEntity *pOther );
static CBolt *Create( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner );
int m_iTrail;
};

View File

@ -1,150 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASESPRITE_H
#define BASESPRITE_H
#define SF_TEMPSPRITE 0x8000 //play sequence and die
#include "baseworld.h"
class CSprite : public CBaseLogic
{
public:
void Spawn( void );
void Precache( void ) { UTIL_PrecacheModel( pev->model ); }
void PostActivate( void )
{
// env_glow always enabled
if( FClassnameIs( pev, "env_glow" ) || FStringNull( pev->targetname ) || pev->spawnflags & SF_START_ON )
{
TurnOn();
ClearBits( pev->spawnflags, SF_START_ON );
}
else TurnOff();
}
void Think( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void Move( void );
void PostSpawn( void );
void Animate( float frames )
{
if( Frames() > 1 )
{
pev->frame += frames;
if( pev->frame > Frames() )
{
if( pev->spawnflags & SF_FIREONCE ) TurnOff();
else if( Frames() > 0 ) pev->frame = fmod( pev->frame, Frames() );
}
}
}
void TurnOff( void );
void TurnOn( void );
float Frames( void ) { return MODEL_FRAMES( pev->modelindex ) - 1; }
inline void SetTransparency( int rendermode, int r, int g, int b, int a, int fx )
{
pev->rendermode = rendermode;
pev->rendercolor.x = r;
pev->rendercolor.y = g;
pev->rendercolor.z = b;
pev->renderamt = a;
pev->renderfx = fx;
}
inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; }
inline void SetScale( float scale ) { pev->scale = scale; }
inline void SetBrightness( int brightness ) { pev->renderamt = brightness; }
inline void AnimateAndDie( float framerate )
{
SetBits( pev->spawnflags, SF_TEMPSPRITE );
pev->framerate = framerate;
pev->dmg_take = gpGlobals->time + (Frames() / framerate);
SetNextThink( 0 );
}
static CSprite *SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
{
CSprite *pSprite = GetClassPtr( (CSprite *)NULL );
pSprite->pev->classname = MAKE_STRING("env_sprite");
pSprite->pev->model = MAKE_STRING(pSpriteName);
pSprite->pev->origin = origin;
pSprite->Spawn();
if ( animate ) pSprite->TurnOn();
else ClearBits( pSprite->pev->effects, EF_NODRAW );
return pSprite;
}
};
class CShot : public CSprite
{
public:
void Touch ( CBaseEntity *pOther )
{
if (pev->teleport_time > gpGlobals->time) return;
pev->teleport_time = gpGlobals->time + 0.1;
if ( pOther != g_pWorld) UTIL_FireTargets( pev->target, pOther, this, USE_ON );
else UTIL_FireTargets( pev->target, pOther, this, USE_SET ); //world touch
}
static CShot *CreateShot ( const char *szGibModel, Vector size )
{
CShot *pShot = GetClassPtr( (CShot*)NULL );
pShot->pev->classname = MAKE_STRING("shot");
pShot->pev->solid = SOLID_SLIDEBOX;
UTIL_SetModel(ENT(pShot->pev), szGibModel );
UTIL_SetSize(pShot->pev, -size, size );
return pShot;
}
};
class CGib : public CBaseEntity
{
public:
void Spawn( const char *szGibModel );
void EXPORT BounceGibTouch ( CBaseEntity *pOther );
void EXPORT StickyGibTouch ( CBaseEntity *pOther );
void EXPORT WaitTillLand( void );
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; }
static CGib *CreateGib ( CBaseEntity *pVictim, const char *szGibModel, int gibtype );
//spawn gibs
static void SpawnHeadGib( CBaseEntity *pVictim, string_t m_iGibModel = NULL )
{
if( FStringNull( m_iGibModel ))
CreateGib( pVictim, "models/gibs/hgibs.mdl", 1 );
else CreateGib( pVictim, STRING( m_iGibModel ), 1 );
}
static void SpawnRandomGibs( CBaseEntity *pVictim, int cGibs, int human, string_t m_iGibModel = NULL )
{
const char *model;
if( FStringNull( m_iGibModel ))
{
if( human ) model = "models/gibs/hgibs.mdl";
else model = "models/gibs/agibs.mdl";
}
else model = (char *)STRING( m_iGibModel );
for( int i = 0; i < cGibs; i++ )
CreateGib( pVictim, model, 0 );
}
static void SpawnStickyGibs( CBaseEntity *pVictim, int cGibs, string_t m_iGibModel = NULL )
{
if( !FStringNull( m_iGibModel ))
for( int i = 0; i < cGibs; i++ )
CreateGib( pVictim, STRING( m_iGibModel ), 2 );
else for( int i = 0; i < cGibs; i++ )
CreateGib( pVictim, "models/gibs/stickygib.mdl", 2 );
}
int m_bloodColor;
int m_cBloodDecals;
int m_material;
float m_lifeTime;
};
#endif //BASESPRITE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,143 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#define SF_TANK_ACTIVE 0x0001
#define SF_TANK_LINEOFSIGHT 0x0010
#define SF_TANK_CANCONTROL 0x0020
#define SF_TANK_LASERSPOT 0x0040 //LRC
#define SF_TANK_MATCHTARGET 0x0080 //LRC
#define SF_TANK_SOUNDON 0x8000
#define SF_TANK_SEQFIRE 0x10000 //LRC - a TankSequence is telling me to fire
static Vector gTankSpread[] =
{
Vector( 0, 0, 0 ), // perfect
Vector( 0.025, 0.025, 0.025 ), // small cone
Vector( 0.05, 0.05, 0.05 ), // medium cone
Vector( 0.1, 0.1, 0.1 ), // large cone
Vector( 0.25, 0.25, 0.25 ), // extra-large cone
};
#define MAX_FIRING_SPREADS ARRAYSIZE(gTankSpread)
enum TANKBULLET
{
TANK_BULLET_NONE = 0,
TANK_BULLET_9MM = 1,
TANK_BULLET_MP5 = 2,
TANK_BULLET_12MM = 3,
};
class CFuncTankControls;
class CFuncTank : public CBaseBrush
{
public:
void Spawn( void );
void PostSpawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void Think( void );
void TrackTarget( void );
int IRelationship( CBaseEntity* pTarget );
int Classify( void ) { return m_iTankClass; }
void TryFire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker );
virtual void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker );
virtual Vector UpdateTargetPosition( CBaseEntity *pTarget )
{
return pTarget->BodyTarget( pev->origin );
}
void StartRotSound( void );
void StopRotSound( void );
inline BOOL IsActive( void ) { return (pev->spawnflags & SF_TANK_ACTIVE)?TRUE:FALSE; }
inline void TankActivate( void ) { pev->spawnflags |= SF_TANK_ACTIVE; SetNextThink(0.1); m_fireLast = 0; }
inline void TankDeactivate( void ) { pev->spawnflags &= ~SF_TANK_ACTIVE; m_fireLast = 0; StopRotSound(); }
inline BOOL CanFire( void ) { return (gpGlobals->time - m_lastSightTime) < m_persist; }
BOOL InRange( float range );
void TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, TraceResult &tr );
Vector BarrelPosition( void )
{
Vector forward, right, up;
UTIL_MakeVectorsPrivate( pev->angles, forward, right, up );
return pev->origin + (forward * m_barrelPos.x) + (right * m_barrelPos.y) + (up * m_barrelPos.z);
}
void AdjustAnglesForBarrel( Vector &angles, float distance );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void UpdateSpot( void );
BOOL StartControl( CBasePlayer* pController, CFuncTankControls* pControls );
void StopControl( CFuncTankControls* pControls );
CBaseEntity* BestVisibleEnemy( void );
CFuncTankControls* m_pControls; // tankcontrols is used as a go-between.
CLaserSpot* m_pSpot; // Laser spot entity
virtual BOOL IsRocketTank( void ) { return FALSE; }
virtual BOOL IsLaserTank( void ) { return FALSE; }
protected:
float m_flNextAttack;
float m_yawCenter; // "Center" yaw
float m_yawRate; // Max turn rate to track targets
float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center)
// Zero is full rotation
float m_yawTolerance; // Tolerance angle
float m_pitchCenter; // "Center" pitch
float m_pitchRate; // Max turn rate on pitch
float m_pitchRange; // Range of pitch motion as above
float m_pitchTolerance; // Tolerance angle
float m_lastSightTime;// Last time I saw target
float m_persist; // Persistence of firing (how long do I shoot when I can't see)
RandomRange m_Range;
float m_minRange; // Minimum range to aim/track
float m_maxRange; // Max range to aim/track
float m_fireLast; // Last time I fired
float m_fireRate; // How many rounds/second
Vector m_barrelPos; // Length of the freakin barrel
float m_spriteScale; // Scale of any sprites we shoot
int m_iszSpriteSmoke;
int m_iszSpriteFlash;
TANKBULLET m_bulletType; // Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage
Vector m_sightOrigin; // Last sight of target
int m_spread; // firing spread
int m_iszMaster; // Master entity
int m_iszFireMaster;//LRC - Fire-Master entity (prevents firing when inactive)
int m_iTankClass; // Behave As
};
class CFuncTankControls : public CBaseLogic
{
public:
virtual int ObjectCaps( void ) { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE; }
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
void HandleTank ( CBaseEntity *pActivator, CBaseEntity *m_pTank, BOOL activate );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BOOL OnControls( entvars_t *pevTest );
Vector m_vecControllerUsePos; // where was the player standing when he used me?
CBasePlayer* m_pController;
//max 32 tanks allowed to control
int m_iTankName [ MAX_MULTI_TARGETS ];// list if indexes into global string array
int m_cTanks;// the total number of targets in this manager's fire list.
EHANDLE m_hPlayer;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,938 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "player.h"
#include "baseweapon.h"
//=======================================================================
// func_trigger - volume, that fire target when player in or out
//=======================================================================
#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger
#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger
#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger
class CBaseTrigger;
class CInOutRegister : public CPointEntity
{
public:
BOOL IsRegistered ( CBaseEntity *pValue );
CInOutRegister *Prune( void );
CInOutRegister *Add( CBaseEntity *pValue );
BOOL IsEmpty( void ) { return m_pNext ? FALSE:TRUE; };
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CBaseTrigger *m_pField;
CInOutRegister *m_pNext;
EHANDLE m_hValue;
};
class CBaseTrigger : public CBaseLogic
{
public:
void Spawn( void );
void EXPORT Touch( CBaseEntity *pOther );
void EXPORT Update( void );
void EXPORT Remove( void ); //generic method for right delete trigger class
virtual void FireOnEntry( CBaseEntity *pOther ){}
virtual void FireOnLeave( CBaseEntity *pOther ){}
BOOL CanTouch( CBaseEntity *pOther );
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
STATE GetState() { return m_pRegister->IsEmpty()? STATE_OFF : STATE_ON; }
CInOutRegister *m_pRegister;
};
TYPEDESCRIPTION CBaseTrigger::m_SaveData[] =
{ DEFINE_FIELD( CBaseTrigger, m_pRegister, FIELD_CLASSPTR ), };
IMPLEMENT_SAVERESTORE(CBaseTrigger, CBaseLogic);
TYPEDESCRIPTION CInOutRegister::m_SaveData[] =
{ DEFINE_FIELD( CInOutRegister, m_pField, FIELD_CLASSPTR ),
DEFINE_FIELD( CInOutRegister, m_pNext, FIELD_CLASSPTR ),
DEFINE_FIELD( CInOutRegister, m_hValue, FIELD_EHANDLE ),
}; IMPLEMENT_SAVERESTORE(CInOutRegister,CPointEntity);
LINK_ENTITY_TO_CLASS( zoneent, CInOutRegister );
BOOL CInOutRegister::IsRegistered ( CBaseEntity *pValue )
{
if (m_hValue == pValue) return TRUE;
else if (m_pNext) return m_pNext->IsRegistered( pValue );
else return FALSE;
}
CInOutRegister *CInOutRegister::Add( CBaseEntity *pValue )
{
if (m_hValue == pValue)
{
// it's already in the list, don't need to do anything
return this;
}
else if (m_pNext)
{
// keep looking
m_pNext = m_pNext->Add( pValue );
return this;
}
else
{
// reached the end of the list; add the new entry, and trigger
CInOutRegister *pResult = GetClassPtr( (CInOutRegister*)NULL );
pResult->m_hValue = pValue;
pResult->m_pNext = this;
pResult->m_pField = m_pField;
pResult->pev->classname = MAKE_STRING("zoneent");
m_pField->FireOnEntry( pValue );
return pResult;
}
}
CInOutRegister *CInOutRegister::Prune( void )
{
if ( m_hValue )
{
ASSERTSZ(m_pNext != NULL, "invalid InOut registry terminator\n");
if ( m_pField->Intersects(m_hValue) )
{
// this entity is still inside the field, do nothing
m_pNext = m_pNext->Prune();
return this;
}
else
{
// this entity has just left the field, trigger
m_pField->FireOnLeave( m_hValue );
SetThink( Remove );
SetNextThink( 0.1 );
return m_pNext->Prune();
}
}
else
{ // this register has a missing or null value
if (m_pNext)
{
// this is an invalid list entry, remove it
SetThink( Remove );
SetNextThink( 0.1 );
return m_pNext->Prune();
}
else
{
// this is the list terminator, leave it.
return this;
}
}
}
void CBaseTrigger::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "offtarget"))
{
pev->netname = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
if (FStrEq(pkvd->szKeyName, "modifier"))
{
pev->armorvalue = atof(pkvd->szValue) / 100.0;
pkvd->fHandled = TRUE;
}
else if (FStrEq( pkvd->szKeyName, "roomtype" )) //for soundfx
{
pev->button = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq( pkvd->szKeyName, "wait" )) // for trigger_push
{
m_flDelay = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else CBaseLogic::KeyValue( pkvd );
}
void CBaseTrigger :: Spawn( void )
{
pev->solid = SOLID_TRIGGER;
pev->movetype = MOVETYPE_NONE;
pev->takedamage = DAMAGE_NO;
UTIL_SetModel( ENT( pev ), pev->model ); // set size and link into world
SetObjectClass( ED_TRIGGER );
// create a null-terminator for the registry
m_pRegister = GetClassPtr(( CInOutRegister *)NULL );
m_pRegister->m_hValue = NULL;
m_pRegister->m_pNext = NULL;
m_pRegister->m_pField = this;
m_pRegister->pev->classname = MAKE_STRING("zoneent");
m_pRegister->SetObjectClass( ED_STATIC );
SetThink( Update );
}
BOOL CBaseTrigger :: CanTouch( CBaseEntity *pOther )
{
if ( gpGlobals->time < pev->dmgtime) return FALSE;
pev->dmgtime = gpGlobals->time + m_flWait;
// Only touch clients, monsters, or pushables (depending on flags)
if (pOther->pev->flags & FL_CLIENT) return !(pev->spawnflags & SF_TRIGGER_NOCLIENTS);
else if (pOther->pev->flags & FL_MONSTER) return pev->spawnflags & SF_TRIGGER_ALLOWMONSTERS;
else if (pOther->IsPushable()) return pev->spawnflags & SF_TRIGGER_PUSHABLES;
return FALSE;
}
void CBaseTrigger :: Touch( CBaseEntity *pOther )
{
if (!CanTouch(pOther)) return;
m_hActivator = pOther; //save activator;
m_pRegister = m_pRegister->Add(pOther);
if (m_fNextThink <= 0 && !m_pRegister->IsEmpty())SetNextThink( 0.1 );
}
void CBaseTrigger :: Update( void )
{
// Prune handles all Intersects tests and fires targets as appropriate
m_pRegister = m_pRegister->Prune();
if (m_pRegister->IsEmpty()) DontThink();
else SetNextThink( 0.1 );
}
void CBaseTrigger :: Remove( void )
{
UTIL_Remove( m_pRegister );
UTIL_Remove( this );
}
//=======================================================================
// trigger_mutiple - classic QUAKE trigger
//=======================================================================
class CTriggerMulti : public CBaseTrigger
{
void FireOnEntry( CBaseEntity *pOther )
{
if(!IsLockedByMaster(pOther))
UTIL_FireTargets(pev->target, pOther, this, USE_TOGGLE );
}
void FireOnLeave( CBaseEntity *pOther )
{
if (!IsLockedByMaster(pOther))
UTIL_FireTargets(pev->netname, pOther, this, USE_TOGGLE );
}
};
LINK_ENTITY_TO_CLASS( trigger_multiple, CTriggerMulti );
//=======================================================================
// trigger_once - classic QUAKE trigger
//=======================================================================
class CTriggerOnce : public CBaseTrigger
{
void FireOnEntry( CBaseEntity *pOther )
{
if ( !IsLockedByMaster(pOther))
{
UTIL_FireTargets( pev->target, pOther, this, USE_TOGGLE );
SetThink( Remove );
SetNextThink( 0 );
}
}
};
LINK_ENTITY_TO_CLASS( trigger_once, CTriggerOnce );
//=======================================================================
// trigger_autosave - game autosave
//=======================================================================
class CTriggerSave : public CBaseTrigger
{
void FireOnEntry( CBaseEntity *pOther ) { SERVER_COMMAND( "autosave\n" ); }
void FireOnLeave( CBaseEntity *pOther )
{
SetThink( Remove );
SetNextThink( 0 );
}
};
LINK_ENTITY_TO_CLASS( trigger_autosave, CTriggerSave );
//=======================================================================
// func_friction - game autosave
//=======================================================================
class CChangeFriction : public CBaseTrigger
{
void Spawn( void )
{
pev->solid = SOLID_TRIGGER;
pev->movetype = MOVETYPE_NONE;
UTIL_SetModel(ENT(pev), pev->model );
}
void Touch( CBaseEntity *pOther )
{
if ( pOther->pev->movetype != 11 && pOther->pev->movetype != 10 )
pOther->pev->friction = pev->armorvalue;
}
};
LINK_ENTITY_TO_CLASS( func_friction, CChangeFriction );
#define SF_PUSH_ONCE 1
//=======================================================================
// trigger_push - triger that pushes player
//=======================================================================
class CTriggerPush : public CBaseTrigger
{
void Spawn( void )
{
if ( pev->angles == g_vecZero ) pev->angles.y = 360;
if (pev->speed == 0) pev->speed = 100;
UTIL_LinearVector( this );
if ( FBitSet (pev->spawnflags, 2) ) pev->solid = SOLID_NOT;
else pev->solid = SOLID_TRIGGER;
pev->movetype = MOVETYPE_NONE;
UTIL_SetModel(ENT(pev), pev->model );
SetBits( pev->effects, EF_NODRAW );
UTIL_SetOrigin( this, pev->origin );
}
void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (pev->solid == SOLID_NOT)
{
pev->solid = SOLID_TRIGGER;
gpGlobals->force_retouch++;
}
else pev->solid = SOLID_NOT;
UTIL_SetOrigin( this, pev->origin );
}
void Touch( CBaseEntity *pOther )
{
switch( pOther->pev->movetype )
{
case MOVETYPE_NONE:
case MOVETYPE_PUSH:
case MOVETYPE_NOCLIP:
case MOVETYPE_FOLLOW:
return;
}
if ( pOther->pev->solid != SOLID_NOT && pOther->pev->solid != SOLID_BSP )
{
// Instant trigger, just transfer velocity and remove
if (FBitSet(pev->spawnflags, 1))
{
pOther->pev->velocity = pOther->pev->velocity + (pev->speed * pev->movedir);
if ( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND;
UTIL_Remove( this );
}
else
{
Vector vecPush = (pev->speed * pev->movedir);
if ( pOther->pev->flags & FL_BASEVELOCITY )
vecPush = vecPush + pOther->pev->basevelocity;
pOther->pev->basevelocity = vecPush;
pOther->pev->flags |= FL_BASEVELOCITY;
}
}
}
};
LINK_ENTITY_TO_CLASS( trigger_push, CTriggerPush );
//=======================================================================
// trigger_gravity - classic HALF_LIFE gravity modifier
//=======================================================================
class CTriggerGravity : public CBaseTrigger
{
void FireOnEntry( CBaseEntity *pOther ) { pOther->pev->gravity = pev->gravity; }
//void FireOnLeave( CBaseEntity *pOther ) { pOther->pev->gravity = EARTH_GRAVITY;}
};
LINK_ENTITY_TO_CLASS( trigger_gravity, CTriggerGravity);
//=======================================================================
// trigger_sound - a DSP zone, brush prototype of env_sound
//=======================================================================
class CTriggerSound : public CBaseTrigger
{
void FireOnEntry( CBaseEntity *pOther )
{
if (!pOther->IsPlayer()) return;
pev->impulse = ((CBasePlayer *)pOther)->m_iSndRoomtype; //save old dsp sound
((CBasePlayer *)pOther)->m_iSndRoomtype = pev->button; //set new dsp
((CBasePlayer *)pOther)->hearNeedsUpdate = 1;
}
void FireOnLeave( CBaseEntity *pOther )
{
if (!pOther->IsPlayer()) return;
((CBasePlayer *)pOther)->m_iSndRoomtype = pev->impulse; //restore old dsp
((CBasePlayer *)pOther)->hearNeedsUpdate = 1;
}
};
LINK_ENTITY_TO_CLASS( trigger_sound, CTriggerSound );
LINK_ENTITY_TO_CLASS( func_soundfx, CTriggerSound ); // Xash 0.4 compatibility
//=======================================================================
// trigger_changelevel - classic HALF_LIFE changelevel
//=======================================================================
class CChangeLevel : public CBaseLogic
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
virtual int ObjectCaps( void ) { return CBaseLogic :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void ChangeLevelNow( CBaseEntity *pActivator );
void Touch( CBaseEntity *pOther ){ if (pOther->IsPlayer())Think(); }
void Think( void )
{
FireAfter();
//SERVER_COMMAND( "intermission\n" );
UTIL_ChangeLevel( pev->netname, pev->message );
}
void FireAfter( void );
};
LINK_ENTITY_TO_CLASS( trigger_changelevel, CChangeLevel );
void CChangeLevel :: KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "map"))
{
char m_szMapName[MAP_MAX_NAME];
if (strlen(pkvd->szValue) >= MAP_MAX_NAME)
Msg("ERROR: Map name '%s' too long (%d chars)\n", pkvd->szValue, MAP_MAX_NAME );
strcpy(m_szMapName, pkvd->szValue);
for (int i = 0; m_szMapName[i]; i++) { m_szMapName[i] = tolower(m_szMapName[i]); }
pev->netname = ALLOC_STRING( m_szMapName );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "landmark"))
{
if (strlen(pkvd->szValue) >= MAP_MAX_NAME)
Msg("ERROR: Landmark name '%s' too long (%d chars)\n", pkvd->szValue, MAP_MAX_NAME );
pev->message = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "changetarget"))
{
pev->target = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else CBaseEntity::KeyValue( pkvd );
}
void CChangeLevel :: Spawn( void )
{
if( FStringNull( pev->netname ))
ALERT( at_error, "a % doesn't have a map\n", STRING( pev->classname ));
if( FStringNull( pev->message ))
ALERT( at_error, "trigger_changelevel to %s doesn't have a landmark\n", STRING( pev->netname ));
// determine work style
if( FStringNull( pev->targetname )) SetUse( NULL );
else SetTouch( NULL );
pev->solid = SOLID_TRIGGER;
pev->movetype = MOVETYPE_NONE;
UTIL_SetModel(ENT(pev), pev->model);
SetBits( pev->effects, EF_NODRAW );//make invisible
}
void CChangeLevel :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (useType == USE_SHOWINFO)
{
DEBUGHEAD;
Msg( "Mapname: %s, Landmark name %f\n", STRING(pev->netname), STRING(pev->message));
SHIFT;
}
else SetNextThink( 0 );
}
void CChangeLevel :: FireAfter( void )
{
// Create an entity to fire the changetarget
if (!FStringNull( pev->target ))
{
CBaseEntity *pPlayer = UTIL_PlayerByIndex( 1 );
CBaseEntity *pChlFire = CBaseEntity::Create( "fireent", pPlayer->pev->origin, g_vecZero, NULL );
if ( pChlFire ) pChlFire->pev->target = pev->target;
}
}
//=========================================================
// trigger_playerfreeze
//=========================================================
class CTriggerFreeze : public CBaseLogic
{
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
m_hActivator = pActivator;
if (pActivator && pActivator->pev->flags & FL_CLIENT);
else pActivator = UTIL_PlayerByIndex( 1 );
if (useType == USE_TOGGLE)
{
if(m_iState == STATE_ON) useType = USE_OFF;
else useType = USE_ON;
}
if (useType == USE_ON)
{
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(FALSE);
m_iState = STATE_ON;
if(m_flDelay) SetNextThink( m_flDelay );
}
else if(useType == USE_OFF)
{
((CBasePlayer *)((CBaseEntity *)pActivator))->EnableControl(TRUE);
m_iState = STATE_OFF;
DontThink();
}
else if(useType == USE_SHOWINFO) { DEBUGHEAD; }
}
void Think( void )
{
((CBasePlayer *)((CBaseEntity *)m_hActivator))->EnableControl(TRUE);
m_iState = STATE_OFF;
}
};
LINK_ENTITY_TO_CLASS( trigger_playerfreeze, CTriggerFreeze );
//=======================================================================
// trigger_hurt - classic QUAKE damage inflictor
//=======================================================================
class CTriggerHurt : public CBaseLogic
{
public:
void Spawn( void );
void Think( void );
void Touch ( CBaseEntity *pOther );
void KeyValue( KeyValueData *pkvd );
void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
};
LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt );
void CTriggerHurt :: KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "damage"))
{
pev->dmg = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "damagetype"))
{
pev->button |= atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else CBaseEntity::KeyValue( pkvd );
}
void CTriggerHurt :: Spawn( void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
UTIL_SetModel(ENT(pev), pev->model);
UTIL_SetOrigin( this, pev->origin );
SetBits( pev->effects, EF_NODRAW );
m_iState = STATE_OFF;
if (!FBitSet(pev->spawnflags, 2 )) Use( this, this, USE_ON, 0 );
}
void CTriggerHurt :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (useType == USE_TOGGLE)
{
if(m_iState) useType = USE_OFF;
else useType = USE_ON;
}
if (useType == USE_ON)
{
pev->solid = SOLID_TRIGGER;
gpGlobals->force_retouch++;
UTIL_SetOrigin( this, pev->origin );
if (pev->button & DMG_RADIATION) SetNextThink( RANDOM_FLOAT(0.0, 0.5) );
m_iState = STATE_ON;
}
else if (useType == USE_OFF)
{
pev->solid = SOLID_NOT;
UTIL_SetOrigin( this, pev->origin );
if (pev->button & DMG_RADIATION) DontThink();
m_iState = STATE_OFF;
}
else if (useType == USE_SET)
{
pev->dmg = value;//set dmg level
}
else if (useType == USE_RESET)
{
pev->dmg = 0;//reset dmg level
}
else if (useType == USE_SHOWINFO)
{
DEBUGHEAD;
ALERT( at_console, "State: %s, Dmg value %g\n", GetStringForState( GetState()), pev->dmg );
PrintStringForDamage( pev->button );
}
}
void CTriggerHurt :: Touch ( CBaseEntity *pOther )
{
float fldmg;
if ( !pOther->pev->takedamage ) return;
if ( !FBitSet( pOther->pev->flags, FL_CLIENT|FL_MONSTER ) && !pOther->IsPushable() ) return;
if ( IsMultiplayer() )
{
if ( pev->dmgtime > gpGlobals->time )
{
if ( gpGlobals->time != pev->pain_finished )
{
// too early to hurt again, and not same frame with a different entity
if ( pOther->IsPlayer() )
{
int playerMask = 1 << (pOther->entindex() - 1);
if ( pev->impulse & playerMask ) return;
pev->impulse |= playerMask;
}
else return;
}
}
else
{
pev->impulse = 0;
if ( pOther->IsPlayer() )
{
int playerMask = 1 << (pOther->entindex() - 1);
pev->impulse |= playerMask;
}
}
}
else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) 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->dmgtime = gpGlobals->time + 0.5;
}
void CTriggerHurt :: Think( void )
{
edict_t *pentPlayer;
CBasePlayer *pPlayer = NULL;
float flRange;
entvars_t *pevTarget;
Vector vecSpot1;
Vector vecSpot2;
Vector vecRange;
Vector origin;
Vector view_ofs;
origin = pev->origin;
view_ofs = pev->view_ofs;
pev->origin = (pev->absmin + pev->absmax) * 0.5;
pev->view_ofs = pev->view_ofs * 0.0;
pentPlayer = FIND_CLIENT_IN_PVS(edict());
pev->origin = origin;
pev->view_ofs = view_ofs;
if (!FNullEnt(pentPlayer))
{
pPlayer = GetClassPtr( (CBasePlayer *)VARS(pentPlayer));
pevTarget = VARS(pentPlayer);
vecSpot1 = (pev->absmin + pev->absmax) * 0.5;
vecSpot2 = (pevTarget->absmin + pevTarget->absmax) * 0.5;
vecRange = vecSpot1 - vecSpot2;
flRange = vecRange.Length();
if (pPlayer->m_flgeigerRange >= flRange) pPlayer->m_flgeigerRange = flRange;
}
SetNextThink( 0.25 );
}
//=======================================================================
// trigger_transition - area that moving all entities inside across level
//=======================================================================
class CTriggerTransition : public CPointEntity // Don't change this!
{
public:
void Spawn( void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
UTIL_SetModel( ENT( pev ), pev->model );
pev->model = pev->modelindex = 0;
}
};
LINK_ENTITY_TO_CLASS( trigger_transition, CTriggerTransition );
//=======================================================================
// trigger_camera - generic camera
//=======================================================================
class CTriggerCamera : public CBaseLogic
{
void Spawn (void );
void PostSpawn( void );
void UpdatePlayerView( void );
void Think( void );
void PostActivate( void );
void OverrideReset( void );
void Move( void );
void TurnOn( void );
void TurnOff(void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData* );
int ObjectCaps( void ) { return CBaseLogic::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
CBaseEntity* pTarget;
};
LINK_ENTITY_TO_CLASS( trigger_camera, CTriggerCamera );
#define SF_CAMERA_PLAYER_POSITION 1 // start from player eyes
#define SF_CAMERA_PLAYER_TARGET 2 // player it's camera target
#define SF_CAMERA_PLAYER_TAKECONTROL 4 // freeze player
void CTriggerCamera :: KeyValue( KeyValueData* pkvd )
{
if (FStrEq( pkvd->szKeyName, "viewentity" ))
{
pev->netname = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq( pkvd->szKeyName, "moveto" ))
{
pev->message = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else CBaseLogic::KeyValue( pkvd );
}
void CTriggerCamera :: Spawn (void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
m_iState = STATE_OFF;
UTIL_SetModel( ENT( pev ), "models/common/null.mdl" );
UTIL_SetSize( pev, g_vecZero, g_vecZero );
SetBits( pFlags, PF_POINTENTITY );
}
void CTriggerCamera::PostSpawn( void )
{
m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( pev->message ));
if ( m_pGoalEnt ) UTIL_SetOrigin( this, m_pGoalEnt->pev->origin );
}
void CTriggerCamera::OverrideReset( void )
{
// find path_corner on a next level
m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( pev->message ));
if( m_pGoalEnt ) UTIL_SetOrigin( this, m_pGoalEnt->pev->origin );
}
void CTriggerCamera::PostActivate( void )
{
if (FStrEq( STRING( pev->target ), "player" ) || ( pev->spawnflags & SF_CAMERA_PLAYER_TARGET ))
pTarget = UTIL_PlayerByIndex( 1 );
else pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
}
void CTriggerCamera::Think( void )
{
SetNextThink( gpGlobals->frametime );
Move();
pev->dmgtime = gpGlobals->time;
if ( pTarget ) UTIL_WatchTarget( this, pTarget );
if( m_flWait && pev->teleport_time < gpGlobals->time )
{
TurnOff();
}
}
void CTriggerCamera :: UpdatePlayerView( void )
{
int flags = 0;
if( m_hActivator == NULL || !m_hActivator->edict() || !( m_hActivator->pev->flags & FL_CLIENT ))
{
ALERT( at_error, "Camera: No Client!\n" );
return;
}
if( pev->spawnflags & SF_CAMERA_PLAYER_TAKECONTROL )
{
int state;
if( GetState() == STATE_ON )
state = TRUE;
else state = FALSE;
// freeze player
((CBasePlayer *)((CBaseEntity *)m_hActivator))->EnableControl( state );
}
#if 1
if( GetState() == STATE_OFF )
flags |= CAMERA_ON;
else flags = 0;
CBaseEntity *pCamera = UTIL_FindEntityByTargetname( NULL, STRING( pev->netname ));
if( pCamera && !pCamera->IsBSPModel( ))
UTIL_SetView( m_hActivator, pCamera, flags );
else UTIL_SetView( m_hActivator, this, flags );
#else
// enchanced engine SET_VIEW (see code in client\global\view.cpp)
if( GetState() == STATE_OFF )
SET_VIEW( m_hActivator->edict(), edict() );
else SET_VIEW( m_hActivator->edict(), m_hActivator->edict() );
#endif
}
void CTriggerCamera :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if( pActivator && pActivator->IsPlayer( ))
{
// only at player
m_hActivator = pActivator;
}
else if( !IsMultiplayer( ))
{
m_hActivator = UTIL_PlayerByIndex( 1 );
}
else
{
ALERT( at_warning, "%s: %s activator not player. Ignored.\n", STRING( pev->classname ), STRING( pev->targetname ));
return;
}
if ( useType == USE_TOGGLE )
{
if ( m_iState == STATE_OFF )
useType = USE_ON;
else useType = USE_OFF;
}
if ( useType == USE_ON )
{
TurnOn();
}
else if ( useType == USE_OFF )
{
TurnOff();
}
else if ( useType == USE_SHOWINFO )
{
ALERT( at_console, "======/Xash Debug System/======\n");
ALERT( at_console, "classname: %s\n", STRING( pev->classname ));
ALERT( at_console, "State: %s, Look at %s\n", GetStringForState( GetState()), pev->netname ? STRING( pev->netname ) : STRING( pev->targetname ));
ALERT( at_console, "Speed: %g Camera target: %s\n", pev->speed, pTarget ? STRING(pTarget->pev->targetname) : "None" );
}
}
void CTriggerCamera::Move( void )
{
// Not moving on a path, return
if (!m_pGoalEnt) return;
// Subtract movement from the previous frame
pev->frags -= pev->speed * gpGlobals->frametime;
// Have we moved enough to reach the target?
if ( pev->frags <= 0 )
{
// Fire the passtarget if there is one
if ( m_pGoalEnt->pev->message )
{
UTIL_FireTargets( m_pGoalEnt->pev->message, this, this, USE_TOGGLE, 0 );
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_FIREONCE ) )
m_pGoalEnt->pev->message = 0;
}
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_TELEPORT ) )
{
m_pGoalEnt = m_pGoalEnt->GetNext();
if ( m_pGoalEnt ) UTIL_AssignOrigin( this, m_pGoalEnt->pev->origin );
}
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_WAITFORTRIG ) )
{
//strange feature...
}
// Time to go to the next target
m_pGoalEnt = m_pGoalEnt->GetNext();
// Set up next corner
if ( !m_pGoalEnt ) UTIL_SetVelocity( this, g_vecZero );
else
{
pev->message = m_pGoalEnt->pev->targetname; //save last corner
pev->armorvalue = m_pGoalEnt->pev->speed;
Vector delta = m_pGoalEnt->pev->origin - pev->origin;
pev->frags = delta.Length();
pev->movedir = delta.Normalize();
m_flDelay = gpGlobals->time + m_pGoalEnt->GetDelay();
}
}
if ( m_flDelay > gpGlobals->time )
pev->speed = UTIL_Approach( 0, pev->speed, 500 * gpGlobals->frametime );
else pev->speed = UTIL_Approach( pev->armorvalue, pev->speed, 500 * gpGlobals->frametime );
if( !pTarget ) UTIL_WatchTarget( this, m_pGoalEnt ); // watch for track
float fraction = 2 * gpGlobals->frametime;
UTIL_SetVelocity( this, ((pev->movedir * pev->speed) * fraction) + (pev->velocity * ( 1 - fraction )));
}
void CTriggerCamera::TurnOff( void )
{
if( m_pGoalEnt ) m_pGoalEnt = m_pGoalEnt->GetPrev();
UTIL_SetVelocity( this, g_vecZero );
UTIL_SetAvelocity( this, g_vecZero );
UpdatePlayerView();
m_iState = STATE_OFF;
DontThink();
}
void CTriggerCamera::TurnOn( void )
{
pev->dmgtime = gpGlobals->time;
pev->armorvalue = pev->speed;
pev->frags = 0;
// copy over player information
if ( pev->spawnflags & SF_CAMERA_PLAYER_POSITION )
{
UTIL_SetOrigin( this, m_hActivator->pev->origin + m_hActivator->pev->view_ofs );
pev->angles.x = -m_hActivator->pev->angles.x;
pev->angles.y = m_hActivator->pev->angles.y;
pev->angles.z = 0;
pev->velocity = m_hActivator->pev->velocity;
ClearBits( pev->spawnflags, SF_CAMERA_PLAYER_POSITION );
}
// time-based camera
if( m_flWait ) pev->teleport_time = gpGlobals->time + m_flWait;
Move();
UpdatePlayerView();
m_iState = STATE_ON;
SetNextThink( gpGlobals->frametime );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,371 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef WEAPONS_H
#define WEAPONS_H
#include "basebeams.h"
#include "player.h"
#include "bullets.h"
#include "sfx.h"
#include "baserockets.h"
#include "damage.h"
#include "defaults.h"
class CLaserSpot;
// weapon flags
#define ITEM_FLAG_SELECTONEMPTY 1 // this weapon can choose without ammo
#define ITEM_FLAG_NOAUTORELOAD 2 // only manual reload
#define ITEM_FLAG_NOAUTOSWITCHEMPTY 4 // don't switch from this weapon
#define ITEM_FLAG_LIMITINWORLD 8 // limit in world
#define ITEM_FLAG_EXHAUSTIBLE 16 // A player can totally exhaust their ammo supply and lose this weapon
#define ITEM_FLAG_NODUPLICATE 32 // player can't give this weapon again
#define ITEM_FLAG_USEAUTOAIM 64 // weapon uses autoaim
#define ITEM_FLAG_HIDEAMMO 128 // hide ammo in round
// suit definitions
#define BARNEY_SUIT 0 // just in case
#define GORDON_SUIT 1 // gordon suit
#define NUM_HANDS 2 // number of hands: barney and gordon
#define PLAYER_HAS_SUIT (m_pPlayer->pev->weapons & ITEM_SUIT)
#define PLAYER_DRAW_SUIT (pev->body & GORDON_SUIT)
#define MAX_SHOOTSOUNDS 3 // max of random shoot sounds
enum {
NONE = 0,
AMMO1, // fire primary ammo
AMMO2, // fire seondary ammo
LASER_DOT, // enable laser dot
ZOOM, // enable zoom
FLASHLIGHT, // enable flashlight
SWITCHMODE, // play two beetwen anims and change body
SWING, // crowbar swing
};
#define BATTACK_FIREMODE0 0 //both attack firemode 0
#define PATTACK_FIREMODE1 1 //primary attack firemode 1
#define SATTACK_FIREMODE1 2 //secondary attack firemode 2
#define EMPTY_RELOAD 3
#define NORMAL_RELOAD 4
typedef struct
{
int iSlot; // hud slot
int iPosition; // hud position
int iViewModel; // path to viewmodel
int iWorldModel; // path to worldmodel
char szAnimExt[16]; // player anim postfix
string_t iszAmmo1; // ammo 1 type
int iMaxAmmo1; // max ammo 1
string_t iszAmmo2; // ammo 2 type
int iMaxAmmo2; // max ammo 2
string_t iszName; // weapon name
int iMaxClip; // clip size
int iId; // unique weapon Id number
int iFlags; // weapon flags
int iWeight; // for autoselect weapon
int attack1; // attack1 type
int attack2; // attack2 type
float fNextAttack; // nextattack
float fNextAttack2; // next secondary attack
string_t firesound[MAX_SHOOTSOUNDS]; // firesounds
string_t sfxsound[MAX_SHOOTSOUNDS]; // sfxsound
int sndcount; // fire sound count
int sfxcount; // sfx sound count
int emptysnd; // empty sound
RandomRange punchangle1; // punchangle 1 attack
RandomRange punchangle2; // punchangle 2 attack
RandomRange recoil1; // recoil 1 attack
RandomRange recoil2; // recoil 2 attack
} ItemInfo;
typedef struct
{
string_t iszName;
int iMaxCarry;
int iId;
} AmmoInfo;
class CBasePlayerWeapon : public CBaseAnimating
{
DECLARE_CLASS( CBasePlayerWeapon, CBaseAnimating );
public:
virtual void SetObjectCollisionBox( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() | FCAP_ACROSS_TRANSITION; }
virtual int AddToPlayer( CBasePlayer *pPlayer ); // return TRUE if the item you want the item added to the player inventory
virtual int AddDuplicate( CBasePlayerWeapon *pItem ); // return TRUE if you want your duplicate removed from world
void EXPORT DestroyItem( void );
void EXPORT DefaultTouch( CBaseEntity *pOther ); // default weapon touch
void EXPORT FallThink ( void ); // when an item is first spawned, this think is run to determine when the object has hit the ground.
void EXPORT Materialize( void ); // make a weapon visible and tangible
void EXPORT AttemptToMaterialize( void ); // the weapon desires to become visible and tangible, if the game rules allow for it
BOOL IsWeapon( void ) { return !strncmp( STRING(pev->classname), "weapon_", 5 ); }
CBaseEntity* Respawn ( void );// copy a weapon
void CheckRespawn( void );
virtual int GetItemInfo(ItemInfo *p); // get weapon default info
virtual BOOL CanDeploy( void );
virtual BOOL CanHolster( void ) { return ( m_iOnControl == 0 ); }; // can this weapon be put away right now?
virtual void SetNextThink( float delay );
virtual void Precache( void );
void EXPORT ItemTouch( CBaseEntity *pOther );
virtual void Drop( void );
virtual void AttachToPlayer ( CBasePlayer *pPlayer );
virtual void Spawn(void);
virtual int UpdateClientData( CBasePlayer *pPlayer ); // sends hud info to client dll, if things have changed
virtual CBasePlayerWeapon *GetWeaponPtr( void ) { return (CBasePlayerWeapon *)this; };
int FoundAlly( void );
inline BOOL CanAttack( float attack_time ) { return ( attack_time <= gpGlobals->time ) ? TRUE : FALSE; }
//ammo operations
virtual int ExtractAmmo( CBasePlayerWeapon *pWeapon ); // Return TRUE if you can add ammo to yourself when picked up
virtual int ExtractClipAmmo( CBasePlayerWeapon *pWeapon ); // Return TRUE if you can add ammo to yourself when picked up
virtual int AddWeapon( void ) { ExtractAmmo( this ); return TRUE; }; // Return TRUE if you want to add yourself to the player
BOOL AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry );
BOOL AddSecondaryAmmo( int iCount, char *szName, int iMaxCarry );
int GetAmmoType( const char *ammo );//determine ammo type primary or secondary
int ReturnAmmoIndex( const char *ammo );//return primary or secondary ammo index
int UseAmmo( const char *ammo, int count = 1 ); //Determine and use ammo type
// parse weapon script files
int ParseWeaponFile( ItemInfo *II, const char *pfile ); // parse weapon_*.txt
int ParseWeaponData( ItemInfo *II, const char *file ); // parse WeaponData {}
int ParsePrimaryAttack( ItemInfo *II, const char *pfile ); // parse PrimaryAttack {}
int ParseSecondaryAttack( ItemInfo *II, const char *pfile ); // parse SeconadryAttack {}
int ParseSoundData( ItemInfo *II, const char *pfile ); // parse SoundData {}
// HudData parses on client side
void ResetParse( ItemInfo *II ); //reset ItemInfo
void GenerateID( void );//generate unicum ID number for each weapon
//Play Animation methods
int SetAnimation( Activity activity, float fps = 0 );
int SetAnimation( char *name, float fps = 0 );
int PlaySequence( Activity activity, float fps = 0 );
void SetPlayerEffects( const char *ammo, int firemode );
void PlayAttackSound( int firemode );
void SendWeaponAnim( int sequence, float fps = 0 );
float SetNextAttack( float delay ) { return m_pPlayer->m_flNextAttack = gpGlobals->time + delay; }
float SetNextIdle( float delay ) { return m_flTimeWeaponIdle = gpGlobals->time + delay; }
float SequenceDuration( int sequence = -1, float fps = 0 );
float SequenceFPS( int sequence = -1 );
int GetNumBodies( void )
{
dstudiohdr_t *pstudiohdr = (dstudiohdr_t *)(GET_MODEL_PTR( ENT( pev )));
if( pstudiohdr )
{
dstudiobodyparts_t *pbodypart = (dstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + NUM_HANDS;
return pbodypart->nummodels;
}
return 0;
}
//main frame
virtual void ItemPreFrame( void ); // called each frame by the player PreThink
virtual void ItemPostFrame( void ); // called each frame by the player PostThink
//global weapon info struct (refresh on save\load)
static ItemInfo ItemInfoArray[ MAX_WEAPONS ];
static AmmoInfo AmmoInfoArray[ MAX_AMMO_SLOTS ];
CBasePlayer *m_pPlayer;
CBasePlayerWeapon *m_pNext;
int m_iId; // Weapon unique Id (0 - MAX_WEAPONS)
//don't save this
CLaserSpot *m_pSpot; // LTD spot
//virtual methods for ItemInfo acess
int iItemPosition(void) { return ItemInfoArray[ m_iId ].iPosition; }
int iItemSlot( void ) { return ItemInfoArray[ m_iId ].iSlot + 1; }
int iViewModel( void ) { return ItemInfoArray[ m_iId ].iViewModel; }
int iWorldModel( void ) { return ItemInfoArray[ m_iId ].iWorldModel; }
int iMaxAmmo1( void ) { return ItemInfoArray[ m_iId ].iMaxAmmo1; }
int iMaxAmmo2( void ) { return ItemInfoArray[ m_iId ].iMaxAmmo2; }
int iMaxClip( void ) { return ItemInfoArray[ m_iId ].iMaxClip; }
int iWeight( void ) { return ItemInfoArray[ m_iId ].iWeight; }
int iFlags( void ) { return ItemInfoArray[ m_iId ].iFlags; }
int iAttack1( void ) { return ItemInfoArray[ m_iId ].attack1; }
int FireSound( int i ) { return ItemInfoArray[ m_iId ].firesound[i]; }
int SfxSound( int i ) { return ItemInfoArray[ m_iId ].sfxsound[i]; }
int EmptySnd( void ) { return ItemInfoArray[ m_iId ].emptysnd; }
int sndcnt( void ) { return ItemInfoArray[ m_iId ].sndcount; }
int sfxcnt( void ) { return ItemInfoArray[ m_iId ].sfxcount; }
int iAttack2( void ) { return ItemInfoArray[ m_iId ].attack2; }
char *szAnimExt( void ) { return ItemInfoArray[ m_iId ].szAnimExt; }
float fNextAttack1( void ){ return ItemInfoArray[ m_iId ].fNextAttack; }
float fNextAttack2( void ){ return ItemInfoArray[ m_iId ].fNextAttack2; }
float fPunchAngle1( void ){ return ItemInfoArray[ m_iId ].punchangle1.Random(); }
float fPunchAngle2( void ){ return ItemInfoArray[ m_iId ].punchangle2.Random(); }
float fRecoil1( void ) { return ItemInfoArray[ m_iId ].recoil1.Random(); }
float fRecoil2( void ) { return ItemInfoArray[ m_iId ].recoil2.Random(); }
const char *pszAmmo1( void ) { return STRING( ItemInfoArray[ m_iId ].iszAmmo1 ); }
const char *pszAmmo2( void ) { return STRING( ItemInfoArray[ m_iId ].iszAmmo2 ); }
const char *pszName( void ) { return STRING( ItemInfoArray[ m_iId ].iszName ); }
BOOL PlayEmptySound( void );//universal empty sound
// default functions
BOOL DefaultDeploy( Activity sequence );
BOOL DefaultHolster( Activity sequence );
BOOL DefaultReload( Activity sequence );
void DefaultIdle( void );
int Shoot ( const char *ammo, Vector vecSpread, int firemode = 0, int cShots = 1 ); //bullet shoot
int Launch ( const char *ammo, int type = 0 ); //rocket launch
int Swing( int fFirst ); //crowbar swing
void ZoomUpdate( void );
void ZoomReset( void );
// virtaul weapon functions
int PlayCurrentAttack( int action, int firemode );
int GetCurrentAttack( const char *ammo, int firemode );
Vector GetCurrentSpread( const char *ammo );
int GetBulletType( const char *ammo );
inline int PlayRangeAttack( float fps = 0 )
{
//play random "range" animation
float flRand = RANDOM_FLOAT(0.0, 1.0);
if( flRand < 0.5 && SetAnimation( ACT_VM_RANGE_ATTACK1, fps ) == -1) return 0;
if( flRand > 0.8 && SetAnimation( ACT_VM_RANGE_ATTACK2, fps ) == -1)
{
if(SetAnimation( ACT_VM_RANGE_ATTACK1, fps ) == -1) return 0;
}
if( flRand < 0.8 && flRand > 0.5 && SetAnimation( ACT_VM_RANGE_ATTACK3, fps ) == -1)
{
if(SetAnimation( ACT_VM_RANGE_ATTACK1, fps ) == -1) return 0;
}
return 1;
}
inline int PlayMeleeAttack( float fps = 0 )
{
//play random "range" animation
float flRand = RANDOM_FLOAT(0.0, 1.0);
if( flRand < 0.5 && SetAnimation( ACT_VM_MELEE_ATTACK1, fps ) == -1) return 0;
if( flRand > 0.8 && SetAnimation( ACT_VM_MELEE_ATTACK2, fps ) == -1)
{
if(SetAnimation( ACT_VM_MELEE_ATTACK1, fps ) == -1) return 0;
}
if( flRand < 0.8 && flRand > 0.5 && SetAnimation( ACT_VM_MELEE_ATTACK3, fps ) == -1)
{
if(SetAnimation( ACT_VM_MELEE_ATTACK1, fps ) == -1) return 0;
}
return 1;
}
inline int PlayEmptyFire( float fps = 0 )
{
if(iMaxClip() && !m_iClip)//last round
{
return SetAnimation( ACT_VM_SHOOT_EMPTY, fps ) == -1 ? FALSE : TRUE;
}
return 0;
}
//GENERIC WEAPON FUNCTIONS
virtual void PrimaryPostAttack( void ) {}
virtual void SecondaryPostAttack( void ) {}
virtual void PostReload( void ) {}
inline int IsEmptyReload( void ) { return m_iStepReload == EMPTY_RELOAD ? TRUE : FALSE; }
virtual void PrimaryAttack( void ) // do "+ATTACK"
{
int iResult = PlayCurrentAttack( iAttack1(), FBitSet(pev->impulse, PATTACK_FIREMODE1) ? 1 : 0 );
if(iResult == 1)
{
m_pPlayer->pev->punchangle.x = fPunchAngle1();
m_pPlayer->pev->velocity = m_pPlayer->pev->velocity - gpGlobals->v_forward * fRecoil1();
if ( (iFlags() & ITEM_FLAG_HIDEAMMO ) && m_iClip < GetNumBodies() && m_iClip ) m_iBody++;
PrimaryPostAttack(); //run post effects
if ( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() )
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + fNextAttack1() + 0.02;
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + fNextAttack1();
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_LONG(10, 15);
}
else if(iResult == 0)
{
PlayEmptySound( );
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
}
m_iStepReload = 0;//reset reload
}
virtual void SecondaryAttack( void ) // do "+ATTACK2"
{
int iResult = PlayCurrentAttack( iAttack2(), FBitSet(pev->impulse, SATTACK_FIREMODE1) ? 1 : 0 );
if(iResult == 1)
{
m_pPlayer->pev->punchangle.x = fPunchAngle2();
m_pPlayer->pev->velocity = m_pPlayer->pev->velocity - gpGlobals->v_forward * fRecoil2();
SecondaryPostAttack(); //run post effects
if ( m_flNextSecondaryAttack < UTIL_WeaponTimeBase() )
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + fNextAttack2() + 0.02;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + fNextAttack2();
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_LONG(10, 15);
}
else if(iResult == 0)
{
PlayEmptySound( );
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
}
m_iStepReload = 0;//reset reload
}
virtual void Reload( void ){ DefaultReload( ACT_VM_RELOAD ); } // do "+RELOAD"
virtual void PostIdle( void ) {} // calling every frame
virtual void WeaponIdle( void ) // called when no buttons pressed
{
if( !stricmp( pszAmmo1(), "grenade" ))
{
if(m_flHoldTime) Launch( pszAmmo1());
else DefaultIdle();
}
else DefaultIdle();
}
virtual void Deploy( void ); // deploy function
virtual void Holster( void ); // holster function
//weapon saved variables
float m_flNextPrimaryAttack; // soonest time ItemPostFrame will call PrimaryAttack
float m_flNextSecondaryAttack; // soonest time ItemPostFrame will call SecondaryAttack
float m_flTimeWeaponIdle; // soonest time ItemPostFrame will call WeaponIdle
float m_flTimeUpdate; // special time for additional effects
int m_iPrimaryAmmoType; // "primary" ammo index into players m_rgAmmo[]
int m_iSecondaryAmmoType; // "secondary" ammo index into players m_rgAmmo[]
int m_iDefaultAmmo; // how much primary ammo you get
int m_iDefaultAmmo2; // how much secondary ammo you get
int m_cActiveRocket; // how many rockets is now active ?
int m_iOnControl; // controllable rocket is on control now
int m_iStepReload; // reload state
int m_iSequence; // current weaponmodel sequence
int m_iClip; // current clip state
int m_iBody; // viewmodel body
int m_iSkin; // viewmodel skin
int m_iSpot; // enable laser dot
int m_iZoom; // zoom current level
//weapon nonsaved variables
float m_flHoldTime; // button holdtime
int m_iClientClip; // the last version of m_iClip sent to hud dll
int m_iClientFov; // g-cont. just to right update crosshairs
int m_iClientWeaponState; // the last version of the weapon state sent to hud dll (is current weapon, is on target)
int m_iPlayEmptySound; // trigger for empty sound
int m_fInReload; // Are we in the middle of a reload;
int m_iClientSkin; // synch server and client skin
int m_iClientBody; // synch server and client body
int b_restored; // restore body and skin
};
#endif // WEAPONS_H

View File

@ -1,68 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "client.h"
#define SF_WORLD_DARK 0x0001
#define SF_WORLD_TITLE 0x0002
void CWorld :: Precache( void )
{
g_pWorld = this;
m_pLinkList = NULL;
InitWorld();
if( pev->spawnflags & SF_WORLD_DARK )
{
CVAR_SET_FLOAT( "v_dark", 1.0f );
ClearBits( pev->spawnflags, SF_WORLD_DARK );
}
else CVAR_SET_FLOAT( "v_dark", 0.0f );
}
void CWorld :: KeyValue( KeyValueData *pkvd )
{
if( FStrEq( pkvd->szKeyName, "skyname" ))
{
CVAR_SET_STRING( "sv_skyname", pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if ( FStrEq(pkvd->szKeyName, "chaptertitle") )
{
pev->netname = ALLOC_STRING( pkvd->szValue );
CVAR_SET_FLOAT( "sv_newunit", 1 ); //new chapter
pkvd->fHandled = TRUE;
}
else if ( FStrEq(pkvd->szKeyName, "gametitle") )
{
SetBits( pev->spawnflags, SF_WORLD_TITLE );
pkvd->fHandled = TRUE;
}
}
void CWorld :: Spawn( void )
{
g_fGameOver = FALSE;
Precache();
}
void CWorld :: PostActivate( void )
{
// run post messages
if ( pev->netname )
{
UTIL_ShowMessageAll( STRING(pev->netname) );
pev->netname = iStringNull;
}
if ( pev->spawnflags & SF_WORLD_TITLE )
{
SERVER_COMMAND( "gametitle\n" );
ClearBits( pev->spawnflags, SF_WORLD_TITLE );
}
}
LINK_ENTITY_TO_CLASS( worldspawn, CWorld );

View File

@ -1,20 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef BASEWORLD_H
#define BASEWORLD_H
class CWorld : public CBaseEntity
{
public:
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void PostActivate( void );
};
extern BOOL g_startSuit;
extern CWorld *g_pWorld;
#endif //BASEWORLD_H

View File

@ -1,56 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#include "extdll.h"
#include "utils.h"
#include "game.h"
cvar_t *sv_maxspeed;
// Register your console variables here
// This gets called one time when the game is initialized
void GameDLLInit( void )
{
ALERT( at_aiconsole, "GameDLLInit();\n" );
sv_maxspeed = CVAR_REGISTER( "sv_maxspeed", "320", 0, "maximum speed a player can accelerate to when on ground" );
// register cvars here:
CVAR_REGISTER( "sv_soundlist", "0", 0, "show server sound list" );
CVAR_REGISTER( "mp_teamplay", "0", FCVAR_SERVERINFO, "sets to 1 to indicate teamplay" );
CVAR_REGISTER( "mp_fraglimit", "0", FCVAR_SERVERINFO, "limit of frags for current server" );
CVAR_REGISTER( "mp_timelimit", "0", FCVAR_SERVERINFO, "server timelimit" );
CVAR_REGISTER( "mp_footsteps", "0", FCVAR_SERVERINFO|FCVAR_PHYSICINFO, "can hear footsteps from other players" );
CVAR_REGISTER( "mp_fragsleft", "0", FCVAR_SERVERINFO, "counter that indicated how many frags remaining" );
CVAR_REGISTER( "mp_timeleft", "0" , FCVAR_SERVERINFO, "counter that indicated how many time remaining" );
CVAR_REGISTER( "mp_friendlyfire", "0", FCVAR_SERVERINFO, "enables firedlyfire for teamplay" );
CVAR_REGISTER( "mp_falldamage", "0", FCVAR_SERVERINFO, "falldamage multiplier" );
CVAR_REGISTER( "mp_weaponstay", "0", FCVAR_SERVERINFO, "weapon leave stays on ground" );
CVAR_REGISTER( "mp_forcerespawn", "1", FCVAR_SERVERINFO, "force client respawn after his death" );
CVAR_REGISTER( "mp_flashlight", "0", FCVAR_SERVERINFO, "attempt to use flashlight in multiplayer" );
CVAR_REGISTER( "mp_autocrosshair", "1", FCVAR_SERVERINFO, "enables auto-aim in multiplayer" );
CVAR_REGISTER( "decalfrequency", "30", FCVAR_SERVERINFO, "how many decals can be spawned" );
CVAR_REGISTER( "mp_teamlist", "hgrunt,scientist", FCVAR_SERVERINFO, "names of default teams" );
CVAR_REGISTER( "mp_teamoverride", "1", 0, "can ovveride teams from map settings ?" );
CVAR_REGISTER( "mp_defaultteam", "0", 0, "use default team instead ?" );
CVAR_REGISTER( "mp_chattime", "10", FCVAR_SERVERINFO, "time beetween messages" );
}
// perform any shutdown operations
void GameDLLShutdown( void )
{
}

View File

@ -1,26 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef GAME_H
#define GAME_H
#include "cvardef.h"
extern void GameDLLInit( void );
extern void GameDLLShutdown( void );
extern cvar_t *sv_maxspeed;
#endif // GAME_H

View File

@ -1,160 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//=========================================================
// GameRules.cpp
//=========================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "player.h"
#include "baseweapon.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "game.h"
extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer );
DLL_GLOBAL CGameRules* g_pGameRules = NULL;
extern DLL_GLOBAL BOOL g_fGameOver;
int g_teamplay = 0;
//=========================================================
//=========================================================
BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry )
{
int iAmmoIndex;
if ( pszAmmoName )
{
iAmmoIndex = pPlayer->GetAmmoIndex( pszAmmoName );
if ( iAmmoIndex > -1 )
{
if ( pPlayer->AmmoInventory( iAmmoIndex ) < iMaxCarry )
{
// player has room for more of this type of ammo
return TRUE;
}
}
}
return FALSE;
}
//=========================================================
//=========================================================
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->velocity = g_vecZero;
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
pPlayer->pev->punchangle = g_vecZero;
pPlayer->pev->fixangle = TRUE;
if( pentSpawnSpot->v.spawnflags & 1 ) // the START WITH SUIT flag
{
g_startSuit = TRUE;
}
return pentSpawnSpot;
}
//=========================================================
//=========================================================
BOOL CGameRules::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon )
{
// only living players can have items
if ( pPlayer->pev->deadflag != DEAD_NO )
return FALSE;
if ( pWeapon->pszAmmo1() )
{
if ( !CanHaveAmmo( pPlayer, pWeapon->pszAmmo1(), pWeapon->iMaxAmmo1() ) )
{
// we can't carry anymore ammo for this gun. We can only
// have the gun if we aren't already carrying one of this type
if ( pPlayer->HasPlayerItem( pWeapon ) )
{
return FALSE;
}
}
}
else
{
// weapon doesn't use ammo, don't take another if you already have it.
if ( pPlayer->HasPlayerItem( pWeapon ) )
{
return FALSE;
}
}
// note: will fall through to here if GetItemInfo doesn't fill the struct!
return TRUE;
}
//=========================================================
// load the SkillData struct with the proper values based on the skill level.
//=========================================================
void CGameRules::RefreshSkillData ( void )
{
}
//=========================================================
// instantiate the proper game rules object
//=========================================================
CGameRules *InstallGameRules( void )
{
SERVER_COMMAND( "exec game.rc\n" );
g_engfuncs.pfnServerExecute();
ALERT( at_aiconsole, "InstallGameRules\n" );
if ( !gpGlobals->deathmatch )
{
// generic half-life
g_teamplay = 0;
return new CHalfLifeRules;
}
else
{
if( CVAR_GET_FLOAT( "mp_teamplay" ) > 0 )
{
// teamplay
g_teamplay = 1;
return new CHalfLifeTeamplay;
}
if ((int)gpGlobals->deathmatch == 1)
{
// vanilla deathmatch
g_teamplay = 0;
return new CHalfLifeMultiplay;
}
else
{
// vanilla deathmatch??
g_teamplay = 0;
return new CHalfLifeMultiplay;
}
}
}

View File

@ -1,307 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//=========================================================
// GameRules
//=========================================================
class CBasePlayerWeapon;
class CBasePlayer;
class CItem;
class CBasePlayerAmmo;
// weapon respawning return codes
enum
{
GR_NONE = 0,
GR_WEAPON_RESPAWN_YES,
GR_WEAPON_RESPAWN_NO,
GR_AMMO_RESPAWN_YES,
GR_AMMO_RESPAWN_NO,
GR_ITEM_RESPAWN_YES,
GR_ITEM_RESPAWN_NO,
GR_PLR_DROP_GUN_ALL,
GR_PLR_DROP_GUN_ACTIVE,
GR_PLR_DROP_GUN_NO,
GR_PLR_DROP_AMMO_ALL,
GR_PLR_DROP_AMMO_ACTIVE,
GR_PLR_DROP_AMMO_NO,
};
// Player relationship return codes
enum
{
GR_NOTTEAMMATE = 0,
GR_TEAMMATE,
GR_ENEMY,
GR_ALLY,
GR_NEUTRAL,
};
class CGameRules
{
public:
virtual void RefreshSkillData( void );// fill skill data struct with proper values
virtual void Think( void ) = 0;// GR_Think - runs every server frame, should handle any timer tasks, periodic events, etc.
virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ) = 0; // Can this item spawn (eg monsters don't spawn in deathmatch).
virtual BOOL FAllowFlashlight( void ) = 0;// Are players allowed to switch on their flashlight?
virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon ) = 0;// should the player switch to this weapon?
virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pCurrentWeapon ) = 0;// I can't use this weapon anymore, get me the next best one.
// Functions to verify the single/multiplayer status of a game
virtual BOOL IsMultiplayer( void ) = 0;// is this a multiplayer game? (either coop or deathmatch)
virtual BOOL IsDeathmatch( void ) = 0;//is this a deathmatch game?
virtual BOOL IsTeamplay( void ) { return FALSE; };// is this deathmatch game being played with team rules?
virtual BOOL IsCoOp( void ) = 0;// is this a coop game?
// Client connection/disconnection
virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) = 0; // a client just connected to the server (player hasn't spawned yet)
virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating
virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server
virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ) = 0;// this client just hit the ground after a fall. How much damage?
virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) {return TRUE;};// can this player take damage from this attacker?
virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) { return TRUE; }
// Client spawn/respawn control
virtual void PlayerSpawn( CBasePlayer *pPlayer ) = 0;// called by CBasePlayer::Spawn just before releasing player into the game
virtual void PlayerThink( CBasePlayer *pPlayer ) = 0; // called by CBasePlayer::PreThink every frame, before physics are run and after keys are accepted
virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ) = 0;// is this player allowed to respawn now?
virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ) = 0;// When in the future will this player be able to spawn?
virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer );// Place this player on their spawnspot and face them the proper direction.
virtual BOOL AllowAutoTargetCrosshair( void ) { return TRUE; };
virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { return FALSE; }; // handles the user commands; returns TRUE if command handled properly
virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) {} // the player has changed userinfo; can change it now
// Client kills/scoring
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) = 0;// how many points do I award whoever kills this player?
virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) = 0;// Called each time a player dies
virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )= 0;// Call this from within a GameRules class to report an obituary.
// Weapon retrieval
virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );// The player is touching an CBasePlayerWeapon, do I give it to him?
virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon ) = 0;// Called each time a player picks up a weapon from the ground
// Weapon spawn/respawn control
virtual int WeaponShouldRespawn( CBasePlayerWeapon *pWeapon ) = 0;// should this weapon respawn?
virtual float FlWeaponRespawnTime( CBasePlayerWeapon *pWeapon ) = 0;// when may this weapon respawn?
virtual float FlWeaponTryRespawn( CBasePlayerWeapon *pWeapon ) = 0; // can i respawn now, and if not, when should i try again?
virtual Vector VecWeaponRespawnSpot( CBasePlayerWeapon *pWeapon ) = 0;// where in the world should this weapon respawn?
// Ammo retrieval
virtual BOOL CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry );// can this player take more of this ammo?
// Healthcharger respawn control
virtual float FlHealthChargerRechargeTime( void ) = 0;// how long until a depleted HealthCharger recharges itself?
virtual float FlHEVChargerRechargeTime( void ) { return 0; }// how long until a depleted HealthCharger recharges itself?
// What happens to a dead player's weapons
virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ) = 0;// what do I do with a player's weapons when he's killed?
// What happens to a dead player's ammo
virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ) = 0;// Do I drop ammo when the player dies? How much?
// Teamplay stuff
virtual const char *GetTeamID( CBaseEntity *pEntity ) = 0;// what team is this entity on?
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) = 0;// What is the player's relationship with this entity?
virtual int GetTeamIndex( const char *pTeamName ) { return -1; }
virtual const char *GetIndexedTeamName( int teamIndex ) { return ""; }
virtual BOOL IsValidTeam( const char *pTeamName ) { return TRUE; }
virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) {}
virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ) { return ""; }
// Sounds
virtual BOOL PlayTextureSounds( void ) { return TRUE; }
virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ) { return TRUE; }
// Monsters
virtual BOOL FAllowMonsters( void ) = 0;//are monsters allowed
// Immediately end a multiplayer game
virtual void EndMultiplayerGame( void ) {}
};
extern CGameRules *InstallGameRules( void );
//=========================================================
// CHalfLifeRules - rules for the single player Half-Life
// game.
//=========================================================
class CHalfLifeRules : public CGameRules
{
public:
CHalfLifeRules ( void );
// GR_Think
virtual void Think( void );
virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity );
virtual BOOL FAllowFlashlight( void ) { return TRUE; };
virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );
virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pCurrentWeapon );
// Functions to verify the single/multiplayer status of a game
virtual BOOL IsMultiplayer( void );
virtual BOOL IsDeathmatch( void );
virtual BOOL IsCoOp( void );
// Client connection/disconnection
virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] );
virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating
virtual void ClientDisconnected( edict_t *pClient );
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
// Client spawn/respawn control
virtual void PlayerSpawn( CBasePlayer *pPlayer );
virtual void PlayerThink( CBasePlayer *pPlayer );
virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer );
virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer );
virtual BOOL AllowAutoTargetCrosshair( void );
// Client kills/scoring
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
// Weapon retrieval
virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );
// Weapon spawn/respawn control
virtual int WeaponShouldRespawn( CBasePlayerWeapon *pWeapon );
virtual float FlWeaponRespawnTime( CBasePlayerWeapon *pWeapon );
virtual float FlWeaponTryRespawn( CBasePlayerWeapon *pWeapon );
virtual Vector VecWeaponRespawnSpot( CBasePlayerWeapon *pWeapon );
// Healthcharger respawn control
virtual float FlHealthChargerRechargeTime( void );
// What happens to a dead player's weapons
virtual int DeadPlayerWeapons( CBasePlayer *pPlayer );
// What happens to a dead player's ammo
virtual int DeadPlayerAmmo( CBasePlayer *pPlayer );
// Monsters
virtual BOOL FAllowMonsters( void );
// Teamplay stuff
virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";};
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
};
//=========================================================
// CHalfLifeMultiplay - rules for the basic half life multiplayer
// competition
//=========================================================
class CHalfLifeMultiplay : public CGameRules
{
public:
CHalfLifeMultiplay();
// GR_Think
virtual void Think( void );
virtual void RefreshSkillData( void );
virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity );
virtual BOOL FAllowFlashlight( void );
virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );
virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pCurrentWeapon );
// Functions to verify the single/multiplayer status of a game
virtual BOOL IsMultiplayer( void );
virtual BOOL IsDeathmatch( void );
virtual BOOL IsCoOp( void );
// Client connection/disconnection
// If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in
// svRejectReason
// Only the client's name and remote address are provided to the dll for verification.
virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] );
virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating
virtual void ClientDisconnected( edict_t *pClient );
virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker );
// Client spawn/respawn control
virtual void PlayerSpawn( CBasePlayer *pPlayer );
virtual void PlayerThink( CBasePlayer *pPlayer );
virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer );
virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer );
virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer );
virtual BOOL AllowAutoTargetCrosshair( void );
virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd );
// Client kills/scoring
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
// Weapon retrieval
virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );
virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon );// The player is touching an CBasePlayerWeapon, do I give it to him?
// Weapon spawn/respawn control
virtual int WeaponShouldRespawn( CBasePlayerWeapon *pWeapon );
virtual float FlWeaponRespawnTime( CBasePlayerWeapon *pWeapon );
virtual float FlWeaponTryRespawn( CBasePlayerWeapon *pWeapon );
virtual Vector VecWeaponRespawnSpot( CBasePlayerWeapon *pWeapon );
// Healthcharger respawn control
virtual float FlHealthChargerRechargeTime( void );
virtual float FlHEVChargerRechargeTime( void );
// What happens to a dead player's weapons
virtual int DeadPlayerWeapons( CBasePlayer *pPlayer );
// What happens to a dead player's ammo
virtual int DeadPlayerAmmo( CBasePlayer *pPlayer );
// Teamplay stuff
virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";}
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual BOOL PlayTextureSounds( void ) { return FALSE; }
virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol );
// Monsters
virtual BOOL FAllowMonsters( void );
// Immediately end a multiplayer game
virtual void EndMultiplayerGame( void ) { GoToIntermission(); }
protected:
virtual void ChangeLevel( void );
virtual void GoToIntermission( void );
float m_flIntermissionEndTime;
BOOL m_iEndIntermissionButtonHit;
void SendMOTDToClient( edict_t *client );
};
extern DLL_GLOBAL CGameRules* g_pGameRules;

View File

@ -1,281 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
/*
===== lights.cpp ========================================================
spawn and think functions for editor-placed lights
*/
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
class CLight : public CBaseLogic
{
public:
void KeyValue( KeyValueData* pkvd );
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void Think( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
int GetStyle( void ) { return m_iszCurrentStyle; };
void SetStyle( int iszPattern );
void SetCorrectStyle( void );
private:
int m_iOnStyle; // style to use while on
int m_iOffStyle; // style to use while off
int m_iTurnOnStyle; // style to use while turning on
int m_iTurnOffStyle; // style to use while turning off
int m_iTurnOnTime; // time taken to turn on
int m_iTurnOffTime; // time taken to turn off
int m_iszPattern; // custom style to use while on
int m_iszCurrentStyle; // current style string
};
LINK_ENTITY_TO_CLASS( light, CLight );
LINK_ENTITY_TO_CLASS( light_spot, CLight );
TYPEDESCRIPTION CLight::m_SaveData[] =
{
DEFINE_FIELD( CLight, m_iState, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iszPattern, FIELD_STRING ),
DEFINE_FIELD( CLight, m_iszCurrentStyle, FIELD_STRING ),
DEFINE_FIELD( CLight, m_iOnStyle, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iOffStyle, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iTurnOnStyle, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iTurnOffStyle, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iTurnOnTime, FIELD_INTEGER ),
DEFINE_FIELD( CLight, m_iTurnOffTime, FIELD_INTEGER ),
};
IMPLEMENT_SAVERESTORE( CLight, CBaseLogic );
//
// Cache user-entity-field values until spawn is called.
//
void CLight :: KeyValue( KeyValueData* pkvd)
{
if (FStrEq(pkvd->szKeyName, "m_iOnStyle"))
{
m_iOnStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iOffStyle"))
{
m_iOffStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iTurnOnStyle"))
{
m_iTurnOnStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iTurnOffStyle"))
{
m_iTurnOffStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iTurnOnTime"))
{
m_iTurnOnTime = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "m_iTurnOffTime"))
{
m_iTurnOffTime = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "pitch"))
{
pev->angles.x = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "pattern"))
{
m_iszPattern = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else CBaseEntity::KeyValue( pkvd );
}
void CLight :: SetStyle ( int iszPattern )
{
if (m_iStyle < 32) // if it's using a global style, don't change it
return;
m_iszCurrentStyle = iszPattern;
LIGHT_STYLE(m_iStyle, (char *)STRING( iszPattern ));
}
void CLight :: SetCorrectStyle ( void )
{
if (m_iStyle >= 32)
{
switch (m_iState)
{
case STATE_ON:
if (m_iszPattern) // custom styles have priority over standard ones
SetStyle( m_iszPattern );
else if (m_iOnStyle)
SetStyle(GetStdLightStyle(m_iOnStyle));
else SetStyle(MAKE_STRING("m"));
break;
case STATE_OFF:
if (m_iOffStyle)
SetStyle(GetStdLightStyle(m_iOffStyle));
else SetStyle(MAKE_STRING("a"));
break;
case STATE_TURN_ON:
if (m_iTurnOnStyle)
SetStyle(GetStdLightStyle(m_iTurnOnStyle));
else SetStyle(MAKE_STRING("a"));
break;
case STATE_TURN_OFF:
if (m_iTurnOffStyle)
SetStyle(GetStdLightStyle(m_iTurnOffStyle));
else SetStyle(MAKE_STRING("m"));
break;
}
}
else m_iszCurrentStyle = GetStdLightStyle( m_iStyle );
}
void CLight :: Think( void )
{
switch (GetState())
{
case STATE_TURN_ON:
m_iState = STATE_ON;
UTIL_FireTargets( pev->target, this, this, USE_ON );
break;
case STATE_TURN_OFF:
m_iState = STATE_OFF;
UTIL_FireTargets(pev->target, this, this, USE_OFF );
break;
}
SetCorrectStyle();
}
void CLight :: Spawn( void )
{
if( FStringNull( pev->targetname ))
{
// inert light
REMOVE_ENTITY(ENT( pev ));
return;
}
if (FBitSet(pev->spawnflags,SF_LIGHT_START_OFF))
m_iState = STATE_OFF;
else m_iState = STATE_ON;
SetCorrectStyle();
}
void CLight :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (m_iStyle >= 32)
{
if (useType == USE_TOGGLE)
{
if(m_iState == STATE_ON || m_iState == STATE_TURN_ON) useType = USE_OFF;
else useType = USE_ON;
}
if (useType == USE_ON)
{
if (m_iTurnOnTime)
{
m_iState = STATE_TURN_ON;
SetNextThink( m_iTurnOnTime );
}
else m_iState = STATE_ON;
}
else if(useType == USE_OFF)
{
if (m_iTurnOffTime)
{
m_iState = STATE_TURN_OFF;
SetNextThink( m_iTurnOffTime );
}
else m_iState = STATE_OFF;
}
SetCorrectStyle();
}
}
class CEnvLight : public CLight
{
public:
void KeyValue( KeyValueData* pkvd );
void Spawn( void );
};
LINK_ENTITY_TO_CLASS( light_environment, CEnvLight );
void CEnvLight::KeyValue( KeyValueData* pkvd )
{
if (FStrEq(pkvd->szKeyName, "_light"))
{
int r, g, b, v, j;
char szColor[64];
j = sscanf( pkvd->szValue, "%d %d %d %d\n", &r, &g, &b, &v );
if (j == 1)
{
g = b = r;
}
else if (j == 4)
{
r = r * (v / 255.0);
g = g * (v / 255.0);
b = b * (v / 255.0);
}
// simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling
r = pow( r / 114.0, 0.6 ) * 264;
g = pow( g / 114.0, 0.6 ) * 264;
b = pow( b / 114.0, 0.6 ) * 264;
pkvd->fHandled = TRUE;
sprintf( szColor, "%d", r );
CVAR_SET_STRING( "sv_skycolor_r", szColor );
sprintf( szColor, "%d", g );
CVAR_SET_STRING( "sv_skycolor_g", szColor );
sprintf( szColor, "%d", b );
CVAR_SET_STRING( "sv_skycolor_b", szColor );
}
else if (FStrEq(pkvd->szKeyName, "pitch"))
{
pev->angles.x = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
}
void CEnvLight :: Spawn( void )
{
char szVector[64];
UTIL_MakeAimVectors( pev->angles );
sprintf( szVector, "%f", gpGlobals->v_forward.x );
CVAR_SET_STRING( "sv_skyvec_x", szVector );
sprintf( szVector, "%f", gpGlobals->v_forward.y );
CVAR_SET_STRING( "sv_skyvec_y", szVector );
sprintf( szVector, "%f", gpGlobals->v_forward.z );
CVAR_SET_STRING( "sv_skyvec_z", szVector );
CLight::Spawn( );
}

View File

@ -1,961 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
// -------------------------------------------
//
// maprules.cpp
//
// This module contains entities for implementing/changing game
// rules dynamically within each map (.BSP)
//
// -------------------------------------------
#include "extdll.h"
#include "utils.h"
#include "gamerules.h"
#include "cbase.h"
#include "player.h"
class CRuleEntity : public CBaseEntity
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void SetMaster( int iszMaster ) { m_iszMaster = iszMaster; }
protected:
BOOL CanFireForActivator( CBaseEntity *pActivator );
private:
string_t m_iszMaster;
};
TYPEDESCRIPTION CRuleEntity::m_SaveData[] =
{
DEFINE_FIELD( CRuleEntity, m_iszMaster, FIELD_STRING),
};
IMPLEMENT_SAVERESTORE( CRuleEntity, CBaseEntity );
void CRuleEntity::Spawn( void )
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = EF_NODRAW;
}
void CRuleEntity::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "master"))
{
SetMaster( ALLOC_STRING(pkvd->szValue) );
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
BOOL CRuleEntity::CanFireForActivator( CBaseEntity *pActivator )
{
if (!pActivator)
{
return TRUE;
}
else if ( m_iszMaster )
{
if ( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) )
return TRUE;
else
return FALSE;
}
return TRUE;
}
//
// CRulePointEntity -- base class for all rule "point" entities (not brushes)
//
class CRulePointEntity : public CRuleEntity
{
public:
void Spawn( void );
};
void CRulePointEntity::Spawn( void )
{
CRuleEntity::Spawn();
pev->frame = 0;
pev->model = 0;
}
//
// CRuleBrushEntity -- base class for all rule "brush" entities (not brushes)
// Default behavior is to set up like a trigger, invisible, but keep the model for volume testing
//
class CRuleBrushEntity : public CRuleEntity
{
public:
void Spawn( void );
private:
};
void CRuleBrushEntity::Spawn( void )
{
SET_MODEL( edict(), STRING(pev->model) );
CRuleEntity::Spawn();
}
// CGameScore / game_score -- award points to player / team
// Points +/- total
// Flag: Allow negative scores SF_SCORE_NEGATIVE
// Flag: Award points to team in teamplay SF_SCORE_TEAM
#define SF_SCORE_NEGATIVE 0x0001
#define SF_SCORE_TEAM 0x0002
class CGameScore : public CRulePointEntity
{
public:
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
inline int Points( void ) { return pev->frags; }
inline BOOL AllowNegativeScore( void ) { return pev->spawnflags & SF_SCORE_NEGATIVE; }
inline BOOL AwardToTeam( void ) { return pev->spawnflags & SF_SCORE_TEAM; }
inline void SetPoints( int points ) { pev->frags = points; }
private:
};
LINK_ENTITY_TO_CLASS( game_score, CGameScore );
void CGameScore::Spawn( void )
{
CRulePointEntity::Spawn();
}
void CGameScore::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "points"))
{
SetPoints( atoi(pkvd->szValue) );
pkvd->fHandled = TRUE;
}
else
CRulePointEntity::KeyValue( pkvd );
}
void CGameScore::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
// Only players can use this
if ( pActivator->IsPlayer() )
{
if ( AwardToTeam() )
{
pActivator->AddPointsToTeam( Points(), AllowNegativeScore() );
}
else
{
pActivator->AddPoints( Points(), AllowNegativeScore() );
}
}
}
// CGameEnd / game_end -- Ends the game in MP
class CGameEnd : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
private:
};
LINK_ENTITY_TO_CLASS( game_end, CGameEnd );
void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
g_pGameRules->EndMultiplayerGame();
}
//
// CGameText / game_text -- NON-Localized HUD Message (use env_message to display a titles.txt message)
// Flag: All players SF_ENVTEXT_ALLPLAYERS
//
#define SF_ENVTEXT_ALLPLAYERS 0x0001
#define SF_ENVTEXT_ONLY_ONCE 0x0002
class CGameText : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
inline BOOL MessageToAll( void ) { return (pev->spawnflags & SF_ENVTEXT_ALLPLAYERS); }
inline void MessageSet( const char *pMessage ) { pev->message = ALLOC_STRING( pMessage ); }
inline const char *MessageGet( void ) { return STRING(pev->message); }
void EXPORT TriggerThink( void );
private:
hudtextparms_t m_textParms;
CBaseEntity *m_pActivator;
};
LINK_ENTITY_TO_CLASS( game_text, CGameText );
// Save parms as a block. Will break save/restore if the structure changes, but this entity didn't ship with Half-Life, so
// it can't impact saved Half-Life games.
TYPEDESCRIPTION CGameText::m_SaveData[] =
{
DEFINE_ARRAY( CGameText, m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ),
DEFINE_FIELD( CGameText, m_pActivator, FIELD_CLASSPTR ),
};
IMPLEMENT_SAVERESTORE( CGameText, CRulePointEntity );
void CGameText::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "channel"))
{
m_textParms.channel = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "x"))
{
m_textParms.x = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "y"))
{
m_textParms.y = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "effect"))
{
m_textParms.effect = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "color"))
{
int color[4];
UTIL_StringToIntArray( color, 4, pkvd->szValue );
m_textParms.r1 = color[0];
m_textParms.g1 = color[1];
m_textParms.b1 = color[2];
m_textParms.a1 = color[3];
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "color2"))
{
int color[4];
UTIL_StringToIntArray( color, 4, pkvd->szValue );
m_textParms.r2 = color[0];
m_textParms.g2 = color[1];
m_textParms.b2 = color[2];
m_textParms.a2 = color[3];
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "fadein"))
{
m_textParms.fadeinTime = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "fadeout"))
{
m_textParms.fadeoutTime = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "holdtime"))
{
m_textParms.holdTime = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "fxtime"))
{
m_textParms.fxTime = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CRulePointEntity::KeyValue( pkvd );
}
void CGameText::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
if ( MessageToAll() )
{
UTIL_HudMessageAll( m_textParms, MessageGet() );
}
else
{
if ( pActivator && pActivator->IsNetClient() )
{
UTIL_HudMessage( pActivator, m_textParms, MessageGet() );
}
}
if ( pev->target )
{
m_pActivator = pActivator;
SetThink( TriggerThink );
SetNextThink( m_textParms.fadeinTime + m_textParms.holdTime + m_textParms.fadeoutTime );
}
else if ( pev->spawnflags & SF_ENVTEXT_ONLY_ONCE )
{
SetThink( Remove );
SetNextThink( 0.1 );
}
}
void CGameText::TriggerThink( void )
{
UTIL_FireTargets( pev->target, m_pActivator, this, USE_TOGGLE, 0 );
if ( pev->spawnflags & SF_ENVTEXT_ONLY_ONCE )
{
SetThink( Remove );
SetNextThink( 0.1 );
}
}
//
// CGameTeamMaster / game_team_master -- "Masters" like multisource, but based on the team of the activator
// Only allows mastered entity to fire if the team matches my team
//
// team index (pulled from server team list "mp_teamlist"
// Flag: Remove on Fire
// Flag: Any team until set? -- Any team can use this until the team is set (otherwise no teams can use it)
//
#define SF_TEAMMASTER_FIREONCE 0x0001
#define SF_TEAMMASTER_ANYTEAM 0x0002
class CGameTeamMaster : public CRulePointEntity
{
public:
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
// int ObjectCaps( void ) { return CRulePointEntity:: ObjectCaps() | FCAP_MASTER; }
BOOL IsTriggered( CBaseEntity *pActivator );
const char *TeamID( void );
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMMASTER_FIREONCE) ? TRUE : FALSE; }
inline BOOL AnyTeam( void ) { return (pev->spawnflags & SF_TEAMMASTER_ANYTEAM) ? TRUE : FALSE; }
private:
BOOL TeamMatch( CBaseEntity *pActivator );
int m_teamIndex;
USE_TYPE triggerType;
};
LINK_ENTITY_TO_CLASS( game_team_master, CGameTeamMaster );
void CGameTeamMaster::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "teamindex"))
{
m_teamIndex = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "triggerstate"))
{
int type = atoi( pkvd->szValue );
switch( type )
{
case 0:
triggerType = USE_OFF;
break;
case 2:
triggerType = USE_TOGGLE;
break;
default:
triggerType = USE_ON;
break;
}
pkvd->fHandled = TRUE;
}
else
CRulePointEntity::KeyValue( pkvd );
}
void CGameTeamMaster::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
if ( useType == USE_SET )
{
if ( value < 0 )
{
m_teamIndex = -1;
}
else
{
m_teamIndex = g_pGameRules->GetTeamIndex( pActivator->TeamID() );
}
return;
}
if ( TeamMatch( pActivator ) )
{
UTIL_FireTargets( pev->target, pActivator, this, triggerType, value );
if ( RemoveOnFire() )
UTIL_Remove( this );
}
}
BOOL CGameTeamMaster::IsTriggered( CBaseEntity *pActivator )
{
return TeamMatch( pActivator );
}
const char *CGameTeamMaster::TeamID( void )
{
if ( m_teamIndex < 0 ) // Currently set to "no team"
return "";
return g_pGameRules->GetIndexedTeamName( m_teamIndex ); // UNDONE: Fill this in with the team from the "teamlist"
}
BOOL CGameTeamMaster::TeamMatch( CBaseEntity *pActivator )
{
if ( m_teamIndex < 0 && AnyTeam() )
return TRUE;
if ( !pActivator )
return FALSE;
return UTIL_TeamsMatch( pActivator->TeamID(), TeamID() );
}
//
// CGameTeamSet / game_team_set -- Changes the team of the entity it targets to the activator's team
// Flag: Fire once
// Flag: Clear team -- Sets the team to "NONE" instead of activator
#define SF_TEAMSET_FIREONCE 0x0001
#define SF_TEAMSET_CLEARTEAM 0x0002
class CGameTeamSet : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMSET_FIREONCE) ? TRUE : FALSE; }
inline BOOL ShouldClearTeam( void ) { return (pev->spawnflags & SF_TEAMSET_CLEARTEAM) ? TRUE : FALSE; }
private:
};
LINK_ENTITY_TO_CLASS( game_team_set, CGameTeamSet );
void CGameTeamSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
if ( ShouldClearTeam() )
{
UTIL_FireTargets( pev->target, pActivator, this, USE_SET, -1 );
}
else
{
UTIL_FireTargets( pev->target, pActivator, this, USE_SET, 0 );
}
if ( RemoveOnFire() )
{
UTIL_Remove( this );
}
}
//
// CGamePlayerZone / game_player_zone -- players in the zone fire my target when I'm fired
//
// Needs master?
class CGamePlayerZone : public CRuleBrushEntity
{
public:
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
private:
string_t m_iszInTarget;
string_t m_iszOutTarget;
string_t m_iszInCount;
string_t m_iszOutCount;
};
LINK_ENTITY_TO_CLASS( game_zone_player, CGamePlayerZone );
TYPEDESCRIPTION CGamePlayerZone::m_SaveData[] =
{
DEFINE_FIELD( CGamePlayerZone, m_iszInTarget, FIELD_STRING ),
DEFINE_FIELD( CGamePlayerZone, m_iszOutTarget, FIELD_STRING ),
DEFINE_FIELD( CGamePlayerZone, m_iszInCount, FIELD_STRING ),
DEFINE_FIELD( CGamePlayerZone, m_iszOutCount, FIELD_STRING ),
};
IMPLEMENT_SAVERESTORE( CGamePlayerZone, CRuleBrushEntity );
void CGamePlayerZone::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "intarget"))
{
m_iszInTarget = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "outtarget"))
{
m_iszOutTarget = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "incount"))
{
m_iszInCount = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "outcount"))
{
m_iszOutCount = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CRuleBrushEntity::KeyValue( pkvd );
}
void CGamePlayerZone::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
int playersInCount = 0;
int playersOutCount = 0;
if ( !CanFireForActivator( pActivator ) )
return;
CBaseEntity *pPlayer = NULL;
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
pPlayer = UTIL_PlayerByIndex( i );
if ( pPlayer )
{
TraceResult trace;
int hullNumber;
BOOL inside = FALSE;
if (pev->origin == g_vecZero) //LRC - to support movewith
{
hullNumber = human_hull;
if ( pPlayer->pev->flags & FL_DUCKING )
{
hullNumber = head_hull;
}
UTIL_TraceModel( pPlayer->pev->origin, pPlayer->pev->origin, hullNumber, edict(), &trace );
inside = trace.fStartSolid;
}
else
{
// LIMITATION: this doesn't allow for non-cuboid game_zone_player entities.
// (is that a problem?)
inside = this->Intersects(pPlayer);
}
if ( inside )
{
playersInCount++;
if ( m_iszInTarget )
{
UTIL_FireTargets( m_iszInTarget, pPlayer, pActivator, useType, value );
}
}
else
{
playersOutCount++;
if ( m_iszOutTarget )
{
UTIL_FireTargets( m_iszOutTarget, pPlayer, pActivator, useType, value );
}
}
}
}
if ( m_iszInCount )
{
UTIL_FireTargets( m_iszInCount, pActivator, this, USE_SET, playersInCount );
}
if ( m_iszOutCount )
{
UTIL_FireTargets( m_iszOutCount, pActivator, this, USE_SET, playersOutCount );
}
}
//
// CGamePlayerHurt / game_player_hurt -- Damages the player who fires it
// Flag: Fire once
#define SF_PKILL_FIREONCE 0x0001
class CGamePlayerHurt : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PKILL_FIREONCE) ? TRUE : FALSE; }
private:
};
LINK_ENTITY_TO_CLASS( game_player_hurt, CGamePlayerHurt );
void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
if ( pActivator->IsPlayer() )
{
if ( pev->dmg < 0 )
pActivator->TakeHealth( -pev->dmg, DMG_GENERIC );
else
pActivator->TakeDamage( pev, pev, pev->dmg, DMG_GENERIC );
}
UTIL_FireTargets( pev->target, pActivator, this, useType, value );
if ( RemoveOnFire() )
{
UTIL_Remove( this );
}
}
//
// CGameCounter / game_counter -- Counts events and fires target
// Flag: Fire once
// Flag: Reset on Fire
#define SF_GAMECOUNT_FIREONCE 0x0001
#define SF_GAMECOUNT_RESET 0x0002
class CGameCounter : public CRulePointEntity
{
public:
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_FIREONCE) ? TRUE : FALSE; }
inline BOOL ResetOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_RESET) ? TRUE : FALSE; }
inline void CountUp( void ) { pev->frags++; }
inline void CountDown( void ) { pev->frags--; }
inline void ResetCount( void ) { pev->frags = pev->dmg; }
inline int CountValue( void ) { return pev->frags; }
inline int LimitValue( void ) { return pev->health; }
inline BOOL HitLimit( void ) { return CountValue() == LimitValue(); }
private:
inline void SetCountValue( int value ) { pev->frags = value; }
inline void SetInitialValue( int value ) { pev->dmg = value; }
};
LINK_ENTITY_TO_CLASS( game_counter, CGameCounter );
void CGameCounter::Spawn( void )
{
// Save off the initial count
SetInitialValue( CountValue() );
CRulePointEntity::Spawn();
}
void CGameCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
switch( useType )
{
case USE_ON:
case USE_TOGGLE:
CountUp();
break;
case USE_OFF:
CountDown();
break;
case USE_SET:
SetCountValue( (int)value );
break;
}
if ( HitLimit() )
{
UTIL_FireTargets( pev->target, pActivator, this, USE_TOGGLE, 0 );
if ( RemoveOnFire() )
{
UTIL_Remove( this );
}
if ( ResetOnFire() )
{
ResetCount();
}
}
}
//
// CGameCounterSet / game_counter_set -- Sets the counter's value
// Flag: Fire once
#define SF_GAMECOUNTSET_FIREONCE 0x0001
class CGameCounterSet : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNTSET_FIREONCE) ? TRUE : FALSE; }
private:
};
LINK_ENTITY_TO_CLASS( game_counter_set, CGameCounterSet );
void CGameCounterSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
UTIL_FireTargets( pev->target, pActivator, this, USE_SET, pev->frags );
if ( RemoveOnFire() )
{
UTIL_Remove( this );
}
}
//
// CGamePlayerEquip / game_playerequip -- Sets the default player equipment
// Flag: USE Only
#define SF_PLAYEREQUIP_USEONLY 0x0001
#define MAX_EQUIP 32
class CGamePlayerEquip : public CRulePointEntity
{
public:
void KeyValue( KeyValueData *pkvd );
void Touch( CBaseEntity *pOther );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline BOOL UseOnly( void ) { return (pev->spawnflags & SF_PLAYEREQUIP_USEONLY) ? TRUE : FALSE; }
private:
void EquipPlayer( CBaseEntity *pPlayer );
string_t m_weaponNames[MAX_EQUIP];
int m_weaponCount[MAX_EQUIP];
};
LINK_ENTITY_TO_CLASS( game_player_equip, CGamePlayerEquip );
void CGamePlayerEquip::KeyValue( KeyValueData *pkvd )
{
CRulePointEntity::KeyValue( pkvd );
if ( !pkvd->fHandled )
{
for ( int i = 0; i < MAX_EQUIP; i++ )
{
if ( !m_weaponNames[i] )
{
char tmp[128];
UTIL_StripToken( pkvd->szKeyName, tmp );
m_weaponNames[i] = ALLOC_STRING(tmp);
m_weaponCount[i] = atoi(pkvd->szValue);
m_weaponCount[i] = max(1,m_weaponCount[i]);
pkvd->fHandled = TRUE;
break;
}
}
}
}
void CGamePlayerEquip::Touch( CBaseEntity *pOther )
{
if ( !CanFireForActivator( pOther ) )
return;
if ( UseOnly() )
return;
EquipPlayer( pOther );
}
void CGamePlayerEquip::EquipPlayer( CBaseEntity *pEntity )
{
CBasePlayer *pPlayer = NULL;
if ( pEntity->IsPlayer() )
{
pPlayer = (CBasePlayer *)pEntity;
}
if ( !pPlayer )
return;
for ( int i = 0; i < MAX_EQUIP; i++ )
{
if ( !m_weaponNames[i] )
break;
for ( int j = 0; j < m_weaponCount[i]; j++ )
{
pPlayer->GiveNamedItem( STRING(m_weaponNames[i]) );
}
}
}
void CGamePlayerEquip::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
EquipPlayer( pActivator );
}
//
// CGamePlayerTeam / game_player_team -- Changes the team of the player who fired it
// Flag: Fire once
// Flag: Kill Player
// Flag: Gib Player
#define SF_PTEAM_FIREONCE 0x0001
#define SF_PTEAM_KILL 0x0002
#define SF_PTEAM_GIB 0x0004
class CGamePlayerTeam : public CRulePointEntity
{
public:
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
private:
inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PTEAM_FIREONCE) ? TRUE : FALSE; }
inline BOOL ShouldKillPlayer( void ) { return (pev->spawnflags & SF_PTEAM_KILL) ? TRUE : FALSE; }
inline BOOL ShouldGibPlayer( void ) { return (pev->spawnflags & SF_PTEAM_GIB) ? TRUE : FALSE; }
const char *TargetTeamName( const char *pszTargetName );
};
LINK_ENTITY_TO_CLASS( game_player_team, CGamePlayerTeam );
const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName )
{
CBaseEntity *pTeamEntity = NULL;
while ((pTeamEntity = UTIL_FindEntityByTargetname( pTeamEntity, pszTargetName )) != NULL)
{
if ( FClassnameIs( pTeamEntity->pev, "game_team_master" ) )
return pTeamEntity->TeamID();
}
return NULL;
}
void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !CanFireForActivator( pActivator ) )
return;
if ( pActivator->IsPlayer() )
{
const char *pszTargetTeam = TargetTeamName( STRING(pev->target) );
if ( pszTargetTeam )
{
CBasePlayer *pPlayer = (CBasePlayer *)pActivator;
g_pGameRules->ChangePlayerTeam( pPlayer, pszTargetTeam, ShouldKillPlayer(), ShouldGibPlayer() );
}
}
if ( RemoveOnFire() )
{
UTIL_Remove( this );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,261 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// teamplay_gamerules.cpp
//
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "player.h"
#include "baseweapon.h"
#include "gamerules.h"
extern DLL_GLOBAL CGameRules *g_pGameRules;
extern DLL_GLOBAL BOOL g_fGameOver;
//=========================================================
//=========================================================
CHalfLifeRules::CHalfLifeRules( void )
{
RefreshSkillData();
}
//=========================================================
//=========================================================
void CHalfLifeRules::Think ( void )
{
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules::IsMultiplayer( void )
{
return FALSE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules::IsDeathmatch ( void )
{
return FALSE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules::IsCoOp( void )
{
return FALSE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon )
{
if ( !pPlayer->m_pActiveItem )
{
// player doesn't have an active item!
return TRUE;
}
if ( !pPlayer->m_pActiveItem->CanHolster() )
{
return FALSE;
}
return TRUE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pCurrentWeapon )
{
return FALSE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] )
{
return TRUE;
}
void CHalfLifeRules :: InitHUD( CBasePlayer *pl )
{
}
//=========================================================
//=========================================================
void CHalfLifeRules :: ClientDisconnected( edict_t *pClient )
{
}
//=========================================================
//=========================================================
float CHalfLifeRules::FlPlayerFallDamage( CBasePlayer *pPlayer )
{
// subtract off the speed at which a player is allowed to fall without being hurt,
// so damage will be based on speed beyond that, not the entire fall
pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED;
return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED;
}
//=========================================================
//=========================================================
void CHalfLifeRules :: PlayerSpawn( CBasePlayer *pPlayer )
{
if( g_startSuit )
pPlayer->pev->weapons |= ITEM_SUIT;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules :: AllowAutoTargetCrosshair( void )
{
return TRUE;
}
//=========================================================
//=========================================================
void CHalfLifeRules :: PlayerThink( CBasePlayer *pPlayer )
{
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules :: FPlayerCanRespawn( CBasePlayer *pPlayer )
{
return TRUE;
}
//=========================================================
//=========================================================
float CHalfLifeRules :: FlPlayerSpawnTime( CBasePlayer *pPlayer )
{
return gpGlobals->time;//now!
}
//=========================================================
// IPointsForKill - how many points awarded to anyone
// that kills this player?
//=========================================================
int CHalfLifeRules :: IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled )
{
return 1;
}
//=========================================================
// PlayerKilled - someone/something killed this player
//=========================================================
void CHalfLifeRules :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )
{
}
//=========================================================
// Deathnotice
//=========================================================
void CHalfLifeRules::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )
{
}
//=========================================================
// PlayerGotWeapon - player has grabbed a weapon that was
// sitting in the world
//=========================================================
void CHalfLifeRules :: PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon )
{
}
//=========================================================
// FlWeaponRespawnTime - what is the time in the future
// at which this weapon may spawn?
//=========================================================
float CHalfLifeRules :: FlWeaponRespawnTime( CBasePlayerWeapon *pWeapon )
{
return -1;
}
//=========================================================
// FlWeaponRespawnTime - Returns 0 if the weapon can respawn
// now, otherwise it returns the time at which it can try
// to spawn again.
//=========================================================
float CHalfLifeRules :: FlWeaponTryRespawn( CBasePlayerWeapon *pWeapon )
{
return 0;
}
//=========================================================
// VecWeaponRespawnSpot - where should this weapon spawn?
// Some game variations may choose to randomize spawn locations
//=========================================================
Vector CHalfLifeRules :: VecWeaponRespawnSpot( CBasePlayerWeapon *pWeapon )
{
return pWeapon->pev->origin;
}
//=========================================================
BOOL CHalfLifeRules::IsAllowedToSpawn( CBaseEntity *pEntity )
{
return TRUE;
}
//=========================================================
//=========================================================
// WeaponShouldRespawn - any conditions inhibiting the
// respawning of this weapon?
//=========================================================
int CHalfLifeRules :: WeaponShouldRespawn( CBasePlayerWeapon *pWeapon )
{
return GR_WEAPON_RESPAWN_NO;
}
//=========================================================
//=========================================================
float CHalfLifeRules::FlHealthChargerRechargeTime( void )
{
return 0;// don't recharge
}
//=========================================================
//=========================================================
int CHalfLifeRules::DeadPlayerWeapons( CBasePlayer *pPlayer )
{
return GR_PLR_DROP_GUN_NO;
}
//=========================================================
//=========================================================
int CHalfLifeRules::DeadPlayerAmmo( CBasePlayer *pPlayer )
{
return GR_PLR_DROP_AMMO_NO;
}
//=========================================================
//=========================================================
int CHalfLifeRules::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget )
{
// why would a single player in half life need this?
return GR_NOTTEAMMATE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules :: FAllowMonsters( void )
{
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
// Spectator.h
class CBaseSpectator : public CBaseEntity
{
public:
void Spawn();
void SpectatorConnect(void);
void SpectatorDisconnect(void);
void SpectatorThink(void);
private:
void SpectatorImpulseCommand(void);
};

View File

@ -1,614 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// teamplay_gamerules.cpp
//
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "client.h"
#include "player.h"
#include "baseweapon.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "game.h"
static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH];
static int team_scores[MAX_TEAMS];
static int num_teams = 0;
extern DLL_GLOBAL BOOL g_fGameOver;
CHalfLifeTeamplay :: CHalfLifeTeamplay()
{
m_DisableDeathMessages = FALSE;
m_DisableDeathPenalty = FALSE;
memset( team_names, 0, sizeof(team_names) );
memset( team_scores, 0, sizeof(team_scores) );
num_teams = 0;
// Copy over the team from the server config
m_szTeamList[0] = 0;
// Cache this because the team code doesn't want to deal with changing this in the middle of a game
strncpy( m_szTeamList, CVAR_GET_STRING( "mp_teamlist" ), TEAMPLAY_TEAMLISTLENGTH );
edict_t *pWorld = INDEXENT(0);
if ( pWorld && pWorld->v.team )
{
if( CVAR_GET_FLOAT( "mp_teamoverride" ))
{
const char *pTeamList = STRING(pWorld->v.team);
if ( pTeamList && strlen(pTeamList) )
{
strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH );
}
}
}
// Has the server set teams
if ( strlen( m_szTeamList ) )
m_teamLimit = TRUE;
else
m_teamLimit = FALSE;
RecountTeams();
}
void CHalfLifeTeamplay :: Think ( void )
{
///// Check game rules /////
static int last_frags;
static int last_time;
int frags_remaining = 0;
int time_remaining = 0;
if ( g_fGameOver ) // someone else quit the game already
{
CHalfLifeMultiplay::Think();
return;
}
float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60;
time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0);
if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit )
{
GoToIntermission();
return;
}
float flFragLimit = CVAR_GET_FLOAT( "mp_fraglimit" );
if ( flFragLimit )
{
int bestfrags = 9999;
int remain;
// check if any team is over the frag limit
for ( int i = 0; i < num_teams; i++ )
{
if ( team_scores[i] >= flFragLimit )
{
GoToIntermission();
return;
}
remain = flFragLimit - team_scores[i];
if ( remain < bestfrags )
{
bestfrags = remain;
}
}
frags_remaining = bestfrags;
}
// Updates when frags change
if( frags_remaining != last_frags )
{
g_engfuncs.pfnCVarSetString( "mp_fragsleft", UTIL_VarArgs( "%i", frags_remaining ));
}
// Updates once per second
if( CVAR_GET_FLOAT( "mp_timeleft" ) != last_time )
{
g_engfuncs.pfnCVarSetString( "mp_timeleft", UTIL_VarArgs( "%i", time_remaining ));
}
last_frags = frags_remaining;
last_time = time_remaining;
}
//=========================================================
// ClientCommand
// the user has typed a command which is unrecognized by everything else;
// this check to see if the gamerules knows anything about the command
//=========================================================
BOOL CHalfLifeTeamplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
{
if ( FStrEq( pcmd, "menuselect" ) )
{
if ( CMD_ARGC() < 2 )
return TRUE;
int slot = atoi( CMD_ARGV(1) );
// select the item from the current menu
return TRUE;
}
return FALSE;
}
void CHalfLifeTeamplay :: UpdateGameMode( CBasePlayer *pPlayer )
{
MESSAGE_BEGIN( MSG_ONE, gmsg.GameMode, NULL, pPlayer->edict() );
WRITE_BYTE( 1 ); // game mode teamplay
MESSAGE_END();
}
const char *CHalfLifeTeamplay::SetDefaultPlayerTeam( CBasePlayer *pPlayer )
{
// copy out the team name from the model
char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" );
strncpy( pPlayer->m_szTeamName, mdls, TEAM_NAME_LENGTH );
RecountTeams();
// update the current player of the team he is joining
if ( pPlayer->m_szTeamName[0] == '\0' || !IsValidTeam( pPlayer->m_szTeamName ) || CVAR_GET_FLOAT( "mp_defaultteam" ))
{
const char *pTeamName = NULL;
if( CVAR_GET_FLOAT( "mp_defaultteam" ))
{
pTeamName = team_names[0];
}
else
{
pTeamName = TeamWithFewestPlayers();
}
strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH );
}
return pPlayer->m_szTeamName;
}
//=========================================================
// InitHUD
//=========================================================
void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer )
{
int i;
SetDefaultPlayerTeam( pPlayer );
CHalfLifeMultiplay::InitHUD( pPlayer );
// Send down the team names
MESSAGE_BEGIN( MSG_ONE, gmsg.TeamNames, NULL, pPlayer->edict() );
WRITE_BYTE( num_teams );
for ( i = 0; i < num_teams; i++ )
{
WRITE_STRING( team_names[ i ] );
}
MESSAGE_END();
RecountTeams();
char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" );
// update the current player of the team he is joining
char text[1024];
if ( !strcmp( mdls, pPlayer->m_szTeamName ) )
{
sprintf( text, "* you are on team \'%s\'\n", pPlayer->m_szTeamName );
}
else
{
sprintf( text, "* assigned to team %s\n", pPlayer->m_szTeamName );
}
ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE );
UTIL_SayText( text, pPlayer );
int clientIndex = pPlayer->entindex();
RecountTeams();
// update this player with all the other players team info
// loop through all active players and send their team info to the new client
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
if ( plr && IsValidTeam( plr->TeamID() ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsg.TeamInfo, NULL, pPlayer->edict() );
WRITE_BYTE( plr->entindex() );
WRITE_STRING( plr->TeamID() );
MESSAGE_END();
}
}
}
void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib )
{
int damageFlags = DMG_GENERIC;
int clientIndex = pPlayer->entindex();
if ( !bGib )
{
damageFlags |= DMG_NEVERGIB;
}
else
{
damageFlags |= DMG_ALWAYSGIB;
}
if ( bKill )
{
// kill the player, remove a death, and let them start on the new team
m_DisableDeathMessages = TRUE;
m_DisableDeathPenalty = TRUE;
entvars_t *pevWorld = VARS( INDEXENT(0) );
pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags );
m_DisableDeathMessages = FALSE;
m_DisableDeathPenalty = FALSE;
}
// copy out the team name from the model
strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH );
g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName );
g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName );
// notify everyone's HUD of the team change
MESSAGE_BEGIN( MSG_ALL, gmsg.TeamInfo );
WRITE_BYTE( clientIndex );
WRITE_STRING( pPlayer->m_szTeamName );
MESSAGE_END();
MESSAGE_BEGIN( MSG_ALL, gmsg.ScoreInfo );
WRITE_BYTE( clientIndex );
WRITE_SHORT( pPlayer->pev->frags );
WRITE_SHORT( pPlayer->m_iDeaths );
WRITE_SHORT( 0 );
WRITE_SHORT( g_pGameRules->GetTeamIndex( pPlayer->m_szTeamName ) + 1 );
MESSAGE_END();
}
//=========================================================
// ClientUserInfoChanged
//=========================================================
void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer )
{
char text[1024];
// prevent skin/color/model changes
char *mdls = g_engfuncs.pfnInfoKeyValue( infobuffer, "model" );
if ( !stricmp( mdls, pPlayer->m_szTeamName ) )
return;
if( CVAR_GET_FLOAT( "mp_defaultteam" ))
{
int clientIndex = pPlayer->entindex();
g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName );
g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName );
sprintf( text, "* Not allowed to change teams in this game!\n" );
UTIL_SayText( text, pPlayer );
return;
}
if( CVAR_GET_FLOAT( "mp_defaultteam" ) || !IsValidTeam( mdls ))
{
int clientIndex = pPlayer->entindex();
g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName );
sprintf( text, "* Can't change team to \'%s\'\n", mdls );
UTIL_SayText( text, pPlayer );
sprintf( text, "* Server limits teams to \'%s\'\n", m_szTeamList );
UTIL_SayText( text, pPlayer );
return;
}
// notify everyone of the team change
sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls );
UTIL_SayTextAll( text, pPlayer );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n",
STRING(pPlayer->pev->netname),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
pPlayer->m_szTeamName,
mdls );
ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE );
// recound stuff
RecountTeams( TRUE );
}
//=========================================================
// Deathnotice.
//=========================================================
void CHalfLifeTeamplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor )
{
if ( m_DisableDeathMessages )
return;
if ( pVictim && pKiller && pKiller->flags & FL_CLIENT )
{
CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller );
if ( pk )
{
if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) )
{
MESSAGE_BEGIN( MSG_ALL, gmsg.DeathMsg );
WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer
WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim
WRITE_STRING( "teammate" ); // flag this as a teammate kill
MESSAGE_END();
return;
}
}
}
CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor );
}
//=========================================================
//=========================================================
void CHalfLifeTeamplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )
{
if ( !m_DisableDeathPenalty )
{
CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor );
RecountTeams();
}
}
//=========================================================
// IsTeamplay
//=========================================================
BOOL CHalfLifeTeamplay::IsTeamplay( void )
{
return TRUE;
}
BOOL CHalfLifeTeamplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker )
{
if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE )
{
// my teammate hit me.
if( (CVAR_GET_FLOAT( "mp_friendlyfire" ) == 0) && (pAttacker != pPlayer) )
{
// friendly fire is off, and this hit came from someone other than myself, then don't get hurt
return FALSE;
}
}
return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker );
}
//=========================================================
//=========================================================
int CHalfLifeTeamplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget )
{
// half life multiplay has a simple concept of Player Relationships.
// you are either on another player's team, or you are not.
if ( !pPlayer || !pTarget || !pTarget->IsPlayer() )
return GR_NOTTEAMMATE;
if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) )
{
return GR_TEAMMATE;
}
return GR_NOTTEAMMATE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeTeamplay::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target )
{
// always autoaim, unless target is a teammate
CBaseEntity *pTgt = CBaseEntity::Instance( target );
if ( pTgt && pTgt->IsPlayer() )
{
if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE )
return FALSE; // don't autoaim at teammates
}
return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target );
}
//=========================================================
//=========================================================
int CHalfLifeTeamplay::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled )
{
if ( !pKilled )
return 0;
if ( !pAttacker )
return 1;
if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE )
return -1;
return 1;
}
//=========================================================
//=========================================================
const char *CHalfLifeTeamplay::GetTeamID( CBaseEntity *pEntity )
{
if ( pEntity == NULL || pEntity->pev == NULL )
return "";
// return their team name
return pEntity->TeamID();
}
int CHalfLifeTeamplay::GetTeamIndex( const char *pTeamName )
{
if ( pTeamName && *pTeamName != 0 )
{
// try to find existing team
for ( int tm = 0; tm < num_teams; tm++ )
{
if ( !stricmp( team_names[tm], pTeamName ) )
return tm;
}
}
return -1; // No match
}
const char *CHalfLifeTeamplay::GetIndexedTeamName( int teamIndex )
{
if ( teamIndex < 0 || teamIndex >= num_teams )
return "";
return team_names[ teamIndex ];
}
BOOL CHalfLifeTeamplay::IsValidTeam( const char *pTeamName )
{
if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set
return TRUE;
return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE;
}
const char *CHalfLifeTeamplay::TeamWithFewestPlayers( void )
{
int i;
int minPlayers = MAX_TEAMS;
int teamCount[ MAX_TEAMS ];
char *pTeamName = NULL;
memset( teamCount, 0, MAX_TEAMS * sizeof(int) );
// loop through all clients, count number of players on each team
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
if ( plr )
{
int team = GetTeamIndex( plr->TeamID() );
if ( team >= 0 )
teamCount[team] ++;
}
}
// Find team with least players
for ( i = 0; i < num_teams; i++ )
{
if ( teamCount[i] < minPlayers )
{
minPlayers = teamCount[i];
pTeamName = team_names[i];
}
}
return pTeamName;
}
//=========================================================
//=========================================================
void CHalfLifeTeamplay::RecountTeams( bool bResendInfo )
{
char *pName;
char teamlist[TEAMPLAY_TEAMLISTLENGTH];
// loop through all teams, recounting everything
num_teams = 0;
// Copy all of the teams from the teamlist
// make a copy because strtok is destructive
strcpy( teamlist, m_szTeamList );
pName = teamlist;
pName = strtok( pName, ";" );
while ( pName != NULL && *pName )
{
if ( GetTeamIndex( pName ) < 0 )
{
strcpy( team_names[num_teams], pName );
num_teams++;
}
pName = strtok( NULL, ";" );
}
if ( num_teams < 2 )
{
num_teams = 0;
m_teamLimit = FALSE;
}
// Sanity check
memset( team_scores, 0, sizeof(team_scores) );
// loop through all clients
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
if ( plr )
{
const char *pTeamName = plr->TeamID();
// try add to existing team
int tm = GetTeamIndex( pTeamName );
if ( tm < 0 ) // no team match found
{
if ( !m_teamLimit )
{
// add to new team
tm = num_teams;
num_teams++;
team_scores[tm] = 0;
strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH );
}
}
if ( tm >= 0 )
{
team_scores[tm] += plr->pev->frags;
}
if ( bResendInfo ) //Someone's info changed, let's send the team info again.
{
if ( plr && IsValidTeam( plr->TeamID() ) )
{
MESSAGE_BEGIN( MSG_ALL, gmsg.TeamInfo, NULL );
WRITE_BYTE( plr->entindex() );
WRITE_STRING( plr->TeamID() );
MESSAGE_END();
}
}
}
}
}

View File

@ -1,56 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// teamplay_gamerules.h
//
#define MAX_TEAMNAME_LENGTH 16
#define MAX_TEAMS 32
#define TEAMPLAY_TEAMLISTLENGTH MAX_TEAMS*MAX_TEAMNAME_LENGTH
class CHalfLifeTeamplay : public CHalfLifeMultiplay
{
public:
CHalfLifeTeamplay();
virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd );
virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer );
virtual BOOL IsTeamplay( void );
virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker );
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual const char *GetTeamID( CBaseEntity *pEntity );
virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target );
virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
virtual void InitHUD( CBasePlayer *pl );
virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor );
virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode
virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
virtual void Think ( void );
virtual int GetTeamIndex( const char *pTeamName );
virtual const char *GetIndexedTeamName( int teamIndex );
virtual BOOL IsValidTeam( const char *pTeamName );
const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer );
virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib );
private:
void RecountTeams( bool bResendInfo = FALSE );
const char *TeamWithFewestPlayers( void );
BOOL m_DisableDeathMessages;
BOOL m_DisableDeathPenalty;
BOOL m_teamLimit; // This means the server set only some teams as valid
char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH];
};

File diff suppressed because it is too large Load Diff

View File

@ -1,115 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef CLIENT_H
#define CLIENT_H
extern void PhysicsPreFrame( void );
extern void PhysicsFrame( void );
extern void PhysicsPostFrame( void );
extern void respawn( entvars_t* pev, BOOL fCopyCorpse );
extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] );
extern void ClientDisconnect( edict_t *pEntity );
extern void ClientKill( edict_t *pEntity );
extern void ClientPutInServer( edict_t *pEntity );
extern void ClientCommand( edict_t *pEntity );
extern void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer );
extern void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax );
extern void ServerDeactivate( void );
extern void StartFrame( void );
extern void RegisterEncoders( void );
extern void PlayerPostThink( edict_t *pEntity );
extern void PlayerPreThink( edict_t *pEntity );
extern void BuildLevelList( void );
extern void InitBodyQue(void);
extern void InitWorld( void );
extern const char *GetGameDescription( void );
extern void SpectatorConnect ( edict_t *pEntity );
extern void SpectatorDisconnect ( edict_t *pEntity );
extern void SpectatorThink ( edict_t *pEntity );
extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int portal );
extern void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
extern int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet );
extern void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodelindex );
extern int GetWeaponData( edict_t *player, struct weapon_data_s *info );
extern void CmdStart( const edict_t *player, const usercmd_t *cmd, unsigned int random_seed );
extern void CmdEnd ( const edict_t *player );
extern int g_serveractive;
// messages affect only player
typedef struct user_messages_s
{
int Shake;
int Fade;
int SelAmmo;
int Intermission;
int Flashlight;
int FlashBattery;
int ResetHUD;
int InitHUD;
int HUDColor;
int CurWeapon;
int Health;
int Damage;
int Battery;
int Train;
int WeaponList;
int AmmoX;
int DeathMsg;
int ScoreInfo;
int TeamInfo;
int TeamScore;
int GameMode;
int MOTD;
int ServerName;
int AmmoPickup;
int WeapPickup;
int ItemPickup;
int HideWeapon;
int WeaponAnim;
int RoomType;
int SayText;
int ShowMenu;
int GeigerRange;
int TeamNames;
int TextMsg;
int StatusText;
int StatusValue;
int SetBody;
int SetSkin;
int ZoomHUD;
int WarHUD;
// entity messages
int TempEntity; // completely moved from engine to user dlls
int SetFog;
int StatusIcon;
int SetSky;
int Particle;
int Fsound;
int CamData;
int RainData;
int HudText;
int ShowGameTitle;
} user_messages_t;
extern user_messages_t gmsg;
extern BOOL MSGSended;
#endif // CLIENT_H

View File

@ -1,51 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#include "decals.h"
DLL_DECALLIST gDecals[] =
{
{ "{shot1", 0 }, // DECAL_GUNSHOT1
{ "{shot2", 0 }, // DECAL_GUNSHOT2
{ "{shot3", 0 }, // DECAL_GUNSHOT3
{ "{shot4", 0 }, // DECAL_GUNSHOT4
{ "{shot5", 0 }, // DECAL_GUNSHOT5
{ "{lambda01", 0 }, // DECAL_LAMBDA1
{ "{lambda02", 0 }, // DECAL_LAMBDA2
{ "{lambda03", 0 }, // DECAL_LAMBDA3
{ "{lambda04", 0 }, // DECAL_LAMBDA4
{ "{lambda05", 0 }, // DECAL_LAMBDA5
{ "{lambda06", 0 }, // DECAL_LAMBDA6
{ "{scorch1", 0 }, // DECAL_SCORCH1
{ "{scorch2", 0 }, // DECAL_SCORCH2
{ "{blood1", 0 }, // DECAL_BLOOD1
{ "{blood2", 0 }, // DECAL_BLOOD2
{ "{blood3", 0 }, // DECAL_BLOOD3
{ "{blood4", 0 }, // DECAL_BLOOD4
{ "{blood5", 0 }, // DECAL_BLOOD5
{ "{blood6", 0 }, // DECAL_BLOOD6
{ "{yblood1", 0 }, // DECAL_YBLOOD1
{ "{yblood2", 0 }, // DECAL_YBLOOD2
{ "{yblood3", 0 }, // DECAL_YBLOOD3
{ "{yblood4", 0 }, // DECAL_YBLOOD4
{ "{yblood5", 0 }, // DECAL_YBLOOD5
{ "{yblood6", 0 }, // DECAL_YBLOOD6
{ "{break1", 0 }, // DECAL_GLASSBREAK1
{ "{break2", 0 }, // DECAL_GLASSBREAK2
{ "{break3", 0 }, // DECAL_GLASSBREAK3
{ "{bigshot1", 0 }, // DECAL_BIGSHOT1
{ "{bigshot2", 0 }, // DECAL_BIGSHOT2
{ "{bigshot3", 0 }, // DECAL_BIGSHOT3
{ "{bigshot4", 0 }, // DECAL_BIGSHOT4
{ "{bigshot5", 0 }, // DECAL_BIGSHOT5
{ "{spit1", 0 }, // DECAL_SPIT1
{ "{spit2", 0 }, // DECAL_SPIT2
{ "{bproof1", 0 }, // DECAL_BPROOF1
{ "{gargstomp", 0 }, // DECAL_GARGSTOMP1, // Gargantua stomp crack
{ "{smscorch1", 0 }, // DECAL_SMALLSCORCH1, // Small scorch mark
{ "{smscorch2", 0 }, // DECAL_SMALLSCORCH2, // Small scorch mark
{ "{smscorch3", 0 }, // DECAL_SMALLSCORCH3, // Small scorch mark
{ "{mommablob", 0 }, // DECAL_MOMMABIRTH // BM Birth spray
{ "{mommablob", 0 }, // DECAL_MOMMASPLAT // BM Mortar spray?? need decal
};

View File

@ -1,63 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2006
//=======================================================================
#ifndef DECALS_H
#define DECALS_H
enum decal_e
{
DECAL_GUNSHOT1 = 0,
DECAL_GUNSHOT2,
DECAL_GUNSHOT3,
DECAL_GUNSHOT4,
DECAL_GUNSHOT5,
DECAL_LAMBDA1,
DECAL_LAMBDA2,
DECAL_LAMBDA3,
DECAL_LAMBDA4,
DECAL_LAMBDA5,
DECAL_LAMBDA6,
DECAL_SCORCH1,
DECAL_SCORCH2,
DECAL_BLOOD1,
DECAL_BLOOD2,
DECAL_BLOOD3,
DECAL_BLOOD4,
DECAL_BLOOD5,
DECAL_BLOOD6,
DECAL_YBLOOD1,
DECAL_YBLOOD2,
DECAL_YBLOOD3,
DECAL_YBLOOD4,
DECAL_YBLOOD5,
DECAL_YBLOOD6,
DECAL_GLASSBREAK1,
DECAL_GLASSBREAK2,
DECAL_GLASSBREAK3,
DECAL_BIGSHOT1,
DECAL_BIGSHOT2,
DECAL_BIGSHOT3,
DECAL_BIGSHOT4,
DECAL_BIGSHOT5,
DECAL_SPIT1,
DECAL_SPIT2,
DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_MOMMASPLAT,
DECAL_COUNT, //Must be last in the list!
};
typedef struct
{
char *name;
int index;
} DLL_DECALLIST;
extern DLL_DECALLIST gDecals[];
#endif // DECALS_H

View File

@ -1,441 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// defaults.h - default global settings for max ammo,
// monster's health, e.t.c
//=======================================================================
#ifndef DEFAULT_H
#define DEFAULT_H
//name of directory with mod
#define PITCHMIN 30 //min pitch
#define PITCHMAX 100 //max pitch
#define MAX_AVELOCITY 4096
#define MAX_VELOCITY 4096
#define MAX_TRANSITION_ENTITY 512
#define MAP_MAX_NAME 32
#define MAX_ITEM_TYPES 6 //selection slots
#define MAX_ITEMS 5 //item types
#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump
//=========================
// Debug macros
//=========================
#define SHIFT Msg("\n")
#define DEBUGHEAD Msg("======/Xash Debug System/======\nclassname: %s[%i], targetname %s\n", STRING(pev->classname), entindex(), STRING(pev->targetname))
#define MSGSTATEHEALTH Msg("State: %s, health %g\n", GetStringForState( GetState()), pev->health )
#define MSGSTATESTRENGTH Msg("State: %s, strength %g\n", GetStringForState( GetState()), pev->health )
#define MSGSTATEVOLUME Msg("State: %s, volume %g\n", GetStringForState( GetState()), m_flVolume )
#define MSGSTATESPEED Msg("State: %s, speed %g\n", GetStringForState( GetState()), pev->speed )
//=========================
// CLOCK DEFAULTS
//=========================
#define SECONDS 60
#define MINUTES 3600
#define HOURS 43200
//=========================
// LIGHT DEFAULTS
//=========================
#define START_SWITCH_STYLE 32
//=========================
// WORLD DEFAULTS
//=========================
#define XEN_GRAVITY 0.6
#define EARTH_GRAVITY 1.0
#define MAP_SIZE 131070
#define MAP_HALFSIZE MAP_SIZE / 2
#define FOG_LIMIT 30000
#define MAX_GIB_LIFETIME 30
//=========================
// Global spawnflag system
//=========================
#define SF_NOTSOLID 0x2
#define SF_FIREONCE 0x2
#define SF_NORESPAWN BIT( 30 )
//=========================
// FCAP DEFAULTS
//=========================
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
#define FCAP_CUSTOMSAVE 0x00000001
#define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions
#define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore
#define FCAP_IMPULSE_USE 0x00000008 // can be used by the player
#define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player
#define FCAP_ONOFF_USE 0x00000020 // can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
#define FCAP_ONLYDIRECT_USE 0x00000100 //LRC - can't use this entity through a wall.
#define FCAP_DONT_SAVE 0x80000000 // Don't save this
//=========================
// MONSTER CLASSIFY
//=========================
// For CLASSIFY
#define CLASS_NONE 0
#define CLASS_MACHINE 1
#define CLASS_PLAYER 2
#define CLASS_HUMAN_PASSIVE 3
#define CLASS_HUMAN_MILITARY 4
#define CLASS_ALIEN_MILITARY 5
#define CLASS_ALIEN_PASSIVE 6
#define CLASS_ALIEN_MONSTER 7
#define CLASS_ALIEN_PREY 8
#define CLASS_ALIEN_PREDATOR 9
#define CLASS_INSECT 10
#define CLASS_PLAYER_ALLY 11
#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players
#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
#define CLASS_FACTION_A 14 // very simple new classes, for use with Behaves As
#define CLASS_FACTION_B 15
#define CLASS_FACTION_C 16
#define CLASS_BARNACLE 99 //special because no one pays attention to it, and it eats a wide cross-section of creatures.
//=========================
// DAMAGE DEFAULTS
//=========================
#define DMG_GENERIC 0 // generic damage was done
#define DMG_CRUSH (1 << 0) // crushed by falling or moving object
#define DMG_BULLET (1 << 1) // shot
#define DMG_SLASH (1 << 2) // cut, clawed, stabbed
#define DMG_BURN (1 << 3) // heat burned
#define DMG_FREEZE (1 << 4) // frozen
#define DMG_FALL (1 << 5) // fell too far
#define DMG_BLAST (1 << 6) // explosive blast damage
#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
#define DMG_SHOCK (1 << 8) // electric shock
#define DMG_SONIC (1 << 9) // sound pulse shockwave
#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
#define DMG_DROWN (1 << 14) // Drowning
#define DMG_TIMEBASED (~(0x3fff))// mask for time-based damage
#define DMG_PARALYZE (1 << 15) // slows affected creature down
#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad
#define DMG_POISON (1 << 17) // blood poisioning
#define DMG_RADIATION (1 << 18) // radiation exposure
#define DMG_DROWNRECOVER (1 << 19) // drowning recovery
#define DMG_ACID (1 << 20) // toxic chemicals or acid burns
#define DMG_SLOWBURN (1 << 21) // in an oven
#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer
#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar)
#define DMG_NUCLEAR (1 << 24) // dmg at nuclear explode
// these are the damage types that are allowed to gib corpses
#define DMG_GIB_CORPSE ( DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB | DMG_NUCLEAR )
// these are the damage types that have client hud art
#define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK | DMG_NUCLEAR)
#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage
#define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval
#define NERVEGAS_DURATION 2
#define NERVEGAS_DAMAGE 5.0
#define POISON_DURATION 5
#define POISON_DAMAGE 2.0
#define RADIATION_DURATION 2
#define RADIATION_DAMAGE 1.0
#define ACID_DURATION 2
#define ACID_DAMAGE 5.0
#define SLOWBURN_DURATION 2
#define SLOWBURN_DAMAGE 1.0
#define SLOWFREEZE_DURATION 2
#define SLOWFREEZE_DAMAGE 1.0
#define itbd_Paralyze 0
#define itbd_NerveGas 1
#define itbd_Poison 2
#define itbd_Radiation 3
#define itbd_DrownRecover 4
#define itbd_Acid 5
#define itbd_SlowBurn 6
#define itbd_SlowFreeze 7
#define CDMG_TIMEBASED 8
// when calling KILLED(), a value that governs gib behavior is expected to be
// one of these three values
#define GIB_NORMAL 0// gib if entity was overkilled
#define GIB_NEVER 1// never gib, no matter how much death damage is done ( freezing, etc )
#define GIB_ALWAYS 2// always gib ( Houndeye Shock, Barnacle Bite )
//=========================
// CAPS DEFAULTS
//=========================
#define bits_CAP_DUCK ( 1 << 0 )// crouch
#define bits_CAP_JUMP ( 1 << 1 )// jump/leap
#define bits_CAP_STRAFE ( 1 << 2 )// strafe ( walk/run sideways)
#define bits_CAP_SQUAD ( 1 << 3 )// can form squads
#define bits_CAP_SWIM ( 1 << 4 )// proficiently navigate in water
#define bits_CAP_CLIMB ( 1 << 5 )// climb ladders/ropes
#define bits_CAP_USE ( 1 << 6 )// open doors/push buttons/pull levers
#define bits_CAP_HEAR ( 1 << 7 )// can hear forced sounds
#define bits_CAP_AUTO_DOORS ( 1 << 8 )// can trigger auto doors
#define bits_CAP_OPEN_DOORS ( 1 << 9 )// can open manual doors
#define bits_CAP_TURN_HEAD ( 1 << 10)// can turn head, always bone controller 0
#define bits_CAP_RANGE_ATTACK1 ( 1 << 11)// can do a range attack 1
#define bits_CAP_RANGE_ATTACK2 ( 1 << 12)// can do a range attack 2
#define bits_CAP_MELEE_ATTACK1 ( 1 << 13)// can do a melee attack 1
#define bits_CAP_MELEE_ATTACK2 ( 1 << 14)// can do a melee attack 2
#define bits_CAP_FLY ( 1 << 15)// can fly, move all around
#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS)
//=========================
// WEAPON DEFAULTS
//=========================
//sound volume for different states
#define PRIMARY_CHARGE_VOLUME 256
#define PRIMARY_FIRE_VOLUME 450
#define LOUD_GUN_VOLUME 1000
#define NORMAL_GUN_VOLUME 600
#define QUIET_GUN_VOLUME 200
//flash brightness
#define BRIGHT_GUN_FLASH 512
#define NORMAL_GUN_FLASH 256
#define DIM_GUN_FLASH 128
#define NO_GUN_FLASH 0
#define WEAPON_NOCLIP -1
#define WEAPON_NOAMMO -1
//default as barney hands for weapon
#define GORDON_HANDS 1
#define BARNEY_HANDS 0
//Bullet damage settings
//#define 9MM_BULLET_DMG 8
//=========================
// SETTINGS FOR EACH WEAPON
//=========================
//Crowbar settings (weapon_crowbar)
#define CROWBAR_WEIGHT 0
#define CROWBAR_DMG 10
#define CROWBAR_BODYHIT_VOLUME 128
#define CROWBAR_WALLHIT_VOLUME 512
//Glock settings (weapon_glock)
#define GLOCK_WEIGHT 10
#define GLOCK_MAX_CARRY 250
#define GLOCK_MAX_CLIP 17
#define GLOCK_DEFAULT_GIVE 17
#define GLOCK_RANDOM_GIVE RANDOM_LONG( 10, 17 )
//Desert eagle settings (weapon_eagle)
#define DESERT_MAX_CLIP 7
#define DESERT_WEIGHT 15
#define DESERT_DEFAULT_GIVE 7
#define DESERT_RANDOM_GIVE RANDOM_LONG( 4, 7 )
#define DESERT_MAX_CARRY 21
#define DESERT_LASER_FOCUS 850
//mp5 settings (weapon_mp5)
#define MP5_WEIGHT 15
#define MP5_MAX_CLIP 50
#define MP5_DEFAULT_GIVE 25
#define MP5_RANDOM_GIVE RANDOM_LONG( 19, 45 )
#define MP5_M203_DEFAULT_GIVE 0
#define MP5_M203_RANDOM_GIVE RANDOM_LONG( 0, 3 )
//saw settings (weapon_m249)
#define SAW_WEIGHT 25
#define SAW_MAX_CARRY 200
#define SAW_MAX_CLIP 100
#define SAW_DEFAULT_GIVE 100
#define SAW_RANDOM_GIVE RANDOM_LONG( 20, 100 )
//shotgun settings (weapon_shotgun)
#define SHOTGUN_WEIGHT 15
#define SHOTGUN_MAX_CLIP 6
#define SHOTGUN_DEFAULT_GIVE 6
#define SHOTGUN_RANDOM_GIVE RANDOM_LONG( 1, 6 )
#define VECTOR_CONE_DM_SHOTGUN Vector( 0.08716, 0.04362, 0.00 )// 10 degrees by 5 degrees
#define VECTOR_CONE_DM_DOUBLESHOTGUN Vector( 0.17365, 0.04362, 0.00 ) // 20 degrees by 5 degrees
//m40a1 settings (weapon_m40a1)
#define M40A1_WEIGHT 25
#define M40A1_MAX_CARRY 10
#define M40A1_MAX_CLIP 5
#define M40A1_DEFAULT_GIVE 5
#define M40A1_RANDOM_GIVE RANDOM_LONG( 1, 5 )
#define MAX_ZOOM 15
//Rpg settings (weapon_rpg)
#define RPG_WEIGHT 20
#define RPG_MAX_CLIP 1
#define RPG_DEFAULT_GIVE 1
#define AMMO_RPGCLIP_GIVE 1
#define RPG_ROCKET_DMG 100
#define RPG_LASER_FOCUS 350
//gauss settings (weapon_gauss)
#define GAUSS_PRIMARY_DMG 20
#define GAUSS_WEIGHT 20
#define GAUSS_DEFAULT_GIVE 20
#define GAUSS_RANDOM_GIVE RANDOM_LONG( 10, 40 )
//Egon settings (weapon_egon)
#define EGON_WEIGHT 20
#define EGON_DEFAULT_GIVE 20
#define EGON_RANDOM_GIVE RANDOM_LONG( 15, 35 )
#define EGON_NARROW_DMG 6
#define EGON_WIDE_DMG 14
#define EGON_BEAM_SPRITE "sprites/xbeam1.spr"
#define EGON_FLARE_SPRITE "sprites/XSpark1.spr"
#define EGON_SOUND_OFF "weapons/egon_off1.wav"
#define EGON_SOUND_RUN "weapons/egon_run3.wav"
#define EGON_SOUND_STARTUP "weapons/egon_windup2.wav"
#define EGON_SWITCH_NARROW_TIME 0.75
#define EGON_SWITCH_WIDE_TIME 1.5
#define EGON_PULSE_INTERVAL 0.1
#define EGON_DISCHARGE_INTERVAL 0.1
//Displacer settings (weapon_displacer)
#define DISPLACER_WEIGHT 10
#define DISPLACER_DEFAULT_GIVE 80
#define DISPLACER_RANDOM_GIVE RANDOM_LONG( 40, 100 )
#define DBALL_DMG 100
#define DBALL_RADIUS 400
//hornetgun settings (weapon_hornetgun)
#define HORNETGUN_WEIGHT 10
#define HIVEHAND_DEFAULT_GIVE 8
//Handgrenade settings (weapon_handgrenade)
#define HANDGRENADE_WEIGHT 5
#define HANDGRENADE_DMG 100
#define HANDGRENADE_DEFAULT_GIVE 1
//=========================
// AMMO SETTINGS
//=========================
//max capacity
#define _9MM_MAX_CARRY 250
#define URANIUM_MAX_CARRY 100
#define BUCKSHOT_MAX_CARRY 125
#define BOLT_MAX_CARRY 50
#define ROCKET_MAX_CARRY 3
#define HANDGRENADE_MAX_CARRY 10
#define HORNET_MAX_CARRY 8
#define M203_GRENADE_MAX_CARRY 10
//ammo default give
#define AMMO_URANIUMBOX_GIVE 20
#define AMMO_GLOCKCLIP_GIVE GLOCK_MAX_CLIP
#define AMMO_357BOX_GIVE 6
#define AMMO_MP5CLIP_GIVE MP5_MAX_CLIP
#define AMMO_CHAINBOX_GIVE 200
#define AMMO_M203BOX_GIVE 2
#define AMMO_BUCKSHOTBOX_GIVE 12
#define AMMO_CROSSBOWCLIP_GIVE CROSSBOW_MAX_CLIP
#define AMMO_URANIUMBOX_GIVE 20
//=========================
// TIME TO RESPAWN
//=========================
#define RESPAWN_TIME_30SEC 30
#define RESPAWN_TIME_60SEC 60
#define RESPAWN_TIME_120SEC 120
#define RND_RESPAWN_TIME_30 RANDOM_FLOAT( 15, 45 )
#define RND_RESPAWN_TIME_60 RANDOM_FLOAT( 45, 80 )
#define RND_RESPAWN_TIME_120 RANDOM_FLOAT( 80, 145 )
//=========================
// BATTERY AND HEALTHKIT CAPACITY
//=========================
#define BATTERY_CHARGE 15
#define MAX_NORMAL_BATTERY 100
//=========================
// MONSTERS HEALTH
//=========================
//agrunt settings
#define AGRUNT_DMG_PUNCH 10
#define AGRUNT_HEALTH 100
//apache
#define APACHE_HEALTH 300
//barney
#define BARNEY_HEALTH 50
#define DEAD_BARNEY_HEALTH 8
// HEALTH/SUIT CHARGE DISTRIBUTION
#define SUIT_CHARGER_CAP 75
#define HEATH_CHARGER_CAP 50
#define MEDKIT_CAP 20
#define BOLT_DMG 40
#define M203_DMG 100
#define BULLSQUID_HEALTH 40
#define HGRUNT_GRENADE_SPEED 400
#define HGRUNT_SHOTGUN_PELLETS 5
#define HGRUNT_DMG_KICK 5
#define HGRUNT_HEALTH 70
#define HASSASSIN_HEALTH 50
#define LEECH_HEALTH 2
#define LEECH_DMG_BITE 2
//headcrab
#define HEADCRAB_HEALTH 10
#define HEADCRAB_DMG_BITE 10
//scientist
#define SCIENTIST_HEALTH 20
#define SCIENTIST_HEAL 25
//turret
#define TURRET_HEALTH 60
#define MINITURRET_HEALTH 40
#define SENTRY_HEALTH 50
//zombie
#define ZOMBIE_HEALTH 75
#define ZOMBIE_ONE_SLASH 15
#define ZOMBIE_BOTH_SLASH 40
//hitgroup setttings
#define DMG_HEAD 3
#define DMG_CHEST 1
#define DMG_STOMACH 1
#define DMG_ARM 1
#define DMG_LEG 1
//bullets damage
#define _9MM_DMG 10
#define _MP5_DMG 5
#define _12MM_DMG 20
#define _357_DMG 40
#define _556_DMG 30
#define _762_DMG 50
#define BUCKSHOT_DMG 15
//bullet vector cone
#define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 )
#define VECTOR_CONE_2DEGREES Vector( 0.01745, 0.01745, 0.01745 )
#define VECTOR_CONE_3DEGREES Vector( 0.02618, 0.02618, 0.02618 )
#define VECTOR_CONE_4DEGREES Vector( 0.03490, 0.03490, 0.03490 )
#define VECTOR_CONE_5DEGREES Vector( 0.04362, 0.04362, 0.04362 )
#define VECTOR_CONE_6DEGREES Vector( 0.05234, 0.05234, 0.05234 )
#define VECTOR_CONE_7DEGREES Vector( 0.06105, 0.06105, 0.06105 )
#define VECTOR_CONE_8DEGREES Vector( 0.06976, 0.06976, 0.06976 )
#define VECTOR_CONE_9DEGREES Vector( 0.07846, 0.07846, 0.07846 )
#define VECTOR_CONE_10DEGREES Vector( 0.08716, 0.08716, 0.08716 )
#define VECTOR_CONE_15DEGREES Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 )
#define VECTOR_CONE_0DEGREES Vector( 0.00000, 0.00000, 0.00000 )
#endif//DEFAULT_H

View File

@ -1,510 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2005
// dll_int.cpp - dll entry points
//=======================================================================
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "saverestore.h"
#include "client.h"
#include "decals.h"
#include "gamerules.h"
#include "game.h"
#include "defaults.h"
#include "baseitem.h"
#include "baseweapon.h"
void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd );
BOOL gTouchDisabled = FALSE;
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
// Main DLL entry point
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return TRUE;
}
void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
{
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
gpGlobals = pGlobals;
}
static DLL_FUNCTIONS gFunctionTable =
{
GameDLLInit, // pfnGameInit
DispatchSpawn, // pfnSpawn
DispatchThink, // pfnThink
DispatchUse, // pfnUse
DispatchTouch, // pfnTouch
DispatchBlocked, // pfnBlocked
DispatchKeyValue, // pfnKeyValue
DispatchSave, // pfnSave
DispatchRestore, // pfnRestore
DispatchObjectCollsionBox, // pfnAbsBox
SaveWriteFields, // pfnSaveWriteFields
SaveReadFields, // pfnSaveReadFields
SaveGlobalState, // pfnSaveGlobalState
RestoreGlobalState, // pfnRestoreGlobalState
ResetGlobalState, // pfnResetGlobalState
ClientConnect, // pfnClientConnect
ClientDisconnect, // pfnClientDisconnect
ClientKill, // pfnClientKill
ClientPutInServer, // pfnClientPutInServer
ClientCommand, // pfnClientCommand
ClientUserInfoChanged, // pfnClientUserInfoChanged
ServerActivate, // pfnServerActivate
ServerDeactivate, // pfnServerDeactivate
PlayerPreThink, // pfnPlayerPreThink
PlayerPostThink, // pfnPlayerPostThink
StartFrame, // pfnStartFrame
DispatchCreate, // pfnCreate
BuildLevelList, // pfnParmsChangeLevel
GetGameDescription, //pfnGetGameDescription Returns string describing current .dll game.
DispatchFrame, // pfnPhysicsEntity
SpectatorConnect, // pfnSpectatorConnect
SpectatorDisconnect, // pfnSpectatorDisconnect
SpectatorThink, // pfnSpectatorThink
ServerClassifyEdict, // pfnClassifyEdict
PM_Move, // pfnPM_Move
PM_Init, // pfnPM_Init
PM_FindTextureType, // pfnPM_FindTextureType
SetupVisibility, // pfnSetupVisibility
UpdateClientData, // pfnUpdateClientData
AddToFullPack, // pfnAddtoFullPack
CreateBaseline, // fpnCreateBaseline
RegisterEncoders, // pfnRegisterEncoders Callbacks for network encoding
GetWeaponData, // pfnGetWeaponData
CmdStart, // pfnCmdStart
CmdEnd, // pfnCmdEnd
OnFreeEntPrivateData, // pfnOnFreeEntPrivateData
GameDLLShutdown, // pfnGameShutdown
ShouldCollide, // pfnShouldCollide
};
//=======================================================================
// General API entering point
//=======================================================================
int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion )
{
if ( !pFunctionTable || interfaceVersion != SV_INTERFACE_VERSION )
{
return FALSE;
}
memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) );
return TRUE;
}
//=======================================================================
// dispatch functions
//=======================================================================
int DispatchSpawn( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if( pEntity )
{
// Initialize these or entities who don't link to the world won't have anything in here
pEntity->pev->absmin = pEntity->pev->origin - Vector( 1.0f, 1.0f, 1.0f );
pEntity->pev->absmax = pEntity->pev->origin + Vector( 1.0f, 1.0f, 1.0f );
pEntity->Spawn();
pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if ( pEntity )
{
pEntity->pev->colormap = ENTINDEX(pent);
if ( g_pGameRules && !g_pGameRules->IsAllowedToSpawn( pEntity ) )
return -1; // return that this entity should be deleted
if ( pEntity->pev->flags & FL_KILLME )
return -1;
}
// Handle global stuff here
if ( pEntity && pEntity->pev->globalname )
{
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname );
if ( pGlobal )
{
// Already dead? delete
if ( pGlobal->state == GLOBAL_DEAD ) return -1;
else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) )
pEntity->MakeDormant();// Hasn't been moved to this level yet, wait but stay alive
// In this level & not dead, continue on as normal
}
else gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON );
}
}
return 0;
}
int DispatchCreate( edict_t *pent, const char *szName )
{
if( FNullEnt( pent ) || FStringNull( szName ))
return -1;
int istr = ALLOC_STRING( szName );
// handle virtual entities here
if( !strncmp( szName, "weapon_", 7 ))
{
CBasePlayerWeapon *pWeapon = GetClassPtr((CBasePlayerWeapon *)VARS( pent ));
if( !pWeapon ) return -1;
pWeapon->pev->netname = istr;
return 0;
}
else if( !strncmp( szName, "item_", 5 ) || !strncmp( szName, "ammo_", 5 ))
{
CItem *pItem = GetClassPtr((CItem *)VARS( pent ));
if( !pItem ) return -1;
pItem->pev->netname = istr;
return 0;
}
return -1;
}
void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd )
{
if ( !pkvd || !pentKeyvalue )return;
EntvarsKeyvalue( VARS(pentKeyvalue), pkvd );
// if the key was an entity variable, or there's no class set yet,
// don't look for the object, it may not exist yet.
if( pkvd->fHandled || pkvd->szClassName == NULL )
return;
// Get the actualy entity object
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentKeyvalue);
if( !pEntity ) return;
pEntity->KeyValue( pkvd );
}
/*
-----------------
DispatchFrame
this function can override any physics movement
and let user use custom physic.
e.g. you can replace MOVETYPE_PUSH for new movewith system
and many many other things.
-----------------
*/
int DispatchFrame( edict_t *pent )
{
return 0;
}
void DispatchTouch( edict_t *pentTouched, edict_t *pentOther )
{
if ( gTouchDisabled ) return;
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther );
if ( pEntity && pOther && ! ((pEntity->pev->flags | pOther->pev->flags) & FL_KILLME) )
pEntity->Touch( pOther );
}
void DispatchUse( edict_t *pentUsed, edict_t *pentOther )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
if( pEntity && !( pEntity->pev->flags & FL_KILLME ))
pEntity->Use( pOther, pOther, USE_TOGGLE, 0 );
}
void DispatchThink( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if( pEntity )
{
if( FBitSet( pEntity->pev->flags, FL_DORMANT ))
ALERT( at_error, "Dormant entity %s is thinking!\n", STRING( pEntity->pev->classname ));
pEntity->Think();
}
}
void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE( pentBlocked );
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther );
if( pEntity ) pEntity->Blocked( pOther );
}
void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if( pEntity && pSaveData )
{
// ALERT( at_console, "DispatchSave( %s, %i )\n", STRING( pent->v.classname ), pent->serialnumber );
ENTITYTABLE *pTable = &pSaveData->pTable[ pSaveData->currentIndex ];
if( pTable->pent != pent )
ALERT( at_error, "ENTITY TABLE OR INDEX IS WRONG!!!!\n" );
if( pEntity->ObjectCaps() & FCAP_DONT_SAVE ) return;
// These don't use ltime & nextthink as times really, but we'll fudge around it.
if( pEntity->pev->movetype == MOVETYPE_PUSH )
{
float delta = gpGlobals->time - pEntity->pev->ltime;
pEntity->pev->ltime += delta;
pEntity->pev->nextthink += delta;
pEntity->m_fPevNextThink = pEntity->pev->nextthink;
pEntity->m_fNextThink += delta;
}
if( gpGlobals->changelevel )
pEntity->ClearPointers();
pTable->location = pSaveData->size; // Remember entity position for file I/O
pTable->classname = pEntity->pev->classname; // Remember entity class for respawn
CSave saveHelper( pSaveData );
pEntity->Save( saveHelper );
pTable->size = pSaveData->size - pTable->location;// Size of entity block is data size written to block
}
}
int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if( pEntity && pSaveData )
{
entvars_t tmpVars;
Vector oldOffset;
// ALERT( at_console, "DispatchRestore( %s )\n", STRING( pent->v.classname ));
CRestore restoreHelper( pSaveData );
if ( globalEntity )
{
CRestore tmpRestore( pSaveData );
tmpRestore.PrecacheMode( 0 );
tmpRestore.ReadEntVars( "ENTVARS", &tmpVars );
pSaveData->size = pSaveData->pTable[pSaveData->currentIndex].location;
pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size;
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( tmpVars.globalname );
// Don't overlay any instance of the global that isn't the latest
// pSaveData->szCurrentMapName is the level this entity is coming from
// pGlobla->levelName is the last level the global entity was active in.
// If they aren't the same, then this global update is out of date.
if ( !FStrEq( pSaveData->szCurrentMapName, pGlobal->levelName )) return 0;
// Compute the new global offset
oldOffset = pSaveData->vecLandmarkOffset;
CBaseEntity *pNewEntity = UTIL_FindGlobalEntity( tmpVars.classname, tmpVars.globalname );
if ( pNewEntity )
{
// Tell the restore code we're overlaying a global entity from another level
restoreHelper.SetGlobalMode( 1 ); // Don't overwrite global fields
pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins;
pEntity = pNewEntity;// we're going to restore this data OVER the old entity
pent = ENT( pEntity->pev );
// Update the global table to say that the global definition of this entity should come from this level
gGlobalState.EntityUpdate( pEntity->pev->globalname, gpGlobals->mapname );
}
else
{
// This entity will be freed automatically by the engine. If we don't do a restore on a matching entity (below)
// or call EntityUpdate() to move it to this level, we haven't changed global state at all.
return 0;
}
}
if ( pEntity->ObjectCaps() & FCAP_MUST_SPAWN )
{
pEntity->Restore( restoreHelper );
pEntity->Spawn();
}
else
{
pEntity->Restore( restoreHelper );
pEntity->Precache( );
}
// Again, could be deleted, get the pointer again.
pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity )pEntity->pev->colormap = ENTINDEX(pent);
// Is this an overriding global entity (coming over the transition), or one restoring in a level
if ( globalEntity )
{
pSaveData->vecLandmarkOffset = oldOffset;
if ( pEntity )
{
pEntity->RestorePhysics();
UTIL_SetOrigin( pEntity, pEntity->pev->origin );
pEntity->OverrideReset();
}
}
else if ( pEntity && pEntity->pev->globalname )
{
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname );
if ( pGlobal )
{
// Already dead? delete
if ( pGlobal->state == GLOBAL_DEAD ) return -1;
else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) )
{
pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive
}
// In this level & not dead, continue on as normal
}
else
{
ALERT( at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname) );
// Spawned entities default to 'On'
gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON );
}
}
}
return 0;
}
void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount )
{
CSave saveHelper( pSaveData );
saveHelper.WriteFields( "SWF", pname, pBaseData, pFields, fieldCount );
}
void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount )
{
CRestore restoreHelper( pSaveData );
restoreHelper.ReadFields( pname, pBaseData, pFields, fieldCount );
}
void OnFreeEntPrivateData( edict_s *pEdict )
{
if( pEdict && pEdict->pvPrivateData )
{
((CBaseEntity*)pEdict->pvPrivateData)->~CBaseEntity();
}
}
void SetObjectCollisionBox( entvars_t *pev )
{
if (( pev->solid == SOLID_BSP ) && ( pev->angles != g_vecZero ))
{
// expand for rotation
float max = 0, v;
int i;
for ( i = 0; i < 3; i++ )
{
v = fabs( pev->mins[i] );
if ( v > max ) max = v;
v = fabs( pev->maxs[i] );
if ( v > max ) max = v;
}
for ( i = 0; i < 3; i++ )
{
pev->absmin[i] = pev->origin[i] - max;
pev->absmax[i] = pev->origin[i] + max;
}
}
else
{
pev->absmin = pev->origin + pev->mins;
pev->absmax = pev->origin + pev->maxs;
}
pev->absmin.x -= 1;
pev->absmin.y -= 1;
pev->absmin.z -= 1;
pev->absmax.x += 1;
pev->absmax.y += 1;
pev->absmax.z += 1;
}
void DispatchObjectCollsionBox( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if( pEntity ) pEntity->SetObjectCollisionBox();
else SetObjectCollisionBox( &pent->v );
}
//=======================================================================
// ehandle operations
//=======================================================================
edict_t * EHANDLE::Get( void )
{
if (m_pent)
{
if (m_pent->serialnumber == m_serialnumber) return m_pent;
else return NULL;
}
return NULL;
};
edict_t *EHANDLE::Set( edict_t *pent )
{
m_pent = pent;
if (pent) m_serialnumber = m_pent->serialnumber;
return pent;
};
EHANDLE :: operator CBaseEntity *()
{
return (CBaseEntity *)GET_PRIVATE(Get());
};
CBaseEntity *EHANDLE :: operator = (CBaseEntity *pEntity)
{
if (pEntity)
{
m_pent = ENT( pEntity->pev );
if (m_pent)m_serialnumber = m_pent->serialnumber;
}
else
{
m_pent = NULL;
m_serialnumber = 0;
}
return pEntity;
}
EHANDLE :: operator int()
{
return Get() != NULL;
}
CBaseEntity *EHANDLE :: operator->()
{
return (CBaseEntity *)GET_PRIVATE(Get());
}

View File

@ -1,164 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef ENGINECALLBACK_H
#define ENGINECALLBACK_H
// Must be provided by user of this code
extern enginefuncs_t g_engfuncs;
// The actual engine callbacks
#define MALLOC( x ) (*g_engfuncs.pfnMemAlloc)( x, __FILE__, __LINE__ )
#define CALLOC( x, y ) (*g_engfuncs.pfnMemAlloc)((x) * (y), __FILE__, __LINE__ )
#define FREE( x ) (*g_engfuncs.pfnMemFree)( x, __FILE__, __LINE__ )
#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId)
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound)
#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric)
#define SET_MODEL (*g_engfuncs.pfnSetModel)
#define MODEL_INDEX (*g_engfuncs.pfnModelIndex)
#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames)
#define SET_SIZE (*g_engfuncs.pfnSetSize)
#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel)
#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms)
#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms)
#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw)
#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles)
#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin)
#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw)
#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch)
#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors)
#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity)
#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity)
#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity)
#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic)
#define LINK_ENTITY (*g_engfuncs.pfnLinkEdict)
#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor)
#define WALK_MOVE (*g_engfuncs.pfnWalkMove)
#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin)
#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound)
#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg)
#define TRACE_LINE (*g_engfuncs.pfnTraceLine)
#define TRACE_TOSS (*g_engfuncs.pfnTraceToss)
#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull)
#define TRACE_HULL (*g_engfuncs.pfnTraceHull)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)
#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex)
#define POINT_CONTENTS (*g_engfuncs.pfnPointContents)
#define CRC32_INIT (*g_engfuncs.pfnCRC_Init)
#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC_ProcessBuffer)
#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC_ProcessByte)
#define CRC32_FINAL (*g_engfuncs.pfnCRC_Final)
#define RANDOM_LONG (*g_engfuncs.pfnRandomLong)
#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat)
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#define CLASSIFY_EDICT (*g_engfuncs.pfnClassifyEdict)
#define COM_Parse (*g_engfuncs.pfnParseToken)
inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL )
{
(*g_engfuncs.pfnMessageBegin)( msg_dest, msg_type, pOrigin, ed );
}
#define MESSAGE_END (*g_engfuncs.pfnMessageEnd)
#define WRITE_BYTE (*g_engfuncs.pfnWriteByte)
#define WRITE_CHAR (*g_engfuncs.pfnWriteChar)
#define WRITE_SHORT (*g_engfuncs.pfnWriteShort)
#define WRITE_LONG (*g_engfuncs.pfnWriteLong)
#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle)
#define WRITE_COORD (*g_engfuncs.pfnWriteCoord)
inline void WRITE_FLOAT( float flValue )
{
union { float f; int l; } dat;
dat.f = flValue;
WRITE_LONG( dat.l );
}
#define WRITE_STRING (*g_engfuncs.pfnWriteString)
#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity)
#define WRITE_DIR( dir ) WRITE_BYTE(DirToBits( dir ))
#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister)
#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat)
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat)
#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString)
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)
inline void *GET_PRIVATE( edict_t *pent )
{
if ( pent )
return pent->pvPrivateData;
return NULL;
}
// NOTE: Xash3D using custom StringTable System that using safety methods for access to strings
// and never make duplicated strings, so it make no differences between ALLOC_STRING and MAKE_STRING
// leave macros as legacy
#define ALLOC_STRING (*g_engfuncs.pfnAllocString)
#define MAKE_STRING (*g_engfuncs.pfnAllocString)
#define STRING (*g_engfuncs.pfnSzFromIndex)
#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData)
#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString)
#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum)
#define FIND_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere)
#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS)
#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound)
#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr)
#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg)
#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition)
#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName)
#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction)
#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture)
#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf)
#define CMD_ARGS (*g_engfuncs.pfnCmd_Args)
#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc)
#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv)
#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment)
#define SET_VIEW (*g_engfuncs.pfnSetView)
#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle)
#define LOAD_FILE (*g_engfuncs.pfnLoadFile)
#define FILE_EXISTS (*g_engfuncs.pfnFileExists)
#define FREE_FILE (*g_engfuncs.pfnFreeFile)
#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer)
#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent)
#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent)
#define SET_BONE_POSITION (*g_engfuncs.pfnSetBonePos)
#define DROP_CLIENT (*g_engfuncs.pfnDropClient)
#define ENGINE_CHECK_PVS (*g_engfuncs.pfnCheckVisibility)
#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS)
#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS)
#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid)
#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer)
#define DELTA_SET (*g_engfuncs.pfnDeltaSetField)
#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField)
#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder)
#define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer)
#define HOST_ERROR (*g_engfuncs.pfnHostError)
#define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString)
#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField)
#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex)
#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex)
#define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask)
#define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats)
#endif //ENGINECALLBACK_H

View File

@ -1,57 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2005
// extdll.h - global defines for dll's
//
//=======================================================================
#ifndef EXTDLL_H
#define EXTDLL_H
// Silence certain warnings
#pragma warning(disable : 4305) // int or float data truncation
#pragma warning(disable : 4201) // nameless struct/union
#pragma warning(disable : 4514) // unreferenced inline function removed
#pragma warning(disable : 4100) // unreferenced formal parameter
#include "windows.h"
#include "basetypes.h"
#define FALSE 0
#define TRUE 1
typedef unsigned long ULONG;
#include <limits.h>
#include <stdarg.h>
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
// misc C-runtime library headers
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// Shared engine/DLL constants
#include "const.h"
#include "game_shared.h"
// Vector class
#include "vector.h"
// Shared header describing protocol between engine and DLLs
#include "entity_def.h"
#include "svgame_api.h"
extern Vector vec3_origin;
extern Vector vec3_angles;
#endif // EXTDLL_H

View File

@ -1,84 +0,0 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. 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
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
/*
===== globals.cpp ========================================================
DLL-wide global variable definitions.
They're all defined here, for convenient centralization.
Source files that need them should "extern ..." declare each
variable, to better document what globals they care about.
*/
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "baseweapon.h"
#include "soundent.h"
DLL_GLOBAL unsigned short m_usPlayEmptySound;
DLL_GLOBAL unsigned short m_usEjectBrass;
DLL_GLOBAL unsigned short m_usPlayTexSound;
DLL_GLOBAL ULONG g_ulFrameCount;
DLL_GLOBAL ULONG g_ulModelIndexEyes;
DLL_GLOBAL ULONG g_ulModelIndexPlayer;
DLL_GLOBAL Vector g_vecAttackDir;
DLL_GLOBAL int g_iSkillLevel;
DLL_GLOBAL int gDisplayTitle;
DLL_GLOBAL BOOL g_fGameOver;
DLL_GLOBAL BOOL g_startSuit;
DLL_GLOBAL const Vector g_vecZero = Vector(0,0,0);
DLL_GLOBAL int g_Language;
DLL_GLOBAL short g_sModelIndexLaser;
DLL_GLOBAL int g_sModelIndexLaserDot;
DLL_GLOBAL short g_sModelIndexFireball;
DLL_GLOBAL short g_sModelIndexSmoke;
DLL_GLOBAL short g_sModelIndexWExplosion;
DLL_GLOBAL short g_sModelIndexBubbles;
DLL_GLOBAL short g_sModelIndexBloodDrop;
DLL_GLOBAL short g_sModelIndexBloodSpray;
DLL_GLOBAL int g_sModelIndexErrorSprite;
DLL_GLOBAL int g_sModelIndexErrorModel;
DLL_GLOBAL int g_sModelIndexNullModel;
DLL_GLOBAL int g_sModelIndexNullSprite;
int GetStdLightStyle (int iStyle)
{
switch (iStyle)
{
case 0: return MAKE_STRING("m"); // 0 normal
case 1: return MAKE_STRING("mmnmmommommnonmmonqnmmo"); // 1 FLICKER (first variety)
case 2: return MAKE_STRING("abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); // 2 SLOW STRONG PULSE
case 3: return MAKE_STRING("mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); // 3 CANDLE (first variety)
case 4: return MAKE_STRING("mamamamamama"); // 4 FAST STROBE
case 5: return MAKE_STRING("jklmnopqrstuvwxyzyxwvutsrqponmlkj"); // 5 GENTLE PULSE 1
case 6: return MAKE_STRING("nmonqnmomnmomomno"); // 6 FLICKER (second variety)
case 7: return MAKE_STRING("mmmaaaabcdefgmmmmaaaammmaamm"); // 7 CANDLE (second variety)
case 8: return MAKE_STRING("mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); // 8 CANDLE (third variety)
case 9: return MAKE_STRING("aaaaaaaazzzzzzzz"); // 9 SLOW STROBE (fourth variety)
case 10: return MAKE_STRING("mmamammmmammamamaaamammma"); // 10 FLUORESCENT FLICKER
case 11: return MAKE_STRING("abcdefghijklmnopqrrqponmlkjihgfedcba"); // 11 SLOW PULSE NOT FADE TO BLACK
case 12: return MAKE_STRING("mmnnmmnnnmmnn"); // 12 UNDERWATER LIGHT MUTATION
case 13: return MAKE_STRING("a"); // 13 OFF
case 14: return MAKE_STRING("aabbccddeeffgghhiijjkkllmmmmmmmmmmmmmm"); // 14 SLOW FADE IN
case 15: return MAKE_STRING("abcdefghijklmmmmmmmmmmmmmmmmmmmmmmmmmm"); // 15 MED FADE IN
case 16: return MAKE_STRING("acegikmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"); // 16 FAST FADE IN
case 17: return MAKE_STRING("llkkjjiihhggffeeddccbbaaaaaaaaaaaaaaaa"); // 17 SLOW FADE OUT
case 18: return MAKE_STRING("lkjihgfedcbaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // 18 MED FADE OUT
case 19: return MAKE_STRING("kigecaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // 19 FAST FADE OUT
default: return MAKE_STRING("m");
}
}

View File

@ -1,107 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2004
// globals.h - store global variables,
//=======================================================================
#ifndef GLOBALS_H
#define GLOBALS_H
extern DLL_GLOBAL short g_sModelIndexLaser;// holds the index for the laser beam
extern DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball
extern DLL_GLOBAL short g_sModelIndexSmoke;// holds the index for the smoke cloud
extern DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater explosion
extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model
extern DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for blood drops
extern DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for blood spray (bigger)
extern DLL_GLOBAL int g_sModelIndexLaserDot;
extern DLL_GLOBAL unsigned short m_usPlayEmptySound;
extern DLL_GLOBAL unsigned short m_usEjectBrass;
extern DLL_GLOBAL unsigned short m_usPlayTexSound;
extern DLL_GLOBAL ULONG g_ulFrameCount;
extern DLL_GLOBAL BOOL g_fGameOver;
extern DLL_GLOBAL BOOL g_startSuit;
// C functions for external declarations that call the appropriate C++ methods
#ifdef _WIN32
#define EXPORT _declspec( dllexport )
#else
#define EXPORT /* */
#endif
extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
extern int DispatchSpawn( edict_t *pent );
extern int DispatchCreate( edict_t *pent, const char *szName );
extern void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd );
extern void DispatchTouch( edict_t *pentTouched, edict_t *pentOther );
extern void DispatchUse( edict_t *pentUsed, edict_t *pentOther );
extern void DispatchThink( edict_t *pent );
extern int DispatchFrame( edict_t *pent );
extern void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther );
extern void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData );
extern int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity );
extern void DispatchObjectCollsionBox( edict_t *pent );
extern int ServerClassifyEdict( edict_t *pentToClassify );
extern void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount );
extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount );
extern void SaveGlobalState( SAVERESTOREDATA *pSaveData );
extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData );
extern void ResetGlobalState( void );
extern void OnFreeEntPrivateData( edict_s *pEdict );
extern int ShouldCollide( edict_t *pentTouched, edict_t *pentOther );
// spectator funcs
extern void SpectatorConnect( edict_t *pEntity );
extern void SpectatorDisconnect( edict_t *pEntity );
extern void SpectatorThink( edict_t *pEntity );
typedef void (CBaseEntity::*BASEPTR)(void);
typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther );
typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
//
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
//
class EHANDLE
{
private:
edict_t *m_pent;
int m_serialnumber;
public:
edict_t *Get( void );
edict_t *Set( edict_t *pent );
operator int ();
operator CBaseEntity *();
CBaseEntity * operator = (CBaseEntity *pEntity);
CBaseEntity * operator ->();
};
//
// Converts a entvars_t * to a class pointer
// It will allocate the class and entity if necessary
//
template <class T> T * GetClassPtr( T *a )
{
entvars_t *pev = (entvars_t *)a;
// allocate entity if necessary
if (pev == NULL)
pev = VARS(CREATE_ENTITY());
// get the private data
a = (T *)GET_PRIVATE(ENT(pev));
if (a == NULL)
{
// allocate private data
a = new(pev) T;
a->pev = pev;
}
return a;
}
#endif //GLOBALS_H

View File

@ -1,29 +0,0 @@
//=======================================================================
// Copyright (C) Shambler Team 2005
// hierarchy.h - Not real code.
// Map of relationshep between classes.
//=======================================================================
#ifndef HIERARCHY_H
#define HIERARCHY_H
/*
Class Hierachy
CBaseEntity
CPointEntity
CBasePlayerAmmo
CBaseLogic
CBaseAnimating
CBasePlayerWeapon
CBaseToggle
CBaseButton
CBaseDoor
CBaseTrigger
CBasePlatTrain
CBaseMonster
CCycler
CBasePlayer
CCineMonster
*/
#endif //HIERARCHY_H

Some files were not shown because too many files have changed in this diff Show More