21 Mar 2010
This commit is contained in:
parent
c48cdf25e0
commit
7f005e320a
|
@ -165,7 +165,7 @@ void TE_ParseExplosion( void )
|
|||
char szDecal[32];
|
||||
|
||||
sprintf( szDecal, "{scorch%i", RANDOM_LONG( 1, 3 ));
|
||||
g_pTempEnts->PlaceDecal( pos2, 48.0f, szDecal );
|
||||
g_pTempEnts->PlaceDecal( pos, 48.0f, szDecal );
|
||||
|
||||
if( !( flags & TE_EXPLFLAG_NOSOUND ))
|
||||
{
|
||||
|
|
|
@ -316,12 +316,9 @@ void CParticleSystem :: Clear( void )
|
|||
m_pParticles[MAX_PARTICLES-1].next = NULL;
|
||||
|
||||
// loading TE shaders
|
||||
m_hDefaultParticle = TEX_Load( "textures/particles/default" );
|
||||
m_hGlowParticle = TEX_Load( "textures/particles/glow" );
|
||||
m_hDroplet = TEX_Load( "textures/particles/droplet" );
|
||||
m_hBubble = TEX_Load( "textures/particles/bubble" );
|
||||
m_hSparks = TEX_Load( "textures/particles/spark" );
|
||||
m_hSmoke = TEX_Load( "textures/particles/smoke" );
|
||||
m_hDefaultParticle = TEX_Load( "$defaultParticle" );
|
||||
m_hSparks = TEX_Load( "gfx/hud/spark" );
|
||||
m_hSmoke = TEX_Load( "gfx/hud/smoke" );
|
||||
}
|
||||
|
||||
void CParticleSystem :: FreeParticle( CParticle *pCur )
|
||||
|
@ -492,41 +489,6 @@ void CParticleSystem :: ExplosionParticles( const Vector pos )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_BubbleParticles
|
||||
=================
|
||||
*/
|
||||
void CParticleSystem :: BubbleParticles( const Vector org, int count, float magnitude )
|
||||
{
|
||||
CParticle src;
|
||||
|
||||
if( !cl_particles->integer ) return;
|
||||
|
||||
for( int i = 0; i < count; i++ )
|
||||
{
|
||||
src.origin.x = org[0] + RANDOM_FLOAT( -magnitude, magnitude );
|
||||
src.origin.y = org[1] + RANDOM_FLOAT( -magnitude, magnitude );
|
||||
src.origin.z = org[2] + RANDOM_FLOAT( -magnitude, magnitude );
|
||||
src.velocity.x = RANDOM_FLOAT( -5, 5 );
|
||||
src.velocity.y = RANDOM_FLOAT( -5, 5 );
|
||||
src.velocity.z = RANDOM_FLOAT( -5, 5 ) + (25 + RANDOM_FLOAT( -5, 5 ));
|
||||
src.accel = Vector( 0, 0, 0 );
|
||||
src.color = Vector( 1, 1, 1 );
|
||||
src.colorVelocity = Vector( 0, 0, 0 );
|
||||
src.alpha = 1.0;
|
||||
src.alphaVelocity = -(0.4 + RANDOM_FLOAT( 0, 0.2 ));
|
||||
src.radius = 1 + RANDOM_FLOAT( -0.5, 0.5 );
|
||||
src.radiusVelocity = 0;
|
||||
src.length = 1;
|
||||
src.lengthVelocity = 0;
|
||||
src.rotation = 0;
|
||||
|
||||
if( !AddParticle( &src, m_hBubble, FPART_UNDERWATER ))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_BulletParticles
|
||||
|
@ -656,10 +618,7 @@ void CParticleSystem :: BulletParticles( const Vector org, const Vector dir )
|
|||
cnt = POINT_CONTENTS( org );
|
||||
|
||||
if( cnt == CONTENTS_WATER )
|
||||
{
|
||||
BubbleParticles( org, count, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
// sparks
|
||||
int flags = (FPART_STRETCH|FPART_BOUNCE|FPART_FRICTION);
|
||||
|
|
|
@ -53,9 +53,6 @@ class CParticleSystem
|
|||
|
||||
// private partsystem shaders
|
||||
HSPRITE m_hDefaultParticle;
|
||||
HSPRITE m_hGlowParticle;
|
||||
HSPRITE m_hDroplet;
|
||||
HSPRITE m_hBubble;
|
||||
HSPRITE m_hSparks;
|
||||
HSPRITE m_hSmoke;
|
||||
public:
|
||||
|
|
|
@ -553,12 +553,11 @@ void DrawScreenFade( void )
|
|||
numFades++;
|
||||
}
|
||||
|
||||
// Divide colors
|
||||
// divide colors
|
||||
if( numFades ) gHUD.m_vecFadeColor /= numFades;
|
||||
else return;
|
||||
|
||||
if( gHUD.m_vecFadeColor == Vector( 0, 0, 0 )) return;
|
||||
const float *RGB = gHUD.m_vecFadeColor;
|
||||
|
||||
FillRGBA( 0, 0, ScreenWidth, ScreenHeight, RGB[0], RGB[1], RGB[2], gHUD.m_flFadeAlpha );
|
||||
}
|
||||
|
||||
|
|
|
@ -94,8 +94,6 @@ typedef struct dllfunction_s
|
|||
#define XRES(x) ((int)(float(x) * ((float)ScreenWidth / 640.0f) + 0.5f))
|
||||
#define YRES(y) ((int)(float(y) * ((float)ScreenHeight / 480.0f) + 0.5f))
|
||||
|
||||
#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
|
||||
// ScreenHeight returns the virtual height of the screen, in pixels
|
||||
#define ScreenHeight (gHUD.m_scrinfo.iHeight)
|
||||
// ScreenWidth returns the virtual width of the screen, in pixels
|
||||
|
|
|
@ -48,6 +48,7 @@ cvar_t *scr_ofsy;
|
|||
cvar_t *scr_ofsz;
|
||||
cvar_t *cl_vsmoothing;
|
||||
cvar_t *cl_stairsmooth;
|
||||
cvar_t *cl_weaponlag;
|
||||
|
||||
cvar_t *cl_bobcycle;
|
||||
cvar_t *cl_bob;
|
||||
|
@ -140,6 +141,7 @@ void V_Init( void )
|
|||
v_iroll_level = g_engfuncs.pfnRegisterVariable( "v_iroll_level", "0.1", 0, "viewing inverse roll level" );
|
||||
v_ipitch_level = g_engfuncs.pfnRegisterVariable( "v_iyaw_level", "0.3", 0, "viewing inverse pitch level" );
|
||||
|
||||
cl_weaponlag = g_engfuncs.pfnRegisterVariable( "v_viewmodel_lag", "0.0", FCVAR_ARCHIVE, "add some lag to viewmodel like in HL2" );
|
||||
cl_bobcycle = g_engfuncs.pfnRegisterVariable( "cl_bobcycle","0.8", 0, "bob full cycle" );
|
||||
cl_bob = g_engfuncs.pfnRegisterVariable( "cl_bob", "0.01", 0, "bob value" );
|
||||
cl_bobup = g_engfuncs.pfnRegisterVariable( "cl_bobup", "0.5", 0, "bob upper limit" );
|
||||
|
@ -263,6 +265,70 @@ void V_DropPunchAngle( float frametime, Vector &ev_punchangle )
|
|||
ev_punchangle *= len;
|
||||
}
|
||||
|
||||
void V_CalcViewModelLag( Vector& origin, Vector& angles, Vector& original_angles )
|
||||
{
|
||||
static Vector m_vecLastFacing;
|
||||
Vector vOriginalOrigin = origin;
|
||||
Vector vOriginalAngles = angles;
|
||||
|
||||
// Calculate our drift
|
||||
Vector forward;
|
||||
AngleVectors( angles, forward, NULL, NULL );
|
||||
|
||||
if ( gpGlobals->frametime != 0.0f )
|
||||
{
|
||||
Vector vDifference;
|
||||
|
||||
vDifference = forward - m_vecLastFacing;
|
||||
|
||||
float flSpeed = 5.0f;
|
||||
|
||||
// If we start to lag too far behind, we'll increase the "catch up" speed.
|
||||
// Solves the problem with fast cl_yawspeed, m_yaw or joysticks rotating quickly.
|
||||
// The old code would slam lastfacing with origin causing the viewmodel to pop to a new position
|
||||
float flDiff = vDifference.Length();
|
||||
if (( flDiff > cl_weaponlag->value ) && ( cl_weaponlag->value > 0.0f ))
|
||||
{
|
||||
float flScale = flDiff / cl_weaponlag->value;
|
||||
flSpeed *= flScale;
|
||||
}
|
||||
|
||||
// FIXME: Needs to be predictable?
|
||||
m_vecLastFacing = m_vecLastFacing + vDifference * ( flSpeed * gpGlobals->frametime );
|
||||
// Make sure it doesn't grow out of control!!!
|
||||
m_vecLastFacing = m_vecLastFacing.Normalize();
|
||||
origin = origin + (vDifference * -1.0f) * 5.0f;
|
||||
ASSERT( m_vecLastFacing.IsValid() );
|
||||
}
|
||||
|
||||
Vector right, up;
|
||||
AngleVectors( original_angles, forward, right, up );
|
||||
|
||||
float pitch = original_angles[PITCH];
|
||||
|
||||
if ( pitch > 180.0f )
|
||||
{
|
||||
pitch -= 360.0f;
|
||||
}
|
||||
else if ( pitch < -180.0f )
|
||||
{
|
||||
pitch += 360.0f;
|
||||
}
|
||||
|
||||
if ( cl_weaponlag->value <= 0.0f )
|
||||
{
|
||||
origin = vOriginalOrigin;
|
||||
angles = vOriginalAngles;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: These are the old settings that caused too many exposed polys on some models
|
||||
origin = origin + forward * ( -pitch * 0.035f );
|
||||
origin = origin + right * ( -pitch * 0.03f );
|
||||
origin = origin + up * ( -pitch * 0.02f );
|
||||
}
|
||||
}
|
||||
|
||||
//==========================
|
||||
// V_CalcGunAngle
|
||||
//==========================
|
||||
|
@ -900,7 +966,9 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
|
|||
AngleVectors( angles, pparams->forward, pparams->right, pparams->up );
|
||||
V_CalcScrOffset( pparams );
|
||||
|
||||
view->v.angles = pparams->cl_viewangles;
|
||||
Vector lastAngles;
|
||||
|
||||
lastAngles = view->v.angles = pparams->cl_viewangles;
|
||||
V_CalcGunAngle( pparams );
|
||||
|
||||
// use predicted origin as view origin.
|
||||
|
@ -911,7 +979,8 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
|
|||
// Let the viewmodel shake at about 10% of the amplitude
|
||||
V_ApplyShake( view->v.origin, view->v.angles, 0.9 );
|
||||
|
||||
for( i = 0; i < 3; i++ ) view->v.origin[i] += bob * 0.4 * pparams->forward[i];
|
||||
for( i = 0; i < 3; i++ )
|
||||
view->v.origin[i] += bob * 0.4 * pparams->forward[i];
|
||||
view->v.origin[2] += bob;
|
||||
|
||||
view->v.angles[YAW] -= bob * 0.5;
|
||||
|
@ -919,6 +988,9 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
|
|||
view->v.angles[PITCH] -= bob * 0.3;
|
||||
view->v.origin[2] -= 1;
|
||||
|
||||
// add lag
|
||||
V_CalcViewModelLag( view->v.origin, view->v.angles, lastAngles );
|
||||
|
||||
// fudge position around to keep amount of weapon visible
|
||||
// roughly equal with different FOV
|
||||
if( pparams->viewsize == 110 ) view->v.origin[2] += 1;
|
||||
|
|
|
@ -436,7 +436,7 @@ int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
|
|||
|
||||
float fadeTime = READ_FLOAT();
|
||||
float holdTime = READ_FLOAT();
|
||||
int fadeFlags = READ_SHORT();
|
||||
int fadeFlags = READ_BYTE();
|
||||
|
||||
Vector m_FadeColor;
|
||||
|
||||
|
|
|
@ -22,8 +22,9 @@ typedef enum
|
|||
ED_VIEWMODEL, // client or bot viewmodel (for spectating)
|
||||
ED_RIGIDBODY, // simulated physic
|
||||
ED_TRIGGER, // just for sorting on a server
|
||||
ED_PORTAL, // realtime display, portal or mirror brush or model
|
||||
ED_PORTAL, // realtime portal or mirror brush or model
|
||||
ED_SKYPORTAL, // realtime 3D-sky camera
|
||||
ED_SCREEN, // realtime monitor (like portal but without perspective)
|
||||
ED_MAXTYPES,
|
||||
} edtype_t;
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
#pragma warning( disable : 4244 ) // int or float down-conversion
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
#define NUMVERTEXNORMALS 162
|
||||
#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (float)3.14159265358979323846
|
||||
|
|
|
@ -15,7 +15,7 @@ const char *CL_LevelshotType( void )
|
|||
{
|
||||
// reinstall loadformats by magic keyword :)
|
||||
if( !com.stricmp( GI->texmode, "Xash3D" ) || !com.stricmp( GI->texmode, "Xash" ))
|
||||
return "png";
|
||||
return "jpg";
|
||||
else if( !com.stricmp( GI->texmode, "stalker" ) || !com.stricmp( GI->texmode, "S.T.A.L.K.E.R" ))
|
||||
return "dds";
|
||||
else if( !com.stricmp( GI->texmode, "Doom1" ) || !com.stricmp( GI->texmode, "Doom2" ))
|
||||
|
|
|
@ -1080,7 +1080,6 @@ int CL_SpawnDecal( HSPRITE m_hDecal, edict_t *pEnt, const vec3_t pos, int colorI
|
|||
int i, j, numfragments;
|
||||
vec3_t dir, verts[MAX_DECAL_VERTS];
|
||||
fragment_t *fr, fragments[MAX_DECAL_FRAGMENTS];
|
||||
float radius = 32.0f; // search radius
|
||||
rgba_t color;
|
||||
|
||||
// invalid decal
|
||||
|
|
|
@ -639,7 +639,6 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
|
||||
svgame.globals->time = sv.time * 0.001f;
|
||||
ent->pvServerData->s.ed_type = ED_CLIENT; // init edict type
|
||||
ent->free = false;
|
||||
|
||||
if( !sv.changelevel && !sv.loadgame )
|
||||
{
|
||||
|
@ -666,8 +665,6 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
// fisrt entering
|
||||
svgame.dllFuncs.pfnClientPutInServer( ent );
|
||||
|
||||
ent->v.origin[2] -= GI->client_mins[2][2]; // FIXME: make sure off ground
|
||||
|
||||
SV_BaselineForEntity( ent );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -642,7 +642,8 @@ edict_t* SV_AllocPrivateData( edict_t *ent, string_t className )
|
|||
|
||||
ent->v.classname = className;
|
||||
ent->v.pContainingEntity = ent; // re-link
|
||||
|
||||
VectorSet( ent->v.rendercolor, 255, 255, 255 ); // assume default color
|
||||
|
||||
// allocate edict private memory (passed by dlls)
|
||||
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName );
|
||||
if( !SpawnEdict )
|
||||
|
@ -739,12 +740,13 @@ sv_client_t *SV_ClientFromEdict( const edict_t *pEdict, bool spawned_only )
|
|||
if( svs.clients[i].state != cs_spawned )
|
||||
return NULL;
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
if( svs.clients[i].state < cs_connected )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
client = svs.clients + i;
|
||||
|
||||
return client;
|
||||
|
@ -3690,10 +3692,6 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
|
|||
pkvd[i].szClassName = (char *)classname;
|
||||
svgame.dllFuncs.pfnKeyValue( ent, &pkvd[i] );
|
||||
}
|
||||
|
||||
// check for rendercolor
|
||||
if( VectorIsNull( ent->v.rendercolor )) VectorSet( ent->v.rendercolor, 255, 255, 255 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3813,6 +3811,7 @@ void SV_SpawnEntities( const char *mapname, script_t *entities )
|
|||
// setup all clients
|
||||
ent = EDICT_NUM( i + 1 );
|
||||
SV_InitEdict( ent );
|
||||
SV_AllocPrivateData( ent, MAKE_STRING( "player" ));
|
||||
ent->pvServerData->client = svs.clients + i;
|
||||
ent->pvServerData->client->edict = ent;
|
||||
}
|
||||
|
|
|
@ -171,13 +171,13 @@ static const loadformat_t load_quake4[] =
|
|||
// wad files not requires path
|
||||
static const loadformat_t load_hl1[] =
|
||||
{
|
||||
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // hl skyboxes
|
||||
{ "%s%s.%s", "mip", Image_LoadMIP, IL_HINT_HL }, // hl textures from wad or buffer
|
||||
{ "%s%s.%s", "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
|
||||
{ "%s%s.%s", "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
|
||||
{ "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_HL }, // hl menu images (cached.wad etc)
|
||||
{ "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl menu images (cached.wad etc)
|
||||
{ "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // hl skyboxes
|
||||
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio palette
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
|
|
@ -360,7 +360,7 @@ void CBaseBrush::Precache( void )
|
|||
default:
|
||||
if( pev->health > 0 ) // mapmaker forget set material ?
|
||||
{
|
||||
DevMsg("\n======/Xash SmartFiled System/======\n\n");
|
||||
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");
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -44,104 +44,31 @@ STATE CBaseDMStart::GetState( CBaseEntity *pEntity )
|
|||
else return STATE_OFF;
|
||||
}
|
||||
|
||||
class CWallTorch : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Precache( void )
|
||||
{
|
||||
// if sound is missing just reset soundindex
|
||||
pev->impulse = PRECACHE_SOUND( "ambience/fire1.wav" );
|
||||
UTIL_PrecacheModel( "models/props/torch1.mdl" );
|
||||
}
|
||||
void Spawn( void )
|
||||
{
|
||||
Precache ();
|
||||
|
||||
if( !pev->impulse )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
// SetObjectClass( ED_NORMAL );
|
||||
pev->flags |= FL_PHS_FILTER; // allow phs filter instead pvs
|
||||
|
||||
// setup attenuation radius
|
||||
pev->armorvalue = 384.0f * ATTN_STATIC;
|
||||
|
||||
pev->soundindex = pev->impulse;
|
||||
UTIL_SetModel( ENT( pev ), "models/props/torch1.mdl" );
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
||||
SetBits( pev->flags, FL_POINTENTITY );
|
||||
pev->animtime = gpGlobals->time + 0.2; // enable animation
|
||||
pev->framerate = 0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// static infodecal
|
||||
//=========================================================
|
||||
class CDecal : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd )
|
||||
void KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if( FStrEq( pkvd->szKeyName, "texture" ))
|
||||
if (FStrEq(pkvd->szKeyName, "texture"))
|
||||
{
|
||||
pkvd->fHandled = TRUE;
|
||||
pev->skin = DECAL_INDEX( pkvd->szValue );
|
||||
if( pev->skin >= 0 ) return;
|
||||
if ( pev->skin >= 0 ) return;
|
||||
Msg( "Can't find decal %s\n", pkvd->szValue );
|
||||
}
|
||||
}
|
||||
|
||||
void PostSpawn( void )
|
||||
void PostSpawn( void )
|
||||
{
|
||||
if ( FStringNull( pev->targetname ))
|
||||
MakeDecal();
|
||||
}
|
||||
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
MakeDecal();
|
||||
}
|
||||
|
||||
void MakeDecal( void )
|
||||
{
|
||||
if ( pev->skin < 0 )
|
||||
{
|
||||
REMOVE_ENTITY( ENT( pev ));
|
||||
return;
|
||||
}
|
||||
|
||||
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 = VARS( trace.pHit )->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 ) modelIndex = (int)VARS(trace.pHit)->modelindex;
|
||||
else modelIndex = 0;
|
||||
|
||||
if ( FStringNull( pev->targetname ))
|
||||
{
|
||||
g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_BROADCAST, gmsg.TempEntity );
|
||||
WRITE_BYTE( TE_BSPDECAL );
|
||||
WRITE_COORD( pev->origin.x );
|
||||
WRITE_COORD( pev->origin.y );
|
||||
WRITE_COORD( pev->origin.z );
|
||||
WRITE_SHORT( (int)pev->skin );
|
||||
WRITE_SHORT( entityIndex );
|
||||
if( entityIndex > 0 )
|
||||
WRITE_SHORT( modelIndex );
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
|
||||
SetThink( Remove );
|
||||
SetNextThink( 0.3 );
|
||||
}
|
||||
|
@ -285,114 +212,206 @@ void CPortalSurface :: PostActivate( void )
|
|||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// multisource
|
||||
//====================================================================
|
||||
|
||||
TYPEDESCRIPTION CMultiSource::m_SaveData[] =
|
||||
//=========================================================
|
||||
// info_path - train node path.
|
||||
//=========================================================
|
||||
void CInfoPath :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
DEFINE_ARRAY( CMultiSource, m_rgEntities, FIELD_EHANDLE, MAX_MULTI_TARGETS ),
|
||||
DEFINE_ARRAY( CMultiSource, m_rgTriggered, FIELD_INTEGER, MAX_MULTI_TARGETS ),
|
||||
DEFINE_FIELD( CMultiSource, m_iTotal, FIELD_INTEGER ),
|
||||
}; IMPLEMENT_SAVERESTORE( CMultiSource, CBaseLogic );
|
||||
LINK_ENTITY_TO_CLASS( multisource, CMultiSource );
|
||||
|
||||
void CMultiSource::Spawn()
|
||||
{
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
SetNextThink( 0.1 );
|
||||
pev->spawnflags |= SF_START_ON;
|
||||
SetThink( Register );
|
||||
}
|
||||
|
||||
void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// Find the entity in our list
|
||||
while (i < m_iTotal) if ( m_rgEntities[i++] == pCaller ) break;
|
||||
|
||||
// if we didn't find it, report error and leave
|
||||
if (i > m_iTotal) return;
|
||||
|
||||
STATE s = GetState();
|
||||
m_rgTriggered[i-1] ^= 1;
|
||||
if ( s == GetState()) return;
|
||||
|
||||
if ( s == STATE_OFF )
|
||||
if ( FStrEq( pkvd->szKeyName, "wait" ))
|
||||
{
|
||||
USE_TYPE useType = USE_TOGGLE;
|
||||
if ( m_globalstate ) useType = USE_ON;
|
||||
UTIL_FireTargets( pev->target, NULL, this, useType, value );
|
||||
UTIL_FireTargets( m_iszKillTarget, NULL, this, USE_REMOVE );
|
||||
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 );
|
||||
}
|
||||
|
||||
STATE CMultiSource::GetState( void )
|
||||
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 )
|
||||
{
|
||||
// Is everything triggered?
|
||||
int i = 0;
|
||||
|
||||
// Still initializing?
|
||||
if ( pev->spawnflags & SF_START_ON ) return STATE_OFF;
|
||||
|
||||
while (i < m_iTotal)
|
||||
if( FClassnameIs( pev, "path_corner" ))
|
||||
{
|
||||
if (m_rgTriggered[i] == 0) break;
|
||||
i++;
|
||||
// compatible mode
|
||||
m_iPathName[m_cPaths] = pev->target;
|
||||
m_iPathWeight[m_cPaths] = 0;
|
||||
m_cPaths++;
|
||||
}
|
||||
|
||||
if (i == m_iTotal)
|
||||
int r_index = 0;
|
||||
int w_index = m_cPaths - 1;
|
||||
|
||||
while( r_index < w_index )
|
||||
{
|
||||
if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
|
||||
return STATE_ON;
|
||||
// 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--;
|
||||
}
|
||||
return STATE_OFF;
|
||||
|
||||
m_iState = STATE_ON;
|
||||
m_index = 0;
|
||||
SetBits( pev->flags, FL_POINTENTITY );
|
||||
UTIL_SetModel( ENT( pev ), "blabla.mdl");
|
||||
pev->scale = 0.1f;
|
||||
}
|
||||
|
||||
void CMultiSource::Register(void)
|
||||
{
|
||||
m_iTotal = 0;
|
||||
memset( m_rgEntities, 0, MAX_MULTI_TARGETS * sizeof(EHANDLE) );
|
||||
|
||||
SetThink(NULL);
|
||||
|
||||
// search for all entities which target this multisource (pev->targetname)
|
||||
|
||||
CBaseEntity *pTarget = UTIL_FindEntityByTarget( NULL, STRING(pev->targetname) );
|
||||
while (pTarget && (m_iTotal < MAX_MULTI_TARGETS))
|
||||
void CInfoPath :: PostActivate( void )
|
||||
{
|
||||
// find all paths and save into array
|
||||
for(int i = 0; i < m_cPaths; i++ )
|
||||
{
|
||||
m_rgEntities[m_iTotal++] = pTarget;
|
||||
pTarget = UTIL_FindEntityByTarget( pTarget, STRING(pev->targetname));
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
pTarget = UTIL_FindEntityByClassname(NULL, "multi_manager");
|
||||
while (pTarget && (m_iTotal < MAX_MULTI_TARGETS))
|
||||
{
|
||||
if ( pTarget->HasTarget(pev->targetname) ) m_rgEntities[m_iTotal++] = pTarget;
|
||||
pTarget = UTIL_FindEntityByClassname( pTarget, "multi_manager" );
|
||||
}
|
||||
pev->spawnflags &= ~SF_START_ON;
|
||||
}
|
||||
|
||||
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( light_torch_small_walltorch, CWallTorch );
|
||||
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
|
||||
LINK_ENTITY_TO_CLASS( misc_teleporter_dest, CPointEntity );
|
||||
LINK_ENTITY_TO_CLASS( misc_portal_surface, CPortalSurface );
|
||||
LINK_ENTITY_TO_CLASS( info_portal, 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( misc_model, 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( 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);
|
||||
LINK_ENTITY_TO_CLASS( info_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 );
|
|
@ -15,7 +15,7 @@ public:
|
|||
class CNullEntity : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void ){ REMOVE_ENTITY(ENT(pev)); }
|
||||
void Spawn( void ){ REMOVE_ENTITY( ENT( pev )); }
|
||||
};
|
||||
|
||||
class CBaseDMStart : public CPointEntity
|
||||
|
@ -27,7 +27,68 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
class CLaserSpot : public CBaseEntity//laser spot for different weapons
|
||||
#define SPEED_MASTER 0
|
||||
#define SPEED_INCREMENT 1
|
||||
#define SPEED_DECREMENT 2
|
||||
#define SPEED_MULTIPLY 3
|
||||
#define SPEED_DIVIDE 4
|
||||
|
||||
#define SF_TELEPORT_TONEXT 0x1
|
||||
|
||||
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 );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,6 @@ public:
|
|||
BOOL IsLockedByMaster( void );
|
||||
BOOL IsLockedByMaster( USE_TYPE useType );
|
||||
BOOL IsLockedByMaster( CBaseEntity *pActivator );
|
||||
void FireTargets( USE_TYPE useType = USE_TOGGLE, float value = 0 );
|
||||
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
||||
virtual void KeyValue( KeyValueData* pkvd);
|
||||
virtual int Save( CSave &save );
|
||||
|
@ -27,105 +26,14 @@ public:
|
|||
EHANDLE m_hTarget;
|
||||
STATE m_iState;
|
||||
string_t m_sMaster;
|
||||
string_t m_iszKillTarget; //evil stuff. agrhh
|
||||
string_t m_sSet;//used for logic_usetype
|
||||
string_t m_sReset;//used for logic_usetype
|
||||
string_t m_globalstate;
|
||||
string_t m_sSet; // used for logic_usetype
|
||||
string_t m_sReset; // used for logic_usetype
|
||||
float m_flMin, m_flMax;
|
||||
};
|
||||
|
||||
#define SF_CORNER_WAITTRIG 0x001
|
||||
#define SF_CORNER_TELEPORT 0x002
|
||||
#define SF_CORNER_FIREONCE 0x004
|
||||
|
||||
class CPathCorner : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void KeyValue( KeyValueData* pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
float GetDelay( void ){ return pev->spawnflags & SF_CORNER_WAITTRIG ? -1 : m_flWait; }
|
||||
void GetSpeed( float *speed ) { if(pev->speed != 0) *speed = pev->speed; }
|
||||
void UpdateTargets( void );
|
||||
void Link( void );
|
||||
void PostActivate( void ){ Link(); }
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
CPathCorner *Instance( edict_t *pent )
|
||||
{
|
||||
if ( FClassnameIs( pent, "path_corner" ) )
|
||||
return (CPathCorner *)GET_PRIVATE(pent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CPathCorner *m_pNextPath1;
|
||||
CPathCorner *m_pNextPath2;
|
||||
CPathCorner *m_pPrevPath;
|
||||
CBaseEntity *ValidPath( CBaseEntity *m_pPath );
|
||||
CBaseEntity *GetNext( void );
|
||||
CBaseEntity *GetPrev( void ){ return ValidPath( m_pPrevPath ); }
|
||||
void SetPrev( CPathCorner *pPrev ) { m_pPrevPath = (CPathCorner *)ValidPath((CPathCorner *)pPrev); }
|
||||
};
|
||||
|
||||
class CPathTrack : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Activate( void );
|
||||
void KeyValue( KeyValueData* pkvd);
|
||||
|
||||
void SetPrevious( CPathTrack *pprevious );
|
||||
void Link( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
CBaseEntity *ValidPath( CBaseEntity *ppath, int testFlag ); // Returns ppath if enabled, NULL otherwise
|
||||
void Project( CBaseEntity *pstart, CBaseEntity *pend, Vector *origin, float dist );
|
||||
|
||||
static CPathTrack *Instance( edict_t *pent );
|
||||
|
||||
CBaseEntity *LookAhead( Vector *origin, float dist, int move );
|
||||
CBaseEntity *Nearest( Vector origin ); //notused
|
||||
|
||||
CBaseEntity *GetNext( void );
|
||||
CBaseEntity *GetPrev( void );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#if PATH_SPARKLE_DEBUG
|
||||
void EXPORT Sparkle(void);
|
||||
#endif
|
||||
|
||||
float m_length;
|
||||
string_t m_altName;
|
||||
CPathTrack *m_pnext;
|
||||
CPathTrack *m_pprevious;
|
||||
CPathTrack *m_paltpath;
|
||||
};
|
||||
|
||||
class CMultiSource : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void Spawn( );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
STATE GetState( void );
|
||||
void EXPORT Register( void );
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
EHANDLE m_rgEntities[MAX_MULTI_TARGETS];
|
||||
int m_rgTriggered[MAX_MULTI_TARGETS];
|
||||
|
||||
int m_iTotal;
|
||||
};
|
||||
|
||||
#include "baseinfo.h"
|
||||
|
||||
class CUtilRainModify : public CPointEntity
|
||||
class CEnvRainModify : public CPointEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,69 +4,33 @@
|
|||
#ifndef BASEMOVER_H
|
||||
#define BASEMOVER_H
|
||||
|
||||
//rotating brush flags
|
||||
#define SF_BRUSH_ROTATE_Z_AXIS 4
|
||||
#define SF_BRUSH_ROTATE_X_AXIS 8
|
||||
|
||||
//door flags
|
||||
#define SF_DOOR_START_OPEN 1
|
||||
#define SF_DOOR_ROTATE_BACKWARDS 2
|
||||
#define SF_DOOR_PASSABLE 8
|
||||
#define SF_DOOR_ONEWAY 16
|
||||
#define SF_DOOR_NO_AUTO_RETURN 32
|
||||
#define SF_DOOR_ROTATE_Z 64
|
||||
#define SF_DOOR_ROTATE_X 128
|
||||
#define SF_DOOR_USE_ONLY 256
|
||||
#define SF_DOOR_NOMONSTERS 512
|
||||
|
||||
// Tracktrain spawn flags
|
||||
#define SF_TRACKTRAIN_NOPITCH 0x0001
|
||||
#define SF_TRACKTRAIN_NOCONTROL 0x0002
|
||||
#define SF_TRACKTRAIN_FORWARDONLY 0x0004
|
||||
#define SF_TRACKTRAIN_PASSABLE 0x0008
|
||||
#define SF_TRACKTRAIN_NOYAW 0x0010 //LRC
|
||||
#define SF_TRACKTRAIN_AVELOCITY 0x800000 //LRC - avelocity has been set manually, don't turn.
|
||||
#define SF_TRACKTRAIN_AVEL_GEARS 0x400000 //LRC - avelocity should be scaled up/down when the train changes gear.
|
||||
|
||||
// Spawnflag for CPathTrack
|
||||
#define SF_PATH_DISABLED 0x00000001
|
||||
#define SF_PATH_FIREONCE 0x00000002
|
||||
#define SF_PATH_ALTREVERSE 0x00000004
|
||||
#define SF_PATH_DISABLE_TRAIN 0x00000008
|
||||
#define SF_PATH_ALTERNATE 0x00008000
|
||||
#define SF_PATH_AVELOCITY 0x00080000 //LRC
|
||||
|
||||
//LRC - values in 'armortype'
|
||||
#define PATHSPEED_SET 0
|
||||
#define PATHSPEED_ACCEL 1
|
||||
#define PATHSPEED_TIME 2
|
||||
#define PATHSPEED_SET_MASTER 3
|
||||
|
||||
class CBaseMover : public CBaseBrush
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
virtual void AxisDir( void );
|
||||
void (CBaseMover::*m_pfnCallWhenMoveDone)(void); //custom movedone function
|
||||
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_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
|
||||
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 );
|
||||
|
@ -89,15 +53,16 @@ public:
|
|||
void Spawn( void );
|
||||
void Precache( void );
|
||||
virtual void PostSpawn( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
BOOL IsWater( void ){ return pev->skin != 0; };
|
||||
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 int ObjectCaps( void )
|
||||
virtual void SetToggleState( int state );
|
||||
virtual int ObjectCaps( void )
|
||||
{
|
||||
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ))//door without name player can direct using
|
||||
return (CBaseMover::ObjectCaps() & ~FCAP_ACROSS_TRANSITION | FCAP_IMPULSE_USE );
|
||||
else return (CBaseMover::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
|
||||
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
|
||||
|
@ -111,7 +76,9 @@ public:
|
|||
class CRotDoor : public CBaseDoor
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
virtual void PostSpawn( void ) {}
|
||||
virtual void SetToggleState( int state );
|
||||
virtual BOOL IsRotatingDoor( void ){ return TRUE; };
|
||||
};
|
||||
|
||||
|
@ -134,6 +101,7 @@ public:
|
|||
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 )
|
||||
|
@ -168,7 +136,6 @@ public:
|
|||
BOOL Stop( float flWait = -1 );
|
||||
BOOL Teleport( void );
|
||||
void Blocked( CBaseEntity *pOther );
|
||||
BOOL IsWater( void ){ return pev->skin != 0; };
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
Vector TrainOrg( void ) { return (pev->mins + pev->maxs) * 0.5; }
|
||||
|
@ -177,76 +144,16 @@ public:
|
|||
void EXPORT Next( void );
|
||||
|
||||
//path operations
|
||||
CBaseEntity *FindPath( void );
|
||||
CBaseEntity *FindNextPath( void );
|
||||
void Reverse( void );
|
||||
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 *pCurPath, *pNextPath;
|
||||
};
|
||||
|
||||
class CFuncTrackTrain : public CBaseMover
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
void Blocked( CBaseEntity *pOther );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void KeyValue( KeyValueData* pkvd );
|
||||
|
||||
void EXPORT DesiredAction( void ); //LRC - used to be called Next!
|
||||
void PostActivate( void );
|
||||
void ClearPointers( void );
|
||||
|
||||
// void EXPORT Next( void );
|
||||
void EXPORT PostponeNext( void );
|
||||
void EXPORT Find( void );
|
||||
void EXPORT NearestPath( void );
|
||||
void EXPORT DeadEnd( void );
|
||||
|
||||
void NextThink( float thinkTime, BOOL alwaysThink );
|
||||
|
||||
void SetTrack( CBaseEntity *track ) { pPath = ((CPathTrack *)track)->Nearest(pev->origin); }
|
||||
void SetControls( entvars_t *pevControls );
|
||||
BOOL OnControls( entvars_t *pev );
|
||||
|
||||
void StopSound ( void );
|
||||
void UpdateSound ( void );
|
||||
|
||||
static CFuncTrackTrain *Instance( edict_t *pent )
|
||||
{
|
||||
if ( FClassnameIs( pent, "func_tracktrain" ) )
|
||||
return (CFuncTrackTrain *)GET_PRIVATE(pent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
virtual int ObjectCaps( void ) { return CBaseMover :: ObjectCaps() | FCAP_DIRECTIONAL_USE; }
|
||||
|
||||
virtual void OverrideReset( void );
|
||||
|
||||
CBaseEntity *pPath;
|
||||
float m_length;
|
||||
float m_height;
|
||||
// I get it... this records the train's max speed (as set by the level designer), whereas
|
||||
// pev->speed records the current speed (as set by the player). --LRC
|
||||
// m_speed is also stored, as an int, in pev->impulse.
|
||||
float m_speed;
|
||||
float m_dir;
|
||||
float m_startSpeed;
|
||||
Vector m_controlMins;
|
||||
Vector m_controlMaxs;
|
||||
int m_soundPlaying;
|
||||
float m_flBank;
|
||||
float m_oldSpeed;
|
||||
Vector m_vecBaseAvel; // LRC - the underlying avelocity, superceded by normal turning behaviour where applicable
|
||||
CBaseEntity *pPath, *pNextPath;
|
||||
};
|
||||
|
||||
#endif //BASEMOVER_H
|
|
@ -66,10 +66,11 @@ void CEnvShower::Touch( CBaseEntity *pOther )
|
|||
class ChangeLevelFire : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void PostActivate( void ) { FireTargets(); UTIL_Remove( this ); }
|
||||
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
|
||||
//=======================================================================
|
||||
|
|
|
@ -1,427 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) XashXT Group 2006
|
||||
//=======================================================================
|
||||
|
||||
#include "extdll.h"
|
||||
#include "utils.h"
|
||||
#include "cbase.h"
|
||||
//atoi(g_engfuncs.pfnInfoKeyValue(g_engfuncs.pfnGetInfoKeyBuffer(edict()), "skin"));
|
||||
//use this for custom change speed
|
||||
|
||||
//=========================================================
|
||||
// path_corner - train node path.
|
||||
//=========================================================
|
||||
TYPEDESCRIPTION CPathCorner::m_SaveData[] =
|
||||
{ DEFINE_FIELD( CPathCorner, m_pNextPath1, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CPathCorner, m_pNextPath2, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CPathCorner, m_pPrevPath, FIELD_CLASSPTR ),
|
||||
};IMPLEMENT_SAVERESTORE(CPathCorner, CBaseLogic);
|
||||
|
||||
void CPathCorner :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "altpath"))
|
||||
{
|
||||
pev->netname = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
LINK_ENTITY_TO_CLASS( path_corner, CPathCorner );
|
||||
|
||||
void CPathCorner :: Spawn( void )
|
||||
{
|
||||
m_iState = STATE_ON;
|
||||
SetBits( pev->flags, FL_POINTENTITY );
|
||||
}
|
||||
|
||||
void CPathCorner :: Link( void )
|
||||
{
|
||||
CBaseEntity *pTarget;
|
||||
|
||||
if ( FStringNull( pev->targetname ) ) return;
|
||||
|
||||
if ( !FStringNull(pev->target) )
|
||||
{
|
||||
pTarget = UTIL_FindEntityByTargetname( NULL, STRING(pev->target));
|
||||
if(pTarget)
|
||||
{
|
||||
m_pNextPath1 = (CPathCorner*)pTarget;//valid path
|
||||
m_pNextPath1->SetPrev( this );
|
||||
}
|
||||
else DevMsg( "Dead end link %s\n", STRING(pev->target) );
|
||||
}
|
||||
if ( !FStringNull(pev->netname) )
|
||||
{
|
||||
pTarget = UTIL_FindEntityByTargetname( NULL, STRING(pev->netname));
|
||||
if(pTarget)
|
||||
{
|
||||
m_pNextPath2 = (CPathCorner*)pTarget;//valid path
|
||||
m_pNextPath2->SetPrev( this );
|
||||
}
|
||||
else DevMsg( "Dead end link %s\n", STRING(pev->netname) );
|
||||
}
|
||||
}
|
||||
|
||||
void CPathCorner::UpdateTargets( void )
|
||||
{
|
||||
UTIL_FireTargets(pev->message, this, this, USE_TOGGLE );
|
||||
|
||||
if(pev->spawnflags & SF_CORNER_FIREONCE)
|
||||
{
|
||||
pev->message = iStringNull;
|
||||
ClearBits( pev->spawnflags, SF_CORNER_FIREONCE );
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *CPathCorner::ValidPath( CBaseEntity *m_pPath )
|
||||
{
|
||||
ASSERTSZ( m_pPath != this, "ValidPath: self path!\n");
|
||||
|
||||
if(m_pPath && m_pPath->edict() && m_pPath != this && ((CPathCorner *)m_pPath)->m_iState == STATE_ON)
|
||||
return m_pPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
CBaseEntity *CPathCorner::GetNext( void )
|
||||
{
|
||||
if(pev->team) return ValidPath( m_pNextPath2 );
|
||||
return ValidPath( m_pNextPath1 );
|
||||
}
|
||||
|
||||
void CPathCorner :: 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;
|
||||
else if(useType == USE_SET) pev->team = !pev->team; //change path
|
||||
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, wait %g\n", GetStringForState( GetState()), m_flWait);
|
||||
if(ValidPath(m_pPrevPath)) Msg("Prev path %s", STRING(m_pPrevPath->pev->targetname));
|
||||
if(ValidPath(m_pNextPath1))Msg("Next path %s", STRING(m_pNextPath1->pev->targetname));
|
||||
if(ValidPath(m_pNextPath2))Msg("Alt path %s", STRING(m_pNextPath2->pev->targetname));
|
||||
SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// path_track - tracktrain node path.
|
||||
//=========================================================
|
||||
TYPEDESCRIPTION CPathTrack::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CPathTrack, m_length, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( CPathTrack, m_pnext, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CPathTrack, m_paltpath, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CPathTrack, m_pprevious, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( CPathTrack, m_altName, FIELD_STRING ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CPathTrack, CBaseEntity );
|
||||
LINK_ENTITY_TO_CLASS( path_track, CPathTrack );
|
||||
|
||||
//
|
||||
// Cache user-entity-field values until spawn is called.
|
||||
//
|
||||
void CPathTrack :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "altpath"))
|
||||
{
|
||||
m_altName = ALLOC_STRING(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "turnspeed")) //LRC
|
||||
{
|
||||
if (pkvd->szValue[0]) // if the field is blank, don't set the spawnflag.
|
||||
{
|
||||
pev->spawnflags |= SF_PATH_AVELOCITY;
|
||||
UTIL_StringToVector( (float*)pev->avelocity, pkvd->szValue);
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CPathTrack :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
int on;
|
||||
|
||||
// Use toggles between two paths
|
||||
if ( m_paltpath )
|
||||
{
|
||||
on = !FBitSet( pev->spawnflags, SF_PATH_ALTERNATE );
|
||||
if (useType == USE_TOGGLE)
|
||||
{
|
||||
if(on) useType = USE_OFF;
|
||||
else useType = USE_ON;
|
||||
}
|
||||
if (useType == USE_ON)ClearBits( pev->spawnflags, SF_PATH_ALTERNATE );
|
||||
else if(useType == USE_OFF)SetBits( pev->spawnflags, SF_PATH_ALTERNATE );
|
||||
}
|
||||
else // Use toggles between enabled/disabled
|
||||
{
|
||||
on = !FBitSet( pev->spawnflags, SF_PATH_DISABLED );
|
||||
if (useType == USE_TOGGLE)
|
||||
{
|
||||
if(on) useType = USE_OFF;
|
||||
else useType = USE_ON;
|
||||
}
|
||||
if (useType == USE_ON)ClearBits( pev->spawnflags, SF_PATH_DISABLED );
|
||||
else if(useType == USE_OFF)SetBits( pev->spawnflags, SF_PATH_DISABLED );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPathTrack :: Link( void )
|
||||
{
|
||||
CBaseEntity *pTarget;
|
||||
|
||||
if( !FStringNull( pev->target ))
|
||||
{
|
||||
pTarget = UTIL_FindEntityByTargetname( NULL, STRING(pev->target) );
|
||||
|
||||
if( pTarget )
|
||||
{
|
||||
m_pnext = (CPathTrack*)pTarget;
|
||||
m_pnext->SetPrevious( this );
|
||||
}
|
||||
else ALERT( at_console, "Dead end link %s\n", STRING(pev->target) );
|
||||
}
|
||||
|
||||
// Find "alternate" path
|
||||
if ( m_altName )
|
||||
{
|
||||
pTarget = UTIL_FindEntityByTargetname( NULL, STRING(m_altName) );
|
||||
if ( pTarget ) // If no next pointer, this is the end of a path
|
||||
{
|
||||
m_paltpath = (CPathTrack*)pTarget;
|
||||
m_paltpath->SetPrevious( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPathTrack :: Spawn( void )
|
||||
{
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8));
|
||||
|
||||
m_pnext = NULL;
|
||||
m_pprevious = NULL;
|
||||
// DEBUGGING CODE
|
||||
#if PATH_SPARKLE_DEBUG
|
||||
SetThink( Sparkle );
|
||||
SetNextThink( 0.5 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CPathTrack::Activate( void )
|
||||
{
|
||||
if ( !FStringNull( pev->targetname ) ) // Link to next, and back-link
|
||||
Link();
|
||||
|
||||
CBaseLogic::Activate();
|
||||
}
|
||||
|
||||
CBaseEntity *CPathTrack :: ValidPath( CBaseEntity *ppath, int testFlag )
|
||||
{
|
||||
if ( !ppath )
|
||||
return NULL;
|
||||
|
||||
if ( testFlag && FBitSet( ppath->pev->spawnflags, SF_PATH_DISABLED ) )
|
||||
return NULL;
|
||||
|
||||
return ppath;
|
||||
}
|
||||
|
||||
|
||||
void CPathTrack :: Project( CBaseEntity *pstart, CBaseEntity *pend, Vector *origin, float dist )
|
||||
{
|
||||
if ( pstart && pend )
|
||||
{
|
||||
Vector dir = (pend->pev->origin - pstart->pev->origin);
|
||||
dir = dir.Normalize();
|
||||
*origin = pend->pev->origin + dir * dist;
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *CPathTrack::GetNext( void )
|
||||
{
|
||||
if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && !FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) )
|
||||
return m_paltpath;
|
||||
|
||||
return m_pnext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CBaseEntity *CPathTrack::GetPrev( void )
|
||||
{
|
||||
if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) )
|
||||
return m_paltpath;
|
||||
|
||||
return m_pprevious;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPathTrack::SetPrevious( CPathTrack *pprev )
|
||||
{
|
||||
// Only set previous if this isn't my alternate path
|
||||
if ( pprev && !FStrEq( STRING(pprev->pev->targetname), STRING(m_altName) ) )
|
||||
m_pprevious = pprev;
|
||||
}
|
||||
|
||||
|
||||
// Assumes this is ALWAYS enabled
|
||||
CBaseEntity *CPathTrack :: LookAhead( Vector *origin, float dist, int move )
|
||||
{
|
||||
CBaseEntity *pcurrent;
|
||||
float originalDist = dist;
|
||||
|
||||
pcurrent = this;
|
||||
Vector currentPos = *origin;
|
||||
|
||||
if ( dist < 0 ) // Travelling backwards through path
|
||||
{
|
||||
dist = -dist;
|
||||
while ( dist > 0 )
|
||||
{
|
||||
Vector dir = pcurrent->pev->origin - currentPos;
|
||||
float length = dir.Length();
|
||||
if ( !length )
|
||||
{
|
||||
if ( !ValidPath(pcurrent->GetPrev(), move) ) // If there is no previous node, or it's disabled, return now.
|
||||
{
|
||||
if ( !move )
|
||||
Project( pcurrent->GetNext(), pcurrent, origin, dist );
|
||||
return NULL;
|
||||
}
|
||||
pcurrent = pcurrent->GetPrev();
|
||||
}
|
||||
else if ( length > dist ) // enough left in this path to move
|
||||
{
|
||||
*origin = currentPos + (dir * (dist / length));
|
||||
return pcurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist -= length;
|
||||
currentPos = pcurrent->pev->origin;
|
||||
*origin = currentPos;
|
||||
if ( !ValidPath(pcurrent->GetPrev(), move) ) // If there is no previous node, or it's disabled, return now.
|
||||
return NULL;
|
||||
|
||||
pcurrent = pcurrent->GetPrev();
|
||||
}
|
||||
}
|
||||
*origin = currentPos;
|
||||
return pcurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( dist > 0 )
|
||||
{
|
||||
if ( !ValidPath(pcurrent->GetNext(), move) ) // If there is no next node, or it's disabled, return now.
|
||||
{
|
||||
if ( !move )
|
||||
Project( pcurrent->GetPrev(), pcurrent, origin, dist );
|
||||
return NULL;
|
||||
}
|
||||
Vector dir = pcurrent->GetNext()->pev->origin - currentPos;
|
||||
float length = dir.Length();
|
||||
if ( !length && !ValidPath( pcurrent->GetNext()->GetNext(), move ) )
|
||||
{
|
||||
if ( dist == originalDist ) // HACK -- up against a dead end
|
||||
return NULL;
|
||||
return pcurrent;
|
||||
}
|
||||
if ( length > dist ) // enough left in this path to move
|
||||
{
|
||||
*origin = currentPos + (dir * (dist / length));
|
||||
return pcurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist -= length;
|
||||
currentPos = pcurrent->GetNext()->pev->origin;
|
||||
pcurrent = pcurrent->GetNext();
|
||||
*origin = currentPos;
|
||||
}
|
||||
}
|
||||
*origin = currentPos;
|
||||
}
|
||||
|
||||
return pcurrent;
|
||||
}
|
||||
|
||||
|
||||
// Assumes this is ALWAYS enabled
|
||||
CBaseEntity *CPathTrack :: Nearest( Vector origin )
|
||||
{
|
||||
int deadCount;
|
||||
float minDist, dist;
|
||||
Vector delta;
|
||||
CBaseEntity *ppath, *pnearest;
|
||||
|
||||
|
||||
delta = origin - pev->origin;
|
||||
delta.z = 0;
|
||||
minDist = delta.Length();
|
||||
pnearest = this;
|
||||
ppath = GetNext();
|
||||
|
||||
// Hey, I could use the old 2 racing pointers solution to this, but I'm lazy :)
|
||||
deadCount = 0;
|
||||
while ( ppath && ppath != this )
|
||||
{
|
||||
deadCount++;
|
||||
if ( deadCount > 9999 )
|
||||
{
|
||||
ALERT( at_error, "Bad sequence of path_tracks from %s", STRING(pev->targetname) );
|
||||
return NULL;
|
||||
}
|
||||
delta = origin - ppath->pev->origin;
|
||||
delta.z = 0;
|
||||
dist = delta.Length();
|
||||
if ( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
pnearest = ppath;
|
||||
}
|
||||
ppath = ppath->GetNext();
|
||||
}
|
||||
return pnearest;
|
||||
}
|
||||
|
||||
|
||||
CPathTrack *CPathTrack::Instance( edict_t *pent )
|
||||
{
|
||||
if ( FClassnameIs( pent, "path_track" ) )
|
||||
return (CPathTrack *)GET_PRIVATE(pent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// DEBUGGING CODE
|
||||
#if PATH_SPARKLE_DEBUG
|
||||
void CPathTrack :: Sparkle( void )
|
||||
{
|
||||
|
||||
SetNextThink( 0.2 );
|
||||
if ( FBitSet( pev->spawnflags, SF_PATH_DISABLED ) )
|
||||
UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 210, 10);
|
||||
else
|
||||
UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 84, 10);
|
||||
}
|
||||
#endif
|
|
@ -605,7 +605,7 @@ void CNukeExplode :: Spawn( void )
|
|||
|
||||
// create first explode sprite
|
||||
SFX_Explode( m_usExplodeSprite, pev->origin, 70, TE_EXPLFLAG_NOPARTICLES|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NODLIGHTS );
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/warhead/whexplode.wav", 1, ATTN_NONE );
|
||||
EMIT_SOUND( edict(), CHAN_VOICE, "weapons/warhead/whexplode.wav", 1, ATTN_NONE );
|
||||
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->solid = SOLID_NOT;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -144,11 +144,16 @@ void CBaseTrigger::KeyValue( KeyValueData *pkvd )
|
|||
pev->armorvalue = atof(pkvd->szValue) / 100.0;
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "roomtype")) //for soundfx
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -214,7 +219,8 @@ class CTriggerMulti : public CBaseTrigger
|
|||
{
|
||||
void FireOnEntry( CBaseEntity *pOther )
|
||||
{
|
||||
if(!IsLockedByMaster(pOther)) FireTargets();
|
||||
if(!IsLockedByMaster(pOther))
|
||||
UTIL_FireTargets(pev->target, pOther, this, USE_TOGGLE );
|
||||
}
|
||||
void FireOnLeave( CBaseEntity *pOther )
|
||||
{
|
||||
|
@ -233,7 +239,7 @@ class CTriggerOnce : public CBaseTrigger
|
|||
{
|
||||
if ( !IsLockedByMaster(pOther))
|
||||
{
|
||||
FireTargets();
|
||||
UTIL_FireTargets( pev->target, pOther, this, USE_TOGGLE );
|
||||
SetThink( Remove );
|
||||
SetNextThink( 0 );
|
||||
}
|
||||
|
@ -375,7 +381,7 @@ class CTriggerPush : public CBaseTrigger
|
|||
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "world/jumppad.wav", VOL_NORM, ATTN_IDLE );
|
||||
|
||||
m_flWait = gpGlobals->time + (2.0f * gpGlobals->frametime);
|
||||
m_flWait = gpGlobals->time + ( 2.0f * gpGlobals->frametime );
|
||||
|
||||
if( FBitSet( pev->spawnflags, SF_PUSH_ONCE ))
|
||||
UTIL_Remove( this );
|
||||
|
@ -433,507 +439,7 @@ class CTriggerSound : public CBaseTrigger
|
|||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_sound, CTriggerSound );
|
||||
|
||||
//=======================================================================
|
||||
// trigger_relay
|
||||
//=======================================================================
|
||||
class CTriggerRelay : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void Spawn( void ){ m_iState = STATE_OFF; }
|
||||
void Think ( void );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_relay, CTriggerRelay );
|
||||
|
||||
void CTriggerRelay::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "triggerstate"))
|
||||
{
|
||||
int type = atoi( pkvd->szValue );
|
||||
switch( type )
|
||||
{
|
||||
case 0: pev->impulse = USE_OFF; break;
|
||||
case 2: pev->impulse = USE_TOGGLE; break;
|
||||
case 3: pev->impulse = USE_SET; break;
|
||||
default: pev->impulse = USE_ON; break;
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "locktarget"))
|
||||
{
|
||||
pev->message = ALLOC_STRING(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CTriggerRelay::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
m_hActivator = pActivator; //save activator
|
||||
if(pev->impulse) pev->button = pev->impulse;
|
||||
else pev->button = (int)useType; //save use type
|
||||
pev->frags = value; //save our value
|
||||
|
||||
if (useType == USE_SHOWINFO)
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg( "target is %s, locktarget %s\n", STRING(pev->target), STRING(pev->message));
|
||||
Msg( "new value %g\n", pev->frags );
|
||||
}
|
||||
else //activate target
|
||||
{
|
||||
m_iState = STATE_ON;
|
||||
SetNextThink(m_flDelay);
|
||||
}
|
||||
}
|
||||
|
||||
void CTriggerRelay::Think ( void )
|
||||
{
|
||||
if (IsLockedByMaster()) UTIL_FireTargets( pev->message, m_hActivator, this, (USE_TYPE)pev->button, pev->frags );
|
||||
else
|
||||
{
|
||||
UTIL_FireTargets( pev->target, m_hActivator, this, (USE_TYPE)pev->button, pev->frags );
|
||||
UTIL_FireTargets( m_iszKillTarget, m_hActivator, this, USE_REMOVE );
|
||||
}
|
||||
|
||||
//suhtdown
|
||||
m_iState = STATE_OFF;
|
||||
DontThink();//just in case
|
||||
if ( pev->spawnflags & 1 ) UTIL_Remove( this );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// trigger_auto
|
||||
//=======================================================================
|
||||
class CAutoTrigger : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void PostActivate( void );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_auto, CAutoTrigger );
|
||||
|
||||
void CAutoTrigger::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "triggerstate"))
|
||||
{
|
||||
int type = atoi( pkvd->szValue );
|
||||
switch( type )
|
||||
{
|
||||
case 0: pev->impulse = USE_OFF; break;
|
||||
case 2: pev->impulse = USE_TOGGLE; break;
|
||||
case 3: pev->impulse = USE_SET; break;
|
||||
default: pev->impulse = USE_ON; break;
|
||||
}
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CAutoTrigger::PostActivate( void )
|
||||
{
|
||||
if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
|
||||
{
|
||||
FireTargets( (USE_TYPE)pev->impulse );
|
||||
if ( pev->spawnflags & 1 ) UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// trigger_changetarget
|
||||
//=======================================================================
|
||||
class CChangeTarget : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_changetarget, CChangeTarget );
|
||||
|
||||
void CChangeTarget::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "newtarget") || FStrEq(pkvd->szKeyName, "m_iszNewTarget"))
|
||||
{
|
||||
pev->message = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CChangeTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBaseEntity *pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ), pActivator );
|
||||
|
||||
if (useType == USE_SHOWINFO)
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg( "Current target %s, new target %s\n", STRING(pev->target), STRING(pev->message) );
|
||||
Msg( "target entity is: %s, current target: %s\n", STRING(pTarget->pev->classname), STRING(pTarget->pev->target));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pTarget)
|
||||
{
|
||||
if (FStrEq(STRING(pev->message), "*this"))
|
||||
{
|
||||
if (pActivator) pTarget->pev->target = pActivator->pev->targetname;
|
||||
else ALERT(at_error, "util_settarget \"%s\" requires a self pointer!\n", STRING(pev->targetname));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pTarget->IsFuncScreen()) pTarget->ChangeCamera( pev->message );
|
||||
else pTarget->pev->target = pev->message;
|
||||
}
|
||||
CBaseMonster *pMonster = pTarget->MyMonsterPointer( );
|
||||
if (pMonster) pMonster->m_pGoalEnt = NULL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// multi_manager
|
||||
//=======================================================================
|
||||
#define FL_CLONE 0x80000000
|
||||
|
||||
class CMultiManager : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Spawn ( void );
|
||||
void Think ( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
BOOL HasTarget( string_t targetname );
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
|
||||
int m_cTargets; // the total number of targets in this manager's fire list.
|
||||
int m_index; // Current target
|
||||
float m_startTime; // Time we started firing
|
||||
int m_iTargetName [ MAX_MULTI_TARGETS ];// list if indexes into global string array
|
||||
float m_flTargetDelay [ MAX_MULTI_TARGETS ];// delay (in seconds)
|
||||
private:
|
||||
inline BOOL IsClone( void ) { return (pev->spawnflags & FL_CLONE) ? TRUE : FALSE; }
|
||||
inline BOOL ShouldClone( void )
|
||||
{
|
||||
if ( IsClone() )return FALSE;
|
||||
//work in progress and calling again ?
|
||||
return (m_iState == STATE_ON) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
CMultiManager *Clone( void );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( multi_manager, CMultiManager );
|
||||
|
||||
// Global Savedata for multi_manager
|
||||
TYPEDESCRIPTION CMultiManager::m_SaveData[] =
|
||||
{ DEFINE_FIELD( CMultiManager, m_cTargets, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMultiManager, m_index, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMultiManager, m_startTime, FIELD_TIME ),
|
||||
DEFINE_ARRAY( CMultiManager, m_iTargetName, FIELD_STRING, MAX_MULTI_TARGETS ),
|
||||
DEFINE_ARRAY( CMultiManager, m_flTargetDelay, FIELD_FLOAT, MAX_MULTI_TARGETS ),
|
||||
};IMPLEMENT_SAVERESTORE(CMultiManager, CBaseLogic);
|
||||
|
||||
void CMultiManager :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if ( m_cTargets < MAX_MULTI_TARGETS )
|
||||
{
|
||||
char tmp[128];
|
||||
|
||||
UTIL_StripToken( pkvd->szKeyName, tmp );
|
||||
m_iTargetName [ m_cTargets ] = ALLOC_STRING( tmp );
|
||||
m_flTargetDelay [ m_cTargets ] = RandomRange((char *)STRING(ALLOC_STRING(pkvd->szValue))).Random();
|
||||
m_cTargets++;
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiManager :: Spawn( void )
|
||||
{
|
||||
// Sort targets
|
||||
// Quick and dirty bubble sort
|
||||
int swapped = 1;
|
||||
|
||||
while ( swapped )
|
||||
{
|
||||
swapped = 0;
|
||||
for ( int i = 1; i < m_cTargets; i++ )
|
||||
{
|
||||
if ( m_flTargetDelay[i] < m_flTargetDelay[i-1] )
|
||||
{
|
||||
// Swap out of order elements
|
||||
int name = m_iTargetName[i];
|
||||
float delay = m_flTargetDelay[i];
|
||||
m_iTargetName[i] = m_iTargetName[i-1];
|
||||
m_flTargetDelay[i] = m_flTargetDelay[i-1];
|
||||
m_iTargetName[i-1] = name;
|
||||
m_flTargetDelay[i-1] = delay;
|
||||
swapped = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_iState = STATE_OFF;
|
||||
m_index = 0;
|
||||
}
|
||||
|
||||
BOOL CMultiManager::HasTarget( string_t targetname )
|
||||
{
|
||||
for ( int i = 0; i < m_cTargets; i++ )
|
||||
if ( FStrEq(STRING(targetname), STRING(m_iTargetName[i])) ) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CMultiManager :: Think ( void )
|
||||
{
|
||||
float time;
|
||||
|
||||
time = gpGlobals->time - m_startTime;
|
||||
while ( m_index < m_cTargets && m_flTargetDelay[ m_index ] <= time )
|
||||
{
|
||||
UTIL_FireTargets( m_iTargetName[ m_index ], m_hActivator, this, USE_TOGGLE, pev->frags );
|
||||
m_index++;
|
||||
}
|
||||
if ( m_index >= m_cTargets )// have we fired all targets?
|
||||
{
|
||||
if ( IsClone() )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
//stop manager
|
||||
m_iState = STATE_OFF;
|
||||
DontThink();
|
||||
return;
|
||||
}
|
||||
m_iState = STATE_ON; //continue firing targets
|
||||
pev->nextthink = m_startTime + m_flTargetDelay[ m_index ];
|
||||
}
|
||||
|
||||
CMultiManager *CMultiManager::Clone( void )
|
||||
{
|
||||
CMultiManager *pMulti = GetClassPtr( (CMultiManager *)NULL );
|
||||
|
||||
edict_t *pEdict = pMulti->pev->pContainingEntity;
|
||||
memcpy( pMulti->pev, pev, sizeof(*pev) );
|
||||
pMulti->pev->pContainingEntity = pEdict;
|
||||
|
||||
pMulti->pev->spawnflags |= FL_CLONE;
|
||||
pMulti->m_cTargets = m_cTargets;
|
||||
pMulti->m_flWait = m_flWait;
|
||||
pMulti->m_iState = m_iState;
|
||||
memcpy( pMulti->m_iTargetName, m_iTargetName, sizeof( m_iTargetName ) );
|
||||
memcpy( pMulti->m_flTargetDelay, m_flTargetDelay, sizeof( m_flTargetDelay ) );
|
||||
|
||||
return pMulti;
|
||||
}
|
||||
|
||||
void CMultiManager :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
m_hActivator = pActivator;
|
||||
|
||||
if(IsLockedByMaster( useType )) return;
|
||||
pev->frags = value;//save our value
|
||||
|
||||
if (useType == USE_TOGGLE || useType == USE_ON)
|
||||
{
|
||||
if ( ShouldClone() )//create clone if needed
|
||||
{
|
||||
CMultiManager *pClone = Clone();
|
||||
pClone->Use( pActivator, pCaller, useType, value );
|
||||
return;
|
||||
}
|
||||
if(m_iState == STATE_OFF)
|
||||
{
|
||||
m_startTime = m_flWait + gpGlobals->time;
|
||||
m_iState = STATE_TURN_ON;
|
||||
m_index = 0;
|
||||
SetNextThink( m_flWait );
|
||||
}
|
||||
}
|
||||
else if (useType == USE_OFF)
|
||||
{
|
||||
m_iState = STATE_OFF;
|
||||
DontThink();
|
||||
}
|
||||
else if (useType == USE_SHOWINFO)//only show info if locked by master
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg("State: %s, number of targets %d\n", GetStringForState( GetState()), m_cTargets);
|
||||
if(m_iState == STATE_ON) Msg("Current target %s, delay time %f\n", STRING(m_iTargetName[ m_index ]), m_flTargetDelay[ m_index ]);
|
||||
else Msg("No targets for firing.\n");
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// multi_master
|
||||
//=======================================================================
|
||||
#define LOGIC_AND 0 // fire if all objects active
|
||||
#define LOGIC_OR 1 // fire if any object active
|
||||
#define LOGIC_NAND 2 // fire if not all objects active
|
||||
#define LOGIC_NOR 3 // fire if all objects disable
|
||||
#define LOGIC_XOR 4 // fire if only one (any) object active
|
||||
#define LOGIC_XNOR 5 // fire if active any number objects, but < then all
|
||||
|
||||
#define ST_ON 0
|
||||
#define ST_OFF 1
|
||||
#define ST_TURNON 2
|
||||
#define ST_TURNOFF 3
|
||||
#define ST_IN_USE 4
|
||||
|
||||
class CMultiMaster : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void Spawn ( void ){ SetNextThink( 0.1 ); }
|
||||
void Think ( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
virtual STATE GetState( void ) { return m_iState; };
|
||||
virtual STATE GetState( CBaseEntity *pActivator ) { return EvalLogic(pActivator)?STATE_ON:STATE_OFF; };
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
int m_cTargets;// the total number of targets in this manager's fire list.
|
||||
int m_iTargetName[ MAX_MULTI_TARGETS ];// list of indexes into global string array
|
||||
int m_iTargetState[ MAX_MULTI_TARGETS ];//list of wishstate targets
|
||||
|
||||
BOOL EvalLogic ( CBaseEntity *pEntity );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( multi_watcher, CMultiMaster );
|
||||
|
||||
TYPEDESCRIPTION CMultiMaster::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CMultiMaster, m_cTargets, FIELD_INTEGER ),
|
||||
DEFINE_ARRAY( CMultiMaster, m_iTargetName, FIELD_STRING, MAX_MULTI_TARGETS ),
|
||||
DEFINE_ARRAY( CMultiMaster, m_iTargetState, FIELD_INTEGER, MAX_MULTI_TARGETS ),
|
||||
};IMPLEMENT_SAVERESTORE(CMultiMaster,CBaseLogic);
|
||||
|
||||
void CMultiMaster :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "mode"))
|
||||
{
|
||||
pev->button = atof(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
if (FStrEq(pkvd->szKeyName, "offtarget"))
|
||||
{
|
||||
pev->netname = ALLOC_STRING(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else // add this field to the target list
|
||||
{
|
||||
// this assumes that additional fields are targetnames and their values are delay values.
|
||||
if ( m_cTargets < MAX_MULTI_TARGETS )
|
||||
{
|
||||
char tmp[128];
|
||||
|
||||
UTIL_StripToken( pkvd->szKeyName, tmp );
|
||||
m_iTargetName [ m_cTargets ] = ALLOC_STRING( tmp );
|
||||
m_iTargetState [ m_cTargets ] = atoi (pkvd->szValue);
|
||||
m_cTargets++;
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiMaster :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if (useType == USE_SHOWINFO)
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg("State: %s, Number of targets %d\n", GetStringForState( GetState()), m_cTargets);
|
||||
Msg("Limit is %d entities\n", MAX_MULTI_TARGETS);
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiMaster :: Think ( void )
|
||||
{
|
||||
if(EvalLogic(NULL))
|
||||
{
|
||||
if(m_iState == STATE_OFF)
|
||||
{
|
||||
m_iState = STATE_ON;
|
||||
UTIL_FireTargets( pev->target, this, this, USE_ON );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_iState == STATE_ON)
|
||||
{
|
||||
m_iState = STATE_OFF;
|
||||
UTIL_FireTargets( pev->netname, this, this, USE_OFF );
|
||||
}
|
||||
}
|
||||
SetNextThink( 0.05 );
|
||||
}
|
||||
|
||||
BOOL CMultiMaster :: EvalLogic ( CBaseEntity *pActivator )
|
||||
{
|
||||
int i;
|
||||
BOOL b;
|
||||
BOOL xorgot = FALSE;
|
||||
|
||||
CBaseEntity* pEntity;
|
||||
|
||||
for (i = 0; i < m_cTargets; i++)
|
||||
{
|
||||
pEntity = UTIL_FindEntityByTargetname(NULL,STRING(m_iTargetName[i]), pActivator);
|
||||
if (pEntity != NULL);
|
||||
else continue;
|
||||
b = FALSE;
|
||||
|
||||
switch (pEntity->GetState())
|
||||
{
|
||||
case STATE_ON: if(m_iTargetState[i] == ST_ON) b = TRUE; break;
|
||||
case STATE_OFF: if(m_iTargetState[i] == ST_OFF) b = TRUE; break;
|
||||
case STATE_TURN_ON: if(m_iTargetState[i] == ST_TURNON) b = TRUE; break;
|
||||
case STATE_TURN_OFF: if(m_iTargetState[i] == ST_TURNOFF) b = TRUE; break;
|
||||
case STATE_IN_USE: if(m_iTargetState[i] == ST_IN_USE) b = TRUE; break;
|
||||
}
|
||||
// handle the states for this logic mode
|
||||
if (b)
|
||||
{
|
||||
switch (pev->button)
|
||||
{
|
||||
case LOGIC_OR: return TRUE;
|
||||
case LOGIC_NOR: return FALSE;
|
||||
case LOGIC_XOR:
|
||||
if(xorgot) return FALSE;
|
||||
xorgot = TRUE;
|
||||
break;
|
||||
case LOGIC_XNOR:
|
||||
if(xorgot) return TRUE;
|
||||
xorgot = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // b is false
|
||||
{
|
||||
switch (pev->button)
|
||||
{
|
||||
case LOGIC_AND: return FALSE;
|
||||
case LOGIC_NAND: return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle the default cases for each logic mode
|
||||
switch (pev->button)
|
||||
{
|
||||
case LOGIC_AND:
|
||||
case LOGIC_NOR: return TRUE;
|
||||
case LOGIC_XOR: return xorgot;
|
||||
case LOGIC_XNOR: return !xorgot;
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
LINK_ENTITY_TO_CLASS( func_soundfx, CTriggerSound ); // Xash 0.4 compatibility
|
||||
|
||||
//=======================================================================
|
||||
// trigger_changelevel - classic HALF_LIFE changelevel
|
||||
|
@ -1131,10 +637,14 @@ void CTriggerHurt :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP
|
|||
{
|
||||
pev->dmg = value;//set dmg level
|
||||
}
|
||||
else if (useType == USE_RESET)
|
||||
{
|
||||
pev->dmg = 0;//reset dmg level
|
||||
}
|
||||
else if (useType == USE_SHOWINFO)
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg( "State: %s, Dmg value %g\n", GetStringForState( GetState()), pev->dmg);
|
||||
ALERT( at_console, "State: %s, Dmg value %g\n", GetStringForState( GetState()), pev->dmg );
|
||||
PrintStringForDamage( pev->button );
|
||||
}
|
||||
|
||||
|
@ -1222,19 +732,18 @@ void CTriggerHurt :: Think( void )
|
|||
//=======================================================================
|
||||
// trigger_transition - area that moving all entities inside across level
|
||||
//=======================================================================
|
||||
class CVolumeTransition : public CPointEntity // Don't change this!
|
||||
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 = NULL;
|
||||
pev->modelindex = 0;
|
||||
UTIL_SetModel( ENT( pev ), pev->model );
|
||||
pev->model = pev->modelindex = 0;
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( trigger_transition, CVolumeTransition );
|
||||
LINK_ENTITY_TO_CLASS( trigger_transition, CTriggerTransition );
|
||||
|
||||
//=======================================================================
|
||||
// trigger_camera - generic camera
|
||||
|
@ -1258,23 +767,23 @@ class CTriggerCamera : public CBaseLogic
|
|||
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
|
||||
#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"))
|
||||
if (FStrEq( pkvd->szKeyName, "viewentity" ))
|
||||
{
|
||||
pev->netname = ALLOC_STRING(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "moveto"))
|
||||
else if (FStrEq( pkvd->szKeyName, "moveto" ))
|
||||
{
|
||||
pev->message = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
else CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CTriggerCamera :: Spawn (void )
|
||||
|
@ -1284,29 +793,29 @@ void CTriggerCamera :: Spawn (void )
|
|||
|
||||
m_iState = STATE_OFF;
|
||||
|
||||
UTIL_SetModel(ENT(pev),"models/common/null.mdl");
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
||||
UTIL_SetModel( ENT( pev ), "models/common/null.mdl" );
|
||||
UTIL_SetSize( pev, g_vecZero, g_vecZero );
|
||||
SetBits( pev->flags, FL_POINTENTITY );
|
||||
}
|
||||
|
||||
void CTriggerCamera::PostSpawn( void )
|
||||
{
|
||||
m_pGoalEnt = UTIL_FindEntityByTargetname (NULL, STRING(pev->message));
|
||||
if(m_pGoalEnt) UTIL_SetOrigin( this, m_pGoalEnt->pev->origin );
|
||||
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 );
|
||||
// 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))
|
||||
if (FStrEq( STRING( pev->target ), "player" ) || ( pev->spawnflags & SF_CAMERA_PLAYER_TARGET ))
|
||||
pTarget = UTIL_PlayerByIndex( 1 );
|
||||
else pTarget = UTIL_FindEntityByTargetname( NULL, STRING(pev->target) );
|
||||
else pTarget = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ));
|
||||
}
|
||||
|
||||
void CTriggerCamera::Think( void )
|
||||
|
@ -1316,50 +825,88 @@ void CTriggerCamera::Think( void )
|
|||
Move();
|
||||
pev->dmgtime = gpGlobals->time;
|
||||
if ( pTarget ) UTIL_WatchTarget( this, pTarget );
|
||||
if(m_flWait && pev->teleport_time < gpGlobals->time) TurnOff();
|
||||
|
||||
if( m_flWait && pev->health < gpGlobals->time )
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
}
|
||||
|
||||
void CTriggerCamera :: UpdatePlayerView( void )
|
||||
{
|
||||
int flags;
|
||||
int flags = 0;
|
||||
|
||||
if(pev->spawnflags & SF_CAMERA_PLAYER_TAKECONTROL) //freeze player
|
||||
((CBasePlayer *)((CBaseEntity *)m_hActivator))->EnableControl(GetState() ? FALSE : TRUE );
|
||||
if(GetState() == STATE_OFF) flags = 0;
|
||||
else flags |= CAMERA_ON;
|
||||
CBaseEntity *pCamera = UTIL_FindEntityByTargetname( NULL, STRING(pev->netname) );
|
||||
if(pCamera && !pCamera->IsBSPModel()) UTIL_SetView( (CBaseEntity *)m_hActivator, pCamera, flags );
|
||||
else UTIL_SetView( (CBaseEntity *)m_hActivator, this, flags );
|
||||
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( 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 );
|
||||
}
|
||||
|
||||
void CTriggerCamera :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if(pActivator && pActivator->IsPlayer())//only at player
|
||||
if( pActivator && pActivator->IsPlayer( ))
|
||||
{
|
||||
m_hActivator = pActivator;//save activator
|
||||
// only at player
|
||||
m_hActivator = pActivator;
|
||||
}
|
||||
else m_hActivator = UTIL_PlayerByIndex( 1 );
|
||||
|
||||
if (useType == USE_TOGGLE)
|
||||
else if( !IsMultiplayer( ))
|
||||
{
|
||||
if(m_iState == STATE_OFF) useType = USE_ON;
|
||||
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)
|
||||
if ( useType == USE_ON )
|
||||
{
|
||||
Msg("======/Xash Debug System/======\n");
|
||||
Msg("classname: %s\n", STRING(pev->classname));
|
||||
Msg("State: %s, Look at %s\n", GetStringForState( GetState()), pev->netname ? STRING(pev->netname) : STRING(pev->targetname));
|
||||
Msg("Speed: %g Camera target: %s\n", pev->speed, pTarget ? STRING(pTarget->pev->targetname) : "None" );
|
||||
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;
|
||||
if ( !m_pGoalEnt ) return;
|
||||
|
||||
// Subtract movement from the previous frame
|
||||
pev->frags -= pev->speed * gpGlobals->frametime;
|
||||
|
@ -1368,17 +915,13 @@ void CTriggerCamera::Move( void )
|
|||
if ( pev->frags <= 0 )
|
||||
{
|
||||
// Fire the passtarget if there is one
|
||||
UTIL_FireTargets(m_pGoalEnt->pev->message, this, this, USE_TOGGLE );
|
||||
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_FIREONCE ) ) m_pGoalEnt->pev->message = iStringNull;
|
||||
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_TELEPORT ) )
|
||||
UTIL_FireTargets(m_pGoalEnt->pev->target, this, this, USE_TOGGLE );
|
||||
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_FIREONCE ) ) m_pGoalEnt->pev->target = iStringNull;
|
||||
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_TELEPORT_TONEXT ) )
|
||||
{
|
||||
m_pGoalEnt = m_pGoalEnt->GetNext();
|
||||
if ( m_pGoalEnt ) UTIL_AssignOrigin( this, m_pGoalEnt->pev->origin);
|
||||
}
|
||||
if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_WAITTRIG ) )
|
||||
{
|
||||
//strange feature...
|
||||
}
|
||||
|
||||
// Time to go to the next target
|
||||
m_pGoalEnt = m_pGoalEnt->GetNext();
|
||||
|
@ -1387,48 +930,44 @@ void CTriggerCamera::Move( void )
|
|||
if ( !m_pGoalEnt ) UTIL_SetVelocity( this, g_vecZero );
|
||||
else
|
||||
{
|
||||
pev->message = m_pGoalEnt->pev->targetname; //save last corner
|
||||
((CPathCorner *)m_pGoalEnt)->GetSpeed( &pev->armorvalue );
|
||||
pev->target = m_pGoalEnt->pev->targetname; //save last corner
|
||||
((CInfoPath *)m_pGoalEnt)->GetSpeed( &pev->armorvalue );
|
||||
|
||||
Vector delta = m_pGoalEnt->pev->origin - pev->origin;
|
||||
pev->frags = delta.Length();
|
||||
pev->movedir = delta.Normalize();
|
||||
m_flDelay = gpGlobals->time + m_pGoalEnt->GetDelay();
|
||||
m_flDelay = gpGlobals->time + ((CInfoPath *)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 );
|
||||
else pev->speed = UTIL_Approach( pev->armorvalue, pev->speed, 500 * gpGlobals->frametime );
|
||||
|
||||
if(!pTarget)UTIL_WatchTarget( this, m_pGoalEnt );//watch for track
|
||||
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)));
|
||||
UTIL_SetVelocity( this, ((pev->movedir * pev->speed) * fraction) + (pev->velocity * ( 1.0f - fraction )));
|
||||
}
|
||||
|
||||
void CTriggerCamera::TurnOff( void )
|
||||
{
|
||||
m_iState = STATE_OFF;
|
||||
if(m_pGoalEnt) m_pGoalEnt = m_pGoalEnt->GetPrev();
|
||||
if( m_pGoalEnt ) m_pGoalEnt = m_pGoalEnt->GetPrev();
|
||||
UTIL_SetVelocity( this, g_vecZero );
|
||||
UTIL_SetAvelocity( this, g_vecZero );
|
||||
UpdatePlayerView();
|
||||
FireTargets();
|
||||
m_iState = STATE_OFF;
|
||||
DontThink();
|
||||
}
|
||||
|
||||
void CTriggerCamera::TurnOn( void )
|
||||
{
|
||||
pev->dmgtime = gpGlobals->time;
|
||||
m_iState = STATE_ON;
|
||||
|
||||
pev->armorvalue = pev->speed;
|
||||
m_flDelay = gpGlobals->time;
|
||||
pev->frags = 0;
|
||||
|
||||
// copy over player information
|
||||
if (pev->spawnflags & SF_CAMERA_PLAYER_POSITION )
|
||||
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;
|
||||
|
@ -1438,10 +977,11 @@ void CTriggerCamera::TurnOn( void )
|
|||
ClearBits( pev->spawnflags, SF_CAMERA_PLAYER_POSITION );
|
||||
}
|
||||
|
||||
//time-based camera
|
||||
if(m_flWait)pev->teleport_time = gpGlobals->time + m_flWait;
|
||||
// time-based camera
|
||||
if( m_flWait ) pev->health = gpGlobals->time + m_flWait;
|
||||
|
||||
Move();
|
||||
UpdatePlayerView();
|
||||
m_iState = STATE_ON;
|
||||
SetNextThink( 0 );
|
||||
}
|
|
@ -1,405 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) Shambler Team 2004
|
||||
// util_.cpp - utility entities: util_fade,
|
||||
// util_shake, util_changehud etc
|
||||
//=======================================================================
|
||||
|
||||
#include "extdll.h"
|
||||
#include "utils.h"
|
||||
#include "cbase.h"
|
||||
#include "saverestore.h"
|
||||
#include "player.h"
|
||||
#include "defaults.h"
|
||||
#include "shake.h"
|
||||
|
||||
//=====================================================
|
||||
// util_changehud: change player hud
|
||||
//=====================================================
|
||||
class CUtilChangeHUD : public CBaseLogic
|
||||
{
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void KeyValue( KeyValueData* );
|
||||
void SetHUD( int hud_num );
|
||||
void ResetHUD( void );
|
||||
char* GetStringForMode( void );
|
||||
};
|
||||
|
||||
void CUtilChangeHUD :: KeyValue( KeyValueData* pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "hud"))
|
||||
{
|
||||
pev->skin = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseEntity::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CUtilChangeHUD :: SetHUD( int hud_num )
|
||||
{
|
||||
m_iState = STATE_ON;
|
||||
((CBasePlayer *)((CBaseEntity *)m_hActivator))->m_iWarHUD = pev->skin = hud_num;
|
||||
}
|
||||
|
||||
void CUtilChangeHUD :: ResetHUD( void )
|
||||
{
|
||||
m_iState = STATE_OFF;
|
||||
((CBasePlayer *)((CBaseEntity *)m_hActivator))->m_iWarHUD = 0;
|
||||
((CBasePlayer *)((CBaseEntity *)m_hActivator))->fadeNeedsUpdate = 1;
|
||||
}
|
||||
|
||||
void CUtilChangeHUD :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if(pActivator && pActivator->IsPlayer())//only at player
|
||||
{
|
||||
m_hActivator = pActivator;//save activator
|
||||
}
|
||||
else m_hActivator = UTIL_PlayerByIndex( 1 );
|
||||
|
||||
if (useType == USE_TOGGLE)
|
||||
{
|
||||
if(m_iState == STATE_OFF) useType = USE_ON;
|
||||
else useType = USE_OFF;
|
||||
}
|
||||
if (useType == USE_ON ) SetHUD( pev->skin );
|
||||
else if (useType == USE_OFF) ResetHUD();
|
||||
else if (useType == USE_SET)
|
||||
{
|
||||
if(value) SetHUD( value );
|
||||
else ResetHUD();
|
||||
}
|
||||
else if (useType == USE_RESET) ResetHUD();
|
||||
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, HUD Mode: %s\n", GetStringForState( GetState()), GetStringForMode());
|
||||
SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
char* CUtilChangeHUD :: GetStringForMode( void )
|
||||
{
|
||||
switch(pev->skin)
|
||||
{
|
||||
case 0: return "Disable Custom HUD";
|
||||
case 1: return "Draw Redeemer HUD";
|
||||
case 2: return "Draw Redeemer Underwater HUD";
|
||||
case 3: return "Draw Redeemer Noise Screen";
|
||||
case 4: return "Draw Security Camera Screen";
|
||||
default: return "Draw None";
|
||||
}
|
||||
}
|
||||
LINK_ENTITY_TO_CLASS( util_changehud, CUtilChangeHUD );
|
||||
|
||||
//=====================================================
|
||||
// util_command: activate a console command
|
||||
//=====================================================
|
||||
class CUtilCommand : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void PostActvaite( void )
|
||||
{
|
||||
if(pev->spawnflags & SF_START_ON) Use( this, this, USE_ON, 0 );
|
||||
}
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
char szCommand[256];
|
||||
|
||||
if (useType == USE_SHOWINFO)
|
||||
{
|
||||
ALERT(at_console, "======/Xash Debug System/======\n");
|
||||
ALERT(at_console, "classname: %s\n", STRING(pev->classname));
|
||||
ALERT(at_console, "Command: %s\n", STRING(pev->netname));
|
||||
SHIFT;
|
||||
}
|
||||
else if (pev->netname)
|
||||
{
|
||||
const char *pString = (char *)STRING( pev->netname );
|
||||
int command, namelen = strlen(pString) - 1;
|
||||
if( namelen > 2) command = pev->netname;//command name
|
||||
else command = atoi( pString );
|
||||
switch( command )
|
||||
{
|
||||
case 0: strcpy( szCommand, "pause\n" ); break; //pause level
|
||||
case 1: strcpy( szCommand, "reload\n" ); break; //revert to saved game
|
||||
case 2: strcpy( szCommand, "game_over\n" ); break;//turn to menu
|
||||
case 3: strcpy( szCommand, "autosave\n" ); break; //autosave game
|
||||
case 4: strcpy( szCommand, "restart\n" ); break; //restart level
|
||||
case 5: strcpy( szCommand, "save quick\n" ); break; //emaulate F6
|
||||
case 6: strcpy( szCommand, "load quick\n" ); break; //emulate F7
|
||||
case 7: strcpy( szCommand, "exit\n" ); break; //return to windows
|
||||
case 8: strcpy( szCommand, "gametitle\n" ); break; //show game title
|
||||
case 9: strcpy( szCommand, "intermission\n" ); break; //show intermission
|
||||
default: sprintf( szCommand, "%s\n", STRING(pev->netname) ); break; //custom command
|
||||
}
|
||||
SERVER_COMMAND( szCommand );
|
||||
if ( pev->spawnflags & SF_FIREONCE ) UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( util_command, CUtilCommand );
|
||||
|
||||
//=========================================================
|
||||
// display message text
|
||||
//=========================================================
|
||||
class CGameText : public CBaseLogic
|
||||
{
|
||||
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[];
|
||||
private:
|
||||
hudtextparms_t m_textParms;
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( util_msgtext, CGameText );
|
||||
|
||||
TYPEDESCRIPTION CGameText::m_SaveData[] =
|
||||
{ DEFINE_ARRAY( CGameText, m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ),
|
||||
};IMPLEMENT_SAVERESTORE( CGameText, CBaseLogic );
|
||||
|
||||
|
||||
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 CBaseLogic::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CGameText::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBaseEntity *pPlayer = NULL;
|
||||
if ( IsMultiplayer())UTIL_HudMessageAll( m_textParms, STRING(pev->message) );
|
||||
else
|
||||
{
|
||||
if ( pActivator && pActivator->IsPlayer() ) pPlayer = pActivator;
|
||||
else pPlayer = UTIL_PlayerByIndex( 1 );
|
||||
}
|
||||
if ( pPlayer ) UTIL_HudMessage( pPlayer, m_textParms, STRING(pev->message));
|
||||
if ( pev->spawnflags & SF_FIREONCE ) UTIL_Remove( this );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// remove all items
|
||||
//=========================================================
|
||||
#define SF_REMOVE_SUIT 1
|
||||
|
||||
class CUtilStripWeapons : public CPointEntity
|
||||
{
|
||||
public:
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBasePlayer *pPlayer = NULL;
|
||||
|
||||
if ( pActivator && pActivator->IsPlayer() ) pPlayer = (CBasePlayer *)pActivator;
|
||||
else pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( 1 );
|
||||
if ( pPlayer ) pPlayer->RemoveAllItems( pev->spawnflags & SF_REMOVE_SUIT );
|
||||
if ( pev->spawnflags & SF_FIREONCE ) UTIL_Remove( this );
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( util_weaponstrip, CUtilStripWeapons );
|
||||
|
||||
//=========================================================
|
||||
// set global fog on a map
|
||||
//=========================================================
|
||||
class CUtilSetFog : public CBaseLogic
|
||||
{
|
||||
public:
|
||||
void PostActivate( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
void TurnOn( void );
|
||||
void TurnOff( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( util_setfog, CUtilSetFog );
|
||||
|
||||
void CUtilSetFog :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "startdist"))
|
||||
{
|
||||
pev->dmg_take = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "enddist"))
|
||||
{
|
||||
pev->dmg_save = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "fadetime"))
|
||||
{
|
||||
m_flDelay = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else CBaseEntity::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CUtilSetFog :: PostActivate ( void )
|
||||
{
|
||||
pev->effects |= EF_NODRAW;
|
||||
if (pev->spawnflags & SF_START_ON)
|
||||
{
|
||||
TurnOn();
|
||||
ClearBits(pev->spawnflags, SF_START_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void CUtilSetFog :: TurnOn ( void )
|
||||
{
|
||||
m_iState = STATE_ON;
|
||||
UTIL_SetFogAll(pev->rendercolor, m_flDelay, pev->dmg_take, pev->dmg_save );
|
||||
}
|
||||
|
||||
void CUtilSetFog :: TurnOff ( void )
|
||||
{
|
||||
m_iState = STATE_OFF;
|
||||
UTIL_SetFogAll(pev->rendercolor, -m_flDelay, pev->dmg_take, pev->dmg_save );
|
||||
}
|
||||
|
||||
void CUtilSetFog :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if (useType == USE_TOGGLE)
|
||||
{
|
||||
if(m_iState == STATE_ON) useType = USE_OFF;
|
||||
else useType = USE_ON;
|
||||
}
|
||||
if (useType == USE_ON) TurnOn();
|
||||
else if ( useType == USE_OFF ) TurnOff();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// UTIL_RainModify (set new rain or snow)
|
||||
//=========================================================
|
||||
void CUtilRainModify::Spawn()
|
||||
{
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->effects |= EF_NODRAW;
|
||||
|
||||
if (IsMultiplayer() || FStringNull( pev->targetname))
|
||||
SetBits( pev->spawnflags, SF_START_ON );
|
||||
}
|
||||
|
||||
TYPEDESCRIPTION CUtilRainModify::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CUtilRainModify, randXY, FIELD_RANGE ),
|
||||
DEFINE_FIELD( CUtilRainModify, windXY, FIELD_RANGE ),
|
||||
};
|
||||
IMPLEMENT_SAVERESTORE( CUtilRainModify, CPointEntity );
|
||||
|
||||
void CUtilRainModify::KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "drips"))
|
||||
{
|
||||
pev->button = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "fadetime"))
|
||||
{
|
||||
pev->dmg = atof(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "rand"))
|
||||
{
|
||||
randXY = RandomRange(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "wind"))
|
||||
{
|
||||
windXY = RandomRange(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CUtilRainModify::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if(useType == USE_SHOWINFO)
|
||||
{
|
||||
DEBUGHEAD;
|
||||
Msg("Wind X: %g Y: %g. Rand X: %g Y: %g\n", windXY[1], windXY[0], randXY[1], randXY[0] );
|
||||
Msg("Fade time %g. Drips per second %d\n", pev->dmg, pev->button );
|
||||
}
|
||||
else if(!pev->spawnflags & SF_START_ON)
|
||||
{
|
||||
CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(1);
|
||||
if (pev->dmg)
|
||||
{
|
||||
pPlayer->Rain_ideal_dripsPerSecond = pev->button;
|
||||
pPlayer->Rain_ideal_randX = randXY[1];
|
||||
pPlayer->Rain_ideal_randY = randXY[0];
|
||||
pPlayer->Rain_ideal_windX = windXY[1];
|
||||
pPlayer->Rain_ideal_windY = windXY[0];
|
||||
pPlayer->Rain_endFade = gpGlobals->time + pev->dmg;
|
||||
pPlayer->Rain_nextFadeUpdate = gpGlobals->time + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPlayer->Rain_dripsPerSecond = pev->button;
|
||||
pPlayer->Rain_randX = randXY[1];
|
||||
pPlayer->Rain_randY = randXY[0];
|
||||
pPlayer->Rain_windX = windXY[1];
|
||||
pPlayer->Rain_windY = windXY[0];
|
||||
pPlayer->rainNeedsUpdate = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
LINK_ENTITY_TO_CLASS( util_rainmodify, CUtilRainModify );
|
|
@ -19,8 +19,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd )
|
|||
{
|
||||
if( FStrEq( pkvd->szKeyName, "skyname" ))
|
||||
{
|
||||
// Sent over net now.
|
||||
SET_SKYBOX( pkvd->szValue );
|
||||
pev->target = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "chaptertitle") )
|
||||
|
@ -44,16 +43,28 @@ void CWorld :: Spawn( void )
|
|||
|
||||
void CWorld :: PostActivate( void )
|
||||
{
|
||||
//run post messages
|
||||
// run post messages
|
||||
if ( pev->netname )
|
||||
{
|
||||
UTIL_ShowMessageAll( STRING(pev->netname) );
|
||||
pev->netname = iStringNull;
|
||||
}
|
||||
|
||||
if ( pev->spawnflags & SF_START_ON )
|
||||
{
|
||||
SERVER_COMMAND( "gametitle\n" );
|
||||
ClearBits( pev->spawnflags, SF_START_ON );
|
||||
}
|
||||
|
||||
if ( pev->target )
|
||||
{
|
||||
// Sent over net now.
|
||||
SET_SKYBOX( STRING( pev->target ));
|
||||
}
|
||||
else
|
||||
{
|
||||
// tell engine there is no skybox set
|
||||
SET_SKYBOX( "<skybox>" );
|
||||
}
|
||||
}
|
||||
LINK_ENTITY_TO_CLASS( worldspawn, CWorld );
|
|
@ -0,0 +1,961 @@
|
|||
/***
|
||||
*
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1227,7 +1227,12 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
|
|||
{
|
||||
to->body = DirToBits( pNet->pev->movedir );
|
||||
|
||||
// FIXME: send mins\maxs for sound spatialization and entity prediction ?
|
||||
if( pNet->pev->movetype == MOVETYPE_CONVEYOR || pNet->pev->flags & FL_CONVEYOR )
|
||||
{
|
||||
// this is conveyor - send speed to render for right texture scrolling
|
||||
to->framerate = pNet->pev->speed;
|
||||
}
|
||||
else to->framerate = 0.0f; // don't let texture moving
|
||||
}
|
||||
else if( to->ed_type == ED_BEAM )
|
||||
{
|
||||
|
@ -1647,31 +1652,27 @@ void LinkUserMessages( void )
|
|||
gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 );
|
||||
gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 );
|
||||
gmsg.Shake = REG_USER_MSG( "ScreenShake", 13 );
|
||||
gmsg.Fade = REG_USER_MSG( "ScreenFade", 14 );
|
||||
gmsg.AmmoX = REG_USER_MSG("AmmoX", 2);
|
||||
gmsg.Fade = REG_USER_MSG( "ScreenFade", 13 );
|
||||
gmsg.AmmoX = REG_USER_MSG( "AmmoX", 2 );
|
||||
gmsg.TeamNames = REG_USER_MSG( "TeamNames", -1 );
|
||||
gmsg.StatusText = REG_USER_MSG("StatusText", -1);
|
||||
gmsg.StatusValue = REG_USER_MSG("StatusValue", 3);
|
||||
gmsg.SetBody = REG_USER_MSG("SetBody", 1);
|
||||
gmsg.SetSkin = REG_USER_MSG("SetSkin", 1);
|
||||
gmsg.ZoomHUD = REG_USER_MSG("ZoomHUD", 1);
|
||||
gmsg.WarHUD = REG_USER_MSG("WarHUD", 1);
|
||||
gmsg.StatusText = REG_USER_MSG( "StatusText", -1 );
|
||||
gmsg.StatusValue = REG_USER_MSG( "StatusValue", 3 );
|
||||
gmsg.SetBody = REG_USER_MSG( "SetBody", 1 );
|
||||
gmsg.SetSkin = REG_USER_MSG( "SetSkin", 1 );
|
||||
gmsg.ZoomHUD = REG_USER_MSG( "ZoomHUD", 1 );
|
||||
gmsg.WarHUD = REG_USER_MSG( "WarHUD", 1 );
|
||||
|
||||
// entity messages
|
||||
gmsg.StatusIcon = REG_USER_MSG("StatusIcon", -1);
|
||||
gmsg.CamData = REG_USER_MSG("CamData", -1);
|
||||
gmsg.Fsound = REG_USER_MSG("Fsound", -1);
|
||||
gmsg.RainData = REG_USER_MSG( "RainData", 28 );
|
||||
gmsg.AddScreen = REG_USER_MSG( "AddScreen", 2);
|
||||
gmsg.AddPortal = REG_USER_MSG( "AddPortal", 2);
|
||||
gmsg.HudText = REG_USER_MSG( "HudText", -1 );
|
||||
gmsg.ShowGameTitle = REG_USER_MSG("GameTitle", 0 );
|
||||
gmsg.TempEntity = REG_USER_MSG( "TempEntity", -1);
|
||||
gmsg.SetFog = REG_USER_MSG("SetFog", 7 );
|
||||
gmsg.SetSky = REG_USER_MSG( "SetSky", 13 );
|
||||
gmsg.Particle = REG_USER_MSG( "Particle", -1);
|
||||
gmsg.Beams = REG_USER_MSG( "Beams", -1 );
|
||||
gmsg.AddMirror = REG_USER_MSG( "AddMirror", 2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -104,10 +104,6 @@ typedef struct user_messages_s
|
|||
int RainData;
|
||||
int HudText;
|
||||
int ShowGameTitle;
|
||||
int AddScreen;
|
||||
int AddMirror;
|
||||
int AddPortal;
|
||||
int Beams;
|
||||
} user_messages_t;
|
||||
|
||||
extern user_messages_t gmsg;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
// Debug macros
|
||||
//=========================
|
||||
#define SHIFT Msg("\n")
|
||||
#define ACTION Msg("Action!\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 )
|
||||
|
|
|
@ -134,10 +134,10 @@ void UTIL_FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEnt
|
|||
int i,j, found = false;
|
||||
char szBuf[80];
|
||||
|
||||
if ( !targetName )return;
|
||||
if ( !targetName ) return;
|
||||
|
||||
//HACKHACK
|
||||
if(FStrEq(targetName, "tr_endchange" ))
|
||||
// HACKHACK
|
||||
if( FStrEq( targetName, "tr_endchange" ))
|
||||
{
|
||||
SERVER_COMMAND("game_over\n");
|
||||
return;
|
||||
|
@ -221,11 +221,11 @@ void UTIL_FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEnt
|
|||
targetName = szBuf;
|
||||
pTarget = UTIL_FindEntityByTargetname(NULL, targetName, inputActivator);
|
||||
|
||||
if (!pTarget)return; // it's a locus specifier all right, but the target's invalid.
|
||||
if( !pTarget ) return; // it's a locus specifier all right, but the target's invalid.
|
||||
}
|
||||
}
|
||||
|
||||
DevMsg( "Firing: (%s) with %s and value %g\n", targetName, GetStringForUseType( useType ), value );
|
||||
ALERT( at_aiconsole, "Firing: (%s) with %s and value %g\n", targetName, GetStringForUseType( useType ), value );
|
||||
|
||||
do //start firing targets
|
||||
{
|
||||
|
@ -1164,6 +1164,7 @@ int UTIL_PrecacheAurora( const char *s )
|
|||
if( !afile )
|
||||
{
|
||||
// verify file exists
|
||||
ALERT( at_warning, "couldn't load %s\n", path );
|
||||
return MAKE_STRING( "scripts/aurora/error.aur" );
|
||||
}
|
||||
|
||||
|
@ -1192,17 +1193,6 @@ void UTIL_SetAurora( CBaseEntity *pAttach, int aur, int attachment )
|
|||
WRITE_STRING( STRING( aur ));
|
||||
MESSAGE_END();
|
||||
}
|
||||
//========================================================================
|
||||
// Set client beams
|
||||
//========================================================================
|
||||
void UTIL_SetBeams( char *szFile, CBaseEntity *pStart, CBaseEntity *pEnd )
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsg.Beams );
|
||||
WRITE_STRING( szFile );
|
||||
WRITE_BYTE( pStart->entindex()); // beam start entity
|
||||
WRITE_BYTE( pEnd->entindex() ); // beam end entity
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
// Precaches and play sound
|
||||
|
@ -1390,8 +1380,8 @@ void UTIL_PrecacheResourse( void )
|
|||
g_sModelIndexNullSprite = UTIL_PrecacheModel("sprites/null.spr");
|
||||
|
||||
// global sprites and models
|
||||
g_sModelIndexFireball = UTIL_PrecacheModel ("sprites/explode.spr");// fireball
|
||||
g_sModelIndexWExplosion = UTIL_PrecacheModel ("sprites/wxplode.spr");// underwater fireball
|
||||
g_sModelIndexFireball = UTIL_PrecacheModel ("sprites/zerogxplode.spr");// fireball
|
||||
g_sModelIndexWExplosion = UTIL_PrecacheModel ("sprites/WXplo1.spr");// underwater fireball
|
||||
g_sModelIndexSmoke = UTIL_PrecacheModel ("sprites/steam1.spr");// smoke
|
||||
g_sModelIndexBubbles = UTIL_PrecacheModel ("sprites/bubble.spr");//bubbles
|
||||
g_sModelIndexLaser = UTIL_PrecacheModel( "sprites/laserbeam.spr" );
|
||||
|
@ -2748,13 +2738,12 @@ void UTIL_Sparks( const Vector &position )
|
|||
void UTIL_Explode( const Vector ¢er, edict_t *pOwner, int radius, int name )
|
||||
{
|
||||
CBaseEntity *pExplosion = CBaseEntity::Create( "env_explosion", center, g_vecZero, pOwner );
|
||||
if( pExplosion )
|
||||
{
|
||||
if( name ) pExplosion->pev->classname = name;
|
||||
pExplosion->pev->dmg = radius;
|
||||
pExplosion->pev->owner = pOwner;
|
||||
pExplosion->Use( NULL, NULL, USE_ON, 0 );
|
||||
}
|
||||
if( !pExplosion ) return;
|
||||
|
||||
if( name ) pExplosion->pev->classname = name;
|
||||
pExplosion->pev->dmg = radius;
|
||||
pExplosion->pev->spawnflags |= SF_FIREONCE; //remove entity after explode
|
||||
pExplosion->Use( NULL, NULL, USE_ON, 0 );
|
||||
}
|
||||
|
||||
void UTIL_Ricochet( const Vector &position, float scale )
|
||||
|
@ -3105,8 +3094,8 @@ int HaveCamerasInPVS( edict_t* edict )
|
|||
}
|
||||
void UTIL_SetView( int ViewEntity, int flags )
|
||||
{
|
||||
//Light version SetView
|
||||
//Please don't use this in multiplayer
|
||||
// light version of SetView
|
||||
// please don't use this in multiplayer
|
||||
CBaseEntity *m_pPlayer = UTIL_PlayerByIndex( 1 );
|
||||
UTIL_SetView( m_pPlayer, ViewEntity, flags );
|
||||
}
|
||||
|
@ -3115,14 +3104,14 @@ void UTIL_SetView( CBaseEntity *pActivator, int ViewEntity, int flags )
|
|||
{
|
||||
CBaseEntity *pViewEnt = 0;
|
||||
|
||||
if(ViewEntity)
|
||||
if ( ViewEntity )
|
||||
{
|
||||
//try to find by targetname
|
||||
pViewEnt = UTIL_FindEntityByString( NULL, "targetname", STRING(ViewEntity));
|
||||
//try to find by classname
|
||||
if(FNullEnt(pViewEnt))
|
||||
pViewEnt = UTIL_FindEntityByString( NULL, "classname", STRING(ViewEntity));
|
||||
if(pViewEnt && pViewEnt->pev->flags & FL_MONSTER) flags |= MONSTER_VIEW;//detect monster view
|
||||
// try to find by targetname
|
||||
pViewEnt = UTIL_FindEntityByString( NULL, "targetname", STRING( ViewEntity ));
|
||||
// try to find by classname
|
||||
if( FNullEnt( pViewEnt ))
|
||||
pViewEnt = UTIL_FindEntityByString( NULL, "classname", STRING( ViewEntity ));
|
||||
if( pViewEnt && pViewEnt->pev->flags & FL_MONSTER ) flags |= MONSTER_VIEW; // detect monster view
|
||||
}
|
||||
UTIL_SetView( pActivator, pViewEnt, flags );
|
||||
}
|
||||
|
|
|
@ -744,7 +744,6 @@ void UTIL_PrecacheEntity( const char *szClassname );
|
|||
int UTIL_PrecacheAurora( string_t s );
|
||||
int UTIL_PrecacheAurora( const char *s );
|
||||
void UTIL_SetAurora( CBaseEntity *pAttach, int aur, int attachment = 0 );
|
||||
void UTIL_SetBeams( char *szFile, CBaseEntity *pStart, CBaseEntity *pEnd );
|
||||
|
||||
extern int giAmmoIndex;
|
||||
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/***
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****/
|
||||
//=========================================================
|
||||
// Monster Maker - this is an entity that creates monsters
|
||||
// in the game.
|
||||
//=========================================================
|
||||
|
||||
#include "extdll.h"
|
||||
#include "utils.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "saverestore.h"
|
||||
|
||||
// Monstermaker spawnflags
|
||||
#define SF_MONSTERMAKER_START_ON 1 // start active ( if has targetname )
|
||||
#define SF_MONSTERMAKER_CYCLIC 4 // drop one monster every time fired.
|
||||
#define SF_MONSTERMAKER_MONSTERCLIP 8 // Children are blocked by monsterclip
|
||||
#define SF_MONSTERMAKER_LEAVECORPSE 16 // Don't fade corpses.
|
||||
#define SF_MONSTERMAKER_NO_WPN_DROP 1024 // Corpses don't drop weapons.
|
||||
|
||||
//=========================================================
|
||||
// MonsterMaker - this ent creates monsters during the game.
|
||||
//=========================================================
|
||||
class CMonsterMaker : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void KeyValue( KeyValueData* pkvd);
|
||||
void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT CyclicUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT MakerThink ( void );
|
||||
void EXPORT MakeMonsterThink( void );
|
||||
void DeathNotice ( entvars_t *pevChild );// monster maker children use this to tell the monster maker that they have died.
|
||||
void TryMakeMonster( void ); //LRC - to allow for a spawndelay
|
||||
CBaseMonster* MakeMonster( void ); //LRC - actually make a monster (and return the new creation)
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
string_t m_iszMonsterClassname;// classname of the monster(s) that will be created.
|
||||
|
||||
int m_cNumMonsters;// max number of monsters this ent can create
|
||||
|
||||
|
||||
int m_cLiveChildren;// how many monsters made by this monster maker that are currently alive
|
||||
int m_iMaxLiveChildren;// max number of monsters that this maker may have out at one time.
|
||||
|
||||
float m_flGround; // z coord of the ground under me, used to make sure no monsters are under the maker when it drops a new child
|
||||
|
||||
BOOL m_fActive;
|
||||
BOOL m_fFadeChildren;// should we make the children fadeout?
|
||||
float m_fSpawnDelay;// LRC- delay between triggering targets and making a child (for env_warpball, mainly)
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monstermaker, CMonsterMaker );
|
||||
|
||||
TYPEDESCRIPTION CMonsterMaker::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CMonsterMaker, m_iszMonsterClassname, FIELD_STRING ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_cNumMonsters, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_cLiveChildren, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_flGround, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_iMaxLiveChildren, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fActive, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fFadeChildren, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CMonsterMaker, m_fSpawnDelay, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CMonsterMaker, CBaseMonster );
|
||||
|
||||
void CMonsterMaker :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
|
||||
if ( FStrEq(pkvd->szKeyName, "monstercount") )
|
||||
{
|
||||
m_cNumMonsters = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "m_imaxlivechildren") )
|
||||
{
|
||||
m_iMaxLiveChildren = atoi(pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "monstertype") )
|
||||
{
|
||||
m_iszMonsterClassname = ALLOC_STRING( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if ( FStrEq(pkvd->szKeyName, "spawndelay") )
|
||||
{
|
||||
m_fSpawnDelay = atof( pkvd->szValue );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseMonster::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
|
||||
void CMonsterMaker :: Spawn( )
|
||||
{
|
||||
pev->solid = SOLID_NOT;
|
||||
|
||||
m_cLiveChildren = 0;
|
||||
Precache();
|
||||
if ( !FStringNull ( pev->targetname ) )
|
||||
{
|
||||
if ( pev->spawnflags & SF_MONSTERMAKER_CYCLIC )
|
||||
{
|
||||
SetUse(&CMonsterMaker :: CyclicUse );// drop one monster each time we fire
|
||||
m_fActive = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetUse(&CMonsterMaker :: ToggleUse );// can be turned on/off
|
||||
|
||||
if ( FBitSet ( pev->spawnflags, SF_MONSTERMAKER_START_ON ) )
|
||||
{
|
||||
// start making monsters as soon as monstermaker spawns
|
||||
m_fActive = TRUE;
|
||||
SetThink(&CMonsterMaker :: MakerThink );
|
||||
}
|
||||
else
|
||||
{
|
||||
// wait to be activated.
|
||||
m_fActive = FALSE;
|
||||
DontThink();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{// no targetname, just start.
|
||||
SetNextThink( m_flDelay );
|
||||
m_fActive = TRUE;
|
||||
SetThink(&CMonsterMaker :: MakerThink );
|
||||
}
|
||||
|
||||
if ( m_cNumMonsters == 1 || (m_cNumMonsters != -1 && pev->spawnflags & SF_MONSTERMAKER_LEAVECORPSE ))
|
||||
{
|
||||
m_fFadeChildren = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fFadeChildren = TRUE;
|
||||
}
|
||||
|
||||
m_flGround = 0;
|
||||
}
|
||||
|
||||
void CMonsterMaker :: Precache( void )
|
||||
{
|
||||
CBaseMonster::Precache();
|
||||
|
||||
UTIL_PrecacheEntity( STRING( m_iszMonsterClassname ) );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// TryMakeMonster- check that it's ok to drop a monster.
|
||||
//=========================================================
|
||||
void CMonsterMaker::TryMakeMonster( void )
|
||||
{
|
||||
if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
|
||||
{// not allowed to make a new one yet. Too many live ones out right now.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_flGround )
|
||||
{
|
||||
// set altitude. Now that I'm activated, any breakables, etc should be out from under me.
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_TraceLine ( pev->origin, pev->origin - Vector ( 0, 0, 2048 ), ignore_monsters, ENT(pev), &tr );
|
||||
m_flGround = tr.vecEndPos.z;
|
||||
}
|
||||
|
||||
Vector mins = pev->origin - Vector( 34, 34, 0 );
|
||||
Vector maxs = pev->origin + Vector( 34, 34, 0 );
|
||||
maxs.z = pev->origin.z;
|
||||
mins.z = m_flGround;
|
||||
|
||||
CBaseEntity *pList[2];
|
||||
int count = UTIL_EntitiesInBox( pList, 2, mins, maxs, FL_CLIENT|FL_MONSTER );
|
||||
if ( count )
|
||||
{
|
||||
// don't build a stack of monsters!
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_fSpawnDelay)
|
||||
{
|
||||
// If I have a target, fire. (no locus)
|
||||
if ( !FStringNull ( pev->target ) )
|
||||
{
|
||||
// delay already overloaded for this entity, so can't call SUB_UseTargets()
|
||||
UTIL_FireTargets( STRING(pev->target), this, this, USE_TOGGLE, 0 );
|
||||
}
|
||||
|
||||
// ALERT(at_console,"Making Monster in %f seconds\n",m_fSpawnDelay);
|
||||
SetThink(&CMonsterMaker:: MakeMonsterThink );
|
||||
SetNextThink( m_fSpawnDelay );
|
||||
}
|
||||
else
|
||||
{
|
||||
// ALERT(at_console,"No delay. Making monster.\n",m_fSpawnDelay);
|
||||
CBaseMonster* pMonst = MakeMonster();
|
||||
|
||||
// If I have a target, fire! (the new monster is the locus)
|
||||
if ( !FStringNull ( pev->target ) )
|
||||
{
|
||||
UTIL_FireTargets( STRING(pev->target), pMonst, this, USE_TOGGLE, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// MakeMonsterThink- a really trivial think function
|
||||
//=========================================================
|
||||
void CMonsterMaker::MakeMonsterThink( void )
|
||||
{
|
||||
MakeMonster();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// MakeMonster- this is the code that drops the monster
|
||||
//=========================================================
|
||||
CBaseMonster* CMonsterMaker::MakeMonster( void )
|
||||
{
|
||||
edict_t *pent;
|
||||
entvars_t *pevCreate;
|
||||
|
||||
// ALERT(at_console,"Making Monster NOW\n");
|
||||
|
||||
pent = CREATE_NAMED_ENTITY( m_iszMonsterClassname );
|
||||
|
||||
if ( FNullEnt( pent ) )
|
||||
{
|
||||
ALERT ( at_console, "NULL Ent in MonsterMaker!\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pevCreate = VARS( pent );
|
||||
pevCreate->origin = pev->origin;
|
||||
pevCreate->angles = pev->angles;
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_FALL_TO_GROUND );
|
||||
|
||||
if (pev->spawnflags & SF_MONSTERMAKER_NO_WPN_DROP)
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_NO_WPN_DROP);
|
||||
|
||||
// Children hit monsterclip brushes
|
||||
if ( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_HITMONSTERCLIP );
|
||||
|
||||
DispatchSpawn( ENT( pevCreate ) );
|
||||
pevCreate->owner = edict();
|
||||
|
||||
//LRC - custom monster behaviour
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance( pevCreate );
|
||||
CBaseMonster *pMonst = NULL;
|
||||
if (pEntity && (pMonst = pEntity->MyMonsterPointer()) != NULL)
|
||||
{
|
||||
pMonst->m_iClass = this->m_iClass;
|
||||
pMonst->m_iPlayerReact = this->m_iPlayerReact;
|
||||
}
|
||||
|
||||
if ( !FStringNull( pev->netname ) )
|
||||
{
|
||||
// if I have a netname (overloaded), give the child monster that name as a targetname
|
||||
pevCreate->targetname = pev->netname;
|
||||
}
|
||||
|
||||
m_cLiveChildren++;// count this monster
|
||||
m_cNumMonsters--;
|
||||
|
||||
if ( m_cNumMonsters == 0 )
|
||||
{
|
||||
// Disable this forever. Don't kill it because it still gets death notices
|
||||
SetThink( NULL );
|
||||
SetUse( NULL );
|
||||
}
|
||||
else if (m_fActive)
|
||||
{
|
||||
SetNextThink( m_flDelay );
|
||||
SetThink(&CMonsterMaker:: MakerThink );
|
||||
}
|
||||
|
||||
return pMonst;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CyclicUse - drops one monster from the monstermaker
|
||||
// each time we call this.
|
||||
//=========================================================
|
||||
void CMonsterMaker::CyclicUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
TryMakeMonster();
|
||||
// ALERT(at_console,"CyclicUse complete\n");
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ToggleUse - activates/deactivates the monster maker
|
||||
//=========================================================
|
||||
void CMonsterMaker :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if ( useType == USE_TOGGLE )
|
||||
{
|
||||
if ( !m_fActive )
|
||||
useType = USE_ON;
|
||||
else useType = USE_OFF;
|
||||
}
|
||||
|
||||
if ( useType == USE_ON )
|
||||
{
|
||||
m_fActive = TRUE;
|
||||
SetThink(&CMonsterMaker :: MakerThink );
|
||||
}
|
||||
else if ( useType == USE_OFF )
|
||||
{
|
||||
m_fActive = FALSE;
|
||||
SetThink ( NULL );
|
||||
}
|
||||
SetNextThink( 0 );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// MakerThink - creates a new monster every so often
|
||||
//=========================================================
|
||||
void CMonsterMaker :: MakerThink ( void )
|
||||
{
|
||||
SetNextThink( m_flDelay );
|
||||
|
||||
TryMakeMonster();
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
//=========================================================
|
||||
void CMonsterMaker :: DeathNotice ( entvars_t *pevChild )
|
||||
{
|
||||
// ok, we've gotten the deathnotice from our child, now clear out its owner if we don't want it to fade.
|
||||
m_cLiveChildren--;
|
||||
|
||||
if ( !m_fFadeChildren )
|
||||
{
|
||||
pevChild->owner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ entvars_t* CGraph :: LinkEntForLink ( CLink *pLink, CNode *pNode )
|
|||
///!!!UNDONE - check for TOGGLE or STAY open doors here. If a door is in the way, and is
|
||||
// TOGGLE or STAY OPEN, even monsters that can't open doors can go that way.
|
||||
|
||||
if ( ( pevLinkEnt->spawnflags & SF_DOOR_USE_ONLY ) )
|
||||
if ( ( pevLinkEnt->team == 1 ) )
|
||||
{// door is use only, so the door is all the monster has to worry about
|
||||
return pevLinkEnt;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ int CGraph :: HandleLinkEnt ( int iNode, entvars_t *pevLinkEnt, int afCapMask, N
|
|||
|
||||
pDoor = ( CBaseEntity::Instance( pevLinkEnt ) );
|
||||
|
||||
if ( ( pevLinkEnt->spawnflags & SF_DOOR_USE_ONLY ) )
|
||||
if ( ( pevLinkEnt->team == 1 ) )
|
||||
{// door is use only.
|
||||
|
||||
if ( ( afCapMask & bits_CAP_OPEN_DOORS ) )
|
||||
|
@ -244,7 +244,7 @@ int CGraph :: HandleLinkEnt ( int iNode, entvars_t *pevLinkEnt, int afCapMask, N
|
|||
else
|
||||
{
|
||||
// monster should try for it if the door is open and looks as if it will stay that way
|
||||
if ( pDoor->GetState() == STATE_ON && ( pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN ))
|
||||
if ( pDoor->GetState() == STATE_ON && ( pevLinkEnt->impulse == 1 ))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -256,13 +256,13 @@ int CGraph :: HandleLinkEnt ( int iNode, entvars_t *pevLinkEnt, int afCapMask, N
|
|||
{// door must be opened with a button or trigger field.
|
||||
|
||||
// monster should try for it if the door is open and looks as if it will stay that way
|
||||
if ( pDoor->GetState() == STATE_ON && ( pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN ))
|
||||
if ( pDoor->GetState() == STATE_ON && ( pevLinkEnt->impulse == 1 ))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if ( ( afCapMask & bits_CAP_OPEN_DOORS ) )
|
||||
{
|
||||
if ( !( pevLinkEnt->spawnflags & SF_DOOR_NOMONSTERS ) || queryType == NODEGRAPH_STATIC )
|
||||
if ( queryType == NODEGRAPH_STATIC )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -3080,6 +3080,130 @@ const char *CBasePlayer::TeamID( void )
|
|||
return m_szTeamName;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// remove all items
|
||||
//=========================================================
|
||||
#define SF_REMOVE_SUIT 1
|
||||
|
||||
class CStripWeapons : public CPointEntity
|
||||
{
|
||||
public:
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBasePlayer *pPlayer = NULL;
|
||||
|
||||
if ( pActivator && pActivator->IsPlayer() )
|
||||
{
|
||||
pPlayer = (CBasePlayer *)pActivator;
|
||||
}
|
||||
else if ( !IsMultiplayer() )
|
||||
{
|
||||
pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ALERT( at_warning, "%s: %s activator not player. Ignored.\n", STRING( pev->classname ), STRING( pev->targetname ));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPlayer ) pPlayer->RemoveAllItems( pev->spawnflags & SF_REMOVE_SUIT );
|
||||
if ( pev->spawnflags & SF_FIREONCE ) UTIL_Remove( this );
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( player_weaponstrip, CStripWeapons );
|
||||
|
||||
class CRevertSaved : public CPointEntity
|
||||
{
|
||||
public:
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT MessageThink( void );
|
||||
void EXPORT LoadThink( void );
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
inline float Duration( void ) { return pev->dmg_take; }
|
||||
inline float HoldTime( void ) { return pev->dmg_save; }
|
||||
inline float MessageTime( void ) { return m_messageTime; }
|
||||
inline float LoadTime( void ) { return m_loadTime; }
|
||||
|
||||
inline void SetDuration( float duration ) { pev->dmg_take = duration; }
|
||||
inline void SetHoldTime( float hold ) { pev->dmg_save = hold; }
|
||||
inline void SetMessageTime( float time ) { m_messageTime = time; }
|
||||
inline void SetLoadTime( float time ) { m_loadTime = time; }
|
||||
|
||||
private:
|
||||
float m_messageTime;
|
||||
float m_loadTime;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( player_loadsaved, CRevertSaved );
|
||||
|
||||
TYPEDESCRIPTION CRevertSaved::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CRevertSaved, m_messageTime, FIELD_FLOAT ), // These are not actual times, but durations, so save as floats
|
||||
DEFINE_FIELD( CRevertSaved, m_loadTime, FIELD_FLOAT ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CRevertSaved, CPointEntity );
|
||||
|
||||
void CRevertSaved :: KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "duration"))
|
||||
{
|
||||
SetDuration( atof(pkvd->szValue) );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "holdtime"))
|
||||
{
|
||||
SetHoldTime( atof(pkvd->szValue) );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "messagetime"))
|
||||
{
|
||||
SetMessageTime( atof(pkvd->szValue) );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "loadtime"))
|
||||
{
|
||||
SetLoadTime( atof(pkvd->szValue) );
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CPointEntity::KeyValue( pkvd );
|
||||
}
|
||||
|
||||
void CRevertSaved :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, FFADE_OUT );
|
||||
SetNextThink( MessageTime() );
|
||||
SetThink(&CRevertSaved :: MessageThink );
|
||||
}
|
||||
|
||||
|
||||
void CRevertSaved :: MessageThink( void )
|
||||
{
|
||||
UTIL_ShowMessageAll( STRING(pev->message) );
|
||||
float nextThink = LoadTime() - MessageTime();
|
||||
if ( nextThink > 0 )
|
||||
{
|
||||
SetNextThink( nextThink );
|
||||
SetThink(&CRevertSaved :: LoadThink );
|
||||
}
|
||||
else
|
||||
LoadThink();
|
||||
}
|
||||
|
||||
|
||||
void CRevertSaved :: LoadThink( void )
|
||||
{
|
||||
if ( !gpGlobals->deathmatch )
|
||||
{
|
||||
SERVER_COMMAND("reload\n");
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
// !!!UNDONE:ultra temporary SprayCan entity to apply
|
||||
|
@ -3773,7 +3897,7 @@ void CBasePlayer :: UpdateClientData( void )
|
|||
MESSAGE_BEGIN( MSG_ONE, gmsg.Fade, NULL, pev );
|
||||
WRITE_FLOAT( m_flFadeTime );
|
||||
WRITE_FLOAT( m_flFadeHold );
|
||||
WRITE_SHORT( m_iFadeFlags ); // fade flags
|
||||
WRITE_BYTE( m_iFadeFlags ); // fade flags
|
||||
WRITE_BYTE( (byte)m_FadeColor.x ); // fade red
|
||||
WRITE_BYTE( (byte)m_FadeColor.y ); // fade green
|
||||
WRITE_BYTE( (byte)m_FadeColor.z ); // fade blue
|
||||
|
@ -3967,14 +4091,14 @@ void CBasePlayer :: UpdateClientData( void )
|
|||
int rainmode = pEnt->pev->button;
|
||||
|
||||
// search for constant rain_modifies
|
||||
pFind = UTIL_FindEntityByClassname( NULL, "util_rainmodify" );
|
||||
pFind = UTIL_FindEntityByClassname( NULL, "env_rainmodify" );
|
||||
while ( !FNullEnt( pFind ) )
|
||||
{
|
||||
if (pFind->pev->spawnflags & 1)
|
||||
if ( pFind->pev->spawnflags & 1 )
|
||||
{
|
||||
// copy settings to player's data and clear fading
|
||||
CBaseEntity *pEnt = CBaseEntity::Instance( pFind->edict() );
|
||||
CUtilRainModify *pRainModify = (CUtilRainModify *)pEnt;
|
||||
CEnvRainModify *pRainModify = (CEnvRainModify *)pEnt;
|
||||
|
||||
Rain_dripsPerSecond = pRainModify->pev->button;
|
||||
Rain_windX = pRainModify->windXY[1];
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
class CWallTorch : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Precache( void )
|
||||
{
|
||||
// if sound is missing just reset soundindex
|
||||
pev->impulse = PRECACHE_SOUND( "ambience/fire1.wav" );
|
||||
UTIL_PrecacheModel( "models/props/torch1.mdl" );
|
||||
}
|
||||
void Spawn( void )
|
||||
{
|
||||
Precache ();
|
||||
|
||||
if( !pev->impulse )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
// SetObjectClass( ED_NORMAL );
|
||||
pev->flags |= FL_PHS_FILTER; // allow phs filter instead pvs
|
||||
|
||||
// setup attenuation radius
|
||||
pev->armorvalue = 384.0f * ATTN_STATIC;
|
||||
|
||||
pev->soundindex = pev->impulse;
|
||||
UTIL_SetModel( ENT( pev ), "models/props/torch1.mdl" );
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
||||
SetBits( pev->flags, FL_POINTENTITY );
|
||||
pev->animtime = gpGlobals->time + 0.2; // enable animation
|
||||
pev->framerate = 0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( light_torch_small_walltorch, CWallTorch );
|
|
@ -61,8 +61,8 @@ TargetDir=\Xash3D\src_main\temp\server\!release
|
|||
InputPath=\Xash3D\src_main\temp\server\!release\server.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\server.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\server.dll "D:\Xash3D\bin\server.dll"
|
||||
"D:\Xash3D\xash\bin\server.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\server.dll "D:\Xash3D\xash\bin\server.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
@ -101,8 +101,8 @@ TargetDir=\Xash3D\src_main\temp\server\!debug
|
|||
InputPath=\Xash3D\src_main\temp\server\!debug\server.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\server.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\server.dll "D:\Xash3D\bin\server.dll"
|
||||
"D:\Xash3D\xash\bin\server.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\server.dll "D:\Xash3D\xash\bin\server.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
@ -181,10 +181,6 @@ SOURCE=.\ents\baseother.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\basepath.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\basephys.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -197,11 +193,11 @@ SOURCE=.\ents\basetank.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\basetrigger.cpp
|
||||
SOURCE=.\ents\basetrain.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\baseutil.cpp
|
||||
SOURCE=.\ents\basetrigger.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
@ -277,6 +273,14 @@ SOURCE=.\game\lights.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\game\maprules.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\monsters\monstermaker.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\game\multiplay_gamerules.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -290,7 +290,7 @@ void LinkUserMessages( void )
|
|||
gmsgWeaponAnim = REG_USER_MSG( "WeaponAnim", 3 );
|
||||
gmsgShowMenu = REG_USER_MSG( "ShowMenu", -1 );
|
||||
gmsgShake = REG_USER_MSG("ScreenShake", 13 );
|
||||
gmsgFade = REG_USER_MSG("ScreenFade", 14 );
|
||||
gmsgFade = REG_USER_MSG("ScreenFade", 13 );
|
||||
gmsgAmmoX = REG_USER_MSG("AmmoX", 2);
|
||||
gmsgTeamNames = REG_USER_MSG( "TeamNames", -1 );
|
||||
gmsgStatusIcon = REG_USER_MSG( "StatusIcon", -1 );
|
||||
|
|
|
@ -1298,11 +1298,11 @@ void UTIL_ScreenFadeWrite( const ScreenFade &fade, CBaseEntity *pEntity )
|
|||
|
||||
WRITE_FLOAT( fade.duration ); // fade lasts this long
|
||||
WRITE_FLOAT( fade.holdTime ); // fade lasts this long
|
||||
WRITE_SHORT( fade.fadeFlags ); // fade type (in / out)
|
||||
WRITE_BYTE( fade.r ); // fade red
|
||||
WRITE_BYTE( fade.g ); // fade green
|
||||
WRITE_BYTE( fade.b ); // fade blue
|
||||
WRITE_BYTE( fade.a ); // fade blue
|
||||
WRITE_BYTE( fade.fadeFlags ); // fade type (in / out)
|
||||
WRITE_BYTE( fade.r ); // fade red
|
||||
WRITE_BYTE( fade.g ); // fade green
|
||||
WRITE_BYTE( fade.b ); // fade blue
|
||||
WRITE_BYTE( fade.a ); // fade blue
|
||||
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
|
|
@ -2998,7 +2998,9 @@ static _inline void R_SetColorForOutlines( void )
|
|||
switch( type )
|
||||
{
|
||||
case MB_MODEL:
|
||||
if( r_currentMeshBuffer->infokey < 0 )
|
||||
if( triState.fActive )
|
||||
pglColor4fv( colorBlue );
|
||||
else if( r_currentMeshBuffer->infokey < 0 )
|
||||
pglColor4fv( colorRed );
|
||||
else pglColor4fv( colorWhite );
|
||||
break;
|
||||
|
|
|
@ -499,7 +499,10 @@ bool R_PushSprite( const meshbuffer_t *mb, int type, float right, float left, fl
|
|||
ref_entity_t *e = RI.currententity;
|
||||
float angle, sr, cr;
|
||||
ref_shader_t *shader;
|
||||
vec3_t point;
|
||||
vec3_t point, origin;
|
||||
|
||||
// don't touch entity origin in case we doesn't have updates
|
||||
VectorCopy( e->origin, origin );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
|
@ -508,10 +511,10 @@ bool R_PushSprite( const meshbuffer_t *mb, int type, float right, float left, fl
|
|||
VectorCopy( e->axis[1], v_right );
|
||||
VectorCopy( e->axis[2], v_up );
|
||||
VectorScale( v_forward, 0.01f, v_forward ); // to avoid z-fighting
|
||||
VectorSubtract( e->origin, v_forward, e->origin );
|
||||
VectorSubtract( origin, v_forward, origin );
|
||||
break;
|
||||
case SPR_FACING_UPRIGHT:
|
||||
VectorSet( v_right, e->origin[1] - RI.viewOrigin[1], -(e->origin[0] - RI.viewOrigin[0]), 0 );
|
||||
VectorSet( v_right, origin[1] - RI.viewOrigin[1], -(origin[0] - RI.viewOrigin[0]), 0 );
|
||||
VectorSet( v_up, 0, 0, 1 );
|
||||
VectorNormalize( v_right );
|
||||
break;
|
||||
|
@ -569,7 +572,7 @@ bool R_PushSprite( const meshbuffer_t *mb, int type, float right, float left, fl
|
|||
if( shader->flags & SHADER_ENTITY_MERGABLE )
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
VectorAdd( spr_xyz[i], e->origin, spr_xyz[i] );
|
||||
VectorAdd( spr_xyz[i], origin, spr_xyz[i] );
|
||||
R_PushMesh( &spr_mesh, features );
|
||||
return false;
|
||||
}
|
||||
|
@ -1863,6 +1866,9 @@ void R_AddLightStyleToScene( int style, float r, float g, float b )
|
|||
{
|
||||
lightstyle_t *ls;
|
||||
|
||||
if( !r_worldmodel || !r_worldbrushmodel->lightgrid || !r_worldbrushmodel->numlightgridelems )
|
||||
return; // don't apply lightstyles when no lighting info
|
||||
|
||||
if( style < 0 || style > MAX_LIGHTSTYLES )
|
||||
Host_Error( "R_AddLightStyleToScene: bad light style %i\n", style );
|
||||
|
||||
|
@ -2477,8 +2483,11 @@ bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, shader_t customShader
|
|||
|
||||
if( !pRefEntity || pRefEntity->v.modelindex <= 0 || pRefEntity->v.modelindex >= MAX_MODELS )
|
||||
return false; // if set to invisible, skip
|
||||
if( r_numEntities >= MAX_ENTITIES ) return false;
|
||||
|
||||
if( r_numEntities >= MAX_ENTITIES )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_AddEntityToScene: too many visible entities\n" );
|
||||
return false;
|
||||
}
|
||||
refent = &r_entities[r_numEntities];
|
||||
|
||||
if( pRefEntity->v.effects & EF_NODRAW && ed_type != ED_PORTAL )
|
||||
|
|
|
@ -687,7 +687,8 @@ void R_DrawMeshes( void )
|
|||
R_LoadIdentity();
|
||||
|
||||
// clearing fog after each frame
|
||||
triState.fogEnabled = false;
|
||||
if( !( RI.params & RP_NONVIEWERREF ))
|
||||
triState.fogEnabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -645,7 +645,7 @@ static bool Shader_SkipConditionBlock( script_t *script )
|
|||
//===========================================================================
|
||||
static bool Shader_CheckSkybox( const char *name )
|
||||
{
|
||||
const char *skybox_ext[4] = { "tga", "jpg", "png", "dds" };
|
||||
const char *skybox_ext[5] = { "tga", "bmp", "jpg", "png", "dds" };
|
||||
int i, j, num_checked_sides;
|
||||
const char *sidename;
|
||||
string loadname;
|
||||
|
@ -662,13 +662,13 @@ static bool Shader_CheckSkybox( const char *name )
|
|||
return true;
|
||||
|
||||
// complex cubemap pack not found, search for skybox images
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
num_checked_sides = 0;
|
||||
for( j = 0; j < 6; j++ )
|
||||
{
|
||||
// build side name
|
||||
sidename = va( "%s_%s.%s", loadname, r_skyBoxSuffix[j], skybox_ext[i] );
|
||||
sidename = va( "%s%s.%s", loadname, r_skyBoxSuffix[j], skybox_ext[i] );
|
||||
if( FS_FileExists( sidename )) num_checked_sides++;
|
||||
|
||||
}
|
||||
|
@ -677,7 +677,7 @@ static bool Shader_CheckSkybox( const char *name )
|
|||
for( j = 0; j < 6; j++ )
|
||||
{
|
||||
// build side name
|
||||
sidename = va( "%s%s.%s", loadname, r_skyBoxSuffix[j], skybox_ext[i] );
|
||||
sidename = va( "%s_%s.%s", loadname, r_skyBoxSuffix[j], skybox_ext[i] );
|
||||
if( FS_FileExists( sidename )) num_checked_sides++;
|
||||
}
|
||||
if( num_checked_sides == 6 )
|
||||
|
@ -719,7 +719,7 @@ static bool Shader_ParseSkySides( script_t *script, ref_shader_t *shader, ref_sh
|
|||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
com.snprintf( name, sizeof( name ), "%s_%s", tok.string, r_skyBoxSuffix[i] );
|
||||
com.snprintf( name, sizeof( name ), "%s%s", tok.string, r_skyBoxSuffix[i] );
|
||||
image = R_FindTexture( name, NULL, 0, TF_CLAMP|TF_NOMIPMAP|TF_SKYSIDE );
|
||||
if( !image ) break;
|
||||
shaders[i] = R_LoadShader( image->name, shaderType, true, image->flags, SHADER_INVALID );
|
||||
|
@ -728,7 +728,7 @@ static bool Shader_ParseSkySides( script_t *script, ref_shader_t *shader, ref_sh
|
|||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
com.snprintf( name, sizeof( name ), "%s%s", tok.string, r_skyBoxSuffix[i] );
|
||||
com.snprintf( name, sizeof( name ), "%s_%s", tok.string, r_skyBoxSuffix[i] );
|
||||
image = R_FindTexture( name, NULL, 0, TF_CLAMP|TF_NOMIPMAP|TF_SKYSIDE );
|
||||
if( !image ) break;
|
||||
shaders[i] = R_LoadShader( image->name, shaderType, true, image->flags, SHADER_INVALID );
|
||||
|
|
Reference in New Issue