09 Jul 2010
This commit is contained in:
parent
9f9228adc4
commit
a9a5a22d06
|
@ -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\
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -46,7 +46,7 @@ CBaseEntity
|
|||
|
||||
#include "saverestore.h"
|
||||
#include "schedule.h"
|
||||
#include "studio_ref.h"
|
||||
#include "studio.h"
|
||||
|
||||
#ifndef MONSTEREVENT_H
|
||||
#include "monsterevent.h"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] );
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
299
public/mathlib.h
299
public/mathlib.h
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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 );
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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 );
|
|
@ -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 );
|
|
@ -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 );
|
|
@ -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;
|
||||
};
|
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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 );
|
|
@ -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
|
|
@ -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 )
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
|
@ -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( );
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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);
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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
|
|
@ -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());
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
Reference in New Issue