04 Jan 2009

This commit is contained in:
g-cont 2009-01-04 00:00:00 +03:00 committed by Alibek Omarov
parent 0d70770186
commit 871bec8990
26 changed files with 516 additions and 439 deletions

View File

@ -644,10 +644,12 @@ public:
int _cdecl MsgFunc_CamData( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_CamData( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_SetSkin( 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_AddScreen( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_AddMirror( 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_AddPortal( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Particle( 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 // filled in VidInit
struct struct

View File

@ -26,6 +26,7 @@ DECLARE_HUDMESSAGE( SetSky );
DECLARE_HUDMESSAGE( RainData ); DECLARE_HUDMESSAGE( RainData );
DECLARE_HUDMESSAGE( SetBody ); DECLARE_HUDMESSAGE( SetBody );
DECLARE_HUDMESSAGE( SetSkin ); DECLARE_HUDMESSAGE( SetSkin );
DECLARE_HUDMESSAGE( WeaponAnim );
DECLARE_HUDMESSAGE( ResetHUD ); DECLARE_HUDMESSAGE( ResetHUD );
DECLARE_HUDMESSAGE( InitHUD ); DECLARE_HUDMESSAGE( InitHUD );
DECLARE_HUDMESSAGE( ViewMode ); DECLARE_HUDMESSAGE( ViewMode );
@ -37,6 +38,7 @@ DECLARE_HUDMESSAGE( CamData );
DECLARE_HUDMESSAGE( AddMirror ); DECLARE_HUDMESSAGE( AddMirror );
DECLARE_HUDMESSAGE( AddScreen ); DECLARE_HUDMESSAGE( AddScreen );
DECLARE_HUDMESSAGE( AddPortal ); DECLARE_HUDMESSAGE( AddPortal );
DECLARE_HUDMESSAGE( TempEntity );
DECLARE_HUDMESSAGE( ServerName ); DECLARE_HUDMESSAGE( ServerName );
DECLARE_HUDMESSAGE( ScreenShake ); DECLARE_HUDMESSAGE( ScreenShake );
DECLARE_HUDMESSAGE( Intermission ); DECLARE_HUDMESSAGE( Intermission );
@ -53,10 +55,12 @@ int CHud :: InitMessages( void )
HOOK_MESSAGE( Concuss ); HOOK_MESSAGE( Concuss );
HOOK_MESSAGE( HUDColor ); HOOK_MESSAGE( HUDColor );
HOOK_MESSAGE( Particle ); HOOK_MESSAGE( Particle );
HOOK_MESSAGE( TempEntity );
HOOK_MESSAGE( SetFog ); HOOK_MESSAGE( SetFog );
HOOK_MESSAGE( SetSky ); HOOK_MESSAGE( SetSky );
HOOK_MESSAGE( CamData ); HOOK_MESSAGE( CamData );
HOOK_MESSAGE( RainData ); HOOK_MESSAGE( RainData );
HOOK_MESSAGE( WeaponAnim );
HOOK_MESSAGE( SetBody ); HOOK_MESSAGE( SetBody );
HOOK_MESSAGE( SetSkin ); HOOK_MESSAGE( SetSkin );
HOOK_MESSAGE( AddMirror); HOOK_MESSAGE( AddMirror);
@ -308,15 +312,25 @@ int CHud :: MsgFunc_RainData( const char *pszName, int iSize, void *pbuf )
return 1; 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 ) int CHud :: MsgFunc_SetBody( const char *pszName, int iSize, void *pbuf )
{ {
BEGIN_READ( pszName, iSize, pbuf ); BEGIN_READ( pszName, iSize, pbuf );
edict_t *viewmodel = GetViewModel(); edict_t *viewmodel = GetViewModel();
int body = READ_BYTE(); viewmodel->v.body = READ_BYTE();
if( viewmodel )
viewmodel->v.body = body;
END_READ(); END_READ();
@ -327,11 +341,8 @@ int CHud :: MsgFunc_SetSkin( const char *pszName, int iSize, void *pbuf )
{ {
BEGIN_READ( pszName, iSize, pbuf ); BEGIN_READ( pszName, iSize, pbuf );
edict_t *viewmodel = GetViewModel(); edict_t *viewmodel = GetViewModel();
int skin = READ_BYTE(); viewmodel->v.skin = READ_BYTE();
if( viewmodel )
viewmodel->v.skin = skin;
END_READ(); END_READ();
@ -384,6 +395,17 @@ int CHud :: MsgFunc_Particle( const char *pszName, int iSize, void *pbuf )
return 1; 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 ) int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
{ {
char m_szServerName[32]; char m_szServerName[32];

View File

@ -15,14 +15,53 @@ FRAME PARSING
*/ */
void CL_UpdateEntityFields( edict_t *ent ) void CL_UpdateEntityFields( edict_t *ent )
{ {
int i;
// always keep an actual
ent->serialnumber = ent->pvClientData->current.number;
// copy state to progs // copy state to progs
ent->v.classname = cl.edict_classnames[ent->pvClientData->current.classname]; ent->v.classname = cl.edict_classnames[ent->pvClientData->current.classname];
ent->v.modelindex = ent->pvClientData->current.model.index; ent->v.modelindex = ent->pvClientData->current.model.index;
ent->v.ambient = ent->pvClientData->current.soundindex; ent->v.ambient = ent->pvClientData->current.soundindex;
ent->v.model = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.model.index] ); 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.origin, ent->v.origin );
VectorCopy( ent->pvClientData->current.angles, ent->v.angles ); 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.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 ); len = MSG_ReadByte( msg );
MSG_ReadData( msg, &cl.frame.areabits, len ); MSG_ReadData( msg, &cl.frame.areabits, len );
if( sv_newprotocol->integer ) // read clientindex
{ cmd = MSG_ReadByte( msg );
// read clientindex if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not clientindex\n" );
cmd = MSG_ReadByte( msg ); idx = MSG_ReadByte( msg );
if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not clientindex\n" ); clent = EDICT_NUM( idx ); // get client
idx = MSG_ReadByte( msg ); if(( idx - 1 ) != cl.playernum )
clent = EDICT_NUM( idx ); // get client Host_Error("CL_ParseFrame: invalid playernum (%d should be %d)\n", idx-1, cl.playernum );
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 packet entities // read packet entities
cmd = MSG_ReadByte( msg ); cmd = MSG_ReadByte( msg );
if( cmd != svc_packetentities ) Host_Error("CL_ParseFrame: not packetentities[%d]\n", cmd ); if( cmd != svc_packetentities ) Host_Error("CL_ParseFrame: not packetentities[%d]\n", cmd );
CL_ParsePacketEntities( msg, old, &cl.frame ); 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 );
// now we can reading delta player state else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->pvClientData->current );
if( old ) cl.frame.ps = MSG_ParseDeltaPlayer( &old->ps, &clent->pvClientData->current );
else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->pvClientData->current );
}
// FIXME // FIXME
if( cls.state == ca_cinematic || cls.demoplayback ) 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)]; s1 = &cl_parse_entities[(frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1)];
ent = EDICT_NUM( s1->number ); 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 ) void CL_AddViewWeapon( entity_state_t *ps )
{ {
edict_t *view; // view model
// allow the gun to be completely removed // allow the gun to be completely removed
if( !cl_gun->value ) return; if( !cl_gun->value ) return;
// don't draw gun if in wide angle view // don't draw gun if in wide angle view
if( ps->fov > 135 ) return; if( ps->fov > 135 ) return;
if( !ps->viewmodel ) return;
view = EDICT_NUM( ps->aiment ); cl.viewent.v.scale = 1.0f;
VectorCopy( cl.refdef.vieworg, view->pvClientData->current.origin ); cl.viewent.serialnumber = -1;
VectorCopy( cl.refdef.viewangles, view->pvClientData->current.angles ); cl.viewent.v.framerate = 1.0f;
VectorCopy( cl.refdef.vieworg, view->pvClientData->prev.origin ); cl.viewent.v.effects |= EF_MINLIGHT;
VectorCopy( cl.refdef.viewangles, view->pvClientData->prev.angles ); cl.viewent.v.modelindex = ps->viewmodel;
re->AddRefEntity( &view->pvClientData->current, &view->pvClientData->prev, cl.refdef.lerpfrac ); 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 // interpolate field of view
cl.refdef.fov_x = ops->fov + lerp * ( ps->fov - ops->fov ); cl.refdef.fov_x = ops->fov + lerp * ( ps->fov - ops->fov );
clent = EDICT_NUM( cl.playernum + 1 );
// add the weapon // add the weapon
CL_AddViewWeapon( ps ); CL_AddViewWeapon( ps );
clent = EDICT_NUM( cl.playernum + 1 ); cl.refdef.iWeaponBits = ps->weapons;
cl.refdef.iWeaponBits = clent->v.weapons;
cls.dllFuncs.pfnUpdateClientData( &cl.refdef, (cl.time * 0.001f)); cls.dllFuncs.pfnUpdateClientData( &cl.refdef, (cl.time * 0.001f));
} }

View File

@ -17,9 +17,15 @@ CL_GetClientEntity
Render callback for studio models 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 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 ) client_textmessage_t *pfnTextMessageGet( const char *pName )
{ {
// FIXME: implement // FIXME: implement or move to client.dll
static client_textmessage_t null_msg; static client_textmessage_t null_msg;
return &null_msg; return &null_msg;
@ -739,33 +745,6 @@ void pfnGetViewAngles( float *angles )
VectorCopy( cl.refdef.viewangles, 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 pfnIsSpectateOnly
@ -809,7 +788,7 @@ can return NULL
*/ */
edict_t* pfnGetViewModel( void ) 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, pfnGetImageSize,
pfnSetDrawParms, pfnSetDrawParms,
pfnGetViewAngles, pfnGetViewAngles,
pfnGetEntityByIndex, CL_GetEdictByIndex,
pfnGetLocalPlayer, CL_GetLocalPlayer,
pfnIsSpectateOnly, pfnIsSpectateOnly,
pfnGetClientTime, pfnGetClientTime,
pfnGetMaxClients, pfnGetMaxClients,
@ -947,11 +926,8 @@ StudioEvent
Event callback for studio models 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 ); cls.dllFuncs.pfnStudioEvent( event, pEdict );
} }

View File

@ -62,9 +62,9 @@ void V_TestEntities( void )
{ {
int i, j; int i, j;
float f, r; 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(); V_ClearScene();
for( i = 0; i < 32; i++ ) for( i = 0; i < 32; i++ )
@ -73,12 +73,14 @@ void V_TestEntities( void )
f = 64 * (i/4) + 128; f = 64 * (i/4) + 128;
for( j = 0; j < 3; j++ ) 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.v.scale = 1.0f;
ent.model.controller[2] = ent.model.controller[3] = 180.0f; ent.serialnumber = cl.frame.ps.number;
ent.model.index = cl.frame.ps.model.index; ent.v.controller[0] = ent.v.controller[1] = 90.0f;
re->AddRefEntity( &ent, NULL, 1.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 );
} }
} }

View File

@ -108,6 +108,7 @@ typedef struct
dword time; // this is the time value that the client dword time; // this is the time value that the client
// is rendering at. always <= cls.realtime // is rendering at. always <= cls.realtime
ref_params_t refdef; // shared refdef ref_params_t refdef; // shared refdef
edict_t viewent; // viewmodel
// misc 2d drawing stuff // misc 2d drawing stuff
int centerPrintTime; int centerPrintTime;
@ -576,10 +577,10 @@ cdlight_t *CL_AllocDlight( int key );
void CL_AddParticles( void ); void CL_AddParticles( void );
void CL_AddDecals( void ); void CL_AddDecals( void );
void CL_ClearEffects( 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 ); 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 ); edict_t *CL_GetEdictByIndex( int index );
entity_state_t *CL_GetLocalPlayer( void ); edict_t *CL_GetLocalPlayer( void );
void PF_addlight( void ); void PF_addlight( void );
void PF_addparticle( void ); void PF_addparticle( void );
void PF_adddecal( void ); void PF_adddecal( void );

