Merge some changes from git version of hlsdk.

This commit is contained in:
Night Owl 2017-06-26 05:47:19 +05:00
parent fc276ad52f
commit a522ae20c3
36 changed files with 473 additions and 123 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -688,7 +688,7 @@ void PlayCDTrack( int iTrack )
if( iTrack == -1 )
{
CLIENT_COMMAND( pClient, "cd pause\n" );
CLIENT_COMMAND( pClient, "cd stop\n" );
}
else
{

View File

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

View File

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

View File

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

View File

@ -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:
//*********************************************************

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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