mirror of
https://github.com/YGGverse/hlsdk-portable.git
synced 2025-01-23 13:14:51 +00:00
Merge some changes from git version of hlsdk.
This commit is contained in:
parent
fc276ad52f
commit
a522ae20c3
@ -110,7 +110,9 @@
|
||||
#define EF_NOINTERP 32 // don't interpolate the next frame
|
||||
#define EF_LIGHT 64 // rocket flare glow sprite
|
||||
#define EF_NODRAW 128 // don't draw entity
|
||||
|
||||
#define EF_NIGHTVISION 256 // player nightvision
|
||||
#define EF_SNIPERLASER 512 // sniper laser effect
|
||||
#define EF_FIBERCAMERA 1024 // fiber camera
|
||||
|
||||
|
||||
#define EF_NOREFLECT (1<<24) // Entity won't reflecting in mirrors
|
||||
@ -531,6 +533,7 @@
|
||||
#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration.
|
||||
#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque
|
||||
#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube.
|
||||
#define TEFIRE_FLAG_ADDITIVE 32 // if set, sprite is rendered non-opaque with additive
|
||||
|
||||
#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
|
||||
// byte (entity index of player)
|
||||
@ -621,8 +624,9 @@
|
||||
#define CHAN_BODY 4
|
||||
#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area
|
||||
#define CHAN_STATIC 6 // allocate channel from the static area
|
||||
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network
|
||||
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network
|
||||
#define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END).
|
||||
#define CHAN_BOT 501 // channel used for bot chatter.
|
||||
|
||||
// attenuation values
|
||||
#define ATTN_NONE 0
|
||||
@ -724,7 +728,8 @@ enum
|
||||
kRenderFxDeadPlayer, // kRenderAmt is the player index
|
||||
kRenderFxExplode, // Scale up really big!
|
||||
kRenderFxGlowShell, // Glowing Shell
|
||||
kRenderFxClampMinScale // Keep this sprite from getting very small (SPRITES only!)
|
||||
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!)
|
||||
kRenderFxLightMultiplier //CTM !!!CZERO added to tell the studiorender that the value in iuser2 is a lightmultiplier
|
||||
};
|
||||
|
||||
typedef unsigned int func_t;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
|
||||
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
|
||||
|
||||
typedef struct cvar_s
|
||||
{
|
||||
@ -34,4 +35,4 @@ typedef struct cvar_s
|
||||
struct cvar_s *next;
|
||||
} cvar_t;
|
||||
|
||||
#endif//CVARDEF_H
|
||||
#endif//CVARDEF_H
|
||||
|
@ -1045,7 +1045,11 @@ void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, US
|
||||
pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance;
|
||||
|
||||
UpdateAllButtons( pev->ideal_yaw, 1 );
|
||||
UpdateTarget( pev->ideal_yaw );
|
||||
|
||||
// Calculate destination angle and use it to predict value, this prevents sending target in wrong direction on retriggering
|
||||
Vector dest = pev->angles + pev->avelocity * ( pev->nextthink - pev->ltime );
|
||||
float value1 = CBaseToggle::AxisDelta( pev->spawnflags, dest, m_start ) / m_flMoveDistance;
|
||||
UpdateTarget( value1 );
|
||||
}
|
||||
|
||||
void CMomentaryRotButton::UpdateAllButtons( float value, int start )
|
||||
|
@ -280,8 +280,8 @@ public:
|
||||
#ifdef _DEBUG
|
||||
void FunctionCheck( void *pFunction, char *name )
|
||||
{
|
||||
if( pFunction && !NAME_FOR_FUNCTION( (unsigned long)( pFunction ) ) )
|
||||
ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING( pev->classname ), name, (unsigned long)pFunction );
|
||||
if( pFunction && !NAME_FOR_FUNCTION( (size_t)( pFunction ) ) )
|
||||
ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING( pev->classname ), name, (size_t)pFunction );
|
||||
}
|
||||
|
||||
BASEPTR ThinkSet( BASEPTR func, char *name )
|
||||
|
238
dlls/client.cpp
238
dlls/client.cpp
@ -48,6 +48,8 @@ extern void CopyToBodyQue( entvars_t* pev );
|
||||
extern int giPrecacheGrunt;
|
||||
extern int gmsgSayText;
|
||||
|
||||
extern cvar_t allow_spectators;
|
||||
|
||||
extern int g_teamplay;
|
||||
|
||||
void LinkUserMessages( void );
|
||||
@ -204,6 +206,97 @@ void ClientPutInServer( edict_t *pEntity )
|
||||
#include "voice_gamemgr.h"
|
||||
extern CVoiceGameMgr g_VoiceGameMgr;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: determine if a uchar32 represents a valid Unicode code point
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_IsValidUChar32( unsigned int uVal )
|
||||
{
|
||||
// Values > 0x10FFFF are explicitly invalid; ditto for UTF-16 surrogate halves,
|
||||
// values ending in FFFE or FFFF, or values in the 0x00FDD0-0x00FDEF reserved range
|
||||
return ( uVal < 0x110000u ) && ( ( uVal - 0x00D800u ) > 0x7FFu ) && ( ( uVal & 0xFFFFu ) < 0xFFFEu ) && ( ( uVal - 0x00FDD0u ) > 0x1Fu );
|
||||
}
|
||||
|
||||
// Decode one character from a UTF-8 encoded string. Treats 6-byte CESU-8 sequences
|
||||
// as a single character, as if they were a correctly-encoded 4-byte UTF-8 sequence.
|
||||
int Q_UTF8ToUChar32( const char *pUTF8_, unsigned int &uValueOut, bool &bErrorOut )
|
||||
{
|
||||
const unsigned char *pUTF8 = (const unsigned char*)pUTF8_;
|
||||
|
||||
int nBytes = 1;
|
||||
unsigned int uValue = pUTF8[0];
|
||||
unsigned int uMinValue = 0;
|
||||
|
||||
// 0....... single byte
|
||||
if( uValue < 0x80 )
|
||||
goto decodeFinishedNoCheck;
|
||||
|
||||
// Expecting at least a two-byte sequence with 0xC0 <= first <= 0xF7 (110...... and 11110...)
|
||||
if( ( uValue - 0xC0u ) > 0x37u || ( pUTF8[1] & 0xC0 ) != 0x80 )
|
||||
goto decodeError;
|
||||
|
||||
uValue = ( uValue << 6 ) - ( 0xC0 << 6 ) + pUTF8[1] - 0x80;
|
||||
nBytes = 2;
|
||||
uMinValue = 0x80;
|
||||
|
||||
// 110..... two-byte lead byte
|
||||
if( !( uValue & ( 0x20 << 6 ) ) )
|
||||
goto decodeFinished;
|
||||
|
||||
// Expecting at least a three-byte sequence
|
||||
if( ( pUTF8[2] & 0xC0 ) != 0x80 )
|
||||
goto decodeError;
|
||||
|
||||
uValue = ( uValue << 6 ) - ( 0x20 << 12 ) + pUTF8[2] - 0x80;
|
||||
nBytes = 3;
|
||||
uMinValue = 0x800;
|
||||
|
||||
// 1110.... three-byte lead byte
|
||||
decodeFinished:
|
||||
if( uValue >= uMinValue && Q_IsValidUChar32( uValue ) )
|
||||
{
|
||||
decodeFinishedNoCheck:
|
||||
uValueOut = uValue;
|
||||
bErrorOut = false;
|
||||
return nBytes;
|
||||
}
|
||||
decodeError:
|
||||
uValueOut = '?';
|
||||
bErrorOut = true;
|
||||
return nBytes;
|
||||
|
||||
decodeFinishedMaybeCESU8:
|
||||
// Do we have a full UTF-16 surrogate pair that's been UTF-8 encoded afterwards?
|
||||
// That is, do we have 0xD800-0xDBFF followed by 0xDC00-0xDFFF? If so, decode it all.
|
||||
if( ( uValue - 0xD800u ) < 0x400u && pUTF8[3] == 0xED && (unsigned char)( pUTF8[4] - 0xB0 ) < 0x10 && ( pUTF8[5] & 0xC0 ) == 0x80 )
|
||||
{
|
||||
uValue = 0x10000 + ( ( uValue - 0xD800u ) << 10 ) + ( (unsigned char)( pUTF8[4] - 0xB0 ) << 6 ) + pUTF8[5] - 0x80;
|
||||
nBytes = 6;
|
||||
uMinValue = 0x10000;
|
||||
}
|
||||
goto decodeFinished;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if UTF-8 string contains invalid sequences.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_UnicodeValidate( const char *pUTF8 )
|
||||
{
|
||||
bool bError = false;
|
||||
while( *pUTF8 )
|
||||
{
|
||||
unsigned int uVal;
|
||||
// Our UTF-8 decoder silently fixes up 6-byte CESU-8 (improperly re-encoded UTF-16) sequences.
|
||||
// However, these are technically not valid UTF-8. So if we eat 6 bytes at once, it's an error.
|
||||
int nCharSize = Q_UTF8ToUChar32( pUTF8, uVal, bError );
|
||||
if( bError || nCharSize == 6 )
|
||||
return false;
|
||||
pUTF8 += nCharSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//// HOST_SAY
|
||||
// String comes in as
|
||||
// say blah blah blah
|
||||
@ -265,20 +358,13 @@ void Host_Say( edict_t *pEntity, int teamonly )
|
||||
p[strlen( p ) - 1] = 0;
|
||||
}
|
||||
|
||||
// make sure the text has content
|
||||
for( pc = p; pc != NULL && *pc != 0; pc++ )
|
||||
{
|
||||
if( !isspace( *pc ) )
|
||||
{
|
||||
pc = NULL; // we've found an alphanumeric character, so text is valid
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( pc != NULL )
|
||||
if( !p || !p[0] || !Q_UnicodeValidate ( p ) )
|
||||
return; // no character found, so say nothing
|
||||
|
||||
// turn on color set 2 (color on, no sound)
|
||||
if( teamonly )
|
||||
if( player->IsObserver() && ( teamonly ) )
|
||||
sprintf( text, "%c(SPEC) %s: ", 2, STRING( pEntity->v.netname ) );
|
||||
else if( teamonly )
|
||||
sprintf( text, "%c(TEAM) %s: ", 2, STRING( pEntity->v.netname ) );
|
||||
else
|
||||
sprintf( text, "%c%s: ", 2, STRING( pEntity->v.netname ) );
|
||||
@ -313,9 +399,14 @@ void Host_Say( edict_t *pEntity, int teamonly )
|
||||
if( g_VoiceGameMgr.PlayerHasBlockedPlayer( client, player ) )
|
||||
continue;
|
||||
#endif
|
||||
if( teamonly && g_pGameRules->PlayerRelationship( client, CBaseEntity::Instance( pEntity ) ) != GR_TEAMMATE )
|
||||
if( !player->IsObserver() && teamonly && g_pGameRules->PlayerRelationship( client, CBaseEntity::Instance( pEntity ) ) != GR_TEAMMATE )
|
||||
continue;
|
||||
|
||||
// Spectators can only talk to other specs
|
||||
if( player->IsObserver() && teamonly )
|
||||
if ( !client->IsObserver() )
|
||||
continue;
|
||||
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, client->pev );
|
||||
WRITE_BYTE( ENTINDEX( pEntity ) );
|
||||
WRITE_STRING( text );
|
||||
@ -459,12 +550,40 @@ void ClientCommand( edict_t *pEntity )
|
||||
{
|
||||
GetClassPtr( (CBasePlayer *)pev )->SelectLastItem();
|
||||
}
|
||||
else if( FStrEq( pcmd, "spectate" ) && ( pev->flags & FL_PROXY ) ) // added for proxy support
|
||||
else if( FStrEq( pcmd, "spectate" ) // clients wants to become a spectator
|
||||
{
|
||||
CBasePlayer * pPlayer = GetClassPtr( (CBasePlayer *)pev );
|
||||
// always allow proxies to become a spectator
|
||||
if( ( pev->flags & FL_PROXY ) || allow_spectators.value )
|
||||
{
|
||||
CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev );
|
||||
|
||||
edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer );
|
||||
pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles );
|
||||
edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer );
|
||||
pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles );
|
||||
|
||||
// notify other clients of player switching to spectator mode
|
||||
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s switched to spectator mode\n",
|
||||
( pev->netname && STRING(pev->netname)[0] != 0 ) ? STRING(pev->netname) : "unconnected" ) );
|
||||
}
|
||||
else
|
||||
ClientPrint( pev, HUD_PRINTCONSOLE, "Spectator mode is disabled.\n" );
|
||||
}
|
||||
else if( FStrEq( pcmd, "specmode" ) ) // new spectator mode
|
||||
{
|
||||
CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev );
|
||||
|
||||
if( pPlayer->IsObserver() )
|
||||
pPlayer->Observer_SetMode( atoi( CMD_ARGV( 1 ) ) );
|
||||
}
|
||||
else if( FStrEq( pcmd, "closemenus" ) )
|
||||
{
|
||||
// just ignore it
|
||||
}
|
||||
else if( FStrEq( pcmd, "follownext" ) ) // follow next player
|
||||
{
|
||||
CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev );
|
||||
|
||||
if( pPlayer->IsObserver() )
|
||||
pPlayer->Observer_FindNextPlayer( atoi( CMD_ARGV( 1 ) ) ? true : false );
|
||||
}
|
||||
else if( g_pGameRules->ClientCommand( GetClassPtr( (CBasePlayer *)pev ), pcmd ) )
|
||||
{
|
||||
@ -524,12 +643,15 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
|
||||
// Set the name
|
||||
g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), infobuffer, "name", sName );
|
||||
|
||||
char text[256];
|
||||
snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) );
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL );
|
||||
WRITE_BYTE( ENTINDEX( pEntity ) );
|
||||
WRITE_STRING( text );
|
||||
MESSAGE_END();
|
||||
if( gpGlobals->maxClients > 1 )
|
||||
{
|
||||
char text[256];
|
||||
snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) );
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL );
|
||||
WRITE_BYTE( ENTINDEX( pEntity ) );
|
||||
WRITE_STRING( text );
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
// team match?
|
||||
if( g_teamplay )
|
||||
@ -983,7 +1105,7 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
|
||||
int i;
|
||||
|
||||
// don't send if flagged for NODRAW and it's not the host getting the message
|
||||
if( ( ent->v.effects == EF_NODRAW ) && ( ent != host ) )
|
||||
if( ( ent->v.effects & EF_NODRAW ) && ( ent != host ) )
|
||||
return 0;
|
||||
|
||||
// Ignore ents without valid / visible models
|
||||
@ -1553,41 +1675,67 @@ engine sets cd to 0 before calling.
|
||||
*/
|
||||
void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd )
|
||||
{
|
||||
cd->flags = ent->v.flags;
|
||||
cd->health = ent->v.health;
|
||||
if( !ent || !ent->pvPrivateData )
|
||||
return;
|
||||
entvars_t *pev = (entvars_t *)&ent->v;
|
||||
CBasePlayer *pl = (CBasePlayer *)( CBasePlayer::Instance( pev ) );
|
||||
entvars_t *pevOrg = NULL;
|
||||
|
||||
cd->viewmodel = MODEL_INDEX( STRING( ent->v.viewmodel ) );
|
||||
// if user is spectating different player in First person, override some vars
|
||||
if( pl && pl->pev->iuser1 == OBS_IN_EYE )
|
||||
{
|
||||
if( pl->m_hObserverTarget )
|
||||
{
|
||||
pevOrg = pev;
|
||||
pev = pl->m_hObserverTarget->pev;
|
||||
pl = (CBasePlayer *)(CBasePlayer::Instance( pev ) );
|
||||
}
|
||||
}
|
||||
|
||||
cd->waterlevel = ent->v.waterlevel;
|
||||
cd->watertype = ent->v.watertype;
|
||||
cd->weapons = ent->v.weapons;
|
||||
cd->flags = pev->flags;
|
||||
cd->health = pev->health;
|
||||
|
||||
cd->viewmodel = MODEL_INDEX( STRING( pev->viewmodel ) );
|
||||
|
||||
cd->waterlevel = pev->waterlevel;
|
||||
cd->watertype = pev->watertype;
|
||||
cd->weapons = pev->weapons;
|
||||
|
||||
// Vectors
|
||||
cd->origin = ent->v.origin;
|
||||
cd->velocity = ent->v.velocity;
|
||||
cd->view_ofs = ent->v.view_ofs;
|
||||
cd->punchangle = ent->v.punchangle;
|
||||
cd->origin = pev->origin;
|
||||
cd->velocity = pev->velocity;
|
||||
cd->view_ofs = pev->view_ofs;
|
||||
cd->punchangle = pev->punchangle;
|
||||
|
||||
cd->bInDuck = ent->v.bInDuck;
|
||||
cd->flTimeStepSound = ent->v.flTimeStepSound;
|
||||
cd->flDuckTime = ent->v.flDuckTime;
|
||||
cd->flSwimTime = ent->v.flSwimTime;
|
||||
cd->waterjumptime = ent->v.teleport_time;
|
||||
cd->bInDuck = pev->bInDuck;
|
||||
cd->flTimeStepSound = pev->flTimeStepSound;
|
||||
cd->flDuckTime = pev->flDuckTime;
|
||||
cd->flSwimTime = pev->flSwimTime;
|
||||
cd->waterjumptime = pev->teleport_time;
|
||||
|
||||
strcpy( cd->physinfo, ENGINE_GETPHYSINFO( ent ) );
|
||||
|
||||
cd->maxspeed = ent->v.maxspeed;
|
||||
cd->fov = ent->v.fov;
|
||||
cd->weaponanim = ent->v.weaponanim;
|
||||
cd->maxspeed = pev->maxspeed;
|
||||
cd->fov = pev->fov;
|
||||
cd->weaponanim = pev->weaponanim;
|
||||
|
||||
cd->pushmsec = ent->v.pushmsec;
|
||||
cd->pushmsec = pev->pushmsec;
|
||||
|
||||
// Spectator mode
|
||||
if( pevOrg != NULL )
|
||||
{
|
||||
// don't use spec vars from chased player
|
||||
cd->iuser1 = pevOrg->iuser1;
|
||||
cd->iuser2 = pevOrg->iuser2;
|
||||
}
|
||||
else
|
||||
{
|
||||
cd->iuser1 = pev->iuser1;
|
||||
cd->iuser2 = pev->iuser2;
|
||||
}
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
if( sendweapons )
|
||||
{
|
||||
entvars_t *pev = (entvars_t *)&ent->v;
|
||||
CBasePlayer *pl = (CBasePlayer *)CBasePlayer::Instance( pev );
|
||||
|
||||
if( pl )
|
||||
{
|
||||
cd->m_flNextAttack = pl->m_flNextAttack;
|
||||
|
@ -353,7 +353,7 @@ void CCrossbow::PrimaryAttack( void )
|
||||
// this function only gets called in multiplayer
|
||||
void CCrossbow::FireSniperBolt()
|
||||
{
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 );
|
||||
|
||||
if( m_iClip == 0 )
|
||||
{
|
||||
@ -451,7 +451,7 @@ void CCrossbow::FireBolt()
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 );
|
||||
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
LINK_ENTITY_TO_CLASS( weapon_crowbar, CCrowbar )
|
||||
|
||||
enum gauss_e
|
||||
enum crowbar_e
|
||||
{
|
||||
CROWBAR_IDLE = 0,
|
||||
CROWBAR_DRAW,
|
||||
@ -40,8 +40,7 @@ enum gauss_e
|
||||
CROWBAR_ATTACK3HIT
|
||||
};
|
||||
|
||||
|
||||
void CCrowbar::Spawn( )
|
||||
void CCrowbar::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_CROWBAR;
|
||||
@ -191,7 +190,7 @@ int CCrowbar::Swing( int fFirst )
|
||||
if( fFirst )
|
||||
{
|
||||
// miss
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
@ -297,7 +296,7 @@ int CCrowbar::Swing( int fFirst )
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 );
|
||||
|
||||
SetThink( &CCrowbar::Smack );
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
|
@ -1100,19 +1100,22 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP
|
||||
Vector move = m_vecPosition1 + ( value * ( m_vecPosition2 - m_vecPosition1 ) );
|
||||
|
||||
Vector delta = move - pev->origin;
|
||||
float speed = delta.Length() * 10;
|
||||
//float speed = delta.Length() * 10;
|
||||
float speed = delta.Length() / 0.1; // move there in 0.1 sec
|
||||
|
||||
if( speed != 0 )
|
||||
{
|
||||
// This entity only thinks when it moves, so if it's thinking, it's in the process of moving
|
||||
// play the sound when it starts moving
|
||||
// play the sound when it starts moving(not yet thinking)
|
||||
if( pev->nextthink < pev->ltime || pev->nextthink == 0 )
|
||||
EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ), 1, ATTN_NORM );
|
||||
// If we already moving to designated point, return
|
||||
else if( move == m_vecFinalDest )
|
||||
return;
|
||||
|
||||
LinearMove( move, speed );
|
||||
SetMoveDone( &CMomentaryDoor::MomentaryMoveDone );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMomentaryDoor::MomentaryMoveDone( void )
|
||||
|
@ -44,7 +44,7 @@
|
||||
#else // _WIN32
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned int ULONG;
|
||||
typedef unsigned char BYTE;
|
||||
typedef int BOOL;
|
||||
#define MAX_PATH PATH_MAX
|
||||
|
@ -39,6 +39,8 @@ cvar_t teamoverride = { "mp_teamoverride","1" };
|
||||
cvar_t defaultteam = { "mp_defaultteam","0" };
|
||||
cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER };
|
||||
|
||||
cvar_t allow_spectators = { "allow_spectators", "0", FCVAR_SERVER }; // 0 prevents players from being spectators
|
||||
|
||||
cvar_t mp_chattime = { "mp_chattime","10", FCVAR_SERVER };
|
||||
|
||||
// Engine Cvars
|
||||
|
@ -145,7 +145,7 @@ void CGauss::PrimaryAttack()
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ void CGauss::SecondaryAttack()
|
||||
PlayEmptySound();
|
||||
}
|
||||
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ void CHandGrenade::WeaponIdle( void )
|
||||
|
||||
m_flReleaseThrow = 0;
|
||||
m_flStartThrow = 0;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
@ -180,7 +180,7 @@ void CHandGrenade::WeaponIdle( void )
|
||||
// just threw last grenade
|
||||
// set attack times in the future, and weapon idle in the future so we can see the whole throw
|
||||
// animation, weapon idle will automatically retire the weapon for us.
|
||||
m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;// ensure that the animation can finish playing
|
||||
m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );// ensure that the animation can finish playing
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ void CMP5::PrimaryAttack()
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.1 );
|
||||
|
||||
if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() )
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
|
||||
@ -227,7 +227,7 @@ void CMP5::SecondaryAttack( void )
|
||||
#endif
|
||||
PLAYBACK_EVENT( flags, m_pPlayer->edict(), m_usMP52 );
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 1 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5;// idle pretty soon after shooting.
|
||||
|
||||
|
@ -92,7 +92,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay()
|
||||
if( IS_DEDICATED_SERVER() )
|
||||
{
|
||||
// dedicated server
|
||||
char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" );
|
||||
/*char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" );
|
||||
|
||||
if( servercfgfile && servercfgfile[0] )
|
||||
{
|
||||
@ -102,6 +102,8 @@ CHalfLifeMultiplay::CHalfLifeMultiplay()
|
||||
sprintf( szCommand, "exec %s\n", servercfgfile );
|
||||
SERVER_COMMAND( szCommand );
|
||||
}
|
||||
*/
|
||||
// this code has been moved into engine, to only run server.cfg once
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1185,8 +1185,22 @@ void CNihilanth::CommandUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_
|
||||
case USE_OFF:
|
||||
{
|
||||
CBaseEntity *pTouch = UTIL_FindEntityByTargetname( NULL, m_szDeadTouch );
|
||||
if( pTouch && m_hEnemy != NULL )
|
||||
pTouch->Touch( m_hEnemy );
|
||||
if( pTouch )
|
||||
{
|
||||
if( m_hEnemy != NULL )
|
||||
{
|
||||
pTouch->Touch( m_hEnemy );
|
||||
}
|
||||
// if the player is using "notarget", the ending sequence won't fire unless we catch it here
|
||||
else
|
||||
{
|
||||
CBaseEntity *pEntity = UTIL_FindEntityByClassname( NULL, "player" );
|
||||
if( pEntity != NULL && pEntity->IsAlive() )
|
||||
{
|
||||
pTouch->Touch( pEntity );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case USE_ON:
|
||||
|
115
dlls/player.cpp
115
dlls/player.cpp
@ -34,6 +34,7 @@
|
||||
#include "decals.h"
|
||||
#include "gamerules.h"
|
||||
#include "game.h"
|
||||
#include "pm_shared.h"
|
||||
#include "hltv.h"
|
||||
|
||||
// #define DUCKFIX
|
||||
@ -201,7 +202,8 @@ void LinkUserMessages( void )
|
||||
gmsgDamage = REG_USER_MSG( "Damage", 12 );
|
||||
gmsgBattery = REG_USER_MSG( "Battery", 2);
|
||||
gmsgTrain = REG_USER_MSG( "Train", 1 );
|
||||
gmsgHudText = REG_USER_MSG( "HudText", -1 );
|
||||
//gmsgHudText = REG_USER_MSG( "HudTextPro", -1 );
|
||||
gmsgHudText = REG_USER_MSG( "HudText", -1 ); // we don't use the message but 3rd party addons may!
|
||||
gmsgSayText = REG_USER_MSG( "SayText", -1 );
|
||||
gmsgTextMsg = REG_USER_MSG( "TextMsg", -1 );
|
||||
gmsgWeaponList = REG_USER_MSG( "WeaponList", -1 );
|
||||
@ -785,6 +787,12 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit )
|
||||
|
||||
m_pLastItem = NULL;
|
||||
|
||||
if( m_pTank != NULL )
|
||||
{
|
||||
m_pTank->Use( this, this, USE_OFF, 0 );
|
||||
m_pTank = NULL;
|
||||
}
|
||||
|
||||
int i;
|
||||
CBasePlayerItem *pPendingItem;
|
||||
for( i = 0; i < MAX_ITEM_TYPES; i++ )
|
||||
@ -1297,6 +1305,9 @@ void CBasePlayer::PlayerDeathThink( void )
|
||||
StartDeathCam();
|
||||
}
|
||||
|
||||
if( pev->iuser1 ) // player is in spectator mode
|
||||
return;
|
||||
|
||||
// wait for any button down, or mp_forcerespawn is set and the respawn time is up
|
||||
if( !fAnyButtonDown && !( g_pGameRules->IsMultiplayer() && forcerespawn.value > 0 && ( gpGlobals->time > ( m_fDeadTime + 5 ) ) ) )
|
||||
return;
|
||||
@ -1345,7 +1356,9 @@ void CBasePlayer::StartDeathCam( void )
|
||||
}
|
||||
|
||||
CopyToBodyQue( pev );
|
||||
StartObserver( pSpot->v.origin, pSpot->v.v_angle );
|
||||
|
||||
UTIL_SetOrigin( pev, pSpot->v.origin );
|
||||
pev->angles = pev->v_angle = pSpot->v.v_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1353,23 +1366,89 @@ void CBasePlayer::StartDeathCam( void )
|
||||
TraceResult tr;
|
||||
CopyToBodyQue( pev );
|
||||
UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, 128 ), ignore_monsters, edict(), &tr );
|
||||
StartObserver( tr.vecEndPos, UTIL_VecToAngles( tr.vecEndPos - pev->origin ) );
|
||||
return;
|
||||
|
||||
UTIL_SetOrigin( pev, tr.vecEndPos );
|
||||
pev->angles = pev->v_angle = UTIL_VecToAngles( tr.vecEndPos - pev->origin );
|
||||
}
|
||||
|
||||
// start death cam
|
||||
m_afPhysicsFlags |= PFLAG_OBSERVER;
|
||||
pev->view_ofs = g_vecZero;
|
||||
pev->fixangle = TRUE;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->modelindex = 0;
|
||||
}
|
||||
|
||||
void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle )
|
||||
{
|
||||
m_afPhysicsFlags |= PFLAG_OBSERVER;
|
||||
// clear any clientside entities attached to this player
|
||||
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
|
||||
WRITE_BYTE( TE_KILLPLAYERATTACHMENTS );
|
||||
WRITE_BYTE( (BYTE)entindex() );
|
||||
MESSAGE_END();
|
||||
|
||||
// Holster weapon immediately, to allow it to cleanup
|
||||
if( m_pActiveItem )
|
||||
m_pActiveItem->Holster();
|
||||
|
||||
if( m_pTank != NULL )
|
||||
{
|
||||
m_pTank->Use( this, this, USE_OFF, 0 );
|
||||
m_pTank = NULL;
|
||||
}
|
||||
|
||||
// clear out the suit message cache so we don't keep chattering
|
||||
SetSuitUpdate( NULL, FALSE, 0 );
|
||||
|
||||
// Tell Ammo Hud that the player is dead
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
|
||||
WRITE_BYTE( 0 );
|
||||
WRITE_BYTE( 0XFF );
|
||||
WRITE_BYTE( 0xFF );
|
||||
MESSAGE_END();
|
||||
|
||||
// reset FOV
|
||||
m_iFOV = m_iClientFOV = 0;
|
||||
pev->fov = m_iFOV;
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev );
|
||||
WRITE_BYTE( 0 );
|
||||
MESSAGE_END();
|
||||
|
||||
// Setup flags
|
||||
m_iHideHUD = ( HIDEHUD_HEALTH | HIDEHUD_WEAPONS );
|
||||
m_afPhysicsFlags |= PFLAG_OBSERVER;
|
||||
pev->effects = EF_NODRAW;
|
||||
pev->view_ofs = g_vecZero;
|
||||
pev->angles = pev->v_angle = vecViewAngle;
|
||||
pev->fixangle = TRUE;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->modelindex = 0;
|
||||
ClearBits( m_afPhysicsFlags, PFLAG_DUCKING );
|
||||
ClearBits( pev->flags, FL_DUCKING );
|
||||
pev->deadflag = DEAD_RESPAWNABLE;
|
||||
pev->health = 1;
|
||||
|
||||
// Clear out the status bar
|
||||
m_fInitHUD = TRUE;
|
||||
|
||||
pev->team = 0;
|
||||
MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo );
|
||||
WRITE_BYTE( ENTINDEX(edict()) );
|
||||
WRITE_STRING( "" );
|
||||
MESSAGE_END();
|
||||
|
||||
// Remove all the player's stuff
|
||||
RemoveAllItems( FALSE );
|
||||
|
||||
// Move them to the new position
|
||||
UTIL_SetOrigin( pev, vecPosition );
|
||||
|
||||
// Find a player to watch
|
||||
m_flNextObserverInput = 0;
|
||||
Observer_SetMode( m_iObserverLastMode );
|
||||
}
|
||||
|
||||
//
|
||||
@ -1379,6 +1458,9 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle )
|
||||
|
||||
void CBasePlayer::PlayerUse( void )
|
||||
{
|
||||
if( IsObserver() )
|
||||
return;
|
||||
|
||||
// Was use pressed or released?
|
||||
if( !( ( pev->button | m_afButtonPressed | m_afButtonReleased) & IN_USE ) )
|
||||
return;
|
||||
@ -1747,6 +1829,16 @@ void CBasePlayer::PreThink( void )
|
||||
|
||||
CheckSuitUpdate();
|
||||
|
||||
// Observer Button Handling
|
||||
if( IsObserver() )
|
||||
{
|
||||
Observer_HandleButtons();
|
||||
Observer_CheckTarget();
|
||||
Observer_CheckProperties();
|
||||
pev->impulse = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if( pev->deadflag >= DEAD_DYING )
|
||||
{
|
||||
PlayerDeathThink();
|
||||
@ -3767,6 +3859,9 @@ void CBasePlayer::UpdateClientData( void )
|
||||
|
||||
g_pGameRules->InitHUD( this );
|
||||
m_fGameHUDInitialized = TRUE;
|
||||
|
||||
m_iObserverLastMode = OBS_ROAMING;
|
||||
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
FireTargets( "game_playerjoin", this, this, USE_TOGGLE, 0 );
|
||||
@ -3807,7 +3902,10 @@ void CBasePlayer::UpdateClientData( void )
|
||||
|
||||
if( pev->health != m_iClientHealth )
|
||||
{
|
||||
int iHealth = max( pev->health, 0 ); // make sure that no negative health values are sent
|
||||
#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) )
|
||||
int iHealth = clamp( pev->health, 0, 255 ); // make sure that no negative health values are sent
|
||||
if( pev->health > 0.0f && pev->health <= 1.0f )
|
||||
iHealth = 1;
|
||||
|
||||
// send "health" update message
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev );
|
||||
@ -4336,7 +4434,8 @@ void CBasePlayer::DropPlayerItem( char *pszItemName )
|
||||
// item we want to drop and hit a BREAK; pWeapon is the item.
|
||||
if( pWeapon )
|
||||
{
|
||||
g_pGameRules->GetNextBestWeapon( this, pWeapon );
|
||||
if( !g_pGameRules->GetNextBestWeapon( this, pWeapon ) )
|
||||
return; // can't drop the item they asked for, may be our last item or something we can't holster
|
||||
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
|
||||
|
@ -86,6 +86,18 @@ enum sbar_data
|
||||
class CBasePlayer : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
// Spectator camera
|
||||
void Observer_FindNextPlayer( bool bReverse );
|
||||
void Observer_HandleButtons();
|
||||
void Observer_SetMode( int iMode );
|
||||
void Observer_CheckTarget();
|
||||
void Observer_CheckProperties();
|
||||
EHANDLE m_hObserverTarget;
|
||||
float m_flNextObserverInput;
|
||||
int m_iObserverWeapon; // weapon of current tracked target
|
||||
int m_iObserverLastMode;// last used observer mode
|
||||
int IsObserver() { return pev->iuser1; };
|
||||
|
||||
int random_seed; // See that is shared between client & server for shared weapons code
|
||||
|
||||
int m_iPlayerSound;// the index of the sound list slot reserved for this player
|
||||
|
@ -297,7 +297,7 @@ void CRpg::Reload( void )
|
||||
// Set the next attack time into the future so that WeaponIdle will get called more often
|
||||
// than reload, allowing the RPG LTD to be updated
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
|
||||
if( m_cActiveRockets && m_fSpotActive )
|
||||
{
|
||||
@ -463,7 +463,7 @@ void CRpg::PrimaryAttack()
|
||||
|
||||
m_iClip--;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5;
|
||||
}
|
||||
else
|
||||
|
@ -354,7 +354,7 @@ void CSatchel::PrimaryAttack()
|
||||
}
|
||||
|
||||
m_chargeReady = 2;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
break;
|
||||
@ -401,7 +401,7 @@ void CSatchel::Throw( void )
|
||||
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.0;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 1.0 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
}
|
||||
}
|
||||
@ -442,7 +442,7 @@ void CSatchel::WeaponIdle( void )
|
||||
// use tripmine animations
|
||||
strcpy( m_pPlayer->m_szAnimExtention, "trip" );
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_chargeReady = 0;
|
||||
break;
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
void WriteVector( const char *pname, const float *value, int count ); // Save a vector
|
||||
void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary
|
||||
void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors
|
||||
void WriteFunction( const char *pname, const int *value, int count ); // Save a function pointer
|
||||
void WriteFunction( const char *pname, void **value, int count ); // Save a function pointer
|
||||
int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t)
|
||||
int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount );
|
||||
|
||||
|
@ -119,7 +119,7 @@ void CShotgun::PrimaryAttack()
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ void CShotgun::PrimaryAttack()
|
||||
if( m_iClip != 0 )
|
||||
m_flPumpTime = gpGlobals->time + 0.5;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75;
|
||||
if( m_iClip != 0 )
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0;
|
||||
@ -187,7 +187,7 @@ void CShotgun::SecondaryAttack( void )
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ void CShotgun::SecondaryAttack( void )
|
||||
if( m_iClip != 0 )
|
||||
m_flPumpTime = gpGlobals->time + 0.95;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
if( m_iClip != 0 )
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 6.0;
|
||||
@ -269,7 +269,7 @@ void CShotgun::Reload( void )
|
||||
m_fInSpecialReload = 1;
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.6;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6;
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.0;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 1.0 );
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0;
|
||||
return;
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ void CSqueak::PrimaryAttack()
|
||||
|
||||
m_fJustThrown = 1;
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.3;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.3 );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0;
|
||||
}
|
||||
}
|
||||
|
@ -415,6 +415,14 @@ After moving, set origin to exact final destination, call "move done" function
|
||||
*/
|
||||
void CBaseToggle::LinearMoveDone( void )
|
||||
{
|
||||
Vector delta = m_vecFinalDest - pev->origin;
|
||||
float error = delta.Length();
|
||||
if( error > 0.03125 )
|
||||
{
|
||||
LinearMove( m_vecFinalDest, 100 );
|
||||
return;
|
||||
}
|
||||
|
||||
UTIL_SetOrigin( pev, m_vecFinalDest );
|
||||
pev->velocity = g_vecZero;
|
||||
pev->nextthink = -1;
|
||||
|
@ -688,7 +688,7 @@ void PlayCDTrack( int iTrack )
|
||||
|
||||
if( iTrack == -1 )
|
||||
{
|
||||
CLIENT_COMMAND( pClient, "cd pause\n" );
|
||||
CLIENT_COMMAND( pClient, "cd stop\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -470,7 +470,7 @@ void CTripmine::PrimaryAttack( void )
|
||||
|
||||
}*/
|
||||
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.3;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay( 0.3 );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
}
|
||||
|
||||
|
@ -1886,7 +1886,7 @@ void CSave::WritePositionVector( const char *pname, const float *value, int coun
|
||||
}
|
||||
}
|
||||
|
||||
void CSave::WriteFunction( const char *pname, const int *data, int count )
|
||||
void CSave::WriteFunction( const char *pname, void **data, int count )
|
||||
{
|
||||
const char *functionName;
|
||||
|
||||
@ -2042,7 +2042,7 @@ int CSave::WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFi
|
||||
WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
case FIELD_FUNCTION:
|
||||
WriteFunction( pTest->fieldName, (int *)pOutputData, pTest->fieldSize );
|
||||
WriteFunction( pTest->fieldName, (void **)pOutputData, pTest->fieldSize );
|
||||
break;
|
||||
default:
|
||||
ALERT( at_error, "Bad field type\n" );
|
||||
|
@ -37,7 +37,7 @@ extern globalvars_t *gpGlobals;
|
||||
#define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset)
|
||||
|
||||
#if !defined __amd64__ || defined(CLIENT_DLL)
|
||||
#define MAKE_STRING(str) ((int)(size_t)str - (int)(size_t)STRING(0))
|
||||
#define MAKE_STRING(str) ((size_t)str - (size_t)STRING(0))
|
||||
#else
|
||||
#define MAKE_STRING ALLOC_STRING
|
||||
#endif
|
||||
|
@ -612,6 +612,11 @@ void CBasePlayerWeapon::ItemPostFrame( void )
|
||||
m_fInReload = FALSE;
|
||||
}
|
||||
|
||||
if( !(m_pPlayer->pev->button & IN_ATTACK ) )
|
||||
{
|
||||
m_flLastFireTime = 0.0f;
|
||||
}
|
||||
|
||||
if( ( m_pPlayer->pev->button & IN_ATTACK2 ) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) )
|
||||
{
|
||||
if( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] )
|
||||
@ -943,6 +948,7 @@ BOOL CBasePlayerWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, i
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0;
|
||||
m_flLastFireTime = 0.0f;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1130,6 +1136,36 @@ void CBasePlayerWeapon::RetireWeapon( void )
|
||||
g_pGameRules->GetNextBestWeapon( m_pPlayer, this );
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetNextAttackDelay - An accurate way of calcualting the next attack time.
|
||||
//=========================================================================
|
||||
float CBasePlayerWeapon::GetNextAttackDelay( float delay )
|
||||
{
|
||||
if( m_flLastFireTime == 0 || m_flNextPrimaryAttack == -1 )
|
||||
{
|
||||
// At this point, we are assuming that the client has stopped firing
|
||||
// and we are going to reset our book keeping variables.
|
||||
m_flLastFireTime = gpGlobals->time;
|
||||
m_flPrevPrimaryAttack = delay;
|
||||
}
|
||||
// calculate the time between this shot and the previous
|
||||
float flTimeBetweenFires = gpGlobals->time - m_flLastFireTime;
|
||||
float flCreep = 0.0f;
|
||||
if( flTimeBetweenFires > 0 )
|
||||
flCreep = flTimeBetweenFires - m_flPrevPrimaryAttack; // postive or negative
|
||||
|
||||
// save the last fire time
|
||||
m_flLastFireTime = gpGlobals->time;
|
||||
|
||||
float flNextAttack = UTIL_WeaponTimeBase() + delay - flCreep;
|
||||
// we need to remember what the m_flNextPrimaryAttack time is set to for each shot,
|
||||
// store it as m_flPrevPrimaryAttack.
|
||||
m_flPrevPrimaryAttack = flNextAttack - UTIL_WeaponTimeBase();
|
||||
//char szMsg[256];
|
||||
//_snprintf( szMsg, sizeof(szMsg), "next attack time: %0.4f\n", gpGlobals->time + flNextAttack );
|
||||
//OutputDebugString( szMsg );
|
||||
return flNextAttack;
|
||||
}
|
||||
//*********************************************************
|
||||
// weaponbox code:
|
||||
//*********************************************************
|
||||
|
@ -331,6 +331,7 @@ public:
|
||||
void PrintState( void );
|
||||
|
||||
virtual CBasePlayerItem *GetWeaponPtr( void ) { return (CBasePlayerItem *)this; };
|
||||
float GetNextAttackDelay( float delay );
|
||||
|
||||
float m_flPumpTime;
|
||||
int m_fInSpecialReload; // Are we in the middle of a reload for the shotguns
|
||||
@ -345,6 +346,10 @@ public:
|
||||
int m_fInReload; // Are we in the middle of a reload;
|
||||
|
||||
int m_iDefaultAmmo;// how much ammo you get when you pick up this weapon as placed by a level designer.
|
||||
|
||||
// hle time creep vars
|
||||
float m_flPrevPrimaryAttack;
|
||||
float m_flLastFireTime;
|
||||
};
|
||||
|
||||
class CBasePlayerAmmo : public CBaseEntity
|
||||
|
@ -169,13 +169,15 @@ void CZombie::IdleSound( void )
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
// Play a random idle sound
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) -1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) -1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
|
||||
void CZombie::AttackSound( void )
|
||||
{
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
// Play a random attack sound
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -57,7 +57,8 @@ typedef enum
|
||||
{
|
||||
force_exactfile, // File on client must exactly match server's file
|
||||
force_model_samebounds, // For model files only, the geometry must fit in the same bbox
|
||||
force_model_specifybounds // For model files only, the geometry must fit in the specified bbox
|
||||
force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox
|
||||
force_model_specifybounds_if_avail // For Steam model files only, the geometry must fit in the specified bbox (if the file is available)
|
||||
} FORCE_TYPE;
|
||||
|
||||
// Returned by TraceLine
|
||||
@ -88,7 +89,7 @@ typedef struct
|
||||
int fPlayTrack;
|
||||
} CDStatus;
|
||||
|
||||
typedef unsigned long CRC32_t;
|
||||
typedef unsigned int CRC32_t;
|
||||
|
||||
// Engine hands this to DLLs for functionality callbacks
|
||||
typedef struct enginefuncs_s
|
||||
@ -156,7 +157,7 @@ typedef struct enginefuncs_s
|
||||
void (*pfnCVarSetString)( const char *szVarName, const char *szValue );
|
||||
void (*pfnAlertMessage)( ALERT_TYPE atype, char *szFmt, ... );
|
||||
void (*pfnEngineFprintf)( FILE *pfile, char *szFmt, ... );
|
||||
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb );
|
||||
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, int cb );
|
||||
void* (*pfnPvEntPrivateData)( edict_t *pEdict );
|
||||
void (*pfnFreeEntPrivateData)( edict_t *pEdict );
|
||||
const char *(*pfnSzFromIndex)( int iString );
|
||||
@ -171,8 +172,8 @@ typedef struct enginefuncs_s
|
||||
int (*pfnRegUserMsg)( const char *pszName, int iSize );
|
||||
void (*pfnAnimationAutomove)( const edict_t* pEdict, float flTime );
|
||||
void (*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles );
|
||||
unsigned long (*pfnFunctionFromName)( const char *pName );
|
||||
const char *(*pfnNameForFunction)( unsigned long function );
|
||||
unsigned int (*pfnFunctionFromName)( const char *pName );
|
||||
const char *(*pfnNameForFunction)( unsigned int function );
|
||||
void (*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients
|
||||
void (*pfnServerPrint)( const char *szMsg );
|
||||
const char *(*pfnCmd_Args)( void ); // these 3 added
|
||||
@ -183,7 +184,7 @@ typedef struct enginefuncs_s
|
||||
void (*pfnCRC32_ProcessBuffer)( CRC32_t *pulCRC, void *p, int len );
|
||||
void (*pfnCRC32_ProcessByte)( CRC32_t *pulCRC, unsigned char ch );
|
||||
CRC32_t (*pfnCRC32_Final)( CRC32_t pulCRC );
|
||||
long (*pfnRandomLong)( long lLow, long lHigh );
|
||||
int (*pfnRandomLong)( int lLow, int lHigh );
|
||||
float (*pfnRandomFloat)( float flLow, float flHigh );
|
||||
void (*pfnSetView)( const edict_t *pClient, const edict_t *pViewent );
|
||||
float (*pfnTime)( void );
|
||||
@ -276,7 +277,7 @@ typedef struct KeyValueData_s
|
||||
char *szClassName; // in: entity classname
|
||||
char *szKeyName; // in: name of key
|
||||
char *szValue; // in: value of key
|
||||
long fHandled; // out: DLL sets to true if key-value pair was understood
|
||||
int fHandled; // out: DLL sets to true if key-value pair was understood
|
||||
} KeyValueData;
|
||||
|
||||
|
||||
@ -354,7 +355,7 @@ typedef enum _fieldtypes
|
||||
FIELD_TYPECOUNT // MUST BE LAST
|
||||
} FIELDTYPE;
|
||||
|
||||
#ifndef offsetof
|
||||
#if !defined(offsetof) && !defined(GNUC)
|
||||
#define offsetof(s,m) (size_t)&(((s *)0)->m)
|
||||
#endif
|
||||
|
||||
|
@ -36,7 +36,7 @@ extern int gmsgFade;
|
||||
#define FFADE_OUT 0x0001 // Fade out (not in)
|
||||
#define FFADE_MODULATE 0x0002 // Modulate (don't blend)
|
||||
#define FFADE_STAYOUT 0x0004 // ignores the duration, stays faded out until new ScreenFade message received
|
||||
|
||||
#define FFADE_LONGFADE 0x0008 // used to indicate the fade can be longer than 16 seconds (added for czero)
|
||||
|
||||
// This structure is sent over the net to describe a screen fade event
|
||||
typedef struct
|
||||
@ -47,4 +47,4 @@ typedef struct
|
||||
byte r, g, b, a; // fade to color ( max alpha )
|
||||
} ScreenFade;
|
||||
|
||||
#endif // SHAKE_H
|
||||
#endif // SHAKE_H
|
||||
|
@ -33,14 +33,14 @@ Studio models are position independent, so the cache manager can move them.
|
||||
// studio limits
|
||||
#define MAXSTUDIOTRIANGLES 32768 // max triangles per model
|
||||
#define MAXSTUDIOVERTS 4096 // max vertices per submodel
|
||||
#define MAXSTUDIOSEQUENCES 256 // total animation sequences
|
||||
#define MAXSTUDIOSEQUENCES 2048 // total animation sequences
|
||||
#define MAXSTUDIOSKINS 256 // total textures
|
||||
#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement
|
||||
#define MAXSTUDIOBONES 128 // total bones actually used
|
||||
#define MAXSTUDIOMODELS 32 // sub-models per model
|
||||
#define MAXSTUDIOBODYPARTS 32 // body parts per submodel
|
||||
#define MAXSTUDIOGROUPS 16 // sequence groups (e.g. barney01.mdl, barney02.mdl, e.t.c)
|
||||
#define MAXSTUDIOANIMATIONS 512 // max frames per sequence
|
||||
#define MAXSTUDIOANIMATIONS 2048 // max frames per sequence
|
||||
#define MAXSTUDIOMESHES 256 // max textures per model
|
||||
#define MAXSTUDIOEVENTS 1024 // events per model
|
||||
#define MAXSTUDIOPIVOTS 256 // pivot points
|
||||
@ -214,10 +214,8 @@ typedef struct
|
||||
{
|
||||
char label[32]; // textual name
|
||||
char name[64]; // file name
|
||||
cache_user_t cache; // cache index pointer
|
||||
#ifndef __amd64
|
||||
int data; // hack for group 0
|
||||
#endif
|
||||
int unused1; // // was "cache" - index pointer
|
||||
int unused2; // was "data" - hack for group 0
|
||||
} mstudioseqgroup_t;
|
||||
|
||||
// sequence descriptions
|
||||
|
@ -201,7 +201,7 @@ typedef struct playermove_s
|
||||
pmtrace_t (*PM_PlayerTrace)( float *start, float *end, int traceFlags, int ignore_pe );
|
||||
#endif
|
||||
struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehulll, int ignore_pe );
|
||||
long (*RandomLong)( long lLow, long lHigh );
|
||||
int (*RandomLong)( int lLow, int lHigh );
|
||||
float (*RandomFloat)( float flLow, float flHigh );
|
||||
int (*PM_GetModelType)( struct model_s *mod );
|
||||
void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs );
|
||||
|
@ -28,4 +28,5 @@
|
||||
#define CHAR_TEX_COMPUTER 'P'
|
||||
#define CHAR_TEX_GLASS 'Y'
|
||||
#define CHAR_TEX_FLESH 'F'
|
||||
#define CHAR_TEX_SNOW 'N'
|
||||
#endif//PM_MATERIALS_H
|
||||
|
@ -87,6 +87,8 @@ playermove_t *pmove = NULL;
|
||||
|
||||
#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump
|
||||
|
||||
#define PLAYER_DUCKING_MULTIPLIER 0.333
|
||||
|
||||
// double to float warning
|
||||
#pragma warning(disable : 4244)
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
@ -2017,9 +2019,9 @@ void PM_Duck( void )
|
||||
|
||||
if( pmove->flags & FL_DUCKING )
|
||||
{
|
||||
pmove->cmd.forwardmove *= 0.333;
|
||||
pmove->cmd.sidemove *= 0.333;
|
||||
pmove->cmd.upmove *= 0.333;
|
||||
pmove->cmd.forwardmove *= PLAYER_DUCKING_MULTIPLIER;
|
||||
pmove->cmd.sidemove *= PLAYER_DUCKING_MULTIPLIER;
|
||||
pmove->cmd.upmove *= PLAYER_DUCKING_MULTIPLIER;
|
||||
}
|
||||
|
||||
if( ( pmove->cmd.buttons & IN_DUCK ) || ( pmove->bInDuck ) || ( pmove->flags & FL_DUCKING ) )
|
||||
@ -2110,16 +2112,24 @@ void PM_LadderMove( physent_t *pLadder )
|
||||
{
|
||||
float forward = 0, right = 0;
|
||||
vec3_t vpn, v_right;
|
||||
float flSpeed = MAX_CLIMB_SPEED;
|
||||
|
||||
// they shouldn't be able to move faster than their maxspeed
|
||||
if( flSpeed > pmove->maxspeed )
|
||||
flSpeed = pmove->maxspeed;
|
||||
|
||||
AngleVectors( pmove->angles, vpn, v_right, NULL );
|
||||
|
||||
if( pmove->flags & FL_DUCKING )
|
||||
flSpeed *= PLAYER_DUCKING_MULTIPLIER;
|
||||
if( pmove->cmd.buttons & IN_BACK )
|
||||
forward -= MAX_CLIMB_SPEED;
|
||||
forward -= flSpeed;
|
||||
if( pmove->cmd.buttons & IN_FORWARD )
|
||||
forward += MAX_CLIMB_SPEED;
|
||||
forward += flSpeed;
|
||||
if( pmove->cmd.buttons & IN_MOVELEFT )
|
||||
right -= MAX_CLIMB_SPEED;
|
||||
right -= flSpeed;
|
||||
if( pmove->cmd.buttons & IN_MOVERIGHT )
|
||||
right += MAX_CLIMB_SPEED;
|
||||
right += flSpeed;
|
||||
|
||||
if( pmove->cmd.buttons & IN_JUMP )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user