View File

@ -33,7 +33,6 @@ extern cvar_t *scr_loading;
extern cvar_t *scr_download; extern cvar_t *scr_download;
extern cvar_t *scr_width; extern cvar_t *scr_width;
extern cvar_t *scr_height; extern cvar_t *scr_height;
extern cvar_t *sv_newprotocol;
/* /*
============================================================== ==============================================================

View File

@ -1352,7 +1352,7 @@ void VM_drawmodel( void )
const char *modname; const char *modname;
int sequence; int sequence;
static ref_params_t refdef; static ref_params_t refdef;
entity_state_t ent; edict_t ent;
static float frame; static float frame;
if(!VM_ValidateArgs( "drawmodel", 4 )) if(!VM_ValidateArgs( "drawmodel", 4 ))
@ -1382,17 +1382,17 @@ void VM_drawmodel( void )
re->ClearScene(); re->ClearScene();
re->RegisterModel( modname, MAX_MODELS - 1 ); re->RegisterModel( modname, MAX_MODELS - 1 );
ent.model.sequence = sequence; ent.v.sequence = sequence;
ent.model.index = MAX_MODELS - 1; ent.v.modelindex = MAX_MODELS - 1;
ent.model.controller[0] = 127; ent.v.controller[0] = 127;
ent.model.controller[1] = 127; ent.v.controller[1] = 127;
ent.model.controller[2] = 127; ent.v.controller[2] = 127;
ent.model.controller[3] = 127; ent.v.controller[3] = 127;
VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.v.origin );
VectorCopy( angles, ent.angles ); VectorCopy( angles, ent.v.angles );
ent.model.frame = frame += 0.7f; // FXIME: needs flag EF_AUTOANIMATE or somewhat 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 ); re->RenderFrame( &refdef );
} }

View File

@ -9,7 +9,7 @@
static net_field_t ent_fields[] = 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(classname), NET_WORD, false },
{ ES_FIELD(soundindex), NET_WORD, false }, // 512 sounds ( OpenAL software limit is 255 ) { ES_FIELD(soundindex), NET_WORD, false }, // 512 sounds ( OpenAL software limit is 255 )
{ ES_FIELD(origin[0]), NET_FLOAT, false }, { 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[1]), NET_SCALE, false },
{ ES_FIELD(viewoffset[2]), NET_SCALE, false }, { ES_FIELD(viewoffset[2]), NET_SCALE, false },
{ ES_FIELD(maxspeed), NET_WORD, 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(fov), NET_FLOAT, false }, // client horizontal field of view
{ ES_FIELD(weapons), NET_LONG, false }, // client weapon 0-32 { ES_FIELD(weapons), NET_LONG, false }, // client weapon 0-32
{ ES_FIELD(health), NET_FLOAT, false }, // client health { ES_FIELD(health), NET_FLOAT, false }, // client health

View File

@ -69,9 +69,9 @@ enum clc_ops_e
// engine messages // engine messages
clc_nop = 201, clc_nop = 201,
clc_move, // [[usercmd_t] clc_move, // [[usercmd_t]
clc_userinfo, // [[userinfo string] clc_userinfo, // [[userinfo string]
clc_stringcmd, // [string] message clc_stringcmd, // [string] message
}; };
typedef enum typedef enum

View File

@ -46,7 +46,6 @@ Copy entvars into entity state
*/ */
void SV_UpdateEntityState( edict_t *ent ) void SV_UpdateEntityState( edict_t *ent )
{ {
edict_t *client;
int i; int i;
// copy progs values to state // 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.health = ent->v.health;
ent->pvServerData->s.model.skin = ent->v.skin; // studio model skin 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.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.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.effects = ent->v.effects; // shared client and render flags
ent->pvServerData->s.renderfx = ent->v.renderfx; // renderer flags ent->pvServerData->s.renderfx = ent->v.renderfx; // renderer flags
ent->pvServerData->s.rendermode = ent->v.rendermode; // rendering mode ent->pvServerData->s.rendermode = ent->v.rendermode; // rendering mode
ent->pvServerData->s.renderamt = ent->v.renderamt; // alpha value 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.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.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 ); VectorCopy( ent->v.rendercolor, ent->pvServerData->s.rendercolor );
// studio model sequence // studio model sequence
@ -80,35 +80,12 @@ void SV_UpdateEntityState( edict_t *ent )
ent->pvServerData->s.model.controller[i] = ent->v.controller[i]; 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 ) if( ent->pvServerData->s.ed_type == ED_MOVER || ent->pvServerData->s.ed_type == ED_BSPBRUSH )
{ {
// these needs to right calculate direction of scroll texture // these needs to right calculate direction of scroll texture
VectorCopy( ent->v.movedir, ent->pvServerData->s.velocity ); VectorCopy( ent->v.movedir, ent->pvServerData->s.velocity );
} }
if( ent->pvServerData->s.ed_type == ED_CLIENT )
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->v.fixangle ) if( ent->v.fixangle )
{ {
@ -122,6 +99,15 @@ void SV_UpdateEntityState( edict_t *ent )
// and clear fixangle for the next frame // and clear fixangle for the next frame
ent->v.fixangle = 0; 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; ent->pvServerData->s.weapons = ent->v.weapons;
} }
else if( ent->pvServerData->s.ed_type == ED_AMBIENT ) 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 ) if( ent->v.flags & FL_DORMANT )
continue; 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 // 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; force = true;
// never send entities that aren't linked in // 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 // just send an client index
// it's safe, because NUM_FOR_EDICT always equal ed->serialnumber, // it's safe, because NUM_FOR_EDICT always equal ed->serialnumber,
// thats shared across network // thats shared across network
if( sv_newprotocol->integer ) MSG_WriteByte( msg, svc_playerinfo );
{ MSG_WriteByte( msg, frame->index );
MSG_WriteByte( msg, svc_playerinfo );
MSG_WriteByte( msg, frame->index );
}
else
{
// delta encode the playerstate
MSG_WriteDeltaPlayerstate( &oldframe->ps, &frame->ps, msg );
}
// delta encode the entities // delta encode the entities
SV_EmitPacketEntities( oldframe, frame, msg ); SV_EmitPacketEntities( oldframe, frame, msg );
@ -483,17 +455,8 @@ void SV_BuildClientFrame( sv_client_t *cl )
VectorCopy( clent->pvServerData->s.origin, org ); VectorCopy( clent->pvServerData->s.origin, org );
VectorAdd( org, clent->pvServerData->s.viewoffset, org ); VectorAdd( org, clent->pvServerData->s.viewoffset, org );
if( sv_newprotocol->integer ) // grab the current player index
{ frame->index = NUM_FOR_EDICT( clent );
// 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;
}
// add all the entities directly visible to the eye, which // add all the entities directly visible to the eye, which
// may include portal entities that merge other viewpoints // may include portal entities that merge other viewpoints

