From 2b482da25aa8797ed5420ea0b9ea2780d03e9ef0 Mon Sep 17 00:00:00 2001 From: g-cont Date: Thu, 24 Jun 2010 00:00:00 +0400 Subject: [PATCH] 24 Jun 2010 --- bshift/airtank.cpp | 5 +- bshift/barney.cpp | 2 +- bshift/bshift.def | 2 +- bshift/cbase.cpp | 19 +- bshift/cbase.h | 3 + bshift/client.cpp | 298 +++- bshift/client.h | 4 +- bshift/crossbow.cpp | 4 +- bshift/crowbar.cpp | 2 +- bshift/egon.cpp | 2 +- bshift/enginecallback.h | 14 +- bshift/func_tank.cpp | 2 +- bshift/gamerules.cpp | 2 +- bshift/gamerules.h | 6 +- bshift/gauss.cpp | 2 +- bshift/handgrenade.cpp | 2 +- bshift/hornetgun.cpp | 8 +- bshift/ichthyosaur.cpp | 6 +- bshift/mp5.cpp | 2 +- bshift/multiplay_gamerules.cpp | 36 +- bshift/player.cpp | 61 +- bshift/player.h | 2 - bshift/python.cpp | 2 +- bshift/rpg.cpp | 10 +- bshift/singleplay_gamerules.cpp | 2 +- bshift/squeakgrenade.cpp | 4 +- bshift/teamplay_gamerules.cpp | 2 + bshift/triggers.cpp | 12 +- bshift/tripmine.cpp | 2 +- bshift/turret.cpp | 2 +- bshift/util.cpp | 28 +- bshift/util.h | 1 - bshift/weapons.cpp | 2 + bshift/world.cpp | 11 +- client/global/dll_int.cpp | 5 +- client/global/ev_common.cpp | 2 +- client/global/r_tempents.cpp | 6 +- common/clgame_api.h | 25 +- common/effects_api.h | 2 - common/entity_def.h | 159 +- common/entity_state.h | 2 +- common/event_api.h | 6 +- common/svgame_api.h | 50 +- common/triangle_api.h | 4 +- engine/client/cl_frame.c | 2 +- engine/client/cl_game.c | 64 +- engine/client/cl_move.c | 4 +- engine/client/cl_view.c | 2 +- engine/client/client.h | 2 +- engine/common.h | 8 - engine/common/con_main.c | 4 +- engine/common/engfuncs.c | 95 -- engine/common/net_encode.c | 35 + engine/common/net_msg.h | 21 + engine/engine.dsp | 4 + engine/server/server.h | 3 + engine/server/sv_client.c | 18 +- engine/server/sv_frame.c | 7 + engine/server/sv_game.c | 199 ++- engine/server/sv_init.c | 1 - engine/server/sv_main.c | 8 + engine/server/sv_move.c | 13 +- engine/server/sv_save.c | 13 +- game_shared/pm_shared.cpp | 11 +- launch/launch.dsp | 4 - launch/library.c | 5 +- server/ents/basefunc.cpp | 4 +- server/ents/baseinfo.cpp | 4 +- server/ents/baseother.cpp | 2 +- server/ents/baserockets.cpp | 4 +- server/ents/basetank.cpp | 4 +- server/ents/basetrigger.cpp | 93 +- server/ents/baseweapon.cpp | 22 +- server/ents/baseworld.cpp | 15 +- server/game/gamerules.cpp | 2 +- server/game/gamerules.h | 6 +- server/game/multiplay_gamerules.cpp | 106 +- server/game/singleplay_gamerules.cpp | 2 +- server/game/teamplay_gamerules.cpp | 7 + server/global/client.cpp | 303 +++- server/global/client.h | 3 +- server/global/dll_int.cpp | 25 +- server/global/enginecallback.h | 12 +- server/global/saverestore.cpp | 7 +- server/global/utils.cpp | 29 +- server/global/utils.h | 3 - server/monsters/nodes.cpp | 386 ++--- server/monsters/nodes.h | 4 +- server/monsters/player.cpp | 39 +- server/monsters/turret.cpp | 4 +- server/server.def | 2 +- spirit/airtank.cpp | 5 +- spirit/barney.cpp | 2 +- spirit/cbase.cpp | 20 +- spirit/cbase.h | 3 + spirit/client.cpp | 271 +++- spirit/client.h | 4 +- spirit/crossbow.cpp | 4 +- spirit/crowbar.cpp | 2 +- spirit/egon.cpp | 2 +- spirit/enginecallback.h | 15 +- spirit/func_tank.cpp | 4 +- spirit/gamerules.cpp | 2 +- spirit/gamerules.h | 6 +- spirit/gauss.cpp | 2 +- spirit/h_export.cpp | 14 + spirit/handgrenade.cpp | 2 +- spirit/hornetgun.cpp | 8 +- spirit/ichthyosaur.cpp | 2230 +++++++++++++------------- spirit/locus.cpp | 2 +- spirit/mp5.cpp | 2 +- spirit/multiplay_gamerules.cpp | 41 +- spirit/nodes.cpp | 190 ++- spirit/nodes.h | 4 +- spirit/player.cpp | 63 +- spirit/player.h | 2 - spirit/python.cpp | 6 +- spirit/rpg.cpp | 10 +- spirit/singleplay_gamerules.cpp | 2 +- spirit/spirit.def | 2 +- spirit/squeakgrenade.cpp | 6 +- spirit/teamplay_gamerules.cpp | 1242 +++++++------- spirit/triggers.cpp | 18 +- spirit/tripmine.cpp | 2 +- spirit/turret.cpp | 2 +- spirit/util.cpp | 34 +- spirit/util.h | 1 - spirit/weapons.cpp | 4 +- spirit/world.cpp | 12 +- 129 files changed, 3805 insertions(+), 2870 deletions(-) create mode 100644 engine/common/net_encode.c diff --git a/bshift/airtank.cpp b/bshift/airtank.cpp index 8d36a003..0bbde7f5 100644 --- a/bshift/airtank.cpp +++ b/bshift/airtank.cpp @@ -105,11 +105,8 @@ void CAirtank::TankTouch( CBaseEntity *pOther ) return; } - CBasePlayer *pPlayer = (CBasePlayer *)CBasePlayer::Instance( pOther->pev ); - if( !pOther ) return; - // give player 12 more seconds of air - pPlayer->m_fAirFinished = gpGlobals->time + 12; + pOther->pev->air_finished = gpGlobals->time + 12; // suit recharge sound EMIT_SOUND( ENT(pev), CHAN_VOICE, "doors/aliendoor3.wav", 1.0, ATTN_NORM ); diff --git a/bshift/barney.cpp b/bshift/barney.cpp index 63c4b8fc..73a6596b 100644 --- a/bshift/barney.cpp +++ b/bshift/barney.cpp @@ -494,7 +494,7 @@ static BOOL IsFacing( entvars_t *pevTest, const Vector &reference ) vecDir.z = 0; vecDir = vecDir.Normalize(); Vector forward, angle; - angle = pevTest->viewangles; + angle = pevTest->v_angle; angle.x = 0; UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL ); // He's facing me, he meant it diff --git a/bshift/bshift.def b/bshift/bshift.def index a895dcba..0f288692 100644 --- a/bshift/bshift.def +++ b/bshift/bshift.def @@ -1,5 +1,5 @@ LIBRARY server EXPORTS - CreateAPI @1 + GiveFnptrsToDll @1 SECTIONS .data READ WRITE diff --git a/bshift/cbase.cpp b/bshift/cbase.cpp index b5de6219..8c34b214 100644 --- a/bshift/cbase.cpp +++ b/bshift/cbase.cpp @@ -29,7 +29,6 @@ extern DLL_GLOBAL int g_iSkillLevel; static DLL_FUNCTIONS gFunctionTable = { - sizeof( DLL_FUNCTIONS ), // Xash3D requires this GameDLLInit, //pfnGameInit DispatchSpawn, //pfnSpawn DispatchThink, //pfnThink @@ -83,13 +82,15 @@ static DLL_FUNCTIONS gFunctionTable = AddToFullPack, // pfnAddtoFullPack EndFrame, // pfnEndFrame - ShouldCollide, // pfnShouldCollide + RegisterEncoders, // pfnRegisterEncoders Callbacks for network encoding + UpdateEntityState, // pfnUpdateEntityState CmdStart, // pfnCmdStart CmdEnd, // pfnCmdEnd OnFreeEntPrivateData, // pfnOnFreeEntPrivateData GameDLLShutdown, // pfnGameShutdown + ShouldCollide, // pfnShouldCollide }; static void SetObjectCollisionBox( entvars_t *pev ); @@ -97,23 +98,17 @@ static void SetObjectCollisionBox( entvars_t *pev ); //======================================================================= // General API entering point //======================================================================= - -int CreateAPI( DLL_FUNCTIONS *pFunctionTable, enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ) { - if( !pFunctionTable || !pengfuncsFromEngine || !pGlobals ) + if ( !pFunctionTable || interfaceVersion != SV_INTERFACE_VERSION ) { return FALSE; } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS )); - memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof( enginefuncs_t )); - gpGlobals = pGlobals; - + + memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); return TRUE; } - - int DispatchSpawn( edict_t *pent ) { CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); diff --git a/bshift/cbase.h b/bshift/cbase.h index 90621a3e..4f02e223 100644 --- a/bshift/cbase.h +++ b/bshift/cbase.h @@ -60,6 +60,9 @@ CBaseEntity #define EXPORT #endif +extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); +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 ); diff --git a/bshift/client.cpp b/bshift/client.cpp index 0fe3bfce..cc15a4fb 100644 --- a/bshift/client.cpp +++ b/bshift/client.cpp @@ -35,6 +35,7 @@ #include "game.h" #include "weapons.h" #include "usercmd.h" +#include "effects.h" extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; extern DLL_GLOBAL BOOL g_fGameOver; @@ -71,9 +72,9 @@ ClientConnect called when a player connects to a server ============ */ -BOOL ClientConnect( edict_t *pEntity, const char *userinfo ) +BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { - return g_pGameRules->ClientConnected( pEntity, userinfo ); + return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason ); // a client connecting during an intermission can cause problems // if (intermission_running) @@ -315,6 +316,34 @@ void Host_Say( edict_t *pEntity, int teamonly ) // echo to server console g_engfuncs.pfnServerPrint( text ); + + char * temp; + if ( teamonly ) + temp = "say_team"; + else + temp = "say"; + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" %s \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pEntity ), "model" ), + temp, + p ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), + temp, + p ); + } } @@ -408,7 +437,7 @@ void ClientCommand( edict_t *pEntity ) else { TraceResult tr; - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000, @@ -526,15 +555,20 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) // team match? if ( g_teamplay ) { - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", - STRING( pEntity->v.netname ), - g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ), + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); } else { - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", - STRING( pEntity->v.netname ), + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); } } @@ -989,7 +1023,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) to->scale = pNet->pev->scale; // shared client and render flags to->movetype = (movetype_t)pNet->pev->movetype; to->frame = pNet->pev->frame; // any model current frame - to->contents = pNet->pev->contents; // physic contents to->framerate = pNet->pev->framerate; to->mins = pNet->pev->mins; to->maxs = pNet->pev->maxs; @@ -1034,8 +1067,8 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) else to->aiment = NULLENT_INDEX; to->viewoffset = pNet->pev->view_ofs; - to->viewangles = pNet->pev->viewangles; - to->idealpitch = pNet->pev->ideal_pitch; + to->viewangles = pNet->pev->v_angle; + to->idealpitch = pNet->pev->idealpitch; to->punch_angles = pNet->pev->punchangle; to->velocity = pNet->pev->velocity; to->basevelocity = pNet->pev->clbasevelocity; @@ -1280,6 +1313,249 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag return 1; } +typedef struct +{ + char name[32]; + int field; +} entity_field_alias_t; + +#define FIELD_ORIGIN0 0 +#define FIELD_ORIGIN1 1 +#define FIELD_ORIGIN2 2 +#define FIELD_ANGLES0 3 +#define FIELD_ANGLES1 4 +#define FIELD_ANGLES2 5 + +static entity_field_alias_t entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, +}; + +void Entity_FieldInit( struct delta_s *pFields ) +{ + entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN0 ].name ); + entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN1 ].name ); + entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN2 ].name ); + entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES0 ].name ); + entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES1 ].name ); + entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES2 ].name ); +} + +/* +================== +Entity_Encode + +Callback for sending entity_state_t info over network. +FIXME: Move to script +================== +*/ +void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +static entity_field_alias_t player_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, +}; + +void Player_FieldInit( struct delta_s *pFields ) +{ + player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN0 ].name ); + player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN1 ].name ); + player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN2 ].name ); +} + +/* +================== +Player_Encode + +Callback for sending entity_state_t for players info over network. +================== +*/ +void Player_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Player_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +#define CUSTOMFIELD_ORIGIN0 0 +#define CUSTOMFIELD_ORIGIN1 1 +#define CUSTOMFIELD_ORIGIN2 2 +#define CUSTOMFIELD_ANGLES0 3 +#define CUSTOMFIELD_ANGLES1 4 +#define CUSTOMFIELD_ANGLES2 5 +#define CUSTOMFIELD_SKIN 6 +#define CUSTOMFIELD_SEQUENCE 7 +#define CUSTOMFIELD_ANIMTIME 8 + +entity_field_alias_t custom_entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, + { "skin", 0 }, + { "sequence", 0 }, + { "animtime", 0 }, +}; + +void Custom_Entity_FieldInit( struct delta_s *pFields ) +{ + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name ); +} + +/* +================== +Custom_Encode + +Callback for sending entity_state_t info ( for custom entities ) over network. +FIXME: Move to script +================== +*/ +void Custom_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int beamType; + static int initialized = 0; + + if ( !initialized ) + { + Custom_Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + beamType = t->rendermode; + + if ( beamType != BEAM_POINTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field ); + } + + if ( beamType != BEAM_POINTS ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field ); + } + + if ( beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field ); + } + + // animtime is compared by rounding first + // see if we really shouldn't actually send it + if ( (int)f->animtime == (int)t->animtime ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field ); + } +} + +/* +================= +RegisterEncoders + +Allows game .dll to override network encoding of certain types of entities and tweak values, etc. +================= +*/ +void RegisterEncoders( void ) +{ + DELTA_ADDENCODER( "Entity_Encode", Entity_Encode ); + DELTA_ADDENCODER( "Custom_Encode", Custom_Encode ); + DELTA_ADDENCODER( "Player_Encode", Player_Encode ); +} + /* ================= CmdStart diff --git a/bshift/client.h b/bshift/client.h index 567c2fe4..4052ac39 100644 --- a/bshift/client.h +++ b/bshift/client.h @@ -16,7 +16,7 @@ #define CLIENT_H extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); -extern BOOL ClientConnect( edict_t *pEntity, const char *userinfo ); +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 ); @@ -30,7 +30,7 @@ extern void PlayerPostThink( edict_t *pEntity ); extern void PlayerPreThink( edict_t *pEntity ); extern void ParmsNewLevel( void ); extern void ParmsChangeLevel( void ); - +extern void RegisterEncoders( void ); extern void ClientPrecache( void ); extern const char *GetGameDescription( void ); diff --git a/bshift/crossbow.cpp b/bshift/crossbow.cpp index d874486a..7ccac45d 100644 --- a/bshift/crossbow.cpp +++ b/bshift/crossbow.cpp @@ -376,7 +376,7 @@ void CCrossbow::FireSniperBolt() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); Vector vecSrc = m_pPlayer->GetGunPosition( ) - gpGlobals->v_up * 2; Vector vecDir = gpGlobals->v_forward; @@ -457,7 +457,7 @@ void CCrossbow::FireBolt() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); // Vector vecSrc = pev->origin + gpGlobals->v_up * 16 + gpGlobals->v_forward * 20 + gpGlobals->v_right * 4; diff --git a/bshift/crowbar.cpp b/bshift/crowbar.cpp index 2a059693..77b74c78 100644 --- a/bshift/crowbar.cpp +++ b/bshift/crowbar.cpp @@ -186,7 +186,7 @@ int CCrowbar::Swing( int fFirst ) TraceResult tr; - UTIL_MakeVectors (m_pPlayer->pev->viewangles); + UTIL_MakeVectors (m_pPlayer->pev->v_angle); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecEnd = vecSrc + gpGlobals->v_forward * 32; diff --git a/bshift/egon.cpp b/bshift/egon.cpp index 94d66b8d..4ff6b449 100644 --- a/bshift/egon.cpp +++ b/bshift/egon.cpp @@ -255,7 +255,7 @@ void CEgon::Attack( void ) return; } - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); diff --git a/bshift/enginecallback.h b/bshift/enginecallback.h index 79ef5dbf..6836512b 100644 --- a/bshift/enginecallback.h +++ b/bshift/enginecallback.h @@ -68,6 +68,7 @@ extern enginefuncs_t g_engfuncs; #define CRC32_FINAL (*g_engfuncs.pfnCRC_Final) #define RANDOM_LONG (*g_engfuncs.pfnRandomLong) #define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #define CLASSIFY_EDICT (*g_engfuncs.pfnClassifyEdict) #define COM_Parse (*g_engfuncs.pfnParseToken) @@ -129,7 +130,6 @@ inline void *GET_PRIVATE( edict_t *pent ) #define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) #define SET_VIEW (*g_engfuncs.pfnSetView) #define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) -#define SET_SKYBOX (*g_engfuncs.pfnSetSkybox) #define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFile) #define FREE_FILE (*g_engfuncs.pfnFreeFile) #define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime) @@ -145,10 +145,20 @@ inline void *GET_PRIVATE( edict_t *pent ) #define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) +#define DELTA_SET ( *g_engfuncs.pfnDeltaSetField ) +#define DELTA_UNSET ( *g_engfuncs.pfnDeltaUnsetField ) +#define DELTA_ADDENCODER ( *g_engfuncs.pfnDeltaAddEncoder ) +#define ENGINE_CURRENT_PLAYER ( *g_engfuncs.pfnGetCurrentPlayer ) + #define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) +#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) + #define ENGINE_CANSKIP ( *g_engfuncs.pfnCanSkipPlayer ) -#define HOST_ENDGAME (*g_engfuncs.pfnEndGame) +#define DELTA_FINDFIELD ( *g_engfuncs.pfnDeltaFindField ) +#define DELTA_SETBYINDEX ( *g_engfuncs.pfnDeltaSetFieldByIndex ) +#define DELTA_UNSETBYINDEX ( *g_engfuncs.pfnDeltaUnsetFieldByIndex ) + #define HOST_ERROR (*g_engfuncs.pfnHostError) #define ENGINE_GETPHYSINFO ( *g_engfuncs.pfnGetPhysicsInfoString ) diff --git a/bshift/func_tank.cpp b/bshift/func_tank.cpp index e8035b1e..bdbb9ff6 100644 --- a/bshift/func_tank.cpp +++ b/bshift/func_tank.cpp @@ -492,7 +492,7 @@ void CFuncTank::TrackTarget( void ) if (m_pController) { // Tanks attempt to mirror the player's angles - angles = m_pController->pev->viewangles; + angles = m_pController->pev->v_angle; angles[0] = 0 - angles[0]; pev->nextthink = pev->ltime + 0.05; } diff --git a/bshift/gamerules.cpp b/bshift/gamerules.cpp index e018e022..0a233db1 100644 --- a/bshift/gamerules.cpp +++ b/bshift/gamerules.cpp @@ -66,7 +66,7 @@ edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer ) edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pPlayer->pev->viewangles = g_vecZero; + pPlayer->pev->v_angle = g_vecZero; pPlayer->pev->velocity = g_vecZero; pPlayer->pev->angles = VARS(pentSpawnSpot)->angles; pPlayer->pev->punchangle = g_vecZero; diff --git a/bshift/gamerules.h b/bshift/gamerules.h index 7d2f0917..cc0ccfa4 100644 --- a/bshift/gamerules.h +++ b/bshift/gamerules.h @@ -75,7 +75,7 @@ public: virtual const char *GetGameDescription( void ) { return "Half-Life"; } // this is the game name that gets seen in the server browser // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ) = 0;// a client just connected to the server (player hasn't spawned yet) + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) = 0;// a client just connected to the server (player hasn't spawned yet) virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode @@ -185,7 +185,7 @@ public: virtual BOOL IsCoOp( void ); // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); @@ -275,7 +275,7 @@ public: // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in // svRejectReason // Only the client's name and remote address are provided to the dll for verification. - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode diff --git a/bshift/gauss.cpp b/bshift/gauss.cpp index eba3df93..93e3cb55 100644 --- a/bshift/gauss.cpp +++ b/bshift/gauss.cpp @@ -348,7 +348,7 @@ void CGauss::StartFire( void ) { float flDamage; - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); // + gpGlobals->v_up * -8 + gpGlobals->v_right * 8; diff --git a/bshift/handgrenade.cpp b/bshift/handgrenade.cpp index 699f669a..6ebe79ea 100644 --- a/bshift/handgrenade.cpp +++ b/bshift/handgrenade.cpp @@ -146,7 +146,7 @@ void CHandGrenade::WeaponIdle( void ) if (m_flStartThrow) { - Vector angThrow = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; if (angThrow.x < 0) angThrow.x = -10 + angThrow.x * ((90 - 10) / 90.0); diff --git a/bshift/hornetgun.cpp b/bshift/hornetgun.cpp index 75b99756..0a5800a1 100644 --- a/bshift/hornetgun.cpp +++ b/bshift/hornetgun.cpp @@ -149,9 +149,9 @@ void CHgun::PrimaryAttack() return; } - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); - CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pHornet->pev->velocity = gpGlobals->v_forward * 300; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; @@ -189,7 +189,7 @@ void CHgun::SecondaryAttack( void ) CBaseEntity *pHornet; Vector vecSrc; - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; @@ -227,7 +227,7 @@ void CHgun::SecondaryAttack( void ) break; } - pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pHornet->pev->velocity = gpGlobals->v_forward * 1200; pHornet->pev->angles = UTIL_VecToAngles( pHornet->pev->velocity ); diff --git a/bshift/ichthyosaur.cpp b/bshift/ichthyosaur.cpp index 0ca85e08..0404a041 100644 --- a/bshift/ichthyosaur.cpp +++ b/bshift/ichthyosaur.cpp @@ -775,14 +775,14 @@ float CIchthyosaur::FlPitchDiff( void ) flCurrentPitch = UTIL_AngleMod( pev->angles.z ); - if ( flCurrentPitch == pev->ideal_pitch ) + if ( flCurrentPitch == pev->idealpitch ) { return 0; } - flPitchDiff = pev->ideal_pitch - flCurrentPitch; + flPitchDiff = pev->idealpitch - flCurrentPitch; - if ( pev->ideal_pitch > flCurrentPitch ) + if ( pev->idealpitch > flCurrentPitch ) { if (flPitchDiff >= 180) flPitchDiff = flPitchDiff - 360; diff --git a/bshift/mp5.cpp b/bshift/mp5.cpp index 729bed0e..cfda06c6 100644 --- a/bshift/mp5.cpp +++ b/bshift/mp5.cpp @@ -239,7 +239,7 @@ void CMP5::SecondaryAttack( void ) EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/glauncher2.wav", 0.8, ATTN_NORM); } - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); // we don't add in player velocity anymore. CGrenade::ShootContact( m_pPlayer->pev, diff --git a/bshift/multiplay_gamerules.cpp b/bshift/multiplay_gamerules.cpp index e7cc674e..be7aa467 100644 --- a/bshift/multiplay_gamerules.cpp +++ b/bshift/multiplay_gamerules.cpp @@ -342,7 +342,7 @@ BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerI //========================================================= //========================================================= -BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } @@ -368,12 +368,17 @@ void CHalfLifeMultiplay :: InitHUD( CBasePlayer *pl ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" entered the game\n", STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pl->edict() ), "model" ) ); } else { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" entered the game\n", - STRING( pl->pev->netname )); + STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), + GETPLAYERUSERID( pl->edict() ) ); } UpdateGameMode( pl ); @@ -428,12 +433,17 @@ void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected\n", STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ) ); } else { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" disconnected\n", - STRING( pPlayer->pev->netname )); + STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + GETPLAYERUSERID( pPlayer->edict() ) ); } pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items @@ -672,6 +682,8 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -679,6 +691,9 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\"\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } @@ -689,8 +704,12 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n", STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( ENT(pKiller) ), "model" ), STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -698,7 +717,13 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\"\n", STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), + GETPLAYERUSERID( ENT(pKiller) ), STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } @@ -711,6 +736,8 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (world)\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -718,6 +745,9 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\" (world)\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } diff --git a/bshift/player.cpp b/bshift/player.cpp index 72c7aebc..3669e93f 100644 --- a/bshift/player.cpp +++ b/bshift/player.cpp @@ -91,8 +91,6 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = DEFINE_FIELD( CBasePlayer, m_flDuckTime, FIELD_TIME ), DEFINE_FIELD( CBasePlayer, m_flWallJumpTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_fAirFinished, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_fPainFinished, FIELD_TIME ), DEFINE_FIELD( CBasePlayer, m_flSuitUpdate, FIELD_TIME ), DEFINE_ARRAY( CBasePlayer, m_rgSuitPlayList, FIELD_INTEGER, CSUITPLAYLIST ), DEFINE_FIELD( CBasePlayer, m_iSuitPlayNext, FIELD_INTEGER ), @@ -380,7 +378,7 @@ int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) Vector CBasePlayer :: GetGunPosition( ) { -// UTIL_MakeVectors(pev->viewangles); +// UTIL_MakeVectors(pev->v_angle); // m_HackedGunPos = pev->view_ofs; Vector origin; @@ -1118,12 +1116,12 @@ void CBasePlayer::WaterMove() // not underwater // play 'up for air' sound - if (m_fAirFinished < gpGlobals->time) + if (pev->air_finished < gpGlobals->time) EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM); - else if (m_fAirFinished < gpGlobals->time + 9) + else if (pev->air_finished < gpGlobals->time + 9) EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM); - m_fAirFinished = gpGlobals->time + AIRTIME; + pev->air_finished = gpGlobals->time + AIRTIME; pev->dmg = 2; // if we took drowning damage, give it back slowly @@ -1148,16 +1146,16 @@ void CBasePlayer::WaterMove() m_bitsDamageType &= ~DMG_DROWNRECOVER; m_rgbTimeBasedDamage[itbd_DrownRecover] = 0; - if (m_fAirFinished < gpGlobals->time) // drown! + if (pev->air_finished < gpGlobals->time) // drown! { - if (m_fPainFinished < gpGlobals->time) + if (pev->pain_finished < gpGlobals->time) { // take drowning damage pev->dmg += 1; if (pev->dmg > 5) pev->dmg = 5; TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN); - m_fPainFinished = gpGlobals->time + 1; + pev->pain_finished = gpGlobals->time + 1; // track drowning damage, give it back when // player finally takes a breath @@ -1193,7 +1191,7 @@ void CBasePlayer::WaterMove() // make bubbles - air = (int)(m_fAirFinished - gpGlobals->time); + air = (int)(pev->air_finished - gpGlobals->time); if (!RANDOM_LONG(0,0x1f) && RANDOM_LONG(0,AIRTIME-1) >= air) { switch (RANDOM_LONG(0,3)) @@ -1363,7 +1361,7 @@ void CBasePlayer::StartDeathCam( void ) } CopyToBodyQue( pev ); - StartObserver( pSpot->v.origin, pSpot->v.viewangles ); + StartObserver( pSpot->v.origin, pSpot->v.v_angle ); } else { @@ -1381,7 +1379,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) m_afPhysicsFlags |= PFLAG_OBSERVER; pev->view_ofs = g_vecZero; - pev->angles = pev->viewangles = vecViewAngle; + pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; @@ -1442,7 +1440,7 @@ void CBasePlayer::PlayerUse ( void ) float flMaxDot = VIEW_FIELD_NARROW; float flDot; - UTIL_MakeVectors ( pev->viewangles );// so we know which way we are facing + UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing while ((pObject = UTIL_FindEntityInSphere( pObject, pev->origin, PLAYER_SEARCH_RADIUS )) != NULL) { @@ -2001,7 +1999,7 @@ void CBasePlayer::PreThink(void) if ( g_fGameOver ) return; // intermission or finale - UTIL_MakeVectors(pev->viewangles); // is this still used? + UTIL_MakeVectors(pev->v_angle); // is this still used? ItemPreFrame( ); WaterMove(); @@ -2947,7 +2945,7 @@ void CBasePlayer::Spawn( void ) pev->max_health = pev->health; pev->flags &= FL_PROXY; // keep proxy flag sey by engine pev->flags = FL_CLIENT; - m_fAirFinished = gpGlobals->time + 12; + pev->air_finished = gpGlobals->time + 12; pev->dmg = 2; // initial water damage pev->effects = 0; pev->deadflag = DEAD_NO; @@ -2958,8 +2956,7 @@ void CBasePlayer::Spawn( void ) pev->gravity = 1.0; pev->renderfx = 0; pev->rendercolor = g_vecZero; - pev->mass = 90; // lbs - pev->viewangles.z = 0; // cut off any camera rolling + pev->v_angle.z = 0; // cut off any camera rolling m_bitsHUDDamage = -1; m_bitsDamageType = 0; m_afPhysicsFlags = 0; @@ -3115,8 +3112,8 @@ int CBasePlayer::Restore( CRestore &restore ) pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); pev->angles = VARS(pentSpawnSpot)->angles; } - pev->viewangles.z = 0; // Clear out roll - pev->angles = pev->viewangles; + pev->v_angle.z = 0; // Clear out roll + pev->angles = pev->v_angle; pev->fixangle = TRUE; // turn this way immediately @@ -3312,7 +3309,7 @@ public: void CSprayCan::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); pev->frame = 0; @@ -3368,7 +3365,7 @@ public: void CBloodSplat::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); SetThink ( Spray ); @@ -3419,7 +3416,7 @@ CBaseEntity *FindEntityForward( CBaseEntity *pMe ) { TraceResult tr; - UTIL_MakeVectors(pMe->pev->viewangles); + UTIL_MakeVectors(pMe->pev->v_angle); UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192,dont_ignore_monsters, pMe->edict(), &tr ); if ( tr.flFraction != 1.0 && !FNullEnt( tr.pHit) ) { @@ -3555,7 +3552,7 @@ void CBasePlayer::ImpulseCommands( ) break; } - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); if ( tr.flFraction != 1.0 ) @@ -3602,7 +3599,7 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse ) } else { - UTIL_MakeVectors( Vector( 0, pev->viewangles.y, 0 ) ); + UTIL_MakeVectors( Vector( 0, pev->v_angle.y, 0 ) ); Create("monster_human_grunt", pev->origin + gpGlobals->v_forward * 128, pev->angles); } break; @@ -3736,7 +3733,7 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse ) } break; case 202:// Random blood splatter - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); if ( tr.flFraction != 1.0 ) @@ -4297,7 +4294,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta ) { if (g_iSkillLevel == SKILL_HARD) { - UTIL_MakeVectors( pev->viewangles + pev->punchangle ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle ); return gpGlobals->v_forward; } @@ -4370,7 +4367,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta ) // ALERT( at_console, "%f %f\n", angles.x, angles.y ); - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); return gpGlobals->v_forward; } @@ -4390,7 +4387,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD return g_vecZero; } - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); // try all possible entities bestdir = gpGlobals->v_forward; @@ -4487,7 +4484,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD { bestdir = UTIL_VecToAngles (bestdir); bestdir.x = -bestdir.x; - bestdir = bestdir - pev->viewangles - pev->punchangle; + bestdir = bestdir - pev->v_angle - pev->punchangle; if (bestent->v.takedamage == DAMAGE_AIM) m_fOnTarget = TRUE; @@ -4899,7 +4896,7 @@ void CInfoIntermission::Spawn( void ) UTIL_SetOrigin( pev, pev->origin ); pev->solid = SOLID_NOT; pev->effects = EF_NODRAW; - pev->viewangles = g_vecZero; + pev->v_angle = g_vecZero; pev->nextthink = gpGlobals->time + 2;// let targets spawn! @@ -4914,8 +4911,8 @@ void CInfoIntermission::Think ( void ) if ( !FNullEnt(pTarget) ) { - pev->viewangles = UTIL_VecToAngles( (pTarget->v.origin - pev->origin).Normalize() ); - pev->viewangles.x = -pev->viewangles.x; + pev->v_angle = UTIL_VecToAngles( (pTarget->v.origin - pev->origin).Normalize() ); + pev->v_angle.x = -pev->v_angle.x; } } diff --git a/bshift/player.h b/bshift/player.h index 4221abea..a827b675 100644 --- a/bshift/player.h +++ b/bshift/player.h @@ -135,8 +135,6 @@ public: EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink()) - float m_fAirFinished; // moved here from progdefs.h - float m_fPainFinished; // moved here from progdefs.h float m_flViewHeight; // keep value from view_ofs.z that engine sets it when player first entering in multiplayer BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true. BOOL m_fLongJump; // does this player have the longjump module? diff --git a/bshift/python.cpp b/bshift/python.cpp index ac740572..aeff41db 100644 --- a/bshift/python.cpp +++ b/bshift/python.cpp @@ -201,7 +201,7 @@ void CPython::PrimaryAttack() m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); diff --git a/bshift/rpg.cpp b/bshift/rpg.cpp index 04207172..1ea58eba 100644 --- a/bshift/rpg.cpp +++ b/bshift/rpg.cpp @@ -558,12 +558,12 @@ void CRpg::PrimaryAttack() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; - CRpgRocket *pRocket = CRpgRocket::CreateRpgRocket( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this ); + CRpgRocket *pRocket = CRpgRocket::CreateRpgRocket( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles );// RpgRocket::Create stomps on globals, so remake. + UTIL_MakeVectors( m_pPlayer->pev->v_angle );// RpgRocket::Create stomps on globals, so remake. pRocket->pev->velocity = pRocket->pev->velocity + gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward ); // firing RPG no longer turns on the designator. ALT fire is a toggle switch for the LTD. @@ -654,8 +654,8 @@ void CRpg::UpdateSpot( void ) m_pSpot = CLaserSpot::CreateSpot( m_pPlayer->pev ); } - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); - Vector vecSrc = m_pPlayer->GetGunPosition( );; + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; diff --git a/bshift/singleplay_gamerules.cpp b/bshift/singleplay_gamerules.cpp index 8a5cb1b7..4e161aaf 100644 --- a/bshift/singleplay_gamerules.cpp +++ b/bshift/singleplay_gamerules.cpp @@ -92,7 +92,7 @@ BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem //========================================================= //========================================================= -BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } diff --git a/bshift/squeakgrenade.cpp b/bshift/squeakgrenade.cpp index 273ef2ee..60419310 100644 --- a/bshift/squeakgrenade.cpp +++ b/bshift/squeakgrenade.cpp @@ -512,7 +512,7 @@ void CSqueak::PrimaryAttack() { if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) { - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); TraceResult tr; Vector trace_origin; @@ -533,7 +533,7 @@ void CSqueak::PrimaryAttack() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pSqueak->pev->velocity = gpGlobals->v_forward * 200 + m_pPlayer->pev->velocity; diff --git a/bshift/teamplay_gamerules.cpp b/bshift/teamplay_gamerules.cpp index 0f65d84d..bc733e0c 100644 --- a/bshift/teamplay_gamerules.cpp +++ b/bshift/teamplay_gamerules.cpp @@ -320,6 +320,8 @@ void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infob UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", STRING(pPlayer->pev->netname), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), pPlayer->m_szTeamName, mdls ); diff --git a/bshift/triggers.cpp b/bshift/triggers.cpp index b893a2d4..34a601e1 100644 --- a/bshift/triggers.cpp +++ b/bshift/triggers.cpp @@ -934,7 +934,7 @@ void CBaseTrigger :: HurtTouch ( CBaseEntity *pOther ) { if ( pev->dmgtime > gpGlobals->time ) { - if ( gpGlobals->time != pev->dmg_take ) + if ( gpGlobals->time != pev->pain_finished ) {// too early to hurt again, and not same frame with a different entity if ( pOther->IsPlayer() ) { @@ -970,7 +970,7 @@ void CBaseTrigger :: HurtTouch ( CBaseEntity *pOther ) } else // Original code -- single player { - if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->dmg_take ) + if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) {// too early to hurt again, and not same frame with a different entity return; } @@ -1007,7 +1007,7 @@ void CBaseTrigger :: HurtTouch ( CBaseEntity *pOther ) pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict ); // Store pain time so we can get all of the other entities on this frame - pev->dmg_take = gpGlobals->time; + pev->pain_finished = gpGlobals->time; // Apply damage every half second pev->dmgtime = gpGlobals->time + 0.5;// half second delay until this trigger can hurt toucher again @@ -1909,7 +1909,7 @@ void CBaseTrigger :: TeleportTouch( CBaseEntity *pOther ) if ( pOther->IsPlayer() ) { - pevToucher->viewangles = pentTarget->v.angles; + pevToucher->v_angle = pentTarget->v.angles; } pevToucher->fixangle = TRUE; @@ -1993,7 +1993,7 @@ void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pC if ( pev->message ) { - HOST_ENDGAME( STRING( pev->message )); + g_engfuncs.pfnEndSection(STRING(pev->message)); } UTIL_Remove( this ); } @@ -2024,7 +2024,7 @@ void CTriggerEndSection::EndSectionTouch( CBaseEntity *pOther ) if (pev->message) { - HOST_ENDGAME( STRING( pev->message )); + g_engfuncs.pfnEndSection(STRING(pev->message)); } UTIL_Remove( this ); } diff --git a/bshift/tripmine.cpp b/bshift/tripmine.cpp index 8c7e006e..70d14913 100644 --- a/bshift/tripmine.cpp +++ b/bshift/tripmine.cpp @@ -445,7 +445,7 @@ void CTripmine::PrimaryAttack( void ) if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) return; - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = gpGlobals->v_forward; diff --git a/bshift/turret.cpp b/bshift/turret.cpp index b7ae83ad..19dc0735 100644 --- a/bshift/turret.cpp +++ b/bshift/turret.cpp @@ -367,7 +367,7 @@ void CBaseTurret::Initialize(void) m_flStartYaw = pev->angles.y; if (m_iOrientation == 1) { - pev->ideal_pitch = 180; + pev->idealpitch = 180; pev->angles.x = 180; pev->view_ofs.z = -pev->view_ofs.z; pev->effects |= EF_INVLIGHT; diff --git a/bshift/util.cpp b/bshift/util.cpp index 71f52a49..c69336fa 100644 --- a/bshift/util.cpp +++ b/bshift/util.cpp @@ -71,27 +71,6 @@ char *COM_ParseToken( const char **data ) return com_token; } -void PLAYBACK_EVENT_FULL( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) -{ - event_args_t args; - - args.flags = 0; - if( !FNullEnt( pInvoker )) - args.entindex = ENTINDEX( (edict_t *)pInvoker ); - else args.entindex = 0; - origin.CopyToArray( args.origin ); - angles.CopyToArray( args.angles ); - // don't add velocity - engine will be reset it for some reasons - args.fparam1 = fparam1; - args.fparam2 = fparam2; - args.iparam1 = iparam1; - args.iparam2 = iparam2; - args.bparam1 = bparam1; - args.bparam2 = bparam2; - - g_engfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, &args ); -} - /* ===================== UTIL_WeaponTimeBase @@ -257,9 +236,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ), + DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( fixangle, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( ideal_pitch, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ), @@ -349,6 +328,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ), }; #define ENTVARS_COUNT (sizeof(gEntvarsDescription)/sizeof(gEntvarsDescription[0])) diff --git a/bshift/util.h b/bshift/util.h index 00b3b873..a73f1cac 100644 --- a/bshift/util.h +++ b/bshift/util.h @@ -519,7 +519,6 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); #define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -extern void PLAYBACK_EVENT_FULL( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); #define GROUP_OP_AND 0 diff --git a/bshift/weapons.cpp b/bshift/weapons.cpp index 493dfb3a..23dc46b3 100644 --- a/bshift/weapons.cpp +++ b/bshift/weapons.cpp @@ -851,6 +851,8 @@ void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) if ( skiplocal && ENGINE_CANSKIP( m_pPlayer->edict() ) ) return; + m_pPlayer->pev->weaponanim = iAnim; + float framerate = 1.0f; // play speed 1.x MESSAGE_BEGIN( MSG_ONE, SVC_WEAPONANIM, NULL, m_pPlayer->pev ); diff --git a/bshift/world.cpp b/bshift/world.cpp index d208ab52..400a136b 100644 --- a/bshift/world.cpp +++ b/bshift/world.cpp @@ -508,15 +508,6 @@ void CWorld :: Precache( void ) { ALERT ( at_console, "**COULD NOT CREATE SOUNDENT**\n" ); } - - if( pev->target != 0 ) - { - SET_SKYBOX( STRING( pev->target )); - } - else - { - SET_SKYBOX( "desert" ); // it's a default Half-Life skybox, right ? - } InitBodyQue(); @@ -693,7 +684,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd ) if ( FStrEq(pkvd->szKeyName, "skyname") ) { // Sent over net now. - pev->target = ALLOC_STRING( pkvd->szValue ); + CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "sounds") ) diff --git a/client/global/dll_int.cpp b/client/global/dll_int.cpp index d3d1fc31..e7daaace 100644 --- a/client/global/dll_int.cpp +++ b/client/global/dll_int.cpp @@ -30,7 +30,6 @@ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) static HUD_FUNCTIONS gFunctionTable = { - sizeof( HUD_FUNCTIONS ), HUD_VidInit, HUD_Init, HUD_Redraw, @@ -222,7 +221,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti ent->v.solid = state->solid; ent->v.movetype = state->movetype; ent->v.flags = state->flags; - ent->v.ideal_pitch = state->idealpitch; + ent->v.idealpitch = state->idealpitch; ent->v.animtime = state->animtime; ent->v.ltime = state->localtime; @@ -271,7 +270,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti { case ED_CLIENT: ent->v.punchangle = LerpAngle( prev->punch_angles, state->punch_angles, m_fLerp ); - ent->v.viewangles = LerpAngle( prev->viewangles, state->viewangles, m_fLerp ); + ent->v.v_angle = LerpAngle( prev->viewangles, state->viewangles, m_fLerp ); ent->v.view_ofs = LerpPoint( prev->viewoffset, state->viewoffset, m_fLerp ); if( prev->fov != 90.0f && state->fov == 90.0f ) diff --git a/client/global/ev_common.cpp b/client/global/ev_common.cpp index 18e10e3e..0a4fb7ec 100644 --- a/client/global/ev_common.cpp +++ b/client/global/ev_common.cpp @@ -181,7 +181,7 @@ void EV_UpadteFlashlight( edict_t *pEnt ) float rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; TraceResult tr; - AngleVectors( pEnt->v.viewangles, forward, NULL, NULL ); + AngleVectors( pEnt->v.v_angle, forward, NULL, NULL ); vecSrc = pEnt->v.origin +pEnt->v.view_ofs; vecEnd = vecSrc + forward * 512; diff --git a/client/global/r_tempents.cpp b/client/global/r_tempents.cpp index 3c29c736..cf8214a0 100644 --- a/client/global/r_tempents.cpp +++ b/client/global/r_tempents.cpp @@ -487,9 +487,9 @@ void CTempEnts::TempEntFree( TEMPENTITY *pTemp, TEMPENTITY *pPrev ) // Cleanup its data. if( pTemp->pvEngineData ) { - // its engine memory block with extradata - // if we will be used 'free' or 'delete' - // engine will be crashed on next memory checking!!! + // it's engine memory block with extradata + // if it will be released with 'free' or 'delete' + // is engine immediately crashed on next memory checking!!! FREE( pTemp->pvEngineData ); } diff --git a/common/clgame_api.h b/common/clgame_api.h index d236b2a8..c120e1c5 100644 --- a/common/clgame_api.h +++ b/common/clgame_api.h @@ -84,10 +84,6 @@ typedef struct cl_globalvars_s float frametime; string_t mapname; - BOOL deathmatch; - BOOL coop; - BOOL teamplay; - ref_params_t *pViewParms; // just for easy acess on client float viewheight[PM_MAXHULLS]; // values from gameinfo.txt @@ -107,9 +103,6 @@ typedef struct cl_globalvars_s typedef struct cl_enginefuncs_s { - // interface validator - size_t api_size; // must matched with sizeof(cl_enginefuncs_t) - // sprite handlers HSPRITE (*pfnSPR_Load)( const char *szPicName ); int (*pfnSPR_Frames)( HSPRITE hPic ); @@ -201,14 +194,13 @@ typedef struct cl_enginefuncs_s void (*pfnTraceModel)( const float *v1, const float *v2, edict_t *pent, TraceResult *ptr ); // was GetSpritePointer const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 ); // was pfnPlaySoundByNameAtLocation - // filesystem handlers (event calls is completely moved to pEventAPI. see common\event_api.h for details) - void* (*pfnFOpen)( const char* path, const char* mode ); // was pfnPrecacheEvent - long (*pfnFRead)( void *file, void* buffer, size_t buffersize ); // was pfnPlaybackEvent - long (*pfnFWrite)(void *file, const void* data, size_t datasize);// was pfnWeaponAnim - int (*pfnFClose)( void *file ); // was pfnRandomFloat - int (*pfnFGets)( void *file, byte *string, size_t bufsize ); // was pfnRandomLong - int (*pfnFSeek)( void *file, long offset, int whence ); // was pfnHookEvent - long (*pfnFTell)( void *file ); // was Con_IsVisible + 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 ); + void (*pfnWeaponAnim)( int iAnim, int body, float framerate ); + float (*pfnRandomFloat)( float flLow, float flHigh ); + long (*pfnRandomLong)( long lLow, long lHigh ); + void (*pfnHookEvent)( const char *name, void ( *pfnEvent )( struct event_args_s *args )); + int (*Con_IsVisible)( void ); // dlls managemenet void* (*pfnLoadLibrary)( const char *name ); // was pfnGetGameDirectory @@ -238,9 +230,6 @@ typedef struct cl_enginefuncs_s typedef struct { - // interface validator - size_t api_size; // must matched with sizeof(HUD_FUNCTIONS) - int (*pfnVidInit)( void ); void (*pfnInit)( void ); int (*pfnRedraw)( float flTime, int state ); diff --git a/common/effects_api.h b/common/effects_api.h index f98c760b..ad0eb8b8 100644 --- a/common/effects_api.h +++ b/common/effects_api.h @@ -17,8 +17,6 @@ struct particle_s typedef struct efxapi_s { - size_t api_size; // must match with sizeof( efxapi_t ); - particle_t *(*R_AllocParticle)( void ); void (*R_BlobExplosion)( const float *org ); void (*R_EntityParticles)( edict_t *ent ); diff --git a/common/entity_def.h b/common/entity_def.h index e829678b..369d3368 100644 --- a/common/entity_def.h +++ b/common/entity_def.h @@ -5,147 +5,164 @@ #ifndef ENTITY_DEF_H #define ENTITY_DEF_H -// Legend: -// ENG - engine can modify this variable for some reasons [only -// NET - field that shared on client across network -// Modifiers: -// [player] - all notify for this field is valid only for client entity -// [all] - valid for all ents -// [phys] - valid only for rigid bodies -// [solid] - only for solid entities -// [push] - only ents with SOLID_BSP and MOVETYPE_PUSH have affect on this field - typedef struct entvars_s { - string_t classname; // ENG [all], NET [all] + string_t classname; string_t globalname; // global entity name transmitted across levels - vec3_t origin; // ENG [all], NET [all] - vec3_t oldorigin; // ENG [all], NET [all] + vec3_t origin; + vec3_t oldorigin; vec3_t velocity; vec3_t basevelocity; - vec3_t clbasevelocity; // ENG [player], NET [player] - + vec3_t clbasevelocity; // Base velocity that was passed in to server physics so + // client can predict conveyors correctly. + // Server zeroes it, so we need to store here, too. vec3_t movedir; - vec3_t angles; // ENG [all], NET [all] - vec3_t oldangles; // ENG [all], NET [all] + vec3_t angles; + vec3_t oldangles; vec3_t avelocity; // angular velocity (degrees per second) - vec3_t punchangle; // NET [player], auto-decaying view angle adjustment - vec3_t viewangles; // NET [player], viewing angle (old name was v_angle) + vec3_t punchangle; // auto-decaying view angle adjustment + vec3_t v_angle; // Viewing angle (player only) int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity - float ideal_pitch; + float idealpitch; float pitch_speed; float ideal_yaw; float yaw_speed; - int modelindex; // ENG [all], NET [all] + int modelindex; string_t model; // model name string_t viewmodel; // player's viewmodel (no network updates) - string_t weaponmodel; // NET [all] - sending weaponmodel index, not name + string_t weaponmodel; // what other players see - vec3_t absmin; // ENG [all] - pfnSetAbsBox passed to modify this values - vec3_t absmax; // ENG [all] - pfnSetAbsBox passed to modify this values - vec3_t mins; // ENG [all], NET [solid] - vec3_t maxs; // ENG [all], NET [solid] - vec3_t size; // ENG [all], restored on client-side from mins-maxs + vec3_t absmin; // BB max translated to world coord + vec3_t absmax; // BB max translated to world coord + vec3_t mins; // local BB min + vec3_t maxs; // local BB max + vec3_t size; // maxs - mins - float ltime; // [push] + float ltime; float nextthink; // time to next call of think function - int movetype; // ENG [all], NET [all] - int solid; // ENG [all], NET [all] + int movetype; + int solid; - int skin; // NET [all] - int body; // NET [all], sub-model selection for studiomodels - int weaponbody; // NET [all], sub-model selection for weaponmodel - int weaponskin; // NET [all], - int effects; // ENG [all], NET [all] + int skin; + int body; // sub-model selection for studiomodels + int effects; float gravity; // % of "normal" gravity float friction; // inverse elasticity of MOVETYPE_BOUNCE - float speed; - float mass; // [phys] physic mass int light_level; // entity current lightlevel - int sequence; // ENG [all], NET [all], animation sequence - int gaitsequence; // NET [player], movement animation sequence for player (0 for none) - float frame; // NET [all], % playback position in animation sequences (0..255) - float animtime; // NET [all], world time when frame was set - float framerate; // NET [all], animation playback rate (-8x to 8x) - byte controller[16]; // NET [all], bone controller setting (0..255) - byte blending[16]; // NET [all], blending amount between sub-sequences (0..255) + int sequence; // animation sequence + int gaitsequence; // movement animation sequence for player (0 for none) + float frame; // % playback position in animation sequences (0..255) + float animtime; // world time when frame was set + float framerate; // animation playback rate (-8x to 8x) + byte controller[16]; // bone controller setting (0..255) + byte blending[16]; // blending amount between sub-sequences (0..255) - float scale; // NET [all], sprites and models rendering scale (0..255) - int rendermode; // NET [all] - float renderamt; // NET [all] - vec3_t rendercolor; // NET [all] - int renderfx; // NET [all] + float scale; // sprites and models rendering scale (0..255) + int rendermode; + float renderamt; + vec3_t rendercolor; + int renderfx; - float fov; // NET [player], client fov, used instead m_iFov - float health; // NET [player] + float health; float frags; - int weapons; // NET [player], bit mask for available weapons - int items; // from Q1, can use for holdable items or user flags + int weapons; // bit mask for available weapons float takedamage; - float maxspeed; // NET [player], uses to limit speed for current client int deadflag; - vec3_t view_ofs; // NET [player], eye position + vec3_t view_ofs; // eye position int button; int impulse; - edict_t *chain; // linked list for EntitiesInPHS\PVS + edict_t *chain; // linked list for EntitiesInPVS\PHS edict_t *dmg_inflictor; edict_t *enemy; - edict_t *aiment; // NET [all], entity pointer when MOVETYPE_FOLLOW - edict_t *owner; // NET [all] - edict_t *groundentity; // NET [all], only if FL_ONGROUND is set + edict_t *aiment; // entity pointer when MOVETYPE_FOLLOW + edict_t *owner; + edict_t *groundentity; // only if FL_ONGROUND is set int spawnflags; // spwanflags are used only during level loading int flags; // generic flags that can be send to client short colormap; // lowbyte topcolor, highbyte bottomcolor - int team; // ENG [player], NET [player], for teamplay + int team; // for teamplay float max_health; - float teleport_time; // ENG [all], NET [all], engine will be reset value on next frame + float teleport_time; // engine will be reset this value on next frame int armortype; float armorvalue; - int waterlevel; // ENG [all] - int watertype; // ENG [all] - int contents; // hl-coders: use this instead of pev->skin, to set entity contents + int waterlevel; + int watertype; string_t target; // various server strings string_t targetname; string_t netname; string_t message; - string_t noise; - string_t noise1; - string_t noise2; - string_t noise3; float dmg_take; float dmg_save; float dmg; float dmgtime; - edict_t *pContainingEntity; // filled by engine, don't save, don't modifiy + string_t noise; + string_t noise1; + string_t noise2; + string_t noise3; + float speed; + float air_finished; + float pain_finished; + float radsuit_finished; + + edict_t *pContainingEntity; // filled by engine, don't save, don't modifiy + + int playerclass; + float maxspeed; // uses to limit speed for current client + + 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 bInDuck; int flTimeStepSound; // Next time we can play a step sound int flSwimTime; // In process of ducking or ducked already? int flDuckTime; // Time we started duck int iStepLeft; // 0 - 4 - float flJumpPadTime; // for scale falling damage float flFallVelocity; // falling velocity z + + int gamestate; int oldbuttons; // buttons last usercmd int groupinfo; // entities culling (on server) - int iSpecMode; // OBS_ROAMING etc (was iuser1) + + // for mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + + float fuser1; + float fuser2; + float fuser3; + float fuser4; + + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; + + edict_t *euser1; + edict_t *euser2; + edict_t *euser3; + edict_t *euser4; } entvars_t; diff --git a/common/entity_state.h b/common/entity_state.h index daf810ac..f9f7cdfd 100644 --- a/common/entity_state.h +++ b/common/entity_state.h @@ -36,7 +36,7 @@ typedef enum typedef struct entity_state_s { // engine specific - uint number; // edict index + 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 diff --git a/common/event_api.h b/common/event_api.h index 68abf372..b88ec616 100644 --- a/common/event_api.h +++ b/common/event_api.h @@ -5,6 +5,8 @@ #ifndef EVENT_API_H #define EVENT_API_H +#define EVENT_API_VERSION 1 + #define FEV_NOTHOST (1<<0) // skip local host for event send. #define FEV_RELIABLE (1<<1) // send the event reliably. #define FEV_GLOBAL (1<<2) // don't restrict to PAS/PVS, send this event to _everybody_ on the server @@ -36,9 +38,9 @@ typedef void (*pfnEventHook)( event_args_t *args ); typedef struct event_api_s { - size_t api_size; // must match with sizeof( event_api_t ); + int version; word (*EV_PrecacheEvent)( int type, const char* psz ); - void (*EV_PlaybackEvent)( int flags, const edict_t *pInvoker, word eventindex, float delay, event_args_t *args ); + void (*EV_PlaybackEvent)( 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 ); void (*EV_WeaponAnim)( int iAnim, int body, float framerate ); float (*EV_RandomFloat)( float flLow, float flHigh ); long (*EV_RandomLong)( long lLow, long lHigh ); diff --git a/common/svgame_api.h b/common/svgame_api.h index 1d534fa7..7e29fbd0 100644 --- a/common/svgame_api.h +++ b/common/svgame_api.h @@ -8,6 +8,8 @@ #include "trace_def.h" #include "pm_shared.h" +#define SV_INTERFACE_VERSION 140 + typedef struct globalvars_s { float time; @@ -42,7 +44,7 @@ typedef struct globalvars_s int trace_hitgroup; int trace_flags; - int changelevel; // transition in progress when true + int changelevel; // transition in progress when true (was msg_entity) int numEntities; // actual ents count (was cdAudioTrack) int maxClients; int maxEntities; @@ -56,9 +58,6 @@ typedef struct globalvars_s // engine hands this to DLLs for functionality callbacks typedef struct enginefuncs_s { - // interface validator - int api_size; // must matched with sizeof( enginefuncs_t ) - int (*pfnPrecacheModel)( const char* s ); int (*pfnPrecacheSound)( const char* s ); void (*pfnSetModel)( edict_t *e, const char *m ); @@ -121,7 +120,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 (*pfnEngineFprintf)( void *pfile, char *szFmt, ... ); + void* (*pfnGetProcAddress)( void *hInstance, const char *name ); // was pfnEngineFprintf void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb ); void* (*pfnPvEntPrivateData)( edict_t *pEdict ); void (*pfnFreeEntPrivateData)( edict_t *pEdict ); @@ -156,14 +155,14 @@ typedef struct enginefuncs_s void (*pfnCrosshairAngle)( const edict_t *pClient, float pitch, float yaw ); byte* (*pfnLoadFile)( const char *filename, int *pLength ); void (*pfnFreeFile)( void *buffer ); - void (*pfnEndGame)( const char *engine_command ); // was pfnEndSection + 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 (*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 (*pfnThinkFakeClient)( edict_t *client, usercmd_t *cmd ); // was pfnRunPlayerMove, like it + 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 char* (*pfnGetInfoKeyBuffer)( edict_t *e ); // passing in NULL gets the serverinfo char* (*pfnInfoKeyValue)( char *infobuffer, char *key ); @@ -172,7 +171,7 @@ typedef struct enginefuncs_s int (*pfnIsMapValid)( char *filename ); void (*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex ); int (*pfnPrecacheGeneric)( const char* s ); - void (*pfnSetSkybox)( const char *name ); // was pfnGetPlayerUserId + 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 int (*pfnIsDedicatedServer)( void ); // is this a dedicated server? void* (*pfnMemAlloc)(size_t cb, const char *file, const int line);// was pfnCVarGetPointer @@ -182,18 +181,18 @@ typedef struct enginefuncs_s 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, struct event_args_s *args ); + 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 ); int (*pfnCheckVisibility)( const edict_t *entity, byte *pset ); - void* (*pfnFOpen)( const char* path, const char* mode ); // was pfnDeltaSetField - long (*pfnFRead)( void *file, void* buffer, size_t buffersize ); // was pfnDeltaUnsetField - long (*pfnFWrite)(void *file, const void* data, size_t datasize);// was pfnDeltaAddEncoder - int (*pfnFClose)( void *file ); // was pfnGetCurrentPlayer + void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname ); + void (*pfnDeltaUnsetField)( struct delta_s *pFields, const char *fieldname ); + void (*pfnDeltaAddEncoder)( char *name, void (*conditionalencode)( struct delta_s *pFields, const byte *from, const byte *to )); + int (*pfnGetCurrentPlayer)( void ); int (*pfnCanSkipPlayer)( const edict_t *player ); - int (*pfnFGets)( void *file, byte *string, size_t bufsize ); // was fnDeltaFindField - int (*pfnFSeek)( void *file, long offset, int whence ); // was pfnDeltaSetFieldByIndex - long (*pfnFTell)( void *file ); // was pfnDeltaUnsetFieldByIndex + int (*pfnDeltaFindField)( struct delta_s *pFields, const char *fieldname ); + 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 @@ -201,9 +200,9 @@ typedef struct enginefuncs_s 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* (*pfnGetProcAddress)( void *hInstance, const char *name ); // was pfnVoice_SetClientListening - void (*pfnFreeLibrary)( void *hInstance ); // was pfnGetPlayerAuthId - // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 + 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 } enginefuncs_t; // passed to pfnKeyValue @@ -313,9 +312,6 @@ typedef struct typedef struct { - // interface validator - size_t api_size; // must matched with sizeof(DLL_FUNCTIONS) - // initialize/shutdown the game (one-time call after loading of game .dll ) void (*pfnGameInit)( void ); int (*pfnSpawn)( edict_t *pent ); @@ -334,7 +330,7 @@ typedef struct void (*pfnRestoreGlobalState)( SAVERESTOREDATA * ); void (*pfnResetGlobalState)( void ); - int (*pfnClientConnect)( edict_t *pEntity, const char *userinfo ); + int (*pfnClientConnect)( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); void (*pfnClientDisconnect)( edict_t *pEntity ); void (*pfnClientKill)( edict_t *pEntity ); @@ -368,15 +364,19 @@ typedef struct int (*pfnPhysicsEntity)( edict_t *pEntity ); // was pfnUpdateClientData int (*pfnAddToFullPack)( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflags, byte *pSet ); void (*pfnEndFrame)( void ); // was pfnCreateBaseline - int (*pfnShouldCollide)( edict_t *pTouch, edict_t *pOther ); // was pfnRegisterEncoders + void (*pfnRegisterEncoders)( void ); void (*pfnUpdateEntityState)( struct entity_state_s *to, edict_t *from, int baseline ); // was pfnGetWeaponData void (*pfnCmdStart)( const edict_t *player, const usercmd_t *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 void (*pfnGameShutdown)( void ); // was pfnGetHullBounds + int (*pfnShouldCollide)( edict_t *pTouch, edict_t *pOther ); // was pfnCreateInstancedBaselines } DLL_FUNCTIONS; -typedef int (*SERVERAPI)( DLL_FUNCTIONS *pFunctionTable, enginefuncs_t* engfuncs, globalvars_t *pGlobals ); +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 ); #endif//SVGAME_API_H \ No newline at end of file diff --git a/common/triangle_api.h b/common/triangle_api.h index fe065b44..9701f952 100644 --- a/common/triangle_api.h +++ b/common/triangle_api.h @@ -5,6 +5,8 @@ #ifndef TRIANGLE_API_H #define TRIANGLE_API_H +#define TRI_API_VERSION 1 + typedef enum { TRI_FRONT = 0, @@ -29,7 +31,7 @@ typedef enum typedef struct triapi_s { - size_t api_size; // must match with sizeof( triapi_t ); + int version; shader_t (*LoadShader)( const char *szShaderName, int fShaderNoMip ); shader_t (*GetSpriteTexture)( int spriteIndex, int spriteFrame ); diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index da05460f..c2669fcc 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -267,7 +267,7 @@ void CL_ParseFrame( sizebuf_t *msg ) Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar // getting a valid frame message ends the connection process VectorCopy( player->pvClientData->current.origin, cl.predicted_origin ); - VectorCopy( player->v.viewangles, cl.predicted_angles ); + VectorCopy( player->v.v_angle, cl.predicted_angles ); } CL_CheckPredictionError(); diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 88d4d297..46b9d183 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -701,10 +701,6 @@ void CL_InitWorld( void ) ent->v.solid = SOLID_BSP; ent->v.movetype = MOVETYPE_PUSH; clgame.globals->numEntities = 1; - - clgame.globals->coop = Cvar_VariableInteger( "coop" ); - clgame.globals->teamplay = Cvar_VariableInteger( "teamplay" ); - clgame.globals->deathmatch = Cvar_VariableInteger( "deathmatch" ); clgame.globals->serverflags = com.atoi( cl.configstrings[CS_SERVERFLAGS] ); for( i = 0; i < clgame.globals->maxClients; i++ ) @@ -1706,9 +1702,9 @@ pfnPlaybackEvent ============= */ -static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, event_args_t *args ) +static 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 ) { - event_args_t dummy; + event_args_t args; int invokerIndex = 0; // first check event for out of bounds @@ -1733,29 +1729,37 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde if( CL_IsValidEdict( pInvoker )) invokerIndex = NUM_FOR_EDICT( pInvoker ); - if( args == NULL ) - { - Mem_Set( &dummy, 0, sizeof( dummy )); - args = &dummy; - } + args.flags = 0; + if( CL_IsValidEdict( pInvoker )) + args.entindex = NUM_FOR_EDICT( pInvoker ); + else args.entindex = 0; + VectorCopy( origin, args.origin ); + VectorCopy( angles, args.angles ); + + args.fparam1 = fparam1; + args.fparam2 = fparam2; + args.iparam1 = iparam1; + args.iparam2 = iparam2; + args.bparam1 = bparam1; + args.bparam2 = bparam2; if( flags & FEV_RELIABLE ) { - args->ducking = 0; - VectorClear( args->velocity ); + args.ducking = 0; + VectorClear( args.velocity ); } else if( invokerIndex ) { // get up some info from invoker - if( VectorIsNull( args->origin )) - VectorCopy( pInvoker->v.origin, args->origin ); - if( VectorIsNull( args->angles )) - VectorCopy( pInvoker->v.angles, args->angles ); - VectorCopy( pInvoker->v.velocity, args->velocity ); - args->ducking = (pInvoker->v.flags & FL_DUCKING) ? true : false; + if( VectorIsNull( args.origin )) + VectorCopy( pInvoker->v.origin, args.origin ); + if( VectorIsNull( args.angles )) + VectorCopy( pInvoker->v.angles, args.angles ); + VectorCopy( pInvoker->v.velocity, args.velocity ); + args.ducking = (pInvoker->v.flags & FL_DUCKING) ? true : false; } - CL_QueueEvent( flags, eventindex, delay, args ); + CL_QueueEvent( flags, eventindex, delay, &args ); } /* @@ -2348,7 +2352,7 @@ void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ) static triapi_t gTriApi = { - sizeof( triapi_t ), + TRI_API_VERSION, TriLoadShader, TriGetSpriteFrame, TriRenderMode, @@ -2372,7 +2376,6 @@ static triapi_t gTriApi = static efxapi_t gEfxApi = { - sizeof( efxapi_t ), CL_AllocParticle, CL_BlobExplosion, CL_EntityParticles, @@ -2398,7 +2401,7 @@ static efxapi_t gEfxApi = static event_api_t gEventApi = { - sizeof( event_api_t ), + EVENT_API_VERSION, pfnPrecacheEvent, pfnPlaybackEvent, pfnWeaponAnim, @@ -2420,7 +2423,6 @@ static event_api_t gEventApi = // engine callbacks static cl_enginefuncs_t gEngfuncs = { - sizeof( cl_enginefuncs_t ), pfnSPR_Load, pfnSPR_Frames, pfnSPR_Height, @@ -2486,13 +2488,13 @@ static cl_enginefuncs_t gEngfuncs = pfnTraceHull, pfnTraceModel, pfnTraceTexture, - pfnFOpen, - pfnFRead, - pfnFWrite, - pfnFClose, - pfnFGets, - pfnFSeek, - pfnFTell, + pfnPrecacheEvent, + pfnPlaybackEvent, + pfnWeaponAnim, + pfnRandomFloat, + pfnRandomLong, + pfnHookEvent, + Con_Visible, pfnLoadLibrary, pfnGetProcAddress, pfnFreeLibrary, diff --git a/engine/client/cl_move.c b/engine/client/cl_move.c index 18c6ffbb..14e16eea 100644 --- a/engine/client/cl_move.c +++ b/engine/client/cl_move.c @@ -459,7 +459,7 @@ void CL_RunCmd( edict_t *clent, usercmd_t *ucmd ) PM_CheckMovingGround( clent, ucmd->msec * 0.001f ); // VectorCopy( ucmd->viewangles, clgame.pmove->oldangles ); // save oldangles -// if( !clent->v.fixangle ) VectorCopy( ucmd->viewangles, clent->v.viewangles ); +// if( !clent->v.fixangle ) VectorCopy( ucmd->viewangles, clent->v.v_angle ); // copy player buttons clent->v.button = ucmd->buttons; @@ -560,7 +560,7 @@ void CL_PredictMovement( void ) if( cls.demoplayback && CL_IsValidEdict( viewent )) { // use interpolated server values - VectorCopy( viewent->v.viewangles, cl.refdef.cl_viewangles ); + VectorCopy( viewent->v.v_angle, cl.refdef.cl_viewangles ); } // unpredicted pure angled values converted into axis diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index 93495fc9..4ce34575 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -40,7 +40,7 @@ void V_SetupRefDef( void ) cl.refdef.onground = clent->v.groundentity; cl.refdef.health = clent->v.health; cl.refdef.movetype = clent->v.movetype; - cl.refdef.idealpitch = clent->v.ideal_pitch; + cl.refdef.idealpitch = clent->v.idealpitch; cl.refdef.num_entities = clgame.globals->numEntities; cl.refdef.max_entities = clgame.globals->maxEntities; cl.refdef.maxclients = clgame.globals->maxClients; diff --git a/engine/client/client.h b/engine/client/client.h index 134ea1ef..9faf0f95 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -586,7 +586,7 @@ int CL_AddTempEntity( struct tempent_s *pTemp, shader_t customShader ); // // cl_con.c // -bool Con_Active( void ); +bool Con_Visible( void ); void Con_CheckResize( void ); void Con_Init( void ); void Con_Clear_f( void ); diff --git a/engine/common.h b/engine/common.h index 5358bbdd..1a4480d2 100644 --- a/engine/common.h +++ b/engine/common.h @@ -166,14 +166,6 @@ void pfnFreeLibrary( void *hInstance ); long pfnRandomLong( long lLow, long lHigh ); float pfnRandomFloat( float flLow, float flHigh ); void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... ); -void *pfnFOpen( const char* path, const char* mode ); -long pfnFWrite( void *file, const void* data, size_t datasize ); -long pfnFRead( void *file, void* buffer, size_t buffersize ); -int pfnFGets( void *file, byte *string, size_t bufsize ); -void pfnEngineFprintf( void *pfile, char *szFmt, ... ); -int pfnFSeek( void *file, long offset, int whence ); -int pfnFClose( void *file ); -long pfnFTell( void *file ); void pfnGetGameDir( char *szGetGameDir ); const char *pfnCmd_Args( void ); const char *pfnCmd_Argv( int argc ); diff --git a/engine/common/con_main.c b/engine/common/con_main.c index 06c5e285..b753dccd 100644 --- a/engine/common/con_main.c +++ b/engine/common/con_main.c @@ -594,7 +594,7 @@ void Con_Close( void ) con.displayFrac = 0; } -bool Con_Active( void ) +bool Con_Visible( void ) { - return con.initialized; + return (con.finalFrac != 0.0f); } \ No newline at end of file diff --git a/engine/common/engfuncs.c b/engine/common/engfuncs.c index fbd934f0..e7055579 100644 --- a/engine/common/engfuncs.c +++ b/engine/common/engfuncs.c @@ -356,101 +356,6 @@ int pfnCmd_Argc( void ) return Cmd_Argc(); } -/* -============= -pfnFOpen - -============= -*/ -void *pfnFOpen( const char* path, const char* mode ) -{ - return FS_Open( path, mode ); -} - -/* -============= -pfnFClose - -============= -*/ -int pfnFClose( void *file ) -{ - return FS_Close( file ); -} - -/* -============= -pfnFWrite - -============= -*/ -long pfnFWrite( void *file, const void* data, size_t datasize ) -{ - return FS_Write( file, data, datasize ); -} - -/* -============= -pfnFRead - -============= -*/ -long pfnFRead( void *file, void* buffer, size_t buffersize ) -{ - return FS_Read( file, buffer, buffersize ); -} - -/* -============= -pfnFGets - -============= -*/ -int pfnFGets( void *file, byte *string, size_t bufsize ) -{ - return FS_Gets( file, string, bufsize ); -} - -/* -============= -pfnFSeek - -============= -*/ -int pfnFSeek( void *file, long offset, int whence ) -{ - return FS_Seek( file, offset, whence ); -} - -/* -============= -pfnFTell - -============= -*/ -long pfnFTell( void *file ) -{ - return FS_Tell( file ); -} - -/* -============= -pfnEngineFprintf - -============= -*/ -void pfnEngineFprintf( void *file, char *szFmt, ... ) -{ - char buffer[2048]; // must support > 1k messages - va_list args; - - va_start( args, szFmt ); - com.vsnprintf( buffer, 2048, szFmt, args ); - va_end( args ); - - FS_Print( file, buffer ); -} - /* ============= pfnLoadLibrary diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c new file mode 100644 index 00000000..13bf06a6 --- /dev/null +++ b/engine/common/net_encode.c @@ -0,0 +1,35 @@ +//======================================================================= +// Copyright XashXT Group 2010 © +// net_encode.c - encode network messages +//======================================================================= + +#include "common.h" +#include "byteorder.h" +#include "mathlib.h" + +// UNDER CONSTRUCTION!!! + +void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc ) +{ +} + +int MSG_DeltaFindField( delta_t *pFields, const char *fieldname ) +{ + return 0; +} + +void MSG_DeltaSetField( delta_t *pFields, const char *fieldname ) +{ +} + +void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname ) +{ +} + +void MSG_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber ) +{ +} + +void MSG_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber ) +{ +} \ No newline at end of file diff --git a/engine/common/net_msg.h b/engine/common/net_msg.h index 6b952d1b..034891d8 100644 --- a/engine/common/net_msg.h +++ b/engine/common/net_msg.h @@ -45,6 +45,17 @@ typedef struct net_field_s bool force; // will be send for newentity } net_field_t; +typedef struct delta_s +{ + char *name; + int offset; // in bytes + int deltaType; // DT_INTEGER, DT_FLOAT etc + float multiplier; + int bits; // how many bits we send\receive +} delta_t; + +typedef void (*pfnDeltaEncode)( delta_t *pFields, const byte *from, const byte *to ); + // server to client enum svc_ops_e { @@ -321,4 +332,14 @@ bool Netchan_Process( netchan_t *chan, sizebuf_t *msg ); bool Netchan_CanPacket( netchan_t *chan ); bool Netchan_CanReliable( netchan_t *chan ); +// +// net_encode.c +// +void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc ); +int MSG_DeltaFindField( delta_t *pFields, const char *fieldname ); +void MSG_DeltaSetField( delta_t *pFields, const char *fieldname ); +void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname ); +void MSG_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber ); +void MSG_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber ); + #endif//NET_MSG_H \ No newline at end of file diff --git a/engine/engine.dsp b/engine/engine.dsp index d09451eb..099a216e 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -214,6 +214,10 @@ SOURCE=.\common\net_chan.c # End Source File # Begin Source File +SOURCE=.\common\net_encode.c +# End Source File +# Begin Source File + SOURCE=.\common\net_huff.c # End Source File # Begin Source File diff --git a/engine/server/server.h b/engine/server/server.h index e095b85f..a4d85445 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -138,6 +138,7 @@ typedef struct sv_client_s double lastconnect; int challenge; // challenge of this user, randomly generated + int userid; // identifying number on server netchan_t netchan; } sv_client_t; @@ -237,6 +238,7 @@ typedef struct int spawncount; // incremented each server start // used to check late spawns sv_client_t *clients; // [sv_maxclients->integer] + sv_client_t *currentPlayer; // current client who network message sending on int num_client_entities; // sv_maxclients->integer*UPDATE_BACKUP*MAX_PACKET_ENTITIES int next_client_entities; // next client_entity to use entity_state_t *client_entities; // [num_client_entities] @@ -273,6 +275,7 @@ extern cvar_t *sv_rollangle; extern cvar_t *sv_rollspeed; extern cvar_t *sv_maxspeed; extern cvar_t *sv_maxclients; +extern cvar_t *sv_skyname; extern cvar_t *serverinfo; extern cvar_t *physinfo; extern sv_client_t *sv_client; diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 494368e3..dc189c09 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -15,6 +15,8 @@ typedef struct ucmd_s void (*func)( sv_client_t *cl ); } ucmd_t; +static int g_userid = 1; + /* ================= SV_GetChallenge @@ -175,6 +177,7 @@ gotnewcl: newcl->edict = ent; newcl->challenge = challenge; // save challenge for checksumming newcl->frames = (client_frame_t *)Z_Malloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP ); + newcl->userid = g_userid++; // create unique userid // get the game a chance to reject this connection or modify the userinfo if(!(SV_ClientConnect( ent, userinfo ))) @@ -288,13 +291,20 @@ e.g. ipban */ bool SV_ClientConnect( edict_t *ent, char *userinfo ) { - bool result = true; + bool result = true; + char *pszName, *pszAddress; + char szRejectReason[128]; // make sure we start with known default if( !sv.loadgame ) ent->v.flags = 0; + szRejectReason[0] = '\0'; + + pszName = Info_ValueForKey( userinfo, "name" ); + pszAddress = Info_ValueForKey( userinfo, "ip" ); MsgDev( D_NOTE, "SV_ClientConnect()\n" ); - result = svgame.dllFuncs.pfnClientConnect( ent, userinfo ); + result = svgame.dllFuncs.pfnClientConnect( ent, pszName, pszAddress, szRejectReason ); + if( szRejectReason[0] ) Info_SetValueForKey( userinfo, "rejmsg", szRejectReason ); return result; } @@ -1395,12 +1405,12 @@ void SV_SetIdealPitch( sv_client_t *cl ) if( !dir ) { - ent->v.ideal_pitch = 0; + ent->v.idealpitch = 0; return; } if( steps < 2 ) return; - ent->v.ideal_pitch = -dir * sv_idealpitchscale->value; + ent->v.idealpitch = -dir * sv_idealpitchscale->value; } /* diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index c8f43693..136e44ad 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -514,6 +514,8 @@ void SV_SendClientMessages( void ) sv_client_t *cl; int i; + svs.currentPlayer = NULL; + if( sv.state == ss_dead ) return; @@ -531,6 +533,8 @@ void SV_SendClientMessages( void ) if( !cl->edict || (cl->edict->v.flags & ( FL_FAKECLIENT|FL_SPECTATOR ))) continue; + svs.currentPlayer = cl; + // update any userinfo packets that have changed if( cl->sendinfo ) { @@ -577,6 +581,9 @@ void SV_SendClientMessages( void ) // yes, message really sended cl->send_message = false; } + + // reset current client + svs.currentPlayer = NULL; } /* diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 7fa1755f..5310e9c0 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -868,7 +868,7 @@ void pfnChangePitch( edict_t* ent ) return; } - ent->v.angles[PITCH] = SV_AngleMod( ent->v.ideal_pitch, ent->v.angles[PITCH], ent->v.pitch_speed ); + ent->v.angles[PITCH] = SV_AngleMod( ent->v.idealpitch, ent->v.angles[PITCH], ent->v.pitch_speed ); } /* @@ -2727,32 +2727,41 @@ edict_t *pfnCreateFakeClient( const char *netname ) /* ============= -pfnThinkFakeClient +pfnRunPlayerMove ============= */ -void pfnThinkFakeClient( edict_t *pClient, usercmd_t *cmd ) +void pfnRunPlayerMove( edict_t *pClient, const float *v_angle, float fmove, float smove, float upmove, word buttons, byte impulse, byte msec ) { sv_client_t *cl; + usercmd_t cmd; if( sv.paused ) return; - cl = SV_ClientFromEdict( pClient, true ); - if( cl == NULL || cmd == NULL ) + if(( cl = SV_ClientFromEdict( pClient, true )) == NULL ) { - if( !cl ) MsgDev( D_ERROR, "SV_ClientThink: fakeclient is not spawned!\n" ); - if( !cmd ) MsgDev( D_ERROR, "SV_ClientThink: NULL usercmd_t!\n" ); + MsgDev( D_ERROR, "SV_ClientThink: fakeclient is not spawned!\n" ); return; } if(!( pClient->v.flags & FL_FAKECLIENT )) return; // only fakeclients allows - SV_PreRunCmd( cl, cmd ); - SV_RunCmd( cl, cmd ); + Mem_Set( &cmd, 0, sizeof( cmd )); + if( v_angle ) VectorCopy( v_angle, cmd.viewangles ); + cmd.forwardmove = fmove; + cmd.sidemove = smove; + cmd.upmove = upmove; + cmd.buttons = buttons; + cmd.impulse = impulse; + cmd.random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range + cmd.msec = msec; + + SV_PreRunCmd( cl, &cmd ); + SV_RunCmd( cl, &cmd ); SV_PostRunCmd( cl ); - cl->lastcmd = *cmd; + cl->lastcmd = cmd; cl->lastcmd.buttons = 0; // avoid multiple fires on lag } @@ -2905,12 +2914,13 @@ pfnPlaybackEvent ============= */ -static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, event_args_t *args ) +static 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 ) { sv_client_t *cl; event_state_t *es; + event_args_t args; event_info_t *ei = NULL; - event_args_t dummy; // in case send naked event without args int j, leafnum, slot, bestslot; int invokerIndex = 0; byte *mask = NULL; @@ -2930,13 +2940,27 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde return; } + args.flags = 0; + if( SV_IsValidEdict( pInvoker )) + args.entindex = NUM_FOR_EDICT( pInvoker ); + else args.entindex = 0; + VectorCopy( origin, args.origin ); + VectorCopy( angles, args.angles ); + + args.fparam1 = fparam1; + args.fparam2 = fparam2; + args.iparam1 = iparam1; + args.iparam2 = iparam2; + args.bparam1 = bparam1; + args.bparam2 = bparam2; + if(!( flags & FEV_GLOBAL )) { // PVS message - trying to get a pvspoint - // args->origin always have higher priority than invoker->origin - if( args && !VectorIsNull( args->origin )) + // args.origin always have higher priority than invoker->origin + if( !VectorIsNull( args.origin )) { - VectorCopy( args->origin, pvspoint ); + VectorCopy( args.origin, pvspoint ); } else if( SV_IsValidEdict( pInvoker )) { @@ -2973,36 +2997,30 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde if( SV_IsValidEdict( pInvoker )) invokerIndex = NUM_FOR_EDICT( pInvoker ); - if( args == NULL ) - { - Mem_Set( &dummy, 0, sizeof( dummy )); - args = &dummy; - } - if( flags & FEV_RELIABLE ) { - args->ducking = 0; - VectorClear( args->velocity ); + args.ducking = 0; + VectorClear( args.velocity ); } else if( invokerIndex ) { // get up some info from invoker - if( VectorIsNull( args->origin )) - VectorCopy( pInvoker->v.origin, args->origin ); - if( VectorIsNull( args->angles )) + if( VectorIsNull( args.origin )) + VectorCopy( pInvoker->v.origin, args.origin ); + if( VectorIsNull( args.angles )) { if( SV_ClientFromEdict( pInvoker, true )) - VectorCopy( pInvoker->v.viewangles, args->angles ); - else VectorCopy( pInvoker->v.angles, args->angles ); + VectorCopy( pInvoker->v.v_angle, args.angles ); + else VectorCopy( pInvoker->v.angles, args.angles ); } - else if( SV_ClientFromEdict( pInvoker, true ) && VectorCompare( pInvoker->v.angles, args->angles )) + else if( SV_ClientFromEdict( pInvoker, true ) && VectorCompare( pInvoker->v.angles, args.angles )) { // NOTE: if user specified pPlayer->pev->angles // silently replace it with viewangles, client expected this - VectorCopy( pInvoker->v.viewangles, args->angles ); + VectorCopy( pInvoker->v.v_angle, args.angles ); } - VectorCopy( pInvoker->v.velocity, args->velocity ); - args->ducking = (pInvoker->v.flags & FL_DUCKING) ? true : false; + VectorCopy( pInvoker->v.velocity, args.velocity ); + args.ducking = (pInvoker->v.flags & FL_DUCKING) ? true : false; } if(!( flags & FEV_GLOBAL )) @@ -3040,7 +3058,7 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde info.index = eventindex; info.fire_time = delay; - info.args = *args; + info.args = args; info.entity_index = invokerIndex; info.packet_index = -1; info.flags = 0; // server ignore flags @@ -3072,7 +3090,7 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde ei->index = eventindex; ei->fire_time = delay; - ei->args = *args; + ei->args = args; ei->entity_index = invokerIndex; ei->packet_index = -1; ei->flags = 0; // server ignore flags @@ -3183,6 +3201,19 @@ int pfnCanSkipPlayer( const edict_t *player ) return false; } +/* +============= +pfnGetCurrentPlayer + +============= +*/ +int pfnGetCurrentPlayer( void ) +{ + if( svs.currentPlayer ) + return svs.currentPlayer - svs.clients; + return -1; +} + /* ============= pfnSetGroupMask @@ -3197,27 +3228,58 @@ void pfnSetGroupMask( int mask, int op ) /* ============= -pfnEndGame +pfnEndSection ============= */ -void pfnEndGame( const char *engine_command ) +void pfnEndSection( const char *pszSection ) { - if( !com.stricmp( "credits", engine_command )) + if( !com.stricmp( "credits", pszSection )) Host_Credits (); - else Host_EndGame( engine_command ); + else Host_EndGame( pszSection ); } /* ============= -pfnSetSkybox +pfnGetPlayerUserId ============= */ -void pfnSetSkybox( const char *name ) +int pfnGetPlayerUserId( edict_t *e ) { - if( sv.loadgame ) return; // sets by saverstore code - SV_ConfigString( CS_SKYNAME, name ); + sv_client_t *cl; + int i; + + if( !svs.initialized ) + return -1; + + if( !SV_ClientFromEdict( e, false )) + return -1; + + for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ ) + { + if( cl->edict == e ) + { + return cl->userid; + } + } + + // couldn't find it + return -1; +} + +/* +============= +pfnGetPlayerAuthId + +These function must returns cd-key hashed value +but Xash3D currently doesn't have any security checks +return nullstring for now +============= +*/ +const char *pfnGetPlayerAuthId( edict_t *e ) +{ + return ""; } /* @@ -3287,7 +3349,6 @@ void pfnAddServerCommand( const char *cmd_name, void (*function)(void), const ch // engine callbacks static enginefuncs_t gEngfuncs = { - sizeof( enginefuncs_t ), pfnPrecacheModel, pfnPrecacheSound, pfnSetModel, @@ -3350,7 +3411,7 @@ static enginefuncs_t gEngfuncs = pfnCVarSetValue, pfnCVarSetString, pfnAlertMessage, - pfnEngineFprintf, + pfnGetProcAddress, pfnPvAllocEntPrivateData, pfnPvEntPrivateData, pfnFreeEntPrivateData, @@ -3385,14 +3446,14 @@ static enginefuncs_t gEngfuncs = pfnCrosshairAngle, pfnLoadFile, pfnFreeFile, - pfnEndGame, + pfnEndSection, pfnCompareFileTime, pfnGetGameDir, pfnClassifyEdict, pfnFadeClientVolume, pfnSetClientMaxspeed, pfnCreateFakeClient, - pfnThinkFakeClient, + pfnRunPlayerMove, pfnFileExists, pfnGetInfoKeyBuffer, pfnInfoKeyValue, @@ -3401,7 +3462,7 @@ static enginefuncs_t gEngfuncs = pfnIsMapValid, pfnStaticDecal, pfnPrecacheGeneric, - pfnSetSkybox, + pfnGetPlayerUserId, pfnPlayMusic, pfnIsDedicatedServer, pfnMemAlloc, @@ -3415,14 +3476,14 @@ static enginefuncs_t gEngfuncs = pfnSetFatPVS, pfnSetFatPAS, pfnCheckVisibility, - pfnFOpen, - pfnFRead, - pfnFWrite, - pfnFClose, + MSG_DeltaSetField, + MSG_DeltaUnsetField, + MSG_DeltaAddEncoder, + pfnGetCurrentPlayer, pfnCanSkipPlayer, - pfnFGets, - pfnFSeek, - pfnFTell, + MSG_DeltaFindField, + MSG_DeltaSetFieldByIndex, + MSG_DeltaUnsetFieldByIndex, pfnSetGroupMask, pfnDropClient, Host_Error, @@ -3430,8 +3491,8 @@ static enginefuncs_t gEngfuncs = pfnGetPlayerStats, pfnAddServerCommand, pfnLoadLibrary, - pfnGetProcAddress, pfnFreeLibrary, + pfnGetPlayerAuthId, }; /* @@ -3618,15 +3679,18 @@ void SV_SpawnEntities( const char *mapname, script_t *entities ) MsgDev( D_NOTE, "SV_SpawnEntities()\n" ); - // reset sky parms + // reset misc parms Cvar_Reset( "sv_zmax" ); Cvar_Reset( "sv_wateramp" ); + + // reset sky parms Cvar_Reset( "sv_skycolor_r" ); Cvar_Reset( "sv_skycolor_g" ); Cvar_Reset( "sv_skycolor_b" ); Cvar_Reset( "sv_skyvec_x" ); Cvar_Reset( "sv_skyvec_y" ); Cvar_Reset( "sv_skyvec_z" ); + Cvar_Reset( "sv_skyname" ); ent = EDICT_NUM( 0 ); if( ent->free ) SV_InitEdict( ent ); @@ -3666,7 +3730,8 @@ void SV_UnloadProgs( void ) bool SV_LoadProgs( const char *name ) { - static SERVERAPI GetEntityAPI; + static APIFUNCTION GetEntityAPI; + static GIVEFNPTRSTODLL GiveFnptrsToDll; static globalvars_t gpGlobals; static playermove_t gpMove; edict_t *e; @@ -3682,24 +3747,36 @@ bool SV_LoadProgs( const char *name ) svgame.hInstance = FS_LoadLibrary( name, true ); if( !svgame.hInstance ) return false; - GetEntityAPI = (SERVERAPI)FS_GetProcAddress( svgame.hInstance, "CreateAPI" ); + GetEntityAPI = (APIFUNCTION)FS_GetProcAddress( svgame.hInstance, "GetEntityAPI" ); if( !GetEntityAPI ) { FS_FreeLibrary( svgame.hInstance ); - MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of CreateAPI proc\n" ); + MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GetEntityAPI proc\n" ); svgame.hInstance = NULL; return false; } - if( !GetEntityAPI( &svgame.dllFuncs, &gEngfuncs, svgame.globals )) + GiveFnptrsToDll = (GIVEFNPTRSTODLL)FS_GetProcAddress( svgame.hInstance, "GiveFnptrsToDll" ); + + if( !GiveFnptrsToDll ) { FS_FreeLibrary( svgame.hInstance ); - MsgDev( D_NOTE, "SV_LoadProgs: couldn't get entity API\n" ); + MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GiveFnptrsToDll proc\n" ); svgame.hInstance = NULL; return false; } + if( !GetEntityAPI( &svgame.dllFuncs, SV_INTERFACE_VERSION )) + { + FS_FreeLibrary( svgame.hInstance ); + MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" ); + svgame.hInstance = NULL; + return false; + } + + GiveFnptrsToDll( &gEngfuncs, svgame.globals ); + svgame.globals->pStringBase = ""; // setup string base if( sys_sharedstrings->integer ) diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 74080167..0cc954cf 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -347,7 +347,6 @@ bool SV_SpawnServer( const char *mapname, const char *startspot ) com.sprintf( sv.configstrings[CS_MODELS+1], "maps/%s.bsp", sv.name ); CM_BeginRegistration( sv.configstrings[CS_MODELS+1], false, &checksum ); com.sprintf( sv.configstrings[CS_MAPCHECKSUM], "%i", checksum ); - com.strncpy( sv.configstrings[CS_SKYNAME], "", 64 ); for( i = 1; i < CM_NumBmodels(); i++ ) { diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 9a5123e7..20adb75a 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -51,6 +51,7 @@ cvar_t *sv_skycolor_b; cvar_t *sv_skyvec_x; cvar_t *sv_skyvec_y; cvar_t *sv_skyvec_z; +cvar_t *sv_skyname; void Master_Shutdown( void ); @@ -162,6 +163,12 @@ void SV_UpdateMovevars( void ) sv_wateramp->modified = false; } + if( sv_skyname->modified ) + { + SV_ConfigString( CS_SKYNAME, sv_skyname->string ); + sv_skyname->modified = false; + } + if( sv_skycolor_r->modified || sv_skycolor_g->modified || sv_skycolor_g->modified ) { com.snprintf( tmp, sizeof( tmp ), "%d %d %d", sv_skycolor_r->integer, sv_skycolor_g->integer, sv_skycolor_b->integer ); @@ -553,6 +560,7 @@ void SV_Init( void ) sv_skyvec_x = Cvar_Get ("sv_skyvec_x", "1", 0, "sky direction x (hl1 compatibility)" ); sv_skyvec_y = Cvar_Get ("sv_skyvec_y", "0", 0, "sky direction y (hl1 compatibility)" ); sv_skyvec_z = Cvar_Get ("sv_skyvec_z", "-1", 0, "sky direction z (hl1 compatibility)" ); + sv_skyname = Cvar_Get ("sv_skyname", "", 0, "skybox name (can be dynamically changed in-game)" ); rcon_password = Cvar_Get( "rcon_password", "", 0, "remote connect password" ); sv_stepheight = Cvar_Get( "sv_stepheight", "18", CVAR_ARCHIVE|CVAR_PHYSICINFO, "how high you can step up" ); diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index ae2ed619..8b5b7c7f 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -524,7 +524,7 @@ static void PM_FinishMove( playermove_t *pmove, edict_t *clent ) { clent->v.teleport_time = pmove->flWaterJumpTime; clent->v.groundentity = pmove->onground; - VectorCopy( pmove->angles, clent->v.viewangles ); + VectorCopy( pmove->angles, clent->v.v_angle ); VectorCopy( pmove->origin, clent->v.origin ); VectorCopy( pmove->movedir, clent->v.movedir ); VectorCopy( pmove->velocity, clent->v.velocity ); @@ -608,8 +608,8 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd ) PM_CheckMovingGround( clent, ucmd->msec * 0.001f ); - VectorCopy( clent->v.viewangles, svgame.pmove->oldangles ); // save oldangles - if( !clent->v.fixangle ) VectorCopy( ucmd->viewangles, clent->v.viewangles ); + VectorCopy( clent->v.v_angle, svgame.pmove->oldangles ); // save oldangles + if( !clent->v.fixangle ) VectorCopy( ucmd->viewangles, clent->v.v_angle ); // copy player buttons clent->v.button = ucmd->buttons; @@ -621,8 +621,8 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd ) { if( !clent->v.fixangle ) { - clent->v.angles[PITCH] = -clent->v.viewangles[PITCH] / 3; - clent->v.angles[YAW] = clent->v.viewangles[YAW]; + clent->v.angles[PITCH] = -clent->v.v_angle[PITCH] / 3; + clent->v.angles[YAW] = clent->v.v_angle[YAW]; } } @@ -661,8 +661,7 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd ) // NOTE: one of triggers apply new velocity to client // e.g trigger_teleport resets it or add new // so we need to apply new velocity immediately here - if( clent->v.fixangle || clent->v.flJumpPadTime ) - VectorCopy( clent->v.velocity, oldvel ); + if( clent->v.fixangle ) VectorCopy( clent->v.velocity, oldvel ); // touch other objects for( i = 0; i < svgame.pmove->numtouch; i++ ) diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index aebe833e..259721ad 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -576,14 +576,9 @@ void SV_SaveGameStateGlobals( SAVERESTOREDATA *pSaveData ) header.connectionCount = pSaveData->connectionCount; header.time = svgame.globals->time; - if( sv.configstrings[CS_SKYNAME][0] ) - { - com.strncpy( header.skyName, sv.configstrings[CS_SKYNAME], sizeof( header.skyName )); - } - else - { - com.strncpy( header.skyName, "", sizeof( header.skyName )); - } + if( sv_skyname->string[0] ) + com.strncpy( header.skyName, sv_skyname->string, sizeof( header.skyName )); + else com.strncpy( header.skyName, "", sizeof( header.skyName )); com.strncpy( header.mapName, sv.name, sizeof( header.mapName )); header.lightStyleCount = 0; @@ -941,7 +936,7 @@ int SV_LoadGameState( char const *level, bool createPlayers ) com.strncpy( sv.name, header.mapName, sizeof( sv.name )); svgame.globals->mapname = MAKE_STRING( sv.name ); - SV_ConfigString( CS_SKYNAME, header.skyName ); + Cvar_Set( "sv_skyname", header.skyName ); // restore sky parms Cvar_SetValue( "sv_skycolor_r", header.skyColor_r ); diff --git a/game_shared/pm_shared.cpp b/game_shared/pm_shared.cpp index 905d7b75..b098cd8b 100644 --- a/game_shared/pm_shared.cpp +++ b/game_shared/pm_shared.cpp @@ -1696,7 +1696,7 @@ void PM_SpectatorMove( void ) // doesn't need excate track position, only to generate PVS, so just copy // targets position and real view position is calculated on client (saves server CPU) - if ( pev->iSpecMode == OBS_ROAMING ) + if ( pev->iuser1 == OBS_ROAMING ) { // Move around in normal spectator method speed = pmove->velocity.Length(); @@ -2460,13 +2460,6 @@ void PM_CheckFalling( void ) { float fvol = 0.5; - if( pev->flJumpPadTime && pev->flJumpPadTime < pmove->realtime ) - { - // scale delta if was pushed by jump pad - float delta = (1.0f + pmove->realtime - pev->flJumpPadTime) * 0.5f; - pev->flFallVelocity /= delta; - } - if( pev->waterlevel > 0 ) { // does nothing @@ -2707,7 +2700,7 @@ void PM_PlayerMove( BOOL server ) // PM_ShowClipBox(); // Special handling for spectator and observers. (iuser1 is set if the player's in observer mode) - if(( pev->flags & FL_SPECTATOR ) || pev->iSpecMode > 0 ) + if(( pev->flags & FL_SPECTATOR ) || pev->iuser1 > 0 ) { PM_SpectatorMove(); PM_CatagorizePosition(); diff --git a/launch/launch.dsp b/launch/launch.dsp index 0cf8aa26..12d23602 100644 --- a/launch/launch.dsp +++ b/launch/launch.dsp @@ -196,10 +196,6 @@ SOURCE=.\parselib.c # End Source File # Begin Source File -SOURCE=.\patch.c -# End Source File -# Begin Source File - SOURCE=.\soundlib\snd_main.c # End Source File # Begin Source File diff --git a/launch/library.c b/launch/library.c index 878da790..df16598c 100644 --- a/launch/library.c +++ b/launch/library.c @@ -13,6 +13,7 @@ --------------------------------------------------------------- */ + typedef struct { PIMAGE_NT_HEADERS headers; @@ -716,12 +717,12 @@ bool LibraryLoadSymbols( dll_user_t *hInst ) for( i = 0; i < hInst->num_ordinals; i++ ) { - if( !com.strcmp( "CreateAPI", hInst->names[i] )) // main entry point for Xash3D dlls + if( !com.strcmp( "GiveFnptrsToDll", hInst->names[i] )) // main entry point for user dlls { void *fn_offset; index = hInst->ordinals[i]; - fn_offset = (void *)Com_GetProcAddress( hInst, "CreateAPI" ); + fn_offset = (void *)Com_GetProcAddress( hInst, "GiveFnptrsToDll" ); hInst->funcBase = (dword)(fn_offset) - hInst->funcs[index]; break; } diff --git a/server/ents/basefunc.cpp b/server/ents/basefunc.cpp index 8b9a081e..e37cdbe8 100644 --- a/server/ents/basefunc.cpp +++ b/server/ents/basefunc.cpp @@ -715,7 +715,7 @@ void CFuncTeleport :: Touch( CBaseEntity *pOther ) pOther->pev->angles.y -= ydiff; if( pOther->IsPlayer()) { - pOther->pev->angles.x = pOther->pev->viewangles.x; + pOther->pev->angles.x = pOther->pev->v_angle.x; pOther->pev->fixangle = TRUE; } @@ -751,7 +751,7 @@ void CFuncTeleport :: Touch( CBaseEntity *pOther ) pOther->pev->velocity = gpGlobals->v_forward * 300; if( pOther->IsPlayer( )) { - pOther->pev->viewangles = pTarget->pev->angles; + pOther->pev->v_angle = pTarget->pev->angles; pOther->pev->fixangle = TRUE; } } diff --git a/server/ents/baseinfo.cpp b/server/ents/baseinfo.cpp index 28c0fc7f..4aac7810 100644 --- a/server/ents/baseinfo.cpp +++ b/server/ents/baseinfo.cpp @@ -147,7 +147,7 @@ void CInfoIntermission::KeyValue( KeyValueData *pkvd ) else if( FStrEq( pkvd->szKeyName, "roll" )) { // Quake3 portal camera - pev->viewangles[ROLL] = atof( pkvd->szValue ) / 360.0f; + pev->v_angle[ROLL] = atof( pkvd->szValue ) / 360.0f; pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue( pkvd ); @@ -222,7 +222,7 @@ void CPortalSurface :: PostActivate( void ) pev->effects &= ~EF_ROTATE; else pev->effects |= EF_ROTATE; - pev->frame = pOwner->pev->viewangles[ROLL]; // rollangle + pev->frame = pOwner->pev->v_angle[ROLL]; // rollangle // see if the portal_camera has a target if( !FStringNull( pOwner->pev->target )) diff --git a/server/ents/baseother.cpp b/server/ents/baseother.cpp index 42950ea1..973bf27c 100644 --- a/server/ents/baseother.cpp +++ b/server/ents/baseother.cpp @@ -275,7 +275,7 @@ void CLaserSpot::Update( CBasePlayer *m_pPlayer ) { TraceResult tr; - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); UTIL_TraceLine( m_pPlayer->GetGunPosition(), m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 8192, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr ); UTIL_SetOrigin( this, tr.vecEndPos ); diff --git a/server/ents/baserockets.cpp b/server/ents/baserockets.cpp index 2adb50cf..3e8a8bad 100644 --- a/server/ents/baserockets.cpp +++ b/server/ents/baserockets.cpp @@ -755,9 +755,9 @@ void CWHRocket :: FollowThink( void ) if( pev->button ) // controllable rocket { - UTIL_MakeVectorsPrivate( m_pPlayer->pev->viewangles, forward, NULL, NULL ); + UTIL_MakeVectorsPrivate( m_pPlayer->pev->v_angle, forward, NULL, NULL ); - angles = m_pPlayer->pev->viewangles; + angles = m_pPlayer->pev->v_angle; angles.x = -angles.x; float steer = WARHEAD_MAX_SPEED / pev->speed; // steer factor diff --git a/server/ents/basetank.cpp b/server/ents/basetank.cpp index 38544647..f9b4944c 100644 --- a/server/ents/basetank.cpp +++ b/server/ents/basetank.cpp @@ -450,7 +450,7 @@ void CFuncTank::TrackTarget( void ) { // "Match target" mode: // first, get the player's angles - angles = pController->pev->viewangles; + angles = pController->pev->v_angle; // work out what point the player is looking at UTIL_MakeVectorsPrivate( angles, direction, NULL, NULL ); @@ -483,7 +483,7 @@ void CFuncTank::TrackTarget( void ) { // "Match angles" mode // just get the player's angles - angles = pController->pev->viewangles; + angles = pController->pev->v_angle; angles[0] = 0 - angles[0]; UpdateSpot(); diff --git a/server/ents/basetrigger.cpp b/server/ents/basetrigger.cpp index bdb99843..4ec8458a 100644 --- a/server/ents/basetrigger.cpp +++ b/server/ents/basetrigger.cpp @@ -289,13 +289,11 @@ class CTriggerPush : public CBaseTrigger { void Spawn( void ) { - if( pev->angles == g_vecZero ) - pev->angles.y = 360; - if( pev->speed == 0 ) pev->speed = 100; + if ( pev->angles == g_vecZero ) pev->angles.y = 360; + if (pev->speed == 0) pev->speed = 100; UTIL_LinearVector( this ); - if ( FBitSet( pev->spawnflags, 2 )) - pev->solid = SOLID_NOT; + if ( FBitSet (pev->spawnflags, 2) ) pev->solid = SOLID_NOT; else pev->solid = SOLID_TRIGGER; pev->movetype = MOVETYPE_NONE; @@ -303,29 +301,9 @@ class CTriggerPush : public CBaseTrigger SetBits( pev->effects, EF_NODRAW ); UTIL_SetOrigin( this, pev->origin ); } - void PostActivate( void ) + void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - Vector dir; - CBaseEntity *pOwner; - - if( FStringNull( pev->target )) - return; // dir set with angles - - pOwner = UTIL_FindEntityByTargetname( NULL, STRING( pev->target )); - if( !pOwner ) return; // dir set with angles - - if( pOwner->pFlags & PF_POINTENTITY ) - { - // xash allows to precache from random place - UTIL_PrecacheSound( "world/jumppad.wav" ); - - pev->owner = pOwner->edict(); - pev->button = TRUE; // Q3A trigger_push - } - } - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) - { - if( pev->solid == SOLID_NOT ) + if (pev->solid == SOLID_NOT) { pev->solid = SOLID_TRIGGER; gpGlobals->force_retouch++; @@ -343,66 +321,23 @@ class CTriggerPush : public CBaseTrigger case MOVETYPE_FOLLOW: return; } - - if( pev->button ) + + if ( pOther->pev->solid != SOLID_NOT && pOther->pev->solid != SOLID_BSP ) { - if( m_flWait >= gpGlobals->time ) return; - - if( !pOther->IsPlayer() || pOther->pev->movetype != MOVETYPE_WALK ) - return; - - float time, dist, f; - Vector origin, velocity; - - origin = (pev->absmin + pev->absmax) * 0.5f; - CBaseEntity *pTarg = CBaseEntity::Instance( pev->owner ); - - // assume pev->owner is valid - time = sqrt (( pTarg->pev->origin.z - origin.z ) / (0.5f * CVAR_GET_FLOAT( "sv_gravity" ))); - if( !time ) - { - UTIL_Remove( this ); - return; - } - - velocity = pTarg->pev->origin - origin; - velocity.z = 0.0f; - dist = velocity.Length(); - velocity = velocity.Normalize(); - - f = dist / time; - velocity *= f; - velocity.z = time * CVAR_GET_FLOAT( "sv_gravity" ); - - pOther->pev->flJumpPadTime = gpGlobals->time; - pOther->pev->basevelocity = velocity; - pOther->pev->velocity = g_vecZero; - pOther->pev->flags &= ~FL_BASEVELOCITY; - - EMIT_SOUND( ENT( pev ), CHAN_VOICE, "world/jumppad.wav", VOL_NORM, ATTN_IDLE ); - - m_flWait = gpGlobals->time + ( 2.0f * gpGlobals->frametime ); - - if( FBitSet( pev->spawnflags, SF_PUSH_ONCE )) - UTIL_Remove( this ); - } - else if( pOther->pev->solid != SOLID_NOT && pOther->pev->solid != SOLID_BSP ) - { - // instant trigger, just transfer velocity and remove - if( FBitSet( pev->spawnflags, SF_PUSH_ONCE )) + // Instant trigger, just transfer velocity and remove + if (FBitSet(pev->spawnflags, 1)) { pOther->pev->velocity = pOther->pev->velocity + (pev->speed * pev->movedir); - if( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND; + if ( pOther->pev->velocity.z > 0 ) pOther->pev->flags &= ~FL_ONGROUND; UTIL_Remove( this ); } else { Vector vecPush = (pev->speed * pev->movedir); if ( pOther->pev->flags & FL_BASEVELOCITY ) - vecPush = vecPush + pOther->pev->basevelocity; + vecPush = vecPush + pOther->pev->basevelocity; pOther->pev->basevelocity = vecPush; pOther->pev->flags |= FL_BASEVELOCITY; - pOther->pev->flJumpPadTime = gpGlobals->time; } } } @@ -661,7 +596,7 @@ void CTriggerHurt :: Touch ( CBaseEntity *pOther ) { if ( pev->dmgtime > gpGlobals->time ) { - if ( gpGlobals->time != pev->dmg_take ) + if ( gpGlobals->time != pev->pain_finished ) { // too early to hurt again, and not same frame with a different entity if ( pOther->IsPlayer() ) @@ -683,14 +618,14 @@ void CTriggerHurt :: Touch ( CBaseEntity *pOther ) } } } - else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->dmg_take ) return; + else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) return; fldmg = pev->dmg * 0.5; // 0.5 seconds worth of damage, pev->dmg is damage/second if ( fldmg < 0 ) pOther->TakeHealth( -fldmg, pev->button ); else pOther->TakeDamage( pev, pev, fldmg, pev->button ); - pev->dmg_take = gpGlobals->time; + pev->pain_finished = gpGlobals->time; pev->dmgtime = gpGlobals->time + 0.5; } diff --git a/server/ents/baseweapon.cpp b/server/ents/baseweapon.cpp index 53afe6b1..53d0cb8b 100644 --- a/server/ents/baseweapon.cpp +++ b/server/ents/baseweapon.cpp @@ -934,6 +934,8 @@ void CBasePlayerWeapon :: SendWeaponAnim( int sequence, float fps ) } } + m_pPlayer->pev->weaponanim = m_iSequence; + // calculate additional body for special effects pev->body = (pev->body % NUM_HANDS) + NUM_HANDS * m_iBody; @@ -1412,7 +1414,7 @@ int CBasePlayerWeapon :: Shoot ( const char *ammo, Vector vecSpread, int firemod // eject brass for( int i = 0; cShots > i; i++ ) { - UTIL_PlaybackEvent( 0, m_pPlayer->edict(), m_usEjectBrass, 0.0, g_vecZero, g_vecZero, 0, 0, GetBulletType( ammo ), 0, firemode, 0 ); + PLAYBACK_EVENT_FULL( 0, m_pPlayer->edict(), m_usEjectBrass, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, GetBulletType( ammo ), 0, firemode, 0 ); } if( !FStriCmp( ammo, "buckshot" ))//HACK { @@ -1438,22 +1440,22 @@ int CBasePlayerWeapon :: Launch ( const char *ammo, int type ) if ( !FStriCmp( ammo, "m203" )) { // we don't add in player velocity anymore. - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); CGrenade::ShootContact( m_pPlayer->pev, m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16, gpGlobals->v_forward * 800 ); } else if( !FStriCmp( ammo, "rockets" )) { - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; - CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles );// RpgRocket::Create stomps on globals, so remake. + CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle );// RpgRocket::Create stomps on globals, so remake. pRocket->pev->velocity = pRocket->pev->velocity + gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward ); } else if( !FStriCmp( ammo, "bolts" )) { // we don't add in player velocity anymore. - Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); anglesAim.x = -anglesAim.x; @@ -1466,13 +1468,13 @@ int CBasePlayerWeapon :: Launch ( const char *ammo, int type ) } else if( !FStriCmp( ammo, "nuke" )) { - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_up * 2; - CWHRocket *pRocket = CWHRocket::Create ( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this, type ); + CWHRocket *pRocket = CWHRocket::Create ( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this, type ); } else if( !FStriCmp( ammo, "grenade" )) { - Vector angThrow = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; if ( angThrow.x < 0 ) angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 ); else angThrow.x = -10 + angThrow.x * ( ( 90 + 10 ) / 90.0 ); @@ -1522,7 +1524,7 @@ int CBasePlayerWeapon::Swing( int fFirst ) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3; - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecEnd = vecSrc + gpGlobals->v_forward * 32; diff --git a/server/ents/baseworld.cpp b/server/ents/baseworld.cpp index f13ea1d8..2210cad5 100644 --- a/server/ents/baseworld.cpp +++ b/server/ents/baseworld.cpp @@ -28,7 +28,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd ) { if( FStrEq( pkvd->szKeyName, "skyname" )) { - pev->target = ALLOC_STRING( pkvd->szValue ); + CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "chaptertitle") ) @@ -62,18 +62,7 @@ void CWorld :: PostActivate( void ) if ( pev->spawnflags & SF_WORLD_TITLE ) { SERVER_COMMAND( "gametitle\n" ); - ClearBits( pev->spawnflags, SF_START_ON ); - } - - if ( pev->target ) - { - // Sent over net now. - SET_SKYBOX( STRING( pev->target )); - } - else - { - // tell engine there is no skybox set - SET_SKYBOX( "" ); + ClearBits( pev->spawnflags, SF_WORLD_TITLE ); } } LINK_ENTITY_TO_CLASS( worldspawn, CWorld ); \ No newline at end of file diff --git a/server/game/gamerules.cpp b/server/game/gamerules.cpp index b6362307..a4494828 100644 --- a/server/game/gamerules.cpp +++ b/server/game/gamerules.cpp @@ -62,7 +62,7 @@ edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer ) edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector( 0, 0, 1 ); - pPlayer->pev->viewangles = g_vecZero; + pPlayer->pev->v_angle = g_vecZero; pPlayer->pev->velocity = g_vecZero; pPlayer->pev->angles = VARS( pentSpawnSpot )->angles; pPlayer->pev->punchangle = g_vecZero; diff --git a/server/game/gamerules.h b/server/game/gamerules.h index f834a1e2..512f9240 100644 --- a/server/game/gamerules.h +++ b/server/game/gamerules.h @@ -72,7 +72,7 @@ public: virtual BOOL IsCoOp( void ) = 0;// is this a coop game? // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ) = 0; // a client just connected to the server (player hasn't spawned yet) + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) = 0; // a client just connected to the server (player hasn't spawned yet) virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode @@ -166,7 +166,7 @@ public: virtual BOOL IsCoOp( void ); // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); @@ -239,7 +239,7 @@ public: // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in // svRejectReason // Only the client's name and remote address are provided to the dll for verification. - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode diff --git a/server/game/multiplay_gamerules.cpp b/server/game/multiplay_gamerules.cpp index 86d349d2..b9a95c9f 100644 --- a/server/game/multiplay_gamerules.cpp +++ b/server/game/multiplay_gamerules.cpp @@ -312,7 +312,7 @@ BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerW //========================================================= //========================================================= -BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } @@ -330,6 +330,24 @@ void CHalfLifeMultiplay :: InitHUD( CBasePlayer *pl ) UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has joined the game\n", ( pl->pev->netname && STRING(pl->pev->netname)[0] != 0 ) ? STRING(pl->pev->netname) : "unconnected" ) ); + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" entered the game\n", + STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pl->edict() ), "model" ) ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" entered the game\n", + STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), + GETPLAYERUSERID( pl->edict() ) ); + } + UpdateGameMode( pl ); // sending just one score makes the hud scoreboard active; otherwise @@ -380,6 +398,25 @@ void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) if ( pPlayer ) { UTIL_FireTargets( "game_playerleave", pPlayer, pPlayer, USE_TOGGLE ); + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected\n", + STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ) ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" disconnected\n", + STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + GETPLAYERUSERID( pPlayer->edict() ) ); + } + pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items } } @@ -610,13 +647,80 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, if ( pVictim->pev == pKiller ) { // killed self + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n", + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), + killer_weapon_name ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\"\n", + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), + killer_weapon_name ); + } } else if ( pKiller->flags & FL_CLIENT ) { + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n", + STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( ENT(pKiller) ), "model" ), + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), + killer_weapon_name ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\"\n", + STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), + GETPLAYERUSERID( ENT(pKiller) ), + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), + killer_weapon_name ); + } } else { // killed by the world + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (world)\n", + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), + killer_weapon_name ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\" (world)\n", + STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), + killer_weapon_name ); + } } // Print a standard message diff --git a/server/game/singleplay_gamerules.cpp b/server/game/singleplay_gamerules.cpp index 45b332d2..789cee5f 100644 --- a/server/game/singleplay_gamerules.cpp +++ b/server/game/singleplay_gamerules.cpp @@ -87,7 +87,7 @@ BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerWeapo //========================================================= //========================================================= -BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } diff --git a/server/game/teamplay_gamerules.cpp b/server/game/teamplay_gamerules.cpp index 81297a22..36f8e808 100644 --- a/server/game/teamplay_gamerules.cpp +++ b/server/game/teamplay_gamerules.cpp @@ -331,6 +331,13 @@ void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infob sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls ); UTIL_SayTextAll( text, pPlayer ); + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", + STRING(pPlayer->pev->netname), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + pPlayer->m_szTeamName, + mdls ); + ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE ); // recound stuff diff --git a/server/global/client.cpp b/server/global/client.cpp index 97cafa42..b5a004c3 100644 --- a/server/global/client.cpp +++ b/server/global/client.cpp @@ -142,9 +142,9 @@ ClientConnect called when a player connects to a server ============ */ -BOOL ClientConnect( edict_t *pEntity, const char *userinfo ) +BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { - return g_pGameRules->ClientConnected( pEntity, userinfo ); + return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason ); // a client connecting during an intermission can cause problems // if (intermission_running) @@ -400,6 +400,28 @@ void Host_Say( edict_t *pEntity, int teamonly ) temp = "say_team"; else temp = "say"; + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" %s \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pEntity ), "model" ), + temp, + p ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), + temp, + p ); + } } @@ -493,7 +515,7 @@ void ClientCommand( edict_t *pEntity ) else { TraceResult tr; - UTIL_MakeVectors( pev->viewangles ); + UTIL_MakeVectors( pev->v_angle ); UTIL_TraceLine( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000, dont_ignore_monsters, pEntity, &tr ); @@ -522,7 +544,7 @@ void ClientCommand( edict_t *pEntity ) else { TraceResult tr; - UTIL_MakeVectors( pev->viewangles ); + UTIL_MakeVectors( pev->v_angle ); UTIL_TraceLine( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000, dont_ignore_monsters, pEntity, &tr ); @@ -545,8 +567,9 @@ void ClientCommand( edict_t *pEntity ) } else if ( FStrEq(pcmd, "game_over" ) ) { - if(IsMultiplayer()) g_pGameRules->EndMultiplayerGame(); //loading next map - else HOST_ENDGAME( CMD_ARGV( 1 ) ); + if ( IsMultiplayer( )) + g_pGameRules->EndMultiplayerGame(); //loading next map + else g_engfuncs.pfnEndSection( CMD_ARGV( 1 ) ); } else if( FStrEq( pcmd, "gametitle" )) { @@ -666,6 +689,26 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) WRITE_BYTE( ENTINDEX(pEntity) ); WRITE_STRING( text ); MESSAGE_END(); + + // team match? + if ( g_teamplay ) + { + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ), + g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); + } + else + { + UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", + STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), + g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); + } } g_pGameRules->ClientUserInfoChanged( GetClassPtr((CBasePlayer *)&pEntity->v), infobuffer ); } @@ -1149,7 +1192,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) to->scale = pNet->pev->scale; // shared client and render flags to->movetype = (movetype_t)pNet->pev->movetype; to->frame = pNet->pev->frame; // any model current frame - to->contents = pNet->pev->contents; // physic contents to->framerate = pNet->pev->framerate; to->mins = pNet->pev->mins; to->maxs = pNet->pev->maxs; @@ -1194,8 +1236,8 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) else to->aiment = NULLENT_INDEX; to->viewoffset = pNet->pev->view_ofs; - to->viewangles = pNet->pev->viewangles; - to->idealpitch = pNet->pev->ideal_pitch; + to->viewangles = pNet->pev->v_angle; + to->idealpitch = pNet->pev->idealpitch; to->punch_angles = pNet->pev->punchangle; to->velocity = pNet->pev->velocity; to->basevelocity = pNet->pev->clbasevelocity; @@ -1598,6 +1640,249 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag return 1; } +typedef struct +{ + char name[32]; + int field; +} entity_field_alias_t; + +#define FIELD_ORIGIN0 0 +#define FIELD_ORIGIN1 1 +#define FIELD_ORIGIN2 2 +#define FIELD_ANGLES0 3 +#define FIELD_ANGLES1 4 +#define FIELD_ANGLES2 5 + +static entity_field_alias_t entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, +}; + +void Entity_FieldInit( struct delta_s *pFields ) +{ + entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN0 ].name ); + entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN1 ].name ); + entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN2 ].name ); + entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES0 ].name ); + entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES1 ].name ); + entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES2 ].name ); +} + +/* +================== +Entity_Encode + +Callback for sending entity_state_t info over network. +FIXME: Move to script +================== +*/ +void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +static entity_field_alias_t player_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, +}; + +void Player_FieldInit( struct delta_s *pFields ) +{ + player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN0 ].name ); + player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN1 ].name ); + player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN2 ].name ); +} + +/* +================== +Player_Encode + +Callback for sending entity_state_t for players info over network. +================== +*/ +void Player_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Player_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +#define CUSTOMFIELD_ORIGIN0 0 +#define CUSTOMFIELD_ORIGIN1 1 +#define CUSTOMFIELD_ORIGIN2 2 +#define CUSTOMFIELD_ANGLES0 3 +#define CUSTOMFIELD_ANGLES1 4 +#define CUSTOMFIELD_ANGLES2 5 +#define CUSTOMFIELD_SKIN 6 +#define CUSTOMFIELD_SEQUENCE 7 +#define CUSTOMFIELD_ANIMTIME 8 + +entity_field_alias_t custom_entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, + { "skin", 0 }, + { "sequence", 0 }, + { "animtime", 0 }, +}; + +void Custom_Entity_FieldInit( struct delta_s *pFields ) +{ + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name ); +} + +/* +================== +Custom_Encode + +Callback for sending entity_state_t info ( for custom entities ) over network. +FIXME: Move to script +================== +*/ +void Custom_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int beamType; + static int initialized = 0; + + if ( !initialized ) + { + Custom_Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + beamType = t->rendermode; + + if ( beamType != BEAM_POINTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field ); + } + + if ( beamType != BEAM_POINTS ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field ); + } + + if ( beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field ); + } + + // animtime is compared by rounding first + // see if we really shouldn't actually send it + if ( (int)f->animtime == (int)t->animtime ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field ); + } +} + +/* +================= +RegisterEncoders + +Allows game .dll to override network encoding of certain types of entities and tweak values, etc. +================= +*/ +void RegisterEncoders( void ) +{ + DELTA_ADDENCODER( "Entity_Encode", Entity_Encode ); + DELTA_ADDENCODER( "Custom_Encode", Custom_Encode ); + DELTA_ADDENCODER( "Player_Encode", Player_Encode ); +} + //======================================================================= // Link User Messages - register new client messages here //======================================================================= diff --git a/server/global/client.h b/server/global/client.h index 1a880449..8a6bbea7 100644 --- a/server/global/client.h +++ b/server/global/client.h @@ -20,7 +20,7 @@ extern void PhysicsFrame( void ); extern void PhysicsPostFrame( void ); extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); -extern BOOL ClientConnect( edict_t *pEntity, const char *userinfo ); +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 ); @@ -30,6 +30,7 @@ extern void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) extern void ServerDeactivate( void ); extern void StartFrame( void ); extern void EndFrame( void ); +extern void RegisterEncoders( void ); extern void PlayerPostThink( edict_t *pEntity ); extern void PlayerPreThink( edict_t *pEntity ); extern void BuildLevelList( void ); diff --git a/server/global/dll_int.cpp b/server/global/dll_int.cpp index d7ce592b..76881685 100644 --- a/server/global/dll_int.cpp +++ b/server/global/dll_int.cpp @@ -27,9 +27,14 @@ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } +void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +{ + memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); + gpGlobals = pGlobals; +} + static DLL_FUNCTIONS gFunctionTable = { - sizeof( DLL_FUNCTIONS ), GameDLLInit, // pfnGameInit DispatchSpawn, // pfnSpawn DispatchThink, // pfnThink @@ -82,31 +87,29 @@ static DLL_FUNCTIONS gFunctionTable = DispatchFrame, // pfnPhysicsEntity AddToFullPack, // pfnAddtoFullPack EndFrame, // pfnEndFrame - - ShouldCollide, // pfnShouldCollide + + RegisterEncoders, // pfnRegisterEncoders Callbacks for network encoding + UpdateEntityState, // pfnUpdateEntityState CmdStart, // pfnCmdStart CmdEnd, // pfnCmdEnd OnFreeEntPrivateData, // pfnOnFreeEntPrivateData GameDLLShutdown, // pfnGameShutdown + ShouldCollide, // pfnShouldCollide }; //======================================================================= // General API entering point //======================================================================= - -int CreateAPI( DLL_FUNCTIONS *pFunctionTable, enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ) { - if( !pFunctionTable || !pengfuncsFromEngine || !pGlobals ) + if ( !pFunctionTable || interfaceVersion != SV_INTERFACE_VERSION ) { return FALSE; } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS )); - memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof( enginefuncs_t )); - gpGlobals = pGlobals; - + + memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); return TRUE; } diff --git a/server/global/enginecallback.h b/server/global/enginecallback.h index 1916d042..5f6254ed 100644 --- a/server/global/enginecallback.h +++ b/server/global/enginecallback.h @@ -22,6 +22,7 @@ extern enginefuncs_t g_engfuncs; #define MALLOC( x ) (*g_engfuncs.pfnMemAlloc)( x, __FILE__, __LINE__ ) #define CALLOC( x, y ) (*g_engfuncs.pfnMemAlloc)((x) * (y), __FILE__, __LINE__ ) #define FREE( x ) (*g_engfuncs.pfnMemFree)( x, __FILE__, __LINE__ ) +#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) #define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel) #define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound) #define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) @@ -65,6 +66,7 @@ extern enginefuncs_t g_engfuncs; #define CRC32_FINAL (*g_engfuncs.pfnCRC_Final) #define RANDOM_LONG (*g_engfuncs.pfnRandomLong) #define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #define CLASSIFY_EDICT (*g_engfuncs.pfnClassifyEdict) #define COM_Parse (*g_engfuncs.pfnParseToken) @@ -132,7 +134,6 @@ inline void *GET_PRIVATE( edict_t *pent ) #define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) #define SET_VIEW (*g_engfuncs.pfnSetView) #define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) -#define SET_SKYBOX (*g_engfuncs.pfnSetSkybox) #define LOAD_FILE (*g_engfuncs.pfnLoadFile) #define FILE_EXISTS (*g_engfuncs.pfnFileExists) #define FREE_FILE (*g_engfuncs.pfnFreeFile) @@ -140,6 +141,7 @@ inline void *GET_PRIVATE( edict_t *pent ) #define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir) #define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer) #define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) +#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) #define SET_BONE_POSITION (*g_engfuncs.pfnSetBonePos) #define DROP_CLIENT (*g_engfuncs.pfnDropClient) #define ENGINE_CHECK_PVS (*g_engfuncs.pfnCheckVisibility) @@ -147,9 +149,15 @@ inline void *GET_PRIVATE( edict_t *pent ) #define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) #define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) #define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) -#define HOST_ENDGAME (*g_engfuncs.pfnEndGame) +#define DELTA_SET (*g_engfuncs.pfnDeltaSetField) +#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField) +#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder) +#define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer) #define HOST_ERROR (*g_engfuncs.pfnHostError) #define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString) +#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField) +#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex) +#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex) #define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask) #define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats) diff --git a/server/global/saverestore.cpp b/server/global/saverestore.cpp index 402784bf..70fb31b4 100644 --- a/server/global/saverestore.cpp +++ b/server/global/saverestore.cpp @@ -33,9 +33,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ), + DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( fixangle, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( ideal_pitch, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ), @@ -124,6 +124,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ), }; // used by engine for FindEntityByString and some other things diff --git a/server/global/utils.cpp b/server/global/utils.cpp index 63343dec..db4957da 100644 --- a/server/global/utils.cpp +++ b/server/global/utils.cpp @@ -473,7 +473,7 @@ CBaseEntity *UTIL_FindEntityForward( CBaseEntity *pMe ) { TraceResult tr; - UTIL_MakeVectors( pMe->pev->viewangles ); + UTIL_MakeVectors( pMe->pev->v_angle ); UTIL_TraceLine( pMe->pev->origin + pMe->pev->view_ofs, pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192, dont_ignore_monsters, pMe->edict(), &tr ); if( tr.flFraction != 1.0 && !FNullEnt( tr.pHit )) { @@ -1621,31 +1621,6 @@ unsigned short UTIL_PrecacheEvent( const char *s ) return g_engfuncs.pfnPrecacheEvent( 1, s ); } -void UTIL_PlaybackEvent( int flags, const edict_t *pInvoker, int ev_index, float delay, event_args_t *args ) -{ - g_engfuncs.pfnPlaybackEvent( flags, pInvoker, ev_index, delay, args ); -} - -void UTIL_PlaybackEvent( int flags, const edict_t *pInvoker, int ev_index, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) -{ - event_args_t args; - - args.flags = 0; - if( !FNullEnt( pInvoker )) - args.entindex = ENTINDEX( (edict_t *)pInvoker ); - else args.entindex = 0; - origin.CopyToArray( args.origin ); - angles.CopyToArray( args.angles ); - // don't add velocity - engine will be reset it for some reasons - args.fparam1 = fparam1; - args.fparam2 = fparam2; - args.iparam1 = iparam1; - args.iparam2 = iparam2; - args.bparam1 = bparam1; - args.bparam2 = bparam2; - - UTIL_PlaybackEvent( flags, pInvoker, ev_index, delay, &args ); -} // ripped this out of the engine float UTIL_AngleMod(float a) @@ -2793,7 +2768,7 @@ BOOL UTIL_IsFacing( entvars_t *pevTest, const Vector &reference ) vecDir.z = 0; vecDir = vecDir.Normalize(); Vector forward, angle; - angle = pevTest->viewangles; + angle = pevTest->v_angle; angle.x = 0; UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL ); diff --git a/server/global/utils.h b/server/global/utils.h index f5ab6099..c3d9e709 100644 --- a/server/global/utils.h +++ b/server/global/utils.h @@ -677,7 +677,6 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); #define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -#define PLAYBACK_EVENT_FULL UTIL_PlaybackEvent #define GROUP_OP_AND 0 #define GROUP_OP_NAND 1 @@ -844,7 +843,5 @@ BOOL UTIL_EntIsVisible( entvars_t* pev, entvars_t* pevTarget); // events stuff unsigned short UTIL_PrecacheEvent( const char *pString ); -void UTIL_PlaybackEvent( int flags, const edict_t *pInvoker, int ev_index, float delay, struct event_args_s *args = NULL ); -void UTIL_PlaybackEvent( int flags, const edict_t *pInvoker, int ev_index, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); #endif //UTIL_H \ No newline at end of file diff --git a/server/monsters/nodes.cpp b/server/monsters/nodes.cpp index 91d465bb..20c16db0 100644 --- a/server/monsters/nodes.cpp +++ b/server/monsters/nodes.cpp @@ -65,7 +65,7 @@ void CGraph :: InitGraph( void) // if ( m_pLinkPool ) { - FREE ( m_pLinkPool ); + free ( m_pLinkPool ); m_pLinkPool = NULL; } @@ -73,13 +73,13 @@ void CGraph :: InitGraph( void) // if ( m_pNodes ) { - FREE ( m_pNodes ); + free ( m_pNodes ); m_pNodes = NULL; } if ( m_di ) { - FREE ( m_di ); + free ( m_di ); m_di = NULL; } @@ -87,13 +87,13 @@ void CGraph :: InitGraph( void) // if ( m_pRouteInfo ) { - FREE ( m_pRouteInfo ); + free ( m_pRouteInfo ); m_pRouteInfo = NULL; } if (m_pHashLinks) { - FREE( m_pHashLinks ); + free(m_pHashLinks); m_pHashLinks = NULL; } @@ -115,7 +115,7 @@ void CGraph :: InitGraph( void) int CGraph :: AllocNodes ( void ) { // malloc all of the nodes - WorldGraph.m_pNodes = (CNode *)CALLOC ( sizeof ( CNode ), MAX_NODES ); + WorldGraph.m_pNodes = (CNode *)calloc ( sizeof ( CNode ), MAX_NODES ); // could not malloc space for all the nodes! if ( !WorldGraph.m_pNodes ) @@ -452,11 +452,11 @@ int CGraph::HullIndex( const CBaseEntity *pEntity ) } -int CGraph::NodeType( const CBaseEntity *pEntity ) +int CGraph::NodeType( const CBaseEntity *pEntity ) { if ( pEntity->pev->movetype == MOVETYPE_FLY) { - if( pEntity->pev->waterlevel != 0 && pEntity->pev->watertype != CONTENTS_FOG ) + if (pEntity->pev->waterlevel != 0 && pEntity->pev->watertype != CONTENTS_FOG) { return bits_NODE_WATER; } @@ -480,9 +480,9 @@ float CGraph::PathLength( int iStart, int iDest, int iHull, int afCapMask ) int iCurrentNode = iStart; int iCap = CapIndex( afCapMask ); - while( iCurrentNode != iDest ) + while (iCurrentNode != iDest) { - if( iMaxLoop-- <= 0 ) + if (iMaxLoop-- <= 0) { ALERT( at_console, "Route Failure\n" ); return 0; @@ -496,13 +496,13 @@ float CGraph::PathLength( int iStart, int iDest, int iHull, int afCapMask ) } int iLink; - HashSearch( iCurrentNode, iNext, iLink ); - if( iLink < 0 ) + HashSearch(iCurrentNode, iNext, iLink); + if (iLink < 0) { - ALERT( at_console, "HashLinks is broken from %d to %d.\n", iCurrentNode, iDest ); + ALERT(at_console, "HashLinks is broken from %d to %d.\n", iCurrentNode, iDest); return 0; } - CLink &link = Link( iLink ); + CLink &link = Link(iLink); distance += link.m_flWeight; iCurrentNode = iNext; @@ -775,14 +775,12 @@ int CGraph :: FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, return iNumPathNodes; } -inline ULONG Hash( void *p, int len ) +inline ULONG Hash(void *p, int len) { - CRC32_t ulCrc; - - CRC32_INIT( &ulCrc ); - CRC32_PROCESS_BUFFER( &ulCrc, p, len ); - - return CRC32_FINAL( ulCrc ); + CRC32_t ulCrc; + CRC32_INIT(&ulCrc); + CRC32_PROCESS_BUFFER(&ulCrc, p, len); + return CRC32_FINAL(ulCrc); } void inline CalcBounds(int &Lower, int &Upper, int Goal, int Best) @@ -1138,7 +1136,7 @@ void CGraph :: ShowNodeConnections ( int iNode ) // If there's a problem with this process, the index // of the offending node will be written to piBadNode //========================================================= -int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) +int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ) { int i,j,z; edict_t *pTraceEnt; @@ -1166,9 +1164,9 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) } else { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "LinkVisibleNodes - Initial Connections\n" ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "LinkVisibleNodes - Initial Connections\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } cTotalLinks = 0;// start with no connections @@ -1184,7 +1182,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "Node #%4d:\n\n", i ); + fprintf ( file, "Node #%4d:\n\n", i ); } for ( z = 0 ; z < MAX_NODE_INITIAL_LINKS ; z++ ) @@ -1272,14 +1270,14 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "%4d", j ); + fprintf ( file, "%4d", j ); if ( !FNullEnt( pLinkPool[ cTotalLinks ].m_pLinkEnt ) ) {// record info about the ent in the way, if any. - ENGINE_FPRINTF ( file, " Entity on connection: %s, name: %s Model: %s", STRING( VARS( pTraceEnt )->classname ), STRING ( VARS( pTraceEnt )->targetname ), STRING ( VARS(tr.pHit)->model ) ); + fprintf ( file, " Entity on connection: %s, name: %s Model: %s", STRING( VARS( pTraceEnt )->classname ), STRING ( VARS( pTraceEnt )->targetname ), STRING ( VARS(tr.pHit)->model ) ); } - ENGINE_FPRINTF ( file, "\n", j ); + fprintf ( file, "\n", j ); } pLinkPool [ cTotalLinks ].m_iDestNode = j; @@ -1291,7 +1289,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( cLinksThisNode == MAX_NODE_INITIAL_LINKS ) { ALERT ( at_aiconsole, "**LinkVisibleNodes:\nNode %d has NodeLinks > MAX_NODE_INITIAL_LINKS", i ); - ENGINE_FPRINTF ( file, "** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i ); + fprintf ( file, "** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i ); *piBadNode = i; return FALSE; } @@ -1304,7 +1302,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( cLinksThisNode == 0 ) { - ENGINE_FPRINTF ( file, "**NO INITIAL LINKS**\n" ); + fprintf ( file, "**NO INITIAL LINKS**\n" ); } // record the connection info in the link pool @@ -1321,12 +1319,12 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } } - ENGINE_FPRINTF ( file, "\n%4d Total Initial Connections - %4d Maximum connections for a single node.\n", cTotalLinks, cMaxInitialLinks ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n\n\n" ); + fprintf ( file, "\n%4d Total Initial Connections - %4d Maximum connections for a single node.\n", cTotalLinks, cMaxInitialLinks ); + fprintf ( file, "----------------------------------------------------------------------------\n\n\n" ); return cTotalLinks; } @@ -1337,7 +1335,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) // want status reports written to disk ). RETURNS the number // of connections that were rejected //========================================================= -int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) +int CGraph :: RejectInlineLinks ( CLink *pLinkPool, FILE *file ) { int i,j,k; @@ -1355,9 +1353,9 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "InLine Rejection:\n" ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "InLine Rejection:\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } cRejectedLinks = 0; @@ -1368,7 +1366,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "Node %3d:\n", i ); + fprintf ( file, "Node %3d:\n", i ); } for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) @@ -1403,7 +1401,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) { if ( file ) { - ENGINE_FPRINTF ( file, "REJECTED NODE %3d through Node %3d, Dot = %8f\n", pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode, pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode, DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) ); + fprintf ( file, "REJECTED NODE %3d through Node %3d, Dot = %8f\n", pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode, pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode, DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) ); } pLinkPool[ pSrcNode->m_iFirstLink + j ] = pLinkPool[ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; @@ -1420,7 +1418,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n\n" ); } } @@ -1599,7 +1597,7 @@ void CTestHull::CallBuildNodeGraph( void ) void CTestHull :: BuildNodeGraph( void ) { TraceResult tr; - void *file; + FILE *file; char szNrpFilename [MAX_PATH];// text node report filename @@ -1641,7 +1639,7 @@ void CTestHull :: BuildNodeGraph( void ) SetNextThink( 0 ); // malloc a swollen temporary connection pool that we trim down after we know exactly how many connections there are. - pTempPool = (CLink *)CALLOC ( sizeof ( CLink ) , ( WorldGraph.m_cNodes * MAX_NODE_INITIAL_LINKS ) ); + pTempPool = (CLink *)calloc ( sizeof ( CLink ) , ( WorldGraph.m_cNodes * MAX_NODE_INITIAL_LINKS ) ); if ( !pTempPool ) { ALERT ( at_aiconsole, "**Could not malloc TempPool!\n" ); @@ -1650,31 +1648,33 @@ void CTestHull :: BuildNodeGraph( void ) // make sure directories have been made - szNrpFilename[0] = '\0'; - strcat( szNrpFilename, "maps" ); + GET_GAME_DIR( szNrpFilename ); + strcat( szNrpFilename, "/maps" ); + CreateDirectory( szNrpFilename, NULL ); strcat( szNrpFilename, "/graphs" ); + CreateDirectory( szNrpFilename, NULL ); + strcat( szNrpFilename, "/" ); strcat( szNrpFilename, STRING( gpGlobals->mapname ) ); strcat( szNrpFilename, ".nrp" ); //disable nrp files - file = g_engfuncs.pfnFOpen( szNrpFilename, "w+" ); + file = fopen ( szNrpFilename, "w+" ); if ( !file ) - { - // file error + {// file error ALERT ( at_aiconsole, "Couldn't create %s!\n", szNrpFilename ); if ( pTempPool ) { - FREE( pTempPool ); + free ( pTempPool ); } return; } - ENGINE_FPRINTF( file, "Node Graph Report for map: %s.bsp\n", STRING(gpGlobals->mapname) ); - ENGINE_FPRINTF ( file, "%d Total Nodes\n\n", WorldGraph.m_cNodes ); + fprintf( file, "Node Graph Report for map: %s.bsp\n", STRING(gpGlobals->mapname) ); + fprintf ( file, "%d Total Nodes\n\n", WorldGraph.m_cNodes ); for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) {// print all node numbers and their locations to the file. @@ -1682,31 +1682,31 @@ void CTestHull :: BuildNodeGraph( void ) WorldGraph.m_pNodes[ i ].m_iFirstLink = 0; memset(WorldGraph.m_pNodes[ i ].m_pNextBestNode, 0, sizeof(WorldGraph.m_pNodes[ i ].m_pNextBestNode)); - ENGINE_FPRINTF ( file, "Node# %4d\n", i ); - ENGINE_FPRINTF ( file, "Location %4d,%4d,%4d\n",(int)WorldGraph.m_pNodes[ i ].m_vecOrigin.x, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.y, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.z ); - ENGINE_FPRINTF ( file, "HintType: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintType ); - ENGINE_FPRINTF ( file, "HintActivity: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintActivity ); - ENGINE_FPRINTF ( file, "HintYaw: %4f\n", WorldGraph.m_pNodes[ i ].m_flHintYaw ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n" ); + fprintf ( file, "Node# %4d\n", i ); + fprintf ( file, "Location %4d,%4d,%4d\n",(int)WorldGraph.m_pNodes[ i ].m_vecOrigin.x, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.y, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.z ); + fprintf ( file, "HintType: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintType ); + fprintf ( file, "HintActivity: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintActivity ); + fprintf ( file, "HintYaw: %4f\n", WorldGraph.m_pNodes[ i ].m_flHintYaw ); + fprintf ( file, "-------------------------------------------------------------------------------\n" ); } - ENGINE_FPRINTF ( file, "\n\n" ); + fprintf ( file, "\n\n" ); // Automatically recognize WATER nodes and drop the LAND nodes to the floor. // for ( i = 0; i < WorldGraph.m_cNodes; i++) { - if( WorldGraph.m_pNodes[i].m_afNodeInfo & bits_NODE_AIR ) + if (WorldGraph.m_pNodes[ i ].m_afNodeInfo & bits_NODE_AIR) { // do nothing } else if (UTIL_PointContents(WorldGraph.m_pNodes[ i ].m_vecOrigin) == CONTENTS_WATER) { - WorldGraph.m_pNodes[i].m_afNodeInfo |= bits_NODE_WATER; + WorldGraph.m_pNodes[ i ].m_afNodeInfo |= bits_NODE_WATER; } else { - WorldGraph.m_pNodes[i].m_afNodeInfo |= bits_NODE_LAND; + WorldGraph.m_pNodes[ i ].m_afNodeInfo |= bits_NODE_LAND; // trace to the ground, then pop up 8 units and place node there to make it // easier for them to connect (think stairs, chairs, and bumps in the floor). @@ -1714,7 +1714,7 @@ void CTestHull :: BuildNodeGraph( void ) // TraceResult tr; - UTIL_TraceLine( WorldGraph.m_pNodes[i].m_vecOrigin, + UTIL_TraceLine ( WorldGraph.m_pNodes[i].m_vecOrigin, WorldGraph.m_pNodes[i].m_vecOrigin - Vector ( 0, 0, 384 ), ignore_monsters, g_pBodyQueueHead,//!!!HACKHACK no real ent to supply here, using a global we don't care about @@ -1754,13 +1754,12 @@ void CTestHull :: BuildNodeGraph( void ) if ( pTempPool ) { - FREE( pTempPool ); + free ( pTempPool ); } if ( file ) - { - // close the file - g_engfuncs.pfnFClose( file ); + {// close the file + fclose ( file ); } return; @@ -1768,15 +1767,15 @@ void CTestHull :: BuildNodeGraph( void ) // send the walkhull to all of this node's connections now. We'll do this here since // so much of it relies on being able to control the test hull. - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "Walk Rejection:\n"); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "Walk Rejection:\n"); for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) { pSrcNode = &WorldGraph.m_pNodes[ i ]; - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Node %4d:\n\n", i ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "Node %4d:\n\n", i ); for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) { @@ -1824,13 +1823,12 @@ void CTestHull :: BuildNodeGraph( void ) ALERT ( at_aiconsole, "**** j = %d ****\n", j ); if ( pTempPool ) { - FREE( pTempPool ); + free ( pTempPool ); } if ( file ) - { - // close the file - g_engfuncs.pfnFClose( file ); + {// close the file + fclose ( file ); } return; } @@ -1838,7 +1836,7 @@ void CTestHull :: BuildNodeGraph( void ) pDestNode = &WorldGraph.m_pNodes [ pTempPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode ]; vecSpot = pDestNode->m_vecOrigin; - // vecSpot.z = pev->origin.z; + //vecSpot.z = pev->origin.z; if (hull < NODE_FLY_HULL) { @@ -1889,17 +1887,17 @@ void CTestHull :: BuildNodeGraph( void ) switch ( hull ) { case NODE_SMALL_HULL: // if this hull can't fit, nothing can, so drop the connection - ENGINE_FPRINTF ( file, "NODE_SMALL_HULL step %f\n", step ); + fprintf ( file, "NODE_SMALL_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_SMALL_HULL | bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); fSkipRemainingHulls = TRUE;// don't bother checking larger hulls break; case NODE_HUMAN_HULL: - ENGINE_FPRINTF ( file, "NODE_HUMAN_HULL step %f\n", step ); + fprintf ( file, "NODE_HUMAN_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); fSkipRemainingHulls = TRUE;// don't bother checking larger hulls break; case NODE_LARGE_HULL: - ENGINE_FPRINTF ( file, "NODE_LARGE_HULL step %f\n", step ); + fprintf ( file, "NODE_LARGE_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~bits_LINK_LARGE_HULL; break; } @@ -1920,9 +1918,9 @@ void CTestHull :: BuildNodeGraph( void ) if (pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo == 0) { - ENGINE_FPRINTF ( file, "Rejected Node %3d - Unreachable by ", pTempPool [ pSrcNode->m_iFirstLink + j ].m_iDestNode ); + fprintf ( file, "Rejected Node %3d - Unreachable by ", pTempPool [ pSrcNode->m_iFirstLink + j ].m_iDestNode ); pTempPool[ pSrcNode->m_iFirstLink + j ] = pTempPool [ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; - ENGINE_FPRINTF ( file, "Any Hull\n" ); + fprintf ( file, "Any Hull\n" ); pSrcNode->m_cNumLinks--; cPoolLinks--;// we just removed a link, so decrement the total number of links in the pool. @@ -1931,31 +1929,30 @@ void CTestHull :: BuildNodeGraph( void ) } } - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n\n\n"); + fprintf ( file, "-------------------------------------------------------------------------------\n\n\n"); cPoolLinks -= WorldGraph.RejectInlineLinks ( pTempPool, file ); // now malloc a pool just large enough to hold the links that are actually used - WorldGraph.m_pLinkPool = (CLink *) CALLOC ( sizeof ( CLink ), cPoolLinks ); + WorldGraph.m_pLinkPool = (CLink *) calloc ( sizeof ( CLink ), cPoolLinks ); if ( !WorldGraph.m_pLinkPool ) {// couldn't make the link pool! ALERT ( at_aiconsole, "Couldn't malloc LinkPool!\n" ); if ( pTempPool ) { - FREE( pTempPool ); + free ( pTempPool ); } if ( file ) - { - // close the file - g_engfuncs.pfnFClose( file ); + {// close the file + fclose ( file ); } return; } WorldGraph.m_cLinks = cPoolLinks; - // copy only the used portions of the TempPool into the graph's link pool +//copy only the used portions of the TempPool into the graph's link pool int iFinalPoolIndex = 0; int iOldFirstLink; @@ -1982,12 +1979,12 @@ void CTestHull :: BuildNodeGraph( void ) fPairsValid = TRUE; // assume that the connection pairs are all valid to start - ENGINE_FPRINTF ( file, "\n\n-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Link Pairings:\n"); + fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); + fprintf ( file, "Link Pairings:\n"); - // link integrity check. The idea here is that if Node A links to Node B, node B should - // link to node A. If not, we have a situation that prevents us from using a basic - // optimization in the FindNearestLink function. +// link integrity check. The idea here is that if Node A links to Node B, node B should +// link to node A. If not, we have a situation that prevents us from using a basic +// optimization in the FindNearestLink function. for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) { for ( j = 0 ; j < WorldGraph.m_pNodes[ i ].m_cNumLinks ; j++ ) @@ -1997,7 +1994,7 @@ void CTestHull :: BuildNodeGraph( void ) if (iLink < 0) { fPairsValid = FALSE;// unmatched link pair. - ENGINE_FPRINTF ( file, "WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); + fprintf ( file, "WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); } } } @@ -2006,15 +2003,15 @@ void CTestHull :: BuildNodeGraph( void ) // (in the find nearest line function) if ( fPairsValid ) { - ENGINE_FPRINTF ( file, "\nAll Connections are Paired!\n"); + fprintf ( file, "\nAll Connections are Paired!\n"); } - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "\n\n-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Connection Pool: %d bytes\n", sizeof ( CLink ) * cPoolLinks ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); + fprintf ( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "Connection Pool: %d bytes\n", sizeof ( CLink ) * cPoolLinks ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); ALERT ( at_aiconsole, "%d Nodes, %d Connections\n", WorldGraph.m_cNodes, cPoolLinks ); @@ -2036,14 +2033,13 @@ void CTestHull :: BuildNodeGraph( void ) if ( pTempPool ) - { - // free the temp pool - FREE( pTempPool ); + {// free the temp pool + free ( pTempPool ); } if ( file ) { - g_engfuncs.pfnFClose( file ); + fclose ( file ); } // We now have some graphing capabilities. @@ -2056,8 +2052,8 @@ void CTestHull :: BuildNodeGraph( void ) // WorldGraph.ComputeStaticRoutingTables(); - // save the node graph for this level - WorldGraph.FSaveGraph( STRING( gpGlobals->mapname )); +// save the node graph for this level + WorldGraph.FSaveGraph( (char *)STRING( gpGlobals->mapname ) ); ALERT( at_console, "Done.\n"); } @@ -2324,11 +2320,18 @@ int CGraph :: FLoadGraph ( const char *szMapName ) byte *pMemFile; // make sure the directories have been made + char szDirName[MAX_PATH]; + GET_GAME_DIR( szDirName ); + strcat( szDirName, "/maps" ); + CreateDirectory( szDirName, NULL ); + strcat( szDirName, "/graphs" ); + CreateDirectory( szDirName, NULL ); + strcpy ( szFilename, "maps/graphs/" ); strcat ( szFilename, szMapName ); strcat( szFilename, ".nod" ); - pMemFile = aMemFile = LOAD_FILE( szFilename, &length); + pMemFile = aMemFile = LOAD_FILE(szFilename, &length); if ( !aMemFile ) { @@ -2369,7 +2372,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) // Malloc for the nodes // - m_pNodes = ( CNode * )CALLOC ( sizeof ( CNode ), m_cNodes ); + m_pNodes = ( CNode * )calloc ( sizeof ( CNode ), m_cNodes ); if ( !m_pNodes ) { @@ -2387,7 +2390,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) // Malloc for the link pool // - m_pLinkPool = ( CLink * )CALLOC ( sizeof ( CLink ), m_cLinks ); + m_pLinkPool = ( CLink * )calloc ( sizeof ( CLink ), m_cLinks ); if ( !m_pLinkPool ) { @@ -2404,7 +2407,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) // Malloc for the sorting info. // - m_di = (DIST_INFO *)CALLOC( sizeof(DIST_INFO), m_cNodes ); + m_di = (DIST_INFO *)calloc( sizeof(DIST_INFO), m_cNodes ); if ( !m_di ) { ALERT ( at_aiconsole, "***ERROR**\nCouldn't malloc %d entries sorting nodes!\n", m_cNodes ); @@ -2421,7 +2424,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) // Malloc for the routing info. // m_fRoutingComplete = FALSE; - m_pRouteInfo = (char *)CALLOC( sizeof(char), m_nRouteInfo ); + m_pRouteInfo = (char *)calloc( sizeof(char), m_nRouteInfo ); if ( !m_pRouteInfo ) { ALERT ( at_aiconsole, "***ERROR**\nCounldn't malloc %d route bytes!\n", m_nRouteInfo ); @@ -2443,7 +2446,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) // malloc for the hash links // - m_pHashLinks = (short *)CALLOC(sizeof(short), m_nHashLinks); + m_pHashLinks = (short *)calloc(sizeof(short), m_nHashLinks); if (!m_pHashLinks) { ALERT ( at_aiconsole, "***ERROR**\nCounldn't malloc %d hash link bytes!\n", m_nHashLinks ); @@ -2458,12 +2461,13 @@ int CGraph :: FLoadGraph ( const char *szMapName ) pMemFile += sizeof(short)*m_nHashLinks; // Set the graph present flag, clear the pointers set flag + // m_fGraphPresent = TRUE; m_fGraphPointersSet = FALSE; - FREE_FILE( aMemFile ); + FREE_FILE(aMemFile); - if( length != 0 ) + if (length != 0) { ALERT ( at_aiconsole, "***WARNING***:Node graph was longer than expected by %d bytes.!\n", length); } @@ -2473,7 +2477,7 @@ int CGraph :: FLoadGraph ( const char *szMapName ) ShortFile: NoMemory: - FREE_FILE( aMemFile ); + FREE_FILE(aMemFile); return FALSE; } @@ -2481,58 +2485,67 @@ NoMemory: // CGraph - FSaveGraph - It's not rocket science. // this WILL overwrite existing files. //========================================================= -int CGraph :: FSaveGraph( const char *szMapName ) +int CGraph :: FSaveGraph ( const char *szMapName ) { - int iVersion = GRAPH_VERSION; + int iVersion = GRAPH_VERSION; char szFilename[MAX_PATH]; - void *file; + FILE *file; - if( !m_fGraphPresent || !m_fGraphPointersSet ) - { - // protect us in the case that the node graph isn't available or built - ALERT( at_aiconsole, "Graph not ready!\n" ); + if ( !m_fGraphPresent || !m_fGraphPointersSet ) + {// protect us in the case that the node graph isn't available or built + ALERT ( at_aiconsole, "Graph not ready!\n" ); return FALSE; } - sprintf( szFilename, "maps/graphs/%s.nod", szMapName ); - file = g_engfuncs.pfnFOpen( szFilename, "wb" ); + // make sure directories have been made + GET_GAME_DIR( szFilename ); + strcat( szFilename, "/maps" ); + CreateDirectory( szFilename, NULL ); + strcat( szFilename, "/graphs" ); + CreateDirectory( szFilename, NULL ); - ALERT( at_aiconsole, "Created: %s\n", szFilename ); + strcat( szFilename, "/" ); + strcat( szFilename, szMapName ); + strcat( szFilename, ".nod" ); - if( !file ) - { - // couldn't create - ALERT( at_aiconsole, "Couldn't Create: %s\n", szFilename ); + file = fopen ( szFilename, "wb" ); + + ALERT ( at_aiconsole, "Created: %s\n", szFilename ); + + if ( !file ) + {// couldn't create + ALERT ( at_aiconsole, "Couldn't Create: %s\n", szFilename ); return FALSE; } else { - // write the version - g_engfuncs.pfnFWrite( file, &iVersion, sizeof( int )); + // write the version + fwrite ( &iVersion, sizeof ( int ), 1, file ); - // write the CGraph class - g_engfuncs.pfnFWrite( file, this, sizeof( CGraph )); + // write the CGraph class + fwrite ( this, sizeof ( CGraph ), 1, file ); - // write the nodes - g_engfuncs.pfnFWrite( file, m_pNodes, sizeof( CNode ) * m_cNodes ); + // write the nodes + fwrite ( m_pNodes, sizeof ( CNode ), m_cNodes, file ); - // write the links - g_engfuncs.pfnFWrite( file, m_pLinkPool, sizeof( CLink ) * m_cLinks ); + // write the links + fwrite ( m_pLinkPool, sizeof ( CLink ), m_cLinks, file ); - g_engfuncs.pfnFWrite( file, m_di, sizeof( DIST_INFO ) * m_cNodes ); + fwrite ( m_di, sizeof(DIST_INFO), m_cNodes, file ); - // write the route info. - if( m_pRouteInfo && m_nRouteInfo ) + // Write the route info. + // + if ( m_pRouteInfo && m_nRouteInfo ) { - g_engfuncs.pfnFWrite( file, m_pRouteInfo, sizeof( char ) * m_nRouteInfo ); + fwrite ( m_pRouteInfo, sizeof( char ), m_nRouteInfo, file ); } - if( m_pHashLinks && m_nHashLinks ) + if (m_pHashLinks && m_nHashLinks) { - g_engfuncs.pfnFWrite( file, m_pHashLinks, sizeof( short ) * m_nHashLinks ); + fwrite(m_pHashLinks, sizeof(short), m_nHashLinks, file); } - g_engfuncs.pfnFClose( file ); + fclose ( file ); return TRUE; } } @@ -2652,57 +2665,51 @@ void CGraph::HashInsert(int iSrcNode, int iDestNode, int iKey) np.iSrc = iSrcNode; np.iDest = iDestNode; + CRC32_t dwHash; + CRC32_INIT(&dwHash); + CRC32_PROCESS_BUFFER(&dwHash, &np, sizeof(np)); + dwHash = CRC32_FINAL(dwHash); - CRC32_t dwHash; - - CRC32_INIT( &dwHash ); - CRC32_PROCESS_BUFFER( &dwHash, &np, sizeof( np )); - dwHash = CRC32_FINAL( dwHash ); - - int di = m_HashPrimes[dwHash & 15]; - int i = (dwHash>>4) % m_nHashLinks; - - while( m_pHashLinks[i] != ENTRY_STATE_EMPTY ) - { - i += di; - if( i >= m_nHashLinks ) - i -= m_nHashLinks; - } + int di = m_HashPrimes[dwHash&15]; + int i = (dwHash >> 4) % m_nHashLinks; + while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) + { + i += di; + if (i >= m_nHashLinks) i -= m_nHashLinks; + } m_pHashLinks[i] = iKey; } -void CGraph::HashSearch( int iSrcNode, int iDestNode, int &iKey ) +void CGraph::HashSearch(int iSrcNode, int iDestNode, int &iKey) { struct tagNodePair np; np.iSrc = iSrcNode; np.iDest = iDestNode; + CRC32_t dwHash; + CRC32_INIT(&dwHash); + CRC32_PROCESS_BUFFER(&dwHash, &np, sizeof(np)); + dwHash = CRC32_FINAL(dwHash); - CRC32_t dwHash; - CRC32_INIT( &dwHash ); - CRC32_PROCESS_BUFFER( &dwHash, &np, sizeof( np )); - dwHash = CRC32_FINAL( dwHash ); - - int di = m_HashPrimes[dwHash & 15]; - int i = (dwHash >> 4) % m_nHashLinks; - - while( m_pHashLinks[i] != ENTRY_STATE_EMPTY ) - { + int di = m_HashPrimes[dwHash&15]; + int i = (dwHash >> 4) % m_nHashLinks; + while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) + { CLink &link = Link(m_pHashLinks[i]); - if( iSrcNode == link.m_iSrcNode && iDestNode == link.m_iDestNode ) - { + if (iSrcNode == link.m_iSrcNode && iDestNode == link.m_iDestNode) + { break; - } - else - { - i += di; - if( i >= m_nHashLinks ) i -= m_nHashLinks; - } - } + } + else + { + i += di; + if (i >= m_nHashLinks) i -= m_nHashLinks; + } + } iKey = m_pHashLinks[i]; } -#define NUMBER_OF_PRIMES 177 +#define NUMBER_OF_PRIMES 177 int Primes[NUMBER_OF_PRIMES] = { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, @@ -2849,7 +2856,7 @@ void CGraph::BuildLinkLookups(void) m_nHashLinks = 3*m_cLinks/2 + 3; HashChoosePrimes(m_nHashLinks); - m_pHashLinks = (short *)CALLOC(sizeof(short), m_nHashLinks); + m_pHashLinks = (short *)calloc(sizeof(short), m_nHashLinks); if (!m_pHashLinks) { ALERT(at_aiconsole, "Couldn't allocated Link Lookup Table.\n"); @@ -2882,11 +2889,11 @@ void CGraph::BuildLinkLookups(void) void CGraph::BuildRegionTables(void) { - if( m_di ) FREE( m_di ); + if (m_di) free(m_di); // Go ahead and setup for range searching the nodes for FindNearestNodes // - m_di = (DIST_INFO *)CALLOC(sizeof(DIST_INFO), m_cNodes); + m_di = (DIST_INFO *)calloc(sizeof(DIST_INFO), m_cNodes); if (!m_di) { ALERT(at_aiconsole, "Couldn't allocated node ordering array.\n"); @@ -3293,9 +3300,9 @@ void CGraph :: ComputeStaticRoutingTables( void ) } else { - char *Tmp = (char *)CALLOC(sizeof(char), (m_nRouteInfo + nRoute)); + char *Tmp = (char *)calloc(sizeof(char), (m_nRouteInfo + nRoute)); memcpy(Tmp, m_pRouteInfo, m_nRouteInfo); - FREE( m_pRouteInfo ); + free(m_pRouteInfo); m_pRouteInfo = Tmp; memcpy(m_pRouteInfo + m_nRouteInfo, pRoute, nRoute); m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = m_nRouteInfo; @@ -3306,7 +3313,7 @@ void CGraph :: ComputeStaticRoutingTables( void ) else { m_nRouteInfo = nRoute; - m_pRouteInfo = (char *)CALLOC(sizeof(char), nRoute); + m_pRouteInfo = (char *)calloc(sizeof(char), nRoute); memcpy(m_pRouteInfo, pRoute, nRoute); m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = 0; nTotalCompressedSize += CompressedSize; @@ -3497,9 +3504,8 @@ LINK_ENTITY_TO_CLASS( node_viewer_large, CNodeViewer ); void CNodeViewer::Spawn( ) { - if( !WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet ) - { - // protect us in the case that the node graph isn't available or built + if ( !WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet ) + {// protect us in the case that the node graph isn't available or built ALERT ( at_console, "Graph not ready!\n" ); UTIL_Remove( this ); return; @@ -3528,7 +3534,7 @@ void CNodeViewer::Spawn( ) m_iBaseNode = WorldGraph.FindNearestNode ( pev->origin, m_afNodeType ); - if( m_iBaseNode < 0 ) + if ( m_iBaseNode < 0 ) { ALERT( at_console, "No nearby node\n" ); return; diff --git a/server/monsters/nodes.h b/server/monsters/nodes.h index ea844f31..692546de 100644 --- a/server/monsters/nodes.h +++ b/server/monsters/nodes.h @@ -159,8 +159,8 @@ public: int m_iLastCoverSearch; // functions to create the graph - int LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ); - int RejectInlineLinks ( CLink *pLinkPool, void *file ); + int LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ); + int RejectInlineLinks ( CLink *pLinkPool, FILE *file ); int FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask); int FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ); int FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ); diff --git a/server/monsters/player.cpp b/server/monsters/player.cpp index 8bea3598..8977f36a 100644 --- a/server/monsters/player.cpp +++ b/server/monsters/player.cpp @@ -1366,7 +1366,7 @@ void CBasePlayer::StartDeathCam( void ) } CopyToBodyQue( pev ); - StartObserver( pSpot->pev->origin, pSpot->pev->viewangles ); + StartObserver( pSpot->pev->origin, pSpot->pev->v_angle ); } else { @@ -1384,7 +1384,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) m_afPhysicsFlags |= PFLAG_OBSERVER; pev->view_ofs = g_vecZero; - pev->angles = pev->viewangles = vecViewAngle; + pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; @@ -1453,7 +1453,7 @@ void CBasePlayer::PlayerUse ( void ) TraceResult tr; int caps; - UTIL_MakeVectors ( pev->viewangles );// so we know which way we are facing + UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing //LRC- try to get an exact entity to use. // (is this causing "use-buttons-through-walls" problems? Surely not!) @@ -1684,7 +1684,7 @@ void CBasePlayer::UpdateStatusBar() // Find an ID Target TraceResult tr; - UTIL_MakeVectors( pev->viewangles + pev->punchangle ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle ); Vector vecSrc = EyePosition(); Vector vecEnd = vecSrc + (gpGlobals->v_forward * MAX_ID_RANGE); UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr); @@ -1789,7 +1789,7 @@ void CBasePlayer::PreThink(void) if ( g_fGameOver ) return; // intermission or finale - UTIL_MakeVectors(pev->viewangles); // is this still used? + UTIL_MakeVectors(pev->v_angle); // is this still used? ItemPreFrame( ); WaterMove(); @@ -2507,14 +2507,6 @@ void CBasePlayer::PostThink() if ( (FBitSet(pev->flags, FL_ONGROUND)) && (pev->health > 0) && m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) { // ALERT ( at_console, "%f\n", m_flFallVelocity ); - - if( pev->flJumpPadTime && pev->flJumpPadTime < gpGlobals->time ) - { - // scale delta if was pushed by jump pad - float delta = (1.0f + gpGlobals->time - pev->flJumpPadTime) * 0.5f; - m_flFallVelocity /= delta; - pev->flJumpPadTime = 0.0f; - } if (pev->watertype == CONTENTS_WATER) { @@ -2728,8 +2720,7 @@ void CBasePlayer::Spawn( void ) pev->gravity = 1.0; pev->renderfx = 0; pev->rendercolor = g_vecZero; - pev->mass = 90; // lbs - pev->viewangles.z = 0; // cut off any camera rolling + pev->v_angle.z = 0; // cut off any camera rolling m_bitsHUDDamage = -1; m_bitsDamageType = 0; m_afPhysicsFlags = 0; @@ -2901,11 +2892,11 @@ int CBasePlayer::Restore( CRestore &restore ) // default to normal spawn edict_t* pentSpawnSpot = EntSelectSpawnPoint( this ); pev->origin = VARS( pentSpawnSpot )->origin + Vector( 0, 0, 1 ); - pev->viewangles = pev->angles = VARS( pentSpawnSpot )->angles; + pev->v_angle = pev->angles = VARS( pentSpawnSpot )->angles; } - pev->viewangles.z = 0; // clear out roll - pev->angles = pev->viewangles; + pev->v_angle.z = 0; // clear out roll + pev->angles = pev->v_angle; pev->fixangle = TRUE; // turn this way immediately // Copied from spawn() for now @@ -3225,7 +3216,7 @@ public: void CSprayCan::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); pev->frame = 0; @@ -3281,7 +3272,7 @@ public: void CBloodSplat::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); SetThink(&CBloodSplat:: Spray ); @@ -3439,7 +3430,7 @@ void CBasePlayer::ImpulseCommands( void ) case 201: // paint decal if( gpGlobals->time < m_flNextDecalTime ) break; - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); if ( tr.flFraction != 1.0 ) @@ -4397,7 +4388,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta ) // ALERT( at_console, "%f %f\n", angles.x, angles.y ); - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); return gpGlobals->v_forward; } @@ -4417,7 +4408,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD return g_vecZero; } - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); // try all possible entities bestdir = gpGlobals->v_forward; @@ -4512,7 +4503,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD { bestdir = UTIL_VecToAngles (bestdir); bestdir.x = -bestdir.x; - bestdir = bestdir - pev->viewangles - pev->punchangle; + bestdir = bestdir - pev->v_angle - pev->punchangle; if (bestent->v.takedamage == DAMAGE_AIM) m_fOnTarget = TRUE; diff --git a/server/monsters/turret.cpp b/server/monsters/turret.cpp index 98c8b5bf..c1c0437b 100644 --- a/server/monsters/turret.cpp +++ b/server/monsters/turret.cpp @@ -271,7 +271,7 @@ void CBaseTurret::Spawn() if (m_iOrientation == 1) { - pev->ideal_pitch = 180; + pev->idealpitch = 180; pev->angles.x = 180; } @@ -391,7 +391,7 @@ void CBaseTurret::Initialize(void) m_flStartYaw = pev->angles.y; if (m_iOrientation == 1) { -// pev->ideal_pitch = 180; //This is moved to CBaseTurret::Spawn for fix old bug in original HL. G-Cont. +// pev->idealpitch = 180; //This is moved to CBaseTurret::Spawn for fix old bug in original HL. G-Cont. // pev->angles.x = 180; pev->view_ofs.z = -pev->view_ofs.z; pev->effects |= EF_INVLIGHT; diff --git a/server/server.def b/server/server.def index 9ff5285c..a2eccc63 100644 --- a/server/server.def +++ b/server/server.def @@ -1,5 +1,5 @@ LIBRARY server EXPORTS - CreateAPI @1 + GiveFnptrsToDll @1 SECTIONS .data READ WRITE diff --git a/spirit/airtank.cpp b/spirit/airtank.cpp index a1bbfe25..bf6240d0 100644 --- a/spirit/airtank.cpp +++ b/spirit/airtank.cpp @@ -105,11 +105,8 @@ void CAirtank::TankTouch( CBaseEntity *pOther ) return; } - CBasePlayer *pPlayer = (CBasePlayer *)CBasePlayer::Instance( pOther->pev ); - if( !pOther ) return; - // give player 12 more seconds of air - pPlayer->m_fAirFinished = gpGlobals->time + 12; + pOther->pev->air_finished = gpGlobals->time + 12; // suit recharge sound EMIT_SOUND( ENT(pev), CHAN_VOICE, "doors/aliendoor3.wav", 1.0, ATTN_NORM ); diff --git a/spirit/barney.cpp b/spirit/barney.cpp index cd45aa21..f4c45e83 100644 --- a/spirit/barney.cpp +++ b/spirit/barney.cpp @@ -539,7 +539,7 @@ static BOOL IsFacing( entvars_t *pevTest, const Vector &reference ) vecDir.z = 0; vecDir = vecDir.Normalize(); Vector forward, angle; - angle = pevTest->viewangles; + angle = pevTest->v_angle; angle.x = 0; UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL ); // He's facing me, he meant it diff --git a/spirit/cbase.cpp b/spirit/cbase.cpp index 0de2a081..fd93ac45 100644 --- a/spirit/cbase.cpp +++ b/spirit/cbase.cpp @@ -24,9 +24,6 @@ #include "skill.h" #include "weapons.h" -enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; - void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ); extern Vector VecBModelOrigin( entvars_t* pevBModel ); @@ -35,7 +32,6 @@ extern DLL_GLOBAL int g_iSkillLevel; static DLL_FUNCTIONS gFunctionTable = { - sizeof( DLL_FUNCTIONS ), // Xash3D requires this GameDLLInit, // pfnGameInit DispatchSpawn, // pfnSpawn DispatchThink, // pfnThink @@ -89,13 +85,15 @@ static DLL_FUNCTIONS gFunctionTable = AddToFullPack, // pfnAddtoFullPack EndFrame, // pfnEndFrame - ShouldCollide, // pfnShouldCollide + + RegisterEncoders, // pfnRegisterEncoders Callbacks for network encoding UpdateEntityState, // pfnUpdateEntityState CmdStart, // pfnCmdStart CmdEnd, // pfnCmdEnd OnFreeEntPrivateData, // pfnOnFreeEntPrivateData GameDLLShutdown, // pfnGameShutdown + ShouldCollide, // pfnShouldCollide }; static void SetObjectCollisionBox( entvars_t *pev ); @@ -103,18 +101,14 @@ static void SetObjectCollisionBox( entvars_t *pev ); //======================================================================= // General API entering point //======================================================================= - -int CreateAPI( DLL_FUNCTIONS *pFunctionTable, enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ) { - if( !pFunctionTable || !pengfuncsFromEngine || !pGlobals ) + if ( !pFunctionTable || interfaceVersion != SV_INTERFACE_VERSION ) { return FALSE; } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS )); - memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof( enginefuncs_t )); - gpGlobals = pGlobals; - + + memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); return TRUE; } diff --git a/spirit/cbase.h b/spirit/cbase.h index cacd2f87..8230ea7a 100644 --- a/spirit/cbase.h +++ b/spirit/cbase.h @@ -70,6 +70,9 @@ CBaseEntity #define EXPORT /* */ #endif +extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); +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 ); diff --git a/spirit/client.cpp b/spirit/client.cpp index cc088b4f..16c142a8 100644 --- a/spirit/client.cpp +++ b/spirit/client.cpp @@ -79,9 +79,9 @@ ClientConnect called when a player connects to a server ============ */ -BOOL ClientConnect( edict_t *pEntity, const char *userinfo ) +BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { - return g_pGameRules->ClientConnected( pEntity, userinfo ); + return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason ); // a client connecting during an intermission can cause problems // if (intermission_running) @@ -340,6 +340,8 @@ void Host_Say( edict_t *pEntity, int teamonly ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" %s \"%s\"\n", STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pEntity ), "model" ), temp, p ); @@ -348,6 +350,9 @@ void Host_Say( edict_t *pEntity, int teamonly ) { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n", STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), temp, p ); } @@ -445,7 +450,7 @@ void ClientCommand( edict_t *pEntity ) else { TraceResult tr; - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 1000, @@ -474,8 +479,9 @@ void ClientCommand( edict_t *pEntity ) } else if ( FStrEq(pcmd, "game_over" ) ) { - if(IsMultiplayer()) g_pGameRules->EndMultiplayerGame(); //loading next map - else HOST_ENDGAME( CMD_ARGV( 1 ) ); + if( IsMultiplayer( )) + g_pGameRules->EndMultiplayerGame(); // loading next map + else g_engfuncs.pfnEndSection( CMD_ARGV( 1 ) ); } else if( FStrEq( pcmd, "gametitle" )) { @@ -607,6 +613,8 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); } @@ -614,6 +622,9 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", STRING( pEntity->v.netname ), + GETPLAYERUSERID( pEntity ), + GETPLAYERAUTHID( pEntity ), + GETPLAYERUSERID( pEntity ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); } } @@ -903,7 +914,7 @@ const char *GetGameDescription() // alternative handle come from Xash 0.4 char *token = NULL; char szbuffer[128]; - char *afile = (char *)LOAD_FILE( "gameinfo.txt", NULL ); + char *afile = (char *)LOAD_FILE_FOR_ME( "gameinfo.txt", NULL ); const char *pfile = afile; memset( text, 0, sizeof( text )); @@ -1117,7 +1128,6 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) to->scale = pNet->pev->scale; // shared client and render flags to->movetype = (movetype_t)pNet->pev->movetype; to->frame = pNet->pev->frame; // any model current frame - to->contents = pNet->pev->contents; // physic contents to->framerate = pNet->pev->framerate; to->mins = pNet->pev->mins; to->maxs = pNet->pev->maxs; @@ -1162,8 +1172,8 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline ) else to->aiment = NULLENT_INDEX; to->viewoffset = pNet->pev->view_ofs; - to->viewangles = pNet->pev->viewangles; - to->idealpitch = pNet->pev->ideal_pitch; + to->viewangles = pNet->pev->v_angle; + to->idealpitch = pNet->pev->idealpitch; to->punch_angles = pNet->pev->punchangle; to->velocity = pNet->pev->velocity; to->basevelocity = pNet->pev->clbasevelocity; @@ -1424,6 +1434,249 @@ int AddToFullPack( edict_t *pView, edict_t *pHost, edict_t *pEdict, int hostflag return 1; } +typedef struct +{ + char name[32]; + int field; +} entity_field_alias_t; + +#define FIELD_ORIGIN0 0 +#define FIELD_ORIGIN1 1 +#define FIELD_ORIGIN2 2 +#define FIELD_ANGLES0 3 +#define FIELD_ANGLES1 4 +#define FIELD_ANGLES2 5 + +static entity_field_alias_t entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, +}; + +void Entity_FieldInit( struct delta_s *pFields ) +{ + entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN0 ].name ); + entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN1 ].name ); + entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN2 ].name ); + entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES0 ].name ); + entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES1 ].name ); + entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES2 ].name ); +} + +/* +================== +Entity_Encode + +Callback for sending entity_state_t info over network. +FIXME: Move to script +================== +*/ +void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +static entity_field_alias_t player_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, +}; + +void Player_FieldInit( struct delta_s *pFields ) +{ + player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN0 ].name ); + player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN1 ].name ); + player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN2 ].name ); +} + +/* +================== +Player_Encode + +Callback for sending entity_state_t for players info over network. +================== +*/ +void Player_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int localplayer = 0; + static int initialized = 0; + + if ( !initialized ) + { + Player_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + // Never send origin to local player, it's sent with more resolution in clientdata_t structure + localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); + if ( localplayer ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + + if ( ( t->movetype == MOVETYPE_FOLLOW ) && + ( t->aiment != 0 ) ) + { + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } + else if ( t->aiment != f->aiment ) + { + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); + DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); + } +} + +#define CUSTOMFIELD_ORIGIN0 0 +#define CUSTOMFIELD_ORIGIN1 1 +#define CUSTOMFIELD_ORIGIN2 2 +#define CUSTOMFIELD_ANGLES0 3 +#define CUSTOMFIELD_ANGLES1 4 +#define CUSTOMFIELD_ANGLES2 5 +#define CUSTOMFIELD_SKIN 6 +#define CUSTOMFIELD_SEQUENCE 7 +#define CUSTOMFIELD_ANIMTIME 8 + +entity_field_alias_t custom_entity_field_alias[]= +{ + { "origin[0]", 0 }, + { "origin[1]", 0 }, + { "origin[2]", 0 }, + { "angles[0]", 0 }, + { "angles[1]", 0 }, + { "angles[2]", 0 }, + { "skin", 0 }, + { "sequence", 0 }, + { "animtime", 0 }, +}; + +void Custom_Entity_FieldInit( struct delta_s *pFields ) +{ + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name ); + custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name ); + custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name ); +} + +/* +================== +Custom_Encode + +Callback for sending entity_state_t info ( for custom entities ) over network. +FIXME: Move to script +================== +*/ +void Custom_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) +{ + entity_state_t *f, *t; + int beamType; + static int initialized = 0; + + if ( !initialized ) + { + Custom_Entity_FieldInit( pFields ); + initialized = 1; + } + + f = (entity_state_t *)from; + t = (entity_state_t *)to; + + beamType = t->rendermode; + + if ( beamType != BEAM_POINTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field ); + } + + if ( beamType != BEAM_POINTS ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field ); + } + + if ( beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field ); + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field ); + } + + // animtime is compared by rounding first + // see if we really shouldn't actually send it + if ( (int)f->animtime == (int)t->animtime ) + { + DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field ); + } +} + +/* +================= +RegisterEncoders + +Allows game .dll to override network encoding of certain types of entities and tweak values, etc. +================= +*/ +void RegisterEncoders( void ) +{ + DELTA_ADDENCODER( "Entity_Encode", Entity_Encode ); + DELTA_ADDENCODER( "Custom_Encode", Custom_Encode ); + DELTA_ADDENCODER( "Player_Encode", Player_Encode ); +} + /* ================= CmdStart diff --git a/spirit/client.h b/spirit/client.h index c6bfc826..169b9498 100644 --- a/spirit/client.h +++ b/spirit/client.h @@ -20,7 +20,7 @@ extern void PhysicsFrame( void ); extern void PhysicsPostFrame( void ); extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); -extern BOOL ClientConnect( edict_t *pEntity, const char *userinfo ); +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 ); @@ -34,7 +34,7 @@ extern void PlayerPostThink( edict_t *pEntity ); extern void PlayerPreThink( edict_t *pEntity ); extern void BuildLevelList( void ); extern void ParmsChangeLevel( void ); - +extern void RegisterEncoders( void ); extern void ClientPrecache( void ); extern const char *GetGameDescription( void ); diff --git a/spirit/crossbow.cpp b/spirit/crossbow.cpp index b73da7ac..34052731 100644 --- a/spirit/crossbow.cpp +++ b/spirit/crossbow.cpp @@ -350,7 +350,7 @@ void CCrossbow::FireSniperBolt() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); Vector vecSrc = m_pPlayer->GetGunPosition( ) - gpGlobals->v_up * 2; Vector vecDir = gpGlobals->v_forward; @@ -425,7 +425,7 @@ void CCrossbow::FireBolt() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - Vector anglesAim = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); anglesAim.x = -anglesAim.x; diff --git a/spirit/crowbar.cpp b/spirit/crowbar.cpp index 483b60df..6251b1ff 100644 --- a/spirit/crowbar.cpp +++ b/spirit/crowbar.cpp @@ -181,7 +181,7 @@ int CCrowbar::Swing( int fFirst ) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3; - UTIL_MakeVectors (m_pPlayer->pev->viewangles); + UTIL_MakeVectors (m_pPlayer->pev->v_angle); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecEnd = vecSrc + gpGlobals->v_forward * 32; diff --git a/spirit/egon.cpp b/spirit/egon.cpp index 671547de..6f13c706 100644 --- a/spirit/egon.cpp +++ b/spirit/egon.cpp @@ -196,7 +196,7 @@ void CEgon::PrimaryAttack( void ) return; } - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); diff --git a/spirit/enginecallback.h b/spirit/enginecallback.h index cb6f850f..19096cbb 100644 --- a/spirit/enginecallback.h +++ b/spirit/enginecallback.h @@ -29,6 +29,7 @@ extern enginefuncs_t g_engfuncs; //#define SET_MODEL (*g_engfuncs.pfnSetModel) //#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) +#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) #define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) #define MODEL_INDEX (*g_engfuncs.pfnModelIndex) #define MODEL_FRAMES (*g_engfuncs.pfnModelFrames) @@ -69,6 +70,7 @@ extern enginefuncs_t g_engfuncs; #define CRC32_FINAL (*g_engfuncs.pfnCRC_Final) #define RANDOM_LONG (*g_engfuncs.pfnRandomLong) #define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) #define CLASSIFY_EDICT (*g_engfuncs.pfnClassifyEdict) #define COM_Parse (*g_engfuncs.pfnParseToken) @@ -100,7 +102,6 @@ inline void WRITE_FLOAT( float flValue ) #define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat) #define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString) #define ALERT (*g_engfuncs.pfnAlertMessage) -#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf) #define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData) inline void *GET_PRIVATE( edict_t *pent ) { @@ -135,8 +136,7 @@ inline void *GET_PRIVATE( edict_t *pent ) #define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) #define SET_VIEW (*g_engfuncs.pfnSetView) #define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) -#define SET_SKYBOX (*g_engfuncs.pfnSetSkybox) -#define LOAD_FILE (*g_engfuncs.pfnLoadFile) +#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFile) #define FILE_EXISTS (*g_engfuncs.pfnFileExists) #define FREE_FILE (*g_engfuncs.pfnFreeFile) #define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) @@ -145,14 +145,21 @@ inline void *GET_PRIVATE( edict_t *pent ) #define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer) #define SET_BONE_POSITION (*g_engfuncs.pfnSetBonePos) #define DROP_CLIENT (*g_engfuncs.pfnDropClient) +#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) #define ENGINE_CHECK_PVS (*g_engfuncs.pfnCheckVisibility) #define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS) #define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) #define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) #define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) -#define HOST_ENDGAME (*g_engfuncs.pfnEndGame) +#define DELTA_SET (*g_engfuncs.pfnDeltaSetField) +#define DELTA_UNSET (*g_engfuncs.pfnDeltaUnsetField) +#define DELTA_ADDENCODER (*g_engfuncs.pfnDeltaAddEncoder) +#define ENGINE_CURRENT_PLAYER (*g_engfuncs.pfnGetCurrentPlayer) #define HOST_ERROR (*g_engfuncs.pfnHostError) #define ENGINE_GETPHYSINFO (*g_engfuncs.pfnGetPhysicsInfoString) +#define DELTA_FINDFIELD (*g_engfuncs.pfnDeltaFindField) +#define DELTA_SETBYINDEX (*g_engfuncs.pfnDeltaSetFieldByIndex) +#define DELTA_UNSETBYINDEX (*g_engfuncs.pfnDeltaUnsetFieldByIndex) #define ENGINE_SETGROUPMASK (*g_engfuncs.pfnSetGroupMask) #define PLAYER_CNX_STATS (*g_engfuncs.pfnGetPlayerStats) diff --git a/spirit/func_tank.cpp b/spirit/func_tank.cpp index 27479f3d..cf0899be 100644 --- a/spirit/func_tank.cpp +++ b/spirit/func_tank.cpp @@ -895,7 +895,7 @@ void CFuncTank::TrackTarget( void ) { // "Match target" mode: // first, get the player's angles - angles = pController->pev->viewangles; + angles = pController->pev->v_angle; // Work out what point the player is looking at UTIL_MakeVectorsPrivate(angles, direction,NULL,NULL); @@ -936,7 +936,7 @@ void CFuncTank::TrackTarget( void ) { // "Match angles" mode // just get the player's angles - angles = pController->pev->viewangles; + angles = pController->pev->v_angle; angles[0] = 0 - angles[0]; UpdateSpot(); diff --git a/spirit/gamerules.cpp b/spirit/gamerules.cpp index a0309849..43848c35 100644 --- a/spirit/gamerules.cpp +++ b/spirit/gamerules.cpp @@ -65,7 +65,7 @@ edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer ) edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pPlayer->pev->viewangles = g_vecZero; + pPlayer->pev->v_angle = g_vecZero; pPlayer->pev->velocity = g_vecZero; pPlayer->pev->angles = VARS(pentSpawnSpot)->angles; pPlayer->pev->punchangle = g_vecZero; diff --git a/spirit/gamerules.h b/spirit/gamerules.h index 4331edfd..c542d21d 100644 --- a/spirit/gamerules.h +++ b/spirit/gamerules.h @@ -78,7 +78,7 @@ public: virtual const char *GetGameDescription( void ) { return GAME_NAME; } // this is the game name that gets seen in the server browser // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ) = 0;// a client just connected to the server (player hasn't spawned yet) + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) = 0;// a client just connected to the server (player hasn't spawned yet) virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode @@ -188,7 +188,7 @@ public: virtual BOOL IsCoOp( void ); // Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); @@ -278,7 +278,7 @@ public: // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in // svRejectReason // Only the client's name and remote address are provided to the dll for verification. - virtual BOOL ClientConnected( edict_t *pEntity, const char *userinfo ); + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ); virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating virtual void ClientDisconnected( edict_t *pClient ); virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode diff --git a/spirit/gauss.cpp b/spirit/gauss.cpp index 38ccc95d..d33fee48 100644 --- a/spirit/gauss.cpp +++ b/spirit/gauss.cpp @@ -272,7 +272,7 @@ void CGauss::StartFire( void ) { float flDamage; - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); diff --git a/spirit/h_export.cpp b/spirit/h_export.cpp index c6879545..a16a5d41 100644 --- a/spirit/h_export.cpp +++ b/spirit/h_export.cpp @@ -26,4 +26,18 @@ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { return TRUE; +} + +enginefuncs_t g_engfuncs; +globalvars_t *gpGlobals; + + +#ifdef _WIN32 +void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +#else +extern "C" void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +#endif +{ + memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); + gpGlobals = pGlobals; } \ No newline at end of file diff --git a/spirit/handgrenade.cpp b/spirit/handgrenade.cpp index 2c720913..b5c9001b 100644 --- a/spirit/handgrenade.cpp +++ b/spirit/handgrenade.cpp @@ -152,7 +152,7 @@ void CHandGrenade::WeaponIdle( void ) if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() ) return; if ( m_flStartThrow ) { - Vector angThrow = m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle; + Vector angThrow = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; if ( angThrow.x < 0 ) angThrow.x = -10 + angThrow.x * ( ( 90 - 10 ) / 90.0 ); diff --git a/spirit/hornetgun.cpp b/spirit/hornetgun.cpp index bc31ca35..2303e2d1 100644 --- a/spirit/hornetgun.cpp +++ b/spirit/hornetgun.cpp @@ -118,9 +118,9 @@ void CHgun::PrimaryAttack() Reload( ); if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) return; - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); - CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pHornet->pev->velocity = gpGlobals->v_forward * 300; m_flRechargeTime = gpGlobals->time + 0.5; @@ -151,7 +151,7 @@ void CHgun::SecondaryAttack( void ) CBaseEntity *pHornet; Vector vecSrc; - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12; m_iFirePhase++; @@ -188,7 +188,7 @@ void CHgun::SecondaryAttack( void ) break; } - pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pHornet->pev->velocity = gpGlobals->v_forward * 1200; pHornet->pev->angles = UTIL_VecToAngles( pHornet->pev->velocity ); diff --git a/spirit/ichthyosaur.cpp b/spirit/ichthyosaur.cpp index 335eebf0..cc56aaf5 100644 --- a/spirit/ichthyosaur.cpp +++ b/spirit/ichthyosaur.cpp @@ -1,1115 +1,1115 @@ -/*** -* -* 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. -* -****/ -#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD ) - -//========================================================= -// icthyosaur - evin, satan fish monster -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "schedule.h" -#include "flyingmonster.h" -#include "nodes.h" -#include "soundent.h" -#include "animation.h" -#include "effects.h" -#include "weapons.h" - -#define SEARCH_RETRY 16 - -#define ICHTHYOSAUR_SPEED 150 - -extern CGraph WorldGraph; - -#define EYE_MAD 0 -#define EYE_BASE 1 -#define EYE_CLOSED 2 -#define EYE_BACK 3 -#define EYE_LOOK 4 - - - -//========================================================= -// Monster's Anim Events Go Here -//========================================================= - -// UNDONE: Save/restore here -class CIchthyosaur : public CFlyingMonster -{ -public: - void Spawn( void ); - void Precache( void ); - void SetYawSpeed( void ); - int Classify( void ); - void HandleAnimEvent( MonsterEvent_t *pEvent ); - CUSTOM_SCHEDULES; - - int Save( CSave &save ); - int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - Schedule_t *GetSchedule( void ); - Schedule_t *GetScheduleOfType ( int Type ); - - void Killed( entvars_t *pevAttacker, int iGib ); - void BecomeDead( void ); - - void EXPORT CombatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT BiteTouch( CBaseEntity *pOther ); - - void StartTask( Task_t *pTask ); - void RunTask( Task_t *pTask ); - - BOOL CheckMeleeAttack1 ( float flDot, float flDist ); - BOOL CheckRangeAttack1 ( float flDot, float flDist ); - - float ChangeYaw( int speed ); - Activity GetStoppedActivity( void ); - - void Move( float flInterval ); - void MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ); - void MonsterThink( void ); - void Stop( void ); - void Swim( void ); - Vector DoProbe(const Vector &Probe); - - float VectorToPitch( const Vector &vec); - float FlPitchDiff( void ); - float ChangePitch( int speed ); - - Vector m_SaveVelocity; - float m_idealDist; - - float m_flBlink; - - float m_flEnemyTouched; - BOOL m_bOnAttack; - - float m_flMaxSpeed; - float m_flMinSpeed; - float m_flMaxDist; - - CBeam *m_pBeam; - - float m_flNextAlert; - - static const char *pIdleSounds[]; - static const char *pAlertSounds[]; - static const char *pAttackSounds[]; - static const char *pBiteSounds[]; - static const char *pDieSounds[]; - static const char *pPainSounds[]; - - void IdleSound( void ); - void AlertSound( void ); - void AttackSound( void ); - void BiteSound( void ); - void DeathSound( void ); - void PainSound( void ); -}; - -LINK_ENTITY_TO_CLASS( monster_ichthyosaur, CIchthyosaur ); - -TYPEDESCRIPTION CIchthyosaur::m_SaveData[] = -{ - DEFINE_FIELD( CIchthyosaur, m_SaveVelocity, FIELD_VECTOR ), - DEFINE_FIELD( CIchthyosaur, m_idealDist, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_flBlink, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_flEnemyTouched, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_bOnAttack, FIELD_BOOLEAN ), - DEFINE_FIELD( CIchthyosaur, m_flMaxSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_flMinSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_flMaxDist, FIELD_FLOAT ), - DEFINE_FIELD( CIchthyosaur, m_flNextAlert, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CIchthyosaur, CFlyingMonster ); - - -const char *CIchthyosaur::pIdleSounds[] = -{ - "ichy/ichy_idle1.wav", - "ichy/ichy_idle2.wav", - "ichy/ichy_idle3.wav", - "ichy/ichy_idle4.wav", -}; - -const char *CIchthyosaur::pAlertSounds[] = -{ - "ichy/ichy_alert2.wav", - "ichy/ichy_alert3.wav", -}; - -const char *CIchthyosaur::pAttackSounds[] = -{ - "ichy/ichy_attack1.wav", - "ichy/ichy_attack2.wav", -}; - -const char *CIchthyosaur::pBiteSounds[] = -{ - "ichy/ichy_bite1.wav", - "ichy/ichy_bite2.wav", -}; - -const char *CIchthyosaur::pPainSounds[] = -{ - "ichy/ichy_pain2.wav", - "ichy/ichy_pain3.wav", - "ichy/ichy_pain5.wav", -}; - -const char *CIchthyosaur::pDieSounds[] = -{ - "ichy/ichy_die2.wav", - "ichy/ichy_die4.wav", -}; - -#define EMIT_ICKY_SOUND( chan, array ) \ - EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, 0.6, 0, RANDOM_LONG(95,105) ); - - -void CIchthyosaur :: IdleSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_VOICE, pIdleSounds ); -} - -void CIchthyosaur :: AlertSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_VOICE, pAlertSounds ); -} - -void CIchthyosaur :: AttackSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_VOICE, pAttackSounds ); -} - -void CIchthyosaur :: BiteSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_WEAPON, pBiteSounds ); -} - -void CIchthyosaur :: DeathSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_VOICE, pDieSounds ); -} - -void CIchthyosaur :: PainSound( void ) -{ - EMIT_ICKY_SOUND( CHAN_VOICE, pPainSounds ); -} - -//========================================================= -// monster-specific tasks and states -//========================================================= -enum -{ - TASK_ICHTHYOSAUR_CIRCLE_ENEMY = LAST_COMMON_TASK + 1, - TASK_ICHTHYOSAUR_SWIM, - TASK_ICHTHYOSAUR_FLOAT, -}; - -//========================================================= -// AI Schedules Specific to this monster -//========================================================= - -static Task_t tlSwimAround[] = -{ - { TASK_SET_ACTIVITY, (float)ACT_WALK }, - { TASK_ICHTHYOSAUR_SWIM, 0.0 }, -}; - -static Schedule_t slSwimAround[] = -{ - { - tlSwimAround, - ARRAYSIZE(tlSwimAround), - bits_COND_LIGHT_DAMAGE | - bits_COND_HEAVY_DAMAGE | - bits_COND_SEE_ENEMY | - bits_COND_NEW_ENEMY | - bits_COND_HEAR_SOUND, - bits_SOUND_PLAYER | - bits_SOUND_COMBAT, - "SwimAround" - }, -}; - -static Task_t tlSwimAgitated[] = -{ - { TASK_STOP_MOVING, (float) 0 }, - { TASK_SET_ACTIVITY, (float)ACT_RUN }, - { TASK_WAIT, (float)2.0 }, -}; - -static Schedule_t slSwimAgitated[] = -{ - { - tlSwimAgitated, - ARRAYSIZE(tlSwimAgitated), - 0, - 0, - "SwimAgitated" - }, -}; - - -static Task_t tlCircleEnemy[] = -{ - { TASK_SET_ACTIVITY, (float)ACT_WALK }, - { TASK_ICHTHYOSAUR_CIRCLE_ENEMY, 0.0 }, -}; - -static Schedule_t slCircleEnemy[] = -{ - { - tlCircleEnemy, - ARRAYSIZE(tlCircleEnemy), - bits_COND_NEW_ENEMY | - bits_COND_LIGHT_DAMAGE | - bits_COND_HEAVY_DAMAGE | - bits_COND_CAN_MELEE_ATTACK1 | - bits_COND_CAN_RANGE_ATTACK1, - 0, - "CircleEnemy" - }, -}; - - -Task_t tlTwitchDie[] = -{ - { TASK_STOP_MOVING, 0 }, - { TASK_SOUND_DIE, (float)0 }, - { TASK_DIE, (float)0 }, - { TASK_ICHTHYOSAUR_FLOAT, (float)0 }, -}; - -Schedule_t slTwitchDie[] = -{ - { - tlTwitchDie, - ARRAYSIZE( tlTwitchDie ), - 0, - 0, - "Die" - }, -}; - - -DEFINE_CUSTOM_SCHEDULES(CIchthyosaur) -{ - slSwimAround, - slSwimAgitated, - slCircleEnemy, - slTwitchDie, -}; -IMPLEMENT_CUSTOM_SCHEDULES(CIchthyosaur, CFlyingMonster); - -//========================================================= -// Classify - indicates this monster's place in the -// relationship table. -//========================================================= -int CIchthyosaur :: Classify ( void ) -{ - return m_iClass?m_iClass:CLASS_ALIEN_MONSTER; -} - - -//========================================================= -// CheckMeleeAttack1 -//========================================================= -BOOL CIchthyosaur :: CheckMeleeAttack1 ( float flDot, float flDist ) -{ - if ( flDot >= 0.7 && m_flEnemyTouched > gpGlobals->time - 0.2 ) - { - return TRUE; - } - return FALSE; -} - -void CIchthyosaur::BiteTouch( CBaseEntity *pOther ) -{ - // bite if we hit who we want to eat - if ( pOther == m_hEnemy ) - { - m_flEnemyTouched = gpGlobals->time; - m_bOnAttack = TRUE; - } -} - -void CIchthyosaur::CombatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_bOnAttack ) ) - return; - - if (m_bOnAttack) - { - m_bOnAttack = 0; - } - else - { - m_bOnAttack = 1; - } -} - -//========================================================= -// CheckRangeAttack1 - swim in for a chomp -// -//========================================================= -BOOL CIchthyosaur :: CheckRangeAttack1 ( float flDot, float flDist ) -{ - if ( flDot > -0.7 && (m_bOnAttack || ( flDist <= 192 && m_idealDist <= 192))) - { - return TRUE; - } - - return FALSE; -} - -//========================================================= -// SetYawSpeed - allows each sequence to have a different -// turn rate associated with it. -//========================================================= -void CIchthyosaur :: SetYawSpeed ( void ) -{ - pev->yaw_speed = 100; -} - - - -//========================================================= -// Killed - overrides CFlyingMonster. -// -void CIchthyosaur :: Killed( entvars_t *pevAttacker, int iGib ) -{ - CBaseMonster::Killed( pevAttacker, iGib ); - pev->velocity = Vector( 0, 0, 0 ); -} - -void CIchthyosaur::BecomeDead( void ) -{ - pev->takedamage = DAMAGE_YES;// don't let autoaim aim at corpses. - - // give the corpse half of the monster's original maximum health. - pev->health = pev->max_health / 2; - pev->max_health = 5; // max_health now becomes a counter for how many blood decals the corpse can place. -} - -#define ICHTHYOSAUR_AE_SHAKE_RIGHT 1 -#define ICHTHYOSAUR_AE_SHAKE_LEFT 2 - - -//========================================================= -// HandleAnimEvent - catches the monster-specific messages -// that occur when tagged animation frames are played. -//========================================================= -void CIchthyosaur :: HandleAnimEvent( MonsterEvent_t *pEvent ) -{ - int bDidAttack = FALSE; - switch( pEvent->event ) - { - case ICHTHYOSAUR_AE_SHAKE_RIGHT: - case ICHTHYOSAUR_AE_SHAKE_LEFT: - { - if (m_hEnemy != NULL && FVisible( m_hEnemy )) - { - CBaseEntity *pHurt = m_hEnemy; - - if (m_flEnemyTouched < gpGlobals->time - 0.2 && (m_hEnemy->BodyTarget( pev->origin ) - pev->origin).Length() > (32+16+32)) - break; - - Vector vecShootDir = ShootAtEnemy( pev->origin ); - UTIL_MakeAimVectors ( pev->angles ); - - if (DotProduct( vecShootDir, gpGlobals->v_forward ) > 0.707) - { - m_bOnAttack = TRUE; - pHurt->pev->punchangle.z = -18; - pHurt->pev->punchangle.x = 5; - pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_right * 300; - if (pHurt->IsPlayer()) - { - pHurt->pev->angles.x += RANDOM_FLOAT( -35, 35 ); - pHurt->pev->angles.y += RANDOM_FLOAT( -90, 90 ); - pHurt->pev->angles.z = 0; - pHurt->pev->fixangle = TRUE; - } - pHurt->TakeDamage( pev, pev, gSkillData.ichthyosaurDmgShake, DMG_SLASH ); - } - } - BiteSound(); - - bDidAttack = TRUE; - } - break; - default: - CFlyingMonster::HandleAnimEvent( pEvent ); - break; - } - - if (bDidAttack) - { - Vector vecSrc = pev->origin + gpGlobals->v_forward * 32; - UTIL_Bubbles( vecSrc - Vector( 8, 8, 8 ), vecSrc + Vector( 8, 8, 8 ), 16 ); - } -} - -//========================================================= -// Spawn -//========================================================= -void CIchthyosaur :: Spawn() -{ - Precache( ); - - if (pev->model) - SET_MODEL(ENT(pev), STRING(pev->model)); //LRC - else - SET_MODEL(ENT(pev), "models/icky.mdl"); - UTIL_SetSize( pev, Vector( -32, -32, -32 ), Vector( 32, 32, 32 ) ); - - pev->solid = SOLID_BBOX; - pev->movetype = MOVETYPE_FLY; - m_bloodColor = BLOOD_COLOR_GREEN; - if (pev->health == 0) - pev->health = gSkillData.ichthyosaurHealth; - pev->view_ofs = Vector ( 0, 0, 16 ); - m_flFieldOfView = VIEW_FIELD_WIDE; - m_MonsterState = MONSTERSTATE_NONE; - SetBits(pev->flags, FL_SWIM); - SetFlyingSpeed( ICHTHYOSAUR_SPEED ); - SetFlyingMomentum( 2.5 ); // Set momentum constant - - m_afCapability = bits_CAP_RANGE_ATTACK1 | bits_CAP_SWIM; - - MonsterInit(); - - SetTouch(&CIchthyosaur :: BiteTouch ); - SetUse(&CIchthyosaur :: CombatUse ); - - m_idealDist = 384; - m_flMinSpeed = 80; - m_flMaxSpeed = 300; - m_flMaxDist = 384; - - Vector Forward; - UTIL_MakeVectorsPrivate(pev->angles, Forward, 0, 0); - pev->velocity = m_flightSpeed * Forward.Normalize(); - m_SaveVelocity = pev->velocity; -} - -//========================================================= -// Precache - precaches all resources this monster needs -//========================================================= -void CIchthyosaur :: Precache() -{ - if (pev->model) - PRECACHE_MODEL((char*)STRING(pev->model)); //LRC - else - PRECACHE_MODEL("models/icky.mdl"); - - PRECACHE_SOUND_ARRAY( pIdleSounds ); - PRECACHE_SOUND_ARRAY( pAlertSounds ); - PRECACHE_SOUND_ARRAY( pAttackSounds ); - PRECACHE_SOUND_ARRAY( pBiteSounds ); - PRECACHE_SOUND_ARRAY( pDieSounds ); - PRECACHE_SOUND_ARRAY( pPainSounds ); -} - -//========================================================= -// GetSchedule -//========================================================= -Schedule_t* CIchthyosaur::GetSchedule() -{ - // ALERT( at_console, "GetSchedule( )\n" ); - switch(m_MonsterState) - { - case MONSTERSTATE_IDLE: - m_flightSpeed = 80; - return GetScheduleOfType( SCHED_IDLE_WALK ); - - case MONSTERSTATE_ALERT: - m_flightSpeed = 150; - return GetScheduleOfType( SCHED_IDLE_WALK ); - - case MONSTERSTATE_COMBAT: - m_flMaxSpeed = 400; - // eat them - if ( HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) ) - { - return GetScheduleOfType( SCHED_MELEE_ATTACK1 ); - } - // chase them down and eat them - if ( HasConditions( bits_COND_CAN_RANGE_ATTACK1 ) ) - { - return GetScheduleOfType( SCHED_CHASE_ENEMY ); - } - if ( HasConditions( bits_COND_HEAVY_DAMAGE ) ) - { - m_bOnAttack = TRUE; - } - if ( pev->health < pev->max_health - 20 ) - { - m_bOnAttack = TRUE; - } - - return GetScheduleOfType( SCHED_STANDOFF ); - } - - return CFlyingMonster :: GetSchedule(); -} - - -//========================================================= -//========================================================= -Schedule_t* CIchthyosaur :: GetScheduleOfType ( int Type ) -{ - // ALERT( at_console, "GetScheduleOfType( %d ) %d\n", Type, m_bOnAttack ); - switch ( Type ) - { - case SCHED_IDLE_WALK: - return slSwimAround; - case SCHED_STANDOFF: - return slCircleEnemy; - case SCHED_FAIL: - return slSwimAgitated; - case SCHED_DIE: - return slTwitchDie; - case SCHED_CHASE_ENEMY: - AttackSound( ); - } - - return CBaseMonster :: GetScheduleOfType( Type ); -} - - - -//========================================================= -// Start task - selects the correct activity and performs -// any necessary calculations to start the next task on the -// schedule. -//========================================================= -void CIchthyosaur::StartTask(Task_t *pTask) -{ - switch (pTask->iTask) - { - case TASK_ICHTHYOSAUR_CIRCLE_ENEMY: - break; - case TASK_ICHTHYOSAUR_SWIM: - break; - case TASK_SMALL_FLINCH: - if (m_idealDist > 128) - { - m_flMaxDist = 512; - m_idealDist = 512; - } - else - { - m_bOnAttack = TRUE; - } - CFlyingMonster::StartTask(pTask); - break; - - case TASK_ICHTHYOSAUR_FLOAT: - pev->skin = EYE_BASE; - SetSequenceByName( "bellyup" ); - break; - - default: - CFlyingMonster::StartTask(pTask); - break; - } -} - -void CIchthyosaur :: RunTask ( Task_t *pTask ) -{ - switch ( pTask->iTask ) - { - case TASK_ICHTHYOSAUR_CIRCLE_ENEMY: - if (m_hEnemy == NULL) - { - TaskComplete( ); - } - else if (FVisible( m_hEnemy )) - { - Vector vecFrom = m_hEnemy->EyePosition( ); - - Vector vecDelta = (pev->origin - vecFrom).Normalize( ); - Vector vecSwim = CrossProduct( vecDelta, Vector( 0, 0, 1 ) ).Normalize( ); - - if (DotProduct( vecSwim, m_SaveVelocity ) < 0) - vecSwim = vecSwim * -1.0; - - Vector vecPos = vecFrom + vecDelta * m_idealDist + vecSwim * 32; - - // ALERT( at_console, "vecPos %.0f %.0f %.0f\n", vecPos.x, vecPos.y, vecPos.z ); - - TraceResult tr; - - UTIL_TraceHull( vecFrom, vecPos, ignore_monsters, large_hull, m_hEnemy->edict(), &tr ); - - if (tr.flFraction > 0.5) - vecPos = tr.vecEndPos; - - m_SaveVelocity = m_SaveVelocity * 0.8 + 0.2 * (vecPos - pev->origin).Normalize() * m_flightSpeed; - - // ALERT( at_console, "m_SaveVelocity %.2f %.2f %.2f\n", m_SaveVelocity.x, m_SaveVelocity.y, m_SaveVelocity.z ); - - if (HasConditions( bits_COND_ENEMY_FACING_ME ) && m_hEnemy->FVisible( this )) - { - m_flNextAlert -= 0.1; - - if (m_idealDist < m_flMaxDist) - { - m_idealDist += 4; - } - if (m_flightSpeed > m_flMinSpeed) - { - m_flightSpeed -= 2; - } - else if (m_flightSpeed < m_flMinSpeed) - { - m_flightSpeed += 2; - } - if (m_flMinSpeed < m_flMaxSpeed) - { - m_flMinSpeed += 0.5; - } - } - else - { - m_flNextAlert += 0.1; - - if (m_idealDist > 128) - { - m_idealDist -= 4; - } - if (m_flightSpeed < m_flMaxSpeed) - { - m_flightSpeed += 4; - } - } - // ALERT( at_console, "%.0f\n", m_idealDist ); - } - else - { - m_flNextAlert = gpGlobals->time + 0.2; - } - - if (m_flNextAlert < gpGlobals->time) - { - // ALERT( at_console, "AlertSound()\n"); - AlertSound( ); - m_flNextAlert = gpGlobals->time + RANDOM_FLOAT( 3, 5 ); - } - - break; - case TASK_ICHTHYOSAUR_SWIM: - if (m_fSequenceFinished) - { - TaskComplete( ); - } - break; - case TASK_DIE: - if ( m_fSequenceFinished ) - { - pev->deadflag = DEAD_DEAD; - - TaskComplete( ); - } - break; - - case TASK_ICHTHYOSAUR_FLOAT: - pev->angles.x = UTIL_ApproachAngle( 0, pev->angles.x, 20 ); - pev->velocity = pev->velocity * 0.8; - if (pev->waterlevel > 1 && pev->watertype != CONTENTS_FOG && pev->velocity.z < 64) - { - pev->velocity.z += 8; - } - else - { - pev->velocity.z -= 8; - } - // ALERT( at_console, "%f\n", pev->velocity.z ); - break; - - default: - CFlyingMonster :: RunTask ( pTask ); - break; - } -} - - - -float CIchthyosaur::VectorToPitch( const Vector &vec ) -{ - float pitch; - if (vec.z == 0 && vec.x == 0) - pitch = 0; - else - { - pitch = (int) (atan2(vec.z, sqrt(vec.x*vec.x+vec.y*vec.y)) * 180 / M_PI); - if (pitch < 0) - pitch += 360; - } - return pitch; -} - -//========================================================= -void CIchthyosaur::Move(float flInterval) -{ - CFlyingMonster::Move( flInterval ); -} - -float CIchthyosaur::FlPitchDiff( void ) -{ - float flPitchDiff; - float flCurrentPitch; - - flCurrentPitch = UTIL_AngleMod( pev->angles.z ); - - if ( flCurrentPitch == pev->ideal_pitch ) - { - return 0; - } - - flPitchDiff = pev->ideal_pitch - flCurrentPitch; - - if ( pev->ideal_pitch > flCurrentPitch ) - { - if (flPitchDiff >= 180) - flPitchDiff = flPitchDiff - 360; - } - else - { - if (flPitchDiff <= -180) - flPitchDiff = flPitchDiff + 360; - } - return flPitchDiff; -} - -float CIchthyosaur :: ChangePitch( int speed ) -{ - if ( pev->movetype == MOVETYPE_FLY ) - { - float diff = FlPitchDiff(); - float target = 0; - if ( m_IdealActivity != GetStoppedActivity() ) - { - if (diff < -20) - target = 45; - else if (diff > 20) - target = -45; - } - pev->angles.x = UTIL_Approach(target, pev->angles.x, 220.0 * 0.1 ); - } - return 0; -} - -float CIchthyosaur::ChangeYaw( int speed ) -{ - if ( pev->movetype == MOVETYPE_FLY ) - { - float diff = FlYawDiff(); - float target = 0; - - if ( m_IdealActivity != GetStoppedActivity() ) - { - if ( diff < -20 ) - target = 20; - else if ( diff > 20 ) - target = -20; - } - pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * 0.1 ); - } - return CFlyingMonster::ChangeYaw( speed ); -} - - -Activity CIchthyosaur:: GetStoppedActivity( void ) -{ - if ( pev->movetype != MOVETYPE_FLY ) // UNDONE: Ground idle here, IDLE may be something else - return ACT_IDLE; - return ACT_WALK; -} - -void CIchthyosaur::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ) -{ - m_SaveVelocity = vecDir * m_flightSpeed; -} - - -void CIchthyosaur::MonsterThink ( void ) -{ - CFlyingMonster::MonsterThink( ); - - if (pev->deadflag == DEAD_NO) - { - if (m_MonsterState != MONSTERSTATE_SCRIPT) - { - Swim( ); - - // blink the eye - if (m_flBlink < gpGlobals->time) - { - pev->skin = EYE_CLOSED; - if (m_flBlink + 0.2 < gpGlobals->time) - { - m_flBlink = gpGlobals->time + RANDOM_FLOAT( 3, 4 ); - if (m_bOnAttack) - pev->skin = EYE_MAD; - else - pev->skin = EYE_BASE; - } - } - } - } -} - -void CIchthyosaur :: Stop( void ) -{ - if (!m_bOnAttack) - m_flightSpeed = 80.0; -} - -void CIchthyosaur::Swim( ) -{ - int retValue = 0; - - Vector start = pev->origin; - - Vector Angles; - Vector Forward, Right, Up; - - if (FBitSet( pev->flags, FL_ONGROUND)) - { - pev->angles.x = 0; - pev->angles.y += RANDOM_FLOAT( -45, 45 ); - ClearBits( pev->flags, FL_ONGROUND ); - - Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); - UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); - - pev->velocity = Forward * 200 + Up * 200; - - return; - } - - if (m_bOnAttack && m_flightSpeed < m_flMaxSpeed) - { - m_flightSpeed += 40; - } - if (m_flightSpeed < 180) - { - if (m_IdealActivity == ACT_RUN) - SetActivity( ACT_WALK ); - if (m_IdealActivity == ACT_WALK) - pev->framerate = m_flightSpeed / 150.0; - // ALERT( at_console, "walk %.2f\n", pev->framerate ); - } - else - { - if (m_IdealActivity == ACT_WALK) - SetActivity( ACT_RUN ); - if (m_IdealActivity == ACT_RUN) - pev->framerate = m_flightSpeed / 150.0; - // ALERT( at_console, "run %.2f\n", pev->framerate ); - } - -/* - if (!m_pBeam) - { - m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 80 ); - m_pBeam->PointEntInit( pev->origin + m_SaveVelocity, entindex( ) ); - m_pBeam->SetEndAttachment( 1 ); - m_pBeam->SetColor( 255, 180, 96 ); - m_pBeam->SetBrightness( 192 ); - } -*/ -#define PROBE_LENGTH 150 - Angles = UTIL_VecToAngles( m_SaveVelocity ); - Angles.x = -Angles.x; - UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); - - Vector f, u, l, r, d; - f = DoProbe(start + PROBE_LENGTH * Forward); - r = DoProbe(start + PROBE_LENGTH/3 * Forward+Right); - l = DoProbe(start + PROBE_LENGTH/3 * Forward-Right); - u = DoProbe(start + PROBE_LENGTH/3 * Forward+Up); - d = DoProbe(start + PROBE_LENGTH/3 * Forward-Up); - - Vector SteeringVector = f+r+l+u+d; - m_SaveVelocity = (m_SaveVelocity + SteeringVector/2).Normalize(); - - Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); - UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); - // ALERT( at_console, "%f : %f\n", Angles.x, Forward.z ); - - float flDot = DotProduct( Forward, m_SaveVelocity ); - if (flDot > 0.5) - pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed; - else if (flDot > 0) - pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed * (flDot + 0.5); - else - pev->velocity = m_SaveVelocity = m_SaveVelocity * 80; - - // ALERT( at_console, "%.0f %.0f\n", m_flightSpeed, pev->velocity.Length() ); - - - // ALERT( at_console, "Steer %f %f %f\n", SteeringVector.x, SteeringVector.y, SteeringVector.z ); - -/* - m_pBeam->SetStartPos( pev->origin + pev->velocity ); - m_pBeam->RelinkBeam( ); -*/ - - // ALERT( at_console, "speed %f\n", m_flightSpeed ); - - Angles = UTIL_VecToAngles( m_SaveVelocity ); - - // Smooth Pitch - // - if (Angles.x > 180) - Angles.x = Angles.x - 360; - pev->angles.x = UTIL_Approach(Angles.x, pev->angles.x, 50 * 0.1 ); - if (pev->angles.x < -80) pev->angles.x = -80; - if (pev->angles.x > 80) pev->angles.x = 80; - - // Smooth Yaw and generate Roll - // - float turn = 360; - // ALERT( at_console, "Y %.0f %.0f\n", Angles.y, pev->angles.y ); - - if (fabs(Angles.y - pev->angles.y) < fabs(turn)) - { - turn = Angles.y - pev->angles.y; - } - if (fabs(Angles.y - pev->angles.y + 360) < fabs(turn)) - { - turn = Angles.y - pev->angles.y + 360; - } - if (fabs(Angles.y - pev->angles.y - 360) < fabs(turn)) - { - turn = Angles.y - pev->angles.y - 360; - } - - float speed = m_flightSpeed * 0.1; - - // ALERT( at_console, "speed %.0f %f\n", turn, speed ); - if (fabs(turn) > speed) - { - if (turn < 0.0) - { - turn = -speed; - } - else - { - turn = speed; - } - } - pev->angles.y += turn; - pev->angles.z -= turn; - pev->angles.y = fmod((pev->angles.y + 360.0), 360.0); - - static float yaw_adj; - - yaw_adj = yaw_adj * 0.8 + turn; - - // ALERT( at_console, "yaw %f : %f\n", turn, yaw_adj ); - - SetBoneController( 0, -yaw_adj / 4.0 ); - - // Roll Smoothing - // - turn = 360; - if (fabs(Angles.z - pev->angles.z) < fabs(turn)) - { - turn = Angles.z - pev->angles.z; - } - if (fabs(Angles.z - pev->angles.z + 360) < fabs(turn)) - { - turn = Angles.z - pev->angles.z + 360; - } - if (fabs(Angles.z - pev->angles.z - 360) < fabs(turn)) - { - turn = Angles.z - pev->angles.z - 360; - } - speed = m_flightSpeed/2 * 0.1; - if (fabs(turn) < speed) - { - pev->angles.z += turn; - } - else - { - if (turn < 0.0) - { - pev->angles.z -= speed; - } - else - { - pev->angles.z += speed; - } - } - if (pev->angles.z < -20) pev->angles.z = -20; - if (pev->angles.z > 20) pev->angles.z = 20; - - UTIL_MakeVectorsPrivate( Vector( -Angles.x, Angles.y, Angles.z ), Forward, Right, Up); - - // UTIL_MoveToOrigin ( ENT(pev), pev->origin + Forward * speed, speed, MOVE_STRAFE ); -} - - -Vector CIchthyosaur::DoProbe(const Vector &Probe) -{ - Vector WallNormal = Vector(0,0,-1); // WATER normal is Straight Down for fish. - float frac; - BOOL bBumpedSomething = ProbeZ(pev->origin, Probe, &frac); - - TraceResult tr; - TRACE_MONSTER_HULL(edict(), pev->origin, Probe, dont_ignore_monsters, edict(), &tr); - if ( tr.fAllSolid || tr.flFraction < 0.99 ) - { - if (tr.flFraction < 0.0) tr.flFraction = 0.0; - if (tr.flFraction > 1.0) tr.flFraction = 1.0; - if (tr.flFraction < frac) - { - frac = tr.flFraction; - bBumpedSomething = TRUE; - WallNormal = tr.vecPlaneNormal; - } - } - - if (bBumpedSomething && (m_hEnemy == NULL || tr.pHit != m_hEnemy->edict())) - { - Vector ProbeDir = Probe - pev->origin; - - Vector NormalToProbeAndWallNormal = CrossProduct(ProbeDir, WallNormal); - Vector SteeringVector = CrossProduct( NormalToProbeAndWallNormal, ProbeDir); - - float SteeringForce = m_flightSpeed * (1-frac) * (DotProduct(WallNormal.Normalize(), m_SaveVelocity.Normalize())); - if (SteeringForce < 0.0) - { - SteeringForce = -SteeringForce; - } - SteeringVector = SteeringForce * SteeringVector.Normalize(); - - return SteeringVector; - } - return Vector(0, 0, 0); -} - -#endif +/*** +* +* 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. +* +****/ +#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD ) + +//========================================================= +// icthyosaur - evin, satan fish monster +//========================================================= + +#include "extdll.h" +#include "util.h" +#include "cbase.h" +#include "monsters.h" +#include "schedule.h" +#include "flyingmonster.h" +#include "nodes.h" +#include "soundent.h" +#include "animation.h" +#include "effects.h" +#include "weapons.h" + +#define SEARCH_RETRY 16 + +#define ICHTHYOSAUR_SPEED 150 + +extern CGraph WorldGraph; + +#define EYE_MAD 0 +#define EYE_BASE 1 +#define EYE_CLOSED 2 +#define EYE_BACK 3 +#define EYE_LOOK 4 + + + +//========================================================= +// Monster's Anim Events Go Here +//========================================================= + +// UNDONE: Save/restore here +class CIchthyosaur : public CFlyingMonster +{ +public: + void Spawn( void ); + void Precache( void ); + void SetYawSpeed( void ); + int Classify( void ); + void HandleAnimEvent( MonsterEvent_t *pEvent ); + CUSTOM_SCHEDULES; + + int Save( CSave &save ); + int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + + Schedule_t *GetSchedule( void ); + Schedule_t *GetScheduleOfType ( int Type ); + + void Killed( entvars_t *pevAttacker, int iGib ); + void BecomeDead( void ); + + void EXPORT CombatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void EXPORT BiteTouch( CBaseEntity *pOther ); + + void StartTask( Task_t *pTask ); + void RunTask( Task_t *pTask ); + + BOOL CheckMeleeAttack1 ( float flDot, float flDist ); + BOOL CheckRangeAttack1 ( float flDot, float flDist ); + + float ChangeYaw( int speed ); + Activity GetStoppedActivity( void ); + + void Move( float flInterval ); + void MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ); + void MonsterThink( void ); + void Stop( void ); + void Swim( void ); + Vector DoProbe(const Vector &Probe); + + float VectorToPitch( const Vector &vec); + float FlPitchDiff( void ); + float ChangePitch( int speed ); + + Vector m_SaveVelocity; + float m_idealDist; + + float m_flBlink; + + float m_flEnemyTouched; + BOOL m_bOnAttack; + + float m_flMaxSpeed; + float m_flMinSpeed; + float m_flMaxDist; + + CBeam *m_pBeam; + + float m_flNextAlert; + + static const char *pIdleSounds[]; + static const char *pAlertSounds[]; + static const char *pAttackSounds[]; + static const char *pBiteSounds[]; + static const char *pDieSounds[]; + static const char *pPainSounds[]; + + void IdleSound( void ); + void AlertSound( void ); + void AttackSound( void ); + void BiteSound( void ); + void DeathSound( void ); + void PainSound( void ); +}; + +LINK_ENTITY_TO_CLASS( monster_ichthyosaur, CIchthyosaur ); + +TYPEDESCRIPTION CIchthyosaur::m_SaveData[] = +{ + DEFINE_FIELD( CIchthyosaur, m_SaveVelocity, FIELD_VECTOR ), + DEFINE_FIELD( CIchthyosaur, m_idealDist, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_flBlink, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_flEnemyTouched, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_bOnAttack, FIELD_BOOLEAN ), + DEFINE_FIELD( CIchthyosaur, m_flMaxSpeed, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_flMinSpeed, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_flMaxDist, FIELD_FLOAT ), + DEFINE_FIELD( CIchthyosaur, m_flNextAlert, FIELD_TIME ), +}; + +IMPLEMENT_SAVERESTORE( CIchthyosaur, CFlyingMonster ); + + +const char *CIchthyosaur::pIdleSounds[] = +{ + "ichy/ichy_idle1.wav", + "ichy/ichy_idle2.wav", + "ichy/ichy_idle3.wav", + "ichy/ichy_idle4.wav", +}; + +const char *CIchthyosaur::pAlertSounds[] = +{ + "ichy/ichy_alert2.wav", + "ichy/ichy_alert3.wav", +}; + +const char *CIchthyosaur::pAttackSounds[] = +{ + "ichy/ichy_attack1.wav", + "ichy/ichy_attack2.wav", +}; + +const char *CIchthyosaur::pBiteSounds[] = +{ + "ichy/ichy_bite1.wav", + "ichy/ichy_bite2.wav", +}; + +const char *CIchthyosaur::pPainSounds[] = +{ + "ichy/ichy_pain2.wav", + "ichy/ichy_pain3.wav", + "ichy/ichy_pain5.wav", +}; + +const char *CIchthyosaur::pDieSounds[] = +{ + "ichy/ichy_die2.wav", + "ichy/ichy_die4.wav", +}; + +#define EMIT_ICKY_SOUND( chan, array ) \ + EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, 0.6, 0, RANDOM_LONG(95,105) ); + + +void CIchthyosaur :: IdleSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_VOICE, pIdleSounds ); +} + +void CIchthyosaur :: AlertSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_VOICE, pAlertSounds ); +} + +void CIchthyosaur :: AttackSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_VOICE, pAttackSounds ); +} + +void CIchthyosaur :: BiteSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_WEAPON, pBiteSounds ); +} + +void CIchthyosaur :: DeathSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_VOICE, pDieSounds ); +} + +void CIchthyosaur :: PainSound( void ) +{ + EMIT_ICKY_SOUND( CHAN_VOICE, pPainSounds ); +} + +//========================================================= +// monster-specific tasks and states +//========================================================= +enum +{ + TASK_ICHTHYOSAUR_CIRCLE_ENEMY = LAST_COMMON_TASK + 1, + TASK_ICHTHYOSAUR_SWIM, + TASK_ICHTHYOSAUR_FLOAT, +}; + +//========================================================= +// AI Schedules Specific to this monster +//========================================================= + +static Task_t tlSwimAround[] = +{ + { TASK_SET_ACTIVITY, (float)ACT_WALK }, + { TASK_ICHTHYOSAUR_SWIM, 0.0 }, +}; + +static Schedule_t slSwimAround[] = +{ + { + tlSwimAround, + ARRAYSIZE(tlSwimAround), + bits_COND_LIGHT_DAMAGE | + bits_COND_HEAVY_DAMAGE | + bits_COND_SEE_ENEMY | + bits_COND_NEW_ENEMY | + bits_COND_HEAR_SOUND, + bits_SOUND_PLAYER | + bits_SOUND_COMBAT, + "SwimAround" + }, +}; + +static Task_t tlSwimAgitated[] = +{ + { TASK_STOP_MOVING, (float) 0 }, + { TASK_SET_ACTIVITY, (float)ACT_RUN }, + { TASK_WAIT, (float)2.0 }, +}; + +static Schedule_t slSwimAgitated[] = +{ + { + tlSwimAgitated, + ARRAYSIZE(tlSwimAgitated), + 0, + 0, + "SwimAgitated" + }, +}; + + +static Task_t tlCircleEnemy[] = +{ + { TASK_SET_ACTIVITY, (float)ACT_WALK }, + { TASK_ICHTHYOSAUR_CIRCLE_ENEMY, 0.0 }, +}; + +static Schedule_t slCircleEnemy[] = +{ + { + tlCircleEnemy, + ARRAYSIZE(tlCircleEnemy), + bits_COND_NEW_ENEMY | + bits_COND_LIGHT_DAMAGE | + bits_COND_HEAVY_DAMAGE | + bits_COND_CAN_MELEE_ATTACK1 | + bits_COND_CAN_RANGE_ATTACK1, + 0, + "CircleEnemy" + }, +}; + + +Task_t tlTwitchDie[] = +{ + { TASK_STOP_MOVING, 0 }, + { TASK_SOUND_DIE, (float)0 }, + { TASK_DIE, (float)0 }, + { TASK_ICHTHYOSAUR_FLOAT, (float)0 }, +}; + +Schedule_t slTwitchDie[] = +{ + { + tlTwitchDie, + ARRAYSIZE( tlTwitchDie ), + 0, + 0, + "Die" + }, +}; + + +DEFINE_CUSTOM_SCHEDULES(CIchthyosaur) +{ + slSwimAround, + slSwimAgitated, + slCircleEnemy, + slTwitchDie, +}; +IMPLEMENT_CUSTOM_SCHEDULES(CIchthyosaur, CFlyingMonster); + +//========================================================= +// Classify - indicates this monster's place in the +// relationship table. +//========================================================= +int CIchthyosaur :: Classify ( void ) +{ + return m_iClass?m_iClass:CLASS_ALIEN_MONSTER; +} + + +//========================================================= +// CheckMeleeAttack1 +//========================================================= +BOOL CIchthyosaur :: CheckMeleeAttack1 ( float flDot, float flDist ) +{ + if ( flDot >= 0.7 && m_flEnemyTouched > gpGlobals->time - 0.2 ) + { + return TRUE; + } + return FALSE; +} + +void CIchthyosaur::BiteTouch( CBaseEntity *pOther ) +{ + // bite if we hit who we want to eat + if ( pOther == m_hEnemy ) + { + m_flEnemyTouched = gpGlobals->time; + m_bOnAttack = TRUE; + } +} + +void CIchthyosaur::CombatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + if ( !ShouldToggle( useType, m_bOnAttack ) ) + return; + + if (m_bOnAttack) + { + m_bOnAttack = 0; + } + else + { + m_bOnAttack = 1; + } +} + +//========================================================= +// CheckRangeAttack1 - swim in for a chomp +// +//========================================================= +BOOL CIchthyosaur :: CheckRangeAttack1 ( float flDot, float flDist ) +{ + if ( flDot > -0.7 && (m_bOnAttack || ( flDist <= 192 && m_idealDist <= 192))) + { + return TRUE; + } + + return FALSE; +} + +//========================================================= +// SetYawSpeed - allows each sequence to have a different +// turn rate associated with it. +//========================================================= +void CIchthyosaur :: SetYawSpeed ( void ) +{ + pev->yaw_speed = 100; +} + + + +//========================================================= +// Killed - overrides CFlyingMonster. +// +void CIchthyosaur :: Killed( entvars_t *pevAttacker, int iGib ) +{ + CBaseMonster::Killed( pevAttacker, iGib ); + pev->velocity = Vector( 0, 0, 0 ); +} + +void CIchthyosaur::BecomeDead( void ) +{ + pev->takedamage = DAMAGE_YES;// don't let autoaim aim at corpses. + + // give the corpse half of the monster's original maximum health. + pev->health = pev->max_health / 2; + pev->max_health = 5; // max_health now becomes a counter for how many blood decals the corpse can place. +} + +#define ICHTHYOSAUR_AE_SHAKE_RIGHT 1 +#define ICHTHYOSAUR_AE_SHAKE_LEFT 2 + + +//========================================================= +// HandleAnimEvent - catches the monster-specific messages +// that occur when tagged animation frames are played. +//========================================================= +void CIchthyosaur :: HandleAnimEvent( MonsterEvent_t *pEvent ) +{ + int bDidAttack = FALSE; + switch( pEvent->event ) + { + case ICHTHYOSAUR_AE_SHAKE_RIGHT: + case ICHTHYOSAUR_AE_SHAKE_LEFT: + { + if (m_hEnemy != NULL && FVisible( m_hEnemy )) + { + CBaseEntity *pHurt = m_hEnemy; + + if (m_flEnemyTouched < gpGlobals->time - 0.2 && (m_hEnemy->BodyTarget( pev->origin ) - pev->origin).Length() > (32+16+32)) + break; + + Vector vecShootDir = ShootAtEnemy( pev->origin ); + UTIL_MakeAimVectors ( pev->angles ); + + if (DotProduct( vecShootDir, gpGlobals->v_forward ) > 0.707) + { + m_bOnAttack = TRUE; + pHurt->pev->punchangle.z = -18; + pHurt->pev->punchangle.x = 5; + pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_right * 300; + if (pHurt->IsPlayer()) + { + pHurt->pev->angles.x += RANDOM_FLOAT( -35, 35 ); + pHurt->pev->angles.y += RANDOM_FLOAT( -90, 90 ); + pHurt->pev->angles.z = 0; + pHurt->pev->fixangle = TRUE; + } + pHurt->TakeDamage( pev, pev, gSkillData.ichthyosaurDmgShake, DMG_SLASH ); + } + } + BiteSound(); + + bDidAttack = TRUE; + } + break; + default: + CFlyingMonster::HandleAnimEvent( pEvent ); + break; + } + + if (bDidAttack) + { + Vector vecSrc = pev->origin + gpGlobals->v_forward * 32; + UTIL_Bubbles( vecSrc - Vector( 8, 8, 8 ), vecSrc + Vector( 8, 8, 8 ), 16 ); + } +} + +//========================================================= +// Spawn +//========================================================= +void CIchthyosaur :: Spawn() +{ + Precache( ); + + if (pev->model) + SET_MODEL(ENT(pev), STRING(pev->model)); //LRC + else + SET_MODEL(ENT(pev), "models/icky.mdl"); + UTIL_SetSize( pev, Vector( -32, -32, -32 ), Vector( 32, 32, 32 ) ); + + pev->solid = SOLID_BBOX; + pev->movetype = MOVETYPE_FLY; + m_bloodColor = BLOOD_COLOR_GREEN; + if (pev->health == 0) + pev->health = gSkillData.ichthyosaurHealth; + pev->view_ofs = Vector ( 0, 0, 16 ); + m_flFieldOfView = VIEW_FIELD_WIDE; + m_MonsterState = MONSTERSTATE_NONE; + SetBits(pev->flags, FL_SWIM); + SetFlyingSpeed( ICHTHYOSAUR_SPEED ); + SetFlyingMomentum( 2.5 ); // Set momentum constant + + m_afCapability = bits_CAP_RANGE_ATTACK1 | bits_CAP_SWIM; + + MonsterInit(); + + SetTouch(&CIchthyosaur :: BiteTouch ); + SetUse(&CIchthyosaur :: CombatUse ); + + m_idealDist = 384; + m_flMinSpeed = 80; + m_flMaxSpeed = 300; + m_flMaxDist = 384; + + Vector Forward; + UTIL_MakeVectorsPrivate(pev->angles, Forward, 0, 0); + pev->velocity = m_flightSpeed * Forward.Normalize(); + m_SaveVelocity = pev->velocity; +} + +//========================================================= +// Precache - precaches all resources this monster needs +//========================================================= +void CIchthyosaur :: Precache() +{ + if (pev->model) + PRECACHE_MODEL((char*)STRING(pev->model)); //LRC + else + PRECACHE_MODEL("models/icky.mdl"); + + PRECACHE_SOUND_ARRAY( pIdleSounds ); + PRECACHE_SOUND_ARRAY( pAlertSounds ); + PRECACHE_SOUND_ARRAY( pAttackSounds ); + PRECACHE_SOUND_ARRAY( pBiteSounds ); + PRECACHE_SOUND_ARRAY( pDieSounds ); + PRECACHE_SOUND_ARRAY( pPainSounds ); +} + +//========================================================= +// GetSchedule +//========================================================= +Schedule_t* CIchthyosaur::GetSchedule() +{ + // ALERT( at_console, "GetSchedule( )\n" ); + switch(m_MonsterState) + { + case MONSTERSTATE_IDLE: + m_flightSpeed = 80; + return GetScheduleOfType( SCHED_IDLE_WALK ); + + case MONSTERSTATE_ALERT: + m_flightSpeed = 150; + return GetScheduleOfType( SCHED_IDLE_WALK ); + + case MONSTERSTATE_COMBAT: + m_flMaxSpeed = 400; + // eat them + if ( HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) ) + { + return GetScheduleOfType( SCHED_MELEE_ATTACK1 ); + } + // chase them down and eat them + if ( HasConditions( bits_COND_CAN_RANGE_ATTACK1 ) ) + { + return GetScheduleOfType( SCHED_CHASE_ENEMY ); + } + if ( HasConditions( bits_COND_HEAVY_DAMAGE ) ) + { + m_bOnAttack = TRUE; + } + if ( pev->health < pev->max_health - 20 ) + { + m_bOnAttack = TRUE; + } + + return GetScheduleOfType( SCHED_STANDOFF ); + } + + return CFlyingMonster :: GetSchedule(); +} + + +//========================================================= +//========================================================= +Schedule_t* CIchthyosaur :: GetScheduleOfType ( int Type ) +{ + // ALERT( at_console, "GetScheduleOfType( %d ) %d\n", Type, m_bOnAttack ); + switch ( Type ) + { + case SCHED_IDLE_WALK: + return slSwimAround; + case SCHED_STANDOFF: + return slCircleEnemy; + case SCHED_FAIL: + return slSwimAgitated; + case SCHED_DIE: + return slTwitchDie; + case SCHED_CHASE_ENEMY: + AttackSound( ); + } + + return CBaseMonster :: GetScheduleOfType( Type ); +} + + + +//========================================================= +// Start task - selects the correct activity and performs +// any necessary calculations to start the next task on the +// schedule. +//========================================================= +void CIchthyosaur::StartTask(Task_t *pTask) +{ + switch (pTask->iTask) + { + case TASK_ICHTHYOSAUR_CIRCLE_ENEMY: + break; + case TASK_ICHTHYOSAUR_SWIM: + break; + case TASK_SMALL_FLINCH: + if (m_idealDist > 128) + { + m_flMaxDist = 512; + m_idealDist = 512; + } + else + { + m_bOnAttack = TRUE; + } + CFlyingMonster::StartTask(pTask); + break; + + case TASK_ICHTHYOSAUR_FLOAT: + pev->skin = EYE_BASE; + SetSequenceByName( "bellyup" ); + break; + + default: + CFlyingMonster::StartTask(pTask); + break; + } +} + +void CIchthyosaur :: RunTask ( Task_t *pTask ) +{ + switch ( pTask->iTask ) + { + case TASK_ICHTHYOSAUR_CIRCLE_ENEMY: + if (m_hEnemy == NULL) + { + TaskComplete( ); + } + else if (FVisible( m_hEnemy )) + { + Vector vecFrom = m_hEnemy->EyePosition( ); + + Vector vecDelta = (pev->origin - vecFrom).Normalize( ); + Vector vecSwim = CrossProduct( vecDelta, Vector( 0, 0, 1 ) ).Normalize( ); + + if (DotProduct( vecSwim, m_SaveVelocity ) < 0) + vecSwim = vecSwim * -1.0; + + Vector vecPos = vecFrom + vecDelta * m_idealDist + vecSwim * 32; + + // ALERT( at_console, "vecPos %.0f %.0f %.0f\n", vecPos.x, vecPos.y, vecPos.z ); + + TraceResult tr; + + UTIL_TraceHull( vecFrom, vecPos, ignore_monsters, large_hull, m_hEnemy->edict(), &tr ); + + if (tr.flFraction > 0.5) + vecPos = tr.vecEndPos; + + m_SaveVelocity = m_SaveVelocity * 0.8 + 0.2 * (vecPos - pev->origin).Normalize() * m_flightSpeed; + + // ALERT( at_console, "m_SaveVelocity %.2f %.2f %.2f\n", m_SaveVelocity.x, m_SaveVelocity.y, m_SaveVelocity.z ); + + if (HasConditions( bits_COND_ENEMY_FACING_ME ) && m_hEnemy->FVisible( this )) + { + m_flNextAlert -= 0.1; + + if (m_idealDist < m_flMaxDist) + { + m_idealDist += 4; + } + if (m_flightSpeed > m_flMinSpeed) + { + m_flightSpeed -= 2; + } + else if (m_flightSpeed < m_flMinSpeed) + { + m_flightSpeed += 2; + } + if (m_flMinSpeed < m_flMaxSpeed) + { + m_flMinSpeed += 0.5; + } + } + else + { + m_flNextAlert += 0.1; + + if (m_idealDist > 128) + { + m_idealDist -= 4; + } + if (m_flightSpeed < m_flMaxSpeed) + { + m_flightSpeed += 4; + } + } + // ALERT( at_console, "%.0f\n", m_idealDist ); + } + else + { + m_flNextAlert = gpGlobals->time + 0.2; + } + + if (m_flNextAlert < gpGlobals->time) + { + // ALERT( at_console, "AlertSound()\n"); + AlertSound( ); + m_flNextAlert = gpGlobals->time + RANDOM_FLOAT( 3, 5 ); + } + + break; + case TASK_ICHTHYOSAUR_SWIM: + if (m_fSequenceFinished) + { + TaskComplete( ); + } + break; + case TASK_DIE: + if ( m_fSequenceFinished ) + { + pev->deadflag = DEAD_DEAD; + + TaskComplete( ); + } + break; + + case TASK_ICHTHYOSAUR_FLOAT: + pev->angles.x = UTIL_ApproachAngle( 0, pev->angles.x, 20 ); + pev->velocity = pev->velocity * 0.8; + if (pev->waterlevel > 1 && pev->watertype != CONTENTS_FOG && pev->velocity.z < 64) + { + pev->velocity.z += 8; + } + else + { + pev->velocity.z -= 8; + } + // ALERT( at_console, "%f\n", pev->velocity.z ); + break; + + default: + CFlyingMonster :: RunTask ( pTask ); + break; + } +} + + + +float CIchthyosaur::VectorToPitch( const Vector &vec ) +{ + float pitch; + if (vec.z == 0 && vec.x == 0) + pitch = 0; + else + { + pitch = (int) (atan2(vec.z, sqrt(vec.x*vec.x+vec.y*vec.y)) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + return pitch; +} + +//========================================================= +void CIchthyosaur::Move(float flInterval) +{ + CFlyingMonster::Move( flInterval ); +} + +float CIchthyosaur::FlPitchDiff( void ) +{ + float flPitchDiff; + float flCurrentPitch; + + flCurrentPitch = UTIL_AngleMod( pev->angles.z ); + + if ( flCurrentPitch == pev->idealpitch ) + { + return 0; + } + + flPitchDiff = pev->idealpitch - flCurrentPitch; + + if ( pev->idealpitch > flCurrentPitch ) + { + if (flPitchDiff >= 180) + flPitchDiff = flPitchDiff - 360; + } + else + { + if (flPitchDiff <= -180) + flPitchDiff = flPitchDiff + 360; + } + return flPitchDiff; +} + +float CIchthyosaur :: ChangePitch( int speed ) +{ + if ( pev->movetype == MOVETYPE_FLY ) + { + float diff = FlPitchDiff(); + float target = 0; + if ( m_IdealActivity != GetStoppedActivity() ) + { + if (diff < -20) + target = 45; + else if (diff > 20) + target = -45; + } + pev->angles.x = UTIL_Approach(target, pev->angles.x, 220.0 * 0.1 ); + } + return 0; +} + +float CIchthyosaur::ChangeYaw( int speed ) +{ + if ( pev->movetype == MOVETYPE_FLY ) + { + float diff = FlYawDiff(); + float target = 0; + + if ( m_IdealActivity != GetStoppedActivity() ) + { + if ( diff < -20 ) + target = 20; + else if ( diff > 20 ) + target = -20; + } + pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * 0.1 ); + } + return CFlyingMonster::ChangeYaw( speed ); +} + + +Activity CIchthyosaur:: GetStoppedActivity( void ) +{ + if ( pev->movetype != MOVETYPE_FLY ) // UNDONE: Ground idle here, IDLE may be something else + return ACT_IDLE; + return ACT_WALK; +} + +void CIchthyosaur::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ) +{ + m_SaveVelocity = vecDir * m_flightSpeed; +} + + +void CIchthyosaur::MonsterThink ( void ) +{ + CFlyingMonster::MonsterThink( ); + + if (pev->deadflag == DEAD_NO) + { + if (m_MonsterState != MONSTERSTATE_SCRIPT) + { + Swim( ); + + // blink the eye + if (m_flBlink < gpGlobals->time) + { + pev->skin = EYE_CLOSED; + if (m_flBlink + 0.2 < gpGlobals->time) + { + m_flBlink = gpGlobals->time + RANDOM_FLOAT( 3, 4 ); + if (m_bOnAttack) + pev->skin = EYE_MAD; + else + pev->skin = EYE_BASE; + } + } + } + } +} + +void CIchthyosaur :: Stop( void ) +{ + if (!m_bOnAttack) + m_flightSpeed = 80.0; +} + +void CIchthyosaur::Swim( ) +{ + int retValue = 0; + + Vector start = pev->origin; + + Vector Angles; + Vector Forward, Right, Up; + + if (FBitSet( pev->flags, FL_ONGROUND)) + { + pev->angles.x = 0; + pev->angles.y += RANDOM_FLOAT( -45, 45 ); + ClearBits( pev->flags, FL_ONGROUND ); + + Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); + UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); + + pev->velocity = Forward * 200 + Up * 200; + + return; + } + + if (m_bOnAttack && m_flightSpeed < m_flMaxSpeed) + { + m_flightSpeed += 40; + } + if (m_flightSpeed < 180) + { + if (m_IdealActivity == ACT_RUN) + SetActivity( ACT_WALK ); + if (m_IdealActivity == ACT_WALK) + pev->framerate = m_flightSpeed / 150.0; + // ALERT( at_console, "walk %.2f\n", pev->framerate ); + } + else + { + if (m_IdealActivity == ACT_WALK) + SetActivity( ACT_RUN ); + if (m_IdealActivity == ACT_RUN) + pev->framerate = m_flightSpeed / 150.0; + // ALERT( at_console, "run %.2f\n", pev->framerate ); + } + +/* + if (!m_pBeam) + { + m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 80 ); + m_pBeam->PointEntInit( pev->origin + m_SaveVelocity, entindex( ) ); + m_pBeam->SetEndAttachment( 1 ); + m_pBeam->SetColor( 255, 180, 96 ); + m_pBeam->SetBrightness( 192 ); + } +*/ +#define PROBE_LENGTH 150 + Angles = UTIL_VecToAngles( m_SaveVelocity ); + Angles.x = -Angles.x; + UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); + + Vector f, u, l, r, d; + f = DoProbe(start + PROBE_LENGTH * Forward); + r = DoProbe(start + PROBE_LENGTH/3 * Forward+Right); + l = DoProbe(start + PROBE_LENGTH/3 * Forward-Right); + u = DoProbe(start + PROBE_LENGTH/3 * Forward+Up); + d = DoProbe(start + PROBE_LENGTH/3 * Forward-Up); + + Vector SteeringVector = f+r+l+u+d; + m_SaveVelocity = (m_SaveVelocity + SteeringVector/2).Normalize(); + + Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); + UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); + // ALERT( at_console, "%f : %f\n", Angles.x, Forward.z ); + + float flDot = DotProduct( Forward, m_SaveVelocity ); + if (flDot > 0.5) + pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed; + else if (flDot > 0) + pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed * (flDot + 0.5); + else + pev->velocity = m_SaveVelocity = m_SaveVelocity * 80; + + // ALERT( at_console, "%.0f %.0f\n", m_flightSpeed, pev->velocity.Length() ); + + + // ALERT( at_console, "Steer %f %f %f\n", SteeringVector.x, SteeringVector.y, SteeringVector.z ); + +/* + m_pBeam->SetStartPos( pev->origin + pev->velocity ); + m_pBeam->RelinkBeam( ); +*/ + + // ALERT( at_console, "speed %f\n", m_flightSpeed ); + + Angles = UTIL_VecToAngles( m_SaveVelocity ); + + // Smooth Pitch + // + if (Angles.x > 180) + Angles.x = Angles.x - 360; + pev->angles.x = UTIL_Approach(Angles.x, pev->angles.x, 50 * 0.1 ); + if (pev->angles.x < -80) pev->angles.x = -80; + if (pev->angles.x > 80) pev->angles.x = 80; + + // Smooth Yaw and generate Roll + // + float turn = 360; + // ALERT( at_console, "Y %.0f %.0f\n", Angles.y, pev->angles.y ); + + if (fabs(Angles.y - pev->angles.y) < fabs(turn)) + { + turn = Angles.y - pev->angles.y; + } + if (fabs(Angles.y - pev->angles.y + 360) < fabs(turn)) + { + turn = Angles.y - pev->angles.y + 360; + } + if (fabs(Angles.y - pev->angles.y - 360) < fabs(turn)) + { + turn = Angles.y - pev->angles.y - 360; + } + + float speed = m_flightSpeed * 0.1; + + // ALERT( at_console, "speed %.0f %f\n", turn, speed ); + if (fabs(turn) > speed) + { + if (turn < 0.0) + { + turn = -speed; + } + else + { + turn = speed; + } + } + pev->angles.y += turn; + pev->angles.z -= turn; + pev->angles.y = fmod((pev->angles.y + 360.0), 360.0); + + static float yaw_adj; + + yaw_adj = yaw_adj * 0.8 + turn; + + // ALERT( at_console, "yaw %f : %f\n", turn, yaw_adj ); + + SetBoneController( 0, -yaw_adj / 4.0 ); + + // Roll Smoothing + // + turn = 360; + if (fabs(Angles.z - pev->angles.z) < fabs(turn)) + { + turn = Angles.z - pev->angles.z; + } + if (fabs(Angles.z - pev->angles.z + 360) < fabs(turn)) + { + turn = Angles.z - pev->angles.z + 360; + } + if (fabs(Angles.z - pev->angles.z - 360) < fabs(turn)) + { + turn = Angles.z - pev->angles.z - 360; + } + speed = m_flightSpeed/2 * 0.1; + if (fabs(turn) < speed) + { + pev->angles.z += turn; + } + else + { + if (turn < 0.0) + { + pev->angles.z -= speed; + } + else + { + pev->angles.z += speed; + } + } + if (pev->angles.z < -20) pev->angles.z = -20; + if (pev->angles.z > 20) pev->angles.z = 20; + + UTIL_MakeVectorsPrivate( Vector( -Angles.x, Angles.y, Angles.z ), Forward, Right, Up); + + // UTIL_MoveToOrigin ( ENT(pev), pev->origin + Forward * speed, speed, MOVE_STRAFE ); +} + + +Vector CIchthyosaur::DoProbe(const Vector &Probe) +{ + Vector WallNormal = Vector(0,0,-1); // WATER normal is Straight Down for fish. + float frac; + BOOL bBumpedSomething = ProbeZ(pev->origin, Probe, &frac); + + TraceResult tr; + TRACE_MONSTER_HULL(edict(), pev->origin, Probe, dont_ignore_monsters, edict(), &tr); + if ( tr.fAllSolid || tr.flFraction < 0.99 ) + { + if (tr.flFraction < 0.0) tr.flFraction = 0.0; + if (tr.flFraction > 1.0) tr.flFraction = 1.0; + if (tr.flFraction < frac) + { + frac = tr.flFraction; + bBumpedSomething = TRUE; + WallNormal = tr.vecPlaneNormal; + } + } + + if (bBumpedSomething && (m_hEnemy == NULL || tr.pHit != m_hEnemy->edict())) + { + Vector ProbeDir = Probe - pev->origin; + + Vector NormalToProbeAndWallNormal = CrossProduct(ProbeDir, WallNormal); + Vector SteeringVector = CrossProduct( NormalToProbeAndWallNormal, ProbeDir); + + float SteeringForce = m_flightSpeed * (1-frac) * (DotProduct(WallNormal.Normalize(), m_SaveVelocity.Normalize())); + if (SteeringForce < 0.0) + { + SteeringForce = -SteeringForce; + } + SteeringVector = SteeringForce * SteeringVector.Normalize(); + + return SteeringVector; + } + return Vector(0, 0, 0); +} + +#endif diff --git a/spirit/locus.cpp b/spirit/locus.cpp index 70340939..7cc881c2 100644 --- a/spirit/locus.cpp +++ b/spirit/locus.cpp @@ -507,7 +507,7 @@ Vector CCalcSubVelocity::CalcVelocity( CBaseEntity *pLocus ) case 1: //angles return ConvertAngles( pLocus, pLocus->pev->angles ); case 2: //v_angle - return ConvertAngles( pLocus, pLocus->pev->viewangles ); + return ConvertAngles( pLocus, pLocus->pev->v_angle ); case 5: // this could cause problems. // is there a good way to check whether it's really a CBaseAnimating? diff --git a/spirit/mp5.cpp b/spirit/mp5.cpp index cf790bfa..67e5933b 100644 --- a/spirit/mp5.cpp +++ b/spirit/mp5.cpp @@ -166,7 +166,7 @@ void CMP5::SecondaryAttack( void ) // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); // we don't add in player velocity anymore. CGrenade::ShootContact( m_pPlayer->pev, m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_forward * 16, gpGlobals->v_forward * 800 ); diff --git a/spirit/multiplay_gamerules.cpp b/spirit/multiplay_gamerules.cpp index 6e01f418..12c3c87e 100644 --- a/spirit/multiplay_gamerules.cpp +++ b/spirit/multiplay_gamerules.cpp @@ -368,7 +368,7 @@ BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerI //========================================================= //========================================================= -BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } @@ -394,12 +394,17 @@ void CHalfLifeMultiplay :: InitHUD( CBasePlayer *pl ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" entered the game\n", STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pl->edict() ), "model" ) ); } else { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" entered the game\n", - STRING( pl->pev->netname )); + STRING( pl->pev->netname ), + GETPLAYERUSERID( pl->edict() ), + GETPLAYERAUTHID( pl->edict() ), + GETPLAYERUSERID( pl->edict() ) ); } UpdateGameMode( pl ); @@ -453,17 +458,23 @@ void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) { FireTargets( "game_playerleave", pPlayer, pPlayer, USE_TOGGLE, 0 ); + // team match? if ( g_teamplay ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected\n", STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ) ); } else { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" disconnected\n", - STRING( pPlayer->pev->netname )); + STRING( pPlayer->pev->netname ), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + GETPLAYERUSERID( pPlayer->edict() ) ); } pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items @@ -708,6 +719,8 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -715,6 +728,9 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\"\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } @@ -725,8 +741,12 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n", STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( ENT(pKiller) ), "model" ), STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -734,7 +754,13 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\"\n", STRING( pKiller->netname ), + GETPLAYERUSERID( ENT(pKiller) ), + GETPLAYERAUTHID( ENT(pKiller) ), + GETPLAYERUSERID( ENT(pKiller) ), STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } @@ -747,6 +773,8 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (world)\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pVictim->edict() ), "model" ), killer_weapon_name ); } @@ -754,6 +782,9 @@ void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, { UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\" (world)\n", STRING( pVictim->pev->netname ), + GETPLAYERUSERID( pVictim->edict() ), + GETPLAYERAUTHID( pVictim->edict() ), + GETPLAYERUSERID( pVictim->edict() ), killer_weapon_name ); } } @@ -1174,7 +1205,7 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) char szMap[ 32 ]; int length; char *pToken; - char *aFileList = (char *)LOAD_FILE( filename, &length ); + char *aFileList = (char *)LOAD_FILE_FOR_ME( filename, &length ); const char *pFileList = aFileList; int hasbuffer; mapcycle_item_s *item, *newlist = NULL, *next; @@ -1509,7 +1540,7 @@ void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) // read from the MOTD.txt file int length, char_count = 0; char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE( (char *)CVAR_GET_STRING( "motdfile" ), &length ); + char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( (char *)CVAR_GET_STRING( "motdfile" ), &length ); // send the server name MESSAGE_BEGIN( MSG_ONE, gmsgServerName, NULL, client ); diff --git a/spirit/nodes.cpp b/spirit/nodes.cpp index 3f755e93..3e700530 100644 --- a/spirit/nodes.cpp +++ b/spirit/nodes.cpp @@ -43,7 +43,10 @@ CGraph WorldGraph; LINK_ENTITY_TO_CLASS( info_node, CNodeEnt ); LINK_ENTITY_TO_CLASS( info_node_air, CNodeEnt ); - +#ifdef __linux__ +#include +#define CreateDirectory(p, n) mkdir(p, 0777) +#endif //========================================================= // CGraph - InitGraph - prepares the graph for use. Frees any // memory currently in use by the world graph, NULLs @@ -90,7 +93,7 @@ void CGraph :: InitGraph( void) if (m_pHashLinks) { - free ( m_pHashLinks ); + free(m_pHashLinks); m_pHashLinks = NULL; } @@ -1133,7 +1136,7 @@ void CGraph :: ShowNodeConnections ( int iNode ) // If there's a problem with this process, the index // of the offending node will be written to piBadNode //========================================================= -int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) +int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ) { int i,j,z; edict_t *pTraceEnt; @@ -1161,9 +1164,9 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) } else { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "LinkVisibleNodes - Initial Connections\n" ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "LinkVisibleNodes - Initial Connections\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } cTotalLinks = 0;// start with no connections @@ -1179,7 +1182,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "Node #%4d:\n\n", i ); + fprintf ( file, "Node #%4d:\n\n", i ); } for ( z = 0 ; z < MAX_NODE_INITIAL_LINKS ; z++ ) @@ -1267,14 +1270,14 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "%4d", j ); + fprintf ( file, "%4d", j ); if ( !FNullEnt( pLinkPool[ cTotalLinks ].m_pLinkEnt ) ) {// record info about the ent in the way, if any. - ENGINE_FPRINTF ( file, " Entity on connection: %s, name: %s Model: %s", STRING( VARS( pTraceEnt )->classname ), STRING ( VARS( pTraceEnt )->targetname ), STRING ( VARS(tr.pHit)->model ) ); + fprintf ( file, " Entity on connection: %s, name: %s Model: %s", STRING( VARS( pTraceEnt )->classname ), STRING ( VARS( pTraceEnt )->targetname ), STRING ( VARS(tr.pHit)->model ) ); } - ENGINE_FPRINTF ( file, "\n", j ); + fprintf ( file, "\n", j ); } pLinkPool [ cTotalLinks ].m_iDestNode = j; @@ -1286,7 +1289,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( cLinksThisNode == MAX_NODE_INITIAL_LINKS ) { ALERT ( at_aiconsole, "**LinkVisibleNodes:\nNode %d has NodeLinks > MAX_NODE_INITIAL_LINKS", i ); - ENGINE_FPRINTF ( file, "** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i ); + fprintf ( file, "** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i ); *piBadNode = i; return FALSE; } @@ -1299,7 +1302,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( cLinksThisNode == 0 ) { - ENGINE_FPRINTF ( file, "**NO INITIAL LINKS**\n" ); + fprintf ( file, "**NO INITIAL LINKS**\n" ); } // record the connection info in the link pool @@ -1316,12 +1319,12 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } } - ENGINE_FPRINTF ( file, "\n%4d Total Initial Connections - %4d Maximum connections for a single node.\n", cTotalLinks, cMaxInitialLinks ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n\n\n" ); + fprintf ( file, "\n%4d Total Initial Connections - %4d Maximum connections for a single node.\n", cTotalLinks, cMaxInitialLinks ); + fprintf ( file, "----------------------------------------------------------------------------\n\n\n" ); return cTotalLinks; } @@ -1332,7 +1335,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ) // want status reports written to disk ). RETURNS the number // of connections that were rejected //========================================================= -int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) +int CGraph :: RejectInlineLinks ( CLink *pLinkPool, FILE *file ) { int i,j,k; @@ -1350,9 +1353,9 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "InLine Rejection:\n" ); - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "InLine Rejection:\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n" ); } cRejectedLinks = 0; @@ -1363,7 +1366,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "Node %3d:\n", i ); + fprintf ( file, "Node %3d:\n", i ); } for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) @@ -1398,7 +1401,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) { if ( file ) { - ENGINE_FPRINTF ( file, "REJECTED NODE %3d through Node %3d, Dot = %8f\n", pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode, pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode, DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) ); + fprintf ( file, "REJECTED NODE %3d through Node %3d, Dot = %8f\n", pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode, pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode, DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) ); } pLinkPool[ pSrcNode->m_iFirstLink + j ] = pLinkPool[ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; @@ -1415,7 +1418,7 @@ int CGraph :: RejectInlineLinks ( CLink *pLinkPool, void *file ) if ( file ) { - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n\n" ); + fprintf ( file, "----------------------------------------------------------------------------\n\n" ); } } @@ -1594,7 +1597,7 @@ void CTestHull::CallBuildNodeGraph( void ) void CTestHull :: BuildNodeGraph( void ) { TraceResult tr; - void *file; + FILE *file; char szNrpFilename [MAX_PATH];// text node report filename @@ -1645,14 +1648,17 @@ void CTestHull :: BuildNodeGraph( void ) // make sure directories have been made - szNrpFilename[0] = '\0'; - strcat( szNrpFilename, "maps" ); + GET_GAME_DIR( szNrpFilename ); + strcat( szNrpFilename, "/maps" ); + CreateDirectory( szNrpFilename, NULL ); strcat( szNrpFilename, "/graphs" ); + CreateDirectory( szNrpFilename, NULL ); + strcat( szNrpFilename, "/" ); strcat( szNrpFilename, STRING( gpGlobals->mapname ) ); strcat( szNrpFilename, ".nrp" ); - file = g_engfuncs.pfnFOpen ( szNrpFilename, "w+" ); + file = fopen ( szNrpFilename, "w+" ); if ( !file ) {// file error @@ -1666,8 +1672,8 @@ void CTestHull :: BuildNodeGraph( void ) return; } - ENGINE_FPRINTF ( file, "Node Graph Report for map: %s.bsp\n", STRING(gpGlobals->mapname) ); - ENGINE_FPRINTF ( file, "%d Total Nodes\n\n", WorldGraph.m_cNodes ); + fprintf( file, "Node Graph Report for map: %s.bsp\n", STRING(gpGlobals->mapname) ); + fprintf ( file, "%d Total Nodes\n\n", WorldGraph.m_cNodes ); for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) {// print all node numbers and their locations to the file. @@ -1675,14 +1681,14 @@ void CTestHull :: BuildNodeGraph( void ) WorldGraph.m_pNodes[ i ].m_iFirstLink = 0; memset(WorldGraph.m_pNodes[ i ].m_pNextBestNode, 0, sizeof(WorldGraph.m_pNodes[ i ].m_pNextBestNode)); - ENGINE_FPRINTF ( file, "Node# %4d\n", i ); - ENGINE_FPRINTF ( file, "Location %4d,%4d,%4d\n",(int)WorldGraph.m_pNodes[ i ].m_vecOrigin.x, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.y, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.z ); - ENGINE_FPRINTF ( file, "HintType: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintType ); - ENGINE_FPRINTF ( file, "HintActivity: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintActivity ); - ENGINE_FPRINTF ( file, "HintYaw: %4f\n", WorldGraph.m_pNodes[ i ].m_flHintYaw ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n" ); + fprintf ( file, "Node# %4d\n", i ); + fprintf ( file, "Location %4d,%4d,%4d\n",(int)WorldGraph.m_pNodes[ i ].m_vecOrigin.x, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.y, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.z ); + fprintf ( file, "HintType: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintType ); + fprintf ( file, "HintActivity: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintActivity ); + fprintf ( file, "HintYaw: %4f\n", WorldGraph.m_pNodes[ i ].m_flHintYaw ); + fprintf ( file, "-------------------------------------------------------------------------------\n" ); } - ENGINE_FPRINTF ( file, "\n\n" ); + fprintf ( file, "\n\n" ); // Automatically recognize WATER nodes and drop the LAND nodes to the floor. @@ -1752,7 +1758,7 @@ void CTestHull :: BuildNodeGraph( void ) if ( file ) {// close the file - g_engfuncs.pfnFClose ( file ); + fclose ( file ); } return; @@ -1760,15 +1766,15 @@ void CTestHull :: BuildNodeGraph( void ) // send the walkhull to all of this node's connections now. We'll do this here since // so much of it relies on being able to control the test hull. - ENGINE_FPRINTF ( file, "----------------------------------------------------------------------------\n" ); - ENGINE_FPRINTF ( file, "Walk Rejection:\n"); + fprintf ( file, "----------------------------------------------------------------------------\n" ); + fprintf ( file, "Walk Rejection:\n"); for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) { pSrcNode = &WorldGraph.m_pNodes[ i ]; - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Node %4d:\n\n", i ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "Node %4d:\n\n", i ); for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) { @@ -1821,7 +1827,7 @@ void CTestHull :: BuildNodeGraph( void ) if ( file ) {// close the file - g_engfuncs.pfnFClose ( file ); + fclose ( file ); } return; } @@ -1880,17 +1886,17 @@ void CTestHull :: BuildNodeGraph( void ) switch ( hull ) { case NODE_SMALL_HULL: // if this hull can't fit, nothing can, so drop the connection - ENGINE_FPRINTF ( file, "NODE_SMALL_HULL step %f\n", step ); + fprintf ( file, "NODE_SMALL_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_SMALL_HULL | bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); fSkipRemainingHulls = TRUE;// don't bother checking larger hulls break; case NODE_HUMAN_HULL: - ENGINE_FPRINTF ( file, "NODE_HUMAN_HULL step %f\n", step ); + fprintf ( file, "NODE_HUMAN_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); fSkipRemainingHulls = TRUE;// don't bother checking larger hulls break; case NODE_LARGE_HULL: - ENGINE_FPRINTF ( file, "NODE_LARGE_HULL step %f\n", step ); + fprintf ( file, "NODE_LARGE_HULL step %f\n", step ); pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~bits_LINK_LARGE_HULL; break; } @@ -1911,9 +1917,9 @@ void CTestHull :: BuildNodeGraph( void ) if (pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo == 0) { - ENGINE_FPRINTF ( file, "Rejected Node %3d - Unreachable by ", pTempPool [ pSrcNode->m_iFirstLink + j ].m_iDestNode ); + fprintf ( file, "Rejected Node %3d - Unreachable by ", pTempPool [ pSrcNode->m_iFirstLink + j ].m_iDestNode ); pTempPool[ pSrcNode->m_iFirstLink + j ] = pTempPool [ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; - ENGINE_FPRINTF ( file, "Any Hull\n" ); + fprintf ( file, "Any Hull\n" ); pSrcNode->m_cNumLinks--; cPoolLinks--;// we just removed a link, so decrement the total number of links in the pool. @@ -1922,7 +1928,7 @@ void CTestHull :: BuildNodeGraph( void ) } } - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n\n\n"); + fprintf ( file, "-------------------------------------------------------------------------------\n\n\n"); cPoolLinks -= WorldGraph.RejectInlineLinks ( pTempPool, file ); @@ -1938,7 +1944,7 @@ void CTestHull :: BuildNodeGraph( void ) } if ( file ) {// close the file - g_engfuncs.pfnFClose ( file ); + fclose ( file ); } return; @@ -1972,8 +1978,8 @@ void CTestHull :: BuildNodeGraph( void ) fPairsValid = TRUE; // assume that the connection pairs are all valid to start - ENGINE_FPRINTF ( file, "\n\n-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Link Pairings:\n"); + fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); + fprintf ( file, "Link Pairings:\n"); // link integrity check. The idea here is that if Node A links to Node B, node B should // link to node A. If not, we have a situation that prevents us from using a basic @@ -1987,7 +1993,7 @@ void CTestHull :: BuildNodeGraph( void ) if (iLink < 0) { fPairsValid = FALSE;// unmatched link pair. - ENGINE_FPRINTF ( file, "WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); + fprintf ( file, "WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); } } } @@ -1996,15 +2002,15 @@ void CTestHull :: BuildNodeGraph( void ) // (in the find nearest line function) if ( fPairsValid ) { - ENGINE_FPRINTF ( file, "\nAll Connections are Paired!\n"); + fprintf ( file, "\nAll Connections are Paired!\n"); } - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "\n\n-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); - ENGINE_FPRINTF ( file, "Connection Pool: %d bytes\n", sizeof ( CLink ) * cPoolLinks ); - ENGINE_FPRINTF ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); + fprintf ( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); + fprintf ( file, "Connection Pool: %d bytes\n", sizeof ( CLink ) * cPoolLinks ); + fprintf ( file, "-------------------------------------------------------------------------------\n"); ALERT ( at_aiconsole, "%d Nodes, %d Connections\n", WorldGraph.m_cNodes, cPoolLinks ); @@ -2032,7 +2038,7 @@ void CTestHull :: BuildNodeGraph( void ) if ( file ) { - g_engfuncs.pfnFClose ( file ); + fclose ( file ); } // We now have some graphing capabilities. @@ -2117,7 +2123,7 @@ void CStack :: Push( int value ) { if ( m_level >= MAX_STACK_NODES ) { - ALERT ( at_error, "CStack:Push: error!\n"); + printf("Error!\n"); return; } m_stack[m_level] = value; @@ -2175,7 +2181,7 @@ void CQueue :: Insert ( int iValue, float fPriority ) if ( Full() ) { - ALERT ( at_error, "CStack:Insert: queue is full!\n" ); + printf ( "Queue is full!\n" ); return; } @@ -2222,7 +2228,7 @@ void CQueuePriority :: Insert( int iValue, float fPriority ) if ( Full() ) { - ALERT ( at_error, "CStack:Insert: queue is full!\n" ); + printf ( "Queue is full!\n" ); return; } @@ -2313,11 +2319,18 @@ int CGraph :: FLoadGraph ( char *szMapName ) byte *pMemFile; // make sure the directories have been made + char szDirName[MAX_PATH]; + GET_GAME_DIR( szDirName ); + strcat( szDirName, "/maps" ); + CreateDirectory( szDirName, NULL ); + strcat( szDirName, "/graphs" ); + CreateDirectory( szDirName, NULL ); + strcpy ( szFilename, "maps/graphs/" ); strcat ( szFilename, szMapName ); strcat( szFilename, ".nod" ); - pMemFile = aMemFile = LOAD_FILE( szFilename, &length ); + pMemFile = aMemFile = LOAD_FILE_FOR_ME(szFilename, &length); if ( !aMemFile ) { @@ -2474,9 +2487,9 @@ NoMemory: int CGraph :: FSaveGraph ( char *szMapName ) { - int iVersion = GRAPH_VERSION; + int iVersion = GRAPH_VERSION; char szFilename[MAX_PATH]; - void *file; + FILE *file; if ( !m_fGraphPresent || !m_fGraphPointersSet ) {// protect us in the case that the node graph isn't available or built @@ -2484,8 +2497,18 @@ int CGraph :: FSaveGraph ( char *szMapName ) return FALSE; } - sprintf( szFilename, "maps/graphs/%s.nod", szMapName ); - file = g_engfuncs.pfnFOpen( szFilename, "wb" ); + // make sure directories have been made + GET_GAME_DIR( szFilename ); + strcat( szFilename, "/maps" ); + CreateDirectory( szFilename, NULL ); + strcat( szFilename, "/graphs" ); + CreateDirectory( szFilename, NULL ); + + strcat( szFilename, "/" ); + strcat( szFilename, szMapName ); + strcat( szFilename, ".nod" ); + + file = fopen ( szFilename, "wb" ); ALERT ( at_aiconsole, "Created: %s\n", szFilename ); @@ -2496,31 +2519,32 @@ int CGraph :: FSaveGraph ( char *szMapName ) } else { - // write the version - g_engfuncs.pfnFWrite( file, &iVersion, sizeof( int )); + // write the version + fwrite ( &iVersion, sizeof ( int ), 1, file ); - // write the CGraph class - g_engfuncs.pfnFWrite( file, this, sizeof( CGraph )); + // write the CGraph class + fwrite ( this, sizeof ( CGraph ), 1, file ); - // write the nodes - g_engfuncs.pfnFWrite( file, m_pNodes, sizeof( CNode ) * m_cNodes ); + // write the nodes + fwrite ( m_pNodes, sizeof ( CNode ), m_cNodes, file ); - // write the links - g_engfuncs.pfnFWrite( file, m_pLinkPool, sizeof( CLink ) * m_cLinks ); + // write the links + fwrite ( m_pLinkPool, sizeof ( CLink ), m_cLinks, file ); - g_engfuncs.pfnFWrite( file, m_di, sizeof( DIST_INFO ) * m_cNodes ); + fwrite ( m_di, sizeof(DIST_INFO), m_cNodes, file ); - // write the route info. - if( m_pRouteInfo && m_nRouteInfo ) + // Write the route info. + // + if ( m_pRouteInfo && m_nRouteInfo ) { - g_engfuncs.pfnFWrite( file, m_pRouteInfo, sizeof( char ) * m_nRouteInfo ); + fwrite ( m_pRouteInfo, sizeof( char ), m_nRouteInfo, file ); } - if( m_pHashLinks && m_nHashLinks ) + if (m_pHashLinks && m_nHashLinks) { - g_engfuncs.pfnFWrite( file, m_pHashLinks, sizeof( short ) * m_nHashLinks ); + fwrite(m_pHashLinks, sizeof(short), m_nHashLinks, file); } - g_engfuncs.pfnFClose( file ); + fclose ( file ); return TRUE; } } @@ -3277,7 +3301,7 @@ void CGraph :: ComputeStaticRoutingTables( void ) { char *Tmp = (char *)calloc(sizeof(char), (m_nRouteInfo + nRoute)); memcpy(Tmp, m_pRouteInfo, m_nRouteInfo); - free ( m_pRouteInfo ); + free(m_pRouteInfo); m_pRouteInfo = Tmp; memcpy(m_pRouteInfo + m_nRouteInfo, pRoute, nRoute); m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = m_nRouteInfo; diff --git a/spirit/nodes.h b/spirit/nodes.h index 9456fc36..6b6739d6 100644 --- a/spirit/nodes.h +++ b/spirit/nodes.h @@ -159,8 +159,8 @@ public: int m_iLastCoverSearch; // functions to create the graph - int LinkVisibleNodes ( CLink *pLinkPool, void *file, int *piBadNode ); - int RejectInlineLinks ( CLink *pLinkPool, void *file ); + int LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ); + int RejectInlineLinks ( CLink *pLinkPool, FILE *file ); int FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask); int FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ); int FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ); diff --git a/spirit/player.cpp b/spirit/player.cpp index 5010a9ef..522629dd 100644 --- a/spirit/player.cpp +++ b/spirit/player.cpp @@ -94,8 +94,6 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = DEFINE_FIELD( CBasePlayer, m_flDuckTime, FIELD_TIME ), DEFINE_FIELD( CBasePlayer, m_flWallJumpTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_fAirFinished, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_fPainFinished, FIELD_TIME ), DEFINE_FIELD( CBasePlayer, m_flSuitUpdate, FIELD_TIME ), DEFINE_ARRAY( CBasePlayer, m_rgSuitPlayList, FIELD_INTEGER, CSUITPLAYLIST ), DEFINE_FIELD( CBasePlayer, m_iSuitPlayNext, FIELD_INTEGER ), @@ -463,7 +461,7 @@ int CBasePlayer :: TakeArmor( float flArmor ) Vector CBasePlayer :: GetGunPosition( ) { -// UTIL_MakeVectors(pev->viewangles); +// UTIL_MakeVectors(pev->v_angle); // m_HackedGunPos = pev->view_ofs; Vector origin; @@ -1359,12 +1357,12 @@ void CBasePlayer::WaterMove() // not underwater // play 'up for air' sound - if (m_fAirFinished < gpGlobals->time) + if (pev->air_finished < gpGlobals->time) EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM); - else if (m_fAirFinished < gpGlobals->time + 9) + else if (pev->air_finished < gpGlobals->time + 9) EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM); - m_fAirFinished = gpGlobals->time + AIRTIME; + pev->air_finished = gpGlobals->time + AIRTIME; pev->dmg = 2; // if we took drowning damage, give it back slowly @@ -1389,16 +1387,16 @@ void CBasePlayer::WaterMove() m_bitsDamageType &= ~DMG_DROWNRECOVER; m_rgbTimeBasedDamage[itbd_DrownRecover] = 0; - if (m_fAirFinished < gpGlobals->time) // drown! + if (pev->air_finished < gpGlobals->time) // drown! { - if (m_fPainFinished < gpGlobals->time) + if (pev->pain_finished < gpGlobals->time) { // take drowning damage pev->dmg += 1; if (pev->dmg > 5) pev->dmg = 5; TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN); - m_fPainFinished = gpGlobals->time + 1; + pev->pain_finished = gpGlobals->time + 1; // track drowning damage, give it back when // player finally takes a breath @@ -1423,7 +1421,7 @@ void CBasePlayer::WaterMove() // make bubbles - air = (int)(m_fAirFinished - gpGlobals->time); + air = (int)(pev->air_finished - gpGlobals->time); if (!RANDOM_LONG(0,0x1f) && RANDOM_LONG(0,AIRTIME-1) >= air) { switch (RANDOM_LONG(0,3)) @@ -1581,7 +1579,7 @@ void CBasePlayer::StartDeathCam( void ) } CopyToBodyQue( pev ); - StartObserver( pSpot->pev->origin, pSpot->pev->viewangles ); + StartObserver( pSpot->pev->origin, pSpot->pev->v_angle ); } else { @@ -1599,7 +1597,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) m_afPhysicsFlags |= PFLAG_OBSERVER; pev->view_ofs = g_vecZero; - pev->angles = pev->viewangles = vecViewAngle; + pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; @@ -1662,7 +1660,7 @@ void CBasePlayer::PlayerUse ( void ) TraceResult tr; int caps; - UTIL_MakeVectors ( pev->viewangles );// so we know which way we are facing + UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing //LRC- try to get an exact entity to use. // (is this causing "use-buttons-through-walls" problems? Surely not!) @@ -1895,7 +1893,7 @@ void CBasePlayer::UpdateStatusBar() // Find an ID Target TraceResult tr; - UTIL_MakeVectors( pev->viewangles + pev->punchangle ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle ); Vector vecSrc = EyePosition(); Vector vecEnd = vecSrc + (gpGlobals->v_forward * MAX_ID_RANGE); UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr); @@ -2004,7 +2002,7 @@ void CBasePlayer::PreThink(void) if ( g_fGameOver ) return; // intermission or finale - UTIL_MakeVectors(pev->viewangles); // is this still used? + UTIL_MakeVectors(pev->v_angle); // is this still used? ItemPreFrame( ); WaterMove(); @@ -2935,7 +2933,7 @@ void CBasePlayer::Spawn( void ) pev->max_health = pev->health; pev->flags &= FL_PROXY; // keep proxy flag sey by engine pev->flags |= FL_CLIENT; - m_fAirFinished = gpGlobals->time + 12; + pev->air_finished = gpGlobals->time + 12; pev->dmg = 2; // initial water damage pev->effects = 0; pev->deadflag = DEAD_NO; @@ -2946,8 +2944,7 @@ void CBasePlayer::Spawn( void ) pev->gravity = 1.0; pev->renderfx = 0; pev->rendercolor = g_vecZero; - pev->mass = 90; // lbs - pev->viewangles.z = 0; // cut off any camera rolling + pev->v_angle.z = 0; // cut off any camera rolling m_bitsHUDDamage = -1; m_bitsDamageType = 0; m_afPhysicsFlags = 0; @@ -3123,8 +3120,8 @@ int CBasePlayer::Restore( CRestore &restore ) pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); pev->angles = VARS(pentSpawnSpot)->angles; } - pev->viewangles.z = 0; // Clear out roll - pev->angles = pev->viewangles; + pev->v_angle.z = 0; // Clear out roll + pev->angles = pev->v_angle; pev->fixangle = TRUE; // turn this way immediately @@ -3347,7 +3344,7 @@ public: void CSprayCan::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); pev->frame = 0; @@ -3403,7 +3400,7 @@ public: void CBloodSplat::Spawn ( entvars_t *pevOwner ) { pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->viewangles; + pev->angles = pevOwner->v_angle; pev->owner = ENT(pevOwner); SetThink(&CBloodSplat:: Spray ); @@ -3456,7 +3453,7 @@ CBaseEntity *FindEntityForward( CBaseEntity *pMe ) { TraceResult tr; - UTIL_MakeVectors(pMe->pev->viewangles); + UTIL_MakeVectors(pMe->pev->v_angle); UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192,dont_ignore_monsters, pMe->edict(), &tr ); if ( tr.flFraction != 1.0 && !FNullEnt( tr.pHit) ) { @@ -3583,7 +3580,7 @@ void CBasePlayer::ImpulseCommands( ) break; } - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); if ( tr.flFraction != 1.0 ) @@ -3624,7 +3621,7 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse ) { case 76: { - UTIL_MakeVectors( Vector( 0, pev->viewangles.y, 0 ) ); + UTIL_MakeVectors( Vector( 0, pev->v_angle.y, 0 ) ); Create("monster_human_grunt", pev->origin + gpGlobals->v_forward * 128, pev->angles); break; } @@ -3782,7 +3779,7 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse ) } break; case 202:// Random blood splatter - UTIL_MakeVectors(pev->viewangles); + UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); if ( tr.flFraction != 1.0 ) @@ -4568,7 +4565,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta ) { if (g_iSkillLevel == SKILL_HARD) { - UTIL_MakeVectors( pev->viewangles + pev->punchangle ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle ); return gpGlobals->v_forward; } @@ -4641,7 +4638,7 @@ Vector CBasePlayer :: GetAutoaimVector( float flDelta ) // ALERT( at_console, "%f %f\n", angles.x, angles.y ); - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); return gpGlobals->v_forward; } @@ -4661,7 +4658,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD return g_vecZero; } - UTIL_MakeVectors( pev->viewangles + pev->punchangle + m_vecAutoAim ); + UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); // try all possible entities bestdir = gpGlobals->v_forward; @@ -4758,7 +4755,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD { bestdir = UTIL_VecToAngles (bestdir); bestdir.x = -bestdir.x; - bestdir = bestdir - pev->viewangles - pev->punchangle; + bestdir = bestdir - pev->v_angle - pev->punchangle; if (bestent->v.takedamage == DAMAGE_AIM) m_fOnTarget = TRUE; @@ -5332,7 +5329,7 @@ void CInfoIntermission::Spawn( void ) UTIL_SetOrigin( this, pev->origin ); pev->solid = SOLID_NOT; pev->effects = EF_NODRAW; - pev->viewangles = g_vecZero; + pev->v_angle = g_vecZero; SetNextThink( 2 );// let targets spawn! @@ -5347,8 +5344,8 @@ void CInfoIntermission::Think ( void ) if ( pTarget ) { - pev->viewangles = UTIL_VecToAngles( (pTarget->pev->origin - pev->origin).Normalize() ); - pev->viewangles.x = -pev->viewangles.x; + pev->v_angle = UTIL_VecToAngles( (pTarget->pev->origin - pev->origin).Normalize() ); + pev->v_angle.x = -pev->v_angle.x; } } diff --git a/spirit/player.h b/spirit/player.h index b3e18bea..c607ee5b 100644 --- a/spirit/player.h +++ b/spirit/player.h @@ -154,8 +154,6 @@ public: EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink()) - float m_fAirFinished; // moved here from progdefs.h - float m_fPainFinished; // moved here from progdefs.h float m_flViewHeight; // keep value from view_ofs.z that engine sets it when player first entering in multiplayer BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true. diff --git a/spirit/python.cpp b/spirit/python.cpp index 6b958414..98fbf9ef 100644 --- a/spirit/python.cpp +++ b/spirit/python.cpp @@ -149,7 +149,7 @@ void CPython::PrimaryAttack() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); @@ -192,8 +192,8 @@ void CPython::UpdateSpot( void ) EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM); } - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); - Vector vecSrc = m_pPlayer->GetGunPosition( );; + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; diff --git a/spirit/rpg.cpp b/spirit/rpg.cpp index c1567dcc..0c3f64c7 100644 --- a/spirit/rpg.cpp +++ b/spirit/rpg.cpp @@ -366,11 +366,11 @@ void CRpg::PrimaryAttack() // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); Vector vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -8; - CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->viewangles, m_pPlayer, this ); - UTIL_MakeVectors( m_pPlayer->pev->viewangles );// RpgRocket::Create stomps on globals, so remake. + CRpgRocket *pRocket = CRpgRocket::Create ( vecSrc, m_pPlayer->pev->v_angle, m_pPlayer, this ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle );// RpgRocket::Create stomps on globals, so remake. pRocket->pev->velocity = pRocket->pev->velocity + gpGlobals->v_forward * DotProduct( m_pPlayer->pev->velocity, gpGlobals->v_forward ); // firing RPG no longer turns on the designator. ALT fire is a toggle switch for the LTD. @@ -423,8 +423,8 @@ void CRpg::UpdateSpot( void ) EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM); } - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); - Vector vecSrc = m_pPlayer->GetGunPosition( );; + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); + Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = gpGlobals->v_forward; TraceResult tr; diff --git a/spirit/singleplay_gamerules.cpp b/spirit/singleplay_gamerules.cpp index c79d9602..f20e1a16 100644 --- a/spirit/singleplay_gamerules.cpp +++ b/spirit/singleplay_gamerules.cpp @@ -92,7 +92,7 @@ BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem //========================================================= //========================================================= -BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *userinfo ) +BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] ) { return TRUE; } diff --git a/spirit/spirit.def b/spirit/spirit.def index a895dcba..0f288692 100644 --- a/spirit/spirit.def +++ b/spirit/spirit.def @@ -1,5 +1,5 @@ LIBRARY server EXPORTS - CreateAPI @1 + GiveFnptrsToDll @1 SECTIONS .data READ WRITE diff --git a/spirit/squeakgrenade.cpp b/spirit/squeakgrenade.cpp index 7b3de885..7a4825d5 100644 --- a/spirit/squeakgrenade.cpp +++ b/spirit/squeakgrenade.cpp @@ -454,7 +454,7 @@ void CSqueak::PrimaryAttack() { if ( m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] ) { - UTIL_MakeVectors( m_pPlayer->pev->viewangles ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle ); TraceResult tr; Vector trace_origin; @@ -468,14 +468,14 @@ void CSqueak::PrimaryAttack() // find place to toss monster UTIL_TraceLine( trace_origin + gpGlobals->v_forward * 20, trace_origin + gpGlobals->v_forward * 64, dont_ignore_monsters, NULL, &tr ); - PLAYBACK_EVENT_FULL( 0, m_pPlayer->edict(), m_usSnarkFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, pev->body, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( 0, m_pPlayer->edict(), m_usSnarkFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, pev->body, 0, 0, 0 ); if ( tr.fAllSolid == 0 && tr.fStartSolid == 0 && tr.flFraction > 0.25 ) { // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->viewangles, m_pPlayer->edict() ); + CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->v_angle, m_pPlayer->edict() ); pSqueak->pev->velocity = gpGlobals->v_forward * 200 + m_pPlayer->pev->velocity; // play hunt sound diff --git a/spirit/teamplay_gamerules.cpp b/spirit/teamplay_gamerules.cpp index d5a0ca6f..f40415e0 100644 --- a/spirit/teamplay_gamerules.cpp +++ b/spirit/teamplay_gamerules.cpp @@ -1,620 +1,622 @@ -/*** -* -* Copyright (c) 1996-2002, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "teamplay_gamerules.h" -#include "game.h" - -static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH]; -static int team_scores[MAX_TEAMS]; -static int num_teams = 0; - -extern DLL_GLOBAL BOOL g_fGameOver; - -CHalfLifeTeamplay :: CHalfLifeTeamplay() -{ - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - - memset( team_names, 0, sizeof(team_names) ); - memset( team_scores, 0, sizeof(team_scores) ); - num_teams = 0; - - // Copy over the team from the server config - m_szTeamList[0] = 0; - - // Cache this because the team code doesn't want to deal with changing this in the middle of a game - strncpy( m_szTeamList, teamlist->string, TEAMPLAY_TEAMLISTLENGTH ); - - edict_t *pWorld = INDEXENT(0); - if ( pWorld && pWorld->v.team ) - { - if ( teamoverride->value ) - { - const char *pTeamList = STRING(pWorld->v.team); - if ( pTeamList && strlen(pTeamList) ) - { - strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH ); - } - } - } - // Has the server set teams - if ( strlen( m_szTeamList ) ) - m_teamLimit = TRUE; - else - m_teamLimit = FALSE; - - RecountTeams(); -} - -extern cvar_t *timeleft, *fragsleft; - -void CHalfLifeTeamplay :: Think ( void ) -{ - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - if ( g_fGameOver ) // someone else quit the game already - { - CHalfLifeMultiplay::Think(); - return; - } - - float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) - { - GoToIntermission(); - return; - } - - float flFragLimit = fraglimit->value; - if ( flFragLimit ) - { - int bestfrags = 9999; - int remain; - - // check if any team is over the frag limit - for ( int i = 0; i < num_teams; i++ ) - { - if ( team_scores[i] >= flFragLimit ) - { - GoToIntermission(); - return; - } - - remain = flFragLimit - team_scores[i]; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - frags_remaining = bestfrags; - } - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - CVAR_SET_STRING( "mp_fragsleft", UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft->value != last_time ) - { - CVAR_SET_STRING( "mp_timeleft", UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - -//========================================================= -// ClientCommand -// the user has typed a command which is unrecognized by everything else; -// this check to see if the gamerules knows anything about the command -//========================================================= -BOOL CHalfLifeTeamplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ - if ( FStrEq( pcmd, "menuselect" ) ) - { - if ( CMD_ARGC() < 2 ) - return TRUE; - - int slot = atoi( CMD_ARGV(1) ); - - // select the item from the current menu - - return TRUE; - } - - return FALSE; -} - -extern int gmsgGameMode; -extern int gmsgSayText; -extern int gmsgTeamInfo; -extern int gmsgTeamNames; -extern int gmsgScoreInfo; - -void CHalfLifeTeamplay :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( 1 ); // game mode teamplay - MESSAGE_END(); -} - - -const char *CHalfLifeTeamplay::SetDefaultPlayerTeam( CBasePlayer *pPlayer ) -{ - // copy out the team name from the model - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - strncpy( pPlayer->m_szTeamName, mdls, TEAM_NAME_LENGTH ); - - RecountTeams(); - - // update the current player of the team he is joining - if ( pPlayer->m_szTeamName[0] == '\0' || !IsValidTeam( pPlayer->m_szTeamName ) || defaultteam->value ) - { - const char *pTeamName = NULL; - - if ( defaultteam->value ) - { - pTeamName = team_names[0]; - } - else - { - pTeamName = TeamWithFewestPlayers(); - } - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - } - - return pPlayer->m_szTeamName; -} - - -//========================================================= -// InitHUD -//========================================================= -void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer ) -{ - int i; - - SetDefaultPlayerTeam( pPlayer ); - CHalfLifeMultiplay::InitHUD( pPlayer ); - - // Send down the team names - MESSAGE_BEGIN( MSG_ONE, gmsgTeamNames, NULL, pPlayer->edict() ); - WRITE_BYTE( num_teams ); - for ( i = 0; i < num_teams; i++ ) - { - WRITE_STRING( team_names[ i ] ); - } - MESSAGE_END(); - - RecountTeams(); - - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - // update the current player of the team he is joining - char text[1024]; - if ( !strcmp( mdls, pPlayer->m_szTeamName ) ) - { - sprintf( text, "* you are on team \'%s\'\n", pPlayer->m_szTeamName ); - } - else - { - sprintf( text, "* assigned to team %s\n", pPlayer->m_szTeamName ); - } - - ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE ); - UTIL_SayText( text, pPlayer ); - int clientIndex = pPlayer->entindex(); - RecountTeams(); - // update this player with all the other players team info - // loop through all active players and send their team info to the new client - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - if ( plr && IsValidTeam( plr->TeamID() ) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgTeamInfo, NULL, pPlayer->edict() ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - } - } -} - - -void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) -{ - int damageFlags = DMG_GENERIC; - int clientIndex = pPlayer->entindex(); - - if ( !bGib ) - { - damageFlags |= DMG_NEVERGIB; - } - else - { - damageFlags |= DMG_ALWAYSGIB; - } - - if ( bKill ) - { - // kill the player, remove a death, and let them start on the new team - m_DisableDeathMessages = TRUE; - m_DisableDeathPenalty = TRUE; - - entvars_t *pevWorld = VARS( INDEXENT(0) ); - pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags ); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - } - - // copy out the team name from the model - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - - // notify everyone's HUD of the team change - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( clientIndex ); - WRITE_STRING( pPlayer->m_szTeamName ); - MESSAGE_END(); - - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( clientIndex ); - WRITE_SHORT( pPlayer->pev->frags ); - WRITE_SHORT( pPlayer->m_iDeaths ); - WRITE_SHORT( 0 ); - WRITE_SHORT( g_pGameRules->GetTeamIndex( pPlayer->m_szTeamName ) + 1 ); - MESSAGE_END(); -} - - -//========================================================= -// ClientUserInfoChanged -//========================================================= -void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) -{ - char text[1024]; - - // prevent skin/color/model changes - char *mdls = g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ); - - if ( !stricmp( mdls, pPlayer->m_szTeamName ) ) - return; - - if ( defaultteam->value ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - sprintf( text, "* Not allowed to change teams in this game!\n" ); - UTIL_SayText( text, pPlayer ); - return; - } - - if ( defaultteam->value || !IsValidTeam( mdls ) ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - sprintf( text, "* Can't change team to \'%s\'\n", mdls ); - UTIL_SayText( text, pPlayer ); - sprintf( text, "* Server limits teams to \'%s\'\n", m_szTeamList ); - UTIL_SayText( text, pPlayer ); - return; - } - // notify everyone of the team change - sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls ); - UTIL_SayTextAll( text, pPlayer ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", - STRING(pPlayer->pev->netname), - pPlayer->m_szTeamName, - mdls ); - - ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE ); - // recound stuff - RecountTeams( TRUE ); -} - -extern int gmsgDeathMsg; - -//========================================================= -// Deathnotice. -//========================================================= -void CHalfLifeTeamplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - if ( m_DisableDeathMessages ) - return; - - if ( pVictim && pKiller && pKiller->flags & FL_CLIENT ) - { - CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller ); - - if ( pk ) - { - if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "teammate" ); // flag this as a teammate kill - MESSAGE_END(); - return; - } - } - } - - CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor ); -} - -//========================================================= -//========================================================= -void CHalfLifeTeamplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - if ( !m_DisableDeathPenalty ) - { - CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor ); - RecountTeams(); - } -} - - -//========================================================= -// IsTeamplay -//========================================================= -BOOL CHalfLifeTeamplay::IsTeamplay( void ) -{ - return TRUE; -} - -BOOL CHalfLifeTeamplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE ) - { - // my teammate hit me. - if ( (friendlyfire->value == 0) && (pAttacker != pPlayer) ) - { - // friendly fire is off, and this hit came from someone other than myself, then don't get hurt - return FALSE; - } - } - - return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life multiplay has a simple concept of Player Relationships. - // you are either on another player's team, or you are not. - if ( !pPlayer || !pTarget || !pTarget->IsPlayer() ) - return GR_NOTTEAMMATE; - - if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) ) - { - return GR_TEAMMATE; - } - - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeTeamplay::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) -{ - // always autoaim, unless target is a teammate - CBaseEntity *pTgt = CBaseEntity::Instance( target ); - if ( pTgt && pTgt->IsPlayer() ) - { - if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE ) - return FALSE; // don't autoaim at teammates - } - - return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - if ( !pKilled ) - return 0; - - if ( !pAttacker ) - return 1; - - if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE ) - return -1; - - return 1; -} - -//========================================================= -//========================================================= -const char *CHalfLifeTeamplay::GetTeamID( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL || pEntity->pev == NULL ) - return ""; - - // return their team name - return pEntity->TeamID(); -} - - -int CHalfLifeTeamplay::GetTeamIndex( const char *pTeamName ) -{ - if ( pTeamName && *pTeamName != 0 ) - { - // try to find existing team - for ( int tm = 0; tm < num_teams; tm++ ) - { - if ( !stricmp( team_names[tm], pTeamName ) ) - return tm; - } - } - - return -1; // No match -} - - -const char *CHalfLifeTeamplay::GetIndexedTeamName( int teamIndex ) -{ - if ( teamIndex < 0 || teamIndex >= num_teams ) - return ""; - - return team_names[ teamIndex ]; -} - - -BOOL CHalfLifeTeamplay::IsValidTeam( const char *pTeamName ) -{ - if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set - return TRUE; - - return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE; -} - -const char *CHalfLifeTeamplay::TeamWithFewestPlayers( void ) -{ - int i; - int minPlayers = MAX_TEAMS; - int teamCount[ MAX_TEAMS ]; - char *pTeamName = NULL; - - memset( teamCount, 0, MAX_TEAMS * sizeof(int) ); - - // loop through all clients, count number of players on each team - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - int team = GetTeamIndex( plr->TeamID() ); - if ( team >= 0 ) - teamCount[team] ++; - } - } - - // Find team with least players - for ( i = 0; i < num_teams; i++ ) - { - if ( teamCount[i] < minPlayers ) - { - minPlayers = teamCount[i]; - pTeamName = team_names[i]; - } - } - - return pTeamName; -} - - -//========================================================= -//========================================================= -void CHalfLifeTeamplay::RecountTeams( bool bResendInfo ) -{ - char *pName; - char teamlist[TEAMPLAY_TEAMLISTLENGTH]; - - // loop through all teams, recounting everything - num_teams = 0; - - // Copy all of the teams from the teamlist - // make a copy because strtok is destructive - strcpy( teamlist, m_szTeamList ); - pName = teamlist; - pName = strtok( pName, ";" ); - while ( pName != NULL && *pName ) - { - if ( GetTeamIndex( pName ) < 0 ) - { - strcpy( team_names[num_teams], pName ); - num_teams++; - } - pName = strtok( NULL, ";" ); - } - - if ( num_teams < 2 ) - { - num_teams = 0; - m_teamLimit = FALSE; - } - - // Sanity check - memset( team_scores, 0, sizeof(team_scores) ); - - // loop through all clients - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - const char *pTeamName = plr->TeamID(); - // try add to existing team - int tm = GetTeamIndex( pTeamName ); - - if ( tm < 0 ) // no team match found - { - if ( !m_teamLimit ) - { - // add to new team - tm = num_teams; - num_teams++; - team_scores[tm] = 0; - strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH ); - } - } - - if ( tm >= 0 ) - { - team_scores[tm] += plr->pev->frags; - } - - if ( bResendInfo ) //Someone's info changed, let's send the team info again. - { - if ( plr && IsValidTeam( plr->TeamID() ) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo, NULL ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - } - } - } - } -} +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// teamplay_gamerules.cpp +// +#include "extdll.h" +#include "util.h" +#include "cbase.h" +#include "player.h" +#include "weapons.h" +#include "gamerules.h" +#include "teamplay_gamerules.h" +#include "game.h" + +static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH]; +static int team_scores[MAX_TEAMS]; +static int num_teams = 0; + +extern DLL_GLOBAL BOOL g_fGameOver; + +CHalfLifeTeamplay :: CHalfLifeTeamplay() +{ + m_DisableDeathMessages = FALSE; + m_DisableDeathPenalty = FALSE; + + memset( team_names, 0, sizeof(team_names) ); + memset( team_scores, 0, sizeof(team_scores) ); + num_teams = 0; + + // Copy over the team from the server config + m_szTeamList[0] = 0; + + // Cache this because the team code doesn't want to deal with changing this in the middle of a game + strncpy( m_szTeamList, teamlist->string, TEAMPLAY_TEAMLISTLENGTH ); + + edict_t *pWorld = INDEXENT(0); + if ( pWorld && pWorld->v.team ) + { + if ( teamoverride->value ) + { + const char *pTeamList = STRING(pWorld->v.team); + if ( pTeamList && strlen(pTeamList) ) + { + strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH ); + } + } + } + // Has the server set teams + if ( strlen( m_szTeamList ) ) + m_teamLimit = TRUE; + else + m_teamLimit = FALSE; + + RecountTeams(); +} + +extern cvar_t *timeleft, *fragsleft; + +void CHalfLifeTeamplay :: Think ( void ) +{ + ///// Check game rules ///// + static int last_frags; + static int last_time; + + int frags_remaining = 0; + int time_remaining = 0; + + if ( g_fGameOver ) // someone else quit the game already + { + CHalfLifeMultiplay::Think(); + return; + } + + float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60; + + time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); + + if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) + { + GoToIntermission(); + return; + } + + float flFragLimit = fraglimit->value; + if ( flFragLimit ) + { + int bestfrags = 9999; + int remain; + + // check if any team is over the frag limit + for ( int i = 0; i < num_teams; i++ ) + { + if ( team_scores[i] >= flFragLimit ) + { + GoToIntermission(); + return; + } + + remain = flFragLimit - team_scores[i]; + if ( remain < bestfrags ) + { + bestfrags = remain; + } + } + frags_remaining = bestfrags; + } + + // Updates when frags change + if ( frags_remaining != last_frags ) + { + CVAR_SET_STRING( "mp_fragsleft", UTIL_VarArgs( "%i", frags_remaining ) ); + } + + // Updates once per second + if ( timeleft->value != last_time ) + { + CVAR_SET_STRING( "mp_timeleft", UTIL_VarArgs( "%i", time_remaining ) ); + } + + last_frags = frags_remaining; + last_time = time_remaining; +} + +//========================================================= +// ClientCommand +// the user has typed a command which is unrecognized by everything else; +// this check to see if the gamerules knows anything about the command +//========================================================= +BOOL CHalfLifeTeamplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) +{ + if ( FStrEq( pcmd, "menuselect" ) ) + { + if ( CMD_ARGC() < 2 ) + return TRUE; + + int slot = atoi( CMD_ARGV(1) ); + + // select the item from the current menu + + return TRUE; + } + + return FALSE; +} + +extern int gmsgGameMode; +extern int gmsgSayText; +extern int gmsgTeamInfo; +extern int gmsgTeamNames; +extern int gmsgScoreInfo; + +void CHalfLifeTeamplay :: UpdateGameMode( CBasePlayer *pPlayer ) +{ + MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); + WRITE_BYTE( 1 ); // game mode teamplay + MESSAGE_END(); +} + + +const char *CHalfLifeTeamplay::SetDefaultPlayerTeam( CBasePlayer *pPlayer ) +{ + // copy out the team name from the model + char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); + strncpy( pPlayer->m_szTeamName, mdls, TEAM_NAME_LENGTH ); + + RecountTeams(); + + // update the current player of the team he is joining + if ( pPlayer->m_szTeamName[0] == '\0' || !IsValidTeam( pPlayer->m_szTeamName ) || defaultteam->value ) + { + const char *pTeamName = NULL; + + if ( defaultteam->value ) + { + pTeamName = team_names[0]; + } + else + { + pTeamName = TeamWithFewestPlayers(); + } + strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); + } + + return pPlayer->m_szTeamName; +} + + +//========================================================= +// InitHUD +//========================================================= +void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer ) +{ + int i; + + SetDefaultPlayerTeam( pPlayer ); + CHalfLifeMultiplay::InitHUD( pPlayer ); + + // Send down the team names + MESSAGE_BEGIN( MSG_ONE, gmsgTeamNames, NULL, pPlayer->edict() ); + WRITE_BYTE( num_teams ); + for ( i = 0; i < num_teams; i++ ) + { + WRITE_STRING( team_names[ i ] ); + } + MESSAGE_END(); + + RecountTeams(); + + char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); + // update the current player of the team he is joining + char text[1024]; + if ( !strcmp( mdls, pPlayer->m_szTeamName ) ) + { + sprintf( text, "* you are on team \'%s\'\n", pPlayer->m_szTeamName ); + } + else + { + sprintf( text, "* assigned to team %s\n", pPlayer->m_szTeamName ); + } + + ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE ); + UTIL_SayText( text, pPlayer ); + int clientIndex = pPlayer->entindex(); + RecountTeams(); + // update this player with all the other players team info + // loop through all active players and send their team info to the new client + for ( i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *plr = UTIL_PlayerByIndex( i ); + if ( plr && IsValidTeam( plr->TeamID() ) ) + { + MESSAGE_BEGIN( MSG_ONE, gmsgTeamInfo, NULL, pPlayer->edict() ); + WRITE_BYTE( plr->entindex() ); + WRITE_STRING( plr->TeamID() ); + MESSAGE_END(); + } + } +} + + +void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) +{ + int damageFlags = DMG_GENERIC; + int clientIndex = pPlayer->entindex(); + + if ( !bGib ) + { + damageFlags |= DMG_NEVERGIB; + } + else + { + damageFlags |= DMG_ALWAYSGIB; + } + + if ( bKill ) + { + // kill the player, remove a death, and let them start on the new team + m_DisableDeathMessages = TRUE; + m_DisableDeathPenalty = TRUE; + + entvars_t *pevWorld = VARS( INDEXENT(0) ); + pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags ); + + m_DisableDeathMessages = FALSE; + m_DisableDeathPenalty = FALSE; + } + + // copy out the team name from the model + strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); + + g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); + g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); + + // notify everyone's HUD of the team change + MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); + WRITE_BYTE( clientIndex ); + WRITE_STRING( pPlayer->m_szTeamName ); + MESSAGE_END(); + + MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); + WRITE_BYTE( clientIndex ); + WRITE_SHORT( pPlayer->pev->frags ); + WRITE_SHORT( pPlayer->m_iDeaths ); + WRITE_SHORT( 0 ); + WRITE_SHORT( g_pGameRules->GetTeamIndex( pPlayer->m_szTeamName ) + 1 ); + MESSAGE_END(); +} + + +//========================================================= +// ClientUserInfoChanged +//========================================================= +void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) +{ + char text[1024]; + + // prevent skin/color/model changes + char *mdls = g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ); + + if ( !stricmp( mdls, pPlayer->m_szTeamName ) ) + return; + + if ( defaultteam->value ) + { + int clientIndex = pPlayer->entindex(); + + g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); + g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); + sprintf( text, "* Not allowed to change teams in this game!\n" ); + UTIL_SayText( text, pPlayer ); + return; + } + + if ( defaultteam->value || !IsValidTeam( mdls ) ) + { + int clientIndex = pPlayer->entindex(); + + g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); + sprintf( text, "* Can't change team to \'%s\'\n", mdls ); + UTIL_SayText( text, pPlayer ); + sprintf( text, "* Server limits teams to \'%s\'\n", m_szTeamList ); + UTIL_SayText( text, pPlayer ); + return; + } + // notify everyone of the team change + sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls ); + UTIL_SayTextAll( text, pPlayer ); + + UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", + STRING(pPlayer->pev->netname), + GETPLAYERUSERID( pPlayer->edict() ), + GETPLAYERAUTHID( pPlayer->edict() ), + pPlayer->m_szTeamName, + mdls ); + + ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE ); + // recound stuff + RecountTeams( TRUE ); +} + +extern int gmsgDeathMsg; + +//========================================================= +// Deathnotice. +//========================================================= +void CHalfLifeTeamplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) +{ + if ( m_DisableDeathMessages ) + return; + + if ( pVictim && pKiller && pKiller->flags & FL_CLIENT ) + { + CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller ); + + if ( pk ) + { + if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) ) + { + MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); + WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer + WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim + WRITE_STRING( "teammate" ); // flag this as a teammate kill + MESSAGE_END(); + return; + } + } + } + + CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor ); +} + +//========================================================= +//========================================================= +void CHalfLifeTeamplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) +{ + if ( !m_DisableDeathPenalty ) + { + CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor ); + RecountTeams(); + } +} + + +//========================================================= +// IsTeamplay +//========================================================= +BOOL CHalfLifeTeamplay::IsTeamplay( void ) +{ + return TRUE; +} + +BOOL CHalfLifeTeamplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) +{ + if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE ) + { + // my teammate hit me. + if ( (friendlyfire->value == 0) && (pAttacker != pPlayer) ) + { + // friendly fire is off, and this hit came from someone other than myself, then don't get hurt + return FALSE; + } + } + + return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker ); +} + +//========================================================= +//========================================================= +int CHalfLifeTeamplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) +{ + // half life multiplay has a simple concept of Player Relationships. + // you are either on another player's team, or you are not. + if ( !pPlayer || !pTarget || !pTarget->IsPlayer() ) + return GR_NOTTEAMMATE; + + if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) ) + { + return GR_TEAMMATE; + } + + return GR_NOTTEAMMATE; +} + +//========================================================= +//========================================================= +BOOL CHalfLifeTeamplay::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) +{ + // always autoaim, unless target is a teammate + CBaseEntity *pTgt = CBaseEntity::Instance( target ); + if ( pTgt && pTgt->IsPlayer() ) + { + if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE ) + return FALSE; // don't autoaim at teammates + } + + return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target ); +} + +//========================================================= +//========================================================= +int CHalfLifeTeamplay::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) +{ + if ( !pKilled ) + return 0; + + if ( !pAttacker ) + return 1; + + if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE ) + return -1; + + return 1; +} + +//========================================================= +//========================================================= +const char *CHalfLifeTeamplay::GetTeamID( CBaseEntity *pEntity ) +{ + if ( pEntity == NULL || pEntity->pev == NULL ) + return ""; + + // return their team name + return pEntity->TeamID(); +} + + +int CHalfLifeTeamplay::GetTeamIndex( const char *pTeamName ) +{ + if ( pTeamName && *pTeamName != 0 ) + { + // try to find existing team + for ( int tm = 0; tm < num_teams; tm++ ) + { + if ( !stricmp( team_names[tm], pTeamName ) ) + return tm; + } + } + + return -1; // No match +} + + +const char *CHalfLifeTeamplay::GetIndexedTeamName( int teamIndex ) +{ + if ( teamIndex < 0 || teamIndex >= num_teams ) + return ""; + + return team_names[ teamIndex ]; +} + + +BOOL CHalfLifeTeamplay::IsValidTeam( const char *pTeamName ) +{ + if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set + return TRUE; + + return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE; +} + +const char *CHalfLifeTeamplay::TeamWithFewestPlayers( void ) +{ + int i; + int minPlayers = MAX_TEAMS; + int teamCount[ MAX_TEAMS ]; + char *pTeamName = NULL; + + memset( teamCount, 0, MAX_TEAMS * sizeof(int) ); + + // loop through all clients, count number of players on each team + for ( i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *plr = UTIL_PlayerByIndex( i ); + + if ( plr ) + { + int team = GetTeamIndex( plr->TeamID() ); + if ( team >= 0 ) + teamCount[team] ++; + } + } + + // Find team with least players + for ( i = 0; i < num_teams; i++ ) + { + if ( teamCount[i] < minPlayers ) + { + minPlayers = teamCount[i]; + pTeamName = team_names[i]; + } + } + + return pTeamName; +} + + +//========================================================= +//========================================================= +void CHalfLifeTeamplay::RecountTeams( bool bResendInfo ) +{ + char *pName; + char teamlist[TEAMPLAY_TEAMLISTLENGTH]; + + // loop through all teams, recounting everything + num_teams = 0; + + // Copy all of the teams from the teamlist + // make a copy because strtok is destructive + strcpy( teamlist, m_szTeamList ); + pName = teamlist; + pName = strtok( pName, ";" ); + while ( pName != NULL && *pName ) + { + if ( GetTeamIndex( pName ) < 0 ) + { + strcpy( team_names[num_teams], pName ); + num_teams++; + } + pName = strtok( NULL, ";" ); + } + + if ( num_teams < 2 ) + { + num_teams = 0; + m_teamLimit = FALSE; + } + + // Sanity check + memset( team_scores, 0, sizeof(team_scores) ); + + // loop through all clients + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *plr = UTIL_PlayerByIndex( i ); + + if ( plr ) + { + const char *pTeamName = plr->TeamID(); + // try add to existing team + int tm = GetTeamIndex( pTeamName ); + + if ( tm < 0 ) // no team match found + { + if ( !m_teamLimit ) + { + // add to new team + tm = num_teams; + num_teams++; + team_scores[tm] = 0; + strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH ); + } + } + + if ( tm >= 0 ) + { + team_scores[tm] += plr->pev->frags; + } + + if ( bResendInfo ) //Someone's info changed, let's send the team info again. + { + if ( plr && IsValidTeam( plr->TeamID() ) ) + { + MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo, NULL ); + WRITE_BYTE( plr->entindex() ); + WRITE_STRING( plr->TeamID() ); + MESSAGE_END(); + } + } + } + } +} diff --git a/spirit/triggers.cpp b/spirit/triggers.cpp index 57b0771c..8bed8a99 100644 --- a/spirit/triggers.cpp +++ b/spirit/triggers.cpp @@ -2273,7 +2273,7 @@ void CTriggerHurt :: HurtTouch ( CBaseEntity *pOther ) { if ( pev->dmgtime > gpGlobals->time ) { - if ( gpGlobals->time != pev->dmg_take ) + if ( gpGlobals->time != pev->pain_finished ) {// too early to hurt again, and not same frame with a different entity if ( pOther->IsPlayer() ) { @@ -2309,7 +2309,7 @@ void CTriggerHurt :: HurtTouch ( CBaseEntity *pOther ) } else // Original code -- single player { - if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->dmg_take ) + if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) {// too early to hurt again, and not same frame with a different entity return; } @@ -2346,7 +2346,7 @@ void CTriggerHurt :: HurtTouch ( CBaseEntity *pOther ) pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict ); // Store pain time so we can get all of the other entities on this frame - pev->dmg_take = gpGlobals->time; + pev->pain_finished = gpGlobals->time; // Apply damage every half second pev->dmgtime = gpGlobals->time + 0.5;// half second delay until this trigger can hurt toucher again @@ -4152,9 +4152,9 @@ void CTriggerTeleport :: TeleportTouch( CBaseEntity *pOther ) pOther->pev->angles.y += ydiff; if (pOther->IsPlayer()) { -// ALERT(at_console, "viewangles = %f %f %f\n", pOther->pev->viewangles.x, pOther->pev->viewangles.y, pOther->pev->viewangles.z); - pOther->pev->angles.x = pOther->pev->viewangles.x; -// pOther->pev->viewangles.y += ydiff; +// ALERT(at_console, "v_angle = %f %f %f\n", pOther->pev->v_angle.x, pOther->pev->v_angle.y, pOther->pev->v_angle.z); + pOther->pev->angles.x = pOther->pev->v_angle.x; +// pOther->pev->v_angles.y += ydiff; pOther->pev->fixangle = TRUE; } @@ -4199,7 +4199,7 @@ void CTriggerTeleport :: TeleportTouch( CBaseEntity *pOther ) pOther->pev->velocity = pOther->pev->basevelocity = g_vecZero; if ( pOther->IsPlayer() ) { - pOther->pev->viewangles = pTarget->pev->angles; //LRC + pOther->pev->v_angle = pTarget->pev->angles; //LRC pOther->pev->fixangle = TRUE; } } @@ -4272,7 +4272,7 @@ void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pC if ( pev->message ) { - HOST_ENDGAME( STRING( pev->message )); + g_engfuncs.pfnEndSection(STRING(pev->message)); } UTIL_Remove( this ); } @@ -4303,7 +4303,7 @@ void CTriggerEndSection::EndSectionTouch( CBaseEntity *pOther ) if (pev->message) { - HOST_ENDGAME( STRING( pev->message )); + g_engfuncs.pfnEndSection(STRING(pev->message)); } UTIL_Remove( this ); } diff --git a/spirit/tripmine.cpp b/spirit/tripmine.cpp index 44b8670b..550be332 100644 --- a/spirit/tripmine.cpp +++ b/spirit/tripmine.cpp @@ -416,7 +416,7 @@ void CTripmine::PrimaryAttack( void ) { if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) return; - UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); + UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = gpGlobals->v_forward; diff --git a/spirit/turret.cpp b/spirit/turret.cpp index ba7429f9..74f9cdeb 100644 --- a/spirit/turret.cpp +++ b/spirit/turret.cpp @@ -269,7 +269,7 @@ void CBaseTurret::Spawn() if (m_iOrientation == 1) { - pev->ideal_pitch = 180; + pev->idealpitch = 180; pev->angles.x = 180; } diff --git a/spirit/util.cpp b/spirit/util.cpp index fb592a32..95c7c86c 100644 --- a/spirit/util.cpp +++ b/spirit/util.cpp @@ -202,7 +202,7 @@ int PRECACHE_PARTICLE( char* s ) } char *token = NULL; - char *afile = (char *)LOAD_FILE( s, NULL ); + char *afile = (char *)LOAD_FILE_FOR_ME( s, NULL ); const char *pfile = afile; if( !afile ) @@ -239,7 +239,7 @@ int PRECACHE_SOUND( char* s ) if(!s || !*s) return g_sSoundIndexNullSound; //set null sound //NOTE: Engine function as predicted for sound folder - //But LOAD_FILE don't known about this. Set it manualy + //But LOAD_FILE_FOR_ME don't known about this. Set it manualy char path[256]; //g-cont. char *sound = s; //sounds from model events can contains a symbol '*'. @@ -276,27 +276,6 @@ unsigned short PRECACHE_EVENT( int type, const char* psz ) return g_engfuncs.pfnPrecacheEvent( type, psz ); } -void PLAYBACK_EVENT_FULL( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) -{ - event_args_t args; - - args.flags = 0; - if( !FNullEnt( pInvoker )) - args.entindex = ENTINDEX( (edict_t *)pInvoker ); - else args.entindex = 0; - origin.CopyToArray( args.origin ); - angles.CopyToArray( args.angles ); - // don't add velocity - engine will be reset it for some reasons - args.fparam1 = fparam1; - args.fparam2 = fparam2; - args.iparam1 = iparam1; - args.iparam2 = iparam2; - args.bparam1 = bparam1; - args.bparam2 = bparam2; - - g_engfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, &args ); -} - float UTIL_WeaponTimeBase( void ) { return gpGlobals->time; @@ -461,9 +440,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( oldangles, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( viewangles, FIELD_VECTOR ), + DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ), DEFINE_ENTITY_FIELD( fixangle, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( ideal_pitch, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ), DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ), @@ -553,6 +532,9 @@ TYPEDESCRIPTION gEntvarsDescription[] = DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ), DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ), + DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ), + DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ), }; #define ENTVARS_COUNT (sizeof(gEntvarsDescription)/sizeof(gEntvarsDescription[0])) @@ -2038,7 +2020,7 @@ BOOL UTIL_IsFacing( entvars_t *pevTest, const Vector &reference ) vecDir.z = 0; vecDir = vecDir.Normalize(); Vector forward, angle; - angle = pevTest->viewangles; + angle = pevTest->v_angle; angle.x = 0; UTIL_MakeVectorsPrivate( angle, forward, NULL, NULL ); // He's facing me, he meant it diff --git a/spirit/util.h b/spirit/util.h index 6de750f2..ef2b3727 100644 --- a/spirit/util.h +++ b/spirit/util.h @@ -605,7 +605,6 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); #define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -extern void PLAYBACK_EVENT_FULL( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, Vector origin, Vector angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); #define GROUP_OP_AND 0 #define GROUP_OP_NAND 1 diff --git a/spirit/weapons.cpp b/spirit/weapons.cpp index 669c950a..e85284db 100644 --- a/spirit/weapons.cpp +++ b/spirit/weapons.cpp @@ -1033,7 +1033,9 @@ void CBasePlayerWeapon::SendWeaponAnim( int iAnim, float fps ) } } - //calculate additional body for special effects + m_pPlayer->pev->weaponanim = iAnim; + + // calculate additional body for special effects pev->body = (pev->body % NUM_HANDS) + NUM_HANDS * m_iBody; MESSAGE_BEGIN( MSG_ONE, gmsgWeaponAnim, NULL, m_pPlayer->pev ); diff --git a/spirit/world.cpp b/spirit/world.cpp index 329fe05c..8647b052 100644 --- a/spirit/world.cpp +++ b/spirit/world.cpp @@ -532,16 +532,6 @@ void CWorld :: Precache( void ) { ALERT ( at_debug, "**COULD NOT CREATE SOUNDENT**\n" ); } - - if( pev->target != 0 ) - { - SET_SKYBOX( STRING( pev->target )); - } - else - { - SET_SKYBOX( "desert" ); // it's a default Half-Life skybox, right ? - } - InitBodyQue(); // init sentence group playback stuff from sentences.txt. @@ -685,7 +675,7 @@ void CWorld :: KeyValue( KeyValueData *pkvd ) if( FStrEq( pkvd->szKeyName, "skyname" )) { // Sent over net now. - pev->target = ALLOC_STRING( pkvd->szValue ); + CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); pkvd->fHandled = TRUE; } else if ( FStrEq(pkvd->szKeyName, "sounds") )