From 871bec8990c8134675a03d6db29190bdd64ee2e6 Mon Sep 17 00:00:00 2001 From: g-cont Date: Sun, 4 Jan 2009 00:00:00 +0300 Subject: [PATCH] 04 Jan 2009 --- client/hud/hud.h | 2 + client/hud/hud_msg.cpp | 42 +++-- engine/client/cl_frame.c | 98 +++++++---- engine/client/cl_game.c | 58 ++----- engine/client/cl_view.c | 16 +- engine/client/client.h | 7 +- engine/common.h | 1 - engine/common/engfuncs.c | 22 +-- engine/common/net_msg.c | 3 +- engine/common/net_msg.h | 6 +- engine/server/sv_frame.c | 73 +++------ engine/server/sv_game.c | 19 ++- engine/server/sv_main.c | 2 - public/const.h | 1 + public/engine_api.h | 1 + public/entity_def.h | 5 +- public/render_api.h | 8 +- render/r_local.h | 11 +- render/r_main.c | 106 +++++++----- render/r_studio.c | 62 +++---- server/ents/baseweapon.cpp | 324 +++++++++++++++++++------------------ server/global/client.cpp | 5 +- server/global/dll_int.cpp | 1 - server/global/utils.cpp | 77 +++++---- server/global/utils.h | 3 +- todo.log | 2 + 26 files changed, 516 insertions(+), 439 deletions(-) diff --git a/client/hud/hud.h b/client/hud/hud.h index 4eb2af12..a2687a01 100644 --- a/client/hud/hud.h +++ b/client/hud/hud.h @@ -644,10 +644,12 @@ public: int _cdecl MsgFunc_CamData( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf ); + int _cdecl MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_AddScreen( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_AddMirror( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_AddPortal( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_Particle( const char *pszName, int iSize, void *pbuf ); + int _cdecl MsgFunc_TempEntity( const char *pszName, int iSize, void *pbuf ); // filled in VidInit struct diff --git a/client/hud/hud_msg.cpp b/client/hud/hud_msg.cpp index 2dbd927b..99210884 100644 --- a/client/hud/hud_msg.cpp +++ b/client/hud/hud_msg.cpp @@ -26,6 +26,7 @@ DECLARE_HUDMESSAGE( SetSky ); DECLARE_HUDMESSAGE( RainData ); DECLARE_HUDMESSAGE( SetBody ); DECLARE_HUDMESSAGE( SetSkin ); +DECLARE_HUDMESSAGE( WeaponAnim ); DECLARE_HUDMESSAGE( ResetHUD ); DECLARE_HUDMESSAGE( InitHUD ); DECLARE_HUDMESSAGE( ViewMode ); @@ -37,6 +38,7 @@ DECLARE_HUDMESSAGE( CamData ); DECLARE_HUDMESSAGE( AddMirror ); DECLARE_HUDMESSAGE( AddScreen ); DECLARE_HUDMESSAGE( AddPortal ); +DECLARE_HUDMESSAGE( TempEntity ); DECLARE_HUDMESSAGE( ServerName ); DECLARE_HUDMESSAGE( ScreenShake ); DECLARE_HUDMESSAGE( Intermission ); @@ -53,10 +55,12 @@ int CHud :: InitMessages( void ) HOOK_MESSAGE( Concuss ); HOOK_MESSAGE( HUDColor ); HOOK_MESSAGE( Particle ); + HOOK_MESSAGE( TempEntity ); HOOK_MESSAGE( SetFog ); HOOK_MESSAGE( SetSky ); HOOK_MESSAGE( CamData ); HOOK_MESSAGE( RainData ); + HOOK_MESSAGE( WeaponAnim ); HOOK_MESSAGE( SetBody ); HOOK_MESSAGE( SetSkin ); HOOK_MESSAGE( AddMirror); @@ -308,15 +312,25 @@ int CHud :: MsgFunc_RainData( const char *pszName, int iSize, void *pbuf ) return 1; } +int CHud :: MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf ) +{ + BEGIN_READ( pszName, iSize, pbuf ); + + edict_t *viewmodel = GetViewModel(); + viewmodel->v.sequence = READ_BYTE(); + viewmodel->v.effects |= EF_ANIMATE; + + END_READ(); + + return 1; +} + int CHud :: MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf ) { BEGIN_READ( pszName, iSize, pbuf ); - edict_t *viewmodel = GetViewModel(); - int body = READ_BYTE(); - - if( viewmodel ) - viewmodel->v.body = body; + edict_t *viewmodel = GetViewModel(); + viewmodel->v.body = READ_BYTE(); END_READ(); @@ -327,11 +341,8 @@ int CHud :: MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf ) { BEGIN_READ( pszName, iSize, pbuf ); - edict_t *viewmodel = GetViewModel(); - int skin = READ_BYTE(); - - if( viewmodel ) - viewmodel->v.skin = skin; + edict_t *viewmodel = GetViewModel(); + viewmodel->v.skin = READ_BYTE(); END_READ(); @@ -384,6 +395,17 @@ int CHud :: MsgFunc_Particle( const char *pszName, int iSize, void *pbuf ) return 1; } +int CHud :: MsgFunc_TempEntity( const char *pszName, int iSize, void *pbuf ) +{ + BEGIN_READ( pszName, iSize, pbuf ); + + // AddTempEntity( ... ); + + END_READ(); + + return 1; +} + int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf ) { char m_szServerName[32]; diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index d634ab12..25e4d429 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -15,14 +15,53 @@ FRAME PARSING */ void CL_UpdateEntityFields( edict_t *ent ) { + int i; + + // always keep an actual + ent->serialnumber = ent->pvClientData->current.number; + // copy state to progs ent->v.classname = cl.edict_classnames[ent->pvClientData->current.classname]; ent->v.modelindex = ent->pvClientData->current.model.index; ent->v.ambient = ent->pvClientData->current.soundindex; ent->v.model = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.model.index] ); + ent->v.weaponmodel = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.pmodel.index] ); + ent->v.frame = ent->pvClientData->current.model.frame; + ent->v.sequence = ent->pvClientData->current.model.sequence; + ent->v.gaitsequence = ent->pvClientData->current.model.gaitsequence; + ent->v.body = ent->pvClientData->current.model.body; + ent->v.skin = ent->pvClientData->current.model.skin; + VectorCopy( ent->pvClientData->current.rendercolor, ent->v.rendercolor ); + VectorCopy( ent->pvClientData->current.velocity, ent->v.velocity ); VectorCopy( ent->pvClientData->current.origin, ent->v.origin ); VectorCopy( ent->pvClientData->current.angles, ent->v.angles ); + VectorCopy( ent->pvClientData->prev.origin, ent->v.oldorigin ); + VectorCopy( ent->pvClientData->prev.angles, ent->v.oldangles ); + VectorCopy( ent->pvClientData->current.mins, ent->v.mins ); + VectorCopy( ent->pvClientData->current.maxs, ent->v.maxs ); + ent->v.framerate = ent->pvClientData->current.model.framerate; + ent->v.colormap = ent->pvClientData->current.model.colormap; + ent->v.rendermode = ent->pvClientData->current.rendermode; + ent->v.renderamt = ent->pvClientData->current.renderamt; + ent->v.renderfx = ent->pvClientData->current.renderfx; + ent->v.scale = ent->pvClientData->current.model.scale; ent->v.weapons = ent->pvClientData->current.weapons; + ent->v.gravity = ent->pvClientData->current.gravity; + ent->v.health = ent->pvClientData->current.health; + ent->v.solid = ent->pvClientData->current.solidtype; + ent->v.movetype = ent->pvClientData->current.movetype; + if( ent->v.scale == 0.0f ) ent->v.scale = 1.0f; + + for( i = 0; i < MAXSTUDIOBLENDS; i++ ) + ent->v.blending[i] = ent->pvClientData->current.model.blending[i]; + for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ ) + ent->v.controller[i] = ent->pvClientData->current.model.controller[i]; + + if( ent->pvClientData->current.aiment ) + ent->v.aiment = EDICT_NUM( ent->pvClientData->current.aiment ); + else ent->v.aiment = NULL; + + ent->v.pContainingEntity = ent; } /* @@ -238,35 +277,22 @@ void CL_ParseFrame( sizebuf_t *msg ) len = MSG_ReadByte( msg ); MSG_ReadData( msg, &cl.frame.areabits, len ); - if( sv_newprotocol->integer ) - { - // read clientindex - cmd = MSG_ReadByte( msg ); - if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not clientindex\n" ); - idx = MSG_ReadByte( msg ); - clent = EDICT_NUM( idx ); // get client - if((idx-1) != cl.playernum ) Host_Error("CL_ParseFrame: invalid playernum (%d should be %d)\n", idx-1, cl.playernum ); - } - else - { - // read playerinfo - cmd = MSG_ReadByte( msg ); - if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not playerinfo\n" ); - if( old ) MSG_ReadDeltaPlayerstate( msg, &old->ps, &cl.frame.ps ); - else MSG_ReadDeltaPlayerstate( msg, NULL, &cl.frame.ps ); - } + // read clientindex + cmd = MSG_ReadByte( msg ); + if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not clientindex\n" ); + idx = MSG_ReadByte( msg ); + clent = EDICT_NUM( idx ); // get client + if(( idx - 1 ) != cl.playernum ) + Host_Error("CL_ParseFrame: invalid playernum (%d should be %d)\n", idx-1, cl.playernum ); // read packet entities cmd = MSG_ReadByte( msg ); if( cmd != svc_packetentities ) Host_Error("CL_ParseFrame: not packetentities[%d]\n", cmd ); CL_ParsePacketEntities( msg, old, &cl.frame ); - if( sv_newprotocol->integer ) - { - // now we can reading delta player state - if( old ) cl.frame.ps = MSG_ParseDeltaPlayer( &old->ps, &clent->pvClientData->current ); - else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->pvClientData->current ); - } + // now we can reading delta player state + if( old ) cl.frame.ps = MSG_ParseDeltaPlayer( &old->ps, &clent->pvClientData->current ); + else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->pvClientData->current ); // FIXME if( cls.state == ca_cinematic || cls.demoplayback ) @@ -312,7 +338,8 @@ void CL_AddPacketEntities( frame_t *frame ) { s1 = &cl_parse_entities[(frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1)]; ent = EDICT_NUM( s1->number ); - re->AddRefEntity( &ent->pvClientData->current, &ent->pvClientData->prev, cl.refdef.lerpfrac ); + + re->AddRefEntity( ent, s1->ed_type, cl.refdef.lerpfrac ); } } @@ -323,20 +350,23 @@ CL_AddViewWeapon */ void CL_AddViewWeapon( entity_state_t *ps ) { - edict_t *view; // view model - // allow the gun to be completely removed if( !cl_gun->value ) return; // don't draw gun if in wide angle view if( ps->fov > 135 ) return; + if( !ps->viewmodel ) return; - view = EDICT_NUM( ps->aiment ); - VectorCopy( cl.refdef.vieworg, view->pvClientData->current.origin ); - VectorCopy( cl.refdef.viewangles, view->pvClientData->current.angles ); - VectorCopy( cl.refdef.vieworg, view->pvClientData->prev.origin ); - VectorCopy( cl.refdef.viewangles, view->pvClientData->prev.angles ); - re->AddRefEntity( &view->pvClientData->current, &view->pvClientData->prev, cl.refdef.lerpfrac ); + cl.viewent.v.scale = 1.0f; + cl.viewent.serialnumber = -1; + cl.viewent.v.framerate = 1.0f; + cl.viewent.v.effects |= EF_MINLIGHT; + cl.viewent.v.modelindex = ps->viewmodel; + VectorCopy( cl.refdef.vieworg, cl.viewent.v.origin ); + VectorCopy( cl.refdef.viewangles, cl.viewent.v.angles ); + VectorCopy( cl.refdef.vieworg, cl.viewent.v.oldorigin ); + VectorCopy( cl.refdef.viewangles, cl.viewent.v.oldangles ); + re->AddRefEntity( &cl.viewent, ED_VIEWMODEL, cl.refdef.lerpfrac ); } @@ -428,12 +458,12 @@ void CL_CalcViewValues( void ) // interpolate field of view cl.refdef.fov_x = ops->fov + lerp * ( ps->fov - ops->fov ); + clent = EDICT_NUM( cl.playernum + 1 ); // add the weapon CL_AddViewWeapon( ps ); - clent = EDICT_NUM( cl.playernum + 1 ); - cl.refdef.iWeaponBits = clent->v.weapons; + cl.refdef.iWeaponBits = ps->weapons; cls.dllFuncs.pfnUpdateClientData( &cl.refdef, (cl.time * 0.001f)); } diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index e557f235..69a634b9 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -17,9 +17,15 @@ CL_GetClientEntity Render callback for studio models ==================== */ -entity_state_t *CL_GetEdictByIndex( int index ) +edict_t *CL_GetEdictByIndex( int index ) { - return &EDICT_NUM( index )->pvClientData->current; + if( index < 0 || index > clgame.numEntities ) + { + if( index == -1 ) return &cl.viewent; + MsgDev( D_ERROR, "CL_GetEntityByIndex: invalid entindex %i\n", index ); + return NULL; + } + return EDICT_NUM( index ); } /* @@ -29,9 +35,9 @@ CL_GetLocalPlayer Render callback for studio models ==================== */ -entity_state_t *CL_GetLocalPlayer( void ) +edict_t *CL_GetLocalPlayer( void ) { - return &EDICT_NUM( cl.playernum + 1 )->pvClientData->current; + return EDICT_NUM( cl.playernum + 1 ); } /* @@ -505,7 +511,7 @@ void pfnClientCmd( const char *szCmdString ) /* ============= -pfnTextMessageGet +pfnGetPlayerInfo ============= */ @@ -519,13 +525,13 @@ void pfnGetPlayerInfo( int player_num, hud_player_info_t *pinfo ) /* ============= -pfnGetPlayerInfo +pfnTextMessageGet ============= */ client_textmessage_t *pfnTextMessageGet( const char *pName ) { - // FIXME: implement + // FIXME: implement or move to client.dll static client_textmessage_t null_msg; return &null_msg; @@ -739,33 +745,6 @@ void pfnGetViewAngles( float *angles ) VectorCopy( cl.refdef.viewangles, angles ); } -/* -============= -pfnGetEntityByIndex - -============= -*/ -edict_t* pfnGetEntityByIndex( int idx ) -{ - if( idx < 0 || idx > clgame.numEntities ) - { - MsgDev( D_ERROR, "CL_GetEntityByIndex: invalid entindex %i\n", idx ); - return EDICT_NUM( 0 ); - } - return EDICT_NUM( idx ); -} - -/* -============= -pfnGetLocalPlayer - -============= -*/ -edict_t* pfnGetLocalPlayer( void ) -{ - return EDICT_NUM( cl.playernum + 1 ); -} - /* ============= pfnIsSpectateOnly @@ -809,7 +788,7 @@ can return NULL */ edict_t* pfnGetViewModel( void ) { - return EDICT_NUM( cl.playernum + 1 )->v.aiment; + return &cl.viewent; } /* @@ -922,8 +901,8 @@ static cl_enginefuncs_t gEngfuncs = pfnGetImageSize, pfnSetDrawParms, pfnGetViewAngles, - pfnGetEntityByIndex, - pfnGetLocalPlayer, + CL_GetEdictByIndex, + CL_GetLocalPlayer, pfnIsSpectateOnly, pfnGetClientTime, pfnGetMaxClients, @@ -947,11 +926,8 @@ StudioEvent Event callback for studio models ==================== */ -void CL_StudioEvent( dstudioevent_t *event, entity_state_t *ent ) +void CL_StudioEvent( dstudioevent_t *event, edict_t *pEdict ) { - // do upcast - edict_t *pEdict = EDICT_NUM( ent->number ); - cls.dllFuncs.pfnStudioEvent( event, pEdict ); } diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index ac073068..8e431033 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -62,9 +62,9 @@ void V_TestEntities( void ) { int i, j; float f, r; - entity_state_t ent; + edict_t ent; - Mem_Set( &ent, 0, sizeof( entity_state_t )); + Mem_Set( &ent, 0, sizeof( edict_t )); V_ClearScene(); for( i = 0; i < 32; i++ ) @@ -73,12 +73,14 @@ void V_TestEntities( void ) f = 64 * (i/4) + 128; for( j = 0; j < 3; j++ ) - ent.origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r; + ent.v.origin[j] = cl.refdef.vieworg[j]+cl.refdef.forward[j] * f + cl.refdef.right[j] * r; - ent.model.controller[0] = ent.model.controller[1] = 90.0f; - ent.model.controller[2] = ent.model.controller[3] = 180.0f; - ent.model.index = cl.frame.ps.model.index; - re->AddRefEntity( &ent, NULL, 1.0f ); + ent.v.scale = 1.0f; + ent.serialnumber = cl.frame.ps.number; + ent.v.controller[0] = ent.v.controller[1] = 90.0f; + ent.v.controller[2] = ent.v.controller[3] = 180.0f; + ent.v.modelindex = cl.frame.ps.model.index; + re->AddRefEntity( &ent, ED_NORMAL, 1.0f ); } } diff --git a/engine/client/client.h b/engine/client/client.h index 74c9c900..d6aa775a 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -108,6 +108,7 @@ typedef struct dword time; // this is the time value that the client // is rendering at. always <= cls.realtime ref_params_t refdef; // shared refdef + edict_t viewent; // viewmodel // misc 2d drawing stuff int centerPrintTime; @@ -576,10 +577,10 @@ cdlight_t *CL_AllocDlight( int key ); void CL_AddParticles( void ); void CL_AddDecals( void ); void CL_ClearEffects( void ); -void CL_StudioEvent( dstudioevent_t *event, entity_state_t *ent ); +void CL_StudioEvent( dstudioevent_t *event, edict_t *ent ); void CL_AddDecal( vec3_t org, matrix3x3 m, shader_t s, vec4_t rgba, bool fade, decalFragment_t *df, const vec3_t *v ); -entity_state_t *CL_GetEdictByIndex( int index ); -entity_state_t *CL_GetLocalPlayer( void ); +edict_t *CL_GetEdictByIndex( int index ); +edict_t *CL_GetLocalPlayer( void ); void PF_addlight( void ); void PF_addparticle( void ); void PF_adddecal( void ); diff --git a/engine/common.h b/engine/common.h index ecb3473d..592fa61c 100644 --- a/engine/common.h +++ b/engine/common.h @@ -33,7 +33,6 @@ extern cvar_t *scr_loading; extern cvar_t *scr_download; extern cvar_t *scr_width; extern cvar_t *scr_height; -extern cvar_t *sv_newprotocol; /* ============================================================== diff --git a/engine/common/engfuncs.c b/engine/common/engfuncs.c index de1a64c6..63a7fb73 100644 --- a/engine/common/engfuncs.c +++ b/engine/common/engfuncs.c @@ -1352,7 +1352,7 @@ void VM_drawmodel( void ) const char *modname; int sequence; static ref_params_t refdef; - entity_state_t ent; + edict_t ent; static float frame; if(!VM_ValidateArgs( "drawmodel", 4 )) @@ -1382,17 +1382,17 @@ void VM_drawmodel( void ) re->ClearScene(); re->RegisterModel( modname, MAX_MODELS - 1 ); - ent.model.sequence = sequence; - ent.model.index = MAX_MODELS - 1; - ent.model.controller[0] = 127; - ent.model.controller[1] = 127; - ent.model.controller[2] = 127; - ent.model.controller[3] = 127; - VectorCopy( origin, ent.origin ); - VectorCopy( angles, ent.angles ); - ent.model.frame = frame += 0.7f; // FXIME: needs flag EF_AUTOANIMATE or somewhat + ent.v.sequence = sequence; + ent.v.modelindex = MAX_MODELS - 1; + ent.v.controller[0] = 127; + ent.v.controller[1] = 127; + ent.v.controller[2] = 127; + ent.v.controller[3] = 127; + VectorCopy( origin, ent.v.origin ); + VectorCopy( angles, ent.v.angles ); + ent.v.frame = frame += 0.7f; // FXIME: needs flag EF_AUTOANIMATE or somewhat - re->AddRefEntity( &ent, NULL, 1.0f ); + re->AddRefEntity( &ent, ED_NORMAL, 1.0f ); re->RenderFrame( &refdef ); } diff --git a/engine/common/net_msg.c b/engine/common/net_msg.c index 339061f0..0584d67a 100644 --- a/engine/common/net_msg.c +++ b/engine/common/net_msg.c @@ -9,7 +9,7 @@ static net_field_t ent_fields[] = { -{ ES_FIELD(ed_type), NET_CHAR, false }, // stateflags_t #0 (4 bytes) +{ ES_FIELD(ed_type), NET_BYTE, false }, // stateflags_t #0 (4 bytes) { ES_FIELD(classname), NET_WORD, false }, { ES_FIELD(soundindex), NET_WORD, false }, // 512 sounds ( OpenAL software limit is 255 ) { ES_FIELD(origin[0]), NET_FLOAT, false }, @@ -91,6 +91,7 @@ static net_field_t ent_fields[] = { ES_FIELD(viewoffset[1]), NET_SCALE, false }, { ES_FIELD(viewoffset[2]), NET_SCALE, false }, { ES_FIELD(maxspeed), NET_WORD, false }, +{ ES_FIELD(viewmodel), NET_WORD, false }, { ES_FIELD(fov), NET_FLOAT, false }, // client horizontal field of view { ES_FIELD(weapons), NET_LONG, false }, // client weapon 0-32 { ES_FIELD(health), NET_FLOAT, false }, // client health diff --git a/engine/common/net_msg.h b/engine/common/net_msg.h index 8d6cf8a8..36536f3b 100644 --- a/engine/common/net_msg.h +++ b/engine/common/net_msg.h @@ -69,9 +69,9 @@ enum clc_ops_e // engine messages clc_nop = 201, - clc_move, // [[usercmd_t] - clc_userinfo, // [[userinfo string] - clc_stringcmd, // [string] message + clc_move, // [[usercmd_t] + clc_userinfo, // [[userinfo string] + clc_stringcmd, // [string] message }; typedef enum diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index 6d45d85c..309079a9 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -46,7 +46,6 @@ Copy entvars into entity state */ void SV_UpdateEntityState( edict_t *ent ) { - edict_t *client; int i; // copy progs values to state @@ -59,15 +58,16 @@ void SV_UpdateEntityState( edict_t *ent ) ent->pvServerData->s.health = ent->v.health; ent->pvServerData->s.model.skin = ent->v.skin; // studio model skin ent->pvServerData->s.model.body = ent->v.body; // studio model submodel - ent->pvServerData->s.model.frame = ent->v.frame; // any model current frame ent->pvServerData->s.model.gaitsequence = ent->v.gaitsequence;// player sequence, that will be playing on client ent->pvServerData->s.effects = ent->v.effects; // shared client and render flags ent->pvServerData->s.renderfx = ent->v.renderfx; // renderer flags ent->pvServerData->s.rendermode = ent->v.rendermode; // rendering mode ent->pvServerData->s.renderamt = ent->v.renderamt; // alpha value - ent->pvServerData->s.model.framerate = ent->v.framerate; ent->pvServerData->s.model.animtime = (int)(1000.0 * ent->v.animtime) * 0.001; // sequence time ent->pvServerData->s.model.scale = ent->v.scale; // shared client and render flags + ent->pvServerData->s.movetype = ent->v.movetype; + ent->pvServerData->s.model.frame = ent->v.frame; // any model current frame + ent->pvServerData->s.model.framerate = ent->v.framerate; VectorCopy( ent->v.rendercolor, ent->pvServerData->s.rendercolor ); // studio model sequence @@ -80,35 +80,12 @@ void SV_UpdateEntityState( edict_t *ent ) ent->pvServerData->s.model.controller[i] = ent->v.controller[i]; } - if( ent->pvServerData->s.ed_type != ED_VIEWMODEL ) - ent->pvServerData->s.movetype = ent->v.movetype; - if( ent->pvServerData->s.ed_type == ED_MOVER || ent->pvServerData->s.ed_type == ED_BSPBRUSH ) { // these needs to right calculate direction of scroll texture VectorCopy( ent->v.movedir, ent->pvServerData->s.velocity ); } - - if( ent->pvServerData->s.ed_type == ED_VIEWMODEL ) - { - if( !ent->v.aiment ) return; // no aiment - - // copy v_model state from client to viemodel entity - client = ent->v.aiment; - - // update both arrays, because viewmodel are hidden for qc-coders - ent->v.modelindex = SV_ModelIndex( STRING( client->v.viewmodel )); - ent->pvServerData->s.aiment = NUM_FOR_EDICT( client ); // viewmodel parent - ent->pvServerData->s.model.index = ent->v.modelindex; - ent->pvServerData->s.model.frame = ent->v.frame = client->v.weaponframe; - ent->pvServerData->s.model.body = ent->v.body = client->v.weaponbody; - ent->pvServerData->s.model.skin = ent->v.skin = client->v.weaponskin; - ent->v.sequence = client->v.weaponsequence; - if( ent->v.sequence != -1 ) ent->pvServerData->s.model.sequence = ent->v.sequence; - ent->pvServerData->s.model.colormap = ent->v.colormap = client->v.colormap; - ent->pvServerData->s.effects |= EF_MINLIGHT; // always have some light - } - else if( ent->pvServerData->s.ed_type == ED_CLIENT ) + if( ent->pvServerData->s.ed_type == ED_CLIENT ) { if( ent->v.fixangle ) { @@ -122,6 +99,15 @@ void SV_UpdateEntityState( edict_t *ent ) // and clear fixangle for the next frame ent->v.fixangle = 0; } + + if( ent->v.viewmodel ) + ent->pvServerData->s.viewmodel = SV_ModelIndex( STRING( ent->v.viewmodel )); + else ent->pvServerData->s.viewmodel = 0; + + if( ent->v.aiment ) + ent->pvServerData->s.aiment = NUM_FOR_EDICT( ent->v.aiment ); + else ent->pvServerData->s.aiment = 0; + ent->pvServerData->s.weapons = ent->v.weapons; } else if( ent->pvServerData->s.ed_type == ED_AMBIENT ) @@ -274,14 +260,8 @@ static void SV_AddEntitiesToPacket( vec3_t origin, client_frame_t *frame, sv_ent if( ent->v.flags & FL_DORMANT ) continue; - // send viewmodel entity always - // NOTE: never apply LinkEdict to viewmodel entity, because - // we wan't see it in list of entities returned with SV_AreaEdicts - if( ent->pvServerData->s.ed_type == ED_VIEWMODEL ) - force = true; - // NOTE: client index on client expected that entity will be valid - if( sv_newprotocol->integer && ent->pvServerData->s.ed_type == ED_CLIENT ) + if( ent->pvServerData->s.ed_type == ED_CLIENT ) force = true; // never send entities that aren't linked in @@ -426,16 +406,8 @@ void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg ) // just send an client index // it's safe, because NUM_FOR_EDICT always equal ed->serialnumber, // thats shared across network - if( sv_newprotocol->integer ) - { - MSG_WriteByte( msg, svc_playerinfo ); - MSG_WriteByte( msg, frame->index ); - } - else - { - // delta encode the playerstate - MSG_WriteDeltaPlayerstate( &oldframe->ps, &frame->ps, msg ); - } + MSG_WriteByte( msg, svc_playerinfo ); + MSG_WriteByte( msg, frame->index ); // delta encode the entities SV_EmitPacketEntities( oldframe, frame, msg ); @@ -483,17 +455,8 @@ void SV_BuildClientFrame( sv_client_t *cl ) VectorCopy( clent->pvServerData->s.origin, org ); VectorAdd( org, clent->pvServerData->s.viewoffset, org ); - if( sv_newprotocol->integer ) - { - // grab the current player index - frame->index = NUM_FOR_EDICT( clent ); - } - else - { - // grab the current player state - cl->edict->pvServerData->framenum = sv.net_framenum; - frame->ps = clent->pvServerData->s; - } + // grab the current player index + frame->index = NUM_FOR_EDICT( clent ); // add all the entities directly visible to the eye, which // may include portal entities that merge other viewpoints diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 691af96e..4659e427 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -539,7 +539,9 @@ void SV_SetMassCentre( edict_t *ent ) void SV_SetModel( edict_t *ent, const char *name ) { int i; + cmodel_t *mod; vec3_t angles; + int mod_type = mod_bad; i = SV_ModelIndex( name ); if( i == 0 ) return; @@ -547,11 +549,22 @@ void SV_SetModel( edict_t *ent, const char *name ) ent->v.model = MAKE_STRING( sv.configstrings[CS_MODELS+i] ); ent->v.modelindex = i; - if( !pe->RegisterModel( name )) // precache sv.model - MsgDev( D_ERROR, "SV_SetModel: %s not found\n", name ); + mod = pe->RegisterModel( name ); // precache sv.model + if( !mod ) MsgDev( D_ERROR, "SV_SetModel: %s not found\n", name ); + else mod_type = mod->type; // can be changed from qc-code later - SV_SetMinMaxSize( ent, vec3_origin, vec3_origin, false ); + switch( mod_type ) + { + case mod_brush: + case mod_sprite: + SV_SetMinMaxSize( ent, mod->mins, mod->maxs, false ); + break; + case mod_studio: + case mod_bad: + SV_SetMinMaxSize( ent, vec3_origin, vec3_origin, false ); + break; + } switch( ent->v.movetype ) { diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 378df813..2ada553d 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -28,7 +28,6 @@ cvar_t *sv_rollspeed; cvar_t *sv_maxspeed; cvar_t *sv_accelerate; cvar_t *sv_friction; -cvar_t *sv_newprotocol; cvar_t *sv_physics; cvar_t *hostname; cvar_t *public_server; // should heartbeats be sent @@ -369,7 +368,6 @@ void SV_Init( void ) sv_maxspeed = Cvar_Get("sv_maxspeed", "320", 0, "maximum speed a player can accelerate to when on ground (can be exceeded by tricks)"); sv_accelerate = Cvar_Get( "sv_accelerate", "10", 0, "rate at which a player accelerates to sv_maxspeed" ); sv_friction = Cvar_Get( "sv_friction", "4", 0, "how fast you slow down" ); - sv_newprotocol = Cvar_Get( "sv_protocol", "0", CVAR_LATCH|CVAR_ARCHIVE, "using protocol version 0 or 1" ); sv_physics = Cvar_Get( "cm_physic", "1", CVAR_ARCHIVE|CVAR_LATCH, "change physic model: 0 - Classic Quake Physic, 1 - Physics Engine" ); public_server = Cvar_Get ("public", "0", 0, "change server type from private to public" ); diff --git a/public/const.h b/public/const.h index d5952ab2..bd99e7bd 100644 --- a/public/const.h +++ b/public/const.h @@ -98,6 +98,7 @@ typedef int shader_t; #define EF_ROTATE (1<<7) // rotate bonus item #define EF_MINLIGHT (1<<8) // allways have some light (viewmodel) #define EF_LIGHT (1<<9) // dynamic light (rockets use) +#define EF_ANIMATE (1<<10) // do client animate (ignore v.frame) // edict->deadflag values #define DEAD_NO 0 // alive diff --git a/public/engine_api.h b/public/engine_api.h index 814089a7..bf843f07 100644 --- a/public/engine_api.h +++ b/public/engine_api.h @@ -76,6 +76,7 @@ typedef struct entity_state_s vec3_t viewangles; // already calculated view angles on server-side vec3_t viewoffset; // viewoffset over ground int maxspeed; // sv_maxspeed will be duplicate on all clients + int viewmodel; // contains vmodel index float health; // client health (other parms can be send by custom messages) float fov; // horizontal field of view int weapons; // weapon flags diff --git a/public/entity_def.h b/public/entity_def.h index 434b8c85..274f3cd7 100644 --- a/public/entity_def.h +++ b/public/entity_def.h @@ -58,6 +58,7 @@ typedef struct entvars_s 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) + vec3_t attachment[16]; // server-client attachment actual coords float controller[16]; // bone controller setting (0..255) float blending[16]; // blending amount between sub-sequences (0..255) @@ -102,10 +103,6 @@ typedef struct entvars_s vec3_t v_angle; // viewing angle (player only) int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity string_t viewmodel; // player's viewmodel - float weaponframe; // viewmodel frame - int weaponsequence; - int weaponbody; // viewmodel body - int weaponskin; // viewmodel skin int gaitsequence; // movement animation sequence for player (0 for none) short colormap; // lowbyte topcolor, highbyte bottomcolor int playerclass; diff --git a/public/render_api.h b/public/render_api.h index 33ccba08..6b681928 100644 --- a/public/render_api.h +++ b/public/render_api.h @@ -45,7 +45,7 @@ typedef struct render_exp_s void (*EndRegistration)( const char *skyname ); // prepare frame to rendering - bool (*AddRefEntity)( entity_state_t *s1, entity_state_t *s2, float lerp ); + bool (*AddRefEntity)( edict_t *pRefEntity, int ed_type, float lerp ); bool (*AddDynLight)( vec3_t org, vec3_t color, float intensity ); bool (*AddParticle)( shader_t shader, const vec3_t p1, const vec3_t p2, float rad, float len, float rot, int col ); bool (*AddPolygon)( shader_t shader, int numVerts, const polyVert_t *verts ); @@ -77,12 +77,12 @@ typedef struct render_imp_s // client fundamental callbacks void (*UpdateScreen)( void ); // update screen while loading - void (*StudioEvent)( dstudioevent_t *event, entity_state_t *ent ); + void (*StudioEvent)( dstudioevent_t *event, edict_t *ent ); void (*AddDecal)( vec3_t org, matrix3x3 m, shader_t s, vec4_t rgba, bool fade, decalFragment_t *df, const vec3_t *v ); void (*ShowCollision)( cmdraw_t callback ); // debug long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam ); - entity_state_t *(*GetClientEdict)( int index ); - entity_state_t *(*GetLocalPlayer)( void ); + edict_t *(*GetClientEdict)( int index ); + edict_t *(*GetLocalPlayer)( void ); int (*GetMaxClients)( void ); } render_imp_t; diff --git a/render/r_local.h b/render/r_local.h index 47aa0b2a..c2779efa 100644 --- a/render/r_local.h +++ b/render/r_local.h @@ -497,13 +497,13 @@ typedef struct typedef struct latchedvars_s { - float animtime; + float animtime; // ??? float sequencetime; - vec3_t origin; + vec3_t origin; // edict->v.old_origin vec3_t angles; vec3_t gaitorigin; - int sequence; + int sequence; // ??? float frame; float blending[MAXSTUDIOBLENDS]; @@ -516,7 +516,7 @@ typedef struct latchedvars_s typedef struct ref_entity_s { edtype_t ent_type; // entity type - int index; // entity index + int index; // viewmodel has entindex -1 rmodel_t *model; // opaque type outside refresh rmodel_t *weaponmodel; // opaque type outside refresh @@ -562,7 +562,7 @@ typedef struct ref_entity_s float gaityaw; // local value // shader information - ref_shader_t *shader; + ref_shader_t *shader; float shaderTime; // subtracted from refdef time to control effect start times float radius; // bbox approximate radius float rotation; // what the hell ??? @@ -576,6 +576,7 @@ void R_ModelList_f( void ); void R_StudioInit( void ); void R_StudioShutdown( void ); bool R_StudioComputeBBox( vec3_t bbox[8] ); // for drawing bounds +void R_StudioResetSequenceInfo( ref_entity_t *ent, dstudiohdr_t *hdr ); void R_StudioSetupModel( int body, int bodypart ); void R_InitModels( void ); void R_ShutdownModels( void ); diff --git a/render/r_main.c b/render/r_main.c index e6cfb948..3c6fb4bd 100644 --- a/render/r_main.c +++ b/render/r_main.c @@ -1017,22 +1017,22 @@ void R_SetLightLevel( void ) R_AddEntityToScene ================= */ -static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float lerpfrac ) +static bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac ) { ref_entity_t *refent; int i; - if( !s1 || !s1->model.index ) return false; // if set to invisible, skip + if( !pRefEntity || !pRefEntity->v.modelindex ) + return false; // if set to invisible, skip if( r_numEntities >= MAX_ENTITIES ) return false; refent = &r_entities[r_numEntities]; - if( !s2 ) s2 = s1; // no lerping state - if( s1->effects & EF_NODRAW ) - return true; // done + if( pRefEntity->v.effects & EF_NODRAW ) + return true; // done // filter ents - switch( s1->ed_type ) + switch( ed_type ) { case ED_MOVER: case ED_CLIENT: @@ -1044,46 +1044,70 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le } // copy state to render - refent->frame = s1->model.frame; - refent->index = s1->number; - refent->ent_type = s1->ed_type; + refent->index = pRefEntity->serialnumber; + refent->ent_type = ed_type; refent->backlerp = 1.0f - lerpfrac; - refent->renderamt = s1->renderamt / 255.0f; - refent->rendermode = s1->rendermode; - refent->body = s1->model.body; - refent->sequence = s1->model.sequence; - refent->movetype = s1->movetype; - refent->scale = (s1->model.scale != 0.0f) ? s1->model.scale : 1.0f; - refent->colormap = s1->model.colormap; - refent->framerate = s1->model.framerate; - refent->effects = s1->effects; - refent->animtime = s1->model.animtime; - if( VectorIsNull( s1->rendercolor )) + refent->renderamt = pRefEntity->v.renderamt / 255.0f; + refent->rendermode = pRefEntity->v.rendermode; + refent->body = pRefEntity->v.body; + refent->scale = pRefEntity->v.scale; + refent->colormap = pRefEntity->v.colormap; + refent->framerate = pRefEntity->v.framerate; + refent->effects = pRefEntity->v.effects; + if( VectorIsNull( pRefEntity->v.rendercolor )) VectorSet( refent->rendercolor, 1.0f, 1.0f, 1.0f ); - else VectorDivide( s1->rendercolor, 255.0f, refent->rendercolor ); + else VectorDivide( pRefEntity->v.rendercolor, 255.0f, refent->rendercolor ); // setup latchedvars - refent->prev.frame = s2->model.frame; - refent->prev.animtime = s2->model.animtime; - VectorCopy( s2->origin, refent->prev.origin ); - VectorCopy( s2->angles, refent->prev.angles ); - refent->prev.sequence = s2->model.sequence; + VectorCopy( pRefEntity->v.oldorigin, refent->prev.origin ); + VectorCopy( pRefEntity->v.oldangles, refent->prev.angles ); // interpolate origin for( i = 0; i < 3; i++ ) - refent->origin[i] = LerpPoint( s2->origin[i], s1->origin[i], lerpfrac ); + refent->origin[i] = LerpPoint( pRefEntity->v.oldorigin[i], pRefEntity->v.origin[i], lerpfrac ); + + if( ed_type != ED_VIEWMODEL ) + { + refent->frame = pRefEntity->v.frame; + refent->movetype = pRefEntity->v.movetype; + refent->sequence = pRefEntity->v.sequence; + refent->animtime = pRefEntity->v.animtime; + + /* FIXME + refent->prev.animtime = pRefEntity->v.animtime; + refent->prev.sequencetime = pRefEntity->v.animtime - s2->model.animtime; + refent->prev.frame = s2->v.frame; + refent->prev.sequence = s2->model.sequence; + */ + } + else + { + if( !refent->model || !refent->model->phdr ) + return false; + + // update sequence only if finished or not equal current + if( pRefEntity->v.effects & EF_ANIMATE ) + { + Msg("SetSequence: %i\n", pRefEntity->v.sequence ); + refent->sequence = pRefEntity->v.sequence; + R_StudioResetSequenceInfo( refent, refent->model->phdr ); + pRefEntity->v.effects &= ~EF_ANIMATE; + } + } // set skin - refent->skin = s1->model.skin; - refent->model = cl_models[s1->model.index]; - refent->weaponmodel = cl_models[s1->pmodel.index]; - refent->renderfx = s1->renderfx; - refent->prev.sequencetime = s1->model.animtime - s2->model.animtime; + refent->skin = pRefEntity->v.skin; + refent->model = cl_models[pRefEntity->v.modelindex]; + refent->renderfx = pRefEntity->v.renderfx; + + // FIXME: + // refent->weaponmodel = cl_models[pRefEntity->v.modelindex]; + if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH ) { // store conveyor movedir in pev->velocity - VectorNormalize2( s1->velocity, refent->movedir ); + VectorNormalize2( pRefEntity->v.velocity, refent->movedir ); } // calculate angles @@ -1096,7 +1120,7 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le { // interpolate angles for( i = 0; i < 3; i++ ) - refent->angles[i] = LerpAngle( s2->angles[i], s1->angles[i], lerpfrac ); + refent->angles[i] = LerpAngle( pRefEntity->v.oldangles[i], pRefEntity->v.angles[i], lerpfrac ); } Matrix3x3_FromAngles( refent->angles, refent->matrix ); @@ -1104,19 +1128,23 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le // copy controllers for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ ) { - refent->controller[i] = s1->model.controller[i]; - refent->prev.controller[i] = s2->model.controller[i]; + refent->controller[i] = pRefEntity->v.controller[i]; + + // FIXME: + // refent->prev.controller[i] = s2->model.controller[i]; } // copy blends for( i = 0; i < MAXSTUDIOBLENDS; i++ ) { - refent->blending[i] = s1->model.blending[i]; - refent->prev.blending[i] = s2->model.blending[i]; + refent->blending[i] = pRefEntity->v.blending[i]; + + // FIXME: + // refent->prev.blending[i] = s2->model.blending[i]; } if( refent->ent_type == ED_CLIENT ) - refent->gaitsequence = s1->model.gaitsequence; + refent->gaitsequence = pRefEntity->v.gaitsequence; // because entity without models never added to scene if( !refent->ent_type ) diff --git a/render/r_studio.c b/render/r_studio.c index c83ca5d8..78052fa3 100644 --- a/render/r_studio.c +++ b/render/r_studio.c @@ -354,7 +354,7 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval { if( flInterval == 0.0 ) { - flInterval = (r_refdef.time - ent->animtime ); + flInterval = ( r_refdef.time - ent->animtime ); if( flInterval <= 0.001 ) { ent->animtime = r_refdef.time; @@ -376,17 +376,18 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval return flInterval; } -void R_StudioResetSequenceInfo( ref_entity_t *ent ) +void R_StudioResetSequenceInfo( ref_entity_t *ent, dstudiohdr_t *hdr ) { float m_flFrameRate; - R_StudioGetSequenceInfo( m_pStudioHeader, ent, &m_flFrameRate, NULL ); - ent->m_fSequenceLoops = ((R_StudioGetSequenceFlags( m_pStudioHeader, ent ) & STUDIO_LOOPING) != 0 ); + if( !ent || !hdr ) return; + + R_StudioGetSequenceInfo( hdr, ent, &m_flFrameRate, NULL ); + ent->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 ); // if custom framerate not specified, use default value from studiomodel - if( !ent->framerate ) ent->framerate = m_flFrameRate; + ent->framerate = m_flFrameRate; ent->animtime = r_refdef.time; - ent->framerate = 1.0; ent->m_fSequenceFinished = FALSE; } @@ -1381,7 +1382,7 @@ void R_StudioDrawMeshes( dstudiotexture_t * ptexture, short *pskinref, int pass VectorScale(m_plightcolor, lv_tmp, lv ); } } - + for( j = 0; j < m_pSubModel->nummesh; j++ ) { float s, t; @@ -1391,8 +1392,8 @@ void R_StudioDrawMeshes( dstudiotexture_t * ptexture, short *pskinref, int pass ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex); flags = ptexture[pskinref[pmesh->skinref]].flags; - s = 1.0/(float)ptexture[pskinref[pmesh->skinref]].width; - t = 1.0/(float)ptexture[pskinref[pmesh->skinref]].height; + s = 1.0 / (float)ptexture[pskinref[pmesh->skinref]].width; + t = 1.0 / (float)ptexture[pskinref[pmesh->skinref]].height; m_pCurrentShader = &r_shaders[ptexture[pskinref[pmesh->skinref]].shader]; @@ -1752,10 +1753,11 @@ bool R_StudioDrawModel( int pass, int flags ) return 0; // viewmodel animate on client - R_StudioFrameAdvance( m_pCurrentEntity, 1.0f, 0 ); + //if( !m_pCurrentEntity->m_fSequenceFinished ) + R_StudioFrameAdvance( m_pCurrentEntity, 1.0f, 0 ); - if( m_pCurrentEntity->m_fSequenceFinished ) - R_StudioResetSequenceInfo( m_pCurrentEntity ); + //if( m_pCurrentEntity->m_fSequenceFinished && m_pCurrentEntity->m_fSequenceLoops ) + // R_StudioResetSequenceInfo( m_pCurrentEntity, m_pStudioHeader ); } R_StudioSetupRender( pass ); @@ -1797,8 +1799,8 @@ bool R_StudioDrawModel( int pass, int flags ) if( m_pCurrentEntity->index > 0 ) { // copy attachments into global entity array - entity_state_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); - Mem_Copy( m_pCurrentEntity->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); + edict_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); + Mem_Copy( ent->v.attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); } } @@ -1843,7 +1845,7 @@ StudioEstimateGait ==================== */ -void R_StudioEstimateGait( entity_state_t *pplayer ) +void R_StudioEstimateGait( edict_t *pplayer ) { float dt; vec3_t est_velocity; @@ -1858,7 +1860,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer ) return; } - // VectorAdd( pplayer->velocity, pplayer->prediction_error, est_velocity ); + // VectorAdd( pplayer->v.velocity, pplayer->v.prediction_error, est_velocity ); if( m_fGaitEstimation ) { VectorSubtract( m_pCurrentEntity->origin, m_pCurrentEntity->prev.gaitorigin, est_velocity ); @@ -1874,7 +1876,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer ) } else { - VectorCopy( pplayer->velocity, est_velocity ); + VectorCopy( pplayer->v.velocity, est_velocity ); m_flGaitMovement = VectorLength( est_velocity ) * dt; } @@ -1908,7 +1910,7 @@ StudioProcessGait ==================== */ -void R_StudioProcessGait( entity_state_t *pplayer ) +void R_StudioProcessGait( edict_t *pplayer ) { dstudioseqdesc_t *pseqdesc; float dt, flYaw; // view direction relative to movement @@ -1968,10 +1970,10 @@ void R_StudioProcessGait( entity_state_t *pplayer ) if( m_pCurrentEntity->angles[YAW] < -0 ) m_pCurrentEntity->angles[YAW] += 360; m_pCurrentEntity->prev.angles[YAW] = m_pCurrentEntity->angles[YAW]; - if( pplayer->model.gaitsequence >= m_pStudioHeader->numseq ) - pplayer->model.gaitsequence = 0; + if( pplayer->v.gaitsequence >= m_pStudioHeader->numseq ) + pplayer->v.gaitsequence = 0; - pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->model.gaitsequence; + pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->v.gaitsequence; // calc gait frame if( pseqdesc->linearmovement[0] > 0 ) @@ -1996,12 +1998,12 @@ StudioDrawPlayer */ int R_StudioDrawPlayer( int pass, int flags ) { - entity_state_t *pplayer; + edict_t *pplayer; if( m_pCurrentEntity->ent_type == ED_CLIENT ) return 0; - if(!(flags & STUDIO_MIRROR)) + if( !( flags & STUDIO_MIRROR )) { //m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); } @@ -2010,20 +2012,20 @@ int R_StudioDrawPlayer( int pass, int flags ) R_StudioSetupRender( pass ); // MsgDev( D_INFO, "DrawPlayer %d\n", m_pCurrentEntity->blending[0] ); - // MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount, pplayer->number, m_pCurrentEntity->sequence ); - // MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", pplayer->velocity[0], pplayer->velocity[1], pplayer->velocity[2] ); + // MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount, pplayer->serialnumber, m_pCurrentEntity->sequence ); + // MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", pplayer->v.velocity[0], pplayer->v.velocity[1], pplayer->v.velocity[2] ); - if( pplayer->number < 0 || pplayer->number > ri.GetMaxClients()) + if( pplayer->serialnumber < 0 || pplayer->serialnumber > ri.GetMaxClients()) return 0; - if( pplayer->model.gaitsequence ) + if( pplayer->v.gaitsequence ) { vec3_t orig_angles; VectorCopy( m_pCurrentEntity->angles, orig_angles ); R_StudioProcessGait( pplayer ); - m_pCurrentEntity->gaitsequence = pplayer->model.gaitsequence; + m_pCurrentEntity->gaitsequence = pplayer->v.gaitsequence; R_StudioSetUpTransform( ); VectorCopy( orig_angles, m_pCurrentEntity->angles ); } @@ -2068,8 +2070,8 @@ int R_StudioDrawPlayer( int pass, int flags ) if( m_pCurrentEntity->index > 0 ) { // copy attachments into global entity array - entity_state_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); - Mem_Copy( m_pCurrentEntity->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); + edict_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); + Mem_Copy( ent->v.attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); } } diff --git a/server/ents/baseweapon.cpp b/server/ents/baseweapon.cpp index 1dfd3bd1..aa1eaf15 100644 --- a/server/ents/baseweapon.cpp +++ b/server/ents/baseweapon.cpp @@ -329,7 +329,7 @@ void CBasePlayerWeapon::DefaultTouch( CBaseEntity *pOther ) return; } - if (pOther->AddPlayerItem( this )) + if( pOther->AddPlayerItem( this )) { AttachToPlayer( pPlayer ); EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); @@ -344,8 +344,8 @@ void CBasePlayerWeapon :: ResetParse( ItemInfo *II ) m_iId = MAX_WEAPONS; //Will be owerwrite with GenerateID() II->iSlot = 0; II->iPosition = 0; - II->iViewModel = MAKE_STRING( "models/weapons/v_glock.mdl" ); - II->iWorldModel = MAKE_STRING( "models/weapons/w_glock.mdl" ); + II->iViewModel = iStringNull; + II->iWorldModel = iStringNull; strcpy( II->szAnimExt, "onehanded"); II->iszAmmo1 = MAKE_STRING( "none" ); II->iMaxAmmo1 = WEAPON_NOAMMO; @@ -739,11 +739,11 @@ int CBasePlayerWeapon :: PlaySequence( Activity activity, float fps ) //========================================================= int CBasePlayerWeapon :: SetAnimation( char *name, float fps ) { - if(!m_pPlayer->pev->viewmodel) return -1; - UTIL_SetModel( ENT(pev), STRING( m_pPlayer->pev->viewmodel )); + if( !m_pPlayer->pev->viewmodel ) return -1; + UTIL_SetModel( ENT( pev ), STRING( m_pPlayer->pev->viewmodel )); int iSequence = LookupSequence( name ); - if(iSequence != -1) SendWeaponAnim(iSequence, fps); - else DevMsg("Warning: Sequence \"%s\" not found\n", name); + if( iSequence != -1 ) SendWeaponAnim( iSequence, fps ); + else ALERT( at_warning, "sequence \"%s\" not found\n", name ); return iSequence; } @@ -759,15 +759,15 @@ int CBasePlayerWeapon :: SetAnimation( Activity activity, float fps ) if(!m_pPlayer->pev->viewmodel) return -1; UTIL_SetModel( ENT(pev), STRING( m_pPlayer->pev->viewmodel )); - //try to playing ACT sequence + // try to playing ACT sequence iSequence = LookupActivity( activity ); - if(iSequence != -1) + if( iSequence != -1 ) { - SendWeaponAnim(iSequence, fps); //activity method + SendWeaponAnim( iSequence, fps ); // activity method return iSequence; } - //ACT not found, translate name to ACT + // ACT not found, translate name to ACT switch ( activity ) { case ACT_VM_IDLE1: @@ -847,9 +847,9 @@ int CBasePlayerWeapon :: SetAnimation( Activity activity, float fps ) for(int i = 0; i < m_iAnimCount; i++ ) { iSequence = LookupSequence( pAnimsList[i] ); - if(iSequence != -1) + if( iSequence != -1 ) { - SendWeaponAnim(iSequence, fps); //names method + SendWeaponAnim (iSequence, fps ); // names method return iSequence; } } @@ -871,10 +871,9 @@ void CBasePlayerWeapon :: SendWeaponAnim( int sequence, float fps ) MESSAGE_BEGIN( MSG_ONE, gmsg.WeaponAnim, NULL, m_pPlayer->pev ); WRITE_BYTE( sequence ); - WRITE_BYTE( pev->body ); MESSAGE_END(); - if(pstudiohdr) + if( pstudiohdr ) { pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)sequence; if(fps) pseqdesc->fps = fps; @@ -892,20 +891,20 @@ BOOL CBasePlayerWeapon :: DefaultDeploy( Activity sequence ) if ( SUIT ) pev->body = TRUE; else pev->body = FALSE; - m_iClientSkin = -1;//reset last skin info for new weapon - m_iClientBody = -1;//reset last skin info for new weapon + m_iClientSkin = -1; // reset last skin info for new weapon + m_iClientBody = -1; // reset last skin info for new weapon m_pPlayer->pev->viewmodel = iViewModel(); m_pPlayer->pev->weaponmodel = iWorldModel(); - strcpy( m_pPlayer->m_szAnimExtention, szAnimExt() ); - - if(SetAnimation( sequence ) != -1) + strcpy( m_pPlayer->m_szAnimExtention, szAnimExt()); + + if( SetAnimation( sequence ) != -1 ) { - SetNextAttack(SequenceDuration() + 0.5);//delay before idle playing + SetNextAttack( SequenceDuration() + 0.5 );//delay before idle playing return TRUE; } - //animation not found + // animation not found return FALSE; } @@ -915,21 +914,22 @@ BOOL CBasePlayerWeapon :: DefaultHolster( Activity sequence ) int iResult = 0; iResult = SetAnimation( sequence ); - if(iResult == -1) return 0; + if( iResult == -1 ) return 0; - SetNextAttack(SequenceDuration() + 0.1);//delay before switching - if(m_pSpot)//disable laser dot + SetNextAttack( SequenceDuration() + 0.1 ); // delay before switching + if( m_pSpot ) // disable laser dot { - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_off.wav", 1, ATTN_NORM); + EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/spot_off.wav", 1, ATTN_NORM ); m_pSpot->Killed(); m_pSpot = NULL; } ZoomReset(); - m_iSkin = 0;//reset screen + m_iSkin = 0; // reset screen - if(iAttack1() == FLASHLIGHT || iAttack2() == FLASHLIGHT) ClearBits(m_pPlayer->pev->effects, EF_DIMLIGHT); + if( iAttack1() == FLASHLIGHT || iAttack2() == FLASHLIGHT ) + ClearBits( m_pPlayer->pev->effects, EF_DIMLIGHT ); - if ( (iFlags() & ITEM_FLAG_EXHAUSTIBLE) && (m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] <= 0) ) + if( (iFlags() & ITEM_FLAG_EXHAUSTIBLE) && (m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] <= 0) ) { // no more ammo! m_pPlayer->pev->weapons &= ~(1<m_rgAmmo[m_iPrimaryAmmoType] > 0 || iMaxAmmo1() == -1) { - //play random idle animation + // play random idle animation int iAnim; float flRand = RANDOM_FLOAT(0, 1.2); if (flRand < 0.2) iAnim = ACT_VM_IDLE1; @@ -970,59 +970,63 @@ void CBasePlayerWeapon :: DefaultIdle( void ) BOOL CBasePlayerWeapon :: DefaultReload( Activity sequence ) { - if (m_cActiveRocket && m_iSpot ) return FALSE; - if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase()) return FALSE; - if (m_flNextSecondaryAttack > UTIL_WeaponTimeBase()) return FALSE; - if(m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0)//have ammo? + if( m_cActiveRocket && m_iSpot ) + return FALSE; + if( m_flNextPrimaryAttack > UTIL_WeaponTimeBase()) + return FALSE; + if( m_flNextSecondaryAttack > UTIL_WeaponTimeBase()) + return FALSE; + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 ) // have ammo? { - if(iMaxClip() == m_iClip) return FALSE; - if (m_iStepReload == 0)//try to playing step reload + if( iMaxClip() == m_iClip ) return FALSE; + if( m_iStepReload == 0 ) // try to playing step reload { - if(SetAnimation( ACT_VM_START_RELOAD ) != -1) + if( SetAnimation( ACT_VM_START_RELOAD ) != -1 ) { - //found anim, continue + // found anim, continue m_iStepReload = 1; - m_fInReload = TRUE;//disable reload button - return TRUE;//start reload cycle. See also ItemPostFrame + m_fInReload = TRUE; // disable reload button + return TRUE; // start reload cycle. See also ItemPostFrame } else // init default reload { int i = min(iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - if (i == 0) return FALSE; + if( i == 0 ) return FALSE; int iResult = -1; - ZoomReset();//reset zoom - if(m_iClip <= 0)//empty clip ? + ZoomReset(); // reset zoom + if( m_iClip <= 0 ) // empty clip ? { - //iResult is error code + // iResult is error code iResult = SetAnimation( ACT_VM_RELOAD_EMPTY ); - m_iStepReload = EMPTY_RELOAD;//it's empty reload + m_iStepReload = EMPTY_RELOAD; // it's empty reload } - if(iResult == -1) + if( iResult == -1 ) { SetAnimation( sequence ); - m_iStepReload = NORMAL_RELOAD;//it's not empty reload + m_iStepReload = NORMAL_RELOAD; // it's not empty reload } - if(m_pSpot)m_pSpot->Suspend(SequenceDuration());//suspend laserdot - SetNextAttack(SequenceDuration()); - m_fInReload = TRUE;//disable reload button + if( m_pSpot ) m_pSpot->Suspend( SequenceDuration( )); // suspend laserdot + SetNextAttack( SequenceDuration( )); + m_fInReload = TRUE; // disable reload button - return TRUE;//that's all right + return TRUE; // that's all right } } - else if (m_iStepReload == 1)//continue step reload + else if( m_iStepReload == 1 ) // continue step reload { - if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase()) return FALSE; + if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase( )) + return FALSE; // was waiting for gun to move to side SetAnimation( sequence ); m_iStepReload = 2; } - else if (m_iStepReload == 2)//continue step reload + else if( m_iStepReload == 2 ) // continue step reload { - // Add them to the clip + // add them to the clip m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; m_iClip++; m_iStepReload = 1; - if(m_iClip == iMaxClip()) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1; + if( m_iClip == iMaxClip()) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1; } return TRUE; } @@ -1031,9 +1035,10 @@ BOOL CBasePlayerWeapon :: DefaultReload( Activity sequence ) BOOL CBasePlayerWeapon :: PlayEmptySound( void ) { - if (m_iPlayEmptySound) + if( m_iPlayEmptySound ) { - if(EmptySnd()) EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, STRING(EmptySnd()), 1, ATTN_NORM); + if( EmptySnd( )) + EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, STRING( EmptySnd( )), 1, ATTN_NORM ); m_iPlayEmptySound = 0; return TRUE; } @@ -1044,15 +1049,16 @@ BOOL CBasePlayerWeapon :: PlayEmptySound( void ) //========================================================= Vector CBasePlayerWeapon :: GetCurrentSpread( const char *ammo ) { - int iBullet = GetBulletType( ammo ); - if( iBullet == BULLET_9MM) return VECTOR_CONE_2DEGREES; - else if( iBullet == BULLET_357) return VECTOR_CONE_2DEGREES; - else if( iBullet == BULLET_556) return VECTOR_CONE_3DEGREES; - else if( iBullet == BULLET_762) return VECTOR_CONE_1DEGREES; - else if( iBullet == BULLET_12MM) return VECTOR_CONE_15DEGREES; - else if( iBullet == BULLET_BUCKSHOT) return VECTOR_CONE_10DEGREES; - - return VECTOR_CONE_0DEGREES; + switch( GetBulletType( ammo )) + { + case BULLET_9MM: return VECTOR_CONE_2DEGREES; + case BULLET_357: return VECTOR_CONE_2DEGREES; + case BULLET_556: return VECTOR_CONE_3DEGREES; + case BULLET_762: return VECTOR_CONE_1DEGREES; + case BULLET_12MM: return VECTOR_CONE_15DEGREES; + case BULLET_BUCKSHOT: return VECTOR_CONE_10DEGREES; + default: return VECTOR_CONE_0DEGREES; + } } int CBasePlayerWeapon :: GetBulletType( const char *ammo ) @@ -1080,10 +1086,10 @@ int CBasePlayerWeapon :: GetAmmoType( const char *ammo ) int CBasePlayerWeapon :: ReturnAmmoIndex( const char *ammo ) { const char *ammoname; - ammoname = m_pPlayer->GetAmmoName(m_iPrimaryAmmoType); - if(!stricmp( ammo, ammoname )) return m_iPrimaryAmmoType; - ammoname = m_pPlayer->GetAmmoName(m_iSecondaryAmmoType); - if(!stricmp( ammo, ammoname )) return m_iSecondaryAmmoType; + ammoname = m_pPlayer->GetAmmoName( m_iPrimaryAmmoType ); + if( !stricmp( ammo, ammoname )) return m_iPrimaryAmmoType; + ammoname = m_pPlayer->GetAmmoName( m_iSecondaryAmmoType ); + if( !stricmp( ammo, ammoname )) return m_iSecondaryAmmoType; return 0; } @@ -1093,7 +1099,7 @@ int CBasePlayerWeapon :: GetCurrentAttack( const char *ammo, int firemode ) if( !stricmp( ammo, "none" )) //no ammo { //just play animation and sound - if(!firemode) iResult = PlayRangeAttack();//anim is present ? + if(!firemode) iResult = PlayRangeAttack(); // anim is present ? else iResult = PlayMeleeAttack(); SetPlayerEffects( ammo, firemode ); @@ -1590,17 +1596,17 @@ void CBasePlayerWeapon::ZoomUpdate( void ) void CBasePlayerWeapon::ZoomReset( void ) { - //return viewmodel - if(m_iZoom) + // return viewmodel + if( m_iZoom ) { m_pPlayer->pev->viewmodel = iViewModel(); m_flHoldTime = UTIL_WeaponTimeBase() + 0.5; m_pPlayer->m_iFOV = 90; - m_iZoom = 0;//clear zoom + m_iZoom = 0; // clear zoom MESSAGE_BEGIN( MSG_ONE, gmsg.ZoomHUD, NULL, m_pPlayer->pev ); WRITE_BYTE( m_iZoom ); MESSAGE_END(); - m_pPlayer->UpdateClientData();//update client data manually + m_pPlayer->UpdateClientData(); // update client data manually } } @@ -1610,37 +1616,37 @@ void CBasePlayerWeapon::ZoomReset( void ) void CBasePlayerWeapon :: Deploy( void ) { m_iStepReload = 0; - if(iMaxClip() && m_iClip <= 0) //weapon have clip and clip is empty ? + if( iMaxClip() && m_iClip <= 0 ) // weapon have clip and clip is empty ? { - if(!DefaultDeploy(ACT_VM_DEPLOY_EMPTY)) //try to playing "deploy_empty" anim - DefaultDeploy(ACT_VM_DEPLOY); //custom animation not found, play standard animation + if(!DefaultDeploy( ACT_VM_DEPLOY_EMPTY ))// try to playing "deploy_empty" anim + DefaultDeploy( ACT_VM_DEPLOY );// custom animation not found, play standard animation } - else DefaultDeploy(ACT_VM_DEPLOY); //just playing standard anim + else DefaultDeploy( ACT_VM_DEPLOY ); // just playing standard anim } void CBasePlayerWeapon :: Holster( void ) { - if(iMaxClip() && m_iClip <= 0) //weapon have clip and clip is empty ? + if( iMaxClip() && m_iClip <= 0 ) // weapon have clip and clip is empty ? { - if(!DefaultHolster(ACT_VM_HOLSTER_EMPTY))//try to playing "holster_empty" anim - DefaultHolster(ACT_VM_HOLSTER); + if(!DefaultHolster(ACT_VM_HOLSTER_EMPTY))// try to playing "holster_empty" anim + DefaultHolster( ACT_VM_HOLSTER ); } - else DefaultHolster(ACT_VM_HOLSTER); //just playing standard anim + else DefaultHolster(ACT_VM_HOLSTER); // just playing standard anim } //========================================================= // NOT USED:HoldDown weapon //========================================================= -int CBasePlayerWeapon::FoundAlly( void ) +int CBasePlayerWeapon :: FoundAlly( void ) { CBaseEntity *pEntity = UTIL_FindEntityForward( m_pPlayer ); - if ( pEntity ) + if( pEntity ) { CBaseMonster *pMonster = pEntity->MyMonsterPointer(); - if ( pMonster ) + if( pMonster ) { int m_class = pMonster->Classify(); - if( m_class == CLASS_PLAYER_ALLY || m_class == CLASS_HUMAN_PASSIVE) + if( m_class == CLASS_PLAYER_ALLY || m_class == CLASS_HUMAN_PASSIVE ) { return 1; } @@ -1659,83 +1665,84 @@ void CBasePlayerWeapon::ItemPreFrame( void ) void CBasePlayerWeapon::ItemPostFrame( void ) { - if(!b_restored) + if( !b_restored ) { - m_iClientSkin = -1;//reset last skin info for new weapon - m_iClientBody = -1;//reset last skin info for new weapon - if(iMaxClip() && !m_iClip) SetAnimation(ACT_VM_IDLE_EMPTY); //restore last animation + m_iClientSkin = -1; // reset last skin info for new weapon + m_iClientBody = -1; // reset last skin info for new weapon + if( iMaxClip() && !m_iClip ) + SetAnimation( ACT_VM_IDLE_EMPTY ); // restore last animation else SetAnimation( ACT_VM_IDLE1 ); b_restored = TRUE; } - if(!m_iSpot && m_pSpot)//disable laser dot + if( !m_iSpot && m_pSpot ) // disable laser dot { - m_iSkin = 0; //disable screen - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_off.wav", 1, ATTN_NORM); + m_iSkin = 0; // disable screen + EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/spot_off.wav", 1, ATTN_NORM ); m_pSpot->Killed(); m_pSpot = NULL; } - if(m_iSpot && !m_pSpot)//enable laser dot + if( m_iSpot && !m_pSpot ) // enable laser dot { m_pSpot = CLaserSpot::CreateSpot(); - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM); - m_iSkin = 1; //enable screen + EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM ); + m_iSkin = 1; // enable screen } - if(m_pSpot) m_pSpot->Update( m_pPlayer ); + if( m_pSpot ) m_pSpot->Update( m_pPlayer ); - ZoomUpdate();//update zoom + ZoomUpdate(); // update zoom - if ( !m_iStepReload ) m_fInReload = FALSE;//reload done - if ( m_flTimeUpdate < UTIL_WeaponTimeBase() ) PostIdle(); //catch all - if (m_fInReload && m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase()) + if( !m_iStepReload ) m_fInReload = FALSE; // reload done + if( m_flTimeUpdate < UTIL_WeaponTimeBase()) PostIdle(); // catch all + if( m_fInReload && m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) { - if(m_iStepReload > 2) + if( m_iStepReload > 2 ) { // complete the reload. int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - // Add them to the clip + // add them to the clip m_iClip += j; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.01;//play PostReload - //m_iStepReload = 1; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.01; // play PostReload + // m_iStepReload = 1; m_fInReload = FALSE; } } - if ((m_pPlayer->pev->button & IN_ATTACK2) && CanAttack( m_flNextSecondaryAttack ) && !m_iOnControl) + if((m_pPlayer->pev->button & IN_ATTACK2) && CanAttack( m_flNextSecondaryAttack ) && !m_iOnControl ) { SecondaryAttack(); m_pPlayer->pev->button &= ~IN_ATTACK2; } - else if ((m_pPlayer->pev->button & IN_ATTACK) && CanAttack( m_flNextPrimaryAttack )) + else if((m_pPlayer->pev->button & IN_ATTACK) && CanAttack( m_flNextPrimaryAttack )) { - if(m_iOnControl == 1)//destroy controllable rocket + if( m_iOnControl == 1 ) // destroy controllable rocket { - m_iOnControl = 2;//destroy nuke + m_iOnControl = 2; // destroy nuke m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5; return; } PrimaryAttack(); m_pPlayer->pev->button &= ~IN_ATTACK; } - else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) + else if( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) { // reload when reload is pressed, or if no buttons are down and weapon is empty. Reload(); } - else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) ) + else if(!(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2))) { - //play sequence holster/deploy if player find or lose suit + // play sequence holster/deploy if player find or lose suit if( ((SUIT) && !PLAYER_HAS_SUIT) || (!(SUIT) && PLAYER_HAS_SUIT)) { m_pPlayer->m_pActiveItem->Holster( ); - m_pPlayer->QueueItem(this); - if (m_pPlayer->m_pActiveItem) m_pPlayer->m_pActiveItem->Deploy(); + m_pPlayer->QueueItem( this ); + if( m_pPlayer->m_pActiveItem ) m_pPlayer->m_pActiveItem->Deploy( ); } - if ( !CanDeploy() && m_flNextPrimaryAttack < gpGlobals->time ) + if( !CanDeploy() && m_flNextPrimaryAttack < gpGlobals->time ) { // weapon isn't useable, switch. - if ( !(iFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && g_pGameRules->GetNextBestWeapon( m_pPlayer, this ) ) + if( !(iFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && g_pGameRules->GetNextBestWeapon( m_pPlayer, this )) { m_flNextPrimaryAttack = gpGlobals->time + 0.3; return; @@ -1744,38 +1751,42 @@ void CBasePlayerWeapon::ItemPostFrame( void ) else { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing - if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->time ) + if( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->time ) { Reload(); return; } } - m_iPlayEmptySound = 1;//reset empty sound + m_iPlayEmptySound = 1; // reset empty sound if(iFlags() & ITEM_FLAG_USEAUTOAIM) m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); - if(m_flTimeWeaponIdle < UTIL_WeaponTimeBase())//step reload + if(m_flTimeWeaponIdle < UTIL_WeaponTimeBase()) // step reload { if (m_iStepReload > 0 ) { - if (m_iClip != iMaxClip() && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) Reload(); + if (m_iClip != iMaxClip() && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) + { + Reload(); + } else { // reload debounce has timed out - if(IsEmptyReload()) + if( IsEmptyReload()) { - if(SetAnimation( ACT_VM_PUMP_EMPTY ) == -1) + if( SetAnimation( ACT_VM_PUMP_EMPTY ) == -1 ) SetAnimation( ACT_VM_PUMP ); } else SetAnimation( ACT_VM_PUMP ); - if ( iFlags() & ITEM_FLAG_HIDEAMMO ) m_iBody = 0;//reset ammo - PostReload();//post effects + if( iFlags() & ITEM_FLAG_HIDEAMMO ) + m_iBody = 0; // reset ammo + PostReload(); // post effects m_iStepReload = 0; } } - else if ( m_iOnControl > 3 )//item deploy + else if( m_iOnControl > 3 ) // item deploy { m_iOnControl = 0; - if ( m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] ) + if( m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] ) { SetAnimation( ACT_VM_DEPLOY ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_LONG( 10, 15 ); @@ -1792,48 +1803,49 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) BOOL bSend = FALSE; int state = 0; - //update weapon body - if( m_iClientBody != m_iBody) + // update weapon body + if( m_iClientBody != m_iBody ) { - pev->body = (pev->body % NUM_HANDS) + NUM_HANDS * m_iBody; //calculate body + pev->body = (pev->body % NUM_HANDS) + NUM_HANDS * m_iBody; // calculate body MESSAGE_BEGIN( MSG_ONE, gmsg.SetBody, NULL, m_pPlayer->pev ); - WRITE_BYTE( pev->body ); //weaponmodel body + WRITE_BYTE( pev->body ); // weaponmodel body MESSAGE_END(); m_iClientBody = m_iBody;//synched } - //update weapon skin - if( m_iClientSkin != m_iSkin) + // update weapon skin + if( m_iClientSkin != m_iSkin ) { - pev->skin = m_iSkin; //calculate skin + pev->skin = m_iSkin; // calculate skin MESSAGE_BEGIN( MSG_ONE, gmsg.SetSkin, NULL, m_pPlayer->pev ); WRITE_BYTE( pev->skin ); //weaponmodel skin. MESSAGE_END(); m_iClientSkin = m_iSkin;//synched } - if ( pPlayer->m_pActiveItem == this ) + if( pPlayer->m_pActiveItem == this ) { - if ( pPlayer->m_fOnTarget ) state = 0x40;//weapon is ontarget - else state = 1; + if( pPlayer->m_fOnTarget ) + state = 0x40; // weapon is ontarget + else state = 1; } - // Forcing send of all data! - if ( !pPlayer->m_fWeapon ) bSend = TRUE; + // forcing send of all data! + if( !pPlayer->m_fWeapon ) bSend = TRUE; // This is the current or last weapon, so the state will need to be updated - if ( this == pPlayer->m_pActiveItem || this == pPlayer->m_pClientActiveItem ) + if( this == pPlayer->m_pActiveItem || this == pPlayer->m_pClientActiveItem ) { - if ( pPlayer->m_pActiveItem != pPlayer->m_pClientActiveItem ) bSend = TRUE; + if( pPlayer->m_pActiveItem != pPlayer->m_pClientActiveItem ) bSend = TRUE; } - // If the ammo, state, or fov has changed, update the weapon - if ( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_iFOV != pPlayer->m_iClientFOV ) + // if the ammo, state, or fov has changed, update the weapon + if( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_iFOV != pPlayer->m_iClientFOV ) { bSend = TRUE; } - if ( bSend ) + if( bSend ) { MESSAGE_BEGIN( MSG_ONE, gmsg.CurWeapon, NULL, pPlayer->pev ); WRITE_BYTE( state ); @@ -1846,7 +1858,7 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) pPlayer->m_fWeapon = TRUE; } - if ( m_pNext ) m_pNext->UpdateClientData( pPlayer ); + if( m_pNext ) m_pNext->UpdateClientData( pPlayer ); return 1; } @@ -1869,22 +1881,24 @@ void CBasePlayerWeapon::DestroyItem( void ) void CBasePlayerWeapon::Drop( void ) { SetTouch( NULL ); - SetThink(Remove); + SetThink( Remove ); SetNextThink( 0.1 ); } -void CBasePlayerWeapon::AttachToPlayer ( CBasePlayer *pPlayer ) +void CBasePlayerWeapon::AttachToPlayer( CBasePlayer *pPlayer ) { - SetObjectClass( ED_VIEWMODEL ); + SetObjectClass( ED_STATIC ); // disable client updates + + // make cross-links for consitency + pev->aiment = pPlayer->edict(); + pev->owner = pPlayer->edict(); pev->movetype = MOVETYPE_FOLLOW; pev->solid = SOLID_NOT; - pev->aiment = pPlayer->edict(); - pev->effects = EF_NODRAW; - pev->modelindex = 0; // server won't send down to clients if modelindex == 0 - pev->targetname = iStringNull; // don't try remove this weapon from map + pev->effects |= EF_NODRAW; + pev->modelindex = 0; // server won't send down to clients if modelindex == 0 + pev->targetname = iStringNull; // don't try remove this weapon from map pev->model = iStringNull; - pev->owner = pPlayer->edict(); SetNextThink( 0.1 ); SetTouch( NULL ); SetThink( NULL ); diff --git a/server/global/client.cpp b/server/global/client.cpp index e3376564..46bfaa8c 100644 --- a/server/global/client.cpp +++ b/server/global/client.cpp @@ -1044,7 +1044,7 @@ void LinkUserMessages( void ) gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -1 ); gmsg.RoomType = REG_USER_MSG( "RoomType", 2 ); gmsg.HideWeapon = REG_USER_MSG( "HideWeapon", 1 ); - gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 2 ); + gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 1 ); gmsg.SetFOV = REG_USER_MSG( "SetFOV", 1 ); gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 ); gmsg.Shake = REG_USER_MSG("ScreenShake", 13 ); @@ -1058,7 +1058,7 @@ void LinkUserMessages( void ) gmsg.ZoomHUD = REG_USER_MSG("ZoomHUD", 1); gmsg.WarHUD = REG_USER_MSG("WarHUD", 1); - //entity messages + // entity messages gmsg.StatusIcon = REG_USER_MSG("StatusIcon", -1); gmsg.CamData = REG_USER_MSG("CamData", -1); gmsg.Fsound = REG_USER_MSG("Fsound", -1); @@ -1067,6 +1067,7 @@ void LinkUserMessages( void ) gmsg.AddPortal = REG_USER_MSG( "AddPortal", 1); gmsg.HudText = REG_USER_MSG( "HudText", -1 ); gmsg.ShowGameTitle = REG_USER_MSG("GameTitle", 1); + gmsg.TempEntity = REG_USER_MSG( "TempEntity", 1); // FIXME gmsg.SetFog = REG_USER_MSG("SetFog", 7 ); gmsg.SetSky = REG_USER_MSG( "SetSky", 13 ); gmsg.Particle = REG_USER_MSG( "Particle", -1); diff --git a/server/global/dll_int.cpp b/server/global/dll_int.cpp index f71d69c2..54b8f1b3 100644 --- a/server/global/dll_int.cpp +++ b/server/global/dll_int.cpp @@ -103,7 +103,6 @@ int DispatchSpawn( edict_t *pent ) pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1); pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1); - pEntity->SetObjectClass(); // apply default value pEntity->Spawn(); pEntity = (CBaseEntity *)GET_PRIVATE(pent); diff --git a/server/global/utils.cpp b/server/global/utils.cpp index ac005b11..f8276e49 100644 --- a/server/global/utils.cpp +++ b/server/global/utils.cpp @@ -1005,53 +1005,55 @@ void UTIL_SetAvelocity ( CBaseEntity *pEnt, const Vector vecSet ) //======================================================================== // Precache and set resources - add check for present or invalid name -// Don't crash game if model not found or no specified +// NOTE: game will not crashed if model not specified, this code is legacy //======================================================================== -void UTIL_SetModel( edict_t *e, string_t s, char *c )//set default model if not found +void UTIL_SetModel( edict_t *e, string_t s, char *c ) // set default model if not found { - if (FStringNull( s )) UTIL_SetModel( e, c ); + if( FStringNull( s )) UTIL_SetModel( e, c ); else UTIL_SetModel( e, s ); } -void UTIL_SetModel( edict_t *e, string_t model ){ UTIL_SetModel( e, STRING(model)); } + +void UTIL_SetModel( edict_t *e, string_t model ) +{ + UTIL_SetModel( e, STRING( model )); +} + void UTIL_SetModel( edict_t *e, const char *model ) { - //if(g_serveractive && g_engfuncs.pfnModelIndex( model ) >= 0) return; - if(!model || !*model) + if( !model || !*model ) { - g_engfuncs.pfnSetModel(e, "models/common/null.mdl"); - return; - } - //is this brush model? - if (model[0] == '*') - { - g_engfuncs.pfnSetModel(e, model); + g_engfuncs.pfnSetModel( e, "models/common/null.mdl" ); return; } - //verify file exists - byte *data = LOAD_FILE((char*)model, NULL); - if (data) + // is this brush model? + if( model[0] == '*' ) { - FREE_FILE( data ); - g_engfuncs.pfnSetModel(e, model); + g_engfuncs.pfnSetModel( e, model ); return; } - int namelen = strlen(model) - 1; - if (model[namelen] == 'l') + // verify file exists + if( FILE_EXISTS( model )) { - //this is model - g_engfuncs.pfnSetModel(e, "models/common/error.mdl"); + g_engfuncs.pfnSetModel( e, model ); + return; } - else if (model[namelen] == 'r') + + if( !strcmp( UTIL_FileExtension( model ), "mdl" )) { - //this is sprite - g_engfuncs.pfnSetModel(e, "sprites/error.spr"); + // this is model + g_engfuncs.pfnSetModel(e, "models/common/error.mdl" ); + } + else if( !strcmp( UTIL_FileExtension( model ), "spr" )) + { + // this is sprite + g_engfuncs.pfnSetModel( e, "sprites/error.spr" ); } else { - //set null model - g_engfuncs.pfnSetModel(e, "models/common/null.mdl"); + // set null model + g_engfuncs.pfnSetModel( e, "models/common/null.mdl" ); } } @@ -2998,6 +3000,27 @@ void UTIL_LogPrintf( char *fmt, ... ) ALERT( at_logged, "%s", string ); } +//============ +// UTIL_FileExtension +// returns file extension +//============ +const char *UTIL_FileExtension( const char *in ) +{ + const char *separator, *backslash, *colon, *dot; + + separator = strrchr( in, '/' ); + backslash = strrchr( in, '\\' ); + if( !separator || separator < backslash ) + separator = backslash; + colon = strrchr( in, ':' ); + if( !separator || separator < colon ) + separator = colon; + dot = strrchr( in, '.' ); + if( dot == NULL || (separator && ( dot < separator ))) + return ""; + return dot + 1; +} + //========================================================= // UTIL_DotPoints - returns the dot product of a line from // src to check and vecdir. diff --git a/server/global/utils.h b/server/global/utils.h index ef9da65f..92d40889 100644 --- a/server/global/utils.h +++ b/server/global/utils.h @@ -447,7 +447,8 @@ extern char *UTIL_dtos3( int d ); extern char *UTIL_dtos4( int d ); // Writes message to console with timestamp and FragLog header. -extern void UTIL_LogPrintf( char *fmt, ... ); +extern void UTIL_LogPrintf( char *fmt, ... ); +extern const char *UTIL_FileExtension( const char *in ); // Sorta like FInViewCone, but for nonmonsters. extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); diff --git a/todo.log b/todo.log index 8d8d8dd3..fcf5b9ef 100644 --- a/todo.log +++ b/todo.log @@ -37,6 +37,8 @@ Beta 13.12.08 16.Copy Resources OK 17.тормоза на больших картах 18.weapon pickup & drawing +19.AddRefEntity uses edict_t instead entity state +20.render custom models entity_state_t невидима для пользователя