View File

@ -539,7 +539,9 @@ void SV_SetMassCentre( edict_t *ent )
void SV_SetModel( edict_t *ent, const char *name ) void SV_SetModel( edict_t *ent, const char *name )
{ {
int i; int i;
cmodel_t *mod;
vec3_t angles; vec3_t angles;
int mod_type = mod_bad;
i = SV_ModelIndex( name ); i = SV_ModelIndex( name );
if( i == 0 ) return; 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.model = MAKE_STRING( sv.configstrings[CS_MODELS+i] );
ent->v.modelindex = i; ent->v.modelindex = i;
if( !pe->RegisterModel( name )) // precache sv.model mod = pe->RegisterModel( name ); // precache sv.model
MsgDev( D_ERROR, "SV_SetModel: %s not found\n", name ); if( !mod ) MsgDev( D_ERROR, "SV_SetModel: %s not found\n", name );
else mod_type = mod->type;
// can be changed from qc-code later // 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 ) switch( ent->v.movetype )
{ {

View File

@ -28,7 +28,6 @@ cvar_t *sv_rollspeed;
cvar_t *sv_maxspeed; cvar_t *sv_maxspeed;
cvar_t *sv_accelerate; cvar_t *sv_accelerate;
cvar_t *sv_friction; cvar_t *sv_friction;
cvar_t *sv_newprotocol;
cvar_t *sv_physics; cvar_t *sv_physics;
cvar_t *hostname; cvar_t *hostname;
cvar_t *public_server; // should heartbeats be sent 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_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_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_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" ); 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" ); public_server = Cvar_Get ("public", "0", 0, "change server type from private to public" );

View File

@ -98,6 +98,7 @@ typedef int shader_t;
#define EF_ROTATE (1<<7) // rotate bonus item #define EF_ROTATE (1<<7) // rotate bonus item
#define EF_MINLIGHT (1<<8) // allways have some light (viewmodel) #define EF_MINLIGHT (1<<8) // allways have some light (viewmodel)
#define EF_LIGHT (1<<9) // dynamic light (rockets use) #define EF_LIGHT (1<<9) // dynamic light (rockets use)
#define EF_ANIMATE (1<<10) // do client animate (ignore v.frame)
// edict->deadflag values // edict->deadflag values
#define DEAD_NO 0 // alive #define DEAD_NO 0 // alive

View File

@ -76,6 +76,7 @@ typedef struct entity_state_s
vec3_t viewangles; // already calculated view angles on server-side vec3_t viewangles; // already calculated view angles on server-side
vec3_t viewoffset; // viewoffset over ground vec3_t viewoffset; // viewoffset over ground
int maxspeed; // sv_maxspeed will be duplicate on all clients 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 health; // client health (other parms can be send by custom messages)
float fov; // horizontal field of view float fov; // horizontal field of view
int weapons; // weapon flags int weapons; // weapon flags

View File

@ -58,6 +58,7 @@ typedef struct entvars_s
float frame; // % playback position in animation sequences (0..255) float frame; // % playback position in animation sequences (0..255)
float animtime; // world time when frame was set float animtime; // world time when frame was set
float framerate; // animation playback rate (-8x to 8x) 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 controller[16]; // bone controller setting (0..255)
float blending[16]; // blending amount between sub-sequences (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) vec3_t v_angle; // viewing angle (player only)
int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity int fixangle; // 0 - nothing, 1 - force view angles, 2 - add avelocity
string_t viewmodel; // player's viewmodel 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) int gaitsequence; // movement animation sequence for player (0 for none)
short colormap; // lowbyte topcolor, highbyte bottomcolor short colormap; // lowbyte topcolor, highbyte bottomcolor
int playerclass; int playerclass;

View File

@ -45,7 +45,7 @@ typedef struct render_exp_s
void (*EndRegistration)( const char *skyname ); void (*EndRegistration)( const char *skyname );
// prepare frame to rendering // 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 (*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 (*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 ); bool (*AddPolygon)( shader_t shader, int numVerts, const polyVert_t *verts );
@ -77,12 +77,12 @@ typedef struct render_imp_s
// client fundamental callbacks // client fundamental callbacks
void (*UpdateScreen)( void ); // update screen while loading 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 (*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 void (*ShowCollision)( cmdraw_t callback ); // debug
long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam ); long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam );
entity_state_t *(*GetClientEdict)( int index ); edict_t *(*GetClientEdict)( int index );
entity_state_t *(*GetLocalPlayer)( void ); edict_t *(*GetLocalPlayer)( void );
int (*GetMaxClients)( void ); int (*GetMaxClients)( void );
} render_imp_t; } render_imp_t;

View File

