Skip to content
This repository has been archived by the owner on May 4, 2022. It is now read-only.

Commit

Permalink
Merge some changes from git version of hlsdk.
Browse files Browse the repository at this point in the history
  • Loading branch information
nekonomicon committed Jun 26, 2017
1 parent fc276ad commit a522ae2
Show file tree
Hide file tree
Showing 36 changed files with 473 additions and 123 deletions.
11 changes: 8 additions & 3 deletions common/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion common/cvardef.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -34,4 +35,4 @@ typedef struct cvar_s
struct cvar_s *next;
} cvar_t;

#endif//CVARDEF_H
#endif//CVARDEF_H
6 changes: 5 additions & 1 deletion dlls/buttons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
4 changes: 2 additions & 2 deletions dlls/cbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ class CBaseEntity
#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 )
Expand Down
238 changes: 193 additions & 45 deletions dlls/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 ) );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );

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

edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer );
pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles );
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 ) )
{
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

// 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->viewmodel = MODEL_INDEX( STRING( ent->v.viewmodel ) );
cd->flags = pev->flags;
cd->health = pev->health;

cd->waterlevel = ent->v.waterlevel;
cd->watertype = ent->v.watertype;
cd->weapons = ent->v.weapons;
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;
Expand Down
Loading

0 comments on commit a522ae2

Please sign in to comment.