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_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

View File

@ -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];

View File

@ -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));
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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 );

View File

@ -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;
/*
==============================================================

View File

@ -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 );
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 )
{

View File

@ -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" );

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 );

View File

@ -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 )

View File

@ -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 );
}
}

View File

@ -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_iId);
@ -939,7 +939,7 @@ BOOL CBasePlayerWeapon :: DefaultHolster( Activity sequence )
SetNextThink( 0.5 );
}
//animation not found
// animation not found
return 1;
}
@ -948,7 +948,7 @@ void CBasePlayerWeapon :: DefaultIdle( void )
// weapon have clip and ammo or just have ammo
if ((iMaxClip() && m_iClip) || m_pPlayer->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 );

View File

@ -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);

View File

@ -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);

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
// 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.

View File

@ -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 );

View File

@ -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 невидима для пользователя