@ -497,13 +497,13 @@ typedef struct
typedef struct latchedvars_s typedef struct latchedvars_s
{ {
float animtime; float animtime; // ???
float sequencetime; float sequencetime;
vec3_t origin; vec3_t origin; // edict->v.old_origin
vec3_t angles; vec3_t angles;
vec3_t gaitorigin; vec3_t gaitorigin;
int sequence; int sequence; // ???
float frame; float frame;
float blending[MAXSTUDIOBLENDS]; float blending[MAXSTUDIOBLENDS];
@ -516,7 +516,7 @@ typedef struct latchedvars_s
typedef struct ref_entity_s typedef struct ref_entity_s
{ {
edtype_t ent_type; // entity type 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 *model; // opaque type outside refresh
rmodel_t *weaponmodel; // opaque type outside refresh rmodel_t *weaponmodel; // opaque type outside refresh
@ -562,7 +562,7 @@ typedef struct ref_entity_s
float gaityaw; // local value float gaityaw; // local value
// shader information // shader information
ref_shader_t *shader; ref_shader_t *shader;
float shaderTime; // subtracted from refdef time to control effect start times float shaderTime; // subtracted from refdef time to control effect start times
float radius; // bbox approximate radius float radius; // bbox approximate radius
float rotation; // what the hell ??? float rotation; // what the hell ???
@ -576,6 +576,7 @@ void R_ModelList_f( void );
void R_StudioInit( void ); void R_StudioInit( void );
void R_StudioShutdown( void ); void R_StudioShutdown( void );
bool R_StudioComputeBBox( vec3_t bbox[8] ); // for drawing bounds 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_StudioSetupModel( int body, int bodypart );
void R_InitModels( void ); void R_InitModels( void );
void R_ShutdownModels( void ); void R_ShutdownModels( void );

View File

@ -1017,22 +1017,22 @@ void R_SetLightLevel( void )
R_AddEntityToScene 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; ref_entity_t *refent;
int i; 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; if( r_numEntities >= MAX_ENTITIES ) return false;
refent = &r_entities[r_numEntities]; refent = &r_entities[r_numEntities];
if( !s2 ) s2 = s1; // no lerping state
if( s1->effects & EF_NODRAW ) if( pRefEntity->v.effects & EF_NODRAW )
return true; // done return true; // done
// filter ents // filter ents
switch( s1->ed_type ) switch( ed_type )
{ {
case ED_MOVER: case ED_MOVER:
case ED_CLIENT: 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 // copy state to render
refent->frame = s1->model.frame; refent->index = pRefEntity->serialnumber;
refent->index = s1->number; refent->ent_type = ed_type;
refent->ent_type = s1->ed_type;
refent->backlerp = 1.0f - lerpfrac; refent->backlerp = 1.0f - lerpfrac;
refent->renderamt = s1->renderamt / 255.0f; refent->renderamt = pRefEntity->v.renderamt / 255.0f;
refent->rendermode = s1->rendermode; refent->rendermode = pRefEntity->v.rendermode;
refent->body = s1->model.body; refent->body = pRefEntity->v.body;
refent->sequence = s1->model.sequence; refent->scale = pRefEntity->v.scale;
refent->movetype = s1->movetype; refent->colormap = pRefEntity->v.colormap;
refent->scale = (s1->model.scale != 0.0f) ? s1->model.scale : 1.0f; refent->framerate = pRefEntity->v.framerate;
refent->colormap = s1->model.colormap; refent->effects = pRefEntity->v.effects;
refent->framerate = s1->model.framerate; if( VectorIsNull( pRefEntity->v.rendercolor ))
refent->effects = s1->effects;
refent->animtime = s1->model.animtime;
if( VectorIsNull( s1->rendercolor ))
VectorSet( refent->rendercolor, 1.0f, 1.0f, 1.0f ); 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 // setup latchedvars
refent->prev.frame = s2->model.frame; VectorCopy( pRefEntity->v.oldorigin, refent->prev.origin );
refent->prev.animtime = s2->model.animtime; VectorCopy( pRefEntity->v.oldangles, refent->prev.angles );
VectorCopy( s2->origin, refent->prev.origin );
VectorCopy( s2->angles, refent->prev.angles );
refent->prev.sequence = s2->model.sequence;
// interpolate origin // interpolate origin
for( i = 0; i < 3; i++ ) 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 // set skin
refent->skin = s1->model.skin; refent->skin = pRefEntity->v.skin;
refent->model = cl_models[s1->model.index]; refent->model = cl_models[pRefEntity->v.modelindex];
refent->weaponmodel = cl_models[s1->pmodel.index]; refent->renderfx = pRefEntity->v.renderfx;
refent->renderfx = s1->renderfx;
refent->prev.sequencetime = s1->model.animtime - s2->model.animtime; // FIXME:
// refent->weaponmodel = cl_models[pRefEntity->v.modelindex];
if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH ) if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH )
{ {
// store conveyor movedir in pev->velocity // store conveyor movedir in pev->velocity
VectorNormalize2( s1->velocity, refent->movedir ); VectorNormalize2( pRefEntity->v.velocity, refent->movedir );
} }
// calculate angles // calculate angles
@ -1096,7 +1120,7 @@ static bool R_AddEntityToScene( entity_state_t *s1, entity_state_t *s2, float le
{ {
// interpolate angles // interpolate angles
for( i = 0; i < 3; i++ ) 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 ); 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 // copy controllers
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ ) for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
{ {
refent->controller[i] = s1->model.controller[i]; refent->controller[i] = pRefEntity->v.controller[i];
refent->prev.controller[i] = s2->model.controller[i];
// FIXME:
// refent->prev.controller[i] = s2->model.controller[i];
} }
// copy blends // copy blends
for( i = 0; i < MAXSTUDIOBLENDS; i++ ) for( i = 0; i < MAXSTUDIOBLENDS; i++ )
{ {
refent->blending[i] = s1->model.blending[i]; refent->blending[i] = pRefEntity->v.blending[i];
refent->prev.blending[i] = s2->model.blending[i];
// FIXME:
// refent->prev.blending[i] = s2->model.blending[i];
} }
if( refent->ent_type == ED_CLIENT ) if( refent->ent_type == ED_CLIENT )
refent->gaitsequence = s1->model.gaitsequence; refent->gaitsequence = pRefEntity->v.gaitsequence;
// because entity without models never added to scene // because entity without models never added to scene
if( !refent->ent_type ) if( !refent->ent_type )

View File

@ -354,7 +354,7 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval
{ {
if( flInterval == 0.0 ) if( flInterval == 0.0 )
{ {
flInterval = (r_refdef.time - ent->animtime ); flInterval = ( r_refdef.time - ent->animtime );
if( flInterval <= 0.001 ) if( flInterval <= 0.001 )
{ {
ent->animtime = r_refdef.time; ent->animtime = r_refdef.time;
@ -376,17 +376,18 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval
return flInterval; return flInterval;
} }
void R_StudioResetSequenceInfo( ref_entity_t *ent ) void R_StudioResetSequenceInfo( ref_entity_t *ent, dstudiohdr_t *hdr )
{ {
float m_flFrameRate; float m_flFrameRate;
R_StudioGetSequenceInfo( m_pStudioHeader, ent, &m_flFrameRate, NULL ); if( !ent || !hdr ) return;
ent->m_fSequenceLoops = ((R_StudioGetSequenceFlags( m_pStudioHeader, ent ) & STUDIO_LOOPING) != 0 );
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 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->animtime = r_refdef.time;
ent->framerate = 1.0;
ent->m_fSequenceFinished = FALSE; ent->m_fSequenceFinished = FALSE;
} }
@ -1381,7 +1382,7 @@ void R_StudioDrawMeshes( dstudiotexture_t * ptexture, short *pskinref, int pass
VectorScale(m_plightcolor, lv_tmp, lv ); VectorScale(m_plightcolor, lv_tmp, lv );
} }
} }
for( j = 0; j < m_pSubModel->nummesh; j++ ) for( j = 0; j < m_pSubModel->nummesh; j++ )
{ {
float s, t; float s, t;
@ -1391,8 +1392,8 @@ void R_StudioDrawMeshes( dstudiotexture_t * ptexture, short *pskinref, int pass
ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex); ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex);
flags = ptexture[pskinref[pmesh->skinref]].flags; flags = ptexture[pskinref[pmesh->skinref]].flags;
s = 1.0/(float)ptexture[pskinref[pmesh->skinref]].width; s = 1.0 / (float)ptexture[pskinref[pmesh->skinref]].width;
t = 1.0/(float)ptexture[pskinref[pmesh->skinref]].height; t = 1.0 / (float)ptexture[pskinref[pmesh->skinref]].height;
m_pCurrentShader = &r_shaders[ptexture[pskinref[pmesh->skinref]].shader]; m_pCurrentShader = &r_shaders[ptexture[pskinref[pmesh->skinref]].shader];
@ -1752,10 +1753,11 @@ bool R_StudioDrawModel( int pass, int flags )
return 0; return 0;
// viewmodel animate on client // 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 ) //if( m_pCurrentEntity->m_fSequenceFinished && m_pCurrentEntity->m_fSequenceLoops )
R_StudioResetSequenceInfo( m_pCurrentEntity ); // R_StudioResetSequenceInfo( m_pCurrentEntity, m_pStudioHeader );
} }
R_StudioSetupRender( pass ); R_StudioSetupRender( pass );
@ -1797,8 +1799,8 @@ bool R_StudioDrawModel( int pass, int flags )
if( m_pCurrentEntity->index > 0 ) if( m_pCurrentEntity->index > 0 )
{ {
// copy attachments into global entity array // copy attachments into global entity array
entity_state_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); edict_t *ent = ri.GetClientEdict( m_pCurrentEntity->index );
Mem_Copy( m_pCurrentEntity->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); 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; float dt;
vec3_t est_velocity; vec3_t est_velocity;
@ -1858,7 +1860,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
return; return;
} }
// VectorAdd( pplayer->velocity, pplayer->prediction_error, est_velocity ); // VectorAdd( pplayer->v.velocity, pplayer->v.prediction_error, est_velocity );
if( m_fGaitEstimation ) if( m_fGaitEstimation )
{ {
VectorSubtract( m_pCurrentEntity->origin, m_pCurrentEntity->prev.gaitorigin, est_velocity ); VectorSubtract( m_pCurrentEntity->origin, m_pCurrentEntity->prev.gaitorigin, est_velocity );
@ -1874,7 +1876,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
} }
else else
{ {
VectorCopy( pplayer->velocity, est_velocity ); VectorCopy( pplayer->v.velocity, est_velocity );
m_flGaitMovement = VectorLength( est_velocity ) * dt; 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; dstudioseqdesc_t *pseqdesc;
float dt, flYaw; // view direction relative to movement 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; if( m_pCurrentEntity->angles[YAW] < -0 ) m_pCurrentEntity->angles[YAW] += 360;
m_pCurrentEntity->prev.angles[YAW] = m_pCurrentEntity->angles[YAW]; m_pCurrentEntity->prev.angles[YAW] = m_pCurrentEntity->angles[YAW];
if( pplayer->model.gaitsequence >= m_pStudioHeader->numseq ) if( pplayer->v.gaitsequence >= m_pStudioHeader->numseq )
pplayer->model.gaitsequence = 0; 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 // calc gait frame
if( pseqdesc->linearmovement[0] > 0 ) if( pseqdesc->linearmovement[0] > 0 )
@ -1996,12 +1998,12 @@ StudioDrawPlayer
*/ */
int R_StudioDrawPlayer( int pass, int flags ) int R_StudioDrawPlayer( int pass, int flags )
{ {
entity_state_t *pplayer; edict_t *pplayer;
if( m_pCurrentEntity->ent_type == ED_CLIENT ) if( m_pCurrentEntity->ent_type == ED_CLIENT )
return 0; return 0;
if(!(flags & STUDIO_MIRROR)) if( !( flags & STUDIO_MIRROR ))
{ {
//m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); //m_pCurrentEntity = IEngineStudio.GetCurrentEntity();
} }
@ -2010,20 +2012,20 @@ int R_StudioDrawPlayer( int pass, int flags )
R_StudioSetupRender( pass ); R_StudioSetupRender( pass );
// MsgDev( D_INFO, "DrawPlayer %d\n", m_pCurrentEntity->blending[0] ); // 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, "DrawPlayer %d %d (%d)\n", r_framecount, pplayer->serialnumber, m_pCurrentEntity->sequence );
// MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", pplayer->velocity[0], pplayer->velocity[1], pplayer->velocity[2] ); // 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; return 0;
if( pplayer->model.gaitsequence ) if( pplayer->v.gaitsequence )
{ {
vec3_t orig_angles; vec3_t orig_angles;
VectorCopy( m_pCurrentEntity->angles, orig_angles ); VectorCopy( m_pCurrentEntity->angles, orig_angles );
R_StudioProcessGait( pplayer ); R_StudioProcessGait( pplayer );
m_pCurrentEntity->gaitsequence = pplayer->model.gaitsequence; m_pCurrentEntity->gaitsequence = pplayer->v.gaitsequence;
R_StudioSetUpTransform( ); R_StudioSetUpTransform( );
VectorCopy( orig_angles, m_pCurrentEntity->angles ); VectorCopy( orig_angles, m_pCurrentEntity->angles );
} }
@ -2068,8 +2070,8 @@ int R_StudioDrawPlayer( int pass, int flags )
if( m_pCurrentEntity->index > 0 ) if( m_pCurrentEntity->index > 0 )
{ {
// copy attachments into global entity array // copy attachments into global entity array
entity_state_t *ent = ri.GetClientEdict( m_pCurrentEntity->index ); edict_t *ent = ri.GetClientEdict( m_pCurrentEntity->index );
Mem_Copy( m_pCurrentEntity->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS ); Mem_Copy( ent->v.attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * MAXSTUDIOATTACHMENTS );
} }
} }

View File

@ -329,7 +329,7 @@ void CBasePlayerWeapon::DefaultTouch( CBaseEntity *pOther )
return; return;
} }
if (pOther->AddPlayerItem( this )) if( pOther->AddPlayerItem( this ))
{ {
AttachToPlayer( pPlayer ); AttachToPlayer( pPlayer );
EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); 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() m_iId = MAX_WEAPONS; //Will be owerwrite with GenerateID()
II->iSlot = 0; II->iSlot = 0;
II->iPosition = 0; II->iPosition = 0;
II->iViewModel = MAKE_STRING( "models/weapons/v_glock.mdl" ); II->iViewModel = iStringNull;
II->iWorldModel = MAKE_STRING( "models/weapons/w_glock.mdl" ); II->iWorldModel = iStringNull;
strcpy( II->szAnimExt, "onehanded"); strcpy( II->szAnimExt, "onehanded");
II->iszAmmo1 = MAKE_STRING( "none" ); II->iszAmmo1 = MAKE_STRING( "none" );
II->iMaxAmmo1 = WEAPON_NOAMMO; II->iMaxAmmo1 = WEAPON_NOAMMO;
@ -739,11 +739,11 @@ int CBasePlayerWeapon :: PlaySequence( Activity activity, float fps )
//========================================================= //=========================================================
int CBasePlayerWeapon :: SetAnimation( char *name, float fps ) int CBasePlayerWeapon :: SetAnimation( char *name, float fps )
{ {
if(!m_pPlayer->pev->viewmodel) return -1; if( !m_pPlayer->pev->viewmodel ) return -1;
UTIL_SetModel( ENT(pev), STRING( m_pPlayer->pev->viewmodel )); UTIL_SetModel( ENT( pev ), STRING( m_pPlayer->pev->viewmodel ));
int iSequence = LookupSequence( name ); int iSequence = LookupSequence( name );
if(iSequence != -1) SendWeaponAnim(iSequence, fps); if( iSequence != -1 ) SendWeaponAnim( iSequence, fps );
else DevMsg("Warning: Sequence \"%s\" not found\n", name); else ALERT( at_warning, "sequence \"%s\" not found\n", name );
return iSequence; return iSequence;
} }
@ -759,15 +759,15 @@ int CBasePlayerWeapon :: SetAnimation( Activity activity, float fps )
if(!m_pPlayer->pev->viewmodel) return -1; if(!m_pPlayer->pev->viewmodel) return -1;
UTIL_SetModel( ENT(pev), STRING( m_pPlayer->pev->viewmodel )); UTIL_SetModel( ENT(pev), STRING( m_pPlayer->pev->viewmodel ));
//try to playing ACT sequence // try to playing ACT sequence
iSequence = LookupActivity( activity ); iSequence = LookupActivity( activity );
if(iSequence != -1) if( iSequence != -1 )
{ {
SendWeaponAnim(iSequence, fps); //activity method SendWeaponAnim( iSequence, fps ); // activity method
return iSequence; return iSequence;
} }
//ACT not found, translate name to ACT // ACT not found, translate name to ACT
switch ( activity ) switch ( activity )
{ {
case ACT_VM_IDLE1: case ACT_VM_IDLE1:
@ -847,9 +847,9 @@ int CBasePlayerWeapon :: SetAnimation( Activity activity, float fps )
for(int i = 0; i < m_iAnimCount; i++ ) for(int i = 0; i < m_iAnimCount; i++ )
{ {
iSequence = LookupSequence( pAnimsList[i] ); iSequence = LookupSequence( pAnimsList[i] );
if(iSequence != -1) if( iSequence != -1 )
{ {
SendWeaponAnim(iSequence, fps); //names method SendWeaponAnim (iSequence, fps ); // names method
return iSequence; return iSequence;
} }
} }
@ -871,10 +871,9 @@ void CBasePlayerWeapon :: SendWeaponAnim( int sequence, float fps )
MESSAGE_BEGIN( MSG_ONE, gmsg.WeaponAnim, NULL, m_pPlayer->pev ); MESSAGE_BEGIN( MSG_ONE, gmsg.WeaponAnim, NULL, m_pPlayer->pev );
WRITE_BYTE( sequence ); WRITE_BYTE( sequence );
WRITE_BYTE( pev->body );
MESSAGE_END(); MESSAGE_END();
if(pstudiohdr) if( pstudiohdr )
{ {
pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)sequence; pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)sequence;
if(fps) pseqdesc->fps = fps; if(fps) pseqdesc->fps = fps;
@ -892,20 +891,20 @@ BOOL CBasePlayerWeapon :: DefaultDeploy( Activity sequence )
if ( SUIT ) pev->body = TRUE; if ( SUIT ) pev->body = TRUE;
else pev->body = FALSE; else pev->body = FALSE;
m_iClientSkin = -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_iClientBody = -1; // reset last skin info for new weapon
m_pPlayer->pev->viewmodel = iViewModel(); m_pPlayer->pev->viewmodel = iViewModel();
m_pPlayer->pev->weaponmodel = iWorldModel(); m_pPlayer->pev->weaponmodel = iWorldModel();
strcpy( m_pPlayer->m_szAnimExtention, szAnimExt() ); strcpy( m_pPlayer->m_szAnimExtention, szAnimExt());
if(SetAnimation( sequence ) != -1) if( SetAnimation( sequence ) != -1 )
{ {
SetNextAttack(SequenceDuration() + 0.5);//delay before idle playing SetNextAttack( SequenceDuration() + 0.5 );//delay before idle playing
return TRUE; return TRUE;
} }
//animation not found // animation not found
return FALSE; return FALSE;
} }
@ -915,21 +914,22 @@ BOOL CBasePlayerWeapon :: DefaultHolster( Activity sequence )
int iResult = 0; int iResult = 0;
iResult = SetAnimation( sequence ); iResult = SetAnimation( sequence );
if(iResult == -1) return 0; if( iResult == -1 ) return 0;
SetNextAttack(SequenceDuration() + 0.1);//delay before switching SetNextAttack( SequenceDuration() + 0.1 ); // delay before switching
if(m_pSpot)//disable laser dot 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->Killed();
m_pSpot = NULL; m_pSpot = NULL;
} }
ZoomReset(); 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! // no more ammo!
m_pPlayer->pev->weapons &= ~(1<<m_iId); m_pPlayer->pev->weapons &= ~(1<<m_iId);
@ -939,7 +939,7 @@ BOOL CBasePlayerWeapon :: DefaultHolster( Activity sequence )
SetNextThink( 0.5 ); SetNextThink( 0.5 );
} }
//animation not found // animation not found
return 1; return 1;
} }
@ -948,7 +948,7 @@ void CBasePlayerWeapon :: DefaultIdle( void )
// weapon have clip and ammo or just have ammo // weapon have clip and ammo or just have ammo
if ((iMaxClip() && m_iClip) || m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 || iMaxAmmo1() == -1) if ((iMaxClip() && m_iClip) || m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 || iMaxAmmo1() == -1)
{ {
//play random idle animation // play random idle animation
int iAnim; int iAnim;
float flRand = RANDOM_FLOAT(0, 1.2); float flRand = RANDOM_FLOAT(0, 1.2);
if (flRand < 0.2) iAnim = ACT_VM_IDLE1; if (flRand < 0.2) iAnim = ACT_VM_IDLE1;
@ -970,59 +970,63 @@ void CBasePlayerWeapon :: DefaultIdle( void )
BOOL CBasePlayerWeapon :: DefaultReload( Activity sequence ) BOOL CBasePlayerWeapon :: DefaultReload( Activity sequence )
{ {
if (m_cActiveRocket && m_iSpot ) return FALSE; if( m_cActiveRocket && m_iSpot )
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase()) return FALSE; return FALSE;
if (m_flNextSecondaryAttack > UTIL_WeaponTimeBase()) return FALSE; if( m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
if(m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0)//have ammo? 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( iMaxClip() == m_iClip ) return FALSE;
if (m_iStepReload == 0)//try to playing step reload 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_iStepReload = 1;
m_fInReload = TRUE;//disable reload button m_fInReload = TRUE; // disable reload button
return TRUE;//start reload cycle. See also ItemPostFrame return TRUE; // start reload cycle. See also ItemPostFrame
} }
else // init default reload else // init default reload
{ {
int i = min(iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); 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; int iResult = -1;
ZoomReset();//reset zoom ZoomReset(); // reset zoom
if(m_iClip <= 0)//empty clip ? if( m_iClip <= 0 ) // empty clip ?
{ {
//iResult is error code // iResult is error code
iResult = SetAnimation( ACT_VM_RELOAD_EMPTY ); 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 ); 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 if( m_pSpot ) m_pSpot->Suspend( SequenceDuration( )); // suspend laserdot
SetNextAttack(SequenceDuration()); SetNextAttack( SequenceDuration( ));
m_fInReload = TRUE;//disable reload button 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 // was waiting for gun to move to side
SetAnimation( sequence ); SetAnimation( sequence );
m_iStepReload = 2; 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_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
m_iClip++; m_iClip++;
m_iStepReload = 1; 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; return TRUE;
} }
@ -1031,9 +1035,10 @@ BOOL CBasePlayerWeapon :: DefaultReload( Activity sequence )
BOOL CBasePlayerWeapon :: PlayEmptySound( void ) 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; m_iPlayEmptySound = 0;
return TRUE; return TRUE;
} }
@ -1044,15 +1049,16 @@ BOOL CBasePlayerWeapon :: PlayEmptySound( void )
//========================================================= //=========================================================
Vector CBasePlayerWeapon :: GetCurrentSpread( const char *ammo ) Vector CBasePlayerWeapon :: GetCurrentSpread( const char *ammo )
{ {
int iBullet = GetBulletType( ammo ); switch( GetBulletType( ammo ))
if( iBullet == BULLET_9MM) return VECTOR_CONE_2DEGREES; {
else if( iBullet == BULLET_357) return VECTOR_CONE_2DEGREES; case BULLET_9MM: return VECTOR_CONE_2DEGREES;
else if( iBullet == BULLET_556) return VECTOR_CONE_3DEGREES; case BULLET_357: return VECTOR_CONE_2DEGREES;
else if( iBullet == BULLET_762) return VECTOR_CONE_1DEGREES; case BULLET_556: return VECTOR_CONE_3DEGREES;
else if( iBullet == BULLET_12MM) return VECTOR_CONE_15DEGREES; case BULLET_762: return VECTOR_CONE_1DEGREES;
else if( iBullet == BULLET_BUCKSHOT) return VECTOR_CONE_10DEGREES; case BULLET_12MM: return VECTOR_CONE_15DEGREES;
case BULLET_BUCKSHOT: return VECTOR_CONE_10DEGREES;
return VECTOR_CONE_0DEGREES; default: return VECTOR_CONE_0DEGREES;
}
} }
int CBasePlayerWeapon :: GetBulletType( const char *ammo ) int CBasePlayerWeapon :: GetBulletType( const char *ammo )
@ -1080,10 +1086,10 @@ int CBasePlayerWeapon :: GetAmmoType( const char *ammo )
int CBasePlayerWeapon :: ReturnAmmoIndex( const char *ammo ) int CBasePlayerWeapon :: ReturnAmmoIndex( const char *ammo )
{ {
const char *ammoname; const char *ammoname;
ammoname = m_pPlayer->GetAmmoName(m_iPrimaryAmmoType); ammoname = m_pPlayer->GetAmmoName( m_iPrimaryAmmoType );
if(!stricmp( ammo, ammoname )) return m_iPrimaryAmmoType; if( !stricmp( ammo, ammoname )) return m_iPrimaryAmmoType;
ammoname = m_pPlayer->GetAmmoName(m_iSecondaryAmmoType); ammoname = m_pPlayer->GetAmmoName( m_iSecondaryAmmoType );
if(!stricmp( ammo, ammoname )) return m_iSecondaryAmmoType; if( !stricmp( ammo, ammoname )) return m_iSecondaryAmmoType;
return 0; return 0;
} }
@ -1093,7 +1099,7 @@ int CBasePlayerWeapon :: GetCurrentAttack( const char *ammo, int firemode )
if( !stricmp( ammo, "none" )) //no ammo if( !stricmp( ammo, "none" )) //no ammo
{ {
//just play animation and sound //just play animation and sound
if(!firemode) iResult = PlayRangeAttack();//anim is present ? if(!firemode) iResult = PlayRangeAttack(); // anim is present ?
else iResult = PlayMeleeAttack(); else iResult = PlayMeleeAttack();
SetPlayerEffects( ammo, firemode ); SetPlayerEffects( ammo, firemode );
@ -1590,17 +1596,17 @@ void CBasePlayerWeapon::ZoomUpdate( void )
void CBasePlayerWeapon::ZoomReset( void ) void CBasePlayerWeapon::ZoomReset( void )
{ {
//return viewmodel // return viewmodel
if(m_iZoom) if( m_iZoom )
{ {
m_pPlayer->pev->viewmodel = iViewModel(); m_pPlayer->pev->viewmodel = iViewModel();
m_flHoldTime = UTIL_WeaponTimeBase() + 0.5; m_flHoldTime = UTIL_WeaponTimeBase() + 0.5;
m_pPlayer->m_iFOV = 90; 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 ); MESSAGE_BEGIN( MSG_ONE, gmsg.ZoomHUD, NULL, m_pPlayer->pev );
WRITE_BYTE( m_iZoom ); WRITE_BYTE( m_iZoom );
MESSAGE_END(); 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 ) void CBasePlayerWeapon :: Deploy( void )
{ {
m_iStepReload = 0; 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 if(!DefaultDeploy( ACT_VM_DEPLOY_EMPTY ))// try to playing "deploy_empty" anim
DefaultDeploy(ACT_VM_DEPLOY); //custom animation not found, play standard animation 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 ) 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 if(!DefaultHolster(ACT_VM_HOLSTER_EMPTY))// try to playing "holster_empty" anim
DefaultHolster(ACT_VM_HOLSTER); 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 // NOT USED:HoldDown weapon
//========================================================= //=========================================================
int CBasePlayerWeapon::FoundAlly( void ) int CBasePlayerWeapon :: FoundAlly( void )
{ {
CBaseEntity *pEntity = UTIL_FindEntityForward( m_pPlayer ); CBaseEntity *pEntity = UTIL_FindEntityForward( m_pPlayer );
if ( pEntity ) if( pEntity )
{ {
CBaseMonster *pMonster = pEntity->MyMonsterPointer(); CBaseMonster *pMonster = pEntity->MyMonsterPointer();
if ( pMonster ) if( pMonster )
{ {
int m_class = pMonster->Classify(); 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; return 1;
} }
@ -1659,83 +1665,84 @@ void CBasePlayerWeapon::ItemPreFrame( void )
void CBasePlayerWeapon::ItemPostFrame( void ) void CBasePlayerWeapon::ItemPostFrame( void )
{ {
if(!b_restored) if( !b_restored )
{ {
m_iClientSkin = -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_iClientBody = -1; // reset last skin info for new weapon
if(iMaxClip() && !m_iClip) SetAnimation(ACT_VM_IDLE_EMPTY); //restore last animation if( iMaxClip() && !m_iClip )
SetAnimation( ACT_VM_IDLE_EMPTY ); // restore last animation
else SetAnimation( ACT_VM_IDLE1 ); else SetAnimation( ACT_VM_IDLE1 );
b_restored = TRUE; b_restored = TRUE;
} }
if(!m_iSpot && m_pSpot)//disable laser dot if( !m_iSpot && m_pSpot ) // disable laser dot
{ {
m_iSkin = 0; //disable screen m_iSkin = 0; // disable screen
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->Killed();
m_pSpot = NULL; m_pSpot = NULL;
} }
if(m_iSpot && !m_pSpot)//enable laser dot if( m_iSpot && !m_pSpot ) // enable laser dot
{ {
m_pSpot = CLaserSpot::CreateSpot(); m_pSpot = CLaserSpot::CreateSpot();
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM); EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/spot_on.wav", 1, ATTN_NORM );
m_iSkin = 1; //enable screen 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_iStepReload ) m_fInReload = FALSE; // reload done
if ( m_flTimeUpdate < UTIL_WeaponTimeBase() ) PostIdle(); //catch all if( m_flTimeUpdate < UTIL_WeaponTimeBase()) PostIdle(); // catch all
if (m_fInReload && m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase()) if( m_fInReload && m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() )
{ {
if(m_iStepReload > 2) if( m_iStepReload > 2 )
{ {
// complete the reload. // complete the reload.
int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); 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_iClip += j;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.01;//play PostReload m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.01; // play PostReload
//m_iStepReload = 1; // m_iStepReload = 1;
m_fInReload = FALSE; 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(); SecondaryAttack();
m_pPlayer->pev->button &= ~IN_ATTACK2; 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; m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5;
return; return;
} }
PrimaryAttack(); PrimaryAttack();
m_pPlayer->pev->button &= ~IN_ATTACK; 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 when reload is pressed, or if no buttons are down and weapon is empty.
Reload(); 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)) if( ((SUIT) && !PLAYER_HAS_SUIT) || (!(SUIT) && PLAYER_HAS_SUIT))
{ {
m_pPlayer->m_pActiveItem->Holster( ); m_pPlayer->m_pActiveItem->Holster( );
m_pPlayer->QueueItem(this); m_pPlayer->QueueItem( this );
if (m_pPlayer->m_pActiveItem) m_pPlayer->m_pActiveItem->Deploy(); 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. // 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; m_flNextPrimaryAttack = gpGlobals->time + 0.3;
return; return;
@ -1744,38 +1751,42 @@ void CBasePlayerWeapon::ItemPostFrame( void )
else else
{ {
// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing // 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(); Reload();
return; return;
} }
} }
m_iPlayEmptySound = 1;//reset empty sound m_iPlayEmptySound = 1; // reset empty sound
if(iFlags() & ITEM_FLAG_USEAUTOAIM) m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); 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_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 else
{ {
// reload debounce has timed out // 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 ); SetAnimation( ACT_VM_PUMP );
} }
else SetAnimation( ACT_VM_PUMP ); else SetAnimation( ACT_VM_PUMP );
if ( iFlags() & ITEM_FLAG_HIDEAMMO ) m_iBody = 0;//reset ammo if( iFlags() & ITEM_FLAG_HIDEAMMO )
PostReload();//post effects m_iBody = 0; // reset ammo
PostReload(); // post effects
m_iStepReload = 0; m_iStepReload = 0;
} }
} }
else if ( m_iOnControl > 3 )//item deploy else if( m_iOnControl > 3 ) // item deploy
{ {
m_iOnControl = 0; m_iOnControl = 0;
if ( m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] ) if( m_pPlayer->m_rgAmmo[ m_iPrimaryAmmoType ] )
{ {
SetAnimation( ACT_VM_DEPLOY ); SetAnimation( ACT_VM_DEPLOY );
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_LONG( 10, 15 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_LONG( 10, 15 );
@ -1792,48 +1803,49 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer )
BOOL bSend = FALSE; BOOL bSend = FALSE;
int state = 0; int state = 0;
//update weapon body // update weapon body
if( m_iClientBody != m_iBody) 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 ); MESSAGE_BEGIN( MSG_ONE, gmsg.SetBody, NULL, m_pPlayer->pev );
WRITE_BYTE( pev->body ); //weaponmodel body WRITE_BYTE( pev->body ); // weaponmodel body
MESSAGE_END(); MESSAGE_END();
m_iClientBody = m_iBody;//synched m_iClientBody = m_iBody;//synched
} }
//update weapon skin // update weapon skin
if( m_iClientSkin != m_iSkin) 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 ); MESSAGE_BEGIN( MSG_ONE, gmsg.SetSkin, NULL, m_pPlayer->pev );
WRITE_BYTE( pev->skin ); //weaponmodel skin. WRITE_BYTE( pev->skin ); //weaponmodel skin.
MESSAGE_END(); MESSAGE_END();
m_iClientSkin = m_iSkin;//synched m_iClientSkin = m_iSkin;//synched
} }
if ( pPlayer->m_pActiveItem == this ) if( pPlayer->m_pActiveItem == this )
{ {
if ( pPlayer->m_fOnTarget ) state = 0x40;//weapon is ontarget if( pPlayer->m_fOnTarget )
else state = 1; state = 0x40; // weapon is ontarget
else state = 1;
} }
// Forcing send of all data! // forcing send of all data!
if ( !pPlayer->m_fWeapon ) bSend = TRUE; if( !pPlayer->m_fWeapon ) bSend = TRUE;
// This is the current or last weapon, so the state will need to be updated // 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 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( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_iFOV != pPlayer->m_iClientFOV )
{ {
bSend = TRUE; bSend = TRUE;
} }
if ( bSend ) if( bSend )
{ {
MESSAGE_BEGIN( MSG_ONE, gmsg.CurWeapon, NULL, pPlayer->pev ); MESSAGE_BEGIN( MSG_ONE, gmsg.CurWeapon, NULL, pPlayer->pev );
WRITE_BYTE( state ); WRITE_BYTE( state );
@ -1846,7 +1858,7 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer )
pPlayer->m_fWeapon = TRUE; pPlayer->m_fWeapon = TRUE;
} }
if ( m_pNext ) m_pNext->UpdateClientData( pPlayer ); if( m_pNext ) m_pNext->UpdateClientData( pPlayer );
return 1; return 1;
} }
@ -1869,22 +1881,24 @@ void CBasePlayerWeapon::DestroyItem( void )
void CBasePlayerWeapon::Drop( void ) void CBasePlayerWeapon::Drop( void )
{ {
SetTouch( NULL ); SetTouch( NULL );
SetThink(Remove); SetThink( Remove );
SetNextThink( 0.1 ); 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->movetype = MOVETYPE_FOLLOW;
pev->solid = SOLID_NOT; pev->solid = SOLID_NOT;
pev->aiment = pPlayer->edict(); pev->effects |= EF_NODRAW;
pev->effects = EF_NODRAW; pev->modelindex = 0; // server won't send down to clients if modelindex == 0
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->targetname = iStringNull; // don't try remove this weapon from map
pev->model = iStringNull; pev->model = iStringNull;
pev->owner = pPlayer->edict();
SetNextThink( 0.1 ); SetNextThink( 0.1 );
SetTouch( NULL ); SetTouch( NULL );
SetThink( NULL ); SetThink( NULL );

View File

@ -1044,7 +1044,7 @@ void LinkUserMessages( void )
gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -1 ); gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -1 );
gmsg.RoomType = REG_USER_MSG( "RoomType", 2 ); gmsg.RoomType = REG_USER_MSG( "RoomType", 2 );
gmsg.HideWeapon = REG_USER_MSG( "HideWeapon", 1 ); 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.SetFOV = REG_USER_MSG( "SetFOV", 1 );
gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 ); gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 );
gmsg.Shake = REG_USER_MSG("ScreenShake", 13 ); gmsg.Shake = REG_USER_MSG("ScreenShake", 13 );
@ -1058,7 +1058,7 @@ void LinkUserMessages( void )
gmsg.ZoomHUD = REG_USER_MSG("ZoomHUD", 1); gmsg.ZoomHUD = REG_USER_MSG("ZoomHUD", 1);
gmsg.WarHUD = REG_USER_MSG("WarHUD", 1); gmsg.WarHUD = REG_USER_MSG("WarHUD", 1);
//entity messages // entity messages
gmsg.StatusIcon = REG_USER_MSG("StatusIcon", -1); gmsg.StatusIcon = REG_USER_MSG("StatusIcon", -1);
gmsg.CamData = REG_USER_MSG("CamData", -1); gmsg.CamData = REG_USER_MSG("CamData", -1);
gmsg.Fsound = REG_USER_MSG("Fsound", -1); gmsg.Fsound = REG_USER_MSG("Fsound", -1);
@ -1067,6 +1067,7 @@ void LinkUserMessages( void )
gmsg.AddPortal = REG_USER_MSG( "AddPortal", 1); gmsg.AddPortal = REG_USER_MSG( "AddPortal", 1);
gmsg.HudText = REG_USER_MSG( "HudText", -1 ); gmsg.HudText = REG_USER_MSG( "HudText", -1 );
gmsg.ShowGameTitle = REG_USER_MSG("GameTitle", 1); gmsg.ShowGameTitle = REG_USER_MSG("GameTitle", 1);
gmsg.TempEntity = REG_USER_MSG( "TempEntity", 1); // FIXME
gmsg.SetFog = REG_USER_MSG("SetFog", 7 ); gmsg.SetFog = REG_USER_MSG("SetFog", 7 );
gmsg.SetSky = REG_USER_MSG( "SetSky", 13 ); gmsg.SetSky = REG_USER_MSG( "SetSky", 13 );
gmsg.Particle = REG_USER_MSG( "Particle", -1); gmsg.Particle = REG_USER_MSG( "Particle", -1);

