16 Aug 2010

This commit is contained in:
g-cont 2010-08-16 00:00:00 +04:00 committed by Alibek Omarov
parent 9d9d4b36da
commit 9258cdcc18
317 changed files with 38985 additions and 51640 deletions

View File

@ -17,6 +17,7 @@ client\
client\hud\
client\global\
common\
dlls\
game_shared\
game_launch\
gameui\
@ -35,7 +36,6 @@ server\game\
server\global\
server\monsters\
launch\
spirit\
snd_dx\
vid_gl\
xtools\

View File

@ -840,7 +840,7 @@ BOOL CApache :: FireGun( )
if (!m_pBeam)
{
m_pBeam = CBeam::BeamCreate( "sprites/lgtning.spr", 80 );
m_pBeam->PointEntInit( pev->origin, edict( ) );
m_pBeam->PointEntInit( pev->origin, entindex( ) );
m_pBeam->SetEndAttachment( 1 );
m_pBeam->SetColor( 255, 180, 96 );
m_pBeam->SetBrightness( 192 );

View File

@ -27,6 +27,10 @@ extern Vector VecBModelOrigin( entvars_t* pevBModel );
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL int g_iSkillLevel;
extern void PM_Move ( struct playermove_s *ppmove, int server );
extern void PM_Init ( struct playermove_s *ppmove );
extern char PM_FindTextureType( const char *name );
static DLL_FUNCTIONS gFunctionTable =
{
GameDLLInit, //pfnGameInit
@ -61,17 +65,17 @@ static DLL_FUNCTIONS gFunctionTable =
PlayerPostThink, //pfnPlayerPostThink
StartFrame, //pfnStartFrame
DispatchCreate, //pfnCreate
ParmsNewLevel, //pfnParmsNewLevel
ParmsChangeLevel, //pfnParmsChangeLevel
GetGameDescription, //pfnGetGameDescription Returns string describing current .dll game.
DispatchFrame, // pfnPhysicsEntity
PlayerCustomization, // pfnPlayerCustomization
SpectatorConnect, //pfnSpectatorConnect Called when spectator joins server
SpectatorDisconnect, //pfnSpectatorDisconnect Called when spectator leaves the server
SpectatorThink, //pfnSpectatorThink Called when spectator sends a command packet (usercmd_t)
ServerClassifyEdict, // pfnClassifyEdict
Sys_Error, // pfnSys_Error
PM_Move, // pfnPM_Move
PM_Init, // pfnPM_Init Server version of player movement initialization
@ -88,9 +92,11 @@ static DLL_FUNCTIONS gFunctionTable =
CmdStart, // pfnCmdStart
CmdEnd, // pfnCmdEnd
OnFreeEntPrivateData, // pfnOnFreeEntPrivateData
ConnectionlessPacket, // pfnConnectionlessPacket
GetHullBounds, // pfnGetHullBounds
ShouldCollide, // pfnShouldCollide
CreateInstancedBaselines, // pfnCreateInstancedBaselines
InconsistentFile, // pfnInconsistentFile
AllowLagCompensation, // pfnAllowLagCompensation
};
static void SetObjectCollisionBox( entvars_t *pev );
@ -100,7 +106,7 @@ static void SetObjectCollisionBox( entvars_t *pev );
//=======================================================================
int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion )
{
if ( !pFunctionTable || interfaceVersion != SV_INTERFACE_VERSION )
if ( !pFunctionTable || interfaceVersion != INTERFACE_VERSION )
{
return FALSE;
}
@ -595,7 +601,6 @@ CBaseEntity *CBaseEntity::GetNextTarget( void )
TYPEDESCRIPTION CBaseEntity::m_SaveData[] =
{
DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ),
DEFINE_FIELD( CBaseEntity, m_iClassType, FIELD_INTEGER ),
DEFINE_FIELD( CBaseEntity, m_pfnThink, FIELD_FUNCTION ), // UNDONE: Build table of these!!!
DEFINE_FIELD( CBaseEntity, m_pfnTouch, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnUse, FIELD_FUNCTION ),
@ -619,9 +624,6 @@ int CBaseEntity::Restore( CRestore &restore )
if ( status )
status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) );
// restore edict class here
SetObjectClass( m_iClassType );
if ( pev->modelindex != 0 && !FStringNull(pev->model) )
{
Vector mins, maxs;

View File

@ -26,8 +26,6 @@ CBaseEntity
CBaseGroup
*/
#include "entity_state.h"
#define MAX_PATH_SIZE 10 // max number of nodes available for a path.
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
@ -79,7 +77,6 @@ extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void
extern void SaveGlobalState( SAVERESTOREDATA *pSaveData );
extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData );
extern void ResetGlobalState( void );
extern int ServerClassifyEdict( edict_t *pentToClassify );
extern void OnFreeEntPrivateData( edict_s *pEdict );
extern int ShouldCollide( edict_t *pentTouched, edict_t *pentOther );
@ -150,13 +147,6 @@ public:
// path corners
CBaseEntity *m_pGoalEnt;// path corner we are heading towards
CBaseEntity *m_pLink;// used for temporary link-list operations.
int m_iClassType; // edict classtype
virtual void SetObjectClass( int iClassType = ED_SPAWNED )
{
m_iClassType = iClassType;
}
// initialization functions
virtual void Spawn( void ) { return; }

View File

@ -661,6 +661,15 @@ void PlayerPostThink( edict_t *pEntity )
pPlayer->PostThink( );
}
void PlayerCustomization( edict_t *pEntity, void *pUnused )
{
// completely ignored in Xash3D
}
void ParmsNewLevel( void )
{
}
void ParmsChangeLevel( void )
{
// retrieve the pointer to the save data
@ -840,6 +849,19 @@ const char *GetGameDescription()
return "Half-Life";
}
/*
================
Sys_Error
Engine is going to shut down, allows setting a breakpoint in game .dll to catch that occasion
================
*/
void Sys_Error( const char *error_string )
{
// Default case, do nothing. MOD AUTHORS: Add code ( e.g., _asm { int 3 }; here to cause a breakpoint for debugging your game .dlls
}
/*
================
SpectatorConnect
@ -888,104 +910,6 @@ void SpectatorThink( edict_t *pEntity )
pPlayer->SpectatorThink( );
}
// FIXME: implement VirtualClass GetClass instead
int AutoClassify( edict_t *pentToClassify )
{
CBaseEntity *pClass;
pClass = CBaseEntity::Instance( pentToClassify );
if( !pClass ) return ED_SPAWNED;
const char *classname = STRING( pClass->pev->classname );
if ( !strnicmp( "worldspawn", classname, 10 ))
{
return ED_WORLDSPAWN;
}
if ( !strnicmp( "bodyque", classname, 7 ))
{
return ED_NORMAL;
}
// first pass: determine type by explicit parms
if ( pClass->pev->solid == SOLID_TRIGGER )
{
if ( FClassnameIs( pClass->pev, "ambient_generic" ) || FClassnameIs( pClass->pev, "target_speaker" )) // FIXME
{
pClass->pev->flags |= FL_PHS_FILTER;
return ED_AMBIENT;
}
else if( pClass->pev->movetype == MOVETYPE_TOSS )
return ED_NORMAL; // it's item or weapon
if ( FBitSet( pClass->pev->effects, EF_NODRAW ))
return ED_TRIGGER; // never sending to client
return ED_NORMAL; // e.g. friction modifier
}
else if ( pClass->pev->movetype == MOVETYPE_PHYSIC )
return ED_RIGIDBODY;
else if ( pClass->pev->solid == SOLID_BSP )
{
if ( pClass->pev->flags & FL_CONVEYOR )
return ED_MOVER;
else if ( pClass->pev->flags & FL_WORLDBRUSH )
return ED_BSPBRUSH;
else if ( pClass->pev->movetype == MOVETYPE_PUSH )
return ED_MOVER;
else if ( pClass->pev->movetype == MOVETYPE_NONE )
return ED_BSPBRUSH;
}
else if ( pClass->pev->flags & FL_MONSTER )
return ED_MONSTER;
else if ( pClass->pev->flags & FL_CLIENT )
return ED_CLIENT;
if ( pClass->pev->flags & FL_CONVEYOR )
return ED_MOVER;
else if ( !pClass->pev->modelindex && !pClass->pev->aiment )
{
if ( pClass->pev->noise || pClass->pev->noise1 || pClass->pev->noise2 || pClass->pev->noise3 )
{
pClass->pev->flags |= FL_PHS_FILTER;
return ED_AMBIENT;
}
return ED_STATIC; // never sending to client
}
// mark as normal
if ( pClass->pev->modelindex || pClass->pev->noise )
return ED_NORMAL;
// fail to classify :-(
return ED_SPAWNED;
}
int ServerClassifyEdict( edict_t *pentToClassify )
{
// NOTE: we can't use FNullEnt here to handle 'worldspawn' properly
// but must skip clients because they not spawned at this point
if( !pentToClassify || pentToClassify->free || !pentToClassify->pvPrivateData )
return ED_SPAWNED;
CBaseEntity *pClass;
pClass = CBaseEntity::Instance( pentToClassify );
if( !pClass ) return ED_SPAWNED;
// user-defined
if( pClass->m_iClassType != ED_SPAWNED )
return pClass->m_iClassType;
int m_iNewClass = AutoClassify( pentToClassify );
if( m_iNewClass != ED_SPAWNED )
{
// tell server.dll about new class
pClass->SetObjectClass( m_iNewClass );
}
return m_iNewClass;
}
////////////////////////////////////////////////////////
// PAS and PVS routines for client messaging
//
@ -1004,12 +928,12 @@ From the eye position, we set up the PAS and PVS to use for filtering network me
NOTE: Do not cache the values of pas and pvs, as they depend on reusable memory in the engine, they are only good for this one frame
================
*/
void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int portal )
void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int mergepvs )
{
Vector org = g_vecZero;
edict_t *pView = pClient;
if( portal )
if( mergepvs )
{
// Entity's added from portal camera PVS
if( FNullEnt( pViewEntity )) return; // broken portal ?
@ -1019,14 +943,14 @@ void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte *
if( !pCamera ) return;
// determine visible point
if( pCamera->m_iClassType == ED_PORTAL )
if( FClassnameIs( pCamera->pev, "info_portal" ))
{
// don't build visibility for mirrors
if( pCamera->pev->origin == pCamera->pev->oldorigin )
return;
else org = pCamera->pev->oldorigin;
}
else if( pCamera->m_iClassType == ED_SKYPORTAL )
else if( FClassnameIs( pCamera->pev, "env_sky" ))
{
org = pCamera->pev->origin;
}
@ -1051,10 +975,13 @@ void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte *
org = pView->v.origin + pView->v.view_ofs;
}
*pvs = ENGINE_SET_PVS( (float *)&org, portal );
*pas = ENGINE_SET_PAS( (float *)&org, portal );
*pvs = ENGINE_SET_PVS( (float *)&org, mergepvs );
*pas = ENGINE_SET_PAS( (float *)&org, mergepvs );
}
#include "entity_state.h"
#include "entity_types.h"
/*
AddToFullPack
@ -1082,19 +1009,27 @@ int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_
BOOL bIsPortalPass = FALSE;
if( pViewEntity && pViewEntity->m_iClassType == ED_PORTAL )
if( pViewEntity && FClassnameIs( pViewEntity->pev, "info_portal" ))
bIsPortalPass = TRUE; // view from portal camera
pEntity = (CBaseEntity *)CBaseEntity::Instance( pEdict );
if( !pEntity ) return 0;
if ( !pEntity ) return 0;
// NOTE: always add himslef to list
if( !bIsPortalPass && ( pHost == pEdict ))
if ( !bIsPortalPass && ( pHost == pEdict ))
goto addEntity;
// don't send if flagged for NODRAW and it's not the host getting the message
if (( pEdict->v.effects == EF_NODRAW ) && ( pEdict != pHost ))
return 0;
// Ignore ents without valid / visible models
if ( !pEdict->v.modelindex || !STRING( pEdict->v.model ))
return 0;
// completely ignore dormant entity
if( pEdict->v.flags & FL_DORMANT )
if ( pEdict->v.flags & FL_DORMANT )
return 0;
// don't send spectators to other players
@ -1103,32 +1038,8 @@ int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_
return 0;
}
// FIXME: temporary hack
if( pEdict->v.flags & FL_CUSTOMENTITY )
{
pEntity->m_iClassType = ED_BEAM;
state->ed_type = ED_BEAM;
}
// quick reject by type
switch( pEntity->m_iClassType )
{
case ED_SKYPORTAL:
goto addEntity; // no additional check requires
case ED_BEAM:
case ED_MOVER:
case ED_NORMAL:
case ED_PORTAL:
case ED_CLIENT:
case ED_MONSTER:
case ED_AMBIENT:
case ED_BSPBRUSH:
case ED_RIGIDBODY: break;
default: return 0; // skipped
}
// check for ambients distance
if( pEntity->m_iClassType == ED_AMBIENT )
if(FClassnameIs( pViewEntity->pev, "ambient_generic" ))
{
Vector entorigin;
@ -1142,22 +1053,26 @@ int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_
}
else delta = g_vecZero;
// check visibility
if ( !ENGINE_CHECK_PVS( pEdict, pSet ))
// Ignore if not the host and not touching a PVS/PAS leaf
// If pSet is NULL, then the test will always succeed and the entity will be added to the update
if ( pEdict != pHost )
{
float m_flRadius = 1024; // g-cont: tune distance by taste :)
if ( pEntity->pev->flags & FL_PHS_FILTER )
if ( !ENGINE_CHECK_VISIBILITY( pEdict, pSet ))
{
if( pEntity->pev->armorvalue > 0 )
m_flRadius = pEntity->pev->armorvalue;
float m_flRadius = 1024; // g-cont: tune distance by taste :)
if( delta.Length() > m_flRadius )
if ( pEntity->pev->flags & FL_PHS_FILTER )
{
if( pEntity->pev->armorvalue > 0 )
m_flRadius = pEntity->pev->armorvalue;
if( delta.Length() > m_flRadius )
return 0;
}
else
{
return 0;
}
else //if( pEntity->m_iClassType != ED_BEAM )
{
return 0;
}
}
}
@ -1171,13 +1086,6 @@ int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_
return 0;
}
if( !pEntity->pev->modelindex || FStringNull( pEntity->pev->model ))
{
// can't ignore ents withouts models, because portals and mirrors can't working otherwise
// and null.mdl it's no more needs to be set: ED_CLASS rejection is working fine
// so we wan't reject this entities here.
}
if( pHost->v.groupinfo )
{
UTIL_SetGroupTrace( pHost->v.groupinfo, GROUP_OP_AND );
@ -1200,10 +1108,11 @@ int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_
}
addEntity:
// setup some special edict flags (engine will clearing them after the current frame)
if( state->modelindex != pEntity->pev->modelindex || ( pEntity->pev->effects & EF_NOINTERP ))
state->ed_flags |= ESF_NODELTA;
if( pEdict->v.flags & FL_CLIENT )
state->entityType = ET_PLAYER;
else if( pEdict->v.flags & FL_CUSTOMENTITY )
state->entityType = ET_BEAM;
else state->entityType = ET_NORMAL;
// always keep an actual
state->number = pEdict->serialnumber;
@ -1258,7 +1167,7 @@ addEntity:
for( i = 0; i < 4; i++ )
state->controller[i] = pEntity->pev->controller[i];
if( state->ed_type == ED_CLIENT )
if( pEdict->v.flags & FL_CLIENT )
{
if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment );
@ -1276,17 +1185,13 @@ addEntity:
state->weaponmodel = MODEL_INDEX( STRING( pEntity->pev->weaponmodel ));
else state->weaponmodel = 0;
}
else if( state->ed_type == ED_AMBIENT )
else if( pEdict->v.movetype == MOVETYPE_PUSH )
{
// add here specified fields e.g for trigger_teleport wind sound etc
}
else if( state->ed_type == ED_MOVER || state->ed_type == ED_BSPBRUSH || state->ed_type == ED_PORTAL )
{
state->body = DirToBits( pEntity->pev->movedir );
state->body = DirToBits( pEntity->pev->movedir ); // legacy
state->velocity = pEntity->pev->velocity;
// this is conveyor - send speed to render for right texture scrolling
state->framerate = pEntity->pev->speed;
state->framerate = pEntity->pev->speed; // legacy
}
return 1;
}
@ -1300,14 +1205,11 @@ Creates baselines used for network encoding, especially for player data since pl
*/
void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodelindex )
{
// FIXME: temporary hack
if( entity->v.flags & FL_CUSTOMENTITY )
{
baseline->ed_type = ED_BEAM;
}
// always set nodelta's for baseline
baseline->ed_flags |= ESF_NODELTA;
if( entity->v.flags & FL_CLIENT )
baseline->entityType = ET_PLAYER;
else if( entity->v.flags & FL_CUSTOMENTITY )
baseline->entityType = ET_BEAM;
else baseline->entityType = ET_NORMAL;
baseline->origin = entity->v.origin;
baseline->angles = entity->v.angles;
@ -1325,7 +1227,7 @@ void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodeli
baseline->mins = entity->v.mins;
baseline->maxs = entity->v.maxs;
if( baseline->ed_type == ED_CLIENT )
if( baseline->entityType == ET_PLAYER )
{
baseline->colormap = entity->serialnumber;
baseline->modelindex = playermodelindex; // "model" field from userinfo
@ -1695,6 +1597,29 @@ void CmdEnd ( const edict_t *player )
}
}
/*
================================
ConnectionlessPacket
Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max
size of the response_buffer, so you must zero it out if you choose not to respond.
================================
*/
int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size )
{
// Parse stuff from args
int max_buffer_size = *response_buffer_size;
// Zero it out since we aren't going to respond.
// If we wanted to response, we'd write data into response_buffer
*response_buffer_size = 0;
// Since we don't listen for anything here, just respond that it's a bogus message
// If we didn't reject the message, we'd return 1 for success instead.
return 0;
}
/*
================================
GetHullBounds
@ -1729,6 +1654,65 @@ int GetHullBounds( int hullnumber, float *mins, float *maxs )
return iret;
}
/*
================================
CreateInstancedBaselines
Create pseudo-baselines for items that aren't placed in the map at spawn time, but which are likely
to be created during play ( e.g., grenades, ammo packs, projectiles, corpses, etc. )
================================
*/
void CreateInstancedBaselines ( void )
{
int iret = 0;
entity_state_t state;
memset( &state, 0, sizeof( state ) );
// Create any additional baselines here for things like grendates, etc.
// iret = ENGINE_INSTANCE_BASELINE( pc->pev->classname, &state );
// Destroy objects.
//UTIL_Remove( pc );
}
/*
================================
InconsistentFile
One of the ENGINE_FORCE_UNMODIFIED files failed the consistency check for the specified player
Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters )
================================
*/
int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message )
{
// Server doesn't care?
if ( CVAR_GET_FLOAT( "mp_consistency" ) != 1 )
return 0;
// Default behavior is to kick the player
sprintf( disconnect_message, "Server is enforcing file consistency for %s\n", filename );
// Kick now with specified disconnect message.
return 1;
}
/*
================================
AllowLagCompensation
The game .dll should return 1 if lag compensation should be allowed ( could also just set
the sv_unlag cvar.
Most games right now should return 0, until client-side weapon prediction code is written
and tested for them ( note you can predict weapons, but not do lag compensation, too,
if you want.
================================
*/
int AllowLagCompensation( void )
{
return 1;
}
/*
================================
ShouldCollide

View File

@ -33,6 +33,7 @@ extern void RegisterEncoders( void );
extern void ClientPrecache( void );
extern const char *GetGameDescription( void );
extern void PlayerCustomization( edict_t *pEntity, void *pUnused );
extern int GetWeaponData( edict_t *player, struct weapon_data_s *info );
extern void SpectatorConnect ( edict_t *pEntity );
@ -43,12 +44,17 @@ extern void Sys_Error( const char *error_string );
extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int portal );
extern void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
extern int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet );
extern void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodelindex );
extern int AddToFullPack( struct entity_state_s *state, edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet );
extern void CreateBaseline( struct entity_state_s *baseline, edict_t *entity, int playermodelindex );
extern void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed );
extern void CmdEnd ( const edict_t *player );
extern int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
extern int GetHullBounds( int hullnumber, float *mins, float *maxs );
extern void CreateInstancedBaselines ( void );
extern int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message );
extern int AllowLagCompensation( void );
extern int GetHullBounds( int hullnumber, float *mins, float *maxs );
#endif // CLIENT_H

View File

@ -230,8 +230,6 @@ CBeam *CBeam::BeamCreate( const char *pSpriteName, int width )
void CBeam::BeamInit( const char *pSpriteName, int width )
{
SetObjectClass( ED_BEAM );
pev->flags |= FL_CUSTOMENTITY;
SetColor( 255, 255, 255 );
SetBrightness( 255 );
@ -468,7 +466,6 @@ void CLightning::Spawn( void )
if ( ServerSide() )
{
SetObjectClass( ED_BEAM );
SetThink( NULL );
if ( pev->dmg > 0 )
{
@ -962,7 +959,6 @@ void CLaser::Spawn( void )
return;
}
SetObjectClass( ED_BEAM );
pev->solid = SOLID_NOT; // Remove model & collisions
Precache( );

View File

@ -70,7 +70,6 @@ extern enginefuncs_t g_engfuncs;
#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat)
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#define CLASSIFY_EDICT (*g_engfuncs.pfnClassifyEdict)
#define COM_Parse (*g_engfuncs.pfnParseToken)
inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL ) {
(*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed);
@ -92,6 +91,7 @@ inline void WRITE_FLOAT( float flValue )
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat)
#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString)
#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer)
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)
@ -136,9 +136,9 @@ inline void *GET_PRIVATE( edict_t *pent )
#define FILE_EXISTS (*g_engfuncs.pfnFileExists)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid)
#define SET_BONE_POSITION (*g_engfuncs.pfnSetBonePos)
#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities)
#define DROP_CLIENT (*g_engfuncs.pfnDropClient)
#define ENGINE_CHECK_PVS (*g_engfuncs.pfnCheckVisibility)
#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility)
#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS)
#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS)

View File

@ -33,7 +33,6 @@
#pragma warning(disable : 4100) // unreferenced formal parameter
#include "windows.h"
#include "basetypes.h"
#define FALSE 0
#define TRUE 1
@ -64,9 +63,9 @@ typedef unsigned long ULONG;
// Vector class
#include "vector.h"
// Shared header describing protocol between engine and DLLs
#include "entity_def.h"
#include "svgame_api.h"
// Shared header describing protocol between engine and DLLs
#include "edict.h"
#include "eiface.h"
// Shared header between the client DLL and the game DLLs
#include "cdll_dll.h"

View File

@ -841,7 +841,7 @@ float CHalfLifeMultiplay :: FlWeaponTryRespawn( CBasePlayerItem *pWeapon )
{
if ( pWeapon && pWeapon->m_iId && (pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) )
{
if ( gpGlobals->numEntities < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) )
if ( NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) )
return 0;
// we're past the entity tolerance level, so delay the respawn
@ -1122,6 +1122,85 @@ void DestroyMapCycle( mapcycle_t *cycle )
cycle->next_item = NULL;
}
static char com_token[ 1500 ];
/*
==============
COM_Parse
Parse a token out of a string
==============
*/
char *COM_Parse (char *data)
{
int c;
int len;
len = 0;
com_token[0] = 0;
if (!data)
return NULL;
// skip whitespace
skipwhite:
while ( (c = *data) <= ' ')
{
if (c == 0)
return NULL; // end of file;
data++;
}
// skip // comments
if (c=='/' && data[1] == '/')
{
while (*data && *data != '\n')
data++;
goto skipwhite;
}
// handle quoted strings specially
if (c == '\"')
{
data++;
while (1)
{
c = *data++;
if (c=='\"' || !c)
{
com_token[len] = 0;
return data;
}
com_token[len] = c;
len++;
}
}
// parse single characters
if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' )
{
com_token[len] = c;
len++;
com_token[len] = 0;
return data+1;
}
// parse a regular word
do
{
com_token[len] = c;
data++;
len++;
c = *data;
if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' )
break;
} while (c>32);
com_token[len] = 0;
return data;
}
/*
==============
COM_TokenWaiting
@ -1158,9 +1237,8 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle )
char szBuffer[ MAX_RULE_BUFFER ];
char szMap[ 32 ];
int length;
char *pToken;
char *aFileList = (char *)LOAD_FILE_FOR_ME( filename, &length );
const char *pFileList = aFileList;
char *pFileList = aFileList;
int hasbuffer;
mapcycle_item_s *item, *newlist = NULL, *next;
@ -1172,22 +1250,20 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle )
hasbuffer = 0;
memset( szBuffer, 0, MAX_RULE_BUFFER );
pToken = COM_Parse( &pFileList );
if ( !pToken ) break;
if ( strlen( pToken ) <= 0 )
pFileList = COM_Parse( pFileList );
if ( strlen( com_token ) <= 0 )
break;
strcpy( szMap, pToken );
strcpy( szMap, com_token );
// Any more tokens on this line?
if ( COM_TokenWaiting( pFileList ) )
{
pToken = COM_Parse( &pFileList );
if ( strlen( pToken ) > 0 )
pFileList = COM_Parse( pFileList );
if ( strlen( com_token ) > 0 )
{
hasbuffer = 1;
strcpy( szBuffer, pToken );
strcpy( szBuffer, com_token );
}
}

View File

@ -2961,7 +2961,6 @@ void CBasePlayer::Spawn( void )
g_pGameRules->SetDefaultPlayerTeam( this );
g_pGameRules->GetPlayerSpawnSpot( this );
SetObjectClass( ED_CLIENT ); // critical stuff!!!
SET_MODEL(ENT(pev), "models/player.mdl");
g_ulModelIndexPlayer = pev->modelindex;
pev->sequence = LookupActivity( ACT_IDLE );

View File

@ -201,7 +201,6 @@ CRpgRocket *CRpgRocket::CreateRpgRocket( Vector vecOrigin, Vector vecAngles, CBa
{
CRpgRocket *pRocket = GetClassPtr( (CRpgRocket *)NULL );
pRocket->SetObjectClass( ED_NORMAL );
UTIL_SetOrigin( pRocket->pev, vecOrigin );
pRocket->pev->angles = vecAngles;
pRocket->Spawn();

View File

@ -2203,9 +2203,6 @@ IMPLEMENT_SAVERESTORE(CTriggerCamera,CBaseDelay);
void CTriggerCamera::Spawn( void )
{
// force camera to send on client
SetObjectClass( ED_NORMAL );
pev->movetype = MOVETYPE_NOCLIP;
pev->solid = SOLID_NOT; // Remove model & collisions
pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on

View File

@ -61,16 +61,6 @@ DLL_GLOBAL int DirToBits( const Vector dir )
return best;
}
char *COM_ParseToken( const char **data )
{
char *com_token = COM_Parse( data );
// debug
// ALERT( at_console, "ParseToken: %s\n", com_token );
return com_token;
}
/*
=====================
UTIL_WeaponTimeBase

View File

@ -20,7 +20,6 @@
#include <string.h>
#include "te_shared.h"
#include "shake.h"
#include "game_shared.h"
#include "activity.h"
@ -47,8 +46,6 @@ inline edict_t *FIND_ENTITY_BY_TARGET(edict_t *entStart, const char *pszName)
extern int DirToBits( const Vector dir );
char *COM_ParseToken( const char **data );
// Keeps clutter down a bit, when writing key-value pairs
#define WRITEKEY_INT(pf, szKeyName, iKeyValue) \
ENGINE_FPRINTF(pf, "\"%s\" \"%d\"\n", szKeyName, iKeyValue)
@ -229,6 +226,10 @@ inline void UTIL_MakeVectorsPrivate( const Vector &vecAngles, float *p_vForward,
g_engfuncs.pfnAngleVectors( vecAngles, p_vForward, p_vRight, p_vUp );
}
typedef enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 };
typedef enum { ignore_monsters = 1, dont_ignore_monsters = 0, missile = 2 } IGNORE_MONSTERS;
typedef enum { ignore_glass = 1, dont_ignore_glass = 0 } IGNORE_GLASS;
extern void UTIL_MakeAimVectors ( const Vector &vecAngles ); // like MakeVectors, but assumes pitch isn't inverted
extern void UTIL_MakeInvVectors ( const Vector &vec, globalvars_t *pgv );

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /I "./" /I "../common" /I "global" /I "hud" /I "../game_shared" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "./" /I "../common" /I "global" /I "hud" /I "../game_shared" /I "../dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /Fr /YX
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -54,7 +54,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 msvcrt.lib /nologo /subsystem:windows /dll /machine:I386 /nodefaultlib:"libc" /def:".\client.def" /libpath:"..\common\libs"
# ADD LINK32 msvcrt.lib /nologo /subsystem:windows /dll /machine:I386 /nodefaultlib:"libc.lib" /def:".\client.def" /libpath:"..\common\libs"
# SUBTRACT LINK32 /map
# Begin Custom Build
TargetDir=\Xash3D\src_main\temp\client\!release
@ -82,7 +82,7 @@ SOURCE="$(InputPath)"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\common\vgui" /I "..\client" /I "..\client\render" /I ".\hud" /I "..\common\engine" /I "..\common" /I "..\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /YX /FD /c
# SUBTRACT BASE CPP /Fr
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "../common" /I "global" /I "hud" /I "../game_shared" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /Gi- /GX /ZI /Od /I "./" /I "../common" /I "global" /I "hud" /I "../game_shared" /I "../dlls" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

View File

@ -332,7 +332,7 @@ ParticleSystem::ParticleSystem( int iEntIndex, char *szFilename )
if( !szFile )
{
ALERT( at_error, "particle %s not found.\n", szFilename );
Con_Printf( "Error: particle %s not found.\n", szFilename );
return;
}
else
@ -467,7 +467,7 @@ ParticleType *ParticleSystem::ParseType( const char **szFile )
{
// there's already a type with this name
if (pTemp->m_bIsDefined)
ALERT( at_warning, "Particle type %s is defined more than once!\n", szToken);
Con_Printf( "Warning: particle type %s is defined more than once!\n", szToken);
// copy all our data into the existing type, throw away the type we were making
*pTemp = *pType;
@ -979,7 +979,7 @@ void ParticleSystem::DrawParticle( particle *part, Vector &right, Vector &up )
int numFrames = GetModelFrames( pDraw->pType->m_SpriteIndex );
// ALERT( at_console, "UpdParticle %d: age %f, life %f, R:%f G:%f, B, %f \n", pDraw->pType->m_hSprite, part->age, part->age_death, pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue);
// Con_Printf( "UpdParticle %d: age %f, life %f, R:%f G:%f, B, %f \n", pDraw->pType->m_hSprite, part->age, part->age_death, pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue);
// if we've reached the end of the sprite's frames, loop back
while ( pDraw->frame > numFrames )

View File

@ -713,7 +713,7 @@ void TE_AddClientMessage( void )
if( channel <= 0 || channel > ( MAX_CHANNELS - 1 ))
{
// invalid channel specified, use internal counter
if( channel != 0 ) ALERT( at_warning, "HUD_Message: invalid channel %i\n", channel );
if( channel != 0 ) Con_Printf( "ERROR: HUD_Message: invalid channel %i\n", channel );
channel = msgindex;
msgindex = (msgindex + 1) & (MAX_CHANNELS - 1);
}

View File

@ -16,6 +16,8 @@
#include "ev_hldm.h"
#include "r_weather.h"
#include "pm_shared.h"
#include "pm_movevars.h"
#include "entity_types.h"
cl_enginefuncs_t g_engfuncs;
cl_globalvars_t *gpGlobals;
@ -220,21 +222,10 @@ int HUD_UpdateClientData( client_data_t *pcldata, float flTime )
return gHUD.UpdateClientData( pcldata, flTime );
}
int HUD_Redraw( float flTime, int state )
int HUD_Redraw( float flTime, int intermission )
{
switch( state )
{
case CL_ACTIVE:
case CL_PAUSED:
gHUD.Redraw( flTime );
break;
case CL_LOADING:
// called while map is loading
break;
case CL_CHANGELEVEL:
// called once when changelevel in-action
break;
}
gHUD.Redraw( flTime );
return 1;
}
@ -265,6 +256,9 @@ void HUD_TxferLocalOverrides( entity_state_t *state, const clientdata_t *client
// Spectating or not dead == get control over view angles.
g_iAlive = ( client->iuser1 || ( client->deadflag == DEAD_NO ) ) ? 1 : 0;
// FIXME: temporary hack so gaitsequence it's works properly
state->velocity = client->velocity;
}
/*
@ -331,7 +325,7 @@ void HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_sta
}
}
int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type )
int HUD_AddVisibleEntity( cl_entity_t *pEnt, int entityType )
{
float oldScale, oldRenderAmt;
float shellScale = 1.0f;
@ -345,7 +339,7 @@ int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type )
pEnt->curstate.renderamt = 255; // clear amount
}
result = CL_AddEntity( pEnt, ed_type, -1 );
result = CL_AddEntity( pEnt, entityType, -1 );
if ( pEnt->curstate.renderfx == kRenderFxGlowShell )
{
@ -354,7 +348,7 @@ int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type )
pEnt->curstate.renderamt = 128;
// render glowshell
result |= CL_AddEntity( pEnt, ed_type, g_pTempEnts->hSprGlowShell );
result |= CL_AddEntity( pEnt, entityType, g_pTempEnts->hSprGlowShell );
// restore parms
pEnt->curstate.scale = oldScale;
@ -369,7 +363,7 @@ int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type )
// add in muzzleflash effect
if ( pEnt->curstate.effects & EF_MUZZLEFLASH )
{
if( ed_type == ED_VIEWMODEL )
if( entityType == ET_VIEWENTITY )
pEnt->curstate.effects &= ~EF_MUZZLEFLASH;
g_pTempEnts->WeaponFlash( pEnt, 1 );
}
@ -384,7 +378,7 @@ int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type )
// add dimlight
if ( pEnt->curstate.effects & EF_DIMLIGHT )
{
if ( ed_type == ED_CLIENT )
if ( entityType == ET_PLAYER )
{
EV_UpadteFlashlight( pEnt );
}

View File

@ -42,7 +42,8 @@
#define Cmd_RemoveCommand (*g_engfuncs.pfnDelCommand)
#define CMD_ARGC (*g_engfuncs.pfnCmdArgc)
#define CMD_ARGV (*g_engfuncs.pfnCmdArgv)
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define Con_Printf (*g_engfuncs.Con_Printf)
#define Con_DPrintf (*g_engfuncs.Con_DPrintf)
#define IN_GAME (*g_engfuncs.pfnIsInGame)
inline void SPR_Set( HSPRITE hPic, int r, int g, int b )

View File

@ -1002,6 +1002,7 @@ void EV_FirePython( event_args_t *args )
//======================
#define GAUSS_PRIMARY_CHARGE_VOLUME 256 // how loud gauss is while charging
#define GAUSS_PRIMARY_FIRE_VOLUME 450 // how loud gauss is when discharged
#define SND_CHANGE_PITCH (1<<7) // duplicated in protocol.h change sound pitch
void EV_SpinGauss( event_args_t *args )
{
@ -1063,7 +1064,7 @@ void EV_FireGauss( event_args_t *args )
return;
}
// ALERT( at_console, "firing gauss with %f\n", flDamage );
// Con_Printf( "firing gauss with %f\n", flDamage );
EV_GetGunPosition( args, vecSrc, origin );
m_iBeam = g_engfuncs.pEventAPI->EV_FindModelIndex( "sprites/smoke.spr" );
@ -1136,7 +1137,7 @@ void EV_FireGauss( event_args_t *args )
if ( n < 0.5f ) // 60 degrees
{
// ALERT( at_console, "reflect %f\n", n );
// Con_Printf( "reflect %f\n", n );
// reflect
Vector r;
@ -1648,12 +1649,12 @@ void EV_UpdateLaserSpot( void )
m_pLaserSpot->entity.baseline.rendercolor.r = 200;
m_pLaserSpot->entity.baseline.rendercolor.g = 12;
m_pLaserSpot->entity.baseline.rendercolor.b = 12;
// ALERT( at_console, "CLaserSpot::Create()\n" );
// Con_Printf( "CLaserSpot::Create()\n" );
}
else if( !( m_pPlayer->curstate.effects & EF_LASERSPOT ) && m_pLaserSpot )
{
// destroy laserspot
// ALERT( at_console, "CLaserSpot::Killed()\n" );
// Con_Printf( "CLaserSpot::Killed()\n" );
m_pLaserSpot->die = 0.0f;
m_pLaserSpot = NULL;
return;
@ -1746,7 +1747,7 @@ void EV_SnarkFire( event_args_t *args )
//======================
void EV_FireNull( event_args_t *args )
{
ALERT( at_console, "Called null event!\n" );
Con_Printf( "Called null event!\n" );
}
//======================
// NULL END

View File

@ -13,7 +13,6 @@
#pragma warning(disable : 4100) // unreferenced formal parameter
#include "windows.h"
#include "basetypes.h"
// Misc C-runtime library headers
#include <assert.h>
@ -31,6 +30,6 @@
// Shared header describing protocol between engine and DLLs
#include "cl_entity.h"
#include "clgame_api.h"
#include "game_shared.h"
#include "cdll_dll.h"
#endif//EXTDLL_H

View File

@ -140,7 +140,7 @@ void IN_KeyDown( kbutton_t *b )
}
else
{
ALERT( at_error, "three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c );
Con_Printf( "Error: three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c );
return;
}
@ -236,7 +236,7 @@ static float CL_KeyState( kbutton_t *key )
#if 0
if( msec )
{
ALERT( at_console, "%i ", msec );
Con_Printf( "%i ", msec );
}
#endif
val = bound( 0, (float)msec / frame_msec, 1 );

View File

@ -1435,8 +1435,8 @@ void CViewRenderBeams::DrawLaser( Beam_t *pbeam, int frame, int rendermode, floa
color2[1] *= flFade;
color2[2] *= flFade;
//ALERT( at_console, "Fade: %f", flFade );
//ALERT( at_console, "Dist: %f", flDistance );
//Con_Printf( "Fade: %f", flFade );
//Con_Printf( "Dist: %f", flDistance );
}
DrawSegs( NOISE_DIVISIONS, pbeam->rgNoise, spriteIndex, frame, rendermode, pbeam->attachment[0],
@ -1533,7 +1533,7 @@ void CViewRenderBeams::DrawBeam( Beam_t *pbeam )
DrawLaser( pbeam, frame, rendermode, color, pbeam->modelIndex );
break;
default:
ALERT( at_warning, "CViewRenderBeams::DrawBeam: Unknown beam type %i\n", pbeam->type );
Con_Printf( "CViewRenderBeams::DrawBeam: Unknown beam type %i\n", pbeam->type );
break;
}
}
@ -1570,7 +1570,7 @@ bool CViewRenderBeams::RecomputeBeamEndpoints( Beam_t *pbeam )
}
else
{
// ALERT( at_warning, "can't find start entity\n" );
// Con_Printf( "Warning: can't find start entity\n" );
// return false;
}
@ -1612,7 +1612,7 @@ void CViewRenderBeams::AddServerBeam( cl_entity_t *pEnvBeam )
{
if( m_nNumServerBeams >= MAX_BEAMS )
{
ALERT( at_error, "Too many static beams %d!\n", m_nNumServerBeams );
Con_Printf( "ERROR: Too many static beams %d!\n", m_nNumServerBeams );
return;
}
@ -2338,7 +2338,7 @@ void DrawBeamFollow( int modelIndex, BeamTrail_t* pHead, int frame, int rendermo
while ( pHead )
{
// ALERT( at_console, "%.2f ", fraction );
// Con_Printf( "%.2f ", fraction );
g_engfuncs.pTriAPI->Color4ub( nColor[0], nColor[1], nColor[2], 255 );
g_engfuncs.pTriAPI->TexCoord2f( 1.0f, 1.0f );
g_engfuncs.pTriAPI->Vertex3fv( last2 );

View File

@ -6,14 +6,32 @@
#ifndef R_BEAMS_H
#define R_BEAMS_H
#include "beam_def.h"
#include "te_shared.h"
#include "customentity.h"
#define NOISE_DIVISIONS 64 // don't touch - many tripmines cause the crash when it equal 128
#define NOISE_MASK (NOISE_DIVISIONS-1)
#define MAX_BEAM_ENTS 2 // start & end entity
#define MAX_BEAMS 128 // Max simultaneous beams
#define MAX_BEAMTRAILS 2048 // default max # of particles at one time
// beam flags
#define FBEAM_STARTENTITY 0x00000001
#define FBEAM_ENDENTITY 0x00000002
#define FBEAM_FADEIN 0x00000004
#define FBEAM_FADEOUT 0x00000008
// BEGIN SHARED FLAGS
#define FBEAM_SINENOISE 0x00000010
#define FBEAM_SOLID 0x00000020
#define FBEAM_SHADEIN 0x00000040
#define FBEAM_SHADEOUT 0x00000080
// END SHARED FLAGS
#define FBEAM_ONLYNOISEONCE 0x00000100 // Only calculate our noise once
#define FBEAM_STARTVISIBLE 0x10000000 // Has this client actually seen this beam's start entity yet?
#define FBEAM_ENDVISIBLE 0x20000000 // Has this client actually seen this beam's end entity yet?
#define FBEAM_ISACTIVE 0x40000000
#define FBEAM_FOREVER 0x80000000
struct BeamTrail_t
{

View File

@ -14,6 +14,12 @@
#include "r_particle.h"
#include "r_tempents.h"
// particle velocities
static const float r_avertexnormals[NUMVERTEXNORMALS][3] =
{
#include "anorms.h"
};
// particle ramps
static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 };
static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
@ -80,7 +86,7 @@ void CParticleSystem :: Clear( void )
m_vecAvelocities[i][2] = RANDOM_LONG( 0, 255 ) * 0.01f;
// also build avertexnormals
m_vecAvertexNormals[i] = Vector( bytedirs[i] );
m_vecAvertexNormals[i] = Vector( r_avertexnormals[i] );
}
// build the local copy of particle palette
@ -122,7 +128,7 @@ CBaseParticle *CParticleSystem :: AllocParticle( HSPRITE m_hSpr )
if( !m_pFreeParticles )
{
ALERT( at_console, "Overflow %d particles\n", MAX_PARTICLES );
Con_Printf( "Overflow %d particles\n", MAX_PARTICLES );
return NULL;
}

View File

@ -6,6 +6,7 @@
#ifndef R_PARTICLE_H
#define R_PARTICLE_H
#define NUMVERTEXNORMALS 162
#define MAX_PARTICLES 4096
#define SIMSHIFT 10

View File

@ -8,6 +8,7 @@
#include "studio_event.h"
#include "triangle_api.h"
#include "effects_api.h"
#include "entity_types.h"
#include "pm_movevars.h"
#include "r_particle.h"
#include "r_tempents.h"
@ -113,7 +114,7 @@ int CTempEnts::TE_Update( TEMPENTITY *pTemp )
// before first frame when movevars not initialized
if( !gpMovevars )
{
ALERT( at_error, "TempEntUpdate: no movevars!!!\n" );
Con_Printf( "ERROR: TempEntUpdate: no movevars!!!\n" );
return true;
}
@ -429,7 +430,7 @@ void CTempEnts :: Update( void )
{
while( current )
{
CL_AddEntity( &current->entity, ED_TEMPENTITY, -1 );
CL_AddEntity( &current->entity, ET_TEMPENTITY, -1 );
current = current->next;
}
}
@ -452,7 +453,7 @@ void CTempEnts :: Update( void )
else
{
// renderer rejected entity for some reasons...
if( !CL_AddEntity( &current->entity, ED_TEMPENTITY, -1 ))
if( !CL_AddEntity( &current->entity, ET_TEMPENTITY, -1 ))
{
if(!( current->flags & FTENT_PERSIST ))
{
@ -554,7 +555,7 @@ TEMPENTITY *CTempEnts::TempEntAlloc( const Vector& org, int modelIndex )
if ( !m_pFreeTempEnts )
{
ALERT( at_console, "Overflow %d temporary ents!\n", MAX_TEMP_ENTITIES );
Con_Printf( "Overflow %d temporary ents!\n", MAX_TEMP_ENTITIES );
return NULL;
}
@ -594,7 +595,7 @@ TEMPENTITY *CTempEnts::TempEntAllocHigh( const Vector& org, int modelIndex )
{
// didn't find anything? The tent list is either full of high-priority tents
// or all tents in the list are still due to live for > 10 seconds.
ALERT( at_console, "Couldn't alloc a high priority TENT!\n" );
Con_Printf( "Couldn't alloc a high priority TENT!\n" );
return NULL;
}
@ -825,20 +826,20 @@ void CTempEnts::AttachTentToPlayer( int client, int modelIndex, float zoffset, f
if ( client <= 0 || client > gpGlobals->maxClients )
{
ALERT( at_warning, "Bad client in AttachTentToPlayer()!\n" );
Con_Printf( "Bad client in AttachTentToPlayer()!\n" );
return;
}
cl_entity_t *pClient = GetEntityByIndex( client );
if ( !pClient )
{
ALERT( at_warning, "Couldn't get ClientEntity for %i\n", client );
Con_Printf( "Couldn't get ClientEntity for %i\n", client );
return;
}
if( GetModelType( modelIndex ) == mod_bad )
{
ALERT( at_console, "No model %d!\n", modelIndex );
Con_Printf( "No model %d!\n", modelIndex );
return;
}
@ -848,7 +849,7 @@ void CTempEnts::AttachTentToPlayer( int client, int modelIndex, float zoffset, f
pTemp = TempEntAllocHigh( position, modelIndex );
if ( !pTemp )
{
ALERT( at_warning, "No temp ent.\n" );
Con_Printf( "No temp ent.\n" );
return;
}
@ -889,7 +890,7 @@ void CTempEnts::KillAttachedTents( int client )
{
if ( client <= 0 || client > gpGlobals->maxClients )
{
ALERT( at_warning, "Bad client in KillAttachedTents()!\n" );
Con_Printf( "Bad client in KillAttachedTents()!\n" );
return;
}
@ -1081,7 +1082,7 @@ void CTempEnts::MuzzleFlash( cl_entity_t *pEnt, int iAttachment, int type )
if( pos == pEnt->origin )
{
ALERT( at_error, "Invalid muzzleflash entity!\n" );
Con_Printf( "Invalid muzzleflash entity!\n" );
return;
}
@ -1110,7 +1111,7 @@ void CTempEnts::MuzzleFlash( cl_entity_t *pEnt, int iAttachment, int type )
}
// render now (guranteed that muzzleflash will be draw)
CL_AddEntity( &pTemp->entity, ED_TEMPENTITY, -1 );
CL_AddEntity( &pTemp->entity, ET_TEMPENTITY, -1 );
}
void CTempEnts::BloodSprite( const Vector &org, int colorIndex, int modelIndex, int modelIndex2, float size )
@ -1255,7 +1256,7 @@ TEMPENTITY *CTempEnts::DefaultSprite( const Vector &pos, int spriteIndex, float
if( !spriteIndex || GetModelType( spriteIndex ) != mod_sprite )
{
ALERT( at_console, "No Sprite %d!\n", spriteIndex );
Con_Printf( "No Sprite %d!\n", spriteIndex );
return NULL;
}
@ -1291,7 +1292,7 @@ TEMPENTITY *CTempEnts::TempSprite( const Vector &pos, const Vector &dir, float s
if( GetModelType( modelIndex ) == mod_bad )
{
ALERT( at_console, "No model %d!\n", modelIndex );
Con_Printf( "No model %d!\n", modelIndex );
return NULL;
}
@ -1391,7 +1392,7 @@ void CTempEnts::Sprite_Spray( const Vector &pos, const Vector &dir, int modelInd
if( GetModelType( modelIndex ) == mod_bad )
{
ALERT( at_console, "No model %d!\n", modelIndex );
Con_Printf( "No model %d!\n", modelIndex );
return;
}
@ -1430,7 +1431,7 @@ void CTempEnts::Sprite_Trail( int type, const Vector &vecStart, const Vector &ve
if( GetModelType( modelIndex ) == mod_bad )
{
ALERT( at_console, "No model %d!\n", modelIndex );
Con_Printf( "No model %d!\n", modelIndex );
return;
}

View File

@ -9,7 +9,6 @@
//-----------------------------------------------------------------------------
// Purpose: implementation for temp entities
//-----------------------------------------------------------------------------
#include "te_shared.h"
#include "tmpent_def.h"
#include "effects_api.h"

View File

@ -182,7 +182,7 @@ void ProcessRain( void )
// just in case..
if ( deathHeight > vecStart[2] )
{
ALERT( at_error, "rain: can't create drip in water\n" );
Con_Printf( "rain: can't create drip in water\n" );
continue;
}
@ -191,7 +191,7 @@ void ProcessRain( void )
if ( !newClDrip )
{
gHUD.Rain.dripsPerSecond = 0; // disable rain
ALERT( at_error, "rain: failed to allocate object!\n");
Con_Printf( "rain: failed to allocate object!\n");
return;
}
@ -222,22 +222,22 @@ void ProcessRain( void )
else
{
if ( cl_debugrain->value )
ALERT( at_error, "rain: drip limit overflow! %i > %i\n", dripcounter, MAXDRIPS );
Con_Printf( "rain: drip limit overflow! %i > %i\n", dripcounter, MAXDRIPS );
return;
}
}
if ( cl_debugrain->value ) // print debug info
{
ALERT( at_console, "Rain info: Drips exist: %i\n", dripcounter );
ALERT( at_console, "Rain info: FX's exist: %i\n", fxcounter );
ALERT( at_console, "Rain info: Attempted/Dropped: %i, %i\n", debug_attempted, debug_dropped );
Con_Printf( "Rain info: Drips exist: %i\n", dripcounter );
Con_Printf( "Rain info: FX's exist: %i\n", fxcounter );
Con_Printf( "Rain info: Attempted/Dropped: %i, %i\n", debug_attempted, debug_dropped );
if ( debug_howmany )
{
float ave = debug_lifetime / (float)debug_howmany;
ALERT( at_console, "Rain info: Average drip life time: %f\n", ave);
Con_Printf( "Rain info: Average drip life time: %f\n", ave);
}
else ALERT( at_console, "Rain info: Average drip life time: --\n" );
else Con_Printf( "Rain info: Average drip life time: --\n" );
}
return;
}
@ -251,14 +251,14 @@ void WaterLandingEffect( cl_drip *drip )
{
if ( fxcounter >= MAXFX )
{
ALERT( at_console, "Rain error: FX limit overflow!\n" );
Con_Printf( "Rain error: FX limit overflow!\n" );
return;
}
cl_rainfx *newFX = new cl_rainfx;
if ( !newFX )
{
ALERT( at_console, "Rain error: failed to allocate FX object!\n");
Con_Printf( "Rain error: failed to allocate FX object!\n");
return;
}
@ -427,7 +427,7 @@ void ParseRainFile( void )
strcpy( mapname, STRING( gpGlobals->mapname ));
if ( strlen( mapname ) == 0 )
{
ALERT( at_error, "rain: unable to read map name\n" );
Con_Printf( "rain: unable to read map name\n" );
return;
}
@ -442,7 +442,7 @@ void ParseRainFile( void )
if ( !pfile )
{
if (cl_debugrain->value > 1 )
ALERT( at_error, "rain: couldn't open rain settings file %s\n", mapname );
Con_Printf( "rain: couldn't open rain settings file %s\n", mapname );
return;
}
@ -491,7 +491,7 @@ void ParseRainFile( void )
token = COM_ParseToken( &pfile );
gHUD.Rain.globalHeight = atof( token );
}
else ALERT( at_error, "rain: unknown token %s in file %s\n", token, mapname );
else Con_Printf( "rain: unknown token %s in file %s\n", token, mapname );
}
FREE_FILE( afile );
}
@ -667,7 +667,7 @@ void DrawFXObjects( void )
// UNDONE: calc lighting right
g_engfuncs.pEfxAPI->R_LightForPoint( (const float *)curFX->origin, color );
// ALERT( at_console, "color %g %g %g\n", color[0], color[1], color[2] );
// Con_Printf( "color %g %g %g\n", color[0], color[1], color[2] );
g_engfuncs.pTriAPI->Color4f( 0.4 + color[0], 0.4 + color[1], 0.4 + color[2], alpha );
g_engfuncs.pTriAPI->Begin( TRI_QUADS );

View File

@ -112,7 +112,7 @@ void HUD_StudioEvent( const mstudioevent_t *event, cl_entity_t *entity )
EV_EjectShell( event, entity );
break;
default:
ALERT( at_console, "Unhandled client-side attachment %i ( %s )\n", event->event, event->options );
Con_Printf( "Unhandled client-side attachment %i ( %s )\n", event->event, event->options );
break;
}
}
@ -160,7 +160,7 @@ int HUD_StudioDoInterp( cl_entity_t *e )
{
if( r_studio_lerping->integer )
{
return (e->curstate.flags & EF_NOINTERP) ? false : true;
return (e->curstate.effects & EF_NOINTERP) ? false : true;
}
return false;
}

View File

@ -10,11 +10,6 @@
DLL_GLOBAL const Vector g_vecZero = Vector( 0.0f, 0.0f, 0.0f );
const float bytedirs[NUMVERTEXNORMALS][3] =
{
#include "anorms.h"
};
#ifdef _DEBUG
void DBG_AssertFunction( BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage )
{
@ -24,27 +19,11 @@ void DBG_AssertFunction( BOOL fExpr, const char* szExpr, const char* szFile, int
if( szMessage != NULL )
sprintf( szOut, "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage );
else sprintf( szOut, "ASSERT FAILED:\n %s \n(%s@%d)", szExpr, szFile, szLine );
ALERT( at_error, szOut );
Con_Printf( szOut );
}
#endif // DEBUG
Vector BitsToDir( int bits )
{
Vector dir;
if( bits < 0 || bits >= NUMVERTEXNORMALS )
return Vector( 0, 0, 0 );
dir.x = bytedirs[bits][0];
dir.y = bytedirs[bits][1];
dir.z = bytedirs[bits][2];
return dir;
}
// NOTE: modify these functions with caution
typedef struct
{
char *name;
@ -69,7 +48,7 @@ void END_READ( void )
{
if( gMsg.badRead )
{
ALERT( at_console, "%s was received with errors\n", gMsg.name );
Con_Printf( "%s was received with errors\n", gMsg.name );
}
}
@ -186,11 +165,6 @@ float READ_ANGLE( void )
return (float)(READ_SHORT() * (360.0 / 65536));
}
Vector READ_DIR( void )
{
return BitsToDir( READ_BYTE() );
}
/*
==============================================================================
@ -307,11 +281,6 @@ void SetScreenFade( Vector fadeColor, float alpha, float duration, float holdTim
sf->fadeEnd += sf->fadeReset;
}
}
if( fadeFlags & FFADE_PURGE )
{
ClearAllFades();
}
}
void DrawScreenFade( void )
@ -545,7 +514,7 @@ BOOL Sys_LoadLibrary( const char* dllname, dllhandle_t* handle, const dllfunctio
}
}
ALERT( at_loading, "%s loaded succesfully!\n", dllname );
Con_Printf( "%s loaded succesfully!\n", dllname );
*handle = dllhandle;
return true;
}

View File

@ -15,6 +15,14 @@ extern cl_enginefuncs_t g_engfuncs;
#define FILE_GLOBAL static
#define DLL_GLOBAL
// euler angle order
#define PITCH 0
#define YAW 1
#define ROLL 2
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
//
// How did I ever live without ASSERT?
//
@ -35,7 +43,7 @@ void DBG_AssertFunction( BOOL fExpr, const char* szExpr, const char* szFile, int
extern DLL_GLOBAL const Vector g_vecZero;
extern cl_globalvars_t *gpGlobals;
extern movevars_t *gpMovevars;
extern struct movevars_s *gpMovevars;
extern int HUD_VidInit( void );
extern void HUD_Init( void );
@ -51,7 +59,7 @@ extern void HUD_Frame( double time );
extern void HUD_Shutdown( void );
extern void HUD_RenderCallback( int fTrans );
extern void HUD_CreateEntities( void );
extern int HUD_AddVisibleEntity( cl_entity_t *pEnt, int ed_type );
extern int HUD_AddVisibleEntity( cl_entity_t *pEnt, int entityType );
extern void HUD_ParticleEffect( const float *org, const float *dir, int color, int count );
extern void HUD_StudioEvent( const mstudioevent_t *event, cl_entity_t *entity );
extern void HUD_StudioFxTransform( cl_entity_t *ent, float transform[4][4] );
@ -189,8 +197,6 @@ inline cl_entity_t *DBG_GetEntityByIndex( int entnum, const char *file, const in
}
#endif
extern Vector BitsToDir( int bits );
// message reading
extern void BEGIN_READ( const char *pszName, int iSize, void *pBuf );
extern int READ_CHAR( void );
@ -202,7 +208,6 @@ extern float READ_FLOAT( void );
extern char* READ_STRING( void );
extern float READ_COORD( void );
extern float READ_ANGLE( void );
extern Vector READ_DIR( void );
extern void END_READ( void );
// misc utilities
@ -228,7 +233,6 @@ extern void Tracer_Draw( HSPRITE hSpr, Vector& start, Vector& delta, float width
// mathlib
extern void AngleMatrix( const vec3_t angles, float (*matrix)[4] );
extern const float bytedirs[NUMVERTEXNORMALS][3];
// from cl_view.c
extern void DrawProgressBar( void );

View File

@ -87,9 +87,8 @@ void V_ThirdPerson( void )
{
// no thirdperson in multiplayer
if( gpGlobals->maxClients > 1 ) return;
if( !gHUD.viewFlags )
gHUD.m_iLastCameraMode = gHUD.m_iCameraMode = 1;
else gHUD.m_iLastCameraMode = 1; // set new view after release camera
gHUD.m_iCameraMode = 1;
}
//==========================
@ -97,9 +96,7 @@ void V_ThirdPerson( void )
//==========================
void V_FirstPerson( void )
{
if( !gHUD.viewFlags )
gHUD.m_iLastCameraMode = gHUD.m_iCameraMode = 0;
else gHUD.m_iLastCameraMode = 0; // set new view after release camera
gHUD.m_iCameraMode = 0;
}
/*
@ -233,7 +230,7 @@ float V_CalcFov( float fov_x, float width, float height )
// check to avoid division by zero
if( fov_x < 1 || fov_x > 179 )
{
ALERT( at_error, "V_CalcFov: invalid fov %g!\n", fov_x );
Con_Printf( "V_CalcFov: invalid fov %g!\n", fov_x );
fov_x = 90;
}
@ -555,37 +552,7 @@ void V_CalcCameraRefdef( ref_params_t *pparams )
{
if( pparams->intermission ) return; // disable in intermission mode
if( gHUD.viewFlags & CAMERA_ON )
{
// this is a viewentity sets with BUzer's custom camera code
cl_entity_t *viewentity = GetEntityByIndex( gHUD.viewEntityIndex );
if( viewentity )
{
studiohdr_t *viewmonster = (studiohdr_t *)GetModelPtr( viewentity );
float m_fLerp = GetLerpFrac();
if( viewentity->curstate.movetype == MOVETYPE_STEP )
v_origin = LerpPoint( viewentity->prevstate.origin, viewentity->curstate.origin, m_fLerp );
else v_origin = viewentity->origin; // already interpolated
// calc monster view if supposed
if( gHUD.viewFlags & MONSTER_VIEW && viewmonster )
v_origin += viewmonster->eyeposition;
if( viewentity->curstate.movetype == MOVETYPE_STEP )
v_angles = LerpAngle( viewentity->prevstate.angles, viewentity->curstate.angles, m_fLerp );
else v_angles = viewentity->angles; // already interpolated
if( gHUD.viewFlags & INVERSE_X ) // inverse X coordinate
v_angles[0] = -v_angles[0];
pparams->crosshairangle[ROLL] = 1; // crosshair is hided
// refresh position
pparams->viewangles = v_angles;
pparams->vieworg = v_origin;
}
}
else if( GetEntityByIndex( pparams->viewentity ) != GetLocalPlayer( ))
if( GetEntityByIndex( pparams->viewentity ) != GetLocalPlayer( ))
{
// this is a viewentity which sets by SET_VIEW builtin
cl_entity_t *viewentity = GetEntityByIndex( pparams->viewentity );
@ -625,7 +592,7 @@ cl_entity_t *V_FindIntermisionSpot( ref_params_t *pparams )
for( int i = 0; i < pparams->num_entities; i++ )
{
ent = GetEntityByIndex( i );
if( ent && !stricmp( STRING( ent->classname ), "info_intermission" ))
if( ent && !stricmp( ent->curstate.classname, "info_intermission" ))
{
if( j > 15 ) break; // spotlist is full
spotindex[j] = ent->index; // save entindex

View File

@ -135,7 +135,7 @@ void CHud :: VidInit( void )
}
else
{
ALERT( at_warning, "hud.txt couldn't load\n" );
Con_Printf( "Warning: hud.txt couldn't load\n" );
CVAR_SET_FLOAT( "hud_draw", 0 );
return;
}
@ -262,10 +262,6 @@ int CHud :: Redraw( float flTime )
CLIENT_COMMAND( "screenshot\n" );
m_flShotTime = 0;
}
// custom view active, and flag "draw hud" isn't set
if(( viewFlags & CAMERA_ON ) && !( viewFlags & DRAW_HUD ))
return 1;
if( CVAR_GET_FLOAT( "hud_draw" ))
{

View File

@ -538,16 +538,13 @@ public:
int m_Teamplay;
int m_iRes;
int m_iCameraMode;
int m_iLastCameraMode;
int m_iFontHeight;
int DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b );
int DrawHudString( int x, int y, int iMaxX, char *szString, int r, int g, int b );
int DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b );
int DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b );
int GetNumWidth( int iNumber, int iFlags );
int viewEntityIndex;
int m_iHUDColor;
int viewFlags;
private:
// the memory for these arrays are allocated in the first call to CHud::VidInit()
// when the hud.txt and associated sprites are loaded. freed in ~CHud()
@ -603,7 +600,6 @@ public:
int _cdecl MsgFunc_RainData( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_HUDColor( const char *pszName, int iSize, void *pbuf);
int _cdecl MsgFunc_SetFog( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_CamData( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf );

View File

@ -432,10 +432,10 @@ void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
if( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS|HIDEHUD_ALL ))
return;
if(!(gHUD.m_iWeaponBits & ITEM_SUIT))
if(!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT))))
return;
if(!(gHUD.m_iWeaponBits & ~ITEM_SUIT))
if(!(gHUD.m_iWeaponBits & ~(1<<(WEAPON_SUIT))))
return;
WEAPON *p = NULL;
@ -828,7 +828,7 @@ int CHudAmmo::Draw( float flTime )
int a, x, y, r, g, b;
int AmmoWidth;
if(!(gHUD.m_iWeaponBits & ITEM_SUIT))
if(!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT))))
return 1;
if((gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS|HIDEHUD_ALL)))

View File

@ -84,7 +84,7 @@ int CHudBattery :: Draw( float flTime )
UnpackRGB( r, g, b, gHUD.m_iHUDColor );
if(!(gHUD.m_iWeaponBits & ITEM_SUIT))
if(!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT))))
return 1;
// Has health changed? Flash the health #

View File

@ -95,7 +95,7 @@ int CHudFlashlight :: Draw( float flTime )
int r, g, b, x, y, a;
wrect_t rc;
if(!(gHUD.m_iWeaponBits & ITEM_SUIT))
if(!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT))))
return 1;
if( m_fOn )

View File

@ -68,12 +68,12 @@ int CHudGeiger::Draw( float flTime )
// peicewise linear is better than continuous formula for this
if( m_iGeigerRange > 800 )
{
pct = 0; //ALERT( at_console, "range > 800\n" );
pct = 0; //Con_Printf( "range > 800\n" );
}
else if( m_iGeigerRange > 600 )
{
pct = 2;
flvol = 0.4; //ALERT( at_console, "range > 600\n" );
flvol = 0.4; //Con_Printf( "range > 600\n" );
rg[0] = 1;
rg[1] = 1;
i = 2;
@ -81,7 +81,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 500 )
{
pct = 4;
flvol = 0.5; //ALERT( at_console, "range > 500\n" );
flvol = 0.5; //Con_Printf( "range > 500\n" );
rg[0] = 1;
rg[1] = 2;
i = 2;
@ -89,7 +89,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 400 )
{
pct = 8;
flvol = 0.6; //ALERT( at_console, "range > 400\n" );
flvol = 0.6; //Con_Printf( "range > 400\n" );
rg[0] = 1;
rg[1] = 2;
rg[2] = 3;
@ -98,7 +98,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 300 )
{
pct = 8;
flvol = 0.7; //ALERT( at_console, "range > 300\n" );
flvol = 0.7; //Con_Printf( "range > 300\n" );
rg[0] = 2;
rg[1] = 3;
rg[2] = 4;
@ -107,7 +107,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 200 )
{
pct = 28;
flvol = 0.78; //ALERT( at_console, "range > 200\n" );
flvol = 0.78; //Con_Printf( "range > 200\n" );
rg[0] = 2;
rg[1] = 3;
rg[2] = 4;
@ -116,7 +116,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 150 )
{
pct = 40;
flvol = 0.80; //ALERT( at_console, "range > 150\n" );
flvol = 0.80; //Con_Printf( "range > 150\n" );
rg[0] = 3;
rg[1] = 4;
rg[2] = 5;
@ -125,7 +125,7 @@ int CHudGeiger::Draw( float flTime )
else if( m_iGeigerRange > 100 )
{
pct = 60;
flvol = 0.85; //ALERT( at_console, "range > 100\n" );
flvol = 0.85; //Con_Printf( "range > 100\n" );
rg[0] = 3;
rg[1] = 4;
rg[2] = 5;

View File

@ -189,7 +189,7 @@ int CHudHealth :: Draw( float flTime )
ScaleColors( r, g, b, a );
// Only draw health if we have the suit.
if( gHUD.m_iWeaponBits & ITEM_SUIT )
if( gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )
{
HealthWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left;
int CrossWidth = gHUD.GetSpriteRect(m_HUD_cross).right - gHUD.GetSpriteRect(m_HUD_cross).left;

View File

@ -39,7 +39,6 @@ DECLARE_HUDMESSAGE( ViewMode );
DECLARE_HUDMESSAGE( Particle );
DECLARE_HUDMESSAGE( Concuss );
DECLARE_HUDMESSAGE( GameMode );
DECLARE_HUDMESSAGE( CamData );
DECLARE_HUDMESSAGE( TempEntity );
DECLARE_HUDMESSAGE( ServerName );
DECLARE_HUDMESSAGE( ScreenShake );
@ -61,7 +60,6 @@ int CHud :: InitMessages( void )
HOOK_MESSAGE( Particle );
HOOK_MESSAGE( TempEntity );
HOOK_MESSAGE( SetFog );
HOOK_MESSAGE( CamData );
HOOK_MESSAGE( RainData );
HOOK_MESSAGE( WeaponAnim );
HOOK_MESSAGE( SetBody );
@ -71,8 +69,6 @@ int CHud :: InitMessages( void )
HOOK_COMMAND( "hud_changelevel", ChangeLevel ); // send by engine
viewEntityIndex = 0; // trigger_viewset stuff
viewFlags = 0;
m_flFOV = 0;
m_iHUDColor = RGB_YELLOWISH; // 255, 160, 0
@ -80,7 +76,6 @@ int CHud :: InitMessages( void )
CVAR_REGISTER( "default_fov", "90", 0, "default client fov" );
CVAR_REGISTER( "hud_draw", "1", 0, "disable hud rendering" );
CVAR_REGISTER( "hud_takesshots", "0", 0, "take screenshots at 30 fps" );
CVAR_REGISTER( "hud_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
// clear any old HUD list
if( m_pHudList )
@ -273,27 +268,6 @@ int CHud :: MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf )
return 1;
}
int CHud :: MsgFunc_CamData( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
gHUD.viewEntityIndex = READ_SHORT();
gHUD.viewFlags = READ_SHORT();
if( gHUD.viewFlags )
m_iCameraMode = 1;
else m_iCameraMode = m_iLastCameraMode;
// update pparams->viewentity too for right hearing
if( gHUD.viewEntityIndex )
gpViewParams->viewentity = gHUD.viewEntityIndex;
else gpViewParams->viewentity = GetLocalPlayer()->index;
END_READ();
return 1;
}
int CHud :: MsgFunc_RainData( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
@ -424,41 +398,15 @@ int CHud::MsgFunc_ScreenShake( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
ShakeCommand_t eCommand = (ShakeCommand_t)READ_SHORT();
float amplitude = (float)(unsigned short)READ_SHORT() * (1.0f / (float)(1<<12));
float duration = (float)(unsigned short)READ_SHORT() * (1.0f / (float)(1<<12));
float frequency = (float)(unsigned short)READ_SHORT() * (1.0f / (float)(1<<8));
if( eCommand == SHAKE_STOP )
{
m_Shake.amplitude = 0;
m_Shake.frequency = 0;
m_Shake.duration = 0;
}
else
{
if(( eCommand == SHAKE_START) || ( eCommand == SHAKE_FREQUENCY ))
{
m_Shake.frequency = frequency;
}
if(( eCommand == SHAKE_START) || ( eCommand == SHAKE_AMPLITUDE ))
{
// don't overwrite larger existing shake unless we are told to.
if(( amplitude > m_Shake.amplitude ) || ( eCommand == SHAKE_AMPLITUDE ))
{
m_Shake.amplitude = amplitude;
}
}
// only reset the timer for a new shake.
if( eCommand == SHAKE_START )
{
m_Shake.duration = duration;
m_Shake.nextShake = 0;
m_Shake.time = m_flTime + duration;
}
}
m_Shake.frequency = frequency;
m_Shake.amplitude = amplitude;
m_Shake.duration = duration;
m_Shake.time = m_flTime + duration;
m_Shake.nextShake = 0;
END_READ();

View File

@ -1,50 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2006 ©
// basetypes.h - general typedefs
//=======================================================================
#ifndef BASETYPES_H
#define BASETYPES_H
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
typedef unsigned __int64 qword;
typedef unsigned int uint;
typedef int BOOL;
typedef signed __int64 int64;
typedef int func_t;
typedef int sound_t;
typedef int string_t;
typedef int shader_t;
typedef struct cvar_s cvar_t;
typedef struct edict_s edict_t;
typedef struct pmove_s pmove_t;
typedef struct movevars_s movevars_t;
typedef struct usercmd_s usercmd_t;
typedef struct cl_priv_s cl_priv_t;
typedef struct sv_priv_s sv_priv_t;
typedef struct netadr_s netadr_t;
typedef unsigned short CRC16_t;
typedef unsigned long CRC32_t;
typedef float vec_t;
#define DLLEXPORT __declspec( dllexport )
#define FALSE 0
#define TRUE 1
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef BIT
#define BIT( n ) (1<<( n ))
#endif
// color strings
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
typedef struct { byte r; byte g; byte b; } color24;
#endif//BASETYPES_H

View File

@ -14,20 +14,7 @@ typedef enum
BEAM_HOSE,
} kBeamType_t;
// beam flags
#define FBEAM_STARTENTITY 0x00000001
#define FBEAM_ENDENTITY 0x00000002
#define FBEAM_FADEIN 0x00000004
#define FBEAM_FADEOUT 0x00000008
#define FBEAM_SINENOISE 0x00000010
#define FBEAM_SOLID 0x00000020
#define FBEAM_SHADEIN 0x00000040
#define FBEAM_SHADEOUT 0x00000080
#define FBEAM_ONLYNOISEONCE 0x00000100 // Only calculate our noise once
#define FBEAM_STARTVISIBLE 0x10000000 // Has this client actually seen this beam's start entity yet?
#define FBEAM_ENDVISIBLE 0x20000000 // Has this client actually seen this beam's end entity yet?
#define FBEAM_ISACTIVE 0x40000000
#define FBEAM_FOREVER 0x80000000
// Start/End Entity is encoded as 12 bits of entity index, and 4 bits of attachment (4:12)
#define BEAMENT_ENTITY( x ) ((x) & 0xFFF)

View File

@ -18,6 +18,10 @@ BRUSH MODELS
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
#define HLBSP_VERSION 30 // half-life regular version
// worldcraft predefined angles
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// bmodel limits
#define MAX_MAP_HULLS 4 // MAX_HULLS

View File

@ -53,14 +53,8 @@ struct cl_entity_s
{
int index; // Index into cl_entities ( always match actual slot )
int player; // True if this entity is a "player"
string_t classname; // classname come from server
// Add also targetname, target, message and netname ?
int serverframe; // TEMPORARY PLACED HERE
link_t area; // used by physics code
vec3_t absmin;
vec3_t absmax;
entity_state_t baseline; // The original state from which to delta during an uncompressed message
entity_state_t prevstate; // The state information from the penultimate message received from the server
entity_state_t curstate; // The state information from the last message received from server

View File

@ -122,7 +122,7 @@ typedef struct cl_globalvars_s
int maxEntities;
int numEntities; // actual ents count
const char *pStringBase; // actual only when sys_sharedstrings is 1
const char *pStringBase;
void *pSaveData; // (SAVERESTOREDATA *) pointer
} cl_globalvars_t;
@ -193,7 +193,8 @@ typedef struct cl_enginefuncs_s
const char *(*pfnCmd_Args)( void ); // was Con_Printf
float (*pfnGetLerpFrac)( void ); // was Con_DPrintf
void (*pfnDelCommand)( const char *cmd_name ); // was Con_NPrintf
void (*pfnAlertMessage)( ALERT_TYPE, char *szFmt, ... ); // was Con_NXPrintf
void (*Con_Printf)( char *fmt, ... ); // was Con_NXPrintf
void (*Con_DPrintf)( char *fmt, ... ); // !!!
const char* (*pfnPhysInfo_ValueForKey)( const char *key );
const char* (*pfnServerInfo_ValueForKey)( const char *key );
@ -268,13 +269,13 @@ typedef struct
void (*pfnShutdown)( void );
void (*pfnDrawTriangles)( int fTrans );
void (*pfnCreateEntities)( void );
int (*pfnAddVisibleEntity)( struct cl_entity_s *pEnt, int ed_type );
int (*pfnAddVisibleEntity)( struct cl_entity_s *pEnt, int entityType );
void (*pfnStudioEvent)( const mstudioevent_t *event, struct cl_entity_s *entity );
void (*pfnStudioFxTransform)( struct cl_entity_s *pEdict, float transform[4][4] );
void (*pfnCalcRefdef)( ref_params_t *parms );
void (*pfnPM_Move)( struct playermove_s *ppmove, int server );
void (*pfnPM_Init)( struct playermove_s *ppmove );
char (*pfnPM_FindTextureType)( const char *name );
char (*pfnPM_FindTextureType)( char *name );
void (*pfnCmdStart)( const struct cl_entity_s *player, int runfuncs );
void (*pfnCmdEnd)( const struct cl_entity_s *player, const usercmd_t *cmd, unsigned int random_seed );
void (*pfnCreateMove)( usercmd_t *cmd, int msec, int active );

View File

@ -67,7 +67,7 @@ typedef struct msurface_s
// lighting info
byte *samples; // [numstyles*surfsize]
int numstyles;
byte styles[LM_STYLES]; // index into d_lightstylevalue[] for animated lights
byte styles[4]; // index into d_lightstylevalue[] for animated lights
// no one surface can be effected by more than 4
// animated lights.
} msurface_t;

View File

@ -5,56 +5,569 @@
#ifndef CONST_H
#define CONST_H
// euler angle order
#define PITCH 0
#define YAW 1
#define ROLL 2
//
// Constants shared by the engine and dlls
// This header file included by engine files and DLL files.
// Most came from server.h
#define LM_STYLES 4 // MAXLIGHTMAPS
// edict->flags
#define FL_FLY (1<<0) // Changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1<<1) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define FL_CONVEYOR (1<<2)
#define FL_CLIENT (1<<3)
#define FL_INWATER (1<<4)
#define FL_MONSTER (1<<5)
#define FL_GODMODE (1<<6)
#define FL_NOTARGET (1<<7)
#define FL_SKIPLOCALHOST (1<<8) // Don't send entity to local host, it's predicting this entity itself
#define FL_ONGROUND (1<<9) // At rest / on the ground
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
#define FL_WATERJUMP (1<<11) // player jumping out of water
#define FL_FROZEN (1<<12) // Player is frozen for 3rd person camera
#define FL_FAKECLIENT (1<<13) // JAC: fake client, simulated server side; don't send network messages to them
#define FL_DUCKING (1<<14) // Player flag -- Player is fully crouched
#define FL_FLOAT (1<<15) // Apply floating force to this entity when in water
#define FL_GRAPHED (1<<16) // worldgraph has this ent listed as something that blocks a connection
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
// UNDONE: Do we need these?
#define FL_IMMUNE_WATER (1<<17)
#define FL_IMMUNE_SLIME (1<<18)
#define FL_IMMUNE_LAVA (1<<19)
// worldcraft predefined angles
#define ANGLE_UP -1
#define ANGLE_DOWN -2
#define FL_PROXY (1<<20) // This is a spectator proxy
#define FL_ALWAYSTHINK (1<<21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path)
#define FL_BASEVELOCITY (1<<22) // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_MONSTERCLIP (1<<23) // Only collide in with monsters who have FL_MONSTERCLIP set
#define FL_ONTRAIN (1<<24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_WORLDBRUSH (1<<25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_SPECTATOR (1<<26) // This client is a spectator, don't run touch functions, etc.
#define FL_CHECK_PHS (1<<27) // This entity requested phs bitvector instead of pvsbitvector in AddToFullPack calls
#define FL_PLAYERCLIP (1<<28) // Only collide in with clients who have FL_PLAYERCLIP set
#define FL_CUSTOMENTITY (1<<29) // This is a custom entity
#define FL_KILLME (1<<30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time
#define FL_DORMANT (1<<31) // Entity is dormant, no updates to client
// sound specific
#define VOL_NORM 1.0f // volume values
// Goes into globalvars_t.trace_flags
#define FTRACE_SIMPLEBOX (1<<0) // Traceline with a simple box
#define FTRACE_IGNORE_GLASS (1<<1) // traceline will be ignored entities with rendermode != kRenderNormal
// pitch values
#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high
#define PITCH_NORM 100 // non-pitch shifted
#define PITCH_HIGH 120
// walkmove modes
#define WALKMOVE_NORMAL 0 // normal walkmove
#define WALKMOVE_WORLDONLY 1 // doesn't hit ANY entities, no matter what the solid type
#define WALKMOVE_CHECKONLY 2 // move, but don't touch triggers
// attenuation values
#define ATTN_NONE 0.0f
#define ATTN_NORM 0.8f
#define ATTN_IDLE 2.0f
#define ATTN_STATIC 1.25f
// edict->movetype values
#define MOVETYPE_NONE 0 // never moves
//#define MOVETYPE_ANGLENOCLIP 1
//#define MOVETYPE_ANGLECLIP 2
#define MOVETYPE_WALK 3 // Player only - moving on the ground
#define MOVETYPE_STEP 4 // gravity, special edge handling -- monsters use this
#define MOVETYPE_FLY 5 // No gravity, but still collides with stuff
#define MOVETYPE_TOSS 6 // gravity/collisions
#define MOVETYPE_PUSH 7 // no clip to world, push and crush
#define MOVETYPE_NOCLIP 8 // No gravity, no collisions, still do velocity/avelocity
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
#define MOVETYPE_BOUNCE 10 // Just like Toss, but reflect velocity when contacting surfaces
#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity
#define MOVETYPE_FOLLOW 12 // track movement of aiment
#define MOVETYPE_PUSHSTEP 13 // BSP model that needs physics/world collisions (uses nearest hull for world collision)
// common conversion tools
#define ATTN_TO_SNDLVL( a ) (int)((a) ? (50 + 20 / ((float)a)) : 0 )
#define SNDLVL_TO_ATTN( a ) ((a > 50) ? (20.0f / (float)(a - 50)) : 4.0 )
// edict->solid values
// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves
// SOLID only effects OTHER entities colliding with this one when they move - UGH!
#define SOLID_NOT 0 // no interaction with other objects
#define SOLID_TRIGGER 1 // touch on edge, but not blocking
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SND_CHANGE_VOL (1<<0) // change sound vol
#define SND_CHANGE_PITCH (1<<1) // change sound pitch
#define SND_STOP (1<<2) // stop the sound
#define SND_SPAWNING (1<<3) // we're spawing, used in some cases for ambients
#define SND_LOCALSOUND (1<<4) // not paused, not looped, for internal use
#define SND_STOP_LOOPING (1<<5) // stop all looping sounds on the entity.
#define SND_SPEAKER (1<<6) // being played again by a microphone through a speaker
// edict->deadflag values
#define DEAD_NO 0 // alive
#define DEAD_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground
#define DEAD_DEAD 2 // dead. lying still.
#define DEAD_RESPAWNABLE 3 // wait for respawn
#define DEAD_DISCARDBODY 4
// 7 channels available
#define CHAN_REPLACE -1 // force to replace sound for any channel
#define CHAN_AUTO 0
#define CHAN_WEAPON 1
#define CHAN_VOICE 2
#define CHAN_ITEM 3
#define CHAN_BODY 4
#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area
#define CHAN_STATIC 6 // allocate channel from the static area
#define CHAN_VOICE_BASE 7 // allocate channel for network voice data
#define DAMAGE_NO 0 // can't be damaged
#define DAMAGE_YES 1 // attempt to damage
#define DAMAGE_AIM 2 // special case for aiming damage
// entity effects
#define EF_BRIGHTFIELD (1<<0) // swirling cloud of particles
#define EF_MUZZLEFLASH (1<<1) // single frame ELIGHT on entity attachment 0
#define EF_BRIGHTLIGHT (1<<2) // DLIGHT centered at entity origin
#define EF_DIMLIGHT (1<<3) // player flashlight
#define EF_INVLIGHT (1<<4) // get lighting from ceiling
#define EF_NOINTERP (1<<5) // don't interpolate the next frame
#define EF_LIGHT (1<<6) // rocket flare glow sprite
#define EF_NODRAW (1<<7) // don't draw entity
#define EF_NOREFLECT (1<<8) // entity won't reflecting in mirrors
#define EF_REFLECTONLY (1<<9) // entity will be drawing only in mirrors
#define EF_NOWATERCSG (1<<10) // do not remove sides for func_water entity
#define EF_MINLIGHT (1<<11) // allways have some light (e.g. viewentity)
#define EF_FULLBRIGHT (1<<12) // just get fullbright
#define EF_NOSHADOW (1<<13) // ignore shadow for this entity
#define EF_MERGE_VISIBILITY (1<<14) // this entity allowed to merge vis (e.g. env_sky or portal camera)
// user-specified entity effects
#define EF_LASERSPOT (1<<16) // tempentity laserspot at attachment #1 from player or npc
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
// classic quake flags (must be not collide with any dll spawnflags - engine uses this)
// please include string "allow_inhibited_entities" into your gameinfo.txt if you want to enable this feature
#define SF_NOT_EASY (1<<8)
#define SF_NOT_MEDIUM (1<<9)
#define SF_NOT_HARD (1<<10)
#define SF_NOT_DEATHMATCH (1<<11)
//
// temp entity events (engine ignore it)
//
#define TE_BEAMPOINTS 0 // beam effect between two points
// coord coord coord (start position)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMENTPOINT 1 // beam effect between point and entity
// short (start entity)
// coord coord coord (end position)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_GUNSHOT 2 // particle effect plus ricochet sound
// coord coord coord (position)
#define TE_EXPLOSION 3 // additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
// byte (flags)
//
// The Explosion effect has some flags to control performance/aesthetic features:
#define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
#define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
#define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
#define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
#define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
#define TE_EXPLFLAG_DRAWALPHA 16 // sprite will be drawn alpha
#define TE_EXPLFLAG_ROTATE 32 // rotate the sprite randomly
#define TE_TAREXPLOSION 4 // Quake1 "tarbaby" explosion with sound
// coord coord coord (position)
#define TE_SMOKE 5 // alphablend sprite, move vertically 30 pps
// coord coord coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (framerate)
#define TE_TRACER 6 // tracer effect from point to point
// coord, coord, coord (start)
// coord, coord, coord (end)
#define TE_LIGHTNING 7 // TE_BEAMPOINTS with simplified parameters
// coord, coord, coord (start)
// coord, coord, coord (end)
// byte (life in 0.1's)
// byte (width in 0.1's)
// byte (amplitude in 0.01's)
// short (sprite model index)
#define TE_BEAMENTS 8
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_SPARKS 9 // 8 random tracers with gravity, ricochet sprite
// coord coord coord (position)
#define TE_LAVASPLASH 10 // Quake1 lava splash
// coord coord coord (position)
#define TE_TELEPORT 11 // Quake1 teleport splash
// coord coord coord (position)
#define TE_EXPLOSION2 12 // Quake1 colormaped (base palette) particle explosion with sound
// coord coord coord (position)
// byte (starting color)
// byte (num colors)
#define TE_BSPDECAL 13 // Decal from the .BSP file
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// short (texture index of precached decal texture name)
// short (entity index)
// [optional - only included if previous short is non-zero (not the world)] short (index of model of above entity)
#define TE_IMPLOSION 14 // tracers moving toward a point
// coord, coord, coord (position)
// byte (radius)
// byte (count)
// byte (life in 0.1's)
#define TE_SPRITETRAIL 15 // line of moving glow sprites with gravity, fadeout, and collisions
// coord, coord, coord (start)
// coord, coord, coord (end)
// short (sprite index)
// byte (count)
// byte (life in 0.1's)
// byte (scale in 0.1's)
// byte (velocity along vector in 10's)
// byte (randomness of velocity in 10's)
#define TE_BEAM 16 // obsolete
#define TE_SPRITE 17 // additive sprite, plays 1 cycle
// coord, coord, coord (position)
// short (sprite index)
// byte (scale in 0.1's)
// byte (brightness)
#define TE_BEAMSPRITE 18 // A beam with a sprite at the end
// coord, coord, coord (start position)
// coord, coord, coord (end position)
// short (beam sprite index)
// short (end sprite index)
#define TE_BEAMTORUS 19 // screen aligned beam ring, expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMDISK 20 // disk that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMCYLINDER 21 // cylinder that expands to max radius over lifetime
// coord coord coord (center position)
// coord coord coord (axis and radius)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_BEAMFOLLOW 22 // create a line of decaying beam segments until entity stops moving
// short (entity:attachment to follow)
// short (sprite index)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte,byte,byte (color)
// byte (brightness)
#define TE_GLOWSPRITE 23
// coord, coord, coord (pos) short (model index) byte (scale / 10)
#define TE_BEAMRING 24 // connect a beam ring to two entities
// short (start entity)
// short (end entity)
// short (sprite index)
// byte (starting frame)
// byte (frame rate in 0.1's)
// byte (life in 0.1's)
// byte (line width in 0.1's)
// byte (noise amplitude in 0.01's)
// byte,byte,byte (color)
// byte (brightness)
// byte (scroll speed in 0.1's)
#define TE_STREAK_SPLASH 25 // oriented shower of tracers
// coord coord coord (start position)
// coord coord coord (direction vector)
// byte (color)
// short (count)
// short (base speed)
// short (ramdon velocity)
#define TE_BEAMHOSE 26 // obsolete
#define TE_DLIGHT 27 // dynamic light, effect world, minor entity effect
// coord, coord, coord (pos)
// byte (radius in 10's)
// byte byte byte (color)
// byte (brightness)
// byte (life in 10's)
// byte (decay rate in 10's)
#define TE_ELIGHT 28 // point entity light, no world effect
// short (entity:attachment to follow)
// coord coord coord (initial position)
// coord (radius)
// byte byte byte (color)
// byte (life in 0.1's)
// coord (decay rate)
#define TE_TEXTMESSAGE 29
// short 1.2.13 x (-1 = center)
// short 1.2.13 y (-1 = center)
// byte Effect 0 = fade in/fade out
// 1 = flickery credits
// 2 = write out (training room)
// 4 bytes r,g,b,a color1 (text color)
// 4 bytes r,g,b,a color2 (effect color)
// ushort 8.8 fadein time
// ushort 8.8 fadeout time
// ushort 8.8 hold time
// optional ushort 8.8 fxtime (time the highlight lags behing the leading text in effect 2)
// string text message (512 chars max sz string)
#define TE_LINE 30
// coord, coord, coord startpos
// coord, coord, coord endpos
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_BOX 31
// coord, coord, coord boxmins
// coord, coord, coord boxmaxs
// short life in 0.1 s
// 3 bytes r, g, b
#define TE_KILLBEAM 99 // kill all beams attached to entity
// short (entity)
#define TE_LARGEFUNNEL 100
// coord coord coord (funnel position)
// short (sprite index)
// short (flags)
#define TE_BLOODSTREAM 101 // particle spray
// coord coord coord (start position)
// coord coord coord (spray vector)
// byte (color)
// byte (speed)
#define TE_SHOWLINE 102 // line of particles every 5 units, dies in 30 seconds
// coord coord coord (start position)
// coord coord coord (end position)
#define TE_BLOOD 103 // particle spray
// coord coord coord (start position)
// coord coord coord (spray vector)
// byte (color)
// byte (speed)
#define TE_DECAL 104 // Decal applied to a brush entity (not the world)
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
// short (entity index)
#define TE_FIZZ 105 // create alpha sprites inside of entity, float upwards
// short (entity)
// short (sprite index)
// byte (density)
#define TE_MODEL 106 // create a moving model that bounces and makes a sound when it hits
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// angle (initial yaw)
// short (model index)
// byte (bounce sound type)
// byte (life in 0.1's)
#define TE_EXPLODEMODEL 107 // spherical shower of models, picks from set
// coord, coord, coord (origin)
// coord (velocity)
// short (model index)
// short (count)
// byte (life in 0.1's)
#define TE_BREAKMODEL 108 // box of models or sprites
// coord, coord, coord (position)
// coord, coord, coord (size)
// coord, coord, coord (velocity)
// byte (random velocity in 10's)
// short (sprite or model index)
// byte (count)
// byte (life in 0.1 secs)
// byte (flags)
#define TE_GUNSHOTDECAL 109 // decal and ricochet sound
// coord, coord, coord (position)
// short (entity index???)
// byte (decal???)
#define TE_SPRITE_SPRAY 110 // spay of alpha sprites
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (sprite index)
// byte (count)
// byte (speed)
// byte (noise)
#define TE_ARMOR_RICOCHET 111 // quick spark sprite, client ricochet sound.
// coord, coord, coord (position)
// byte (scale in 0.1's)
#define TE_PLAYERDECAL 112 // ???
// byte (playerindex)
// coord, coord, coord (position)
// short (entity???)
// byte (decal number???)
// [optional] short (model index???)
#define TE_BUBBLES 113 // create alpha sprites inside of box, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BUBBLETRAIL 114 // create alpha sprites along a line, float upwards
// coord, coord, coord (min start position)
// coord, coord, coord (max start position)
// coord (float height)
// short (model index)
// byte (count)
// coord (speed)
#define TE_BLOODSPRITE 115 // spray of opaque sprite1's that fall, single sprite2 for 1..2 secs (this is a high-priority tent)
// coord, coord, coord (position)
// short (sprite1 index)
// short (sprite2 index)
// byte (color)
// byte (scale)
#define TE_WORLDDECAL 116 // Decal applied to the world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name)
#define TE_WORLDDECALHIGH 117 // Decal (with texture index > 256) applied to world brush
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
#define TE_DECALHIGH 118 // Same as TE_DECAL, but the texture index was greater than 256
// coord, coord, coord (x,y,z), decal position (center of texture in world)
// byte (texture index of precached decal texture name - 256)
// short (entity index)
#define TE_PROJECTILE 119 // Makes a projectile (like a nail) (this is a high-priority tent)
// coord, coord, coord (position)
// coord, coord, coord (velocity)
// short (modelindex)
// byte (life)
// byte (owner) projectile won't collide with owner (if owner == 0, projectile will hit any client).
#define TE_SPRAY 120 // Throws a shower of sprites or models
// coord, coord, coord (position)
// coord, coord, coord (direction)
// short (modelindex)
// byte (count)
// byte (speed)
// byte (noise)
// byte (rendermode)
#define TE_PLAYERSPRITES 121 // sprites emit from a player's bounding box (ONLY use for players!)
// byte (playernum)
// short (sprite modelindex)
// byte (count)
// byte (variance) (0 = no variance in size) (10 = 10% variance in size)
#define TE_PARTICLEBURST 122 // very similar to lavasplash.
// coord (origin)
// short (radius)
// byte (particle color)
// byte (duration * 10) (will be randomized a bit)
#define TE_FIREFIELD 123 // makes a field of fire.
// coord (origin)
// short (radius) (fire is made in a square around origin. -radius, -radius to radius, radius)
// short (modelindex)
// byte (count)
// byte (flags)
// byte (duration (in seconds) * 10) (will be randomized a bit)
//
// to keep network traffic low, this message has associated flags that fit into a byte:
#define TEFIRE_FLAG_ALLFLOAT 1 // all sprites will drift upwards as they animate
#define TEFIRE_FLAG_SOMEFLOAT 2 // some of the sprites will drift upwards. (50% chance)
#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration.
#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque
#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube.
#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
// byte (entity index of player)
// coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset )
// short (model index)
// short (life * 10 );
#define TE_KILLPLAYERATTACHMENTS 125 // will expire all TENTS attached to a player.
// byte (entity index of player)
#define TE_MULTIGUNSHOT 126 // much more compact shotgun message
// This message is used to make a client approximate a 'spray' of gunfire.
// Any weapon that fires more than one bullet per frame and fires in a bit of a spread is
// a good candidate for MULTIGUNSHOT use. (shotguns)
//
// NOTE: This effect makes the client do traces for each bullet, these client traces ignore
// entities that have studio models.Traces are 4096 long.
//
// coord (origin)
// coord (origin)
// coord (origin)
// coord (direction)
// coord (direction)
// coord (direction)
// coord (x noise * 100)
// coord (y noise * 100)
// byte (count)
// byte (bullethole decal texture index)
#define TE_USERTRACER 127 // larger message than the standard tracer, but allows some customization.
// coord (origin)
// coord (origin)
// coord (origin)
// coord (velocity)
// coord (velocity)
// coord (velocity)
// byte ( life * 10 )
// byte ( color ) this is an index into an array of color vectors in the engine. (0 - )
// byte ( length * 10 )
#define MSG_BROADCAST 0 // unreliable to all
#define MSG_ONE 1 // reliable to one (msg_entity)
@ -67,7 +580,7 @@
#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram ( could be dropped )
#define MSG_SPEC 9 // Sends to all spectator proxies
#define CONTENTS_NONE 0
// contents of a spot in the world
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
@ -84,172 +597,42 @@
#define CONTENTS_CURRENT_DOWN -14
#define CONTENTS_TRANSLUCENT -15
#define CONTENTS_LADDER -16
#define CONTENTS_FLYFIELD -17
#define CONTENTS_GRAVITY_FLYFIELD -18
#define CONTENTS_FOG -19
#define CONTENT_FLYFIELD -17
#define CONTENT_GRAVITY_FLYFIELD -18
#define CONTENT_FOG -19
// pev->flags
#define FL_FLY (1<<0) // changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1<<1) // same as AI_FLY but stay in water
#define FL_CONVEYOR (1<<2) // not used in Xash3D
#define FL_CLIENT (1<<3) // this a client entity
#define FL_INWATER (1<<4) // npc in water
#define FL_MONSTER (1<<5) // monster bit
#define FL_GODMODE (1<<6) // invulnerability npc or client
#define FL_NOTARGET (1<<7) // mark all npc's as neytral
#define FL_SKIPLOCALHOST (1<<8) // Don't send entity to local host, it's predicting this entity itself
#define FL_ONGROUND (1<<9) // at rest / on the ground
#define FL_PARTIALGROUND (1<<10) // not corners are valid
#define FL_WATERJUMP (1<<11) // water jumping
#define FL_FROZEN (1<<12) // stop moving, but continue thinking (e.g. for thirdperson camera)
#define FL_FAKECLIENT (1<<13) // JAC: fake client, simulated server side; don't send network messages to them
#define FL_DUCKING (1<<14) // monster (or player) is ducked
#define FL_FLOAT (1<<15) // Apply floating force to this entity when in water
#define FL_GRAPHED (1<<16) // worldgraph has this ent listed as something that blocks a connection
#define FL_IMMUNE_WATER (1<<17) // not used
#define FL_IMMUNE_SLIME (1<<18) // not used
#define FL_IMMUNE_LAVA (1<<19) // not used
#define FL_PROXY (1<<20) // This is a spectator proxy
#define FL_ALWAYSTHINK (1<<21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path)
#define FL_BASEVELOCITY (1<<22) // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_MONSTERCLIP (1<<23) // Only collide in with monsters who have FL_MONSTERCLIP set
#define FL_ONTRAIN (1<<24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_WORLDBRUSH (1<<25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_SPECTATOR (1<<26) // This client is a spectator, don't run touch functions, etc.
#define FL_PHS_FILTER (1<<27) // This entity requested phs bitvector in AddToFullPack calls
#define FL_PLAYERCLIP (1<<28) // Only collide in with clients who have FL_PLAYERCLIP set
#define FL_CUSTOMENTITY (1<<29) // This is a custom entity
#define FL_KILLME (1<<30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time
#define FL_DORMANT (1<<31) // Entity is dormant, no updates to client
// same as CONTENTS_*
#define CONTENT_EMPTY -1
#define CONTENT_SOLID -2
#define CONTENT_WATER -3
#define CONTENT_SLIME -4
#define CONTENT_LAVA -5
#define CONTENT_SKY -6
// pev->spawnflags
#define SF_START_ON (1<<0)
// channels
#define CHAN_AUTO 0
#define CHAN_WEAPON 1
#define CHAN_VOICE 2
#define CHAN_ITEM 3
#define CHAN_BODY 4
#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area
#define CHAN_STATIC 6 // allocate channel from the static area
// classic quake flags (must be not collide with any dll spawnflags - engine uses this)
// please include string "allow_inhibited_entities" into your gameinfo.txt if you want to enable this feature
#define SF_NOT_EASY (1<<8)
#define SF_NOT_MEDIUM (1<<9)
#define SF_NOT_HARD (1<<10)
#define SF_NOT_DEATHMATCH (1<<11)
// attenuation values
#define ATTN_NONE 0.0f
#define ATTN_NORM 0.8f
#define ATTN_IDLE 2.0f
#define ATTN_STATIC 1.25f
// pev->effects
#define EF_BRIGHTFIELD (1<<0) // swirling cloud of particles
#define EF_MUZZLEFLASH (1<<1) // single frame ELIGHT on entity attachment 0
#define EF_BRIGHTLIGHT (1<<2) // DLIGHT centered at entity origin
#define EF_DIMLIGHT (1<<3) // player flashlight
#define EF_INVLIGHT (1<<4) // get lighting from ceiling
#define EF_NOINTERP (1<<5) // don't interpolate the next frame
#define EF_LIGHT (1<<6) // dynamic light (rockets use)
#define EF_NODRAW (1<<7) // don't draw entity
#define EF_ROTATE (1<<8) // rotate bonus item
#define EF_MINLIGHT (1<<9) // allways have some light (viewmodel)
#define EF_FULLBRIGHT (1<<10) // completely ignore light values
#define EF_NOWATERCSG (1<<11) // do not remove sides for func_water entity
#define EF_NOSHADOW (1<<12) // ignore shadow for this entity
#define EF_PLANARSHADOW (1<<13) // use fast planarshadow method instead of shadow casters
#define EF_OCCLUSIONTEST (1<<14) // use occlusion test for this entity (e.g. glares)
#define EF_LASERSPOT (1<<15) // tempentity laserspot at attachment #1 from player or npc
#define EF_NOREFLECT (1<<16) // entity won't reflecting in mirrors
#define EF_REFLECTONLY (1<<17) // entity will be drawing only in mirrors
// pitch values
#define PITCH_NORM 100 // non-pitch shifted
#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high
#define PITCH_HIGH 120
// The explosion effect has some flags to control performance/aesthetic features:
#define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion
#define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite)
#define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights
#define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound
#define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles
#define TE_EXPLFLAG_DRAWALPHA 16 // sprite will be drawn alpha
#define TE_EXPLFLAG_ROTATE 32 // rotate the sprite randomly
// volume values
#define VOL_NORM 1.0f
// pev->takedamage
#define DAMAGE_NO 0 // can't be damaged
#define DAMAGE_YES 1 // attempt to damage
#define DAMAGE_AIM 2 // special case for aiming damage
// pev->deadflag
#define DEAD_NO 0 // alive
#define DEAD_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground
#define DEAD_DEAD 2 // dead. lying still.
#define DEAD_RESPAWNABLE 3 // wait for respawn
#define DEAD_DISCARDBODY 4
#define PM_MAXHULLS 4 // 4 hulls - quake1, half-life
// filter console messages
typedef enum
{
at_console = 1, // format: [msg]
at_warning, // format: Warning: [msg]
at_error, // format: Error: [msg]
at_loading, // print messages during loading
at_aiconsole, // same as at_console, but only shown if developer level is 5!
at_logged // server print to console ( only in multiplayer games ). (NOT IMPLEMENTED)
} ALERT_TYPE;
// filter client messages
typedef enum
{
print_console, // dev. console messages
print_center, // at center of the screen
print_chat, // level high
} PRINT_TYPE;
// model manager types
typedef enum
{
mod_bad,
mod_world,
mod_brush,
mod_studio,
mod_sprite
} modtype_t;
// monster's walkmove modes
typedef enum
{
WALKMOVE_NORMAL = 0,// normal walkmove
WALKMOVE_WORLDONLY, // doesn't hit ANY entities, no matter what the solid type
WALKMOVE_CHECKONLY // move, but don't touch triggers
} walkmove_t;
// monster's move to origin stuff
#define MOVE_START_TURN_DIST 64 // when this far away from moveGoal, start turning to face next goal
#define MOVE_STUCK_DIST 32 // if a monster can't step this far, it is stuck.
#define MOVE_NORMAL 0 // normal move in the direction monster is facing
#define MOVE_STRAFE 1 // moves in direction specified, no matter which way monster is facing
// edict movetype
typedef enum
{
MOVETYPE_NONE = 0, // never moves
MOVETYPE_CONVEYOR, // Xash3D: simulate conveyor belt, push all stuff
MOVETYPE_COMPOUND, // Xash3D: compound two entities
MOVETYPE_WALK, // Player only - moving on the ground
MOVETYPE_STEP, // gravity, special edge handling
MOVETYPE_FLY, // No gravity, but still collides with stuff
MOVETYPE_TOSS, // gravity/collisions
MOVETYPE_PUSH, // no clip to world, push on box contact
MOVETYPE_NOCLIP, // origin and angles change with no interaction
MOVETYPE_FLYMISSILE,// extra size to monsters
MOVETYPE_BOUNCE, // Just like Toss, but reflect velocity when contacting surfaces
MOVETYPE_BOUNCEMISSILE,// bounce w/o gravity
MOVETYPE_FOLLOW, // studio attached models
MOVETYPE_PUSHSTEP, // BSP model that needs physics/world collisions
MOVETYPE_PHYSIC, // phys simulation
} movetype_t;
// edict collision filter
typedef enum
{
SOLID_NOT = 0, // no interaction with other objects
SOLID_TRIGGER, // only touch when inside, after moving
SOLID_BBOX, // touch on edge
SOLID_SLIDEBOX, // touch on edge, but not an onground
SOLID_BSP, // bsp clip, touch on edge
SOLID_MESH, // custom convex mesh
} solid_t;
// pev->buttons (client only)
// buttons
#define IN_ATTACK (1<<0)
#define IN_JUMP (1<<1)
#define IN_DUCK (1<<2)
@ -267,19 +650,45 @@ typedef enum
#define IN_ALT1 (1<<14)
#define IN_SCORE (1<<15) // Used by client.dll for when scoreboard is held down
// rendering constants
// Break Model Defines
#define BREAK_TYPEMASK 0x4F
#define BREAK_GLASS 0x01
#define BREAK_METAL 0x02
#define BREAK_FLESH 0x04
#define BREAK_WOOD 0x08
#define BREAK_SMOKE 0x10
#define BREAK_TRANS 0x20
#define BREAK_CONCRETE 0x40
#define BREAK_2 0x80
// Colliding temp entity sounds
#define BOUNCE_GLASS BREAK_GLASS
#define BOUNCE_METAL BREAK_METAL
#define BOUNCE_FLESH BREAK_FLESH
#define BOUNCE_WOOD BREAK_WOOD
#define BOUNCE_SHRAP 0x10
#define BOUNCE_SHELL 0x20
#define BOUNCE_CONCRETE BREAK_CONCRETE
#define BOUNCE_SHOTSHELL 0x80
// Temp entity bounce sound types
#define TE_BOUNCE_NULL 0
#define TE_BOUNCE_SHELL 1
#define TE_BOUNCE_SHOTSHELL 2
// Rendering constants
typedef enum
{
kRenderNormal, // src
kRenderTransColor, // c*a+dest*(1-a)
kRenderTransTexture, // src*a+dest*(1-a)
kRenderGlow, // src*a+dest -- no Z buffer checks
kRenderGlow, // src*a+dest -- No Z buffer checks
kRenderTransAlpha, // src*srca+dest*(1-srca)
kRenderTransAdd, // src*a+dest
kRenderTransInverse // src*(1-a)+dest*a
} kRenderMode_t;
typedef enum
enum
{
kRenderFxNone = 0,
kRenderFxPulseSlow,
@ -302,80 +711,33 @@ typedef enum
kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!)
kRenderFxReflection, // G-Cont - oldstyle mirror transform
kRenderFxAurora, // set particle trail for this entity
kRenderFxNoReflect, // don't reflecting in mirrors
} kRenderFx_t;
};
// link_t is only used for entity area links now
typedef struct link_s
// shared typedefs
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
typedef unsigned int uint;
typedef float vec_t;
typedef int string_t;
typedef struct cvar_s cvar_t;
typedef struct edict_s edict_t;
typedef struct
{
struct link_s *prev;
struct link_s *next;
int entnum; // svs.edicts \ cls.entities actual number
} link_t;
// breakmodel defines
#define BREAK_TYPEMASK 0x4F
#define BREAK_GLASS 0x01
#define BREAK_METAL 0x02
#define BREAK_FLESH 0x04
#define BREAK_WOOD 0x08
#define BREAK_SMOKE 0x10
#define BREAK_TRANS 0x20
#define BREAK_CONCRETE 0x40
#define BREAK_2 0x80
// colliding temp entity sounds
#define BOUNCE_GLASS BREAK_GLASS
#define BOUNCE_METAL BREAK_METAL
#define BOUNCE_FLESH BREAK_FLESH
#define BOUNCE_WOOD BREAK_WOOD
#define BOUNCE_SHRAP 0x10
#define BOUNCE_SHELL 0x20
#define BOUNCE_CONCRETE BREAK_CONCRETE
#define BOUNCE_SHOTSHELL 0x80
// Temp entity bounce sound types
#define TE_BOUNCE_NULL 0
#define TE_BOUNCE_SHELL 1
#define TE_BOUNCE_SHOTSHELL 2
// studio models event range
#define EVENT_SPECIFIC 0
#define EVENT_SCRIPTED 1000
#define EVENT_SHARED 2000 // both client and server valid for playing
#define EVENT_CLIENT 5000 // less than this value it's a server-side studio events
// game print flags
#define PRINT_LOW 0 // pickup messages
#define PRINT_MEDIUM 1 // death messages
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
// client screen state
#define CL_LOADING 1 // draw loading progress-bar
#define CL_ACTIVE 2 // draw normal hud
#define CL_PAUSED 3 // pause when active
#define CL_CHANGELEVEL 4 // draw 'loading' during changelevel
// renderer flags
#define RDF_NOWORLDMODEL (1<<0) // used for player configuration screen
#define RDF_PORTALINVIEW (1<<1) // cull entities using vis too because pvs\areabits are merged serverside
#define RDF_SKYPORTALINVIEW (1<<2) // draw skyportal instead of regular sky
#define RDF_NOFOVADJUSTMENT (1<<3) // do not adjust fov for widescreen
#define RDF_THIRDPERSON (1<<4) // enable chase cam instead firstperson
// decal flags
#define FDECAL_PERMANENT 0x01 // This decal should not be removed in favor of any new decals
#define FDECAL_CUSTOM 0x02 // This is a custom clan logo and should not be saved/restored
#define FDECAL_DYNAMIC 0x04 // Indicates the decal is dynamic
#define FDECAL_DONTSAVE 0x08 // Decal was loaded from adjacent level, don't save it for this level
#define FDECAL_CLIPTEST 0x10 // Decal needs to be clip-tested
#define FDECAL_NOCLIP 0x20 // Decal is not clipped by containing polygon
#define FDECAL_USESAXIS 0x40 // Uses the s axis field to determine orientation (footprints)
#define FDECAL_ANIMATED 0x80 // this is decal has multiple frames
byte r, g, b;
} color24;
// model types
typedef enum
{
mod_bad,
mod_world,
mod_brush,
mod_studio,
mod_sprite
} modtype_t;
#endif//CONST_H

26
common/customentity.h Normal file
View File

@ -0,0 +1,26 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// customentity.h - beam encode specific
//=======================================================================
#ifndef CUSTOMENTITY_H
#define CUSTOMENTITY_H
// beam types, encoded as a byte
enum
{
BEAM_POINTS = 0,
BEAM_ENTPOINT,
BEAM_ENTS,
BEAM_HOSE,
};
#define BEAM_FSINE 0x10
#define BEAM_FSOLID 0x20
#define BEAM_FSHADEIN 0x40
#define BEAM_FSHADEOUT 0x80
// Start/End Entity is encoded as 12 bits of entity index, and 4 bits of attachment (4:12)
#define BEAMENT_ENTITY( x ) ((x) & 0xFFF)
#define BEAMENT_ATTACHMENT( x ) (((x)>>12) & 0xF)
#endif//CUSTOMENTITY_H

View File

@ -6,11 +6,15 @@
#define CVARDEF_H
// cvar flags
#define FCVAR_ARCHIVE BIT(0) // set to cause it to be saved to config.cfg
#define FCVAR_USERINFO BIT(1) // added to userinfo when changed
#define FCVAR_SERVERINFO BIT(2) // added to serverinfo when changed
#define FCVAR_LATCH BIT(3) // create latched cvar
#define FCVAR_PHYSICINFO BIT(4) // added to physicinfo (movevars) when changed
#define FCVAR_ARCHIVE (1<<0) // set to cause it to be saved to config.cfg
#define FCVAR_USERINFO (1<<1) // changes the client's info string
#define FCVAR_SERVER (1<<2) // changes the serevrinfo string, notifies players when changed
#define FCVAR_EXTDLL (1<<3) // defined by external DLL
#define FCVAR_CLIENTDLL (1<<4) // defined by the client dll
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc.
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( player name )
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console
/*
========================================================================
@ -22,6 +26,7 @@ struct cvar_s
{
char *name;
char *string; // normal string
uint flags; // state flags
float value; // com.atof( string )
int integer; // com.atoi( string )
bool modified; // set each time the cvar is changed

23
common/edict.h Normal file
View File

@ -0,0 +1,23 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// edict.h - server edicts
//=======================================================================
#ifndef EDICT_H
#define EDICT_H
#include "progdefs.h"
struct edict_s
{
int free; // unused entity when true
float freetime; // sv.time when the object was freed
int serialnumber; // must match with entity num
struct sv_priv_s *pvEngineData; // alloced, freed and used by engine only
void *pvPrivateData; // alloced and freed by engine, used by DLLs
entvars_t v; // C exported fields from progs
// other fields from progs come immediately after
};
#endif//EDICT_H

View File

@ -29,7 +29,7 @@ typedef struct efxapi_s
void (*R_LightForPoint)( const float *rgflOrigin, float *lightValue );
int (*CL_IsBoxVisible)( const float *mins, const float *maxs );
int (*R_CullBox)( const float *mins, const float *maxs );
int (*R_AddEntity)( struct cl_entity_s *pEnt, int ed_type, HSPRITE customShader );
int (*R_AddEntity)( struct cl_entity_s *pEnt, int entityType, HSPRITE customShader );
void (*R_EnvShot)( const float *vieworg, const char *name, int skyshot );
} efxapi_t;

View File

@ -1,59 +1,64 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// svgame_api.h - entity interface between engine and svgame
// eiface.h - interface between engine and dlls
//=======================================================================
#ifndef SVGAME_API_H
#define SVGAME_API_H
#ifndef EIFACE_H
#define EIFACE_H
#include "trace_def.h"
#include "pm_shared.h"
#include "cvardef.h"
#define SV_INTERFACE_VERSION 140
#define INTERFACE_VERSION 140 // GetEntityAPI, GetEntityAPI2
#define NEW_DLL_FUNCTIONS_VERSION 2 // GetNewDLLFunctions (Xash3D uses version 2)
typedef struct globalvars_s
{
float time;
float frametime;
int force_retouch;
typedef unsigned long CRC32_t;
string_t mapname;
string_t startspot;
// filter console messages
typedef enum
{
at_notice,
at_console, // format: [msg]
at_warning, // format: Warning: [msg]
at_error, // format: Error: [msg]
at_aiconsole, // same as at_console, but only shown if developer level is 5!
at_logged // server print to console ( only in multiplayer games ). (NOT IMPLEMENTED)
} ALERT_TYPE;
BOOL deathmatch;
BOOL coop;
BOOL teamplay;
// filter client messages
typedef enum
{
print_console, // dev. console messages
print_center, // at center of the screen
print_chat, // level high
} PRINT_TYPE;
int serverflags;
int found_secrets;
// for integrity checking of content on clients
typedef enum
{
force_exactfile, // file on client must exactly match server's file
force_model_samebounds, // for model files only, the geometry must fit in the same bbox
force_model_specifybounds, // for model files only, the geometry must fit in the specified bbox
} FORCE_TYPE;
// MakeVectors info
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
typedef enum
{
AREA_SOLID, // find any solid edicts
AREA_TRIGGERS, // find all SOLID_TRIGGER edicts
AREA_CUSTOM, // find all edicts with custom contents - water, lava, fog, laders etc
} AREA_TYPE;
// global TraceResult
BOOL trace_allsolid;
BOOL trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
edict_t *trace_ent;
BOOL trace_inopen;
BOOL trace_inwater;
int trace_hitgroup;
int trace_flags;
int changelevel; // transition in progress when true (was msg_entity)
int numEntities; // actual ents count (was cdAudioTrack)
int maxClients;
int maxEntities;
const char *pStringBase; // actual only when sys_sharedstrings is 1
void *pSaveData; // (SAVERESTOREDATA *) pointer
vec3_t vecLandmarkOffset;
} globalvars_t;
typedef struct
{
int fAllSolid; // if true, plane is not valid
int fStartSolid; // if true, the initial point was in a solid area
int fInOpen; // if true trace is open
int fInWater; // if true trace is in water
float flFraction; // time completed, 1.0 = didn't hit anything
vec3_t vecEndPos; // final position
float flPlaneDist; // planes distance
vec3_t vecPlaneNormal; // surface normal at impact
edict_t *pHit; // entity the surface is on
int iHitgroup; // 0 == generic, non zero is specific body part
} TraceResult;
// engine hands this to DLLs for functionality callbacks
typedef struct enginefuncs_s
@ -65,8 +70,8 @@ typedef struct enginefuncs_s
int (*pfnModelFrames)( int modelIndex );
void (*pfnSetSize)( edict_t *e, const float *rgflMin, const float *rgflMax );
void (*pfnChangeLevel)( const char* s1, const char* s2 );
edict_t* (*pfnFindClientInPHS)( edict_t *pEdict ); // was pfnGetSpawnParms
edict_t* (*pfnEntitiesInPHS)( edict_t *pplayer ); // was pfnSaveSpawnParms
edict_t* (*pfnFindClientInPHS)( edict_t *pEdict );
edict_t* (*pfnEntitiesInPHS)( edict_t *pplayer );
float (*pfnVecToYaw)( const float *rgflVector );
void (*pfnVecToAngles)( const float *rgflVectorIn, float *rgflVectorOut );
void (*pfnMoveToOrigin)( edict_t *ent, const float *pflGoal, float dist, int iMoveType );
@ -83,7 +88,7 @@ typedef struct enginefuncs_s
void (*pfnRemoveEntity)( edict_t* e );
edict_t* (*pfnCreateNamedEntity)( string_t className );
void (*pfnMakeStatic)( edict_t *ent );
void (*pfnLinkEdict)( edict_t *e, int touch_triggers ); // was pfnEntIsOnFloor
void (*pfnLinkEdict)( edict_t *e, int touch_triggers ); // a part of CustomPhysics implementation
int (*pfnDropToFloor)( edict_t* e );
int (*pfnWalkMove)( edict_t *ent, float yaw, float dist, int iMode );
void (*pfnSetOrigin)( edict_t *e, const float *rgflOrigin );
@ -93,9 +98,9 @@ typedef struct enginefuncs_s
void (*pfnTraceToss)( edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr );
int (*pfnTraceMonsterHull)( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnTraceHull)( const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnTraceModel)( const float *v1, const float *v2, edict_t *pent, TraceResult *ptr );
void (*pfnTraceModel)( const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr );
const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 );
int (*pfnTestEntityPosition)( edict_t *pTestEdict ); // was pfnTraceSphere
int (*pfnAreaEdicts)( const float *mins, const float *maxs, edict_t **list, int maxcount, AREA_TYPE areatype ); // a part of CustomPhysics implementation
void (*pfnGetAimVector)( edict_t* ent, float speed, float *rgflReturn );
void (*pfnServerCommand)( const char* str );
void (*pfnServerExecute)( void );
@ -120,7 +125,7 @@ typedef struct enginefuncs_s
void (*pfnCVarSetFloat)( const char *szVarName, float flValue );
void (*pfnCVarSetString)( const char *szVarName, const char *szValue );
void (*pfnAlertMessage)( ALERT_TYPE level, char *szFmt, ... );
void* (*pfnGetProcAddress)( void *hInstance, const char *name ); // was pfnEngineFprintf
void (*pfnDropClient)( int clientIndex );
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb );
void* (*pfnPvEntPrivateData)( edict_t *pEdict );
void (*pfnFreeEntPrivateData)( edict_t *pEdict );
@ -144,26 +149,26 @@ typedef struct enginefuncs_s
const char *(*pfnCmd_Argv)( int argc );
int (*pfnCmd_Argc)( void );
void (*pfnGetAttachment)( const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles );
void (*pfnCRC_Init)( CRC32_t *pulCRC );
void (*pfnCRC_ProcessBuffer)( CRC32_t *pulCRC, void *p, int len );
void (*pfnCRC_ProcessByte)( CRC32_t *pulCRC, byte ch );
CRC32_t (*pfnCRC_Final)( CRC32_t pulCRC );
void (*pfnCRC32_Init)( CRC32_t *pulCRC );
void (*pfnCRC32_ProcessBuffer)( CRC32_t *pulCRC, void *p, int len );
void (*pfnCRC32_ProcessByte)( CRC32_t *pulCRC, byte ch );
CRC32_t (*pfnCRC32_Final)( CRC32_t pulCRC );
long (*pfnRandomLong)( long lLow, long lHigh );
float (*pfnRandomFloat)( float flLow, float flHigh );
void (*pfnSetView)( const edict_t *pClient, const edict_t *pViewent );
float (*pfnTime)( void ); // host.realtime, not sv.time
void (*pfnCrosshairAngle)( const edict_t *pClient, float pitch, float yaw );
byte* (*pfnLoadFile)( const char *filename, int *pLength );
byte* (*pfnLoadFileForMe)( const char *filename, int *pLength );
void (*pfnFreeFile)( void *buffer );
void (*pfnEndSection)( const char *pszSectionName );
int (*pfnCompareFileTime)( const char *filename1, const char *filename2, int *iCompare );
void (*pfnGetGameDir)( char *szGetGameDir );
void (*pfnClassifyEdict)( edict_t *pEdict, int ed_type ); // was pfnCvar_RegisterVariable
void (*pfnHostError)( const char *szFmt, ... );
void (*pfnFadeClientVolume)( const edict_t *pEdict, float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds );
void (*pfnSetClientMaxspeed)( const edict_t *pEdict, float fNewMaxspeed );
edict_t *(*pfnCreateFakeClient)( const char *netname ); // returns NULL if fake client can't be created
void (*pfnRunPlayerMove)( edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, word buttons, byte impulse, byte msec );
int (*pfnFileExists)( const char *filename ); // was pfnNumberOfEntities - see gpGlobals->numEntities
int (*pfnNumberOfEntities)( void );
char* (*pfnGetInfoKeyBuffer)( edict_t *e ); // passing in NULL gets the serverinfo
char* (*pfnInfoKeyValue)( char *infobuffer, char *key );
void (*pfnSetKeyValue)( char *infobuffer, char *key, char *value );
@ -172,18 +177,18 @@ typedef struct enginefuncs_s
void (*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex );
int (*pfnPrecacheGeneric)( const char* s );
int (*pfnGetPlayerUserId)(edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc.
void (*pfnPlayMusic)( const char *trackname, int flags ); // was pfnBuildSoundMsg
void (*pfnSoundTrack)( const char *trackname, int flags ); // playing looped soundtrack
int (*pfnIsDedicatedServer)( void ); // is this a dedicated server?
void* (*pfnMemAlloc)(size_t cb, const char *file, const int line);// was pfnCVarGetPointer
void (*pfnMemFree)(void *mem, const char *file, const int line); // was pfnGetPlayerWONId
cvar_t *(*pfnCVarGetPointer)( const char *szVarName );
uint (*pfnGetPlayerWONId)( edict_t *e ); // returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
void (*pfnInfo_RemoveKey)( char *s, char *key );
const char *(*pfnGetPhysicsKeyValue)( const edict_t *pClient, const char *key );
void (*pfnSetPhysicsKeyValue)( const edict_t *pClient, const char *key, const char *value );
const char *(*pfnGetPhysicsInfoString)( const edict_t *pClient );
word (*pfnPrecacheEvent)( int type, const char *psz );
void (*pfnPlaybackEvent)( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
byte *(*pfnSetFatPVS)( const float *org, int portal );
byte *(*pfnSetFatPAS)( const float *org, int portal );
byte *(*pfnSetFatPVS)( const float *org );
byte *(*pfnSetFatPAS)( const float *org );
int (*pfnCheckVisibility)( const edict_t *entity, byte *pset );
void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname );
void (*pfnDeltaUnsetField)( struct delta_s *pFields, const char *fieldname );
@ -194,15 +199,13 @@ typedef struct enginefuncs_s
void (*pfnDeltaSetFieldByIndex)( struct delta_s *pFields, int fieldNumber );
void (*pfnDeltaUnsetFieldByIndex)( struct delta_s *pFields, int fieldNumber );
void (*pfnSetGroupMask)( int mask, int op );
void (*pfnDropClient)( int clientIndex ); // was pfnCreateInstancedBaseline
void (*pfnHostError)( const char *szFmt, ... ); // was pfnCvar_DirectSet
char *(*pfnParseToken)( const char **data_p ); // was pfnForceUnmodified
int (*pfnCreateInstancedBaseline)( int classname, struct entity_state_s *baseline );
void (*pfnCvar_DirectSet)( cvar_t *var, char *value );
void (*pfnForceUnmodified)( FORCE_TYPE type, float *mins, float *maxs, const char *filename );
void (*pfnGetPlayerStats)( const edict_t *pClient, int *ping, int *packet_loss );
void (*pfnAddServerCommand)( const char *cmd_name, void (*function)(void), const char *cmd_desc );
void* (*pfnLoadLibrary)( const char *name ); // was pfnVoice_GetClientListening
void (*pfnFreeLibrary)( void *hInstance ); // was pfnVoice_SetClientListening
const char *(*pfnGetPlayerAuthId)( edict_t *e );
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 140
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138
} enginefuncs_t;
// passed to pfnKeyValue
@ -224,8 +227,8 @@ typedef struct
typedef struct
{
int id; // ENG ordinal ID of this entity (used for entity <--> pointer conversions)
edict_t *pent; // ENG pointer to the in-game entity
int id; // ordinal ID of this entity (used for entity <--> pointer conversions)
edict_t *pent; // pointer to the in-game entity
int location; // offset from the base data of this entity
int size; // byte size of this entity's data
@ -243,24 +246,24 @@ typedef struct
typedef struct saverestore_s
{
char *pBaseData; // ENG start of all entity save data
char *pBaseData; // start of all entity save data
char *pCurrentData; // current buffer pointer for sequential access
int size; // current data size
int bufferSize; // ENG total space for data (Valve used 512 kb's)
int bufferSize; // total space for data (Valve used 512 kb's)
int tokenSize; // always equal 0 (probably not used)
int tokenCount; // ENG number of elements in the pTokens table (Valve used 4096 tokens)
char **pTokens; // ENG hash table of entity strings (sparse)
int currentIndex; // ENG holds a global entity table ID
int tableCount; // ENG number of elements in the entity table (numEntities)
int tokenCount; // number of elements in the pTokens table (Valve used 4096 tokens)
char **pTokens; // hash table of entity strings (sparse)
int currentIndex; // holds a global entity table ID
int tableCount; // number of elements in the entity table (numEntities)
int connectionCount; // number of elements in the levelList[]
ENTITYTABLE *pTable; // ENG array of ENTITYTABLE elements (1 for each entity)
ENTITYTABLE *pTable; // array of ENTITYTABLE elements (1 for each entity)
LEVELLIST levelList[MAX_LEVEL_CONNECTIONS]; // list of connections from this level
// smooth transition
int fUseLandmark; // ENG
int fUseLandmark;
char szLandmarkName[20]; // landmark we'll spawn near in next level
vec3_t vecLandmarkOffset; // for landmark transitions
float time; // ENG current sv.time
float time; // current sv.time
char szCurrentMapName[32];// To check global entities
} SAVERESTOREDATA;
@ -284,10 +287,7 @@ typedef enum _fieldtypes
FIELD_TIME, // a floating point time (these are fixed up automatically too!)
FIELD_MODELNAME, // engine string that is a model name (needs precache)
FIELD_SOUNDNAME, // engine string that is a sound name (needs precache)
FIELD_RANGE, // Min and Max range for generate random value
FIELD_INTEGER64, // long integer
FIELD_DOUBLE, // float with double precision
FIELD_TYPECOUNT, // MUST BE LAST
} FIELDTYPE;
@ -343,40 +343,53 @@ typedef struct
void (*pfnPlayerPostThink)( edict_t *pEntity );
void (*pfnStartFrame)( void );
int (*pfnCreate)( edict_t *pent, const char *szName ); // was pfnParmsNewLevel
void (*pfnParmsNewLevel)( void );
void (*pfnParmsChangeLevel)( void );
// returns string describing current .dll. E.g., TeamFotrress 2, Half-Life
const char *(*pfnGetGameDescription)( void );
int (*pfnPhysicsEntity)( edict_t *pEntity ); // was pfnPlayerCustomization
// Notify dll about a player customization. (completely ignored in Xash3D)
void (*pfnPlayerCustomization)( edict_t *pEntity, void *pUnused );
// Spectator funcs
void (*pfnSpectatorConnect)( edict_t *pEntity );
void (*pfnSpectatorDisconnect)( edict_t *pEntity );
void (*pfnSpectatorThink)( edict_t *pEntity );
int (*pfnClassifyEdict)( edict_t *pentToClassify ); // was pfnSys_Error
// Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint.
void (*pfnSys_Error)( const char *error_string );
void (*pfnPM_Move)( struct playermove_s *ppmove, int server );
void (*pfnPM_Init)( struct playermove_s *ppmove );
char (*pfnPM_FindTextureType)( const char *name );
void (*pfnSetupVisibility)( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int portal );
char (*pfnPM_FindTextureType)( char *name );
void (*pfnSetupVisibility)( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas );
void (*pfnUpdateClientData)( const edict_t *ent, int sendweapons, struct clientdata_s *cd );
int (*pfnAddToFullPack)( struct entity_state_s *state, edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet );
void (*pfnCreateBaseline)( struct entity_state_s *baseline, edict_t *entity, int playermodelindex );
int (*pfnAddToFullPack)( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, byte *pSet );
void (*pfnCreateBaseline)( int player, int eindex, struct entity_state_s *baseline, edict_t *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs );
void (*pfnRegisterEncoders)( void );
int (*pfnGetWeaponData)( edict_t *player, struct weapon_data_s *info );
void (*pfnCmdStart)( const edict_t *player, const usercmd_t *cmd, unsigned int random_seed );
void (*pfnCmdStart)( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed );
void (*pfnCmdEnd)( const edict_t *player );
// these funcs come from GetEntityAPI2 and replace some funcs from GetEntityAPI
void (*pfnOnFreeEntPrivateData)( edict_t *pEnt ); // was pfnConnectionlessPacket
int (*pfnConnectionlessPacket)( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
int (*pfnShouldCollide)( edict_t *pTouch, edict_t *pOther ); // was pfnCreateInstancedBaselines
void (*pfnCreateInstancedBaselines)( void );
int (*pfnInconsistentFile)( const edict_t *player, const char *filename, char *disconnect_message );
int (*pfnAllowLagCompensation)( void );
} DLL_FUNCTIONS;
typedef void (*GIVEFNPTRSTODLL)( enginefuncs_t* engfuncs, globalvars_t *pGlobals );
typedef int (*APIFUNCTION)( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
typedef void (*LINK_ENTITY_FUNC)( entvars_t *pev );
typedef struct
{
void (*pfnOnFreeEntPrivateData)( edict_t *pEnt ); // ñalled right before the object's memory is freed.
void (*pfnGameShutdown)( void );
int (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther );
int (*pfnCreate)( edict_t *pent, const char *szName ); // passed through pfnCreate (0 is attempt to create, -1 is reject)
int (*pfnPhysicsEntity)( edict_t *pEntity ); // run custom physics for each entity (return 0 to use engine physic)
} NEW_DLL_FUNCTIONS;
#endif//SVGAME_API_H
typedef int (*APIFUNCTION)( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
typedef int (*APIFUNCTION2)( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );
#endif//EIFACE_H

View File

@ -5,41 +5,15 @@
#ifndef ENTITY_STATE_H
#define ENTITY_STATE_H
// engine edict types that shared across network
typedef enum
{
ED_SPAWNED = 0, // this entity requris to set own type with SV_ClassifyEdict
ED_WORLDSPAWN, // this is a worldspawn
ED_STATIC, // this is a logic without model or entity with static model
ED_AMBIENT, // this is entity emitted ambient sounds only
ED_NORMAL, // normal entity with model (and\or) sound
ED_BSPBRUSH, // brush entity (a part of level)
ED_CLIENT, // this is a client entity
ED_MONSTER, // monster or bot (generic npc with AI)
ED_TEMPENTITY, // this edict will be removed on server when "lifetime" exceeds
ED_BEAM, // laser beam (needs to recalculate pvs and frustum)
ED_MOVER, // func_train, func_door and another bsp or mdl movers
ED_VIEWMODEL, // client or bot viewmodel (for spectating)
ED_RIGIDBODY, // simulated physic
ED_TRIGGER, // just for sorting on a server
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;
// entity_state_t->ed_flags
#define ESF_LINKEDICT BIT( 0 ) // needs to relink edict on client
#define ESF_NODELTA BIT( 1 ) // force no delta frame
#define ESF_NO_PREDICTION BIT( 2 ) // e.g. teleport time
typedef struct entity_state_s
{
// engine specific
// Fields which are filled in by routines outside of delta compression
int entityType; // hint for engine
int number; // edict index
edtype_t ed_type; // edict type
string_t classname; // edict classname
int ed_flags; // engine clearing this at end of server frame
float msg_time;
// Message number last time the player/entity state was updated.
int messagenum;
// Fields which can be transitted and reconstructed over the network stream
vec3_t origin;
@ -113,10 +87,15 @@ typedef struct entity_state_s
vec3_t vuser3;
vec3_t vuser4;
// FIXME: old xash variables needs to be removed
int flags;
// xash shared strings
char classname[32];
char targetname[32];
char target[32];
char netname[32];
} entity_state_t;
#include "pm_info.h"
typedef struct clientdata_s
{
vec3_t origin;
@ -153,7 +132,7 @@ typedef struct clientdata_s
int tfstate;
int pushmsec;
int deadflag;
char physinfo[512]; // MAX_PHYSINFO_STRING
char physinfo[MAX_PHYSINFO_STRING];
// for mods
int iuser1;
@ -171,4 +150,13 @@ typedef struct clientdata_s
} clientdata_t;
#include "weaponinfo.h"
typedef struct local_state_s
{
entity_state_t playerstate;
clientdata_t client;
weapon_data_t weapondata[32]; // WEAPON_BACKUP
} local_state_t;
#endif//ENTITY_STATE_H

17
common/entity_types.h Normal file
View File

@ -0,0 +1,17 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// entity_types.h - shared entity types
//=======================================================================
#ifndef ENTITY_TYPES_H
#define ENTITY_TYPES_H
#define ET_NORMAL 0
#define ET_PLAYER 1
#define ET_TEMPENTITY 2
#define ET_BEAM 3
#define ET_FRAGMENTED 4 // BMODEL or SPRITE that was split across BSP nodes
#define ET_VIEWENTITY 5 // special case for firstperson viewmodel
#define ET_PORTAL 6 // this is portal surface
#define ET_SKYPORTAL 7 // env_sky use this
#endif//ENTITY_TYPES_H

View File

@ -1,30 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// game_shared.h - user constants
//=======================================================================
#ifndef GAME_SHARED_H
#define GAME_SHARED_H
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define MAX_WEAPONS 32
#define WEAPON_ALLWEAPONS (~(1<<WEAPON_SUIT))
#define MAX_AMMO_SLOTS 32
#define ITEM_SUIT BIT( 31 )
#define WEAPON_SUIT 31
#define HIDEHUD_WEAPONS BIT( 0 )
#define HIDEHUD_FLASHLIGHT BIT( 1 )
#define HIDEHUD_ALL BIT( 2 )
#define HIDEHUD_HEALTH BIT( 3 )
// camera flags
#define CAMERA_ON 1
#define DRAW_HUD 2
#define INVERSE_X 4
#define MONSTER_VIEW 8
#endif//GAME_SHARED_H

View File

@ -62,7 +62,8 @@ typedef struct ui_enginefuncs_s
const char *(*pfnCmd_Args)( void );
// debug messages (im-menu shows only notify)
void (*pfnAlertMessage)( ALERT_TYPE, char *szFmt, ... );
void (*Con_Printf)( char *fmt, ... );
void (*Con_DPrintf)( char *fmt, ... );
// sound handlers
void (*pfnPlayLocalSound)( const char *szSound );
@ -79,7 +80,7 @@ typedef struct ui_enginefuncs_s
void (*pfnSetModel)( struct cl_entity_s *ed, const char *path );
void (*pfnClearScene)( void );
void (*pfnRenderScene)( const struct ref_params_s *fd );
int (*R_AddEntity)( struct cl_entity_s *pEnt, int ed_type, HIMAGE customShader );
int (*R_AddEntity)( struct cl_entity_s *pEnt, int entityType, HIMAGE customShader );
// dlls managemenet
void* (*pfnLoadLibrary)( const char *name );
@ -96,7 +97,7 @@ typedef struct ui_enginefuncs_s
// gameinfo handlers
int (*pfnCreateMapsList)( int fRefresh );
int (*pfnClientInGame)( void );
void (*pfnClientJoin)( const netadr_t adr );
void (*pfnClientJoin)( const struct netadr_s adr );
// parse txt files
byte* (*pfnLoadFile)( const char *filename, int *pLength );
@ -145,7 +146,7 @@ typedef struct
void (*pfnKeyEvent)( int key, int down );
void (*pfnMouseMove)( int x, int y );
void (*pfnSetActiveMenu)( int active );
void (*pfnAddServerToList)( netadr_t adr, const char *info );
void (*pfnAddServerToList)( struct netadr_s adr, const char *info );
void (*pfnGetCursorPos)( int *pos_x, int *pos_y );
void (*pfnSetCursorPos)( int pos_x, int pos_y );
void (*pfnShowCursor)( int show );

48
common/hltv.h Normal file
View File

@ -0,0 +1,48 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// hltv.h - all shared consts between server, clients and proxy
//=======================================================================
#ifndef HLTV_H
#define HLTV_H
#define TYPE_CLIENT 0 // client is a normal HL client (default)
#define TYPE_PROXY 1 // client is another proxy
#define TYPE_COMMENTATOR 3 // client is a commentator
#define TYPE_DEMO 4 // client is a demo file
// sub commands of svc_hltv:
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands
#define HLTV_STATUS 1 // send status infos about proxy
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream
// sub commands of svc_director:
#define DRC_CMD_NONE 0 // NULL director command
#define DRC_CMD_START 1 // start director mode
#define DRC_CMD_EVENT 2 // informs about director command
#define DRC_CMD_MODE 3 // switches camera modes
#define DRC_CMD_CAMERA 4 // sets camera registers
#define DRC_CMD_TIMESCALE 5 // sets time scale
#define DRC_CMD_MESSAGE 6 // send HUD centerprint
#define DRC_CMD_SOUND 7 // plays a particular sound
#define DRC_CMD_STATUS 8 // status info about broadcast
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
#define DRC_CMD_FADE 10 // send screen fade command
#define DRC_CMD_SHAKE 11 // send screen shake command
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
#define DRC_CMD_LAST 12
// HLTV_EVENT event flags
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
#define DRC_FLAG_SIDE (1<<4) //
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo
#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc)
#define DRC_FLAG_INTRO (1<<8) // is a introduction scene
#define DRC_FLAG_FINAL (1<<9) // is a final scene
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
#define MAX_DIRECTOR_CMD_PARAMETERS 4
#define MAX_DIRECTOR_CMD_STRING 128
#endif//HLTV_H

22
common/netadr.h Normal file
View File

@ -0,0 +1,22 @@
//=======================================================================
// Copyright XashXT Group 2010 Š
// netadr.h - net address local struct
//=======================================================================
#ifndef NETADR_H
#define NETADR_H
typedef enum
{
NA_LOOPBACK,
NA_BROADCAST,
NA_IP
} netadrtype_t;
typedef struct netadr_s
{
netadrtype_t type;
unsigned char ip[4];
unsigned short port;
} netadr_t;
#endif//NETADR_H

View File

@ -1,9 +1,44 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// entity_def.h - generic engine edict
// Copyright XashXT Group 2010 ©
// progdefs.h - global and entity variables
//=======================================================================
#ifndef ENTITY_DEF_H
#define ENTITY_DEF_H
#ifndef PROGDEFS_H
#define PROGDEFS_H
typedef struct globalvars_s
{
float time;
float frametime;
int force_retouch;
string_t mapname;
string_t startspot;
float deathmatch;
float coop;
float teamplay;
int serverflags;
int found_secrets;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
int trace_allsolid;
int trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
edict_t *trace_ent;
int trace_inopen;
int trace_inwater;
int trace_hitgroup;
int trace_flags;
int changelevel; // transition in progress when true (was msg_entity)
int cdAudioTrack;
int maxClients;
int maxEntities;
const char *pStringBase; // set to NULL during initialize if you want use StringTable system
void *pSaveData; // (SAVERESTOREDATA *) pointer
vec3_t vecLandmarkOffset;
} globalvars_t;
typedef struct entvars_s
{
@ -39,8 +74,8 @@ typedef struct entvars_s
int modelindex;
string_t model; // model name
string_t viewmodel; // player's viewmodel (no network updates)
string_t weaponmodel; // what other players see
int viewmodel; // player's viewmodel
int weaponmodel; // what other players see
vec3_t absmin; // BB max translated to world coord
vec3_t absmax; // BB max translated to world coord
@ -134,9 +169,8 @@ typedef struct entvars_s
float fov; // client fov, used instead m_iFov
int weaponanim; // FIXME: shorten these ?
int pushmsec; // g-cont. localtime when client is standing on PUSH entity
// for right client-side predicting ?
// pm_shared test stuff
int pushmsec; // g-cont. in HL always zeroed
int bInDuck;
int flTimeStepSound; // Next time we can play a step sound
int flSwimTime; // In process of ducking or ducked already?
@ -168,23 +202,6 @@ typedef struct entvars_s
edict_t *euser2;
edict_t *euser3;
edict_t *euser4;
} entvars_t;
struct edict_s
{
BOOL free; // shared parms
float freetime; // sv.time when the object was freed
int serialnumber; // must match with entity num
union
{
sv_priv_t *pvServerData; // alloced, freed and used by engine only
cl_priv_t *pvClientData; // alloced, freed and used by engine only
};
void *pvPrivateData; // alloced and freed by engine, used by DLLs
entvars_t v; // C exported fields from progs (network relative)
};
#endif//ENTITY_DEF_H
#endif//PROGDEFS_H

View File

@ -5,6 +5,13 @@
#ifndef REF_PARAMS_H
#define REF_PARAMS_H
// renderer flags
#define RDF_NOWORLDMODEL (1<<0) // used for player configuration screen
#define RDF_PORTALINVIEW (1<<1) // draw portal pass
#define RDF_SKYPORTALINVIEW (1<<2) // draw skyportal instead of regular sky
#define RDF_NOFOVADJUSTMENT (1<<3) // do not adjust fov for widescreen
#define RDF_THIRDPERSON (1<<4) // enable chase cam instead firstperson
typedef struct skyportal_s
{
float fov;
@ -53,8 +60,8 @@ typedef struct ref_params_s
int movetype; // client movetype (was int hardware;)
int smoothing; // client movement predicting is running
usercmd_t *cmd; // last issued usercmd
movevars_t *movevars; // sv.movevars
struct usercmd_s *cmd; // last issued usercmd
struct movevars_s *movevars; // sv.movevars
int viewport[4]; // x, y, width, height
int nextView; // the renderer calls ClientDLL_CalcRefdef() and Renderview

View File

@ -275,7 +275,6 @@ typedef union
short value;
} mstudioanimvalue_t;
// body part index
typedef struct
{
@ -292,12 +291,7 @@ typedef struct
int flags;
int width;
int height;
union
{
int index; // disk: offset at start of buffer
shader_t shader; // ref: shader number
};
int index;
} mstudiotexture_t;
// skin families

View File

@ -1,35 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// trace_def.h - shared client\server trace struct
//=======================================================================
#ifndef TRACE_DEF_H
#define TRACE_DEF_H
#define FTRACE_SIMPLEBOX (1<<0) // traceline with a simple box
#define FTRACE_IGNORE_GLASS (1<<1) // traceline will be ignored entities with rendermode != kRenderNormal
typedef enum { point_hull = 0, human_hull = 1, large_hull = 2, head_hull = 3 };
typedef enum { ignore_monsters = 1, dont_ignore_monsters = 0, missile = 2 } IGNORE_MONSTERS;
typedef enum { ignore_glass = 1, dont_ignore_glass = 0 } IGNORE_GLASS;
typedef struct
{
int fAllSolid; // if true, plane is not valid
int fStartSolid; // if true, the initial point was in a solid area
int fInOpen; // if true trace is open
int fInWater; // if true trace is in water
float flFraction; // time completed, 1.0 = didn't hit anything
vec3_t vecEndPos; // final position
float flPlaneDist; // planes distance
vec3_t vecPlaneNormal; // surface normal at impact
union
{
struct edict_s *pHit; // entity the surface is on
struct cl_entity_s *pEnt; // client hit entity
};
int iHitgroup; // 0 == generic, non zero is specific body part
} TraceResult;
#endif//TRACE_DEF_H

View File

@ -33,8 +33,8 @@ typedef struct triapi_s
{
int version;
shader_t (*LoadShader)( const char *szShaderName, int fShaderNoMip );
shader_t (*GetSpriteTexture)( int spriteIndex, int spriteFrame );
int (*LoadShader)( const char *szShaderName, int fShaderNoMip );
int (*GetSpriteTexture)( int spriteIndex, int spriteFrame );
void (*RenderMode)( kRenderMode_t mode );
void (*Begin)( TRI_DRAW mode );
void (*End)( void );
@ -48,7 +48,7 @@ typedef struct triapi_s
void (*Color4f)( float r, float g, float b, float a );
void (*Color4ub)( byte r, byte g, byte b, byte a );
void (*TexCoord2f)( float u, float v );
void (*Bind)( shader_t shader, int frame ); // use handle that return pfnLoadShader
void (*Bind)( int shader, int frame ); // use handle that return pfnLoadShader
void (*CullFace)( TRI_CULL mode );
void (*ScreenToWorld)( float *screen, float *world );
int (*WorldToScreen)( float *world, float *screen ); // returns 1 if it's z clipped

View File

@ -8,7 +8,7 @@ set build_type=debug
set BUILD_ERROR=
call vcvars32
%MSDEV% bshift/bshift.dsp %CONFIG%"bshift - Win32 Debug" %build_target%
%MSDEV% dlls/hl.dsp %CONFIG%"hl - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
%MSDEV% client/client.dsp %CONFIG%"client - Win32 Debug" %build_target%

1514
dlls/AI_BaseNPC_Schedule.cpp Normal file

File diff suppressed because it is too large Load Diff

186
dlls/Makefile Normal file
View File

@ -0,0 +1,186 @@
#
# Half-Life Full SDK 2.3 hl_i386.so Makefile for x86 Linux
#
# October 2002 by Leon Hartwig (hartwig@valvesoftware.com)
#
DLLNAME=hl
ARCH=i386
#make sure this is the correct compiler for your system
CC=gcc
DLL_SRCDIR=.
ENGINE_SRCDIR=../engine
COMMON_SRCDIR=../common
WPN_SHARED_SRCDIR=./wpn_shared
PM_SHARED_SRCDIR=../pm_shared
GAME_SHARED_SRCDIR=../game_shared
DLL_OBJDIR=$(DLL_SRCDIR)/obj
WPN_SHARED_OBJDIR=$(WPN_SHARED_SRCDIR)/obj
PM_SHARED_OBJDIR=$(PM_SHARED_SRCDIR)/obj
GAME_SHARED_OBJDIR=$(GAME_SHARED_SRCDIR)/obj
BASE_CFLAGS= -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-DCLIENT_WEAPONS
#safe optimization
CFLAGS=$(BASE_CFLAGS) -w -m486 -O1
#full optimization
#CFLAGS=$(BASE_CFLAGS) -w -O1 -m486 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations \
-malign-loops=2 -malign-jumps=2 -malign-functions=2
#use these when debugging
#CFLAGS=$(BASE_CFLAGS) -g
INCLUDEDIRS=-I. -I$(ENGINE_SRCDIR) -I$(COMMON_SRCDIR) -I$(PM_SHARED_SRCDIR) -I$(GAME_SHARED_SRCDIR)
LDFLAGS=
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared
DO_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) $(INCLUDEDIRS) -o $@ -c $<
#############################################################################
# SETUP AND BUILD
# GAME
#############################################################################
$(DLL_OBJDIR)/%.o: $(DLL_SRCDIR)/%.cpp
$(DO_CC)
$(WPN_SHARED_OBJDIR)/%.o: $(WPN_SHARED_SRCDIR)/%.cpp
$(DO_CC)
$(GAME_SHARED_OBJDIR)/%.o: $(GAME_SHARED_SRCDIR)/%.cpp
$(DO_CC)
$(PM_SHARED_OBJDIR)/%.o: $(PM_SHARED_SRCDIR)/%.c
$(DO_CC)
OBJ = \
$(DLL_OBJDIR)/aflock.o \
$(DLL_OBJDIR)/agrunt.o \
$(DLL_OBJDIR)/airtank.o \
$(DLL_OBJDIR)/animating.o \
$(DLL_OBJDIR)/animation.o \
$(DLL_OBJDIR)/apache.o \
$(DLL_OBJDIR)/barnacle.o \
$(DLL_OBJDIR)/barney.o \
$(DLL_OBJDIR)/bigmomma.o \
$(DLL_OBJDIR)/bloater.o \
$(DLL_OBJDIR)/bmodels.o \
$(DLL_OBJDIR)/bullsquid.o \
$(DLL_OBJDIR)/buttons.o \
$(DLL_OBJDIR)/cbase.o \
$(DLL_OBJDIR)/client.o \
$(DLL_OBJDIR)/combat.o \
$(DLL_OBJDIR)/controller.o \
$(DLL_OBJDIR)/crossbow.o \
$(DLL_OBJDIR)/crowbar.o \
$(DLL_OBJDIR)/defaultai.o \
$(DLL_OBJDIR)/doors.o \
$(DLL_OBJDIR)/effects.o \
$(DLL_OBJDIR)/egon.o \
$(DLL_OBJDIR)/explode.o \
$(DLL_OBJDIR)/flyingmonster.o \
$(DLL_OBJDIR)/func_break.o \
$(DLL_OBJDIR)/func_tank.o \
$(DLL_OBJDIR)/game.o \
$(DLL_OBJDIR)/gamerules.o \
$(DLL_OBJDIR)/gargantua.o \
$(DLL_OBJDIR)/gauss.o \
$(DLL_OBJDIR)/genericmonster.o \
$(DLL_OBJDIR)/ggrenade.o \
$(DLL_OBJDIR)/globals.o \
$(DLL_OBJDIR)/gman.o \
$(DLL_OBJDIR)/h_ai.o \
$(DLL_OBJDIR)/h_battery.o \
$(DLL_OBJDIR)/h_cine.o \
$(DLL_OBJDIR)/h_cycler.o \
$(DLL_OBJDIR)/h_export.o \
$(DLL_OBJDIR)/handgrenade.o \
$(DLL_OBJDIR)/hassassin.o \
$(DLL_OBJDIR)/headcrab.o \
$(DLL_OBJDIR)/healthkit.o \
$(DLL_OBJDIR)/hgrunt.o \
$(DLL_OBJDIR)/hornet.o \
$(DLL_OBJDIR)/hornetgun.o \
$(DLL_OBJDIR)/houndeye.o \
$(DLL_OBJDIR)/ichthyosaur.o \
$(DLL_OBJDIR)/islave.o \
$(DLL_OBJDIR)/items.o \
$(DLL_OBJDIR)/leech.o \
$(DLL_OBJDIR)/lights.o \
$(DLL_OBJDIR)/maprules.o \
$(DLL_OBJDIR)/monstermaker.o \
$(DLL_OBJDIR)/monsters.o \
$(DLL_OBJDIR)/monsterstate.o \
$(DLL_OBJDIR)/mortar.o \
$(DLL_OBJDIR)/mp5.o \
$(DLL_OBJDIR)/multiplay_gamerules.o \
$(DLL_OBJDIR)/nihilanth.o \
$(DLL_OBJDIR)/nodes.o \
$(DLL_OBJDIR)/osprey.o \
$(DLL_OBJDIR)/pathcorner.o \
$(DLL_OBJDIR)/plane.o \
$(DLL_OBJDIR)/plats.o \
$(DLL_OBJDIR)/player.o \
$(DLL_OBJDIR)/python.o \
$(DLL_OBJDIR)/rat.o \
$(DLL_OBJDIR)/roach.o \
$(DLL_OBJDIR)/rpg.o \
$(DLL_OBJDIR)/satchel.o \
$(DLL_OBJDIR)/schedule.o \
$(DLL_OBJDIR)/scientist.o \
$(DLL_OBJDIR)/scripted.o \
$(DLL_OBJDIR)/shotgun.o \
$(DLL_OBJDIR)/singleplay_gamerules.o \
$(DLL_OBJDIR)/skill.o \
$(DLL_OBJDIR)/sound.o \
$(DLL_OBJDIR)/soundent.o \
$(DLL_OBJDIR)/spectator.o \
$(DLL_OBJDIR)/squadmonster.o \
$(DLL_OBJDIR)/squeakgrenade.o \
$(DLL_OBJDIR)/subs.o \
$(DLL_OBJDIR)/talkmonster.o \
$(DLL_OBJDIR)/teamplay_gamerules.o \
$(DLL_OBJDIR)/tempmonster.o \
$(DLL_OBJDIR)/tentacle.o \
$(DLL_OBJDIR)/triggers.o \
$(DLL_OBJDIR)/tripmine.o \
$(DLL_OBJDIR)/turret.o \
$(DLL_OBJDIR)/util.o \
$(DLL_OBJDIR)/weapons.o \
$(DLL_OBJDIR)/world.o \
$(DLL_OBJDIR)/xen.o \
$(DLL_OBJDIR)/zombie.o \
$(WPN_SHARED_OBJDIR)/hl_wpn_glock.o \
$(GAME_SHARED_OBJDIR)/voice_gamemgr.o \
$(PM_SHARED_OBJDIR)/pm_debug.o \
$(PM_SHARED_OBJDIR)/pm_math.o \
$(PM_SHARED_OBJDIR)/pm_shared.o
$(DLLNAME)_$(ARCH).$(SHLIBEXT) : neat $(OBJ)
$(CC) $(CFLAGS) $(SHLIBLDFLAGS) $(LDFLAGS) -o $@ $(OBJ)
neat:
-mkdir $(DLL_OBJDIR)
-mkdir $(WPN_SHARED_OBJDIR)
-mkdir $(GAME_SHARED_OBJDIR)
-mkdir $(PM_SHARED_OBJDIR)
clean:
-rm -f $(OBJ)
-rm -f $(DLLNAME)_$(ARCH).$(SHLIBEXT)
spotless: clean
-rm -r $(DLL_OBJDIR)
-rm -r $(WPN_SHARED_OBJDIR)
-rm -r $(GAME_SHARED_OBJDIR)
-rm -r $(PM_SHARED_OBJDIR)

395
dlls/Wxdebug.cpp Normal file
View File

@ -0,0 +1,395 @@
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
//
//--------------------------------------------------------------------------;
// For every module and executable we store a debugging level and flags
// for the types of output that are desired. Constants for the types are
// defined in WXDEBUG.H and more can be added.
// The keys are stored in the registry under the
// HKEY_LOCAL_MACHINE\SOFTWARE\Debug\<Module Name>\Type and
// HKEY_LOCAL_MACHINE\SOFTWARE\Debug\<Module Name>\Level key values
//
// There are also global values under SOFTWARE\Debug\Global which are loaded
// after the module-specific values. The Types specified there are OR'ed with
// the module specific types and m_dwLevel is set to the greater of the global
// and the module specific settings.
#include <stdarg.h>
#include <stdio.h>
#include "extdll.h"
#include "util.h"
#include "wxdebug.h"
#include <tchar.h>
#ifdef _DEBUG
void WINAPI DbgInitModuleName(void);
void WINAPI DbgInitModuleSettings(void);
void WINAPI DbgInitGlobalSettings(void);
void WINAPI DbgInitLogTo(HKEY hKey);
void WINAPI DbgInitKeyLevels(HKEY hKey, DWORD *pdwTypes, DWORD *pdwLevel);
const INT iDEBUGINFO = 512; // Used to format strings
HINSTANCE m_hInst; // Module instance handle
TCHAR m_ModuleName[iDEBUGINFO]; // Cut down module name
//CRITICAL_SECTION m_CSDebug; // Controls access to list
BOOL m_bInit = FALSE; // Have we been initialised
HANDLE m_hOutput = INVALID_HANDLE_VALUE; // Optional output written here
DWORD m_dwTypes = 0;
DWORD m_dwLevel = 0;
const TCHAR *m_pBaseKey = TEXT("SOFTWARE\\Debug");
const TCHAR *m_pGlobalKey = TEXT("GLOBAL");
TCHAR *pKeyNames[] =
{
TEXT("Types"),
TEXT("Level")
};
// DbgInitialize
// This sets the instance handle that the debug library uses to find
// the module's file name from the Win32 GetModuleFileName function
void WINAPI DbgInitialise(HINSTANCE hInst)
{
if (!m_bInit)
{
//InitializeCriticalSection(&m_CSDebug);
m_bInit = TRUE;
m_hInst = hInst;
DbgInitModuleName();
DbgInitModuleSettings();
DbgInitGlobalSettings();
}
}
// DbgTerminate
// This is called to clear up any resources the debug library uses - at the
// moment we delete our critical section and the handle of the output file.
void WINAPI DbgTerminate()
{
if (m_bInit)
{
if (m_hOutput != INVALID_HANDLE_VALUE)
{
DBGASSERTEXECUTE(CloseHandle(m_hOutput));
m_hOutput = INVALID_HANDLE_VALUE;
}
//DeleteCriticalSection(&m_CSDebug);
m_bInit = FALSE;
}
}
// DbgInitModuleName
// Initialise the module file name
void WINAPI DbgInitModuleName()
{
TCHAR FullName[iDEBUGINFO]; // Load the full path and module name
TCHAR *pName; // Searches from the end for a backslash
GetModuleFileName(m_hInst,FullName,iDEBUGINFO);
pName = _tcsrchr(FullName,'\\');
if (pName == NULL)
{
pName = FullName;
}
else
{
pName++;
}
lstrcpy(m_ModuleName,pName);
}
// DbgInitModuleSettings
// Retrieve the module-specific settings
void WINAPI DbgInitModuleSettings()
{
LONG lReturn; // Create key return value
TCHAR szInfo[iDEBUGINFO]; // Constructs key names
HKEY hModuleKey; // Module key handle
// Construct the base key name
wsprintf(szInfo,TEXT("%s\\%s"),m_pBaseKey,m_ModuleName);
// Create or open the key for this module
lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key
szInfo, // Address of subkey name
(DWORD)0, // Reserved value
NULL, // Address of class name
(DWORD)0, // Special options flags
KEY_ALL_ACCESS, // Desired security access
NULL, // Key security descriptor
&hModuleKey, // Opened handle buffer
NULL); // What really happened
if (lReturn != ERROR_SUCCESS)
{
DbgLogInfo(LOG_ERROR, 0, TEXT("Could not access module key"));
return;
}
DbgInitLogTo(hModuleKey);
DbgInitKeyLevels(hModuleKey, &m_dwTypes, &m_dwLevel);
RegCloseKey(hModuleKey);
}
// DbgInitGlobalSettings
// This is called by DbgInitialize to read the global debug settings for
// Level and Type from the registry. The Types are OR'ed together and m_dwLevel
// is set to the greater of the global and module-specific values.
void WINAPI DbgInitGlobalSettings()
{
LONG lReturn; // Create key return value
TCHAR szInfo[iDEBUGINFO]; // Constructs key names
HKEY hGlobalKey; // Global override key
DWORD dwTypes = 0;
DWORD dwLevel = 0;
// Construct the global base key name
wsprintf(szInfo,TEXT("%s\\%s"),m_pBaseKey,m_pGlobalKey);
// Create or open the key for this module
lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key
szInfo, // Address of subkey name
(DWORD)0, // Reserved value
NULL, // Address of class name
(DWORD)0, // Special options flags
KEY_ALL_ACCESS, // Desired security access
NULL, // Key security descriptor
&hGlobalKey, // Opened handle buffer
NULL); // What really happened
if (lReturn != ERROR_SUCCESS)
{
DbgLogInfo(LOG_ERROR, 0, TEXT("Could not access GLOBAL module key"));
return;
}
DbgInitKeyLevels(hGlobalKey, &dwTypes, &dwLevel);
RegCloseKey(hGlobalKey);
m_dwTypes |= dwTypes;
if (dwLevel > m_dwLevel)
m_dwLevel = dwLevel;
}
// DbgInitLogTo
// Called by DbgInitModuleSettings to setup alternate logging destinations
void WINAPI DbgInitLogTo(HKEY hKey)
{
LONG lReturn;
DWORD dwKeyType;
DWORD dwKeySize;
TCHAR szFile[MAX_PATH] = {0};
static const TCHAR cszKey[] = TEXT("LogToFile");
dwKeySize = MAX_PATH;
lReturn = RegQueryValueEx(
hKey, // Handle to an open key
cszKey, // Subkey name derivation
NULL, // Reserved field
&dwKeyType, // Returns the field type
(LPBYTE) szFile, // Returns the field's value
&dwKeySize); // Number of bytes transferred
// create an empty key if it does not already exist
if (lReturn != ERROR_SUCCESS || dwKeyType != REG_SZ)
{
dwKeySize = 1;
lReturn = RegSetValueEx(
hKey, // Handle of an open key
cszKey, // Address of subkey name
(DWORD) 0, // Reserved field
REG_SZ, // Type of the key field
(PBYTE)szFile, // Value for the field
dwKeySize); // Size of the field buffer
}
// if an output-to was specified. try to open it.
if (m_hOutput != INVALID_HANDLE_VALUE)
{
DBGASSERTEXECUTE(CloseHandle(m_hOutput));
m_hOutput = INVALID_HANDLE_VALUE;
}
if (szFile[0] != 0)
{
if (!lstrcmpi(szFile, TEXT("Console")))
{
m_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
if (m_hOutput == INVALID_HANDLE_VALUE)
{
AllocConsole();
m_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}
SetConsoleTitle (TEXT("Valve Debug Output"));
} else if (szFile[0] &&
lstrcmpi(szFile, TEXT("Debug")) &&
lstrcmpi(szFile, TEXT("Debugger")) &&
lstrcmpi(szFile, TEXT("Deb")))
{
m_hOutput = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != m_hOutput)
{
static const TCHAR cszBar[] = TEXT("\r\n\r\n=====DbgInitialize()=====\r\n\r\n");
SetFilePointer (m_hOutput, 0, NULL, FILE_END);
DbgOutString (cszBar);
}
}
}
}
// DbgInitKeyLevels
// This is called by DbgInitModuleSettings and DbgInitGlobalSettings to read
// settings for Types and Level from the registry
void WINAPI DbgInitKeyLevels(HKEY hKey, DWORD *pdwTypes, DWORD *pdwLevel)
{
LONG lReturn; // Create key return value
DWORD dwKeySize; // Size of the key value
DWORD dwKeyType; // Receives it's type
// Get the Types value
dwKeySize = sizeof(DWORD);
lReturn = RegQueryValueEx(
hKey, // Handle to an open key
pKeyNames[0], // Subkey name derivation
NULL, // Reserved field
&dwKeyType, // Returns the field type
(LPBYTE)pdwTypes, // Returns the field's value
&dwKeySize ); // Number of bytes transferred
// If either the key was not available or it was not a DWORD value
// then we ensure only the high priority debug logging is output
// but we try and update the field to a zero filled DWORD value
if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD)
{
*pdwTypes = 0;
lReturn = RegSetValueEx(
hKey, // Handle of an open key
pKeyNames[0], // Address of subkey name
(DWORD)0, // Reserved field
REG_DWORD, // Type of the key field
(PBYTE)pdwTypes, // Value for the field
sizeof(DWORD)); // Size of the field buffer
if (lReturn != ERROR_SUCCESS)
{
DbgLogInfo(LOG_ERROR, 0, TEXT("Could not create subkey %s"),pKeyNames[0]);
*pdwTypes = 0;
}
}
// Get the Level value
dwKeySize = sizeof(DWORD);
lReturn = RegQueryValueEx(
hKey, // Handle to an open key
pKeyNames[1], // Subkey name derivation
NULL, // Reserved field
&dwKeyType, // Returns the field type
(LPBYTE)pdwLevel, // Returns the field's value
&dwKeySize ); // Number of bytes transferred
// If either the key was not available or it was not a DWORD value
// then we ensure only the high priority debug logging is output
// but we try and update the field to a zero filled DWORD value
if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD)
{
*pdwLevel = 0;
lReturn = RegSetValueEx(
hKey, // Handle of an open key
pKeyNames[1], // Address of subkey name
(DWORD)0, // Reserved field
REG_DWORD, // Type of the key field
(PBYTE)pdwLevel, // Value for the field
sizeof(DWORD)); // Size of the field buffer
if (lReturn != ERROR_SUCCESS)
{
DbgLogInfo(LOG_ERROR, 0, TEXT("Could not create subkey %s"),pKeyNames[1]);
*pdwLevel = 0;
}
}
}
// DbgOutString
void WINAPI DbgOutString(LPCTSTR psz)
{
if (!m_bInit)
return;
if (m_hOutput != INVALID_HANDLE_VALUE) {
UINT cb = lstrlen(psz);
DWORD dw;
WriteFile (m_hOutput, psz, cb, &dw, NULL);
} else {
OutputDebugString (psz);
}
}
// DbgLogInfo
// Print a formatted string to the debugger prefixed with this module's name
// Because the debug code is linked statically every module loaded will
// have its own copy of this code. It therefore helps if the module name is
// included on the output so that the offending code can be easily found
void WINAPI DbgLogInfo(DWORD Type, DWORD Level, const TCHAR *pFormat,...)
{
if (!m_bInit)
return;
// Check the current level for this type combination */
if (((Type & m_dwTypes) == 0) || (m_dwLevel < Level))
return;
TCHAR szInfo[2000];
// Format the variable length parameter list
va_list va;
va_start(va, pFormat);
//lstrcpy(szInfo, m_ModuleName);
//lstrcat(szInfo, TEXT(": "));
wvsprintf(szInfo /* + lstrlen(szInfo) */, pFormat, va);
//lstrcat(szInfo, TEXT("\r\n"));
DbgOutString(szInfo);
va_end(va);
}
// DbgKernelAssert
// If we are executing as a pure kernel filter we cannot display message
// boxes to the user, this provides an alternative which puts the error
// condition on the debugger output with a suitable eye catching message
void WINAPI DbgKernelAssert(const TCHAR *pCondition, const TCHAR *pFileName, INT iLine)
{
if (!m_bInit)
return;
DbgLogInfo(LOG_ERROR, 0, TEXT(m_ModuleName));
DbgLogInfo(LOG_ERROR, 0, TEXT(": Assertion FAILED (%s) at line %d in file %s\r\n"), pCondition, iLine, pFileName);
DebugBreak();
}
#endif // _DEBUG

View File

@ -1,109 +1,109 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef ACTIVITY_H
#define ACTIVITY_H
typedef enum {
ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity
ACT_IDLE = 1,
ACT_GUARD,
ACT_WALK,
ACT_RUN,
ACT_FLY, // Fly (and flap if appropriate)
ACT_SWIM,
ACT_HOP, // vertical jump
ACT_LEAP, // long forward jump
ACT_FALL,
ACT_LAND,
ACT_STRAFE_LEFT,
ACT_STRAFE_RIGHT,
ACT_ROLL_LEFT, // tuck and roll, left
ACT_ROLL_RIGHT, // tuck and roll, right
ACT_TURN_LEFT, // turn quickly left (stationary)
ACT_TURN_RIGHT, // turn quickly right (stationary)
ACT_CROUCH, // the act of crouching down from a standing position
ACT_CROUCHIDLE, // holding body in crouched position (loops)
ACT_STAND, // the act of standing from a crouched position
ACT_USE,
ACT_SIGNAL1,
ACT_SIGNAL2,
ACT_SIGNAL3,
ACT_TWITCH,
ACT_COWER,
ACT_SMALL_FLINCH,
ACT_BIG_FLINCH,
ACT_RANGE_ATTACK1,
ACT_RANGE_ATTACK2,
ACT_MELEE_ATTACK1,
ACT_MELEE_ATTACK2,
ACT_RELOAD,
ACT_ARM, // pull out gun, for instance
ACT_DISARM, // reholster gun
ACT_EAT, // monster chowing on a large food item (loop)
ACT_DIESIMPLE,
ACT_DIEBACKWARD,
ACT_DIEFORWARD,
ACT_DIEVIOLENT,
ACT_BARNACLE_HIT, // barnacle tongue hits a monster
ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop )
ACT_BARNACLE_CHOMP, // barnacle latches on to the monster
ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop )
ACT_SLEEP,
ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor
ACT_INSPECT_WALL, // for active idles, look at something directly ahead of you ( doesn't HAVE to be a wall or on a wall )
ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop)
ACT_WALK_HURT, // limp (loop)
ACT_RUN_HURT, // limp (loop)
ACT_HOVER, // Idle while in flight
ACT_GLIDE, // Fly (don't flap)
ACT_FLY_LEFT, // Turn left in flight
ACT_FLY_RIGHT, // Turn right in flight
ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air
ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster
ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops.
ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc )
ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of
ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever.
ACT_SPECIAL_ATTACK1, // very monster specific special attacks.
ACT_SPECIAL_ATTACK2,
ACT_COMBAT_IDLE, // agitated idle.
ACT_WALK_SCARED,
ACT_RUN_SCARED,
ACT_VICTORY_DANCE, // killed a player, do a victory dance.
ACT_DIE_HEADSHOT, // die, hit in head.
ACT_DIE_CHESTSHOT, // die, hit in chest
ACT_DIE_GUTSHOT, // die, hit in gut
ACT_DIE_BACKSHOT, // die, hit in back
ACT_FLINCH_HEAD,
ACT_FLINCH_CHEST,
ACT_FLINCH_STOMACH,
ACT_FLINCH_LEFTARM,
ACT_FLINCH_RIGHTARM,
ACT_FLINCH_LEFTLEG,
ACT_FLINCH_RIGHTLEG,
} Activity;
typedef struct {
int type;
char *name;
} activity_map_t;
extern activity_map_t activity_map[];
#endif //ACTIVITY_H
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef ACTIVITY_H
#define ACTIVITY_H
typedef enum {
ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity
ACT_IDLE = 1,
ACT_GUARD,
ACT_WALK,
ACT_RUN,
ACT_FLY, // Fly (and flap if appropriate)
ACT_SWIM,
ACT_HOP, // vertical jump
ACT_LEAP, // long forward jump
ACT_FALL,
ACT_LAND,
ACT_STRAFE_LEFT,
ACT_STRAFE_RIGHT,
ACT_ROLL_LEFT, // tuck and roll, left
ACT_ROLL_RIGHT, // tuck and roll, right
ACT_TURN_LEFT, // turn quickly left (stationary)
ACT_TURN_RIGHT, // turn quickly right (stationary)
ACT_CROUCH, // the act of crouching down from a standing position
ACT_CROUCHIDLE, // holding body in crouched position (loops)
ACT_STAND, // the act of standing from a crouched position
ACT_USE,
ACT_SIGNAL1,
ACT_SIGNAL2,
ACT_SIGNAL3,
ACT_TWITCH,
ACT_COWER,
ACT_SMALL_FLINCH,
ACT_BIG_FLINCH,
ACT_RANGE_ATTACK1,
ACT_RANGE_ATTACK2,
ACT_MELEE_ATTACK1,
ACT_MELEE_ATTACK2,
ACT_RELOAD,
ACT_ARM, // pull out gun, for instance
ACT_DISARM, // reholster gun
ACT_EAT, // monster chowing on a large food item (loop)
ACT_DIESIMPLE,
ACT_DIEBACKWARD,
ACT_DIEFORWARD,
ACT_DIEVIOLENT,
ACT_BARNACLE_HIT, // barnacle tongue hits a monster
ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop )
ACT_BARNACLE_CHOMP, // barnacle latches on to the monster
ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop )
ACT_SLEEP,
ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor
ACT_INSPECT_WALL, // for active idles, look at something directly ahead of you ( doesn't HAVE to be a wall or on a wall )
ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop)
ACT_WALK_HURT, // limp (loop)
ACT_RUN_HURT, // limp (loop)
ACT_HOVER, // Idle while in flight
ACT_GLIDE, // Fly (don't flap)
ACT_FLY_LEFT, // Turn left in flight
ACT_FLY_RIGHT, // Turn right in flight
ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air
ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster
ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops.
ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc )
ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of
ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever.
ACT_SPECIAL_ATTACK1, // very monster specific special attacks.
ACT_SPECIAL_ATTACK2,
ACT_COMBAT_IDLE, // agitated idle.
ACT_WALK_SCARED,
ACT_RUN_SCARED,
ACT_VICTORY_DANCE, // killed a player, do a victory dance.
ACT_DIE_HEADSHOT, // die, hit in head.
ACT_DIE_CHESTSHOT, // die, hit in chest
ACT_DIE_GUTSHOT, // die, hit in gut
ACT_DIE_BACKSHOT, // die, hit in back
ACT_FLINCH_HEAD,
ACT_FLINCH_CHEST,
ACT_FLINCH_STOMACH,
ACT_FLINCH_LEFTARM,
ACT_FLINCH_RIGHTARM,
ACT_FLINCH_LEFTLEG,
ACT_FLINCH_RIGHTLEG,
} Activity;
typedef struct {
int type;
char *name;
} activity_map_t;
extern activity_map_t activity_map[];
#endif //ACTIVITY_H

View File

@ -1,97 +1,97 @@
/***
*
* 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.
*
****/
#define _A( a ) { a, #a }
activity_map_t activity_map[] =
{
_A( ACT_IDLE ),
_A( ACT_GUARD ),
_A( ACT_WALK ),
_A( ACT_RUN ),
_A( ACT_FLY ),
_A( ACT_SWIM ),
_A( ACT_HOP ),
_A( ACT_LEAP ),
_A( ACT_FALL ),
_A( ACT_LAND ),
_A( ACT_STRAFE_LEFT ),
_A( ACT_STRAFE_RIGHT ),
_A( ACT_ROLL_LEFT ),
_A( ACT_ROLL_RIGHT ),
_A( ACT_TURN_LEFT ),
_A( ACT_TURN_RIGHT ),
_A( ACT_CROUCH ),
_A( ACT_CROUCHIDLE ),
_A( ACT_STAND ),
_A( ACT_USE ),
_A( ACT_SIGNAL1 ),
_A( ACT_SIGNAL2 ),
_A( ACT_SIGNAL3 ),
_A( ACT_TWITCH ),
_A( ACT_COWER ),
_A( ACT_SMALL_FLINCH ),
_A( ACT_BIG_FLINCH ),
_A( ACT_RANGE_ATTACK1 ),
_A( ACT_RANGE_ATTACK2 ),
_A( ACT_MELEE_ATTACK1 ),
_A( ACT_MELEE_ATTACK2 ),
_A( ACT_RELOAD ),
_A( ACT_ARM ),
_A( ACT_DISARM ),
_A( ACT_EAT ),
_A( ACT_DIESIMPLE ),
_A( ACT_DIEBACKWARD ),
_A( ACT_DIEFORWARD ),
_A( ACT_DIEVIOLENT ),
_A( ACT_BARNACLE_HIT ),
_A( ACT_BARNACLE_PULL ),
_A( ACT_BARNACLE_CHOMP ),
_A( ACT_BARNACLE_CHEW ),
_A( ACT_SLEEP ),
_A( ACT_INSPECT_FLOOR ),
_A( ACT_INSPECT_WALL ),
_A( ACT_IDLE_ANGRY ),
_A( ACT_WALK_HURT ),
_A( ACT_RUN_HURT ),
_A( ACT_HOVER ),
_A( ACT_GLIDE ),
_A( ACT_FLY_LEFT ),
_A( ACT_FLY_RIGHT ),
_A( ACT_DETECT_SCENT ),
_A( ACT_SNIFF ),
_A( ACT_BITE ),
_A( ACT_THREAT_DISPLAY ),
_A( ACT_FEAR_DISPLAY ),
_A( ACT_EXCITED ),
_A( ACT_SPECIAL_ATTACK1 ),
_A( ACT_SPECIAL_ATTACK2 ),
_A( ACT_COMBAT_IDLE ),
_A( ACT_WALK_SCARED ),
_A( ACT_RUN_SCARED ),
_A( ACT_VICTORY_DANCE ),
_A( ACT_DIE_HEADSHOT ),
_A( ACT_DIE_CHESTSHOT ),
_A( ACT_DIE_GUTSHOT ),
_A( ACT_DIE_BACKSHOT ),
_A( ACT_FLINCH_HEAD ),
_A( ACT_FLINCH_CHEST ),
_A( ACT_FLINCH_STOMACH ),
_A( ACT_FLINCH_LEFTARM ),
_A( ACT_FLINCH_RIGHTARM ),
_A( ACT_FLINCH_LEFTLEG ),
_A( ACT_FLINCH_RIGHTLEG ),
0, NULL
};
/***
*
* 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.
*
****/
#define _A( a ) { a, #a }
activity_map_t activity_map[] =
{
_A( ACT_IDLE ),
_A( ACT_GUARD ),
_A( ACT_WALK ),
_A( ACT_RUN ),
_A( ACT_FLY ),
_A( ACT_SWIM ),
_A( ACT_HOP ),
_A( ACT_LEAP ),
_A( ACT_FALL ),
_A( ACT_LAND ),
_A( ACT_STRAFE_LEFT ),
_A( ACT_STRAFE_RIGHT ),
_A( ACT_ROLL_LEFT ),
_A( ACT_ROLL_RIGHT ),
_A( ACT_TURN_LEFT ),
_A( ACT_TURN_RIGHT ),
_A( ACT_CROUCH ),
_A( ACT_CROUCHIDLE ),
_A( ACT_STAND ),
_A( ACT_USE ),
_A( ACT_SIGNAL1 ),
_A( ACT_SIGNAL2 ),
_A( ACT_SIGNAL3 ),
_A( ACT_TWITCH ),
_A( ACT_COWER ),
_A( ACT_SMALL_FLINCH ),
_A( ACT_BIG_FLINCH ),
_A( ACT_RANGE_ATTACK1 ),
_A( ACT_RANGE_ATTACK2 ),
_A( ACT_MELEE_ATTACK1 ),
_A( ACT_MELEE_ATTACK2 ),
_A( ACT_RELOAD ),
_A( ACT_ARM ),
_A( ACT_DISARM ),
_A( ACT_EAT ),
_A( ACT_DIESIMPLE ),
_A( ACT_DIEBACKWARD ),
_A( ACT_DIEFORWARD ),
_A( ACT_DIEVIOLENT ),
_A( ACT_BARNACLE_HIT ),
_A( ACT_BARNACLE_PULL ),
_A( ACT_BARNACLE_CHOMP ),
_A( ACT_BARNACLE_CHEW ),
_A( ACT_SLEEP ),
_A( ACT_INSPECT_FLOOR ),
_A( ACT_INSPECT_WALL ),
_A( ACT_IDLE_ANGRY ),
_A( ACT_WALK_HURT ),
_A( ACT_RUN_HURT ),
_A( ACT_HOVER ),
_A( ACT_GLIDE ),
_A( ACT_FLY_LEFT ),
_A( ACT_FLY_RIGHT ),
_A( ACT_DETECT_SCENT ),
_A( ACT_SNIFF ),
_A( ACT_BITE ),
_A( ACT_THREAT_DISPLAY ),
_A( ACT_FEAR_DISPLAY ),
_A( ACT_EXCITED ),
_A( ACT_SPECIAL_ATTACK1 ),
_A( ACT_SPECIAL_ATTACK2 ),
_A( ACT_COMBAT_IDLE ),
_A( ACT_WALK_SCARED ),
_A( ACT_RUN_SCARED ),
_A( ACT_VICTORY_DANCE ),
_A( ACT_DIE_HEADSHOT ),
_A( ACT_DIE_CHESTSHOT ),
_A( ACT_DIE_GUTSHOT ),
_A( ACT_DIE_BACKSHOT ),
_A( ACT_FLINCH_HEAD ),
_A( ACT_FLINCH_CHEST ),
_A( ACT_FLINCH_STOMACH ),
_A( ACT_FLINCH_LEFTARM ),
_A( ACT_FLINCH_RIGHTARM ),
_A( ACT_FLINCH_LEFTLEG ),
_A( ACT_FLINCH_RIGHTLEG ),
0, NULL
};

View File

@ -202,7 +202,7 @@ void CFlockingFlyerFlock :: SpawnFlock( void )
vecSpot.z = RANDOM_FLOAT( 0, 16 );
vecSpot = pev->origin + vecSpot;
UTIL_SetOrigin(pBoid, vecSpot);
UTIL_SetOrigin(pBoid->pev, vecSpot);
pBoid->pev->movetype = MOVETYPE_FLY;
pBoid->SpawnCommonCode();
pBoid->pev->flags &= ~FL_ONGROUND;
@ -210,8 +210,8 @@ void CFlockingFlyerFlock :: SpawnFlock( void )
pBoid->pev->angles = pev->angles;
pBoid->pev->frame = 0;
pBoid->SetNextThink( 0.2 );
pBoid->SetThink(& CFlockingFlyer :: IdleThink );
pBoid->pev->nextthink = gpGlobals->time + 0.2;
pBoid->SetThink( CFlockingFlyer :: IdleThink );
if ( pBoid != pLeader )
{
@ -228,8 +228,8 @@ void CFlockingFlyer :: Spawn( )
SpawnCommonCode();
pev->frame = 0;
SetNextThink( 0.1 );
SetThink(&CFlockingFlyer :: IdleThink );
pev->nextthink = gpGlobals->time + 0.1;
SetThink( IdleThink );
}
//=========================================================
@ -292,8 +292,8 @@ void CFlockingFlyer :: Killed( entvars_t *pevAttacker, int iGib )
UTIL_SetSize( pev, Vector(0,0,0), Vector(0,0,0) );
pev->movetype = MOVETYPE_TOSS;
SetThink(&CFlockingFlyer :: FallHack );
SetNextThink( 0.1 );
SetThink ( FallHack );
pev->nextthink = gpGlobals->time + 0.1;
}
void CFlockingFlyer :: FallHack( void )
@ -303,7 +303,7 @@ void CFlockingFlyer :: FallHack( void )
if ( !FClassnameIs ( pev->groundentity, "worldspawn" ) )
{
pev->flags &= ~FL_ONGROUND;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
}
else
{
@ -361,14 +361,13 @@ void CFlockingFlyer :: BoidAdvanceFrame ( )
//=========================================================
void CFlockingFlyer :: IdleThink( void )
{
SetNextThink( 0.2 );
pev->nextthink = gpGlobals->time + 0.2;
// see if there's a client in the same pvs as the monster
// if ( !FNullEnt(FIND_CLIENT_IN_PVS(edict())))
if ( !FNullEnt(FIND_CLIENT_IN_PVS(edict())) || HaveCamerasInPVS( edict() ))
if ( !FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
{
SetThink(&CFlockingFlyer :: Start );
SetNextThink( 0.1 );
SetThink( Start );
pev->nextthink = gpGlobals->time + 0.1;
}
}
@ -377,15 +376,15 @@ void CFlockingFlyer :: IdleThink( void )
//=========================================================
void CFlockingFlyer :: Start( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
if ( IsLeader() )
{
SetThink(&CFlockingFlyer :: FlockLeaderThink );
SetThink( FlockLeaderThink );
}
else
{
SetThink(&CFlockingFlyer :: FlockFollowerThink );
SetThink( FlockFollowerThink );
}
/*
@ -439,8 +438,8 @@ void CFlockingFlyer :: FormFlock( void )
}
}
SetThink(&CFlockingFlyer :: IdleThink );// now that flock is formed, go to idle and wait for a player to come along.
SetNextThink( 0 );
SetThink( IdleThink );// now that flock is formed, go to idle and wait for a player to come along.
pev->nextthink = gpGlobals->time;
}
//=========================================================
@ -564,7 +563,7 @@ void CFlockingFlyer :: FlockLeaderThink( void )
float flRightSide;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
UTIL_MakeVectors ( pev->angles );
@ -643,7 +642,7 @@ void CFlockingFlyer :: FlockLeaderThink( void )
// maybe it did, though.
if ( FBitSet (pev->flags, FL_ONGROUND) )
{
UTIL_SetOrigin (this, pev->origin + Vector ( 0 , 0 , 1 ) );
UTIL_SetOrigin (pev, pev->origin + Vector ( 0 , 0 , 1 ) );
pev->velocity.z = 0;
}
@ -669,12 +668,12 @@ void CFlockingFlyer :: FlockFollowerThink( void )
Vector vecDirToLeader;
float flDistToLeader;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
if ( IsLeader() || !InSquad() )
{
// the leader has been killed and this flyer suddenly finds himself the leader.
SetThink(&CFlockingFlyer :: FlockLeaderThink );
SetThink ( FlockLeaderThink );
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -56,10 +56,10 @@ void CAirtank :: Spawn( void )
SET_MODEL(ENT(pev), "models/w_oxygen.mdl");
UTIL_SetSize(pev, Vector( -16, -16, 0), Vector(16, 16, 36));
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
SetTouch(&CAirtank :: TankTouch );
SetThink(&CAirtank :: TankThink );
SetTouch( TankTouch );
SetThink( TankThink );
pev->flags |= FL_MONSTER;
pev->takedamage = DAMAGE_YES;
@ -104,7 +104,7 @@ void CAirtank::TankTouch( CBaseEntity *pOther )
EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_swim2.wav", 1.0, ATTN_NORM );
return;
}
// give player 12 more seconds of air
pOther->pev->air_finished = gpGlobals->time + 12;
@ -112,7 +112,7 @@ void CAirtank::TankTouch( CBaseEntity *pOther )
EMIT_SOUND( ENT(pev), CHAN_VOICE, "doors/aliendoor3.wav", 1.0, ATTN_NORM );
// recharge airtank in 30 seconds
SetNextThink( 30 );
pev->nextthink = gpGlobals->time + 30;
m_state = 0;
SUB_UseTargets( this, USE_TOGGLE, 1 );
}

View File

@ -246,15 +246,6 @@ int CBaseAnimating :: GetBodygroup( int iGroup )
return ::GetBodygroup( GET_MODEL_PTR( ENT(pev) ), pev, iGroup );
}
int CBaseAnimating :: GetBoneCount( void )
{
return ::GetBoneCount( GET_MODEL_PTR(ENT(pev)) );
}
void CBaseAnimating :: SetBones( float (*data)[3], int datasize )
{
::SetBones( GET_MODEL_PTR( ENT(pev) ), data, datasize );
}
int CBaseAnimating :: ExtractBbox( int sequence, Vector &mins, Vector &maxs )
{

View File

@ -17,10 +17,14 @@
#include <string.h>
#include "extdll.h"
#include "const.h"
#include "studio.h"
#include "util.h"
#ifndef ACTIVITY_H
#include "activity.h"
#endif
#include "activitymap.h"
#ifndef ANIMATION_H
@ -120,7 +124,7 @@ void GetEyePosition ( void *pmodel, Vector &vecEyePosition )
if ( !pstudiohdr )
{
ALERT ( at_debug, "GetEyePosition() Can't get pstudiohdr ptr!\n" );
ALERT ( at_console, "GetEyePosition() Can't get pstudiohdr ptr!\n" );
return;
}
@ -189,7 +193,10 @@ void SequencePrecache( void *pmodel, const char *pSequenceName )
ALERT( at_error, "Bad sound event %d in sequence %s :: %s (sound is \"%s\")\n", pevent[i].event, pstudiohdr->name, pSequenceName, pevent[i].options );
}
// g-cont. old code crash server when using StringTable
// new code working fine in both modes
PRECACHE_SOUND( (char *)STRING( ALLOC_STRING( pevent[i].options )) );
// PRECACHE_SOUND( (char *)(gpGlobals->pStringBase + ALLOC_STRING(pevent[i].options) ) );
}
}
}
@ -303,8 +310,7 @@ float SetController( void *pmodel, entvars_t *pev, int iController, float flValu
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex);
// find first controller that matches the index
int i = 0;
for (i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
for (int i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
{
if (pbonecontroller->index == iController)
break;
@ -454,7 +460,7 @@ int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir )
}
}
ALERT( at_debug, "error in transition graph" );
ALERT( at_console, "error in transition graph" );
return iGoalAnim;
}
@ -499,50 +505,4 @@ int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup )
int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels;
return iCurrent;
}
//LRC
int GetBoneCount( void *pmodel )
{
studiohdr_t *pstudiohdr;
pstudiohdr = (studiohdr_t *)pmodel;
if (!pstudiohdr)
{
ALERT(at_error, "Bad header in SetBones!\n");
return 0;
}
return pstudiohdr->numbones;
}
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
//LRC
void SetBones( void *pmodel, float (*data)[3], int datasize)
{
studiohdr_t *pstudiohdr;
pstudiohdr = (studiohdr_t *)pmodel;
if (!pstudiohdr)
{
ALERT(at_error, "Bad header in SetBones!\n");
return;
}
mstudiobone_t *pbone = (mstudiobone_t *)((byte *)pstudiohdr + pstudiohdr->boneindex);
// ALERT(at_console, "List begins:\n");
int j;
int limit = min(pstudiohdr->numbones, datasize);
// go through the bones
for (int i = 0; i < limit; i++, pbone++)
{
// ALERT(at_console, " %s\n", pbone->name);
for (j = 0; j < 3; j++)
pbone->value[j] = data[i][j];
}
// ALERT(at_console, "List ends.\n");
}
}

View File

@ -17,7 +17,9 @@
#define ACTIVITY_NOT_AVAILABLE -1
#ifndef MONSTEREVENT_H
#include "monsterevent.h"
#endif
extern int IsSoundEvent( int eventNumber );
@ -35,15 +37,10 @@ int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir );
void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue );
int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup );
//LRC
void SetBones( void *pmodel, float (*data)[3], int datasize );
int GetBoneCount( void *pmodel );
int GetSequenceFrames( void *pmodel, entvars_t *pev ); //LRC
int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index );
int ExtractBbox( void *pmodel, int sequence, Vector &mins, Vector &maxs );
// From /common/ref_studio.h
// From /engine/studio.h
#define STUDIO_LOOPING 0x0001

View File

@ -121,17 +121,13 @@ void CApache :: Spawn( void )
pev->movetype = MOVETYPE_FLY;
pev->solid = SOLID_BBOX;
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/apache.mdl");
SET_MODEL(ENT(pev), "models/apache.mdl");
UTIL_SetSize( pev, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) );
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
pev->flags |= FL_MONSTER;
pev->takedamage = DAMAGE_AIM;
if (pev->health == 0)
pev->health = gSkillData.apacheHealth;
pev->health = gSkillData.apacheHealth;
m_flFieldOfView = -0.707; // 270 degrees
@ -143,13 +139,13 @@ void CApache :: Spawn( void )
if (pev->spawnflags & SF_WAITFORTRIGGER)
{
SetUse(&CApache :: StartupUse );
SetUse( StartupUse );
}
else
{
SetThink(&CApache :: HuntThink );
SetTouch(&CApache :: FlyTouch );
SetNextThink( 1.0 );
SetThink( HuntThink );
SetTouch( FlyTouch );
pev->nextthink = gpGlobals->time + 1.0;
}
m_iRockets = 10;
@ -158,10 +154,7 @@ void CApache :: Spawn( void )
void CApache::Precache( void )
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/apache.mdl");
PRECACHE_MODEL("models/apache.mdl");
PRECACHE_SOUND("apache/ap_rotor1.wav");
PRECACHE_SOUND("apache/ap_rotor2.wav");
@ -187,15 +180,15 @@ void CApache::Precache( void )
void CApache::NullThink( void )
{
StudioFrameAdvance( );
SetNextThink( 0.5 );
pev->nextthink = gpGlobals->time + 0.5;
}
void CApache::StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetThink(&CApache:: HuntThink );
SetTouch(&CApache:: FlyTouch );
SetNextThink( 0.1 );
SetThink( HuntThink );
SetTouch( FlyTouch );
pev->nextthink = gpGlobals->time + 0.1;
SetUse( NULL );
}
@ -207,9 +200,9 @@ void CApache :: Killed( entvars_t *pevAttacker, int iGib )
STOP_SOUND( ENT(pev), CHAN_STATIC, "apache/ap_rotor2.wav" );
UTIL_SetSize( pev, Vector( -32, -32, -64), Vector( 32, 32, 0) );
SetThink(&CApache :: DyingThink );
SetTouch(&CApache :: CrashTouch );
SetNextThink( 0.1 );
SetThink( DyingThink );
SetTouch( CrashTouch );
pev->nextthink = gpGlobals->time + 0.1;
pev->health = 0;
pev->takedamage = DAMAGE_NO;
@ -226,7 +219,7 @@ void CApache :: Killed( entvars_t *pevAttacker, int iGib )
void CApache :: DyingThink( void )
{
StudioFrameAdvance( );
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
pev->avelocity = pev->avelocity * 1.02;
@ -234,7 +227,7 @@ void CApache :: DyingThink( void )
if (m_flNextRocket > gpGlobals->time )
{
// random explosions
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, pev->origin );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_EXPLOSION); // This just makes a dynamic light now
WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 ));
WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 ));
@ -246,7 +239,7 @@ void CApache :: DyingThink( void )
MESSAGE_END();
// lots of smoke
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, pev->origin );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 ));
WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 ));
@ -257,7 +250,7 @@ void CApache :: DyingThink( void )
MESSAGE_END();
Vector vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5;
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSpot );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot );
WRITE_BYTE( TE_BREAKMODEL);
// position
@ -294,7 +287,7 @@ void CApache :: DyingThink( void )
// don't stop it we touch a entity
pev->flags &= ~FL_ONGROUND;
SetNextThink( 0.2 );
pev->nextthink = gpGlobals->time + 0.2;
return;
}
else
@ -302,7 +295,7 @@ void CApache :: DyingThink( void )
Vector vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5;
/*
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_EXPLOSION); // This just makes a dynamic light now
WRITE_COORD( vecSpot.x );
WRITE_COORD( vecSpot.y );
@ -314,7 +307,7 @@ void CApache :: DyingThink( void )
*/
// fireball
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSpot );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot );
WRITE_BYTE( TE_SPRITE );
WRITE_COORD( vecSpot.x );
WRITE_COORD( vecSpot.y );
@ -325,7 +318,7 @@ void CApache :: DyingThink( void )
MESSAGE_END();
// big smoke
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSpot );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( vecSpot.x );
WRITE_COORD( vecSpot.y );
@ -336,7 +329,7 @@ void CApache :: DyingThink( void )
MESSAGE_END();
// blast circle
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, pev->origin );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_BEAMCYLINDER );
WRITE_COORD( pev->origin.x);
WRITE_COORD( pev->origin.y);
@ -374,7 +367,7 @@ void CApache :: DyingThink( void )
// gibs
vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5;
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSpot );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot );
WRITE_BYTE( TE_BREAKMODEL);
// position
@ -409,8 +402,8 @@ void CApache :: DyingThink( void )
WRITE_BYTE( BREAK_METAL );
MESSAGE_END();
SetThink(&CApache :: SUB_Remove );
SetNextThink( 0.1 );
SetThink( SUB_Remove );
pev->nextthink = gpGlobals->time + 0.1;
}
}
@ -435,7 +428,7 @@ void CApache::CrashTouch( CBaseEntity *pOther )
{
SetTouch( NULL );
m_flNextRocket = gpGlobals->time;
SetNextThink( 0 );
pev->nextthink = gpGlobals->time;
}
}
@ -450,7 +443,7 @@ void CApache :: GibMonster( void )
void CApache :: HuntThink( void )
{
StudioFrameAdvance( );
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
ShowDamage( );
@ -770,7 +763,7 @@ void CApache :: FireRocket( void )
case 4: break;
}
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSrc );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSrc );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( vecSrc.x );
WRITE_COORD( vecSrc.y );
@ -878,7 +871,7 @@ void CApache :: ShowDamage( void )
{
if (m_iDoSmokePuff > 0 || RANDOM_LONG(0,99) > pev->health)
{
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, pev->origin );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_SMOKE );
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
@ -977,16 +970,16 @@ void CApacheHVR :: Spawn( void )
SET_MODEL(ENT(pev), "models/HVR.mdl");
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
SetThink(&CApacheHVR :: IgniteThink );
SetTouch(&CApacheHVR :: ExplodeTouch );
SetThink( IgniteThink );
SetTouch( ExplodeTouch );
UTIL_MakeAimVectors( pev->angles );
m_vecForward = gpGlobals->v_forward;
pev->gravity = 0.5;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
pev->dmg = 150;
}
@ -1011,7 +1004,7 @@ void CApacheHVR :: IgniteThink( void )
EMIT_SOUND( ENT(pev), CHAN_VOICE, "weapons/rocket1.wav", 1, 0.5 );
// rocket trail
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_BEAMFOLLOW );
WRITE_SHORT(entindex()); // entity
@ -1026,8 +1019,8 @@ void CApacheHVR :: IgniteThink( void )
MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS)
// set to accelerate
SetThink(&CApacheHVR :: AccelerateThink );
SetNextThink( 0.1 );
SetThink( AccelerateThink );
pev->nextthink = gpGlobals->time + 0.1;
}
@ -1050,8 +1043,8 @@ void CApacheHVR :: AccelerateThink( void )
// re-aim
pev->angles = UTIL_VecToAngles( pev->velocity );
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
}
#endif
#endif

View File

@ -75,7 +75,7 @@ IMPLEMENT_SAVERESTORE( CBarnacle, CBaseMonster );
//=========================================================
int CBarnacle :: Classify ( void )
{
return m_iClass?m_iClass:CLASS_ALIEN_MONSTER;
return CLASS_ALIEN_MONSTER;
}
//=========================================================
@ -104,10 +104,7 @@ void CBarnacle :: Spawn()
{
Precache( );
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/barnacle.mdl");
SET_MODEL(ENT(pev), "models/barnacle.mdl");
UTIL_SetSize( pev, Vector(-16, -16, -32), Vector(16, 16, 0) );
pev->solid = SOLID_SLIDEBOX;
@ -127,10 +124,10 @@ void CBarnacle :: Spawn()
SetActivity ( ACT_IDLE );
SetThink(&CBarnacle :: BarnacleThink );
SetNextThink( 0.5 );
SetThink ( BarnacleThink );
pev->nextthink = gpGlobals->time + 0.5;
UTIL_SetOrigin ( this, pev->origin );
UTIL_SetOrigin ( pev, pev->origin );
}
int CBarnacle::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
@ -151,7 +148,7 @@ void CBarnacle :: BarnacleThink ( void )
CBaseMonster *pVictim;
float flLength;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
if ( m_hEnemy != NULL )
{
@ -189,8 +186,7 @@ void CBarnacle :: BarnacleThink ( void )
if ( fabs( pev->origin.z - ( vecNewEnemyOrigin.z + m_hEnemy->pev->view_ofs.z - 8 ) ) < BARNACLE_BODY_HEIGHT )
{
// prey has just been lifted into position ( if the victim origin + eye height + 8 is higher
// than the bottom of the barnacle, it is assumed that the head is within barnacle's body )
// prey has just been lifted into position ( if the victim origin + eye height + 8 is higher than the bottom of the barnacle, it is assumed that the head is within barnacle's body )
m_fLiftingPrey = FALSE;
EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_bite3.wav", 1, ATTN_NORM );
@ -206,7 +202,7 @@ void CBarnacle :: BarnacleThink ( void )
}
}
UTIL_SetOrigin ( m_hEnemy, vecNewEnemyOrigin );
UTIL_SetOrigin ( m_hEnemy->pev, vecNewEnemyOrigin );
}
else
{
@ -246,8 +242,8 @@ void CBarnacle :: BarnacleThink ( void )
// barnacle has no prey right now, so just idle and check to see if anything is touching the tongue.
// If idle and no nearby client, don't think so often
if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) && !HaveCamerasInPVS( edict() ) )
SetNextThink( RANDOM_FLOAT(1,1.5) ); // Stagger a bit to keep barnacles from thinking on the same frame
if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5); // Stagger a bit to keep barnacles from thinking on the same frame
if ( m_fSequenceFinished )
{// this is done so barnacle will fidget.
@ -284,8 +280,8 @@ void CBarnacle :: BarnacleThink ( void )
m_hEnemy = pTouchEnt;
pTouchEnt->pev->movetype = MOVETYPE_FLY;
pTouchEnt->pev->velocity = pev->velocity; //LRC- make him come _with_ me
pTouchEnt->pev->basevelocity = pev->velocity; //LRC
pTouchEnt->pev->velocity = g_vecZero;
pTouchEnt->pev->basevelocity = g_vecZero;
pTouchEnt->pev->origin.x = pev->origin.x;
pTouchEnt->pev->origin.y = pev->origin.y;
@ -352,15 +348,15 @@ void CBarnacle :: Killed( entvars_t *pevAttacker, int iGib )
StudioFrameAdvance( 0.1 );
SetNextThink( 0.1 );
SetThink(&CBarnacle :: WaitTillDead );
pev->nextthink = gpGlobals->time + 0.1;
SetThink ( WaitTillDead );
}
//=========================================================
//=========================================================
void CBarnacle :: WaitTillDead ( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
float flInterval = StudioFrameAdvance( 0.1 );
DispatchAnimEvents ( flInterval );
@ -378,10 +374,7 @@ void CBarnacle :: WaitTillDead ( void )
//=========================================================
void CBarnacle :: Precache()
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/barnacle.mdl");
PRECACHE_MODEL("models/barnacle.mdl");
PRECACHE_SOUND("barnacle/bcl_alert2.wav");//happy, lifting food up
PRECACHE_SOUND("barnacle/bcl_bite3.wav");//just got food to mouth

View File

@ -77,7 +77,6 @@ public:
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
int m_iBaseBody; //LRC - for barneys with different bodies
BOOL m_fGunDrawn;
float m_painTime;
float m_checkAttackTime;
@ -93,7 +92,6 @@ LINK_ENTITY_TO_CLASS( monster_barney, CBarney );
TYPEDESCRIPTION CBarney::m_SaveData[] =
{
DEFINE_FIELD( CBarney, m_iBaseBody, FIELD_INTEGER ), //LRC
DEFINE_FIELD( CBarney, m_fGunDrawn, FIELD_BOOLEAN ),
DEFINE_FIELD( CBarney, m_painTime, FIELD_TIME ),
DEFINE_FIELD( CBarney, m_checkAttackTime, FIELD_TIME ),
@ -263,7 +261,7 @@ int CBarney :: ISoundMask ( void)
//=========================================================
int CBarney :: Classify ( void )
{
return m_iClass?m_iClass:CLASS_PLAYER_ALLY;
return CLASS_PLAYER_ALLY;
}
//=========================================================
@ -275,17 +273,7 @@ void CBarney :: AlertSound( void )
{
if ( FOkToSpeak() )
{
if (m_iszSpeakAs)
{
char szBuf[32];
strcpy(szBuf,STRING(m_iszSpeakAs));
strcat(szBuf,"_ATTACK");
PlaySentence( szBuf, RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE );
}
else
{
PlaySentence( "BA_ATTACK", RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE );
}
PlaySentence( "BA_ATTACK", RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE );
}
}
@ -364,28 +352,16 @@ void CBarney :: BarneyFirePistol ( void )
SetBlending( 0, angDir.x );
pev->effects = EF_MUZZLEFLASH;
if (pev->frags)
{
FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_PLAYER_357);
if (RANDOM_LONG(0, 1))
EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "weapons/357_shot1.wav", 1, ATTN_NORM, 0, 100 );
else
EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "weapons/357_shot2.wav", 1, ATTN_NORM, 0, 100 );
}
else
{
FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
int pitchShift = RANDOM_LONG( 0, 20 );
FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
// Only shift about half the time
if ( pitchShift > 10 )
pitchShift = 0;
else
pitchShift -= 5;
EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "barney/ba_attack2.wav", 1, ATTN_NORM, 0, 100 + pitchShift );
}
int pitchShift = RANDOM_LONG( 0, 20 );
// Only shift about half the time
if ( pitchShift > 10 )
pitchShift = 0;
else
pitchShift -= 5;
EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "barney/ba_attack2.wav", 1, ATTN_NORM, 0, 100 + pitchShift );
CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, 384, 0.3 );
@ -409,13 +385,13 @@ void CBarney :: HandleAnimEvent( MonsterEvent_t *pEvent )
case BARNEY_AE_DRAW:
// barney's bodygroup switches here so he can pull gun from holster
pev->body = m_iBaseBody + BARNEY_BODY_GUNDRAWN;
pev->body = BARNEY_BODY_GUNDRAWN;
m_fGunDrawn = TRUE;
break;
case BARNEY_AE_HOLSTER:
// change bodygroup to replace gun in holster
pev->body = m_iBaseBody + BARNEY_BODY_GUNHOLSTERED;
pev->body = BARNEY_BODY_GUNHOLSTERED;
m_fGunDrawn = FALSE;
break;
@ -431,29 +407,24 @@ void CBarney :: Spawn()
{
Precache( );
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/barney.mdl");
SET_MODEL(ENT(pev), "models/barney.mdl");
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP;
m_bloodColor = BLOOD_COLOR_RED;
if (pev->health == 0) //LRC
pev->health = gSkillData.barneyHealth;
pev->health = gSkillData.barneyHealth;
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
m_MonsterState = MONSTERSTATE_NONE;
m_iBaseBody = pev->body; //LRC
pev->body = m_iBaseBody + BARNEY_BODY_GUNHOLSTERED; // gun in holster
pev->body = 0; // gun in holster
m_fGunDrawn = FALSE;
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
MonsterInit();
SetUse(&CBarney :: FollowerUse );
SetUse( FollowerUse );
}
//=========================================================
@ -461,10 +432,7 @@ void CBarney :: Spawn()
//=========================================================
void CBarney :: Precache()
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/barney.mdl");
PRECACHE_MODEL("models/barney.mdl");
PRECACHE_SOUND("barney/ba_attack1.wav" );
PRECACHE_SOUND("barney/ba_attack2.wav" );
@ -489,44 +457,31 @@ void CBarney :: TalkInit()
CTalkMonster::TalkInit();
// barney speech group names (group names are in sentences.txt)
// scientists speach group names (group names are in sentences.txt)
if (!m_iszSpeakAs)
{
m_szGrp[TLK_ANSWER] = "BA_ANSWER";
m_szGrp[TLK_QUESTION] = "BA_QUESTION";
m_szGrp[TLK_IDLE] = "BA_IDLE";
m_szGrp[TLK_STARE] = "BA_STARE";
if (pev->spawnflags & SF_MONSTER_PREDISASTER) //LRC
m_szGrp[TLK_USE] = "BA_PFOLLOW";
else
m_szGrp[TLK_USE] = "BA_OK";
if (pev->spawnflags & SF_MONSTER_PREDISASTER)
m_szGrp[TLK_UNUSE] = "BA_PWAIT";
else
m_szGrp[TLK_UNUSE] = "BA_WAIT";
if (pev->spawnflags & SF_MONSTER_PREDISASTER)
m_szGrp[TLK_DECLINE] = "BA_POK";
else
m_szGrp[TLK_DECLINE] = "BA_NOTOK";
m_szGrp[TLK_STOP] = "BA_STOP";
m_szGrp[TLK_ANSWER] = "BA_ANSWER";
m_szGrp[TLK_QUESTION] = "BA_QUESTION";
m_szGrp[TLK_IDLE] = "BA_IDLE";
m_szGrp[TLK_STARE] = "BA_STARE";
m_szGrp[TLK_USE] = "BA_OK";
m_szGrp[TLK_UNUSE] = "BA_WAIT";
m_szGrp[TLK_STOP] = "BA_STOP";
m_szGrp[TLK_NOSHOOT] = "BA_SCARED";
m_szGrp[TLK_HELLO] = "BA_HELLO";
m_szGrp[TLK_NOSHOOT] = "BA_SCARED";
m_szGrp[TLK_HELLO] = "BA_HELLO";
m_szGrp[TLK_PLHURT1] = "!BA_CUREA";
m_szGrp[TLK_PLHURT2] = "!BA_CUREB";
m_szGrp[TLK_PLHURT3] = "!BA_CUREC";
m_szGrp[TLK_PLHURT1] = "!BA_CUREA";
m_szGrp[TLK_PLHURT2] = "!BA_CUREB";
m_szGrp[TLK_PLHURT3] = "!BA_CUREC";
m_szGrp[TLK_PHELLO] = NULL; //"BA_PHELLO"; // UNDONE
m_szGrp[TLK_PIDLE] = NULL; //"BA_PIDLE"; // UNDONE
m_szGrp[TLK_PQUESTION] = "BA_PQUEST"; // UNDONE
m_szGrp[TLK_PHELLO] = NULL; //"BA_PHELLO"; // UNDONE
m_szGrp[TLK_PIDLE] = NULL; //"BA_PIDLE"; // UNDONE
m_szGrp[TLK_PQUESTION] = "BA_PQUEST"; // UNDONE
m_szGrp[TLK_SMELL] = "BA_SMELL";
m_szGrp[TLK_SMELL] = "BA_SMELL";
m_szGrp[TLK_WOUND] = "BA_WOUND";
m_szGrp[TLK_MORTAL] = "BA_MORTAL";
}
m_szGrp[TLK_WOUND] = "BA_WOUND";
m_szGrp[TLK_MORTAL] = "BA_MORTAL";
// get voice for head - just one barney voice for now
m_voicePitch = 100;
@ -558,9 +513,6 @@ int CBarney :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
if ( !IsAlive() || pev->deadflag == DEAD_DYING )
return ret;
// LRC - if my reaction to the player has been overridden, don't do this stuff
if (m_iPlayerReact) return ret;
if ( m_MonsterState != MONSTERSTATE_PRONE && (pevAttacker->flags & FL_CLIENT) )
{
m_flPlayerDamage += flDamage;
@ -573,17 +525,7 @@ int CBarney :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || IsFacing( pevAttacker, pev->origin ) )
{
// Alright, now I'm pissed!
if (m_iszSpeakAs)
{
char szBuf[32];
strcpy(szBuf,STRING(m_iszSpeakAs));
strcat(szBuf,"_MAD");
PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM );
}
else
{
PlaySentence( "BA_MAD", 4, VOL_NORM, ATTN_NORM );
}
PlaySentence( "BA_MAD", 4, VOL_NORM, ATTN_NORM );
Remember( bits_MEMORY_PROVOKED );
StopFollowing( TRUE );
@ -591,33 +533,13 @@ int CBarney :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, floa
else
{
// Hey, be careful with that
if (m_iszSpeakAs)
{
char szBuf[32];
strcpy(szBuf,STRING(m_iszSpeakAs));
strcat(szBuf,"_SHOT");
PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM );
}
else
{
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
}
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
Remember( bits_MEMORY_SUSPICIOUS );
}
}
else if ( !(m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO )
{
if (m_iszSpeakAs)
{
char szBuf[32];
strcpy(szBuf,STRING(m_iszSpeakAs));
strcat(szBuf,"_SHOT");
PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM );
}
else
{
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
}
PlaySentence( "BA_SHOT", 4, VOL_NORM, ATTN_NORM );
}
}
@ -689,20 +611,16 @@ void CBarney::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
void CBarney::Killed( entvars_t *pevAttacker, int iGib )
{
if ( pev->body < m_iBaseBody + BARNEY_BODY_GUNGONE && !(pev->spawnflags & SF_MONSTER_NO_WPN_DROP))
if ( pev->body < BARNEY_BODY_GUNGONE )
{// drop the gun!
Vector vecGunPos;
Vector vecGunAngles;
pev->body = m_iBaseBody + BARNEY_BODY_GUNGONE;
pev->body = BARNEY_BODY_GUNGONE;
GetAttachment( 0, vecGunPos, vecGunAngles );
CBaseEntity *pGun;
if (pev->frags)
pGun = DropItem( "weapon_357", vecGunPos, vecGunAngles );
else
pGun = DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles );
CBaseEntity *pGun = DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles );
}
SetUse( NULL );
@ -777,18 +695,7 @@ Schedule_t *CBarney :: GetSchedule ( void )
}
if ( HasConditions( bits_COND_ENEMY_DEAD ) && FOkToSpeak() )
{
// Hey, be careful with that
if (m_iszSpeakAs)
{
char szBuf[32];
strcpy(szBuf,STRING(m_iszSpeakAs));
strcat(szBuf,"_KILL");
PlaySentence( szBuf, 4, VOL_NORM, ATTN_NORM );
}
else
{
PlaySentence( "BA_KILL", 4, VOL_NORM, ATTN_NORM );
}
PlaySentence( "BA_KILL", 4, VOL_NORM, ATTN_NORM );
}
switch( m_MonsterState )
@ -863,7 +770,7 @@ MONSTERSTATE CBarney :: GetIdealState ( void )
void CBarney::DeclineFollowing( void )
{
PlaySentence( m_szGrp[TLK_DECLINE], 2, VOL_NORM, ATTN_NORM ); //LRC
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
}
@ -923,7 +830,7 @@ void CDeadBarney :: Spawn( )
pev->sequence = LookupSequence( m_szPoses[m_iPose] );
if (pev->sequence == -1)
{
ALERT ( at_debug, "Dead barney with bad pose\n" );
ALERT ( at_console, "Dead barney with bad pose\n" );
}
// Corpses have less health
pev->health = 8;//gSkillData.barneyHealth;

View File

@ -110,7 +110,7 @@ public:
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
void KeyValue( KeyValueData *pkvd );
@ -121,11 +121,6 @@ public:
// overrideable Monster member functions
// LRC- to allow level-designers to change monster allegiances
int m_iClass;
int m_iPlayerReact;
virtual int Classify( void ) { return m_iClass?m_iClass:CLASS_NONE; }
virtual int BloodColor( void ) { return m_bloodColor; }
virtual CBaseMonster *MyMonsterPointer( void ) { return this; }
@ -193,9 +188,8 @@ public:
virtual Schedule_t *GetScheduleOfType( int Type );
virtual Schedule_t *GetSchedule( void );
virtual void ScheduleChange( void ) {}
// virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual int CanPlaySequence( int interruptFlags );
// virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
// virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAlive(); }
virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation );
virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener );
@ -302,7 +296,6 @@ public:
virtual void GibMonster( void );
BOOL ShouldGibMonster( int iGib );
void CallGibMonster( void );
virtual int HasCustomGibs( void ) { return FALSE; } //LRC
virtual BOOL HasHumanGibs( void );
virtual BOOL HasAlienGibs( void );
virtual void FadeMonster( void ); // Called instead of GibMonster() when gibs are disabled
@ -313,7 +306,6 @@ public:
virtual Vector GetGunPosition( void );
virtual int TakeHealth( float flHealth, int bitsDamageType );
virtual int TakeArmor( float flArmor );
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
int DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
@ -339,16 +331,7 @@ public:
BOOL ExitScriptedSequence( );
BOOL CineCleanup( );
void StartPatrol( CBaseEntity *path );
CBaseEntity* DropItem ( char *pszItemName, const Vector &vecPos, const Vector &vecAng );// drop an item.
//LRC
float CalcRatio( CBaseEntity *pLocus )
{
/*ALERT(at_console, "monster CR: %f/%f = %f\n", pev->health, pev->max_health, pev->health / pev->max_health);*/
return pev->health / pev->max_health;
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,225 +1,219 @@
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
//=========================================================
// Bloater
//=========================================================
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "schedule.h"
//=========================================================
// Monster's Anim Events Go Here
//=========================================================
#define BLOATER_AE_ATTACK_MELEE1 0x01
class CBloater : public CBaseMonster
{
public:
void Spawn( void );
void Precache( void );
void SetYawSpeed( void );
int Classify ( void );
void HandleAnimEvent( MonsterEvent_t *pEvent );
void PainSound( void );
void AlertSound( void );
void IdleSound( void );
void AttackSnd( void );
// No range attacks
BOOL CheckRangeAttack1 ( float flDot, float flDist ) { return FALSE; }
BOOL CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; }
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
};
LINK_ENTITY_TO_CLASS( monster_bloater, CBloater );
//=========================================================
// Classify - indicates this monster's place in the
// relationship table.
//=========================================================
int CBloater :: Classify ( void )
{
return m_iClass?m_iClass:CLASS_ALIEN_MONSTER;
}
//=========================================================
// SetYawSpeed - allows each sequence to have a different
// turn rate associated with it.
//=========================================================
void CBloater :: SetYawSpeed ( void )
{
int ys;
ys = 120;
#if 0
switch ( m_Activity )
{
}
#endif
pev->yaw_speed = ys;
}
int CBloater :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
PainSound();
return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
}
void CBloater :: PainSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,5))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_pain1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_pain2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
default:
break;
}
#endif
}
void CBloater :: AlertSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,2))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert10.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert20.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 2:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert30.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
void CBloater :: IdleSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,2))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 2:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle3.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
void CBloater :: AttackSnd( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,1))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_attack1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_attack2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CBloater :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
switch( pEvent->event )
{
case BLOATER_AE_ATTACK_MELEE1:
{
// do stuff for this event.
AttackSnd();
}
break;
default:
CBaseMonster::HandleAnimEvent( pEvent );
break;
}
}
//=========================================================
// Spawn
//=========================================================
void CBloater :: Spawn()
{
Precache( );
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/floater.mdl");
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_FLY;
pev->spawnflags |= FL_FLY;
m_bloodColor = BLOOD_COLOR_GREEN;
pev->health = 40;
pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin.
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
MonsterInit();
}
//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CBloater :: Precache()
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/floater.mdl");
}
//=========================================================
// AI Schedules Specific to this monster
//=========================================================
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
//=========================================================
// Bloater
//=========================================================
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "schedule.h"
//=========================================================
// Monster's Anim Events Go Here
//=========================================================
#define BLOATER_AE_ATTACK_MELEE1 0x01
class CBloater : public CBaseMonster
{
public:
void Spawn( void );
void Precache( void );
void SetYawSpeed( void );
int Classify ( void );
void HandleAnimEvent( MonsterEvent_t *pEvent );
void PainSound( void );
void AlertSound( void );
void IdleSound( void );
void AttackSnd( void );
// No range attacks
BOOL CheckRangeAttack1 ( float flDot, float flDist ) { return FALSE; }
BOOL CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; }
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
};
LINK_ENTITY_TO_CLASS( monster_bloater, CBloater );
//=========================================================
// Classify - indicates this monster's place in the
// relationship table.
//=========================================================
int CBloater :: Classify ( void )
{
return CLASS_ALIEN_MONSTER;
}
//=========================================================
// SetYawSpeed - allows each sequence to have a different
// turn rate associated with it.
//=========================================================
void CBloater :: SetYawSpeed ( void )
{
int ys;
ys = 120;
#if 0
switch ( m_Activity )
{
}
#endif
pev->yaw_speed = ys;
}
int CBloater :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
PainSound();
return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
}
void CBloater :: PainSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,5))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_pain1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_pain2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
default:
break;
}
#endif
}
void CBloater :: AlertSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,2))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert10.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert20.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 2:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_alert30.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
void CBloater :: IdleSound( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,2))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 2:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_idle3.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
void CBloater :: AttackSnd( void )
{
#if 0
int pitch = 95 + RANDOM_LONG(0,9);
switch (RANDOM_LONG(0,1))
{
case 0:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_attack1.wav", 1.0, ATTN_NORM, 0, pitch);
break;
case 1:
EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "zombie/zo_attack2.wav", 1.0, ATTN_NORM, 0, pitch);
break;
}
#endif
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//=========================================================
void CBloater :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
switch( pEvent->event )
{
case BLOATER_AE_ATTACK_MELEE1:
{
// do stuff for this event.
AttackSnd();
}
break;
default:
CBaseMonster::HandleAnimEvent( pEvent );
break;
}
}
//=========================================================
// Spawn
//=========================================================
void CBloater :: Spawn()
{
Precache( );
SET_MODEL(ENT(pev), "models/floater.mdl");
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_FLY;
pev->spawnflags |= FL_FLY;
m_bloodColor = BLOOD_COLOR_GREEN;
pev->health = 40;
pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin.
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
MonsterInit();
}
//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CBloater :: Precache()
{
PRECACHE_MODEL("models/floater.mdl");
}
//=========================================================
// AI Schedules Specific to this monster
//=========================================================

View File

@ -24,7 +24,6 @@
#include "util.h"
#include "cbase.h"
#include "doors.h"
#include "movewith.h"
extern DLL_GLOBAL Vector g_vecAttackDir;
@ -43,8 +42,7 @@ extern DLL_GLOBAL Vector g_vecAttackDir;
//
Vector VecBModelOrigin( entvars_t* pevBModel )
{
return (pevBModel->absmin + pevBModel->absmax) * 0.5; //LRC - bug fix for rotating ents
// return pevBModel->absmin + ( pevBModel->size * 0.5 );
return pevBModel->absmin + ( pevBModel->size * 0.5 );
}
// =================== FUNC_WALL ==============================================
@ -58,53 +56,28 @@ public:
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual STATE GetState( void ) { return pev->frame?STATE_ON:STATE_OFF; };
// Bmodels don't go across transitions
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
int m_iStyle;
};
LINK_ENTITY_TO_CLASS( func_wall, CFuncWall );
void CFuncWall :: Spawn( void )
{
{
pev->angles = g_vecZero;
pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
pev->solid = SOLID_BSP;
SET_MODEL( ENT(pev), STRING(pev->model) );
// If it can't move/go away, it's really part of the world
if (!m_pMoveWith) //LRC
pev->flags |= FL_WORLDBRUSH;
//LRC
if (m_iStyle >= 32) LIGHT_STYLE(m_iStyle, "a");
else if (m_iStyle <= -32) LIGHT_STYLE(-m_iStyle, "z");
pev->flags |= FL_WORLDBRUSH;
}
void CFuncWall :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( ShouldToggle( useType, (int)(pev->frame)) )
{
pev->frame = 1 - pev->frame;
if (m_iStyle >= 32)
{
if (pev->frame)
LIGHT_STYLE(m_iStyle, "z");
else
LIGHT_STYLE(m_iStyle, "a");
}
else if (m_iStyle <= -32)
{
if (pev->frame)
LIGHT_STYLE(-m_iStyle, "a");
else
LIGHT_STYLE(-m_iStyle, "z");
}
}
}
@ -118,7 +91,6 @@ public:
void TurnOff( void );
void TurnOn( void );
BOOL IsOn( void );
virtual STATE GetState( void ) { return (pev->solid == SOLID_NOT)?STATE_OFF:STATE_ON; };
};
LINK_ENTITY_TO_CLASS( func_wall_toggle, CFuncWallToggle );
@ -135,7 +107,7 @@ void CFuncWallToggle :: TurnOff( void )
{
pev->solid = SOLID_NOT;
pev->effects |= EF_NODRAW;
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
}
@ -143,7 +115,7 @@ void CFuncWallToggle :: TurnOn( void )
{
pev->solid = SOLID_BSP;
pev->effects &= ~EF_NODRAW;
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
}
@ -157,8 +129,7 @@ BOOL CFuncWallToggle :: IsOn( void )
void CFuncWallToggle :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
// int status = IsOn();
BOOL status = (GetState() == STATE_ON);
int status = IsOn();
if ( ShouldToggle( useType, status ) )
{
@ -247,7 +218,6 @@ LINK_ENTITY_TO_CLASS( func_illusionary, CFuncIllusionary );
void CFuncIllusionary :: KeyValue( KeyValueData *pkvd )
{
// LRC- surely it just parses this automatically? pev values are handled by the engine.
if (FStrEq(pkvd->szKeyName, "skin"))//skin is used for content type
{
pev->skin = atof(pkvd->szValue);
@ -270,65 +240,6 @@ void CFuncIllusionary :: Spawn( void )
// MAKE_STATIC(ENT(pev));
}
// =================== FUNC_SHINE ==============================================
//LRC - shiny surfaces
class CFuncShine : public CBaseEntity
{
public:
void Spawn( void );
void Activate( void );
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
void DesiredAction( void );
void EXPORT Think( void );
};
LINK_ENTITY_TO_CLASS( func_shine, CFuncShine );
extern int gmsgAddShine;
void CFuncShine :: Spawn( void )
{
pev->solid = SOLID_NOT;// always solid_not
SET_MODEL( ENT(pev), STRING(pev->model) );
pev->effects |= EF_NODRAW;
// not that we actually need to precache it here, but we do need to make sure it exists
PRECACHE_MODEL( (char*)STRING(pev->message) );
}
void CFuncShine :: Activate( void )
{
// ALERT(at_console, "Activate shine\n");
CBaseEntity::Activate();
UTIL_DesiredAction(this);
}
void CFuncShine :: DesiredAction( void )
{
if (pev->message && pev->renderamt)
{
// ALERT(at_console, "Prepare think\n");
pev->nextthink = gpGlobals->time + 1.5;
}
}
void CFuncShine :: Think( void )
{
// ALERT(at_console, "Think shine\n");
MESSAGE_BEGIN(MSG_BROADCAST, gmsgAddShine, NULL);
WRITE_BYTE(pev->scale);
WRITE_BYTE(pev->renderamt);
WRITE_COORD(pev->absmin.x + 2); // take off 2: mins values are padded, but we just want to hug the surface
WRITE_COORD(pev->absmax.x - 2);
WRITE_COORD(pev->absmin.y + 2);
WRITE_COORD(pev->absmax.y - 2);
WRITE_COORD(pev->absmin.z + 2);
WRITE_STRING(STRING(pev->message));
MESSAGE_END();
}
// -------------------------------------------------------------------------------
//
@ -371,7 +282,6 @@ public:
void KeyValue( KeyValueData* pkvd);
void EXPORT HurtTouch ( CBaseEntity *pOther );
void EXPORT RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT WaitForStart (); //LRC - get round 1.1.0.8's bizarre behaviour on startup
void EXPORT Rotate( void );
void RampPitchVol (int fUp );
void Blocked( CBaseEntity *pOther );
@ -386,16 +296,6 @@ public:
float m_flVolume;
float m_pitch;
int m_sounds;
EHANDLE m_hActivator; //AJH
float m_fCurSpeed; //LRC - during spin-up and spin-down, this is
// the current speed factor (between 0 and 1).
// storing this here lets us avoid the hassle of deriving it
// from pev->avelocity.
STATE m_iState; //LRC
virtual STATE GetState( void ) { return m_iState; }; //LRC
};
TYPEDESCRIPTION CFuncRotating::m_SaveData[] =
@ -404,8 +304,7 @@ TYPEDESCRIPTION CFuncRotating::m_SaveData[] =
DEFINE_FIELD( CFuncRotating, m_flAttenuation, FIELD_FLOAT ),
DEFINE_FIELD( CFuncRotating, m_flVolume, FIELD_FLOAT ),
DEFINE_FIELD( CFuncRotating, m_pitch, FIELD_FLOAT ),
DEFINE_FIELD( CFuncRotating, m_sounds, FIELD_INTEGER ),
DEFINE_FIELD( CFuncRotating, m_fCurSpeed, FIELD_FLOAT ),
DEFINE_FIELD( CFuncRotating, m_sounds, FIELD_INTEGER )
};
IMPLEMENT_SAVERESTORE( CFuncRotating, CBaseEntity );
@ -442,11 +341,6 @@ void CFuncRotating :: KeyValue( KeyValueData* pkvd)
m_sounds = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "axes"))
{
UTIL_StringToVector( (float *)(pev->movedir), pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
@ -467,10 +361,6 @@ REVERSE will cause the it to rotate in the opposite direction.
void CFuncRotating :: Spawn( )
{
m_iState = STATE_OFF;
m_fCurSpeed = 0; //LRC
// set final pitch. Must not be PITCH_NORM, since we
// plan on pitch shifting later.
@ -497,20 +387,17 @@ void CFuncRotating :: Spawn( )
}
// prevent divide by zero if level designer forgets friction!
if ( m_flFanFriction <= 0 ) //LRC - ensure it's not negative
if ( m_flFanFriction == 0 )
{
m_flFanFriction = 1;
}
if (pev->movedir == g_vecZero)
{
if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS) )
pev->movedir = Vector(0,0,1);
else if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS) )
pev->movedir = Vector(1,0,0);
else
pev->movedir = Vector(0,1,0); // y-axis
}
if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS) )
pev->movedir = Vector(0,0,1);
else if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS) )
pev->movedir = Vector(1,0,0);
else
pev->movedir = Vector(0,1,0); // y-axis
// check for reverse rotation
if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_BACKWARDS) )
@ -529,10 +416,10 @@ void CFuncRotating :: Spawn( )
pev->movetype = MOVETYPE_PUSH;
}
UTIL_SetOrigin(this, pev->origin);
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL( ENT(pev), STRING(pev->model) );
SetUse(&CFuncRotating :: RotatingUse );
SetUse( RotatingUse );
// did level designer forget to assign speed?
if (pev->speed <= 0)
pev->speed = 0;
@ -541,15 +428,16 @@ void CFuncRotating :: Spawn( )
// if (pev->dmg == 0)
// pev->dmg = 2;
if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT))
// instant-use brush?
if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) )
{
SetThink(&CFuncRotating :: WaitForStart );
SetNextThink( 1.5 ); // leave a magic delay for client to start up
SetThink( SUB_CallUseToggle );
pev->nextthink = pev->ltime + 1.5; // leave a magic delay for client to start up
}
// can this brush inflict pain?
if ( FBitSet (pev->spawnflags, SF_BRUSH_HURT) )
{
SetTouch(&CFuncRotating :: HurtTouch );
SetTouch( HurtTouch );
}
Precache( );
@ -576,23 +464,23 @@ void CFuncRotating :: Precache( void )
{
case 1:
PRECACHE_SOUND ("fans/fan1.wav");
pev->noiseRunning = MAKE_STRING("fans/fan1.wav");
pev->noiseRunning = ALLOC_STRING("fans/fan1.wav");
break;
case 2:
PRECACHE_SOUND ("fans/fan2.wav");
pev->noiseRunning = MAKE_STRING("fans/fan2.wav");
pev->noiseRunning = ALLOC_STRING("fans/fan2.wav");
break;
case 3:
PRECACHE_SOUND ("fans/fan3.wav");
pev->noiseRunning = MAKE_STRING("fans/fan3.wav");
pev->noiseRunning = ALLOC_STRING("fans/fan3.wav");
break;
case 4:
PRECACHE_SOUND ("fans/fan4.wav");
pev->noiseRunning = MAKE_STRING("fans/fan4.wav");
pev->noiseRunning = ALLOC_STRING("fans/fan4.wav");
break;
case 5:
PRECACHE_SOUND ("fans/fan5.wav");
pev->noiseRunning = MAKE_STRING("fans/fan5.wav");
pev->noiseRunning = ALLOC_STRING("fans/fan5.wav");
break;
case 0:
@ -605,34 +493,23 @@ void CFuncRotating :: Precache( void )
break;
} else
{
pev->noiseRunning = MAKE_STRING("common/null.wav");
pev->noiseRunning = ALLOC_STRING("common/null.wav");
break;
}
}
}
if (m_fCurSpeed != 0 )
if (pev->avelocity != g_vecZero )
{
// if fan was spinning, and we went through transition or save/restore,
// make sure we restart the sound. 1.5 sec delay is magic number. KDB
SetThink(&CFuncRotating :: SpinUp );
SetNextThink( 1.5 );
SetThink ( SpinUp );
pev->nextthink = pev->ltime + 1.5;
}
}
void CFuncRotating :: WaitForStart()
{
if (gpGlobals->time > 1) // has the client started yet?
{
SUB_CallUseToggle();
}
else
{
SetNextThink( 0.1 );
}
}
//
// Touch - will hurt others based on how fast the brush is spinning
@ -646,13 +523,9 @@ void CFuncRotating :: HurtTouch ( CBaseEntity *pOther )
return;
// calculate damage based on rotation speed
pev->dmg = m_fCurSpeed / 10; //LRC
// pev->dmg = pev->avelocity.Length() / 10;
pev->dmg = pev->avelocity.Length() / 10;
if (m_hActivator)
pOther->TakeDamage( pev, m_hActivator->pev, pev->dmg, DMG_CRUSH );
else
pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH );
pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH);
pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * pev->dmg;
}
@ -666,14 +539,34 @@ void CFuncRotating :: HurtTouch ( CBaseEntity *pOther )
void CFuncRotating :: RampPitchVol (int fUp)
{
Vector vecAVel = pev->avelocity;
vec_t vecCur;
vec_t vecFinal;
float fpct;
float fvol;
float fpitch;
int pitch;
float speedfactor = m_fCurSpeed/pev->speed;
fvol = m_flVolume * speedfactor; // slowdown volume ramps down to 0
// get current angular velocity
fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * speedfactor;
vecCur = abs(vecAVel.x != 0 ? vecAVel.x : (vecAVel.y != 0 ? vecAVel.y : vecAVel.z));
// get target angular velocity
vecFinal = (pev->movedir.x != 0 ? pev->movedir.x : (pev->movedir.y != 0 ? pev->movedir.y : pev->movedir.z));
vecFinal *= pev->speed;
vecFinal = abs(vecFinal);
// calc volume and pitch as % of final vol and pitch
fpct = vecCur / vecFinal;
// if (fUp)
// fvol = m_flVolume * (0.5 + fpct/2.0); // spinup volume ramps up from 50% max vol
// else
fvol = m_flVolume * fpct; // slowdown volume ramps down to 0
fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * fpct;
pitch = (int) fpitch;
if (pitch == PITCH_NORM)
@ -691,26 +584,23 @@ void CFuncRotating :: RampPitchVol (int fUp)
//
void CFuncRotating :: SpinUp( void )
{
//Vector vecAVel;//rotational velocity
Vector vecAVel;//rotational velocity
SetNextThink( 0.1 );
m_fCurSpeed = m_fCurSpeed + ( pev->speed * m_flFanFriction );
UTIL_SetAvelocity(this, pev->movedir * m_fCurSpeed);
//pev->avelocity = pev->avelocity + ( pev->movedir * ( pev->speed * m_flFanFriction ) );
pev->nextthink = pev->ltime + 0.1;
pev->avelocity = pev->avelocity + ( pev->movedir * ( pev->speed * m_flFanFriction ) );
//vecAVel = pev->avelocity;// cache entity's rotational velocity
vecAVel = pev->avelocity;// cache entity's rotational velocity
// if we've met or exceeded target speed, set target speed and stop thinking
if ( m_fCurSpeed >= pev->speed )
if ( abs(vecAVel.x) >= abs(pev->movedir.x * pev->speed) &&
abs(vecAVel.y) >= abs(pev->movedir.y * pev->speed) &&
abs(vecAVel.z) >= abs(pev->movedir.z * pev->speed) )
{
m_iState = STATE_ON;
m_fCurSpeed = pev->speed;
UTIL_SetAvelocity(this, pev->movedir * pev->speed);
//pev->avelocity = pev->movedir * pev->speed;// set speed in case we overshot
pev->avelocity = pev->movedir * pev->speed;// set speed in case we overshot
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning),
m_flVolume, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, FANPITCHMAX);
SetThink(&CFuncRotating :: Rotate );
SetThink( Rotate );
Rotate();
}
else
@ -724,25 +614,34 @@ void CFuncRotating :: SpinUp( void )
//
void CFuncRotating :: SpinDown( void )
{
SetNextThink( 0.1 );
Vector vecAVel;//rotational velocity
vec_t vecdir;
m_fCurSpeed = m_fCurSpeed - ( pev->speed * m_flFanFriction );
UTIL_SetAvelocity(this, pev->movedir * m_fCurSpeed);
//pev->avelocity = pev->avelocity - ( pev->movedir * ( pev->speed * m_flFanFriction ) );//spin down slower than spinup
pev->nextthink = pev->ltime + 0.1;
pev->avelocity = pev->avelocity - ( pev->movedir * ( pev->speed * m_flFanFriction ) );//spin down slower than spinup
vecAVel = pev->avelocity;// cache entity's rotational velocity
if (pev->movedir.x != 0)
vecdir = pev->movedir.x;
else if (pev->movedir.y != 0)
vecdir = pev->movedir.y;
else
vecdir = pev->movedir.z;
// if we've met or exceeded target speed, set target speed and stop thinking
if (m_fCurSpeed <= 0)
// (note: must check for movedir > 0 or < 0)
if (((vecdir > 0) && (vecAVel.x <= 0 && vecAVel.y <= 0 && vecAVel.z <= 0)) ||
((vecdir < 0) && (vecAVel.x >= 0 && vecAVel.y >= 0 && vecAVel.z >= 0)))
{
m_iState = STATE_OFF;
m_fCurSpeed = 0;
UTIL_SetAvelocity(this, g_vecZero);
//pev->avelocity = g_vecZero;// set speed in case we overshot
pev->avelocity = g_vecZero;// set speed in case we overshot
// stop sound, we're done
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning /* Stop */),
0, 0, SND_STOP, m_pitch);
SetThink(&CFuncRotating :: Rotate );
SetThink( Rotate );
Rotate();
}
else
@ -753,7 +652,7 @@ void CFuncRotating :: SpinDown( void )
void CFuncRotating :: Rotate( void )
{
SetNextThink( 10 );
pev->nextthink = pev->ltime + 10;
}
//=========================================================
@ -761,61 +660,47 @@ void CFuncRotating :: Rotate( void )
//=========================================================
void CFuncRotating :: RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
m_hActivator = pActivator; //AJH
if (!ShouldToggle(useType)) return;
// is this a brush that should accelerate and decelerate when turned on/off (fan)?
if ( FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) )
{
// fan is spinning, so stop it.
if ( m_fCurSpeed != 0 )
// if ( pev->avelocity != g_vecZero )
if ( pev->avelocity != g_vecZero )
{
m_iState = STATE_TURN_OFF;
SetThink(&CFuncRotating :: SpinDown );
SetThink ( SpinDown );
//EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop),
// m_flVolume, m_flAttenuation, 0, m_pitch);
SetNextThink( 0.1 );
pev->nextthink = pev->ltime + 0.1;
}
else// fan is not moving, so start it
{
m_iState = STATE_TURN_ON;
SetThink(&CFuncRotating :: SpinUp );
SetThink ( SpinUp );
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning),
0.01, m_flAttenuation, 0, FANPITCHMIN);
SetNextThink( 0.1 );
pev->nextthink = pev->ltime + 0.1;
}
}
else // if ( !FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) )//this is a normal start/stop brush.
else if ( !FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) )//this is a normal start/stop brush.
{
if ( m_fCurSpeed != 0 ) //LRC
// if ( pev->avelocity != g_vecZero )
if ( pev->avelocity != g_vecZero )
{
m_iState = STATE_OFF;
// play stopping sound here
SetThink(&CFuncRotating :: SpinDown );
SetThink ( SpinDown );
// EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop),
// m_flVolume, m_flAttenuation, 0, m_pitch);
SetNextThink( 0.1 );
pev->nextthink = pev->ltime + 0.1;
// pev->avelocity = g_vecZero;
}
else
{
m_iState = STATE_ON;
EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning),
m_flVolume, m_flAttenuation, 0, FANPITCHMAX);
pev->avelocity = pev->movedir * pev->speed;
//LRC
m_fCurSpeed = pev->speed;
UTIL_SetAvelocity(this, pev->movedir * pev->speed);
// pev->avelocity = pev->movedir * pev->speed;
SetThink(&CFuncRotating :: Rotate );
SetThink( Rotate );
Rotate();
}
}
@ -826,21 +711,9 @@ void CFuncRotating :: RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller
// RotatingBlocked - An entity has blocked the brush
//
void CFuncRotating :: Blocked( CBaseEntity *pOther )
{
//g-cont. simple recursive anouncer for parent system
//tell parent who blocked his
if(!FNullEnt(m_pMoveWith) && m_iLFlags & LF_PARENTMOVE) m_pMoveWith->Blocked( this );
if(!FNullEnt(m_pChildMoveWith))
{
if(m_pChildMoveWith == pOther)
{
//ALERT(at_console, "I'am blocked by my child!\n");
Use( NULL, NULL, USE_OFF, 0 );
}
}
if (m_hActivator) pOther->TakeDamage( pev, m_hActivator->pev, pev->dmg, DMG_CRUSH ); //AJH Attribute damage to he who switched me.
else pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH );
pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH);
}
@ -856,16 +729,15 @@ class CPendulum : public CBaseEntity
public:
void Spawn ( void );
void KeyValue( KeyValueData *pkvd );
void EXPORT SwingThink( void );
void EXPORT Swing( void );
void EXPORT PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT StopThink( void );
void EXPORT Stop( void );
void Touch( CBaseEntity *pOther );
void EXPORT RopeTouch ( CBaseEntity *pOther );// this touch func makes the pendulum a rope
virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
void Blocked( CBaseEntity *pOther );
virtual STATE GetState( void ) { return (pev->speed)?STATE_ON:STATE_OFF; }
static TYPEDESCRIPTION m_SaveData[];
@ -877,8 +749,6 @@ public:
float m_dampSpeed;
vec3_t m_center;
vec3_t m_start;
EHANDLE m_hActivator; //AJH (give frags to this entity)
};
LINK_ENTITY_TO_CLASS( func_pendulum, CPendulum );
@ -906,11 +776,6 @@ void CPendulum :: KeyValue( KeyValueData *pkvd )
m_distance = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "axes"))
{
UTIL_StringToVector( (float*)(pev->movedir), pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "damp"))
{
m_damp = atof(pkvd->szValue) * 0.001;
@ -931,7 +796,7 @@ void CPendulum :: Spawn( void )
else
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(this, pev->origin);
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model) );
if ( m_distance == 0 )
@ -947,25 +812,21 @@ void CPendulum :: Spawn( void )
if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) )
{
SetThink(&CPendulum :: SUB_CallUseToggle );
SetNextThink( 0.1 );
SetThink( SUB_CallUseToggle );
pev->nextthink = gpGlobals->time + 0.1;
}
pev->speed = 0;
SetUse(&CPendulum :: PendulumUse );
SetUse( PendulumUse );
if ( FBitSet( pev->spawnflags, SF_PENDULUM_SWING ) )
{
SetTouch(&CPendulum :: RopeTouch );
SetTouch ( RopeTouch );
}
}
void CPendulum :: PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (!ShouldToggle(useType)) return;
m_hActivator = pActivator; //AJH
if ( pev->speed ) // Pendulum is moving, stop it and auto-return if necessary
{
if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) )
@ -974,56 +835,43 @@ void CPendulum :: PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, US
delta = CBaseToggle :: AxisDelta( pev->spawnflags, pev->angles, m_start );
UTIL_SetAvelocity(this, m_maxSpeed * pev->movedir); //LRC
//pev->avelocity = m_maxSpeed * pev->movedir;
SetNextThink(delta / m_maxSpeed);
SetThink(&CPendulum ::StopThink);
pev->avelocity = m_maxSpeed * pev->movedir;
pev->nextthink = pev->ltime + (delta / m_maxSpeed);
SetThink( Stop );
}
else
{
pev->speed = 0; // Dead stop
DontThink();
UTIL_SetAvelocity(this, g_vecZero); //LRC
//pev->avelocity = g_vecZero;
SetThink( NULL );
pev->avelocity = g_vecZero;
}
}
else
{
SetNextThink(0.1); // start the pendulum moving
SetThink(&CPendulum ::SwingThink);
pev->nextthink = pev->ltime + 0.1; // Start the pendulum moving
m_time = gpGlobals->time; // Save time to calculate dt
SetThink( Swing );
m_dampSpeed = m_maxSpeed;
}
}
void CPendulum :: StopThink( void )
void CPendulum :: Stop( void )
{
UTIL_AssignAngles(this, m_start); //LRC
//pev->angles = m_start;
pev->angles = m_start;
pev->speed = 0;
DontThink();
UTIL_SetAvelocity(this, g_vecZero); //LRC
//pev->avelocity = g_vecZero;
SetThink( NULL );
pev->avelocity = g_vecZero;
}
void CPendulum::Blocked( CBaseEntity *pOther )
{
//g-cont. simple recursive anouncer for parent system
//tell parent who blocked his
if(!FNullEnt(m_pMoveWith) && m_iLFlags & LF_PARENTMOVE) m_pMoveWith->Blocked( this );
if(!FNullEnt(m_pChildMoveWith))
{
if(m_pChildMoveWith == pOther)
{
//ALERT(at_console, "I'am blocked by my child!\n");
Use( NULL, NULL, USE_OFF, 0 );
}
}
m_time = gpGlobals->time;
}
void CPendulum :: SwingThink( void )
void CPendulum :: Swing( void )
{
float delta, dt;
@ -1040,33 +888,21 @@ void CPendulum :: SwingThink( void )
pev->speed = m_maxSpeed;
else if ( pev->speed < -m_maxSpeed )
pev->speed = -m_maxSpeed;
// scale the destdelta vector by the time spent traveling to get velocity
UTIL_SetAvelocity(this, pev->speed * pev->movedir); //LRC
//pev->avelocity = pev->speed * pev->movedir;
// ALERT(at_console, "m_damp %f, m_dampSpeed %f\n", m_damp, m_dampSpeed);
// ALERT(at_console, "SwingThink: delta %f, dt %f, speed %f, avel %f %f %f\n", delta, dt, pev->speed, pev->avelocity.x, pev->avelocity.y, pev->avelocity.z);
pev->avelocity = pev->speed * pev->movedir;
// Call this again
SetNextThink(0.1);
SetThink(&CPendulum ::SwingThink);
// if (m_pMoveWith) // correct MoveWith problems associated with fast-thinking entities
// UTIL_AssignOrigin(this, m_vecOffsetOrigin + m_pMoveWith->pev->origin);
pev->nextthink = pev->ltime + 0.1;
if ( m_damp )
{
m_dampSpeed -= m_damp * m_dampSpeed * dt;
if ( m_dampSpeed < 30.0 )
{
UTIL_AssignAngles(this, m_center); //LRC
//pev->angles = m_center;
pev->angles = m_center;
pev->speed = 0;
ALERT(at_debug, "**CANCELLING pendulum think!\n");
DontThink();
UTIL_SetAvelocity(this, g_vecZero); //LRC
//pev->avelocity = g_vecZero;
SetThink( NULL );
pev->avelocity = g_vecZero;
}
else if ( pev->speed > m_dampSpeed )
pev->speed = m_dampSpeed;
@ -1094,10 +930,7 @@ void CPendulum :: Touch ( CBaseEntity *pOther )
if ( damage < 0 )
damage = -damage;
if (m_hActivator)
pOther->TakeDamage( pev, m_hActivator->pev, damage, DMG_CRUSH );
else
pOther->TakeDamage( pev, pev, damage, DMG_CRUSH );
pOther->TakeDamage( pev, pev, damage, DMG_CRUSH );
pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * damage;
}
@ -1122,3 +955,4 @@ void CPendulum :: RopeTouch ( CBaseEntity *pOther )
pevOther->movetype = MOVETYPE_NONE;
}

View File

@ -25,9 +25,7 @@
#include "effects.h"
#include "decals.h"
#include "soundent.h"
#include "scripted.h"
#include "game.h"
#include "weapons.h"
#define SQUID_SPRINT_DIST 256 // how close the squid has to get before starting to sprint and refusing to swerve
@ -103,7 +101,7 @@ void CSquidSpit:: Spawn( void )
void CSquidSpit::Animate( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
if ( pev->frame++ )
{
@ -119,12 +117,12 @@ void CSquidSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity
CSquidSpit *pSpit = GetClassPtr( (CSquidSpit *)NULL );
pSpit->Spawn();
UTIL_SetOrigin( pSpit, vecStart );
UTIL_SetOrigin( pSpit->pev, vecStart );
pSpit->pev->velocity = vecVelocity;
pSpit->pev->owner = ENT(pevOwner);
pSpit->SetThink(&CSquidSpit:: Animate );
pSpit->SetNextThink( 0.1 );
pSpit->SetThink ( Animate );
pSpit->pev->nextthink = gpGlobals->time + 0.1;
}
void CSquidSpit :: Touch ( CBaseEntity *pOther )
@ -152,14 +150,10 @@ void CSquidSpit :: Touch ( CBaseEntity *pOther )
// make a splat on the wall
UTIL_TraceLine( pev->origin, pev->origin + pev->velocity * 10, dont_ignore_monsters, ENT( pev ), &tr );
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), 4, 0, 0 );
//UTIL_DecalTrace(&tr, DECAL_SPIT1 + RANDOM_LONG(0,1));
UTIL_DecalTrace(&tr, DECAL_SPIT1 + RANDOM_LONG(0,1));
// make some flecks
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, tr.vecEndPos );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, tr.vecEndPos );
WRITE_BYTE( TE_SPRITE_SPRAY );
WRITE_COORD( tr.vecEndPos.x); // pos
WRITE_COORD( tr.vecEndPos.y);
@ -178,8 +172,8 @@ void CSquidSpit :: Touch ( CBaseEntity *pOther )
pOther->TakeDamage ( pev, pev, gSkillData.bullsquidDmgSpit, DMG_GENERIC );
}
SetThink(&CSquidSpit :: SUB_Remove );
SetNextThink( 0 );
SetThink ( SUB_Remove );
pev->nextthink = gpGlobals->time;
}
//=========================================================
@ -232,7 +226,6 @@ public:
float m_flNextSpitTime;// last time the bullsquid used the spit attack.
};
LINK_ENTITY_TO_CLASS( monster_bullchicken, CBullsquid );
LINK_ENTITY_TO_CLASS( monster_bullsquid, CBullsquid ); //LRC - let's get the right name...
TYPEDESCRIPTION CBullsquid::m_SaveData[] =
{
@ -253,7 +246,6 @@ int CBullsquid::IgnoreConditions ( void )
if ( gpGlobals->time - m_flLastHurtTime <= 20 )
{
// haven't been hurt in 20 seconds, so let the squid care about stink.
// Er, more like, we HAVE been hurt in the last 20 seconds, so DON'T let it care about food. --LRC
iIgnore = bits_COND_SMELL | bits_COND_SMELL_FOOD;
}
@ -262,7 +254,6 @@ int CBullsquid::IgnoreConditions ( void )
if ( FClassnameIs( m_hEnemy->pev, "monster_headcrab" ) )
{
// (Unless after a tasty headcrab)
// i.e. when chasing a headcrab, don't worry about other food. --LRC
iIgnore = bits_COND_SMELL | bits_COND_SMELL_FOOD;
}
}
@ -434,7 +425,7 @@ int CBullsquid :: ISoundMask ( void )
//=========================================================
int CBullsquid :: Classify ( void )
{
return m_iClass?m_iClass:CLASS_ALIEN_PREDATOR;
return CLASS_ALIEN_PREDATOR;
}
//=========================================================
@ -548,14 +539,6 @@ void CBullsquid :: HandleAnimEvent( MonsterEvent_t *pEvent )
// we should be able to read the position of bones at runtime for this info.
vecSpitOffset = ( gpGlobals->v_right * 8 + gpGlobals->v_forward * 37 + gpGlobals->v_up * 23 );
vecSpitOffset = ( pev->origin + vecSpitOffset );
if (m_pCine) // LRC- are we being told to do this by a scripted_action?
{
if (m_hTargetEnt != NULL && m_pCine->PreciseAttack())
vecSpitDir = ( ( m_hTargetEnt->pev->origin ) - vecSpitOffset ).Normalize();
else
vecSpitDir = gpGlobals->v_forward;
}
else
vecSpitDir = ( ( m_hEnemy->pev->origin + m_hEnemy->pev->view_ofs ) - vecSpitOffset ).Normalize();
vecSpitDir.x += RANDOM_FLOAT( -0.05, 0.05 );
@ -567,7 +550,7 @@ void CBullsquid :: HandleAnimEvent( MonsterEvent_t *pEvent )
AttackSound();
// spew the spittle temporary ents.
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, vecSpitOffset );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpitOffset );
WRITE_BYTE( TE_SPRITE_SPRAY );
WRITE_COORD( vecSpitOffset.x); // pos
WRITE_COORD( vecSpitOffset.y);
@ -687,18 +670,14 @@ void CBullsquid :: Spawn()
{
Precache( );
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/bullsquid.mdl");
SET_MODEL(ENT(pev), "models/bullsquid.mdl");
UTIL_SetSize( pev, Vector( -32, -32, 0 ), Vector( 32, 32, 64 ) );
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_STEP;
m_bloodColor = BLOOD_COLOR_GREEN;
pev->effects = 0;
if (pev->health == 0)
pev->health = gSkillData.bullsquidHealth;
pev->health = gSkillData.bullsquidHealth;
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
@ -713,10 +692,7 @@ void CBullsquid :: Spawn()
//=========================================================
void CBullsquid :: Precache()
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/bullsquid.mdl");
PRECACHE_MODEL("models/bullsquid.mdl");
PRECACHE_MODEL("sprites/bigspit.spr");// spit projectile.

View File

@ -29,13 +29,9 @@
#define SF_BUTTON_DONTMOVE 1
#define SF_ROTBUTTON_NOTSOLID 1
#define SF_BUTTON_ONLYDIRECT 16 //LRC - button can't be used through walls.
#define SF_BUTTON_TOGGLE 32 // button stays pushed until reactivated
#define SF_BUTTON_SPARK_IF_OFF 64 // button sparks in OFF state
#define SF_BUTTON_NOT_SOLID 128 // button isn't solid
#define SF_BUTTON_TOUCH_ONLY 256 // button must be touched to be used.
#define SF_BUTTON_USEKEY 512 // change the reaction of the button to the USE key.
// (i.e. if it's meant to be ignored, don't ignore it; otherwise ignore it.)
#define SF_BUTTON_TOUCH_ONLY 256 // button only fires as a result of USE key.
#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn
@ -101,39 +97,28 @@ void CEnvGlobal::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us
GLOBALESTATE oldState = gGlobalState.EntityGetState( m_globalstate );
GLOBALESTATE newState;
if (useType==USE_ON)//this support USE_TYPE global states. G-Cont.
{
newState = GLOBAL_ON;
}
else if(useType==USE_OFF)
{
newState = GLOBAL_OFF;
}
else
switch( m_triggermode )
{
switch( m_triggermode )
{
case 0:
case 0:
newState = GLOBAL_OFF;
break;
case 1:
newState = GLOBAL_ON;
break;
case 2:
newState = GLOBAL_DEAD;
break;
default:
case 3:
if ( oldState == GLOBAL_ON )
newState = GLOBAL_OFF;
break;
case 1:
newState = GLOBAL_ON;
break;
case 2:
newState = GLOBAL_DEAD;
break;
default:
case 3:
if ( oldState == GLOBAL_ON )
newState = GLOBAL_OFF;
else if ( oldState == GLOBAL_OFF )
newState = GLOBAL_ON;
else
newState = oldState;
}
else if ( oldState == GLOBAL_OFF )
newState = GLOBAL_ON;
else
newState = oldState;
}
if ( gGlobalState.EntityInTable( m_globalstate ) )
@ -143,202 +128,6 @@ void CEnvGlobal::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us
}
//==================================================
//LRC- a simple entity, just maintains a state
//==================================================
#define SF_ENVSTATE_START_ON 1
#define SF_ENVSTATE_DEBUG 2
class CEnvState : public CPointEntity
{
public:
void Spawn( void );
void Think( void );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
BOOL IsLockedByMaster( void ) { return !UTIL_IsMasterTriggered(m_sMaster, NULL); };
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
virtual STATE GetState() { return m_iState; }
static TYPEDESCRIPTION m_SaveData[];
STATE m_iState;
float m_fTurnOnTime;
float m_fTurnOffTime;
int m_sMaster;
};
void CEnvState::Spawn( void )
{
if (pev->spawnflags & SF_ENVSTATE_START_ON)
m_iState = STATE_ON;
else
m_iState = STATE_OFF;
}
TYPEDESCRIPTION CEnvState::m_SaveData[] =
{
DEFINE_FIELD( CEnvState, m_iState, FIELD_INTEGER ),
DEFINE_FIELD( CEnvState, m_fTurnOnTime, FIELD_INTEGER ),
DEFINE_FIELD( CEnvState, m_fTurnOffTime, FIELD_INTEGER ),
DEFINE_FIELD( CEnvState, m_sMaster, FIELD_STRING ),
};
IMPLEMENT_SAVERESTORE( CEnvState, CPointEntity );
LINK_ENTITY_TO_CLASS( env_state, CEnvState );
void CEnvState::KeyValue( KeyValueData *pkvd )
{
pkvd->fHandled = TRUE;
if ( FStrEq(pkvd->szKeyName, "turnontime") )
m_fTurnOnTime = atof( pkvd->szValue );
else if ( FStrEq(pkvd->szKeyName, "turnofftime") )
m_fTurnOffTime = atof( pkvd->szValue );
else if ( FStrEq(pkvd->szKeyName, "master") )
m_sMaster = ALLOC_STRING( pkvd->szValue );
else
CPointEntity::KeyValue( pkvd );
}
void CEnvState::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (!ShouldToggle(useType) || IsLockedByMaster())
{
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" ",STRING(pev->targetname));
if (IsLockedByMaster())
ALERT(at_debug,"ignored trigger %s; locked by master \"%s\".\n",GetStringForUseType(useType),STRING(m_sMaster));
else if (useType == USE_ON)
ALERT(at_debug,"ignored trigger USE_ON; already on\n");
else if (useType == USE_OFF)
ALERT(at_debug,"ignored trigger USE_OFF; already off\n");
else
ALERT(at_debug,"ignored trigger %s.\n",GetStringForUseType(useType));
}
return;
}
switch (GetState())
{
case STATE_ON:
case STATE_TURN_ON:
if (m_fTurnOffTime)
{
m_iState = STATE_TURN_OFF;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" triggered; will turn off in %f seconds.\n", STRING(pev->targetname), m_fTurnOffTime);
}
SetNextThink( m_fTurnOffTime );
}
else
{
m_iState = STATE_OFF;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" triggered, turned off", STRING(pev->targetname));
if (pev->target)
{
ALERT(at_debug,": firing \"%s\"",STRING(pev->target));
if (pev->noise2)
ALERT(at_debug," and \"%s\"",STRING(pev->noise2));
}
else if (pev->noise2)
ALERT(at_debug,": firing \"%s\"",STRING(pev->noise2));
ALERT(at_debug,".\n");
}
FireTargets(STRING(pev->target),pActivator,this,USE_OFF,0);
FireTargets(STRING(pev->noise2),pActivator,this,USE_TOGGLE,0);
DontThink();
}
break;
case STATE_OFF:
case STATE_TURN_OFF:
if (m_fTurnOnTime)
{
m_iState = STATE_TURN_ON;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" triggered; will turn on in %f seconds.\n", STRING(pev->targetname), m_fTurnOnTime);
}
SetNextThink( m_fTurnOnTime );
}
else
{
m_iState = STATE_ON;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" triggered, turned on",STRING(pev->targetname));
if (pev->target)
{
ALERT(at_debug,": firing \"%s\"",STRING(pev->target));
if (pev->noise1)
ALERT(at_debug," and \"%s\"",STRING(pev->noise1));
}
else if (pev->noise1)
ALERT(at_debug,": firing \"%s\"", STRING(pev->noise1));
ALERT(at_debug,".\n");
}
FireTargets(STRING(pev->target),pActivator,this,USE_ON,0);
FireTargets(STRING(pev->noise1),pActivator,this,USE_TOGGLE,0);
DontThink();
}
break;
}
}
void CEnvState::Think( void )
{
if (m_iState == STATE_TURN_ON)
{
m_iState = STATE_ON;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" turned itself on",STRING(pev->targetname));
if (pev->target)
{
ALERT(at_debug,": firing %s",STRING(pev->target));
if (pev->noise1)
ALERT(at_debug," and %s",STRING(pev->noise1));
}
else if (pev->noise1)
ALERT(at_debug,": firing %s",STRING(pev->noise1));
ALERT(at_debug,".\n");
}
FireTargets(STRING(pev->target),this,this,USE_ON,0);
FireTargets(STRING(pev->noise1),this,this,USE_TOGGLE,0);
}
else if (m_iState == STATE_TURN_OFF)
{
m_iState = STATE_OFF;
if (pev->spawnflags & SF_ENVSTATE_DEBUG)
{
ALERT(at_debug,"DEBUG: env_state \"%s\" turned itself off",STRING(pev->targetname));
if (pev->target)
ALERT(at_debug,": firing %s",STRING(pev->target));
if (pev->noise2)
ALERT(at_debug," and %s",STRING(pev->noise2));
else if (pev->noise2)
ALERT(at_debug,": firing %s",STRING(pev->noise2));
ALERT(at_debug,".\n");
}
FireTargets(STRING(pev->target),this,this,USE_OFF,0);
FireTargets(STRING(pev->noise2),this,this,USE_TOGGLE,0);
}
}
//===========================
//LRC- the evil multisource...
//===========================
TYPEDESCRIPTION CMultiSource::m_SaveData[] =
{
@ -374,8 +163,7 @@ void CMultiSource::KeyValue( KeyValueData *pkvd )
CPointEntity::KeyValue( pkvd );
}
#define SF_MULTI_FIREONCLOSE 1
#define SF_MULTI_INIT 2
#define SF_MULTI_INIT 1
void CMultiSource::Spawn()
{
@ -383,9 +171,9 @@ void CMultiSource::Spawn()
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
pev->spawnflags |= SF_MULTI_INIT; // Until it's initialized
SetThink(&CMultiSource::Register);
SetThink(Register);
}
void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
@ -400,40 +188,17 @@ void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
// if we didn't find it, report error and leave
if (i > m_iTotal)
{
if (pCaller->pev->targetname)
ALERT(at_debug, "multisource \"%s\": Used by non-member %s \"%s\"\n", STRING(pev->targetname), STRING(pCaller->pev->classname), STRING(pCaller->pev->targetname));
else
ALERT(at_debug, "multisource \"%s\": Used by non-member %s\n", STRING(pev->targetname), STRING(pCaller->pev->classname));
ALERT(at_console, "MultiSrc:Used by non member %s.\n", STRING(pCaller->pev->classname));
return;
}
// CONSIDER: a Use input to the multisource always toggles. Could check useType for ON/OFF/TOGGLE
// LRC- On could be meaningful. Off, sadly, can't work in the obvious manner.
// LRC (09/06/01)- er... why not?
// LRC (28/04/02)- that depends what the "obvious" manner is.
// store the state before the change, so we can compare it to the new state
STATE s = GetState();
// do the change
m_rgTriggered[i-1] ^= 1;
// did we change state?
if ( s == GetState() )
return;
if ( s == STATE_ON && pev->netname)
//
if ( IsTriggered( pActivator ) )
{
// the change disabled me and I have a "fire on disable" field
ALERT( at_aiconsole, "Multisource %s deactivated (%d inputs)\n", STRING(pev->targetname), m_iTotal );
if ( m_globalstate )
FireTargets( STRING(pev->netname), NULL, this, USE_OFF, 0 );
else
FireTargets( STRING(pev->netname), NULL, this, USE_TOGGLE, 0 );
}
else if ( s == STATE_OFF )
{
// the change activated me
ALERT( at_aiconsole, "Multisource %s enabled (%d inputs)\n", STRING(pev->targetname), m_iTotal );
USE_TYPE useType = USE_TOGGLE;
if ( m_globalstate )
@ -443,15 +208,14 @@ void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
}
//LRC- while we're in STATE_OFF, mastered entities can't do anything.
STATE CMultiSource::GetState( void )
BOOL CMultiSource::IsTriggered( CBaseEntity * )
{
// Is everything triggered?
int i = 0;
// Still initializing?
if ( pev->spawnflags & SF_MULTI_INIT )
return STATE_OFF;
return 0;
while (i < m_iTotal)
{
@ -463,12 +227,12 @@ STATE CMultiSource::GetState( void )
if (i == m_iTotal)
{
if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON )
return STATE_ON;
return 1;
}
return STATE_OFF;
return 0;
}
/*
void CMultiSource::Register(void)
{
edict_t *pentTarget = NULL;
@ -476,7 +240,7 @@ void CMultiSource::Register(void)
m_iTotal = 0;
memset( m_rgEntities, 0, MS_MAX_TARGETS * sizeof(EHANDLE) );
SetThink(&CMultiSource::SUB_DoNothing);
SetThink(SUB_DoNothing);
// search for all entities which target this multisource (pev->targetname)
@ -503,54 +267,8 @@ void CMultiSource::Register(void)
pev->spawnflags &= ~SF_MULTI_INIT;
}
*/
void CMultiSource::Register(void)
{
m_iTotal = 0;
memset( m_rgEntities, 0, MS_MAX_TARGETS * sizeof(EHANDLE) );
SetThink(&CMultiSource::SUB_DoNothing);
// search for all entities which target this multisource (pev->targetname)
CBaseEntity *pTarget = UTIL_FindEntityByTarget( NULL, STRING(pev->targetname) );
while (pTarget && (m_iTotal < MS_MAX_TARGETS))
{
m_rgEntities[m_iTotal++] = pTarget;
pTarget = UTIL_FindEntityByTarget( pTarget, STRING(pev->targetname));
}
pTarget = UTIL_FindEntityByClassname(NULL, "multi_manager");
while (pTarget && (m_iTotal < MS_MAX_TARGETS))
{
if ( pTarget->HasTarget(pev->targetname) )
m_rgEntities[m_iTotal++] = pTarget;
pTarget = UTIL_FindEntityByClassname( pTarget, "multi_manager" );
}
if (m_iTotal >= MS_MAX_TARGETS)
{
ALERT(at_debug,"WARNING: There are too many entities targetting multisource \"%s\". (limit is %d)\n", STRING(pev->targetname), MS_MAX_TARGETS);
}
pev->spawnflags &= ~SF_MULTI_INIT;
}
//===================================
// func_button (= CBaseButton)
//===================================
//LRC - moved here from cbase.h to use the spawnflags defined in this file
// Buttons that don't take damage can be IMPULSE used
int CBaseButton::ObjectCaps( void )
{
return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) |
(pev->takedamage?0:FCAP_IMPULSE_USE) |
(pev->spawnflags & SF_BUTTON_ONLYDIRECT?FCAP_ONLYDIRECT_USE:0);
}
// CBaseButton
TYPEDESCRIPTION CBaseButton::m_SaveData[] =
{
DEFINE_FIELD( CBaseButton, m_fStayPushed, FIELD_BOOLEAN ),
@ -737,27 +455,15 @@ void CBaseButton::Spawn( )
if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state
{
SetThink(&CBaseButton:: ButtonSpark );
SetNextThink( 0.5 );// no hurry, make sure everything else spawns
SetThink ( ButtonSpark );
pev->nextthink = gpGlobals->time + 0.5;// no hurry, make sure everything else spawns
}
SetMovedir(pev);
pev->movetype = MOVETYPE_PUSH;
if ( FBitSet ( pev->spawnflags, SF_BUTTON_NOT_SOLID ) )
{
pev->solid = SOLID_NOT;
pev->skin = CONTENTS_EMPTY;
}
else
{
pev->solid = SOLID_BSP;
}
pev->solid = SOLID_BSP;
SET_MODEL(ENT(pev), STRING(pev->model));
//LRC
if (m_iStyle >= 32) LIGHT_STYLE(m_iStyle, "z");
else if (m_iStyle <= -32) LIGHT_STYLE(-m_iStyle, "a");
if (pev->speed == 0)
pev->speed = 40;
@ -789,36 +495,15 @@ void CBaseButton::Spawn( )
if ( FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // touchable button
{
SetTouch(&CBaseButton:: ButtonTouch );
if ( !FBitSet ( pev->spawnflags, SF_BUTTON_USEKEY ) )
SetUse(&CBaseButton:: ButtonUse_IgnorePlayer );
else
SetUse(&CBaseButton:: ButtonUse );
SetTouch( ButtonTouch );
}
else
{
SetTouch ( NULL );
if ( FBitSet ( pev->spawnflags, SF_BUTTON_USEKEY ) )
SetUse(&CBaseButton:: ButtonUse_IgnorePlayer );
else
SetUse(&CBaseButton:: ButtonUse );
SetUse ( ButtonUse );
}
}
//LRC
void CBaseButton :: PostSpawn( void )
{
if (m_pMoveWith)
m_vecPosition1 = pev->origin - m_pMoveWith->pev->origin;
else
m_vecPosition1 = pev->origin;
// Subtract 2 from size because the engine expands bboxes by 1 in all directions
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip));
// Is this a non-moving button?
if ( ((m_vecPosition2 - m_vecPosition1).Length() < 1) || (pev->spawnflags & SF_BUTTON_DONTMOVE) )
m_vecPosition2 = m_vecPosition1;
}
// Button sound table.
// Also used by CBaseDoor to get 'touched' door lock/unlock sounds
@ -868,7 +553,7 @@ void DoSpark(entvars_t *pev, const Vector &location )
Vector tmp = location + pev->size * 0.5;
UTIL_Sparks( tmp );
float flVolume = RANDOM_FLOAT ( 0.1 , 0.25 ) * 0.4;//random volume range
float flVolume = RANDOM_FLOAT ( 0.25 , 0.75 ) * 0.4;//random volume range
switch ( (int)(RANDOM_FLOAT(0,1) * 6) )
{
case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark1.wav", flVolume, ATTN_NORM); break;
@ -882,8 +567,8 @@ void DoSpark(entvars_t *pev, const Vector &location )
void CBaseButton::ButtonSpark ( void )
{
SetThink(&CBaseButton:: ButtonSpark );
SetNextThink( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval
SetThink ( ButtonSpark );
pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval
DoSpark( pev, pev->mins );
}
@ -914,12 +599,6 @@ void CBaseButton::ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE
ButtonActivate( );
}
//LRC - they had it set up so that a touch-only button couldn't even be triggered!?
void CBaseButton::ButtonUse_IgnorePlayer ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if ( !pCaller || !pCaller->IsPlayer() )
ButtonUse( pActivator, pCaller, useType, value );
}
CBaseButton::BUTTON_CODE CBaseButton::ButtonResponseToTouch( void )
{
@ -1001,21 +680,11 @@ void CBaseButton::ButtonActivate( )
ASSERT(m_toggle_state == TS_AT_BOTTOM);
m_toggle_state = TS_GOING_UP;
//LRC - unhelpfully, SF_BUTTON_DONTMOVE is the same value as
// SF_ROTBUTTON_NOTSOLID, so we have to assume that a rotbutton will
// never be DONTMOVE.
if (pev->spawnflags & SF_BUTTON_DONTMOVE && !m_fRotating)
{
TriggerAndWait();
}
SetMoveDone( TriggerAndWait );
if (!m_fRotating)
LinearMove( m_vecPosition2, pev->speed);
else
{
SetMoveDone(&CBaseButton:: TriggerAndWait );
if (!m_fRotating)
LinearMove( m_vecPosition2, pev->speed);
else
AngularMove( m_vecAngle2, pev->speed);
}
AngularMove( m_vecAngle2, pev->speed);
}
//
@ -1030,13 +699,6 @@ void CBaseButton::TriggerAndWait( void )
m_toggle_state = TS_AT_TOP;
pev->frame = 1; // use alternate textures
//LRC
if (m_iStyle >= 32) LIGHT_STYLE(m_iStyle, "a");
else if (m_iStyle <= -32) LIGHT_STYLE(-m_iStyle, "z");
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
// If button automatically comes back out, start it moving out.
// Else re-instate touch method
if (m_fStayPushed || FBitSet ( pev->spawnflags, SF_BUTTON_TOGGLE ) )
@ -1047,20 +709,18 @@ void CBaseButton::TriggerAndWait( void )
SetTouch ( NULL );
}
else
SetTouch(&CBaseButton:: ButtonTouch );
SetTouch( ButtonTouch );
}
else
{
SetThink(&CBaseButton:: ButtonReturn );
if ( m_flWait )
{
SetNextThink( m_flWait );
}
else
{
ButtonReturn();
}
pev->nextthink = pev->ltime + m_flWait;
SetThink( ButtonReturn );
}
pev->frame = 1; // use alternate textures
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
}
@ -1072,24 +732,13 @@ void CBaseButton::ButtonReturn( void )
ASSERT(m_toggle_state == TS_AT_TOP);
m_toggle_state = TS_GOING_DOWN;
pev->frame = 0; // use normal textures
//LRC
if (m_iStyle >= 32) LIGHT_STYLE(m_iStyle, "z");
else if (m_iStyle <= -32) LIGHT_STYLE(-m_iStyle, "a");
if (pev->spawnflags & SF_BUTTON_DONTMOVE)
{
ButtonBackHome();
}
SetMoveDone( ButtonBackHome );
if (!m_fRotating)
LinearMove( m_vecPosition1, pev->speed);
else
{
SetMoveDone(&CBaseButton:: ButtonBackHome );
if (!m_fRotating)
LinearMove( m_vecPosition1, pev->speed);
else
AngularMove( m_vecAngle1, pev->speed);
}
AngularMove( m_vecAngle1, pev->speed);
pev->frame = 0; // use normal textures
}
@ -1111,19 +760,20 @@ void CBaseButton::ButtonBackHome( void )
if (!FStringNull(pev->target))
{
CBaseEntity *pTarget = NULL;
edict_t* pentTarget = NULL;
for (;;)
{
pTarget = UTIL_FindEntityByTargetname(pTarget, STRING(pev->target), m_hActivator);
pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target));
if (FNullEnt(pTarget))
if (FNullEnt(pentTarget))
break;
if (!FClassnameIs(pTarget->pev, "multisource"))
// LRC- hmm... I see. On returning, a button will only turn off multisources.
if (!FClassnameIs(pentTarget, "multisource"))
continue;
CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget );
pTarget->Use( m_hActivator, this, USE_TOGGLE, 0 );
if ( pTarget )
pTarget->Use( m_hActivator, this, USE_TOGGLE, 0 );
}
}
@ -1134,17 +784,13 @@ void CBaseButton::ButtonBackHome( void )
SetTouch ( NULL );
}
else
SetTouch(&CBaseButton:: ButtonTouch );
SetTouch( ButtonTouch );
// reset think for a sparking button
if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )
{
SetThink(&CBaseButton:: ButtonSpark );
SetNextThink( 0.5 );// no hurry.
}
else
{
DontThink();
SetThink ( ButtonSpark );
pev->nextthink = gpGlobals->time + 0.5;// no hurry.
}
}
@ -1157,23 +803,10 @@ class CRotButton : public CBaseButton
{
public:
void Spawn( void );
void PostSpawn( void ) {} // don't use the moveWith fix from CBaseButton
virtual void KeyValue( KeyValueData* pkvd);
};
LINK_ENTITY_TO_CLASS( func_rot_button, CRotButton );
void CRotButton::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "axes"))
{
UTIL_StringToVector( (float*)(pev->movedir), pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CBaseButton::KeyValue( pkvd );
}
void CRotButton::Spawn( void )
{
char *pszSound;
@ -1224,19 +857,10 @@ void CRotButton::Spawn( void )
if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) )
{
SetTouch ( NULL );
if ( FBitSet ( pev->spawnflags, SF_BUTTON_USEKEY ) )
SetUse(&CRotButton:: ButtonUse_IgnorePlayer );
else
SetUse(&CRotButton:: ButtonUse );
SetUse ( ButtonUse );
}
else // touchable button
{
SetTouch(&CRotButton:: ButtonTouch );
if ( !FBitSet ( pev->spawnflags, SF_BUTTON_USEKEY ) )
SetUse(&CRotButton:: ButtonUse_IgnorePlayer );
else
SetUse(&CRotButton:: ButtonUse );
}
SetTouch( ButtonTouch );
//SetTouch( ButtonTouch );
}
@ -1324,7 +948,7 @@ void CMomentaryRotButton::Spawn( void )
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(this, pev->origin);
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model) );
char *pszSound = ButtonSound( m_sounds );
@ -1345,11 +969,6 @@ void CMomentaryRotButton::KeyValue( KeyValueData *pkvd )
m_sounds = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "axes"))
{
UTIL_StringToVector((float*)(pev->movedir), pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseToggle::KeyValue( pkvd );
}
@ -1364,36 +983,33 @@ void CMomentaryRotButton::PlaySound( void )
// current, not future position.
void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (IsLockedByMaster()) return; //LRC
// the distance between the current angle and the "base" angle.
pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance;
UpdateAllButtons( pev->ideal_yaw, 1 );
float f = m_fNextThink - pev->ltime;
f = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles + pev->avelocity*f, m_start ) / m_flMoveDistance;
// ALERT(at_console,"sending update = %f\n", f);
UpdateTarget( f );
UpdateTarget( pev->ideal_yaw );
}
void CMomentaryRotButton::UpdateAllButtons( float value, int start )
{
// Update all rot buttons attached to my target
// (this includes myself)
CBaseEntity *pTarget = NULL;
// Update all rot buttons attached to the same target
edict_t *pentTarget = NULL;
for (;;)
{
pTarget = UTIL_FindEntityByTarget(pTarget, STRING(pev->target));
if (FNullEnt(pTarget))
pentTarget = FIND_ENTITY_BY_STRING(pentTarget, "target", STRING(pev->target));
if (FNullEnt(pentTarget))
break;
if ( FClassnameIs( pTarget->pev, "momentary_rot_button" ) )
if ( FClassnameIs( VARS(pentTarget), "momentary_rot_button" ) )
{
CMomentaryRotButton *pEntity = (CMomentaryRotButton*)pTarget;
if ( start )
pEntity->UpdateSelf( value );
else
pEntity->UpdateSelfReturn( value );
CMomentaryRotButton *pEntity = CMomentaryRotButton::Instance(pentTarget);
if ( pEntity )
{
if ( start )
pEntity->UpdateSelf( value );
else
pEntity->UpdateSelfReturn( value );
}
}
}
}
@ -1409,17 +1025,14 @@ void CMomentaryRotButton::UpdateSelf( float value )
}
m_lastUsed = 1;
SetNextThink( 0.1 );
//LRC check if we're outside the boundaries
pev->nextthink = pev->ltime + 0.1;
if ( m_direction > 0 && value >= 1.0 )
{
pev->avelocity = g_vecZero;
pev->angles = m_end;
return;
}
if ( m_direction < 0 && value <= 0 )
else if ( m_direction < 0 && value <= 0 )
{
pev->avelocity = g_vecZero;
pev->angles = m_start;
@ -1429,32 +1042,31 @@ void CMomentaryRotButton::UpdateSelf( float value )
if (fplaysound)
PlaySound();
// HACKHACK -- If we're going slow, we'll get multiple player packets per frame;
// bump nexthink on each one to avoid stalling
//LRC- that is to say: our avelocity will get us to the target point in 0.1 secs.
// If we're being told to move further than that, wait that much longer.
if ( m_fNextThink < pev->ltime )
SetNextThink( 0.1 );
// HACKHACK -- If we're going slow, we'll get multiple player packets per frame, bump nexthink on each one to avoid stalling
if ( pev->nextthink < pev->ltime )
pev->nextthink = pev->ltime + 0.1;
else
{
AbsoluteNextThink( m_fNextThink + 0.1 );
}
pev->nextthink += 0.1;
pev->avelocity = (m_direction * pev->speed) * pev->movedir;
SetThink(&CMomentaryRotButton:: Off );
SetThink( Off );
}
void CMomentaryRotButton::UpdateTarget( float value )
{
if (!FStringNull(pev->target))
{
CBaseEntity* pTarget = NULL;
edict_t* pentTarget = NULL;
for (;;)
{
pTarget = UTIL_FindEntityByTargetname(pTarget, STRING(pev->target));
if ( !pTarget )
pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target));
if (FNullEnt(pentTarget))
break;
pTarget->Use( this, this, USE_SET, value );
CBaseEntity *pEntity = CBaseEntity::Instance(pentTarget);
if ( pEntity )
{
pEntity->Use( this, this, USE_SET, value );
}
}
}
}
@ -1465,8 +1077,8 @@ void CMomentaryRotButton::Off( void )
m_lastUsed = 0;
if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) && m_returnSpeed > 0 )
{
SetThink(&CMomentaryRotButton:: Return );
SetNextThink( 0.1 );
SetThink( Return );
pev->nextthink = pev->ltime + 0.1;
m_direction = -1;
}
else
@ -1489,13 +1101,13 @@ void CMomentaryRotButton::UpdateSelfReturn( float value )
{
pev->avelocity = g_vecZero;
pev->angles = m_start;
DontThink();
pev->nextthink = -1;
SetThink( NULL );
}
else
{
pev->avelocity = -m_returnSpeed * pev->movedir;
SetNextThink( 0.1 );
pev->nextthink = pev->ltime + 0.1;
}
}
@ -1520,15 +1132,12 @@ public:
static TYPEDESCRIPTION m_SaveData[];
float m_flDelay;
STATE m_iState; //LRC
virtual STATE GetState( void ) { return m_iState; };
};
TYPEDESCRIPTION CEnvSpark::m_SaveData[] =
{
DEFINE_FIELD( CEnvSpark, m_flDelay, FIELD_FLOAT),
DEFINE_FIELD( CEnvSpark, m_iState, FIELD_INTEGER), //LRC
};
IMPLEMENT_SAVERESTORE( CEnvSpark, CBaseEntity );
@ -1545,21 +1154,21 @@ void CEnvSpark::Spawn(void)
{
if (FBitSet(pev->spawnflags, 64)) // Start on
{
SetThink(&CEnvSpark::SparkThink); // start sparking
SetUse(&CEnvSpark::SparkStop); // set up +USE to stop sparking
SetThink(SparkThink); // start sparking
SetUse(SparkStop); // set up +USE to stop sparking
}
else
SetUse(&CEnvSpark::SparkStart);
SetUse(SparkStart);
}
else
SetThink(&CEnvSpark::SparkThink);
SetThink(SparkThink);
SetNextThink( 0.1 + RANDOM_FLOAT (0, 1.5) );
pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );
if (m_flDelay <= 0)
m_flDelay = 1.5;
Precache( );
Precache( );
}
@ -1593,25 +1202,22 @@ void CEnvSpark::KeyValue( KeyValueData *pkvd )
void EXPORT CEnvSpark::SparkThink(void)
{
SetNextThink( 0.1 + RANDOM_FLOAT (0, m_flDelay) );
pev->nextthink = gpGlobals->time + 0.1 + RANDOM_FLOAT (0, m_flDelay);
DoSpark( pev, pev->origin );
}
void EXPORT CEnvSpark::SparkStart(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetUse(&CEnvSpark::SparkStop);
SetThink(&CEnvSpark::SparkThink);
m_iState = STATE_ON; //LRC
SetNextThink( 0.1 + RANDOM_FLOAT ( 0, m_flDelay) );
SetUse(SparkStop);
SetThink(SparkThink);
pev->nextthink = gpGlobals->time + (0.1 + RANDOM_FLOAT ( 0, m_flDelay));
}
void EXPORT CEnvSpark::SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetUse(&CEnvSpark::SparkStart);
SetUse(SparkStart);
SetThink(NULL);
m_iState = STATE_OFF; //LRC
}
//G-Cont. flag 16 is removed - we don't need this
#define SF_BTARGET_USE 0x0001
#define SF_BTARGET_ON 0x0002

774
dlls/cbase.cpp Normal file
View File

@ -0,0 +1,774 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "saverestore.h"
#include "client.h"
#include "decals.h"
#include "gamerules.h"
#include "game.h"
void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd );
extern void PM_Move ( struct playermove_s *ppmove, int server );
extern void PM_Init ( struct playermove_s *ppmove );
extern char PM_FindTextureType( char *name );
extern Vector VecBModelOrigin( entvars_t* pevBModel );
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL int g_iSkillLevel;
static DLL_FUNCTIONS gFunctionTable =
{
GameDLLInit, //pfnGameInit
DispatchSpawn, //pfnSpawn
DispatchThink, //pfnThink
DispatchUse, //pfnUse
DispatchTouch, //pfnTouch
DispatchBlocked, //pfnBlocked
DispatchKeyValue, //pfnKeyValue
DispatchSave, //pfnSave
DispatchRestore, //pfnRestore
DispatchObjectCollsionBox, //pfnAbsBox
SaveWriteFields, //pfnSaveWriteFields
SaveReadFields, //pfnSaveReadFields
SaveGlobalState, //pfnSaveGlobalState
RestoreGlobalState, //pfnRestoreGlobalState
ResetGlobalState, //pfnResetGlobalState
ClientConnect, //pfnClientConnect
ClientDisconnect, //pfnClientDisconnect
ClientKill, //pfnClientKill
ClientPutInServer, //pfnClientPutInServer
ClientCommand, //pfnClientCommand
ClientUserInfoChanged, //pfnClientUserInfoChanged
ServerActivate, //pfnServerActivate
ServerDeactivate, //pfnServerDeactivate
PlayerPreThink, //pfnPlayerPreThink
PlayerPostThink, //pfnPlayerPostThink
StartFrame, //pfnStartFrame
ParmsNewLevel, //pfnParmsNewLevel
ParmsChangeLevel, //pfnParmsChangeLevel
GetGameDescription, //pfnGetGameDescription Returns string describing current .dll game.
PlayerCustomization, //pfnPlayerCustomization Notifies .dll of new customization for player.
SpectatorConnect, //pfnSpectatorConnect Called when spectator joins server
SpectatorDisconnect, //pfnSpectatorDisconnect Called when spectator leaves the server
SpectatorThink, //pfnSpectatorThink Called when spectator sends a command packet (usercmd_t)
Sys_Error, //pfnSys_Error Called when engine has encountered an error
PM_Move, //pfnPM_Move
PM_Init, //pfnPM_Init Server version of player movement initialization
PM_FindTextureType, //pfnPM_FindTextureType
SetupVisibility, //pfnSetupVisibility Set up PVS and PAS for networking for this client
UpdateClientData, //pfnUpdateClientData Set up data sent only to specific client
AddToFullPack, //pfnAddToFullPack
CreateBaseline, //pfnCreateBaseline Tweak entity baseline for network encoding, allows setup of player baselines, too.
RegisterEncoders, //pfnRegisterEncoders Callbacks for network encoding
GetWeaponData, //pfnGetWeaponData
CmdStart, //pfnCmdStart
CmdEnd, //pfnCmdEnd
ConnectionlessPacket, //pfnConnectionlessPacket
GetHullBounds, //pfnGetHullBounds
CreateInstancedBaselines, //pfnCreateInstancedBaselines
InconsistentFile, //pfnInconsistentFile
AllowLagCompensation, //pfnAllowLagCompensation
};
static void SetObjectCollisionBox( entvars_t *pev );
#ifndef _WIN32
extern "C" {
#endif
int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion )
{
if ( !pFunctionTable || interfaceVersion != INTERFACE_VERSION )
{
return FALSE;
}
memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) );
return TRUE;
}
int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion )
{
if ( !pFunctionTable || *interfaceVersion != INTERFACE_VERSION )
{
// Tell engine what version we had, so it can figure out who is out of date.
*interfaceVersion = INTERFACE_VERSION;
return FALSE;
}
memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) );
return TRUE;
}
#ifndef _WIN32
}
#endif
int DispatchSpawn( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity)
{
// Initialize these or entities who don't link to the world won't have anything in here
pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1);
pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1);
pEntity->Spawn();
// Try to get the pointer again, in case the spawn function deleted the entity.
// UNDONE: Spawn() should really return a code to ask that the entity be deleted, but
// that would touch too much code for me to do that right now.
pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if ( pEntity )
{
if ( g_pGameRules && !g_pGameRules->IsAllowedToSpawn( pEntity ) )
return -1; // return that this entity should be deleted
if ( pEntity->pev->flags & FL_KILLME )
return -1;
}
// Handle global stuff here
if ( pEntity && pEntity->pev->globalname )
{
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname );
if ( pGlobal )
{
// Already dead? delete
if ( pGlobal->state == GLOBAL_DEAD )
return -1;
else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) )
pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive
// In this level & not dead, continue on as normal
}
else
{
// Spawned entities default to 'On'
gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON );
// ALERT( at_console, "Added global entity %s (%s)\n", STRING(pEntity->pev->classname), STRING(pEntity->pev->globalname) );
}
}
}
return 0;
}
void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd )
{
if ( !pkvd || !pentKeyvalue )
return;
EntvarsKeyvalue( VARS(pentKeyvalue), pkvd );
// If the key was an entity variable, or there's no class set yet, don't look for the object, it may
// not exist yet.
if ( pkvd->fHandled || pkvd->szClassName == NULL )
return;
// Get the actualy entity object
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentKeyvalue);
if ( !pEntity )
return;
pEntity->KeyValue( pkvd );
}
// HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers)
// while it builds the graph
BOOL gTouchDisabled = FALSE;
void DispatchTouch( edict_t *pentTouched, edict_t *pentOther )
{
if ( gTouchDisabled )
return;
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther );
if ( pEntity && pOther && ! ((pEntity->pev->flags | pOther->pev->flags) & FL_KILLME) )
pEntity->Touch( pOther );
}
void DispatchUse( edict_t *pentUsed, edict_t *pentOther )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed);
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther);
if (pEntity && !(pEntity->pev->flags & FL_KILLME) )
pEntity->Use( pOther, pOther, USE_TOGGLE, 0 );
}
void DispatchThink( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity)
{
if ( FBitSet( pEntity->pev->flags, FL_DORMANT ) )
ALERT( at_error, "Dormant entity %s is thinking!!\n", STRING(pEntity->pev->classname) );
pEntity->Think();
}
}
void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE( pentBlocked );
CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther );
if (pEntity)
pEntity->Blocked( pOther );
}
void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if ( pEntity && pSaveData )
{
ENTITYTABLE *pTable = &pSaveData->pTable[ pSaveData->currentIndex ];
if ( pTable->pent != pent )
ALERT( at_error, "ENTITY TABLE OR INDEX IS WRONG!!!!\n" );
if ( pEntity->ObjectCaps() & FCAP_DONT_SAVE )
return;
// These don't use ltime & nextthink as times really, but we'll fudge around it.
if ( pEntity->pev->movetype == MOVETYPE_PUSH )
{
float delta = pEntity->pev->nextthink - pEntity->pev->ltime;
pEntity->pev->ltime = gpGlobals->time;
pEntity->pev->nextthink = pEntity->pev->ltime + delta;
}
pTable->location = pSaveData->size; // Remember entity position for file I/O
pTable->classname = pEntity->pev->classname; // Remember entity class for respawn
CSave saveHelper( pSaveData );
pEntity->Save( saveHelper );
pTable->size = pSaveData->size - pTable->location; // Size of entity block is data size written to block
}
}
// Find the matching global entity. Spit out an error if the designer made entities of
// different classes with the same global name
CBaseEntity *FindGlobalEntity( string_t classname, string_t globalname )
{
edict_t *pent = FIND_ENTITY_BY_STRING( NULL, "globalname", STRING(globalname) );
CBaseEntity *pReturn = CBaseEntity::Instance( pent );
if ( pReturn )
{
if ( !FClassnameIs( pReturn->pev, STRING(classname) ) )
{
ALERT( at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname) );
pReturn = NULL;
}
}
return pReturn;
}
int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if ( pEntity && pSaveData )
{
entvars_t tmpVars;
Vector oldOffset;
CRestore restoreHelper( pSaveData );
if ( globalEntity )
{
CRestore tmpRestore( pSaveData );
tmpRestore.PrecacheMode( 0 );
tmpRestore.ReadEntVars( "ENTVARS", &tmpVars );
// HACKHACK - reset the save pointers, we're going to restore for real this time
pSaveData->size = pSaveData->pTable[pSaveData->currentIndex].location;
pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size;
// -------------------
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( tmpVars.globalname );
// Don't overlay any instance of the global that isn't the latest
// pSaveData->szCurrentMapName is the level this entity is coming from
// pGlobla->levelName is the last level the global entity was active in.
// If they aren't the same, then this global update is out of date.
if ( !FStrEq( pSaveData->szCurrentMapName, pGlobal->levelName ) )
return 0;
// Compute the new global offset
oldOffset = pSaveData->vecLandmarkOffset;
CBaseEntity *pNewEntity = FindGlobalEntity( tmpVars.classname, tmpVars.globalname );
if ( pNewEntity )
{
// ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) );
// Tell the restore code we're overlaying a global entity from another level
restoreHelper.SetGlobalMode( 1 ); // Don't overwrite global fields
pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins;
pEntity = pNewEntity;// we're going to restore this data OVER the old entity
pent = ENT( pEntity->pev );
// Update the global table to say that the global definition of this entity should come from this level
gGlobalState.EntityUpdate( pEntity->pev->globalname, gpGlobals->mapname );
}
else
{
// This entity will be freed automatically by the engine. If we don't do a restore on a matching entity (below)
// or call EntityUpdate() to move it to this level, we haven't changed global state at all.
return 0;
}
}
if ( pEntity->ObjectCaps() & FCAP_MUST_SPAWN )
{
pEntity->Restore( restoreHelper );
pEntity->Spawn();
}
else
{
pEntity->Restore( restoreHelper );
pEntity->Precache( );
}
// Again, could be deleted, get the pointer again.
pEntity = (CBaseEntity *)GET_PRIVATE(pent);
#if 0
if ( pEntity && pEntity->pev->globalname && globalEntity )
{
ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) );
}
#endif
// Is this an overriding global entity (coming over the transition), or one restoring in a level
if ( globalEntity )
{
// ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) );
pSaveData->vecLandmarkOffset = oldOffset;
if ( pEntity )
{
UTIL_SetOrigin( pEntity->pev, pEntity->pev->origin );
pEntity->OverrideReset();
}
}
else if ( pEntity && pEntity->pev->globalname )
{
const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname );
if ( pGlobal )
{
// Already dead? delete
if ( pGlobal->state == GLOBAL_DEAD )
return -1;
else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) )
{
pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive
}
// In this level & not dead, continue on as normal
}
else
{
ALERT( at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname) );
// Spawned entities default to 'On'
gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON );
}
}
}
return 0;
}
void DispatchObjectCollsionBox( edict_t *pent )
{
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
if (pEntity)
{
pEntity->SetObjectCollisionBox();
}
else
SetObjectCollisionBox( &pent->v );
}
void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount )
{
CSave saveHelper( pSaveData );
saveHelper.WriteFields( pname, pBaseData, pFields, fieldCount );
}
void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount )
{
CRestore restoreHelper( pSaveData );
restoreHelper.ReadFields( pname, pBaseData, pFields, fieldCount );
}
edict_t * EHANDLE::Get( void )
{
if (m_pent)
{
if (m_pent->serialnumber == m_serialnumber)
return m_pent;
else
return NULL;
}
return NULL;
};
edict_t * EHANDLE::Set( edict_t *pent )
{
m_pent = pent;
if (pent)
m_serialnumber = m_pent->serialnumber;
return pent;
};
EHANDLE :: operator CBaseEntity *()
{
return (CBaseEntity *)GET_PRIVATE( Get( ) );
};
CBaseEntity * EHANDLE :: operator = (CBaseEntity *pEntity)
{
if (pEntity)
{
m_pent = ENT( pEntity->pev );
if (m_pent)
m_serialnumber = m_pent->serialnumber;
}
else
{
m_pent = NULL;
m_serialnumber = 0;
}
return pEntity;
}
EHANDLE :: operator int ()
{
return Get() != NULL;
}
CBaseEntity * EHANDLE :: operator -> ()
{
return (CBaseEntity *)GET_PRIVATE( Get( ) );
}
// give health
int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType )
{
if (!pev->takedamage)
return 0;
// heal
if ( pev->health >= pev->max_health )
return 0;
pev->health += flHealth;
if (pev->health > pev->max_health)
pev->health = pev->max_health;
return 1;
}
// inflict damage on this entity. bitsDamageType indicates type of damage inflicted, ie: DMG_CRUSH
int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
Vector vecTemp;
if (!pev->takedamage)
return 0;
// UNDONE: some entity types may be immune or resistant to some bitsDamageType
// if Attacker == Inflictor, the attack was a melee or other instant-hit attack.
// (that is, no actual entity projectile was involved in the attack so use the shooter's origin).
if ( pevAttacker == pevInflictor )
{
vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) );
}
else
// an actual missile was involved.
{
vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) );
}
// this global is still used for glass and other non-monster killables, along with decals.
g_vecAttackDir = vecTemp.Normalize();
// save damage based on the target's armor level
// figure momentum add (don't let hurt brushes or other triggers move player)
if ((!FNullEnt(pevInflictor)) && (pev->movetype == MOVETYPE_WALK || pev->movetype == MOVETYPE_STEP) && (pevAttacker->solid != SOLID_TRIGGER) )
{
Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
vecDir = vecDir.Normalize();
float flForce = flDamage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5;
if (flForce > 1000.0)
flForce = 1000.0;
pev->velocity = pev->velocity + vecDir * flForce;
}
// do the damage
pev->health -= flDamage;
if (pev->health <= 0)
{
Killed( pevAttacker, GIB_NORMAL );
return 0;
}
return 1;
}
void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib )
{
pev->takedamage = DAMAGE_NO;
pev->deadflag = DEAD_DEAD;
UTIL_Remove( this );
}
CBaseEntity *CBaseEntity::GetNextTarget( void )
{
if ( FStringNull( pev->target ) )
return NULL;
edict_t *pTarget = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->target) );
if ( FNullEnt(pTarget) )
return NULL;
return Instance( pTarget );
}
// Global Savedata for Delay
TYPEDESCRIPTION CBaseEntity::m_SaveData[] =
{
DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ),
DEFINE_FIELD( CBaseEntity, m_pfnThink, FIELD_FUNCTION ), // UNDONE: Build table of these!!!
DEFINE_FIELD( CBaseEntity, m_pfnTouch, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnUse, FIELD_FUNCTION ),
DEFINE_FIELD( CBaseEntity, m_pfnBlocked, FIELD_FUNCTION ),
};
int CBaseEntity::Save( CSave &save )
{
if ( save.WriteEntVars( "ENTVARS", pev ) )
return save.WriteFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) );
return 0;
}
int CBaseEntity::Restore( CRestore &restore )
{
int status;
status = restore.ReadEntVars( "ENTVARS", pev );
if ( status )
status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) );
if ( pev->modelindex != 0 && !FStringNull(pev->model) )
{
Vector mins, maxs;
mins = pev->mins; // Set model is about to destroy these
maxs = pev->maxs;
PRECACHE_MODEL( (char *)STRING(pev->model) );
SET_MODEL(ENT(pev), STRING(pev->model));
UTIL_SetSize(pev, mins, maxs); // Reset them
}
return status;
}
// Initialize absmin & absmax to the appropriate box
void SetObjectCollisionBox( entvars_t *pev )
{
if ( (pev->solid == SOLID_BSP) &&
(pev->angles.x || pev->angles.y|| pev->angles.z) )
{ // expand for rotation
float max, v;
int i;
max = 0;
for (i=0 ; i<3 ; i++)
{
v = fabs( ((float *)pev->mins)[i]);
if (v > max)
max = v;
v = fabs( ((float *)pev->maxs)[i]);
if (v > max)
max = v;
}
for (i=0 ; i<3 ; i++)
{
((float *)pev->absmin)[i] = ((float *)pev->origin)[i] - max;
((float *)pev->absmax)[i] = ((float *)pev->origin)[i] + max;
}
}
else
{
pev->absmin = pev->origin + pev->mins;
pev->absmax = pev->origin + pev->maxs;
}
pev->absmin.x -= 1;
pev->absmin.y -= 1;
pev->absmin.z -= 1;
pev->absmax.x += 1;
pev->absmax.y += 1;
pev->absmax.z += 1;
}
void CBaseEntity::SetObjectCollisionBox( void )
{
::SetObjectCollisionBox( pev );
}
int CBaseEntity :: Intersects( CBaseEntity *pOther )
{
if ( pOther->pev->absmin.x > pev->absmax.x ||
pOther->pev->absmin.y > pev->absmax.y ||
pOther->pev->absmin.z > pev->absmax.z ||
pOther->pev->absmax.x < pev->absmin.x ||
pOther->pev->absmax.y < pev->absmin.y ||
pOther->pev->absmax.z < pev->absmin.z )
return 0;
return 1;
}
void CBaseEntity :: MakeDormant( void )
{
SetBits( pev->flags, FL_DORMANT );
// Don't touch
pev->solid = SOLID_NOT;
// Don't move
pev->movetype = MOVETYPE_NONE;
// Don't draw
SetBits( pev->effects, EF_NODRAW );
// Don't think
pev->nextthink = 0;
// Relink
UTIL_SetOrigin( pev, pev->origin );
}
int CBaseEntity :: IsDormant( void )
{
return FBitSet( pev->flags, FL_DORMANT );
}
BOOL CBaseEntity :: IsInWorld( void )
{
// position
if (pev->origin.x >= 4096) return FALSE;
if (pev->origin.y >= 4096) return FALSE;
if (pev->origin.z >= 4096) return FALSE;
if (pev->origin.x <= -4096) return FALSE;
if (pev->origin.y <= -4096) return FALSE;
if (pev->origin.z <= -4096) return FALSE;
// speed
if (pev->velocity.x >= 2000) return FALSE;
if (pev->velocity.y >= 2000) return FALSE;
if (pev->velocity.z >= 2000) return FALSE;
if (pev->velocity.x <= -2000) return FALSE;
if (pev->velocity.y <= -2000) return FALSE;
if (pev->velocity.z <= -2000) return FALSE;
return TRUE;
}
int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState )
{
if ( useType != USE_TOGGLE && useType != USE_SET )
{
if ( (currentState && useType == USE_ON) || (!currentState && useType == USE_OFF) )
return 0;
}
return 1;
}
int CBaseEntity :: DamageDecal( int bitsDamageType )
{
if ( pev->rendermode == kRenderTransAlpha )
return -1;
if ( pev->rendermode != kRenderNormal )
return DECAL_BPROOF1;
return DECAL_GUNSHOT1 + RANDOM_LONG(0,4);
}
// NOTE: szName must be a pointer to constant memory, e.g. "monster_class" because the entity
// will keep a pointer to it after this call.
CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner )
{
edict_t *pent;
CBaseEntity *pEntity;
pent = CREATE_NAMED_ENTITY( MAKE_STRING( szName ));
if ( FNullEnt( pent ) )
{
ALERT ( at_console, "NULL Ent in Create!\n" );
return NULL;
}
pEntity = Instance( pent );
pEntity->pev->owner = pentOwner;
pEntity->pev->origin = vecOrigin;
pEntity->pev->angles = vecAngles;
DispatchSpawn( pEntity->edict() );
return pEntity;
}

View File

@ -1,9 +1,9 @@
/***
*
* 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.
*
* 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
@ -17,25 +17,15 @@
Class Hierachy
CBaseEntity
CPointEntity
CBasePlayerAmmo
CBaseDelay
CBaseAnimating
CBasePlayerItem
CBasePlayerWeapon
CBaseToggle
CBaseButton
CBaseDoor
CBaseTrigger
CBasePlatTrain
CBaseItem
CBaseMonster
CCycler
CBasePlayer
CCineMonster
CBaseCycler
CBasePlayer
CBaseGroup
*/
#include "entity_state.h"
#define MAX_PATH_SIZE 10 // max number of nodes available for a path.
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
@ -48,15 +38,12 @@ CBaseEntity
#define FCAP_ONOFF_USE 0x00000020 // can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
// LRC: no longer used
#define FCAP_ONLYDIRECT_USE 0x00000100 //LRC - can't use this entity through a wall.
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
#include "saverestore.h"
#include "schedule.h"
#include "studio.h"
#ifndef MONSTEREVENT_H
#include "monsterevent.h"
@ -74,28 +61,21 @@ extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interface
extern "C" EXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );
extern int DispatchSpawn( edict_t *pent );
extern int DispatchCreate( edict_t *pent, const char *szName );
extern void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd );
extern void DispatchTouch( edict_t *pentTouched, edict_t *pentOther );
extern void DispatchUse( edict_t *pentUsed, edict_t *pentOther );
extern void DispatchThink( edict_t *pent );
extern int DispatchFrame( edict_t *pent );
extern void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther );
extern void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData );
extern int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity );
extern void DispatchObjectCollsionBox( edict_t *pent );
extern void DispatchObjectCollsionBox( edict_t *pent );
extern void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount );
extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount );
extern void SaveGlobalState( SAVERESTOREDATA *pSaveData );
extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData );
extern void ResetGlobalState( void );
extern int ServerClassifyEdict( edict_t *pentToClassify );
extern void OnFreeEntPrivateData( edict_s *pEdict );
extern int ShouldCollide( edict_t *pentTouched, edict_t *pentOther );
//extern CBaseEntity *g_pDesiredList; //LRC- handles DesiredVel, for movewith
extern char* GetStringForUseType( USE_TYPE useType );
typedef enum { USE_OFF = 0, USE_ON = 1, USE_SET = 2, USE_TOGGLE = 3 } USE_TYPE;
extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
@ -118,16 +98,13 @@ typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCall
#define CLASS_PLAYER_ALLY 11
#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players
#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
#define CLASS_FACTION_A 14 //LRC - very simple new classes, for use with Behaves As
#define CLASS_FACTION_B 15
#define CLASS_FACTION_C 16
#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
class CBaseEntity;
class CBaseMonster;
class CBasePlayerItem;
class CSquadMonster;
class CThinker;
#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn.
@ -155,7 +132,7 @@ public:
//
// Base Entity. All entity types derive from this
//
class CBaseEntity
class CBaseEntity
{
public:
// Constructor. Set engine to use C/C++ callback functions
@ -164,130 +141,35 @@ public:
// path corners
CBaseEntity *m_pGoalEnt;// path corner we are heading towards
CBaseEntity *m_pLink;// used for temporary link-list operations.
CBaseEntity *m_pMoveWith; // LRC- the entity I move with.
int m_MoveWith; //LRC- Name of that entity
CBaseEntity *m_pChildMoveWith; //LRC- one of the entities that's moving with me.
CBaseEntity *m_pSiblingMoveWith; //LRC- another entity that's Moving With the same ent as me. (linked list.)
CBaseEntity *m_pAssistLink; // LRC- link to the next entity which needs to be Assisted before physics are applied.
Vector m_vecPostAssistVel; // LRC
Vector m_vecPostAssistAVel; // LRC
Vector m_vecPostAssistOrg; //g-cont. child postorigin
Vector m_vecPostAssistAng; //g-cont. child postangles
Vector m_vecOffsetOrigin; //spawn offset origin
Vector m_vecOffsetAngles; //spawn offset angles
Vector m_vecParentAngles; //temp container
Vector m_vecParentOrigin; //temp container
float m_fNextThink; // LRC - for SetNextThink and SetPhysThink. Marks the time when a think will be performed - not necessarily the same as pev->nextthink!
float m_fPevNextThink; // LRC - always set equal to pev->nextthink, so that we can tell when the latter gets changed by the @#$^¬! engine.
int m_iLFlags; // LRC- a new set of flags. (pev->spawnflags and pev->flags are full...)
virtual void DesiredAction( void ) {}; // LRC - for postponing stuff until PostThink time, not as a think.
int m_iStyle; // LRC - almost anything can have a lightstyle these days...
int m_iClassType; // edict classtype
Vector m_vecSpawnOffset; // LRC- To fix things which (for example) MoveWith a door which Starts Open.
BOOL m_activated; // LRC- moved here from func_train. Signifies that an entity has already been
// activated. (and hence doesn't need reactivating.)
//LRC - decent mechanisms for setting think times!
// this should have been done a long time ago, but MoveWith finally forced me.
virtual void SetNextThink( float delay ) { SetNextThink(delay, FALSE); }
virtual void SetNextThink( float delay, BOOL correctSpeed );
virtual void AbsoluteNextThink( float time ) { AbsoluteNextThink(time, FALSE); }
virtual void AbsoluteNextThink( float time, BOOL correctSpeed );
void SetEternalThink( );
void DontThink( void );
virtual void ThinkCorrection( void );
//LRC - loci
virtual Vector CalcPosition( CBaseEntity *pLocus ) { return pev->origin; }
virtual Vector CalcVelocity( CBaseEntity *pLocus ) { return pev->velocity; }
virtual float CalcRatio( CBaseEntity *pLocus ) { return 0; }
virtual void SetObjectClass( int iClassType = ED_SPAWNED )
{
m_iClassType = iClassType;
}
//LRC - aliases
virtual BOOL IsAlias( void ) { return FALSE; }
CBaseEntity *m_pLink;// used for temporary link-list operations.
// initialization functions
virtual void Spawn( void ) { return; }
virtual void Precache( void ) { return; }
virtual void KeyValue( KeyValueData* pkvd)
{
//LRC - MoveWith for all!
if (FStrEq(pkvd->szKeyName, "movewith"))
{
m_MoveWith = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "style"))
{
m_iStyle = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else pkvd->fHandled = FALSE;
}
virtual void KeyValue( KeyValueData* pkvd) { pkvd->fHandled = FALSE; }
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
//LRC - if I MoveWith something, then only cross transitions if the MoveWith entity does too.
virtual int ObjectCaps( void ) { return m_pMoveWith?m_pMoveWith->ObjectCaps()&FCAP_ACROSS_TRANSITION:FCAP_ACROSS_TRANSITION; }
virtual void Activate( void ); //LRC
void InitMoveWith( void ); //LRC - called by Activate() to set up moveWith values
void SetParent( int m_iNewParent, int m_iAttachment = 0);//g-cont. two version of SetParent. from xash 0.4
void SetParent( CBaseEntity *pParent, int m_iAttachment = 0 );//g-cont. dynamiclly link parents
void ResetParent( void );
void ClearPointers( void ); //g-cont. directly clear all movewith pointer before changelevel
virtual void PostSpawn( void ) {} //LRC - called by Activate() to handle entity-specific initialisation.
// (mostly setting positions, for MoveWith support)
virtual int ObjectCaps( void ) { return FCAP_ACROSS_TRANSITION; }
virtual void Activate( void ) {}
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
virtual void SetObjectCollisionBox( void );
void UTIL_AutoSetSize( void )//automatically set collision box
{
studiohdr_t *pstudiohdr;
pstudiohdr = (studiohdr_t*)GET_MODEL_PTR( ENT(pev) );
if (pstudiohdr == NULL)
{
ALERT(at_console,"Unable to fetch model pointer!\n");
return;
}
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
UTIL_SetSize(pev,pseqdesc[ pev->sequence ].bbmin,pseqdesc[ pev->sequence ].bbmax);
}
// Classify - returns the type of group (e.g., "alien monster", or "human military" so that monsters
// on the same side won't attack each other, even if they have different classnames.
// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames
// still realize that they are teammates. (overridden for monsters that form groups)
virtual int Classify ( void ) { return CLASS_NONE; };
virtual void DeathNotice ( entvars_t *pevChild ) {}// monster maker children use this to tell the monster maker that they have died.
// LRC- this supports a global concept of "entities with states", so that state_watchers and
// mastership (mastery? masterhood?) can work universally.
virtual STATE GetState ( void ) { return STATE_OFF; };
// For team-specific doors in multiplayer, etc: a master's state depends on who wants to know.
virtual STATE GetState ( CBaseEntity* pEnt ) { return GetState(); };
static TYPEDESCRIPTION m_SaveData[];
virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
virtual int TakeHealth( float flHealth, int bitsDamageType );
virtual int TakeArmor( float flArmor );
virtual void Killed( entvars_t *pevAttacker, int iGib );
virtual int BloodColor( void ) { return DONT_BLEED; }
virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
//LRC- superceded by GetState ( pActivator ).
// virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;}
virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;}
virtual CBaseMonster *MyMonsterPointer( void ) { return NULL;}
virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL;}
virtual int GetToggleState( void ) { return TS_AT_TOP; }
@ -318,7 +200,7 @@ public:
// virtual void SetActivator( CBaseEntity *pActivator ) {}
virtual CBaseEntity *GetNextTarget( void );
// fundamental callbacks
void (CBaseEntity ::*m_pfnThink)(void);
void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther );
@ -327,9 +209,9 @@ public:
virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)(); };
virtual void Touch( CBaseEntity *pOther ) { if (m_pfnTouch) (this->*m_pfnTouch)( pOther ); };
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (m_pfnUse)
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if (m_pfnUse)
(this->*m_pfnUse)( pActivator, pCaller, useType, value );
}
virtual void Blocked( CBaseEntity *pOther ) { if (m_pfnBlocked) (this->*m_pfnBlocked)( pOther ); };
@ -348,17 +230,15 @@ public:
};
#endif
virtual void UpdateOnRemove( void );
void UpdateOnRemove( void );
// common member functions
void EXPORT SUB_Remove( void );
void EXPORT SUB_DoNothing( void );
void EXPORT SUB_StartFadeOut ( void );
void EXPORT SUB_FadeOut ( void );
void EXPORT SUB_CallUseToggle( void ) // a think function used at spawn time. Don't apply the moveWith fix to it.
{ this->Use( this, this, USE_TOGGLE, 0 ); }
void EXPORT SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); }
int ShouldToggle( USE_TYPE useType, BOOL currentState );
int ShouldToggle( USE_TYPE useType ); //LRC this version uses GetState()
void FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL );
Vector FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL, int shared_rand = 0 );
@ -371,16 +251,6 @@ public:
int IsDormant( void );
BOOL IsLockedByMaster( void ) { return FALSE; }
#ifdef _DEBUG
static CBaseEntity *Instance( edict_t *pent )
{
if ( !pent )
pent = ENT(0);
CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent);
ASSERT(pEnt!=NULL);
return pEnt;
}
#else
static CBaseEntity *Instance( edict_t *pent )
{
if ( !pent )
@ -388,20 +258,19 @@ public:
CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent);
return pEnt;
}
#endif
static CBaseEntity *Instance( entvars_t *pev ) { return Instance( ENT( pev ) ); }
static CBaseEntity *Instance( int eoffset) { return Instance( ENT( eoffset) ); }
CBaseMonster *GetMonsterPointer( entvars_t *pevMonster )
{
CBaseMonster *GetMonsterPointer( entvars_t *pevMonster )
{
CBaseEntity *pEntity = Instance( pevMonster );
if ( pEntity )
return pEntity->MyMonsterPointer();
return NULL;
}
CBaseMonster *GetMonsterPointer( edict_t *pentMonster )
{
CBaseMonster *GetMonsterPointer( edict_t *pentMonster )
{
CBaseEntity *pEntity = Instance( pentMonster );
if ( pEntity )
return pEntity->MyMonsterPointer();
@ -411,34 +280,34 @@ public:
// Ugly code to lookup all functions to make sure they are exported when set.
#ifdef _DEBUG
void FunctionCheck( void *pFunction, char *name )
{
void FunctionCheck( void *pFunction, char *name )
{
if (pFunction && !NAME_FOR_FUNCTION((unsigned long)(pFunction)) )
ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, (unsigned long)pFunction );
}
BASEPTR ThinkSet( BASEPTR func, char *name )
{
m_pfnThink = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name );
BASEPTR ThinkSet( BASEPTR func, char *name )
{
m_pfnThink = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name );
return func;
}
ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name )
{
m_pfnTouch = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name );
ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name )
{
m_pfnTouch = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name );
return func;
}
USEPTR UseSet( USEPTR func, char *name )
{
m_pfnUse = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name );
USEPTR UseSet( USEPTR func, char *name )
{
m_pfnUse = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name );
return func;
}
ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name )
{
m_pfnBlocked = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name );
ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name )
{
m_pfnBlocked = func;
FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name );
return func;
}
@ -446,7 +315,7 @@ public:
// virtual functions used by a few classes
// used by monsters that are created by the MonsterMaker
virtual void UpdateOwner( void ) { return; };
@ -488,11 +357,10 @@ public:
int m_fireState;
};
//LRC- moved here from player.cpp. I'd put it in util.h with its friends, but it needs CBaseEntity to be declared.
inline BOOL FNullEnt( CBaseEntity *ent ) { return ent == NULL || FNullEnt( ent->edict() ); }
// Ugly technique to override base member functions
// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
// member function of a base class. static_cast is a sleezy way around that problem.
#ifdef _DEBUG
@ -552,7 +420,8 @@ public:
void Spawn( );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
STATE GetState( void );
int ObjectCaps( void ) { return (CPointEntity::ObjectCaps() | FCAP_MASTER); }
BOOL IsTriggered( CBaseEntity *pActivator );
void EXPORT Register( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
@ -575,12 +444,11 @@ class CBaseDelay : public CBaseEntity
public:
float m_flDelay;
int m_iszKillTarget;
EHANDLE m_hActivator; //LRC - moved here from CBaseToggle
virtual void KeyValue( KeyValueData* pkvd);
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
// common member functions
void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value );
@ -614,11 +482,6 @@ public:
void GetAttachment ( int iAttachment, Vector &origin, Vector &angles );
void SetBodygroup( int iGroup, int iValue );
int GetBodygroup( int iGroup );
//LRC
int GetBoneCount( void );
void SetBones( float (*data)[3], int datasize );
int ExtractBbox( int sequence, Vector &mins, Vector &maxs );
void SetSequenceBox( void );
@ -634,7 +497,7 @@ public:
//
// generic Toggle entity.
//
#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!!
#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!!
class CBaseToggle : public CBaseAnimating
{
@ -656,11 +519,9 @@ public:
int m_cTriggersLeft; // trigger_counter only, # of activations remaining
float m_flHeight;
EHANDLE m_hActivator;
void (CBaseToggle::*m_pfnCallWhenMoveDone)(void);
Vector m_vecFinalDest;
float m_flLinearMoveSpeed; // LRC- allows a LinearMove to be delayed until a think.
float m_flAngularMoveSpeed; // LRC
Vector m_vecFinalAngle;
int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does
@ -671,22 +532,13 @@ public:
static TYPEDESCRIPTION m_SaveData[];
virtual int GetToggleState( void ) { return m_toggle_state; }
// LRC- overridden because toggling entities have general rules governing their states.
virtual STATE GetState( void );
virtual float GetDelay( void ) { return m_flWait; }
// common member functions
void LinearMove( Vector vecInput, float flSpeed );
void EXPORT LinearMoveNow( void ); //LRC- think function that lets us guarantee a LinearMove gets done as a think.
void LinearMove( Vector vecDest, float flSpeed );
void EXPORT LinearMoveDone( void );
void EXPORT LinearMoveDoneNow( void ); //LRC
// void EXPORT LinearMoveFinalDone( void );
void AngularMove( Vector vecDestAngle, float flSpeed );
void EXPORT AngularMoveNow( void ); //LRC- think function that lets us guarantee an AngularMove gets done as a think.
void EXPORT AngularMoveDone( void );
void EXPORT AngularMoveDoneNow( void );
BOOL IsLockedByMaster( void );
static float AxisValue( int flags, const Vector &angles );
@ -694,7 +546,7 @@ public:
static float AxisDelta( int flags, const Vector &angle1, const Vector &angle2 );
string_t m_sMaster; // If this button has a master switch, this is the targetname.
// A master switch must be of the multisource type. If all
// A master switch must be of the multisource type. If all
// of the switches in the multisource have been triggered, then
// the button will be allowed to operate. Otherwise, it will be
// deactivated.
@ -744,7 +596,7 @@ public:
#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
#define DMG_SHOCK (1 << 8) // electric shock
#define DMG_SONIC (1 << 9) // sound pulse shockwave
#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
#define DMG_DROWN (1 << 14) // Drowning
@ -791,7 +643,7 @@ public:
#define SLOWFREEZE_DAMAGE 1.0
#define itbd_Paralyze 0
#define itbd_Paralyze 0
#define itbd_NerveGas 1
#define itbd_Poison 2
#define itbd_Radiation 3
@ -801,7 +653,7 @@ public:
#define itbd_SlowFreeze 7
#define CDMG_TIMEBASED 8
// when calling KILLED(), a value that governs gib behavior is expected to be
// when calling KILLED(), a value that governs gib behavior is expected to be
// one of these three values
#define GIB_NORMAL 0// gib if entity was overkilled
#define GIB_NEVER 1// never gib, no matter how much death damage is done ( freezing, etc )
@ -824,7 +676,6 @@ class CBaseButton : public CBaseToggle
{
public:
void Spawn( void );
virtual void PostSpawn( void ); //LRC
virtual void Precache( void );
void RotSpawn( void );
virtual void KeyValue( KeyValueData* pkvd);
@ -838,17 +689,17 @@ public:
void EXPORT TriggerAndWait( void );
void EXPORT ButtonReturn( void );
void EXPORT ButtonBackHome( void );
void EXPORT ButtonUse_IgnorePlayer( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
enum BUTTON_CODE { BUTTON_NOTHING, BUTTON_ACTIVATE, BUTTON_RETURN };
BUTTON_CODE ButtonResponseToTouch( void );
static TYPEDESCRIPTION m_SaveData[];
virtual int ObjectCaps( void );
// Buttons that don't take damage can be IMPULSE used
virtual int ObjectCaps( void ) { return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage?0:FCAP_IMPULSE_USE); }
BOOL m_fStayPushed; // button stays pushed in until touched again?
BOOL m_fRotating; // a rotating button? default is a sliding button.
@ -858,16 +709,16 @@ public:
// to the button's ChangeTarget. This allows you to make a func_train switch paths, etc.
locksound_t m_ls; // door lock sounds
BYTE m_bLockedSound; // ordinals from entity selection
BYTE m_bLockedSentence;
BYTE m_bUnlockedSound;
BYTE m_bLockedSentence;
BYTE m_bUnlockedSound;
BYTE m_bUnlockedSentence;
int m_sounds;
};
//
// Weapons
// Weapons
//
#define BAD_WEAPON 0x00007FFF
@ -887,9 +738,9 @@ template <class T> T * GetClassPtr( T *a )
// get the private data
a = (T *)GET_PRIVATE(ENT(pev));
if (a == NULL)
if (a == NULL)
{
// allocate private data
// allocate private data
a = new(pev) T;
a->pev = pev;
}
@ -930,63 +781,6 @@ typedef struct _SelAmmo
BYTE Ammo2;
} SelAmmo;
//LRC- much as I hate to add new globals, I can't see how to read data from the World entity.
extern BOOL g_startSuit;
//LRC- moved here from alias.cpp so that util functions can use these defs.
class CBaseAlias : public CPointEntity
{
public:
BOOL IsAlias( void ) { return TRUE; };
virtual CBaseEntity *FollowAlias( CBaseEntity *pFrom ) { return NULL; };
virtual void ChangeValue( int iszValue ) { ALERT(at_error, "%s entities cannot change value!", STRING(pev->classname)); }
virtual void ChangeValue( CBaseEntity *pValue ) { ChangeValue(pValue->pev->targetname); }
virtual void FlushChanges( void ) {};
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CBaseAlias *m_pNextAlias;
};
class CInfoGroup : public CPointEntity
{
public:
void KeyValue( KeyValueData *pkvd );
void Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
int GetMember( const char* szMemberName );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
int m_cMembers;
int m_iszMemberName [ MAX_MULTI_TARGETS ];
int m_iszMemberValue [ MAX_MULTI_TARGETS ];
int m_iszDefaultMember;
};
class CMultiAlias : public CBaseAlias
{
public:
void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
CBaseEntity *FollowAlias( CBaseEntity *pFrom );
int m_cTargets;
int m_iszTargets [ MAX_MULTI_TARGETS ];
int m_iTotalValue;
int m_iValues [ MAX_MULTI_TARGETS ];
int m_iMode;
};
// this moved here from world.cpp, to allow classes to be derived from it
//=======================
@ -1000,8 +794,4 @@ public:
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
CBaseAlias *m_pFirstAlias;
};
extern CWorld *g_pWorld;

View File

@ -20,10 +20,27 @@
#ifndef CDLL_DLL_H
#define CDLL_DLL_H
#define MAX_WEAPONS 32 // ???
#define MAX_WEAPON_SLOTS 5 // hud item selection slots
#define MAX_ITEM_TYPES 6 // hud item selection slots
#define MAX_ITEMS 5 // hard coded item types
#define HIDEHUD_CROSSHAIR ( 1<<4 ) //LRC - probably not the right way to do this, but it's just an experiment.
#define HIDEHUD_WEAPONS ( 1<<0 )
#define HIDEHUD_FLASHLIGHT ( 1<<1 )
#define HIDEHUD_ALL ( 1<<2 )
#define HIDEHUD_HEALTH ( 1<<3 )
#endif
#define MAX_AMMO_TYPES 32 // ???
#define MAX_AMMO_SLOTS 32 // not really slots
#define HUD_PRINTNOTIFY 1
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4
#define WEAPON_SUIT 31
#endif

File diff suppressed because it is too large Load Diff

View File

@ -15,12 +15,8 @@
#ifndef CLIENT_H
#define CLIENT_H
extern void PhysicsPreFrame( void );
extern void PhysicsFrame( void );
extern void PhysicsPostFrame( void );
extern void respawn( entvars_t* pev, BOOL fCopyCorpse );
extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] );
extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] );
extern void ClientDisconnect( edict_t *pEntity );
extern void ClientKill( edict_t *pEntity );
extern void ClientPutInServer( edict_t *pEntity );
@ -31,13 +27,13 @@ extern void ServerDeactivate( void );
extern void StartFrame( void );
extern void PlayerPostThink( edict_t *pEntity );
extern void PlayerPreThink( edict_t *pEntity );
extern void BuildLevelList( void );
extern void ParmsNewLevel( void );
extern void ParmsChangeLevel( void );
extern void RegisterEncoders( void );
extern void ClientPrecache( void );
extern const char *GetGameDescription( void );
extern int GetWeaponData( edict_t *player, struct weapon_data_s *info );
extern void PlayerCustomization( edict_t *pEntity, void *pUnused );
extern void SpectatorConnect ( edict_t *pEntity );
extern void SpectatorDisconnect ( edict_t *pEntity );
@ -45,14 +41,25 @@ extern void SpectatorThink ( edict_t *pEntity );
extern void Sys_Error( const char *error_string );
extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, byte **pvs, byte **pas, int portal );
extern void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
extern int AddToFullPack( entity_state_t *state, edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet );
extern void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodelindex );
extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas );
extern void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
extern int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet );
extern void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs );
extern void RegisterEncoders( void );
extern int GetWeaponData( struct edict_s *player, struct weapon_data_s *info );
extern void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed );
extern void CmdEnd ( const edict_t *player );
extern int g_serveractive;
extern int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
extern int GetHullBounds( int hullnumber, float *mins, float *maxs );
extern void CreateInstancedBaselines ( void );
extern int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message );
extern int AllowLagCompensation( void );
#endif // CLIENT_H

View File

@ -29,7 +29,6 @@
#include "animation.h"
#include "weapons.h"
#include "func_break.h"
#include "studio.h" //LRC
extern DLL_GLOBAL Vector g_vecAttackDir;
extern DLL_GLOBAL int g_iSkillLevel;
@ -116,7 +115,7 @@ void CGib :: SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs
pGib->pev->movetype = MOVETYPE_TOSS;
pGib->pev->solid = SOLID_BBOX;
UTIL_SetSize ( pGib->pev, Vector ( 0, 0 ,0 ), Vector ( 0, 0, 0 ) );
pGib->SetTouch(&CGib:: StickyGibTouch );
pGib->SetTouch ( StickyGibTouch );
pGib->SetThink (NULL);
}
pGib->LimitVelocity();
@ -124,19 +123,19 @@ void CGib :: SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs
}
void CGib :: SpawnHeadGib( entvars_t *pevVictim )
{
if ( g_Language == LANGUAGE_GERMAN )
SpawnHeadGib(pevVictim, "models/germangibs.mdl" );// throw one head
else
SpawnHeadGib(pevVictim, "models/hgibs.mdl" );
}
void CGib :: SpawnHeadGib( entvars_t *pevVictim, const char* szGibModel )
{
CGib *pGib = GetClassPtr( (CGib *)NULL );
pGib->Spawn( szGibModel );// throw one head
pGib->pev->body = 0;
if ( g_Language == LANGUAGE_GERMAN )
{
pGib->Spawn( "models/germangibs.mdl" );// throw one head
pGib->pev->body = 0;
}
else
{
pGib->Spawn( "models/hgibs.mdl" );// throw one head
pGib->pev->body = 0;
}
if ( pevVictim )
{
@ -183,42 +182,32 @@ void CGib :: SpawnHeadGib( entvars_t *pevVictim, const char* szGibModel )
void CGib :: SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human )
{
if ( g_Language == LANGUAGE_GERMAN )
SpawnRandomGibs(pevVictim, cGibs, 1, "models/germangibs.mdl");
else if (human)
SpawnRandomGibs(pevVictim, cGibs, 1, "models/hgibs.mdl");
else
SpawnRandomGibs(pevVictim, cGibs, 0, "models/agibs.mdl");
}
int cSplat;
//LRC - changed signature, to support custom gib models
void CGib :: SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int notfirst, const char *szGibModel )
{
if (cGibs == 0) return; // spawn nothing!
CGib *pGib = GetClassPtr( (CGib *)NULL );
pGib->Spawn( szGibModel );
//LRC - check the model itself to find out how many gibs are available
studiohdr_t *pstudiohdr = (studiohdr_t *)(GET_MODEL_PTR( ENT(pGib->pev) ));
if (! pstudiohdr)
return;
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex);
//ALERT(at_console, "read %d bodyparts, canonical is %d\n", pbodypart->nummodels, HUMAN_GIB_COUNT);
for (int cSplat = 0 ; cSplat < cGibs ; cSplat++ )
for ( cSplat = 0 ; cSplat < cGibs ; cSplat++ )
{
if (pGib == NULL) // first time through, we set pGib before the loop started
{
pGib = GetClassPtr( (CGib *)NULL );
pGib->Spawn( szGibModel );
}
CGib *pGib = GetClassPtr( (CGib *)NULL );
if (notfirst)
pGib->pev->body = RANDOM_LONG(1, pbodypart->nummodels - 1);// start at one to avoid throwing random amounts of skulls (0th gib)
if ( g_Language == LANGUAGE_GERMAN )
{
pGib->Spawn( "models/germangibs.mdl" );
pGib->pev->body = RANDOM_LONG(0,GERMAN_GIB_COUNT-1);
}
else
pGib->pev->body = RANDOM_LONG(0, pbodypart->nummodels - 1);
{
if ( human )
{
// human pieces
pGib->Spawn( "models/hgibs.mdl" );
pGib->pev->body = RANDOM_LONG(1,HUMAN_GIB_COUNT-1);// start at one to avoid throwing random amounts of skulls (0th gib)
}
else
{
// aliens
pGib->Spawn( "models/agibs.mdl" );
pGib->pev->body = RANDOM_LONG(0,ALIEN_GIB_COUNT-1);
}
}
if ( pevVictim )
{
@ -260,66 +249,39 @@ void CGib :: SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int notfirst, con
UTIL_SetSize ( pGib->pev, Vector( 0 , 0 , 0 ), Vector ( 0, 0, 0 ) );
}
pGib->LimitVelocity();
pGib = NULL; //LRC
}
}
//LRC - work out gibs from blood colour, instead of from class.
BOOL CBaseMonster :: HasHumanGibs( void )
{
int myClass = Classify();
// these types of monster don't use gibs
if ( myClass == CLASS_NONE || myClass == CLASS_MACHINE ||
myClass == CLASS_PLAYER_BIOWEAPON && myClass == CLASS_ALIEN_BIOWEAPON)
{
return FALSE;
}
else
{
return (this->m_bloodColor == BLOOD_COLOR_RED);
}
if ( myClass == CLASS_HUMAN_MILITARY ||
myClass == CLASS_PLAYER_ALLY ||
myClass == CLASS_HUMAN_PASSIVE ||
myClass == CLASS_PLAYER )
// if ( myClass == CLASS_HUMAN_MILITARY ||
// myClass == CLASS_PLAYER_ALLY ||
// myClass == CLASS_HUMAN_PASSIVE ||
// myClass == CLASS_PLAYER )
//
// return TRUE;
//
// return FALSE;
return TRUE;
return FALSE;
}
//LRC - work out gibs from blood colour, instead.
BOOL CBaseMonster :: HasAlienGibs( void )
{
int myClass = Classify();
// these types of monster don't use gibs
if ( myClass == CLASS_NONE || myClass == CLASS_MACHINE ||
myClass == CLASS_PLAYER_BIOWEAPON && myClass == CLASS_ALIEN_BIOWEAPON)
{
return FALSE;
}
else
{
return (this->m_bloodColor == BLOOD_COLOR_GREEN);
}
if ( myClass == CLASS_ALIEN_MILITARY ||
myClass == CLASS_ALIEN_MONSTER ||
myClass == CLASS_ALIEN_PASSIVE ||
myClass == CLASS_INSECT ||
myClass == CLASS_ALIEN_PREDATOR ||
myClass == CLASS_ALIEN_PREY )
// int myClass = Classify();
//
// if ( myClass == CLASS_ALIEN_MILITARY ||
// myClass == CLASS_ALIEN_MONSTER ||
// myClass == CLASS_ALIEN_PASSIVE ||
// myClass == CLASS_INSECT ||
// myClass == CLASS_ALIEN_PREDATOR ||
// myClass == CLASS_ALIEN_PREY )
//
// return TRUE;
//
// return FALSE;
return TRUE;
return FALSE;
}
@ -342,23 +304,13 @@ void CBaseMonster :: GibMonster( void )
{
TraceResult tr;
BOOL gibbed = FALSE;
int iszCustomGibs;
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "common/bodysplat.wav", 1, ATTN_NORM);
if ( iszCustomGibs = HasCustomGibs() ) //LRC - monster_generic can have a custom gibset
{
if ( CVAR_GET_FLOAT("violence_hgibs") != 0 )
{
CGib::SpawnHeadGib( pev, STRING(iszCustomGibs) );
CGib::SpawnRandomGibs( pev, 4, 1, STRING(iszCustomGibs) );
}
gibbed = TRUE;
}
// only humans throw skulls !!!UNDONE - eventually monsters will have their own sets of gibs
else if ( HasHumanGibs() )
if ( HasHumanGibs() )
{
if ( CVAR_GET_FLOAT("violence_hgibs") != 0 )// Only the player will ever fail this test
if ( CVAR_GET_FLOAT("violence_hgibs") != 0 ) // Only the player will ever get here
{
CGib::SpawnHeadGib( pev );
CGib::SpawnRandomGibs( pev, 4, 1 ); // throw some human gibs.
@ -367,7 +319,7 @@ void CBaseMonster :: GibMonster( void )
}
else if ( HasAlienGibs() )
{
if ( CVAR_GET_FLOAT("violence_agibs") != 0 )// Should never fail this test, but someone might call it directly
if ( CVAR_GET_FLOAT("violence_agibs") != 0 ) // Should never get here, but someone might call it directly
{
CGib::SpawnRandomGibs( pev, 4, 0 ); // Throw alien gibs
}
@ -379,8 +331,8 @@ void CBaseMonster :: GibMonster( void )
if ( gibbed )
{
// don't remove players!
SetThink(&CBaseMonster :: SUB_Remove );
SetNextThink( 0 );
SetThink ( SUB_Remove );
pev->nextthink = gpGlobals->time;
}
else
{
@ -701,8 +653,8 @@ void CBaseEntity :: SUB_StartFadeOut ( void )
pev->solid = SOLID_NOT;
pev->avelocity = g_vecZero;
SetNextThink( 0.1 );
SetThink(&CBaseEntity :: SUB_FadeOut );
pev->nextthink = gpGlobals->time + 0.1;
SetThink ( SUB_FadeOut );
}
void CBaseEntity :: SUB_FadeOut ( void )
@ -710,13 +662,13 @@ void CBaseEntity :: SUB_FadeOut ( void )
if ( pev->renderamt > 7 )
{
pev->renderamt -= 7;
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
}
else
{
pev->renderamt = 0;
SetNextThink( 0.2 );
SetThink(&CBaseEntity :: SUB_Remove );
pev->nextthink = gpGlobals->time + 0.2;
SetThink ( SUB_Remove );
}
}
@ -736,8 +688,8 @@ void CGib :: WaitTillLand ( void )
if ( pev->velocity == g_vecZero )
{
SetThink(&CGib ::SUB_StartFadeOut);
SetNextThink( m_lifeTime );
SetThink (SUB_StartFadeOut);
pev->nextthink = gpGlobals->time + m_lifeTime;
// If you bleed, you stink!
if ( m_bloodColor != DONT_BLEED )
@ -749,7 +701,7 @@ void CGib :: WaitTillLand ( void )
else
{
// wait and check again in another half second.
SetNextThink( 0.5 );
pev->nextthink = gpGlobals->time + 0.5;
}
}
@ -779,13 +731,7 @@ void CGib :: BounceGibTouch ( CBaseEntity *pOther )
vecSpot = pev->origin + Vector ( 0 , 0 , 8 );//move up a bit, and trace down.
UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ), ignore_monsters, ENT(pev), & tr);
//UTIL_BloodDecalTrace( &tr, m_bloodColor );
int blood;
if(m_bloodColor == BLOOD_COLOR_RED)blood = 1;
else if(m_bloodColor == BLOOD_COLOR_YELLOW)blood = 2;
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), blood, 0, 0 );
UTIL_BloodDecalTrace( &tr, m_bloodColor );
m_cBloodDecals--;
}
@ -810,24 +756,18 @@ void CGib :: StickyGibTouch ( CBaseEntity *pOther )
Vector vecSpot;
TraceResult tr;
SetThink(&CGib :: SUB_Remove );
SetNextThink( 10 );
SetThink ( SUB_Remove );
pev->nextthink = gpGlobals->time + 10;
if ( !FClassnameIs( pOther->pev, "worldspawn" ) )
{
SetNextThink( 0 );
pev->nextthink = gpGlobals->time;
return;
}
UTIL_TraceLine ( pev->origin, pev->origin + pev->velocity * 32, ignore_monsters, ENT(pev), & tr);
//UTIL_BloodDecalTrace( &tr, m_bloodColor );
int blood;
if(m_bloodColor == BLOOD_COLOR_RED)blood = 1;
else if(m_bloodColor == BLOOD_COLOR_YELLOW)blood = 2;
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), blood, 0, 0 );
UTIL_BloodDecalTrace( &tr, m_bloodColor );
pev->velocity = tr.vecPlaneNormal * -1;
pev->angles = UTIL_VecToAngles ( pev->velocity );
@ -849,18 +789,16 @@ void CGib :: Spawn( const char *szGibModel )
pev->renderamt = 255;
pev->rendermode = kRenderNormal;
pev->renderfx = kRenderFxNone;
pev->solid = SOLID_TRIGGER; //LRC - so that they don't get in each other's way when we fire lots
// pev->solid = SOLID_SLIDEBOX;/// hopefully this will fix the VELOCITY TOO LOW crap
pev->solid = SOLID_SLIDEBOX;/// hopefully this will fix the VELOCITY TOO LOW crap
pev->classname = MAKE_STRING("gib");
SetObjectClass( ED_NORMAL ); // AutoClassify can't determine gibs properly
SET_MODEL(ENT(pev), szGibModel);
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
SetNextThink( 4 );
pev->nextthink = gpGlobals->time + 4;
m_lifeTime = 25;
SetThink(&CGib :: WaitTillLand );
SetTouch(&CGib :: BounceGibTouch );
SetThink ( WaitTillLand );
SetTouch ( BounceGibTouch );
m_material = matNone;
m_cBloodDecals = 5;// how many blood decals this gib can place (1 per bounce until none remain).
@ -881,12 +819,6 @@ int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType)
return CBaseEntity::TakeHealth(flHealth, bitsDamageType);
}
int CBaseMonster :: TakeArmor (float flArmor )
{
if (!pev->takedamage) return 0;
return CBaseEntity::TakeArmor( flArmor );
}
/*
============
TakeDamage
@ -999,27 +931,6 @@ int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker,
// react to the damage (get mad)
if ( (pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker) )
{
//LRC - new behaviours, for m_iPlayerReact.
if (pevAttacker->flags & FL_CLIENT)
{
if (m_iPlayerReact == 2)
{
// just get angry.
Remember( bits_MEMORY_PROVOKED );
}
else if (m_iPlayerReact == 3)
{
// try to decide whether it was deliberate... if I have an enemy, assume it was just crossfire.
if ( m_hEnemy == NULL )
{
if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || UTIL_IsFacing( pevAttacker, pev->origin ) )
Remember( bits_MEMORY_PROVOKED );
else
Remember( bits_MEMORY_SUSPICIOUS );
}
}
}
if ( pevAttacker->flags & (FL_MONSTER | FL_CLIENT) )
{// only if the attack was a monster or client!
@ -1327,14 +1238,12 @@ BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity )
UTIL_TraceLine(vecLookerOrigin, vecTargetOrigin, ignore_monsters, ignore_glass, ENT(pev)/*pentIgnore*/, &tr);
if (tr.flFraction != 1.0 && tr.pHit != ENT(pEntity->pev)) //LRC - added so that monsters can "see" some bsp objects
if (tr.flFraction != 1.0)
{
// ALERT(at_console, "can't see \"%s\"\n", STRING(pEntity->pev->classname));
return FALSE;// Line of sight is not established
}
else
{
// ALERT(at_console, "Seen ok\n");
return TRUE;// line of sight is valid.
}
}
@ -1514,7 +1423,7 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting
case BULLET_MONSTER_9MM:
case BULLET_MONSTER_12MM:
default:
MESSAGE_BEGIN( MSG_PAS, gmsgTempEntity, vecTracerSrc );
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, vecTracerSrc );
WRITE_BYTE( TE_TRACER );
WRITE_COORD( vecTracerSrc.x );
WRITE_COORD( vecTracerSrc.y );
@ -1536,8 +1445,7 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting
pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET | ((iDamage > 16) ? DMG_ALWAYSGIB : DMG_NEVERGIB) );
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pEntity->entindex(), 6, 0, 0 );
//DecalGunshot( &tr, iBulletType );
DecalGunshot( &tr, iBulletType );
}
else switch(iBulletType)
{
@ -1546,8 +1454,7 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting
pEntity->TraceAttack(pevAttacker, gSkillData.monDmg9MM, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pEntity->entindex(), 6, 0, 0 );
//DecalGunshot( &tr, iBulletType );
DecalGunshot( &tr, iBulletType );
break;
@ -1555,8 +1462,7 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting
pEntity->TraceAttack(pevAttacker, gSkillData.monDmgMP5, vecDir, &tr, DMG_BULLET);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pEntity->entindex(), 6, 0, 0 );
//DecalGunshot( &tr, iBulletType );
DecalGunshot( &tr, iBulletType );
break;
@ -1565,21 +1471,10 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pEntity->entindex(), 6, 0, 0 );
//DecalGunshot( &tr, iBulletType );
DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_PLAYER_357:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET);
if ( !tracer )
{
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&tr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pEntity->entindex(), 6, 0, 0 );
//DecalGunshot( &tr, iBulletType );
}
break;
case BULLET_NONE: // FIX
pEntity->TraceAttack(pevAttacker, 50, vecDir, &tr, DMG_CLUB);
TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType);
@ -1752,13 +1647,7 @@ void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr,
if ( Bloodtr.flFraction != 1.0 )
{
//UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
int blood;
if(BloodColor() == BLOOD_COLOR_RED)blood = 1;
else if(BloodColor() == BLOOD_COLOR_YELLOW)blood = 2;
CBaseEntity *pHit = CBaseEntity::Instance( Bloodtr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&Bloodtr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), blood, 0, 0 );
UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
}
}
}
@ -1797,7 +1686,7 @@ void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResu
UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * 172, ignore_monsters, ENT(pev), &Bloodtr);
/*
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_SHOWLINE);
WRITE_COORD( ptr->vecEndPos.x );
WRITE_COORD( ptr->vecEndPos.y );
@ -1811,11 +1700,7 @@ void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResu
if ( Bloodtr.flFraction != 1.0 )
{
int blood;
if(BloodColor() == BLOOD_COLOR_RED)blood = 1;
else if(BloodColor() == BLOOD_COLOR_YELLOW)blood = 2;
CBaseEntity *pHit = CBaseEntity::Instance( Bloodtr.pHit );
PLAYBACK_EVENT_FULL( FEV_RELIABLE|FEV_GLOBAL, edict(), m_usDecals, 0.0, (float *)&Bloodtr.vecEndPos, (float *)&g_vecZero, 0.0, 0.0, pHit->entindex(), blood, 0, 0 );
UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
}
}
}

View File

@ -26,7 +26,6 @@
#include "schedule.h"
#include "weapons.h"
#include "squadmonster.h"
#include "scripted.h"
//=========================================================
// Monster's Anim Events Go Here
@ -158,7 +157,7 @@ const char *CController::pDeathSounds[] =
//=========================================================
int CController :: Classify ( void )
{
return m_iClass?m_iClass:CLASS_ALIEN_MILITARY;
return CLASS_ALIEN_MILITARY;
}
//=========================================================
@ -270,12 +269,11 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
case CONTROLLER_AE_HEAD_OPEN:
{
//ALERT(at_console,"Controller Head Open\n");
Vector vecStart, angleGun;
GetAttachment( 0, vecStart, angleGun );
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_ELIGHT );
WRITE_SHORT( entindex( ) + 0x1000 ); // entity, attachment
WRITE_COORD( vecStart.x ); // origin
@ -299,12 +297,11 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
case CONTROLLER_AE_BALL_SHOOT:
{
//ALERT(at_console,"Controller Ball Shoot\n");
Vector vecStart, angleGun;
GetAttachment( 0, vecStart, angleGun );
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_ELIGHT );
WRITE_SHORT( entindex( ) + 0x1000 ); // entity, attachment
WRITE_COORD( 0 ); // origin
@ -321,14 +318,7 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
CBaseMonster *pBall = (CBaseMonster*)Create( "controller_head_ball", vecStart, pev->angles, edict() );
pBall->pev->velocity = Vector( 0, 0, 32 );
if (m_pCine)
{
pBall->m_hEnemy = m_hTargetEnt;
}
else
{
pBall->m_hEnemy = m_hEnemy;
}
pBall->m_hEnemy = m_hEnemy;
m_iBall[0] = 0;
m_iBall[1] = 0;
@ -337,7 +327,6 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
case CONTROLLER_AE_SMALL_SHOOT:
{
//ALERT(at_console,"Controller Small Shoot\n");
AttackSound( );
m_flShootTime = gpGlobals->time;
m_flShootEnd = m_flShootTime + atoi( pEvent->options ) / 15.0;
@ -345,7 +334,6 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
break;
case CONTROLLER_AE_POWERUP_FULL:
{
//ALERT(at_console,"Controller Powerup Full\n");
m_iBall[0] = 255;
m_iBallTime[0] = gpGlobals->time + atoi( pEvent->options ) / 15.0;
m_iBall[1] = 255;
@ -354,7 +342,6 @@ void CController :: HandleAnimEvent( MonsterEvent_t *pEvent )
break;
case CONTROLLER_AE_POWERUP_HALF:
{
//ALERT(at_console,"Controller Powerup Half\n");
m_iBall[0] = 192;
m_iBallTime[0] = gpGlobals->time + atoi( pEvent->options ) / 15.0;
m_iBall[1] = 192;
@ -374,18 +361,14 @@ void CController :: Spawn()
{
Precache( );
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL(ENT(pev), "models/controller.mdl");
SET_MODEL(ENT(pev), "models/controller.mdl");
UTIL_SetSize( pev, Vector( -32, -32, 0 ), Vector( 32, 32, 64 ));
pev->solid = SOLID_SLIDEBOX;
pev->movetype = MOVETYPE_FLY;
pev->flags |= FL_FLY;
m_bloodColor = BLOOD_COLOR_GREEN;
if (pev->health == 0)
pev->health = gSkillData.controllerHealth;
pev->health = gSkillData.controllerHealth;
pev->view_ofs = Vector( 0, 0, -2 );// position of the eyes relative to monster's origin.
m_flFieldOfView = VIEW_FIELD_FULL;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
@ -398,10 +381,7 @@ void CController :: Spawn()
//=========================================================
void CController :: Precache()
{
if (pev->model)
PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
else
PRECACHE_MODEL("models/controller.mdl");
PRECACHE_MODEL("models/controller.mdl");
PRECACHE_SOUND_ARRAY( pAttackSounds );
PRECACHE_SOUND_ARRAY( pIdleSounds );
@ -659,33 +639,17 @@ void CController :: RunTask ( Task_t *pTask )
Vector vecSrc = vecHand + pev->velocity * (m_flShootTime - gpGlobals->time);
Vector vecDir;
if (m_pCine != NULL || m_hEnemy != NULL)
if (m_hEnemy != NULL)
{
if (m_pCine != NULL) // LRC- is this a script that's telling it to fire?
if (HasConditions( bits_COND_SEE_ENEMY ))
{
if (m_hTargetEnt != NULL && m_pCine->PreciseAttack())
{
vecDir = (m_hTargetEnt->pev->origin - pev->origin).Normalize() * gSkillData.controllerSpeedBall;
}
else
{
UTIL_MakeVectors(pev->angles);
vecDir = gpGlobals->v_forward * gSkillData.controllerSpeedBall;
}
m_vecEstVelocity = m_vecEstVelocity * 0.5 + m_hEnemy->pev->velocity * 0.5;
}
else if (m_hEnemy != NULL)
else
{
if (HasConditions( bits_COND_SEE_ENEMY ))
{
m_vecEstVelocity = m_vecEstVelocity * 0.5 + m_hEnemy->pev->velocity * 0.5;
}
else
{
m_vecEstVelocity = m_vecEstVelocity * 0.8;
}
vecDir = Intersect( vecSrc, m_hEnemy->BodyTarget( pev->origin ), m_vecEstVelocity, gSkillData.controllerSpeedBall );
m_vecEstVelocity = m_vecEstVelocity * 0.8;
}
vecDir = Intersect( vecSrc, m_hEnemy->BodyTarget( pev->origin ), m_vecEstVelocity, gSkillData.controllerSpeedBall );
float delta = 0.03490; // +-2 degree
vecDir = vecDir + Vector( RANDOM_FLOAT( -delta, delta ), RANDOM_FLOAT( -delta, delta ), RANDOM_FLOAT( -delta, delta ) ) * gSkillData.controllerSpeedBall;
@ -901,9 +865,9 @@ void CController :: RunAI( void )
m_pBall[i]->SetBrightness( m_iBallCurrent[i] );
GetAttachment( i + 2, vecStart, angleGun );
UTIL_SetOrigin( m_pBall[i], vecStart );
UTIL_SetOrigin( m_pBall[i]->pev, vecStart );
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_ELIGHT );
WRITE_SHORT( entindex( ) + 0x1000 * (i + 3) ); // entity, attachment
WRITE_COORD( vecStart.x ); // origin
@ -1155,12 +1119,13 @@ void CController::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, fl
// ALERT( at_console, "move %.4f %.4f %.4f : %f\n", vecDir.x, vecDir.y, vecDir.z, flInterval );
//float flTotal = m_flGroundSpeed * pev->framerate * flInterval;
//UTIL_MoveToOrigin ( ENT(pev), m_Route[ m_iRouteIndex ].vecLocation, flTotal, MOVE_STRAFE );
// float flTotal = m_flGroundSpeed * pev->framerate * flInterval;
// UTIL_MoveToOrigin ( ENT(pev), m_Route[ m_iRouteIndex ].vecLocation, flTotal, MOVE_STRAFE );
m_velocity = m_velocity * 0.8 + m_flGroundSpeed * vecDir * 0.2;
UTIL_MoveToOrigin ( ENT(pev), pev->origin + m_velocity, m_velocity.Length() * flInterval, MOVE_STRAFE );
}
@ -1203,14 +1168,14 @@ void CControllerHeadBall :: Spawn( void )
pev->scale = 2.0;
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
SetThink(&CControllerHeadBall :: HuntThink );
SetTouch(&CControllerHeadBall :: BounceTouch );
SetThink( HuntThink );
SetTouch( BounceTouch );
m_vecIdeal = Vector( 0, 0, 0 );
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
m_hOwner = Instance( pev->owner );
pev->dmgtime = gpGlobals->time;
@ -1227,11 +1192,11 @@ void CControllerHeadBall :: Precache( void )
void CControllerHeadBall :: HuntThink( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
pev->renderamt -= 5;
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_ELIGHT );
WRITE_SHORT( entindex( ) ); // entity, attachment
WRITE_COORD( pev->origin.x ); // origin
@ -1269,7 +1234,7 @@ void CControllerHeadBall :: HuntThink( void )
ApplyMultiDamage( pev, m_hOwner->pev );
}
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_BEAMENTPOINT );
WRITE_SHORT( entindex() );
WRITE_COORD( tr.vecEndPos.x );
@ -1292,8 +1257,8 @@ void CControllerHeadBall :: HuntThink( void )
m_flNextAttack = gpGlobals->time + 3.0;
SetThink(&CControllerHeadBall :: DieThink );
SetNextThink( 0.3 );
SetThink( DieThink );
pev->nextthink = gpGlobals->time + 0.3;
}
// Crawl( );
@ -1332,7 +1297,7 @@ void CControllerHeadBall :: Crawl( void )
Vector vecAim = Vector( RANDOM_FLOAT( -1, 1 ), RANDOM_FLOAT( -1, 1 ), RANDOM_FLOAT( -1, 1 ) ).Normalize( );
Vector vecPnt = pev->origin + pev->velocity * 0.3 + vecAim * 64;
MESSAGE_BEGIN( MSG_BROADCAST, gmsgTempEntity );
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_BEAMENTPOINT );
WRITE_SHORT( entindex() );
WRITE_COORD( vecPnt.x);
@ -1397,14 +1362,14 @@ void CControllerZapBall :: Spawn( void )
pev->scale = 0.5;
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
SetThink(&CControllerZapBall :: AnimateThink );
SetTouch(&CControllerZapBall :: ExplodeTouch );
SetThink( AnimateThink );
SetTouch( ExplodeTouch );
m_hOwner = Instance( pev->owner );
pev->dmgtime = gpGlobals->time; // keep track of when ball spawned
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
}
@ -1418,7 +1383,7 @@ void CControllerZapBall :: Precache( void )
void CControllerZapBall :: AnimateThink( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
pev->frame = ((int)pev->frame + 1) % 11;

View File

@ -12,6 +12,7 @@
* without written permission from Valve LLC.
*
****/
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
#include "extdll.h"
#include "util.h"
@ -22,9 +23,15 @@
#include "player.h"
#include "gamerules.h"
#ifndef CLIENT_DLL
#define BOLT_AIR_VELOCITY 2000
#define BOLT_WATER_VELOCITY 1000
// UNDONE: Save/restore this? Don't forget to set classname and LINK_ENTITY_TO_CLASS()
//
// OVERLOADS SOME ENTVARS:
//
// speed - the ideal magnitude of my velocity
class CCrossbowBolt : public CBaseEntity
{
void Spawn( void );
@ -61,12 +68,12 @@ void CCrossbowBolt::Spawn( )
SET_MODEL(ENT(pev), "models/crossbow_bolt.mdl");
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
SetTouch(&CCrossbowBolt:: BoltTouch );
SetThink(&CCrossbowBolt:: BubbleThink );
SetNextThink( 0.2 );
SetTouch( BoltTouch );
SetThink( BubbleThink );
pev->nextthink = gpGlobals->time + 0.2;
}
@ -123,7 +130,7 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM); break;
}
if ( !IsMultiplayer() )
if ( !g_pGameRules->IsMultiplayer() )
{
Killed( pev, GIB_NEVER );
}
@ -132,28 +139,22 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
{
EMIT_SOUND_DYN(ENT(pev), CHAN_BODY, "weapons/xbow_hit1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 98 + RANDOM_LONG(0,7));
SetThink(&CCrossbowBolt:: SUB_Remove );
SetNextThink( 10 );// this will get changed below if the bolt is allowed to stick in what it hit.
SetThink( SUB_Remove );
pev->nextthink = gpGlobals->time;// this will get changed below if the bolt is allowed to stick in what it hit.
// if what we hit is static architecture, can stay around for a while.
Vector vecDir = pev->velocity.Normalize( );
UTIL_SetOrigin( this, pev->origin - vecDir * 12 );
pev->angles = UTIL_VecToAngles( vecDir );
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_FLY;
pev->velocity = Vector( 0, 0, 0 );
pev->avelocity.z = 0;
pev->angles.z = RANDOM_LONG(0,360);
if( pOther->IsBSPModel())
{
// TEST compound
pev->movetype = MOVETYPE_COMPOUND;
pev->aiment = pOther->edict();
pev->effects |= EF_NOINTERP;
// SetParent( pOther );//glue bolt with parent system
}
if ( FClassnameIs( pOther->pev, "worldspawn" ) )
{
// if what we hit is static architecture, can stay around for a while.
Vector vecDir = pev->velocity.Normalize( );
UTIL_SetOrigin( pev, pev->origin - vecDir * 12 );
pev->angles = UTIL_VecToAngles( vecDir );
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_FLY;
pev->velocity = Vector( 0, 0, 0 );
pev->avelocity.z = 0;
pev->angles.z = RANDOM_LONG(0,360);
pev->nextthink = gpGlobals->time + 10.0;
}
if (UTIL_PointContents(pev->origin) != CONTENTS_WATER)
{
@ -161,18 +162,18 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
}
}
if ( IsMultiplayer() )
if ( g_pGameRules->IsMultiplayer() )
{
SetThink(&CCrossbowBolt:: ExplodeThink );
SetNextThink( 0.1 );
SetThink( ExplodeThink );
pev->nextthink = gpGlobals->time + 0.1;
}
}
void CCrossbowBolt::BubbleThink( void )
{
SetNextThink( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
if (pev->waterlevel == 0 || pev->watertype <= CONTENTS_FLYFIELD)
if (pev->waterlevel == 0)
return;
UTIL_BubbleTrail( pev->origin - pev->velocity * 0.1, pev->origin, 1 );
@ -186,7 +187,7 @@ void CCrossbowBolt::ExplodeThink( void )
pev->dmg = 40;
iScale = 10;
MESSAGE_BEGIN( MSG_PVS, gmsgTempEntity, pev->origin );
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin );
WRITE_BYTE( TE_EXPLOSION);
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
@ -217,39 +218,23 @@ void CCrossbowBolt::ExplodeThink( void )
UTIL_Remove(this);
}
#endif
enum crossbow_e {
CROSSBOW_IDLE1 = 0, // full
CROSSBOW_IDLE2, // empty
CROSSBOW_IDLE2, // empty
CROSSBOW_FIDGET1, // full
CROSSBOW_FIRE, // full
CROSSBOW_FIRE_LAST, // to empty
CROSSBOW_FIDGET2, // empty
CROSSBOW_FIRE1, // full
CROSSBOW_FIRE2, // reload
CROSSBOW_FIRE3, // empty
CROSSBOW_RELOAD, // from empty
CROSSBOW_DRAW1, // full
CROSSBOW_DRAW2, // empty
CROSSBOW_DRAW1, // full
CROSSBOW_DRAW2, // empty
CROSSBOW_HOLSTER1, // full
CROSSBOW_HOLSTER2, // empty
};
class CCrossbow : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int GetItemInfo(ItemInfo *p);
void FireBolt( void );
void FireSniperBolt( void );
void PrimaryAttack( void );
void SecondaryAttack( void ) { m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1E6; };//just stub
BOOL Deploy( );
void Holster( );
BOOL ShouldWeaponIdle( void ) { return TRUE; };
void Reload( void );
void WeaponIdle( void );
void ZoomUpdate( void );
void ZoomReset( void );
BOOL b_setup;
};
LINK_ENTITY_TO_CLASS( weapon_crossbow, CCrossbow );
void CCrossbow::Spawn( )
@ -263,6 +248,18 @@ void CCrossbow::Spawn( )
FallInit();// get ready to fall down.
}
int CCrossbow::AddToPlayer( CBasePlayer *pPlayer )
{
if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
WRITE_BYTE( m_iId );
MESSAGE_END();
return TRUE;
}
return FALSE;
}
void CCrossbow::Precache( void )
{
PRECACHE_MODEL("models/w_crossbow.mdl");
@ -273,6 +270,9 @@ void CCrossbow::Precache( void )
PRECACHE_SOUND("weapons/xbow_reload1.wav");
UTIL_PrecacheOther( "crossbow_bolt" );
m_usCrossbow = PRECACHE_EVENT( 1, "events/crossbow1.sc" );
m_usCrossbow2 = PRECACHE_EVENT( 1, "events/crossbow2.sc" );
}
@ -300,19 +300,30 @@ BOOL CCrossbow::Deploy( )
return DefaultDeploy( "models/v_crossbow.mdl", "models/p_crossbow.mdl", CROSSBOW_DRAW2, "bow" );
}
void CCrossbow::Holster( )
void CCrossbow::Holster( int skiplocal /* = 0 */ )
{
m_fInReload = FALSE;// cancel any reload in progress.
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
ZoomReset();
if (m_iClip) SendWeaponAnim( CROSSBOW_HOLSTER1 );
else SendWeaponAnim( CROSSBOW_HOLSTER2 );
if ( m_fInZoom )
{
SecondaryAttack( );
}
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
if (m_iClip)
SendWeaponAnim( CROSSBOW_HOLSTER1 );
else
SendWeaponAnim( CROSSBOW_HOLSTER2 );
}
void CCrossbow::PrimaryAttack( void )
{
if ( m_iChargeLevel && IsMultiplayer() )
#ifdef CLIENT_DLL
if ( m_fInZoom && bIsMultiplayer() )
#else
if ( m_fInZoom && g_pGameRules->IsMultiplayer() )
#endif
{
FireSniperBolt();
return;
@ -337,15 +348,14 @@ void CCrossbow::FireSniperBolt()
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
m_iClip--;
// make twang sound
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/xbow_fire1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));
int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif
if (m_iClip)
{
SendWeaponAnim( CROSSBOW_FIRE );
m_iBody++;
}
else SendWeaponAnim( CROSSBOW_FIRE_LAST );
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
@ -357,45 +367,14 @@ void CCrossbow::FireSniperBolt()
UTIL_TraceLine(vecSrc, vecSrc + vecDir * 8192, dont_ignore_monsters, m_pPlayer->edict(), &tr);
#ifndef CLIENT_DLL
if ( tr.pHit->v.takedamage )
{
switch( RANDOM_LONG(0,1) )
{
case 0: EMIT_SOUND( tr.pHit, CHAN_BODY, "weapons/xbow_hitbod1.wav", 1, ATTN_NORM); break;
case 1: EMIT_SOUND( tr.pHit, CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM); break;
}
ClearMultiDamage( );
CBaseEntity::Instance(tr.pHit)->TraceAttack(m_pPlayer->pev, 120, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB );
ApplyMultiDamage( pev, m_pPlayer->pev );
}
else
{
// create a bolt
CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate();
pBolt->pev->origin = tr.vecEndPos - vecDir * 10;
pBolt->pev->angles = UTIL_VecToAngles( vecDir );
pBolt->pev->solid = SOLID_NOT;
pBolt->SetTouch( NULL );
pBolt->SetThink( SUB_Remove );
EMIT_SOUND( pBolt->edict(), CHAN_WEAPON, "weapons/xbow_hit1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM );
if (UTIL_PointContents(tr.vecEndPos) != CONTENTS_WATER)
{
UTIL_Sparks( tr.vecEndPos );
}
if ( FClassnameIs( tr.pHit, "worldspawn" ) )
{
// let the bolt sit around for a while if it hit static architecture
pBolt->pev->nextthink = gpGlobals->time + 5.0;
}
else
{
pBolt->pev->nextthink = gpGlobals->time;
}
}
#endif
}
void CCrossbow::FireBolt()
@ -412,15 +391,14 @@ void CCrossbow::FireBolt()
m_iClip--;
// make twang sound
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/xbow_fire1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));
int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif
if (m_iClip)
{
SendWeaponAnim( CROSSBOW_FIRE );
m_iBody++;
}
else SendWeaponAnim( CROSSBOW_FIRE_LAST );
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 );
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
@ -432,12 +410,13 @@ void CCrossbow::FireBolt()
Vector vecSrc = m_pPlayer->GetGunPosition( ) - gpGlobals->v_up * 2;
Vector vecDir = gpGlobals->v_forward;
#ifndef CLIENT_DLL
CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate();
pBolt->pev->origin = vecSrc;
pBolt->pev->angles = anglesAim;
pBolt->pev->owner = m_pPlayer->edict();
if (m_pPlayer->pev->waterlevel == 3 && m_pPlayer->pev->watertype > CONTENTS_FLYFIELD)
if (m_pPlayer->pev->waterlevel == 3)
{
pBolt->pev->velocity = vecDir * BOLT_WATER_VELOCITY;
pBolt->pev->speed = BOLT_WATER_VELOCITY;
@ -448,71 +427,67 @@ void CCrossbow::FireBolt()
pBolt->pev->speed = BOLT_AIR_VELOCITY;
}
pBolt->pev->avelocity.z = 10;
#endif
if (!m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
// HEV suit - indicate out of ammo condition
m_pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.75;
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75;
if (m_iClip != 0)
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0;
else m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.75;
else
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.75;
}
void CCrossbow::SecondaryAttack()
{
if ( m_pPlayer->pev->fov != 0 )
{
m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0; // 0 means reset to default fov
m_fInZoom = 0;
}
else if ( m_pPlayer->pev->fov != 20 )
{
m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 20;
m_fInZoom = 1;
}
pev->nextthink = UTIL_WeaponTimeBase() + 0.1;
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0;
}
void CCrossbow::Reload( void )
{
if (m_iClip) return;
if ( m_iChargeLevel ) ZoomReset();
m_iBody = 0;//show full
if ( DefaultReload( 5, CROSSBOW_RELOAD, 4.7 ) )
if ( m_pPlayer->ammo_bolts <= 0 )
return;
if ( m_pPlayer->pev->fov != 0 )
{
SecondaryAttack();
}
if ( DefaultReload( 5, CROSSBOW_RELOAD, 4.5 ) )
{
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/xbow_reload1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));
}
}
void CCrossbow :: ZoomUpdate( void )
{
if (m_pPlayer->pev->button & IN_ATTACK2)
{
if(m_iChargeLevel == 0)
{
if (m_flShockTime > UTIL_WeaponTimeBase()) return;
m_iChargeLevel = 1;
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.5;
}
if(m_iChargeLevel == 1)
{
m_pPlayer->pev->fov = 50;
m_iChargeLevel = 2;//ready to zooming, wait for 0.5 secs
}
if (m_flTimeUpdate > UTIL_WeaponTimeBase()) return;
if (m_iChargeLevel == 2 && m_pPlayer->pev->fov > 20)
{
m_pPlayer->pev->fov--;
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.02;
}
if(m_iChargeLevel == 3) ZoomReset();
}
else if(m_iChargeLevel > 1) m_iChargeLevel = 3;
}
void CCrossbow::ZoomReset( void )
{
m_flShockTime = UTIL_WeaponTimeBase() + 0.5;
m_pPlayer->pev->fov = 90;
m_iChargeLevel = 0;//clear zoom
}
void CCrossbow::WeaponIdle( void )
{
m_pPlayer->GetAutoaimVector( AUTOAIM_2DEGREES ); // get the autoaim vector but ignore it; used for autoaim crosshair in DM
ZoomUpdate();
if (m_flTimeWeaponIdle < UTIL_WeaponTimeBase())
ResetEmptySound( );
if ( m_flTimeWeaponIdle < UTIL_WeaponTimeBase() )
{
float flRand = RANDOM_FLOAT(0, 1);
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 );
if (flRand <= 0.75)
{
if (m_iClip)
@ -523,12 +498,20 @@ void CCrossbow::WeaponIdle( void )
{
SendWeaponAnim( CROSSBOW_IDLE2 );
}
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_FLOAT ( 10, 15 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}
else if (m_iClip)
else
{
SendWeaponAnim( CROSSBOW_FIDGET1 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 90.0 / 30.0;
if (m_iClip)
{
SendWeaponAnim( CROSSBOW_FIDGET1 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 90.0 / 30.0;
}
else
{
SendWeaponAnim( CROSSBOW_FIDGET2 );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 80.0 / 30.0;
}
}
}
}
@ -559,3 +542,7 @@ class CCrossbowAmmo : public CBasePlayerAmmo
}
};
LINK_ENTITY_TO_CLASS( ammo_crossbow, CCrossbowAmmo );
#endif

View File

@ -26,28 +26,11 @@
#define CROWBAR_BODYHIT_VOLUME 128
#define CROWBAR_WALLHIT_VOLUME 512
class CCrowbar : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int GetItemInfo(ItemInfo *p);
void PrimaryAttack( void );
void SecondaryAttack( void );
int Swing( int fFirst );
BOOL Deploy( void );
void Holster( );
void WeaponIdle( void );
BOOL ShouldWeaponIdle( void ) { return TRUE; };
int m_iSwing;
BOOL bHit;
private:
unsigned int m_usCrowbar;
};
LINK_ENTITY_TO_CLASS( weapon_crowbar, CCrowbar );
enum crowbar_e {
enum gauss_e {
CROWBAR_IDLE = 0,
CROWBAR_DRAW,
CROWBAR_HOLSTER,
@ -66,6 +49,7 @@ void CCrowbar::Spawn( )
m_iId = WEAPON_CROWBAR;
SET_MODEL(ENT(pev), "models/w_crowbar.mdl");
m_iClip = -1;
FallInit();// get ready to fall down.
}
@ -82,7 +66,7 @@ void CCrowbar::Precache( void )
PRECACHE_SOUND("weapons/cbar_hitbod3.wav");
PRECACHE_SOUND("weapons/cbar_miss1.wav");
m_usCrowbar = PRECACHE_EVENT ( 1, "evCrowbar" );
m_usCrowbar = PRECACHE_EVENT ( 1, "events/crowbar.sc" );
}
int CCrowbar::GetItemInfo(ItemInfo *p)
@ -107,7 +91,7 @@ BOOL CCrowbar::Deploy( )
return DefaultDeploy( "models/v_crowbar.mdl", "models/p_crowbar.mdl", CROWBAR_DRAW, "crowbar" );
}
void CCrowbar::Holster( )
void CCrowbar::Holster( int skiplocal /* = 0 */ )
{
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
SendWeaponAnim( CROWBAR_HOLSTER );
@ -161,32 +145,39 @@ void FindHullIntersection( const Vector &vecSrc, TraceResult &tr, float *mins, f
void CCrowbar::PrimaryAttack()
{
if (!Swing(TRUE)) Swing (FALSE);
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.2;
if (! Swing( 1 ))
{
SetThink( SwingAgain );
pev->nextthink = gpGlobals->time + 0.1;
}
}
void CCrowbar::SecondaryAttack()
void CCrowbar::Smack( )
{
if (!Swing(TRUE)) Swing (FALSE);
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.2;
DecalGunshot( &m_trHit, BULLET_PLAYER_CROWBAR );
}
void CCrowbar::SwingAgain( void )
{
Swing( 0 );
}
int CCrowbar::Swing( int fFirst )
{
int fDidHit = FALSE;
bHit = FALSE;
TraceResult tr;
if ( m_flTimeUpdate > UTIL_WeaponTimeBase() ) return fDidHit;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3;
UTIL_MakeVectors (m_pPlayer->pev->v_angle);
Vector vecSrc = m_pPlayer->GetGunPosition( );
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );
#ifndef CLIENT_DLL
if ( tr.flFraction >= 1.0 )
{
UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT( m_pPlayer->pev ), &tr );
@ -200,21 +191,57 @@ int CCrowbar::Swing( int fFirst )
vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space)
}
}
#endif
if ( tr.flFraction >= 1.0 && fFirst) m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar,
0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0,
0.0, 0, 0.0 );
if ( tr.flFraction >= 1.0 )
{
if (fFirst)
{
// miss
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
}
}
else
{
switch( ((m_iSwing++) % 2) + 1 )
{
case 0:
SendWeaponAnim( CROWBAR_ATTACK1HIT ); break;
case 1:
SendWeaponAnim( CROWBAR_ATTACK2HIT ); break;
case 2:
SendWeaponAnim( CROWBAR_ATTACK3HIT ); break;
}
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL
// hit
fDidHit = TRUE;
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
ClearMultiDamage( );
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB );
if ( (m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() )
{
// first swing does full damage
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB );
}
else
{
// subsequent swings do half
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar / 2, gpGlobals->v_forward, &tr, DMG_CLUB );
}
ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev );
// play thwack, smack, or dong sound
@ -225,33 +252,67 @@ int CCrowbar::Swing( int fFirst )
{
if ( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE )
{
bHit = TRUE;//play hitbody sound on client
// play thwack or smack sound
switch( RANDOM_LONG(0,2) )
{
case 0:
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM); break;
case 1:
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM); break;
case 2:
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM); break;
}
m_pPlayer->m_iWeaponVolume = CROWBAR_BODYHIT_VOLUME;
if ( !pEntity->IsAlive() )
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
else flVol = 0.1;
return TRUE;
else
flVol = 0.1;
fHitWorld = FALSE;
}
}
m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME;
m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.25;
m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.2;
}
PLAYBACK_EVENT_FULL( 0, m_pPlayer->edict(), m_usCrowbar, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, pev->body, fFirst, bHit, 0 );
// play texture hit sound
// UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line
if (fHitWorld)
{
float fvolbar = TEXTURETYPE_PlaySound(&tr, vecSrc, vecSrc + (vecEnd-vecSrc)*2, BULLET_PLAYER_CROWBAR);
if ( g_pGameRules->IsMultiplayer() )
{
// override the volume here, cause we don't play texture sounds in multiplayer,
// and fvolbar is going to be 0 from the above call.
fvolbar = 1;
}
// also play crowbar strike
switch( RANDOM_LONG(0,1) )
{
case 0:
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
break;
case 1:
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
break;
}
// delay the decal a bit
m_trHit = tr;
}
m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME;
#endif
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25;
SetThink( Smack );
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
}
return fDidHit;
}
void CCrowbar:: WeaponIdle( void )
{
if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() ) return;
float flRand = RANDOM_FLOAT(0, 1);
if ( flRand <= 0.5 )
{
SendWeaponAnim( CROWBAR_IDLE );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_FLOAT ( 10, 15 );
}
}

View File

@ -1,75 +1,75 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef DECALS_H
#define DECALS_H
//
// Dynamic Decals
//
enum decal_e
{
DECAL_GUNSHOT1 = 0,
DECAL_GUNSHOT2,
DECAL_GUNSHOT3,
DECAL_GUNSHOT4,
DECAL_GUNSHOT5,
DECAL_LAMBDA1,
DECAL_LAMBDA2,
DECAL_LAMBDA3,
DECAL_LAMBDA4,
DECAL_LAMBDA5,
DECAL_LAMBDA6,
DECAL_SCORCH1,
DECAL_SCORCH2,
DECAL_BLOOD1,
DECAL_BLOOD2,
DECAL_BLOOD3,
DECAL_BLOOD4,
DECAL_BLOOD5,
DECAL_BLOOD6,
DECAL_YBLOOD1,
DECAL_YBLOOD2,
DECAL_YBLOOD3,
DECAL_YBLOOD4,
DECAL_YBLOOD5,
DECAL_YBLOOD6,
DECAL_GLASSBREAK1,
DECAL_GLASSBREAK2,
DECAL_GLASSBREAK3,
DECAL_BIGSHOT1,
DECAL_BIGSHOT2,
DECAL_BIGSHOT3,
DECAL_BIGSHOT4,
DECAL_BIGSHOT5,
DECAL_SPIT1,
DECAL_SPIT2,
DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_MOMMASPLAT,
};
typedef struct
{
char *name;
int index;
} DLL_DECALLIST;
extern DLL_DECALLIST gDecals[];
#endif // DECALS_H
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef DECALS_H
#define DECALS_H
//
// Dynamic Decals
//
enum decal_e
{
DECAL_GUNSHOT1 = 0,
DECAL_GUNSHOT2,
DECAL_GUNSHOT3,
DECAL_GUNSHOT4,
DECAL_GUNSHOT5,
DECAL_LAMBDA1,
DECAL_LAMBDA2,
DECAL_LAMBDA3,
DECAL_LAMBDA4,
DECAL_LAMBDA5,
DECAL_LAMBDA6,
DECAL_SCORCH1,
DECAL_SCORCH2,
DECAL_BLOOD1,
DECAL_BLOOD2,
DECAL_BLOOD3,
DECAL_BLOOD4,
DECAL_BLOOD5,
DECAL_BLOOD6,
DECAL_YBLOOD1,
DECAL_YBLOOD2,
DECAL_YBLOOD3,
DECAL_YBLOOD4,
DECAL_YBLOOD5,
DECAL_YBLOOD6,
DECAL_GLASSBREAK1,
DECAL_GLASSBREAK2,
DECAL_GLASSBREAK3,
DECAL_BIGSHOT1,
DECAL_BIGSHOT2,
DECAL_BIGSHOT3,
DECAL_BIGSHOT4,
DECAL_BIGSHOT5,
DECAL_SPIT1,
DECAL_SPIT2,
DECAL_BPROOF1, // Bulletproof glass decal
DECAL_GARGSTOMP1, // Gargantua stomp crack
DECAL_SMALLSCORCH1, // Small scorch mark
DECAL_SMALLSCORCH2, // Small scorch mark
DECAL_SMALLSCORCH3, // Small scorch mark
DECAL_MOMMABIRTH, // Big momma birth splatter
DECAL_MOMMASPLAT,
};
typedef struct
{
char *name;
int index;
} DLL_DECALLIST;
extern DLL_DECALLIST gDecals[];
#endif // DECALS_H

View File

@ -796,30 +796,9 @@ Schedule_t slError[] =
},
};
//LRC
Task_t tlScriptedTeleport[] =
{
{ TASK_PLANT_ON_SCRIPT, (float)0 },
{ TASK_WAIT_FOR_SCRIPT, (float)0 },
{ TASK_PLAY_SCRIPT, (float)0 },
{ TASK_END_SCRIPT, (float)0 },
};
//LRC
Schedule_t slTeleportToScript[] =
{
{
tlScriptedTeleport,
ARRAYSIZE ( tlScriptedTeleport ),
SCRIPT_BREAK_CONDITIONS,
0,
"TeleportToScript"
},
};
Task_t tlScriptedWalk[] =
{
{ TASK_WALK_TO_SCRIPT, (float)TARGET_MOVE_SCRIPTED },
{ TASK_WALK_TO_TARGET, (float)TARGET_MOVE_SCRIPTED },
{ TASK_WAIT_FOR_MOVEMENT, (float)0 },
{ TASK_PLANT_ON_SCRIPT, (float)0 },
{ TASK_FACE_SCRIPT, (float)0 },
@ -827,7 +806,6 @@ Task_t tlScriptedWalk[] =
{ TASK_ENABLE_SCRIPT, (float)0 },
{ TASK_WAIT_FOR_SCRIPT, (float)0 },
{ TASK_PLAY_SCRIPT, (float)0 },
{ TASK_END_SCRIPT, (float)0 },
};
Schedule_t slWalkToScript[] =
@ -844,7 +822,7 @@ Schedule_t slWalkToScript[] =
Task_t tlScriptedRun[] =
{
{ TASK_RUN_TO_SCRIPT, (float)TARGET_MOVE_SCRIPTED },
{ TASK_RUN_TO_TARGET, (float)TARGET_MOVE_SCRIPTED },
{ TASK_WAIT_FOR_MOVEMENT, (float)0 },
{ TASK_PLANT_ON_SCRIPT, (float)0 },
{ TASK_FACE_SCRIPT, (float)0 },
@ -852,7 +830,6 @@ Task_t tlScriptedRun[] =
{ TASK_ENABLE_SCRIPT, (float)0 },
{ TASK_WAIT_FOR_SCRIPT, (float)0 },
{ TASK_PLAY_SCRIPT, (float)0 },
{ TASK_END_SCRIPT, (float)0 },
};
Schedule_t slRunToScript[] =
@ -869,10 +846,8 @@ Schedule_t slRunToScript[] =
Task_t tlScriptedWait[] =
{
{ TASK_STOP_MOVING, 0 },
// { TASK_ENABLE_SCRIPT, (float)0 },
{ TASK_WAIT_FOR_SCRIPT, (float)0 },
{ TASK_PLAY_SCRIPT, (float)0 },
{ TASK_END_SCRIPT, (float)0 },
};
Schedule_t slWaitScript[] =
@ -893,7 +868,6 @@ Task_t tlScriptedFace[] =
{ TASK_FACE_IDEAL, (float)0 },
{ TASK_WAIT_FOR_SCRIPT, (float)0 },
{ TASK_PLAY_SCRIPT, (float)0 },
{ TASK_END_SCRIPT, (float)0 },
};
Schedule_t slFaceScript[] =
@ -1058,7 +1032,7 @@ Schedule_t *CBaseMonster :: ScheduleInList( const char *pName, Schedule_t **pLis
if ( !pName )
{
ALERT( at_debug, "%s set to unnamed schedule!\n", STRING(pev->classname) );
ALERT( at_console, "%s set to unnamed schedule!\n", STRING(pev->classname) );
return NULL;
}
@ -1067,7 +1041,7 @@ Schedule_t *CBaseMonster :: ScheduleInList( const char *pName, Schedule_t **pLis
{
if ( !pList[i]->pName )
{
ALERT( at_debug, "Unnamed schedule!\n" );
ALERT( at_console, "Unnamed schedule!\n" );
continue;
}
if ( stricmp( pName, pList[i]->pName ) == 0 )
@ -1085,10 +1059,9 @@ Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type )
// ALERT ( at_console, "Sched Type:%d\n", Type );
switch ( Type )
{
// This is the schedule for scripted sequences AND scripted AI. // LRC- And scripted actions, too.
// This is the schedule for scripted sequences AND scripted AI
case SCHED_AISCRIPT:
{
// ALERT(at_console, "Doing AISCRIPT\n");
ASSERT( m_pCine != NULL );
if ( !m_pCine )
{
@ -1101,16 +1074,15 @@ Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type )
switch ( m_pCine->m_fMoveTo )
{
case 0:
return slWaitScript;
case 4: case 6:
return slTeleportToScript;
case 1:
return slWalkToScript;
case 2:
return slRunToScript;
case 5:
return slFaceScript;
case 0:
case 4:
return slWaitScript;
case 1:
return slWalkToScript;
case 2:
return slRunToScript;
case 5:
return slFaceScript;
}
break;
}
@ -1249,7 +1221,7 @@ Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type )
}
default:
{
ALERT ( at_debug, "GetScheduleOfType()\nNo CASE for Schedule Type %d!\n", Type );
ALERT ( at_console, "GetScheduleOfType()\nNo CASE for Schedule Type %d!\n", Type );
return &slIdleStand[ 0 ];
break;

View File

@ -1,98 +1,98 @@
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef DEFAULTAI_H
#define DEFAULTAI_H
//=========================================================
// Failed
//=========================================================
extern Schedule_t slFail[];
//=========================================================
// Idle Schedules
//=========================================================
extern Schedule_t slIdleStand[];
extern Schedule_t slIdleTrigger[];
extern Schedule_t slIdleWalk[];
//=========================================================
// Wake Schedules
//=========================================================
extern Schedule_t slWakeAngry[];
//=========================================================
// AlertTurn Schedules
//=========================================================
extern Schedule_t slAlertFace[];
//=========================================================
// AlertIdle Schedules
//=========================================================
extern Schedule_t slAlertStand[];
//=========================================================
// CombatIdle Schedule
//=========================================================
extern Schedule_t slCombatStand[];
//=========================================================
// CombatFace Schedule
//=========================================================
extern Schedule_t slCombatFace[];
//=========================================================
// reload schedule
//=========================================================
extern Schedule_t slReload[];
//=========================================================
// Attack Schedules
//=========================================================
extern Schedule_t slRangeAttack1[];
extern Schedule_t slRangeAttack2[];
extern Schedule_t slTakeCoverFromBestSound[];
// primary melee attack
extern Schedule_t slMeleeAttack[];
// Chase enemy schedule
extern Schedule_t slChaseEnemy[];
//=========================================================
// small flinch, used when a relatively minor bit of damage
// is inflicted.
//=========================================================
extern Schedule_t slSmallFlinch[];
//=========================================================
// Die!
//=========================================================
extern Schedule_t slDie[];
//=========================================================
// Universal Error Schedule
//=========================================================
extern Schedule_t slError[];
//=========================================================
// Scripted sequences
//=========================================================
extern Schedule_t slWalkToScript[];
extern Schedule_t slRunToScript[];
extern Schedule_t slWaitScript[];
#endif // DEFAULTAI_H
/***
*
* 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.
*
* This source code contains proprietary and confidential information of
* Valve LLC and its suppliers. Access to this code is restricted to
* persons who have executed a written SDK license with Valve. Any access,
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef DEFAULTAI_H
#define DEFAULTAI_H
//=========================================================
// Failed
//=========================================================
extern Schedule_t slFail[];
//=========================================================
// Idle Schedules
//=========================================================
extern Schedule_t slIdleStand[];
extern Schedule_t slIdleTrigger[];
extern Schedule_t slIdleWalk[];
//=========================================================
// Wake Schedules
//=========================================================
extern Schedule_t slWakeAngry[];
//=========================================================
// AlertTurn Schedules
//=========================================================
extern Schedule_t slAlertFace[];
//=========================================================
// AlertIdle Schedules
//=========================================================
extern Schedule_t slAlertStand[];
//=========================================================
// CombatIdle Schedule
//=========================================================
extern Schedule_t slCombatStand[];
//=========================================================
// CombatFace Schedule
//=========================================================
extern Schedule_t slCombatFace[];
//=========================================================
// reload schedule
//=========================================================
extern Schedule_t slReload[];
//=========================================================
// Attack Schedules
//=========================================================
extern Schedule_t slRangeAttack1[];
extern Schedule_t slRangeAttack2[];
extern Schedule_t slTakeCoverFromBestSound[];
// primary melee attack
extern Schedule_t slMeleeAttack[];
// Chase enemy schedule
extern Schedule_t slChaseEnemy[];
//=========================================================
// small flinch, used when a relatively minor bit of damage
// is inflicted.
//=========================================================
extern Schedule_t slSmallFlinch[];
//=========================================================
// Die!
//=========================================================
extern Schedule_t slDie[];
//=========================================================
// Universal Error Schedule
//=========================================================
extern Schedule_t slError[];
//=========================================================
// Scripted sequences
//=========================================================
extern Schedule_t slWalkToScript[];
extern Schedule_t slRunToScript[];
extern Schedule_t slWaitScript[];
#endif // DEFAULTAI_H

View File

@ -22,7 +22,7 @@
#include "util.h"
#include "cbase.h"
#include "doors.h"
#include "movewith.h"
extern void SetMovedir(entvars_t* ev);
@ -34,7 +34,6 @@ class CBaseDoor : public CBaseToggle
public:
void Spawn( void );
void Precache( void );
virtual void PostSpawn( void );
virtual void KeyValue( KeyValueData *pkvd );
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual void Blocked( CBaseEntity *pOther );
@ -43,10 +42,7 @@ public:
virtual int ObjectCaps( void )
{
if (pev->spawnflags & SF_ITEM_USE_ONLY)
{
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE |
(m_iDirectUse ? FCAP_ONLYDIRECT_USE : 0);
}
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE;
else
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
};
@ -78,16 +74,6 @@ public:
BYTE m_bLockedSentence;
BYTE m_bUnlockedSound;
BYTE m_bUnlockedSentence;
BOOL m_iOnOffMode;
BOOL m_iImmediateMode;
BOOL m_iDirectUse;
float m_fAcceleration;
float m_fDeceleration;
float m_flBlockedTime;
BOOL m_iSpeedMode;//AJH for changing door speeds
};
@ -102,10 +88,6 @@ TYPEDESCRIPTION CBaseDoor::m_SaveData[] =
DEFINE_FIELD( CBaseDoor, m_bUnlockedSound, FIELD_CHARACTER ),
DEFINE_FIELD( CBaseDoor, m_bUnlockedSentence, FIELD_CHARACTER ),
DEFINE_FIELD( CBaseDoor, m_iOnOffMode, FIELD_BOOLEAN ),
DEFINE_FIELD( CBaseDoor, m_iImmediateMode, FIELD_BOOLEAN ),
DEFINE_FIELD( CBaseDoor, m_iDirectUse, FIELD_BOOLEAN ),
};
IMPLEMENT_SAVERESTORE( CBaseDoor, CBaseToggle );
@ -253,21 +235,6 @@ void CBaseDoor::KeyValue( KeyValueData *pkvd )
m_bUnlockedSentence = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "immediatemode"))
{
m_iImmediateMode = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "onoffmode"))
{
m_iOnOffMode = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "directuse"))
{
m_iDirectUse = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "WaveHeight"))
{
pev->scale = atof(pkvd->szValue) * (1.0/8.0);
@ -308,9 +275,7 @@ LINK_ENTITY_TO_CLASS( func_door, CBaseDoor );
//
LINK_ENTITY_TO_CLASS( func_water, CBaseDoor );
//MH this new spawn function messes up SF_DOOR_START_OPEN
// so replace it with the old one (below)
/*
void CBaseDoor::Spawn( )
{
Precache();
@ -330,8 +295,8 @@ void CBaseDoor::Spawn( )
}
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL( ENT(pev), STRING(pev->model) );
UTIL_SetOrigin(this, pev->origin);
if (pev->speed == 0)
pev->speed = 100;
@ -342,7 +307,7 @@ void CBaseDoor::Spawn( )
ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal");
if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) )
{ // swap pos1 and pos2, put door at pos2
UTIL_SetOrigin(this, m_vecPosition2);
UTIL_SetOrigin(pev, m_vecPosition2);
m_vecPosition2 = m_vecPosition1;
m_vecPosition1 = pev->origin;
}
@ -350,112 +315,21 @@ void CBaseDoor::Spawn( )
m_toggle_state = TS_AT_BOTTOM;
// if the door is flagged for USE button activation only, use NULL touch function
// (unless it's overridden, of course- LRC)
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) &&
!FBitSet ( pev->spawnflags, SF_DOOR_FORCETOUCHABLE ))
{
SetTouch ( NULL );
}
else // touchable button
SetTouch(&CBaseDoor:: DoorTouch );
}
*/
//standard Spirit 1.0 spawn function
void CBaseDoor::Spawn( )
{
Precache();
SetMovedir (pev);
if ( pev->skin == 0 )
{//normal door
if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) )
pev->solid = SOLID_NOT;
else
pev->solid = SOLID_BSP;
}
else
{// special contents
pev->solid = SOLID_NOT;
SetBits( pev->spawnflags, SF_DOOR_SILENT ); // water is silent for now
}
pev->movetype = MOVETYPE_PUSH;
SET_MODEL( ENT(pev), STRING(pev->model) );
UTIL_SetOrigin(this, pev->origin);
if (pev->speed == 0)
pev->speed = 100;
m_toggle_state = TS_AT_BOTTOM;
// if the door is flagged for USE button activation only, use NULL touch function
// (unless it's overridden, of course- LRC)
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) &&
!FBitSet ( pev->spawnflags, SF_DOOR_FORCETOUCHABLE ))
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) )
{
SetTouch ( NULL );
}
else // touchable button
SetTouch( DoorTouch );
}
//END
//LRC
void CBaseDoor :: PostSpawn( void )
{
if (m_pMoveWith)
m_vecPosition1 = pev->origin - m_pMoveWith->pev->origin;
else
m_vecPosition1 = pev->origin;
// Subtract 2 from size because the engine expands bboxes by 1 in all directions
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip));
ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal");
if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) )
{ // swap pos1 and pos2, put door at pos2
if (m_pMoveWith)
{
m_vecSpawnOffset = m_vecSpawnOffset + (m_vecPosition2 + m_pMoveWith->pev->origin) - pev->origin;
UTIL_AssignOrigin(this, m_vecPosition2 + m_pMoveWith->pev->origin);
}
else
{
m_vecSpawnOffset = m_vecSpawnOffset + m_vecPosition2 - pev->origin;
UTIL_AssignOrigin(this, m_vecPosition2);
}
Vector vecTemp = m_vecPosition2;
m_vecPosition2 = m_vecPosition1;
m_vecPosition1 = vecTemp;
// ALERT(at_console, "func_door postspawn: origin %f %f %f\n", pev->origin.x, pev->origin.y, pev->origin.z);
}
}
//void CBaseDoor :: PostMoveWith( void )
//{
// Vector vecTemp = m_vecPosition1 - m_pMoveWith->m_vecSpawnOffset;
// ALERT(at_console, "door %s pmw: pos1 changes from (%f %f %f) to (%f %f %f)\n", STRING(pev->targetname), m_vecPosition1.x, m_vecPosition1.y, m_vecPosition1.z, vecTemp.x, vecTemp.y, vecTemp.z);
// m_vecPosition1 = m_vecPosition1 - m_pMoveWith->m_vecSpawnOffset;
// m_vecPosition2 = m_vecPosition2 - m_pMoveWith->m_vecSpawnOffset;
//}
void CBaseDoor :: SetToggleState( int state )
{
if ( state == TS_AT_TOP )
{
if (m_pMoveWith)
UTIL_AssignOrigin( this, m_vecPosition2 + m_pMoveWith->pev->origin);
else
UTIL_AssignOrigin( this, m_vecPosition2 );
}
else
{
if (m_pMoveWith)
UTIL_AssignOrigin( this, m_vecPosition1 + m_pMoveWith->pev->origin);
else
UTIL_AssignOrigin( this, m_vecPosition1 );
}
UTIL_SetOrigin( pev, m_vecPosition2 );
else
UTIL_SetOrigin( pev, m_vecPosition1 );
}
@ -467,50 +341,50 @@ void CBaseDoor::Precache( void )
switch (m_bMoveSnd)
{
case 0:
pev->noiseMoving = MAKE_STRING("common/null.wav");
pev->noiseMoving = ALLOC_STRING("common/null.wav");
break;
case 1:
PRECACHE_SOUND ("doors/doormove1.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove1.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav");
break;
case 2:
PRECACHE_SOUND ("doors/doormove2.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove2.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav");
break;
case 3:
PRECACHE_SOUND ("doors/doormove3.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove3.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav");
break;
case 4:
PRECACHE_SOUND ("doors/doormove4.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove4.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav");
break;
case 5:
PRECACHE_SOUND ("doors/doormove5.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove5.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav");
break;
case 6:
PRECACHE_SOUND ("doors/doormove6.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove6.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav");
break;
case 7:
PRECACHE_SOUND ("doors/doormove7.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove7.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav");
break;
case 8:
PRECACHE_SOUND ("doors/doormove8.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove8.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav");
break;
case 9:
PRECACHE_SOUND ("doors/doormove9.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove9.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove9.wav");
break;
case 10:
PRECACHE_SOUND ("doors/doormove10.wav");
pev->noiseMoving = MAKE_STRING("doors/doormove10.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove10.wav");
break;
default:
pev->noiseMoving = MAKE_STRING("common/null.wav");
pev->noiseMoving = ALLOC_STRING("common/null.wav");
break;
}
@ -518,42 +392,42 @@ void CBaseDoor::Precache( void )
switch (m_bStopSnd)
{
case 0:
pev->noiseArrived = MAKE_STRING("common/null.wav");
pev->noiseArrived = ALLOC_STRING("common/null.wav");
break;
case 1:
PRECACHE_SOUND ("doors/doorstop1.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop1.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop1.wav");
break;
case 2:
PRECACHE_SOUND ("doors/doorstop2.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop2.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop2.wav");
break;
case 3:
PRECACHE_SOUND ("doors/doorstop3.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop3.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav");
break;
case 4:
PRECACHE_SOUND ("doors/doorstop4.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop4.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop4.wav");
break;
case 5:
PRECACHE_SOUND ("doors/doorstop5.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop5.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop5.wav");
break;
case 6:
PRECACHE_SOUND ("doors/doorstop6.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop6.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop6.wav");
break;
case 7:
PRECACHE_SOUND ("doors/doorstop7.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop7.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop7.wav");
break;
case 8:
PRECACHE_SOUND ("doors/doorstop8.wav");
pev->noiseArrived = MAKE_STRING("doors/doorstop8.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop8.wav");
break;
default:
pev->noiseArrived = MAKE_STRING("common/null.wav");
pev->noiseArrived = ALLOC_STRING("common/null.wav");
break;
}
@ -577,29 +451,29 @@ void CBaseDoor::Precache( void )
switch (m_bLockedSentence)
{
case 1: m_ls.sLockedSentence = MAKE_STRING("NA"); break; // access denied
case 2: m_ls.sLockedSentence = MAKE_STRING("ND"); break; // security lockout
case 3: m_ls.sLockedSentence = MAKE_STRING("NF"); break; // blast door
case 4: m_ls.sLockedSentence = MAKE_STRING("NFIRE"); break; // fire door
case 5: m_ls.sLockedSentence = MAKE_STRING("NCHEM"); break; // chemical door
case 6: m_ls.sLockedSentence = MAKE_STRING("NRAD"); break; // radiation door
case 7: m_ls.sLockedSentence = MAKE_STRING("NCON"); break; // gen containment
case 8: m_ls.sLockedSentence = MAKE_STRING("NH"); break; // maintenance door
case 9: m_ls.sLockedSentence = MAKE_STRING("NG"); break; // broken door
case 1: m_ls.sLockedSentence = ALLOC_STRING("NA"); break; // access denied
case 2: m_ls.sLockedSentence = ALLOC_STRING("ND"); break; // security lockout
case 3: m_ls.sLockedSentence = ALLOC_STRING("NF"); break; // blast door
case 4: m_ls.sLockedSentence = ALLOC_STRING("NFIRE"); break; // fire door
case 5: m_ls.sLockedSentence = ALLOC_STRING("NCHEM"); break; // chemical door
case 6: m_ls.sLockedSentence = ALLOC_STRING("NRAD"); break; // radiation door
case 7: m_ls.sLockedSentence = ALLOC_STRING("NCON"); break; // gen containment
case 8: m_ls.sLockedSentence = ALLOC_STRING("NH"); break; // maintenance door
case 9: m_ls.sLockedSentence = ALLOC_STRING("NG"); break; // broken door
default: m_ls.sLockedSentence = 0; break;
}
switch (m_bUnlockedSentence)
{
case 1: m_ls.sUnlockedSentence = MAKE_STRING("EA"); break; // access granted
case 2: m_ls.sUnlockedSentence = MAKE_STRING("ED"); break; // security door
case 3: m_ls.sUnlockedSentence = MAKE_STRING("EF"); break; // blast door
case 4: m_ls.sUnlockedSentence = MAKE_STRING("EFIRE"); break; // fire door
case 5: m_ls.sUnlockedSentence = MAKE_STRING("ECHEM"); break; // chemical door
case 6: m_ls.sUnlockedSentence = MAKE_STRING("ERAD"); break; // radiation door
case 7: m_ls.sUnlockedSentence = MAKE_STRING("ECON"); break; // gen containment
case 8: m_ls.sUnlockedSentence = MAKE_STRING("EH"); break; // maintenance door
case 1: m_ls.sUnlockedSentence = ALLOC_STRING("EA"); break; // access granted
case 2: m_ls.sUnlockedSentence = ALLOC_STRING("ED"); break; // security door
case 3: m_ls.sUnlockedSentence = ALLOC_STRING("EF"); break; // blast door
case 4: m_ls.sUnlockedSentence = ALLOC_STRING("EFIRE"); break; // fire door
case 5: m_ls.sUnlockedSentence = ALLOC_STRING("ECHEM"); break; // chemical door
case 6: m_ls.sUnlockedSentence = ALLOC_STRING("ERAD"); break; // radiation door
case 7: m_ls.sUnlockedSentence = ALLOC_STRING("ECON"); break; // gen containment
case 8: m_ls.sUnlockedSentence = ALLOC_STRING("EH"); break; // maintenance door
default: m_ls.sUnlockedSentence = 0; break;
}
@ -624,8 +498,8 @@ void CBaseDoor::DoorTouch( CBaseEntity *pOther )
// If door is somebody's target, then touching does nothing.
// You have to activate the owner (e.g. button).
//LRC- allow flags to override this
if (!FStringNull(pev->targetname) && !FBitSet(pev->spawnflags,SF_DOOR_FORCETOUCHABLE))
if (!FStringNull(pev->targetname))
{
// play locked sound
PlayLockSounds(pev, &m_ls, TRUE, FALSE);
@ -645,41 +519,8 @@ void CBaseDoor::DoorTouch( CBaseEntity *pOther )
void CBaseDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
m_hActivator = pActivator;
if (!UTIL_IsMasterTriggered(m_sMaster, pActivator))
return;
if (m_iOnOffMode)
{
if (useType == USE_ON)
{
if (m_toggle_state == TS_AT_BOTTOM)
{
PlayLockSounds(pev, &m_ls, FALSE, FALSE);
DoorGoUp();
}
return;
}
else if (useType == USE_OFF)
{
if (m_toggle_state == TS_AT_TOP)
{
DoorGoDown();
}
return;
}
}
// if not ready to be used, ignore "use" command.
if (m_toggle_state == TS_AT_TOP)
{
if (!FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN))
return;
}
else if (m_toggle_state != TS_AT_BOTTOM)
return;
if (m_toggle_state == TS_AT_BOTTOM || FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP)
DoorActivate();
}
@ -732,20 +573,9 @@ void CBaseDoor::DoorGoUp( void )
if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) )
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM);
// ALERT(at_debug, "%s go up (was %d)\n", STRING(pev->targetname), m_toggle_state);
m_toggle_state = TS_GOING_UP;
SetMoveDone(&CBaseDoor:: DoorHitTop );
// LRC- if synched, we fire as soon as we start to go up
if (m_iImmediateMode)
{
if (m_iOnOffMode)
SUB_UseTargets( m_hActivator, USE_ON, 0 );
else
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
}
SetMoveDone( DoorHitTop );
if ( FClassnameIs(pev, "func_door_rotating")) // !!! BUGBUG Triggered doors don't work with this yet
{
float sign = 1.0;
@ -786,7 +616,6 @@ void CBaseDoor::DoorHitTop( void )
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM);
}
// ALERT(at_debug, "%s hit top\n", STRING(pev->targetname));
ASSERT(m_toggle_state == TS_GOING_UP);
m_toggle_state = TS_AT_TOP;
@ -794,42 +623,26 @@ void CBaseDoor::DoorHitTop( void )
if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN))
{
// Re-instate touch method, movement is complete
if ( !FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ||
FBitSet ( pev->spawnflags, SF_DOOR_FORCETOUCHABLE ) )
SetTouch(&CBaseDoor:: DoorTouch );
if ( !FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) )
SetTouch( DoorTouch );
}
else
{
// In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open
SetNextThink( m_flWait );
SetThink(&CBaseDoor:: DoorGoDown );
pev->nextthink = pev->ltime + m_flWait;
SetThink( DoorGoDown );
if ( m_flWait == -1 )
{
DontThink();
pev->nextthink = -1;
}
}
// Fire the close target (if startopen is set, then "top" is closed) - netname is the close target
if (pev->spawnflags & SF_DOOR_START_OPEN)
{
if (pev->netname)
FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 );
}
else
{
if (pev->message)
FireTargets( STRING(pev->message), m_hActivator, this, USE_TOGGLE, 0 );
}
if ( pev->netname && (pev->spawnflags & SF_DOOR_START_OPEN) )
FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 );
// LRC
if (!m_iImmediateMode)
{
if (m_iOnOffMode)
SUB_UseTargets( m_hActivator, USE_OFF, 0 );
else
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
}
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished
}
@ -841,36 +654,16 @@ void CBaseDoor::DoorGoDown( void )
if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) )
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM);
// ALERT(at_debug, "%s go down (was %d)\n", STRING(pev->targetname), m_toggle_state);
//FYI: not defined, so this doesn't happen. --LRC
#ifdef DOOR_ASSERT
ASSERT(m_toggle_state == TS_AT_TOP);
#endif // DOOR_ASSERT
m_toggle_state = TS_GOING_DOWN;
SetMoveDone(&CBaseDoor:: DoorHitBottom );
SetMoveDone( DoorHitBottom );
if ( FClassnameIs(pev, "func_door_rotating"))//rotating door
{
// LRC- if synched, we fire as soon as we start to go down
if (m_iImmediateMode)
{
if (m_iOnOffMode)
SUB_UseTargets( m_hActivator, USE_OFF, 0 );
else
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
}
AngularMove( m_vecAngle1, pev->speed);
}
else
{
// LRC- if synched, we fire as soon as we start to go down
if (m_iImmediateMode)
{
SUB_UseTargets( m_hActivator, USE_OFF, 0 );
}
LinearMove( m_vecPosition1, pev->speed);
}
}
//
@ -884,123 +677,88 @@ void CBaseDoor::DoorHitBottom( void )
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM);
}
// ALERT(at_debug, "%s hit bottom\n", STRING(pev->targetname));
ASSERT(m_toggle_state == TS_GOING_DOWN);
m_toggle_state = TS_AT_BOTTOM;
// Re-instate touch method, cycle is complete
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) &&
!FBitSet ( pev->spawnflags, SF_DOOR_FORCETOUCHABLE ) )
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) )
{// use only door
SetTouch ( NULL );
}
else // touchable door
SetTouch(&CBaseDoor:: DoorTouch );
SetTouch( DoorTouch );
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished
// Fire the close target (if startopen is set, then "top" is closed) - netname is the close target
// LRC- 'message' is the open target
if (pev->spawnflags & SF_DOOR_START_OPEN)
{
if (pev->message)
FireTargets( STRING(pev->message), m_hActivator, this, USE_TOGGLE, 0 );
}
else
{
if (pev->netname)
FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 );
}
// else
// {
// ALERT(at_console,"didn't fire closetarget because ");
// if (!(pev->netname))
// ALERT(at_console,"no netname\n");
// else if (pev->spawnflags & SF_DOOR_START_OPEN)
// ALERT(at_console,"startopen\n");
// else
// ALERT(at_console,"!!?!\n");
// }
// LRC- if synched, don't fire now
if (!m_iImmediateMode)
{
if (m_iOnOffMode)
SUB_UseTargets( m_hActivator, USE_ON, 0 );
else
SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 );
}
if ( pev->netname && !(pev->spawnflags & SF_DOOR_START_OPEN) )
FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 );
}
void CBaseDoor::Blocked( CBaseEntity *pOther )
{
//g-cont. simple recursive anouncer for parent system
//tell parent who blocked his
if(!FNullEnt(m_pMoveWith) && m_iLFlags & LF_PARENTMOVE) m_pMoveWith->Blocked( this );
if(!FNullEnt(m_pChildMoveWith))
{
if(m_pChildMoveWith == pOther)
{
//ALERT(at_console, "I'am blocked by my child!\n");
Use( NULL, NULL, USE_OFF, 0 );
}
}
UTIL_AssignOrigin(this, pev->origin);
//make delay before retouching
if ( gpGlobals->time < m_flBlockedTime) return;
m_flBlockedTime = gpGlobals->time + 0.5;
edict_t *pentTarget = NULL;
CBaseDoor *pDoor = NULL;
if ( pev->dmg ) pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH );
// Hurt the blocker a little.
if ( pev->dmg )
pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH );
// if a door has a negative wait, it would never come back if blocked,
// so let it just squash the object to death real fast
if (m_flWait >= 0)
{
if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) )
STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) );
if (m_toggle_state == TS_GOING_DOWN) DoorGoUp();
else DoorGoDown();
if (m_toggle_state == TS_GOING_DOWN)
{
DoorGoUp();
}
else
{
DoorGoDown();
}
}
//what the hell does this ?
//UTIL_SynchDoors( this );
SetNextThink( 0 );
CBaseEntity *pTarget = NULL;
CBaseDoor *pDoor = NULL;
// Block all door pieces with the same targetname here.
//LRC - in immediate mode don't do this, doors are expected to do it themselves.
if ( !m_iImmediateMode && !FStringNull ( pev->targetname ) )
if ( !FStringNull ( pev->targetname ) )
{
for (;;)
{
pTarget = UTIL_FindEntityByTargetname(pTarget, STRING(pev->targetname));
pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->targetname));
if ( !pTarget )
break;
if ( pTarget != this )
if ( VARS( pentTarget ) != pev )
{
pDoor = GetClassPtr( (CBaseDoor *) VARS(pTarget->pev) );
if ( pDoor->m_flWait >= 0)
if (FNullEnt(pentTarget))
break;
if ( FClassnameIs ( pentTarget, "func_door" ) || FClassnameIs ( pentTarget, "func_door_rotating" ) )
{
// avelocity == velocity!? LRC
//g-cont. rewrote this hack. now is working correctly
if (pDoor->pev->velocity == pev->velocity && FClassnameIs ( pTarget->pev, "func_door" ))
pDoor = GetClassPtr( (CBaseDoor *) VARS(pentTarget) );
if ( pDoor->m_flWait >= 0)
{
// this is the most hacked, evil, bastardized thing I've ever seen. kjb
pDoor->pev->origin = pev->origin;
UTIL_SetVelocity(pDoor, g_vecZero);// stop!
if (pDoor->pev->velocity == pev->velocity && pDoor->pev->avelocity == pev->velocity)
{
// this is the most hacked, evil, bastardized thing I've ever seen. kjb
if ( FClassnameIs ( pentTarget, "func_door" ) )
{// set origin to realign normal doors
pDoor->pev->origin = pev->origin;
pDoor->pev->velocity = g_vecZero;// stop!
}
else
{// set angles to realign rotating doors
pDoor->pev->angles = pev->angles;
pDoor->pev->avelocity = g_vecZero;
}
}
if ( pDoor->m_toggle_state == TS_GOING_DOWN)
pDoor->DoorGoUp();
else
pDoor->DoorGoDown();
}
if (pDoor->pev->avelocity == pev->avelocity && FClassnameIs ( pTarget->pev, "func_door_rotating" ))
{
pDoor->pev->angles = pev->angles;
UTIL_SetAvelocity(pDoor, g_vecZero);
}
if ( !FBitSet( pDoor->pev->spawnflags, SF_DOOR_SILENT ) )
STOP_SOUND(ENT(pDoor->pev), CHAN_STATIC, (char*)STRING(pDoor->pev->noiseMoving) );
if ( pDoor->m_toggle_state == TS_GOING_DOWN)
pDoor->DoorGoUp();
else pDoor->DoorGoDown();
}
}
}
@ -1050,8 +808,6 @@ class CRotDoor : public CBaseDoor
{
public:
void Spawn( void );
void KeyValue( KeyValueData *pkvd );
virtual void PostSpawn( void ) {} // don't use the moveWith fix from CBaseDoor
virtual void SetToggleState( int state );
};
@ -1071,9 +827,7 @@ void CRotDoor::Spawn( void )
//m_flWait = 2; who the hell did this? (sjb)
m_vecAngle1 = pev->angles;
m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance;
SetBits( m_iLFlags, LF_ANGULAR );
ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal");
if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) )
@ -1082,7 +836,7 @@ void CRotDoor::Spawn( void )
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(this, pev->origin);
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model) );
if (pev->speed == 0)
@ -1101,24 +855,14 @@ void CRotDoor::Spawn( void )
m_toggle_state = TS_AT_BOTTOM;
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) && !FBitSet(pev->spawnflags, SF_DOOR_FORCETOUCHABLE) )
if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) )
{
SetTouch ( NULL );
}
else // touchable button
SetTouch(&CRotDoor:: DoorTouch );
SetTouch( DoorTouch );
}
void CRotDoor::KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "axes"))
{
UTIL_StringToVector( (float*)(pev->movedir), pkvd->szValue );
pkvd->fHandled = TRUE;
}
else
CBaseDoor::KeyValue( pkvd );
}
void CRotDoor :: SetToggleState( int state )
{
@ -1127,7 +871,7 @@ void CRotDoor :: SetToggleState( int state )
else
pev->angles = m_vecAngle1;
UTIL_SetOrigin( this, pev->origin );
UTIL_SetOrigin( pev, pev->origin );
}
@ -1136,7 +880,6 @@ class CMomentaryDoor : public CBaseToggle
public:
void Spawn( void );
void Precache( void );
void EXPORT MomentaryMoveDone( void );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
@ -1146,14 +889,7 @@ public:
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BYTE m_bMoveSnd; // sound a door makes while moving
BYTE m_bStopSnd; // sound a door makes while moving
STATE m_iState;
float m_fLastPos;
STATE GetState( void ) { return m_iState; }
float CalcRatio( CBaseEntity *pLocus ) { return m_fLastPos; }
BYTE m_bMoveSnd; // sound a door makes while moving
};
LINK_ENTITY_TO_CLASS( momentary_door, CMomentaryDoor );
@ -1161,9 +897,6 @@ LINK_ENTITY_TO_CLASS( momentary_door, CMomentaryDoor );
TYPEDESCRIPTION CMomentaryDoor::m_SaveData[] =
{
DEFINE_FIELD( CMomentaryDoor, m_bMoveSnd, FIELD_CHARACTER ),
DEFINE_FIELD( CMomentaryDoor, m_bStopSnd, FIELD_CHARACTER ),
DEFINE_FIELD( CMomentaryDoor, m_iState, FIELD_INTEGER ),
DEFINE_FIELD( CMomentaryDoor, m_fLastPos, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CMomentaryDoor, CBaseToggle );
@ -1175,41 +908,30 @@ void CMomentaryDoor::Spawn( void )
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(this, pev->origin);
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL( ENT(pev), STRING(pev->model) );
// if (pev->speed == 0)
// pev->speed = 100;
if (pev->speed == 0)
pev->speed = 100;
if (pev->dmg == 0)
pev->dmg = 2;
m_iState = STATE_OFF;
m_vecPosition1 = pev->origin;
// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip));
ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal");
//LRC: FIXME, move to PostSpawn
if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) )
{ // swap pos1 and pos2, put door at pos2
UTIL_AssignOrigin(this, m_vecPosition2);
Vector vecTemp = m_vecPosition2;
UTIL_SetOrigin(pev, m_vecPosition2);
m_vecPosition2 = m_vecPosition1;
m_vecPosition1 = vecTemp;
m_vecPosition1 = pev->origin;
}
if (m_pMoveWith)
{
m_vecPosition1 = m_vecPosition1 - m_pMoveWith->pev->origin;
m_vecPosition2 = m_vecPosition2 - m_pMoveWith->pev->origin;
}
Precache();
SetTouch( NULL );
Precache();
}
void CMomentaryDoor::Precache( void )
{
@ -1255,50 +977,6 @@ void CMomentaryDoor::Precache( void )
pev->noiseMoving = ALLOC_STRING("common/null.wav");
break;
}
// set the door's "stop" sound
switch (m_bStopSnd)
{
case 0:
pev->noiseArrived = ALLOC_STRING("common/null.wav");
break;
case 1:
PRECACHE_SOUND ("doors/doorstop1.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop1.wav");
break;
case 2:
PRECACHE_SOUND ("doors/doorstop2.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop2.wav");
break;
case 3:
PRECACHE_SOUND ("doors/doorstop3.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav");
break;
case 4:
PRECACHE_SOUND ("doors/doorstop4.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop4.wav");
break;
case 5:
PRECACHE_SOUND ("doors/doorstop5.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop5.wav");
break;
case 6:
PRECACHE_SOUND ("doors/doorstop6.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop6.wav");
break;
case 7:
PRECACHE_SOUND ("doors/doorstop7.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop7.wav");
break;
case 8:
PRECACHE_SOUND ("doors/doorstop8.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop8.wav");
break;
default:
pev->noiseArrived = ALLOC_STRING("common/null.wav");
break;
}
}
void CMomentaryDoor::KeyValue( KeyValueData *pkvd )
@ -1311,7 +989,7 @@ void CMomentaryDoor::KeyValue( KeyValueData *pkvd )
}
else if (FStrEq(pkvd->szKeyName, "stopsnd"))
{
m_bStopSnd = atof(pkvd->szValue);
// m_bStopSnd = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "healthvalue"))
@ -1330,55 +1008,19 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP
if ( value > 1.0 )
value = 1.0;
if (IsLockedByMaster()) return;
Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1));
Vector delta = move - pev->origin;
float speed = delta.Length() * 10;
float speed = 0;
Vector delta;
/* if ((value == 1) || (value == 0))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving));//G-Cont. fix sound bug (original HL).
return;
}
*/
if (pev->speed)
{
//LRC- move at the given speed, if any.
speed = pev->speed;
}
else
{
// default: get there in 0.1 secs
delta = move - pev->origin;
speed = delta.Length() * 10;
}
//FIXME: allow for it being told to move at the same speed in the _opposite_ direction!
if ( speed != 0 )
{
// This entity only thinks when it moves
//LRC- nope, in a MoveWith world you can't rely on that. Check the state instead.
if ( m_iState == STATE_OFF )
{
//ALERT(at_console,"USE: start moving to %f %f %f.\n", move.x, move.y, move.z);
m_iState = STATE_ON;
// This entity only thinks when it moves, so if it's thinking, it's in the process of moving
// play the sound when it starts moving
if ( pev->nextthink < pev->ltime || pev->nextthink == 0 )
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM);
}
m_fLastPos = value;
LinearMove( move, speed );
//LinearMove( m_vecPosition1, pev->speed, m_fAcceleration, m_fDeceleration);
SetMoveDone(&CMomentaryDoor:: MomentaryMoveDone );
}
}
void CMomentaryDoor::MomentaryMoveDone( void )
{
m_iState = STATE_OFF;
STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM);
}
}

View File

@ -1,38 +1,33 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef DOORS_H
#define DOORS_H
// doors
#define SF_DOOR_ROTATE_Y 0
#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 // door must be opened by player's use button.
#define SF_DOOR_NOMONSTERS 512 // Monster can't open
#define SF_DOOR_FORCETOUCHABLE 1024 //LRC- Opens when touched, even though it's named and/or "use only"
//LRC - clashes with 'not in deathmatch'. Replaced with 'Target mode' and 'On/Off Mode' fields.
//#define SF_DOOR_SYNCHED 2048 //LRC- sends USE_ON/OFF when it starts to open/close (instead of sending
// USE_TOGGLE when fully open/closed); also responds to USE_ON and USE_OFF
// 'correctly'.
#define SF_DOOR_SILENT 0x80000000
#endif //DOORS_H
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef DOORS_H
#define DOORS_H
// doors
#define SF_DOOR_ROTATE_Y 0
#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 // door must be opened by player's use button.
#define SF_DOOR_NOMONSTERS 512 // Monster can't open
#define SF_DOOR_SILENT 0x80000000
#endif //DOORS_H

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