View File

@ -103,7 +103,6 @@ int DispatchSpawn( edict_t *pent )
pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1); pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1);
pEntity->pev->absmax = 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->Spawn();
pEntity = (CBaseEntity *)GET_PRIVATE(pent); pEntity = (CBaseEntity *)GET_PRIVATE(pent);

View File

@ -1005,53 +1005,55 @@ void UTIL_SetAvelocity ( CBaseEntity *pEnt, const Vector vecSet )
//======================================================================== //========================================================================
// Precache and set resources - add check for present or invalid name // 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 ); 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 ) 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"); g_engfuncs.pfnSetModel( e, "models/common/null.mdl" );
return;
}
//is this brush model?
if (model[0] == '*')
{
g_engfuncs.pfnSetModel(e, model);
return; return;
} }
//verify file exists // is this brush model?
byte *data = LOAD_FILE((char*)model, NULL); if( model[0] == '*' )
if (data)
{ {
FREE_FILE( data ); g_engfuncs.pfnSetModel( e, model );
g_engfuncs.pfnSetModel(e, model);
return; return;
} }
int namelen = strlen(model) - 1; // verify file exists
if (model[namelen] == 'l') if( FILE_EXISTS( model ))
{ {
//this is model g_engfuncs.pfnSetModel( e, model );
g_engfuncs.pfnSetModel(e, "models/common/error.mdl"); return;
} }
else if (model[namelen] == 'r')
if( !strcmp( UTIL_FileExtension( model ), "mdl" ))
{ {
//this is sprite // this is model
g_engfuncs.pfnSetModel(e, "sprites/error.spr"); 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 else
{ {
//set null model // set null model
g_engfuncs.pfnSetModel(e, "models/common/null.mdl"); g_engfuncs.pfnSetModel( e, "models/common/null.mdl" );
} }
} }
@ -2998,6 +3000,27 @@ void UTIL_LogPrintf( char *fmt, ... )
ALERT( at_logged, "%s", string ); 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 // UTIL_DotPoints - returns the dot product of a line from
// src to check and vecdir. // src to check and vecdir.

View File

@ -447,7 +447,8 @@ extern char *UTIL_dtos3( int d );
extern char *UTIL_dtos4( int d ); extern char *UTIL_dtos4( int d );
// Writes message to console with timestamp and FragLog header. // 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. // Sorta like FInViewCone, but for nonmonsters.
extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir );

View File

@ -37,6 +37,8 @@ Beta 13.12.08
16.Copy Resources OK 16.Copy Resources OK
17.тормоза на больших картах 17.тормоза на больших картах
18.weapon pickup & drawing 18.weapon pickup & drawing
19.AddRefEntity uses edict_t instead entity state
20.render custom models
entity_state_t невидима для пользователя entity_state_t невидима для пользователя