mirror of
https://github.com/YGGverse/hlsdk-portable.git
synced 2025-02-08 21:14:14 +00:00
Merge
This commit is contained in:
commit
1bf208cf27
@ -993,7 +993,7 @@ void CHudSpectator::DrawOverviewLayer()
|
|||||||
if ( hasMapImage)
|
if ( hasMapImage)
|
||||||
{
|
{
|
||||||
i = m_MapSprite->numframes / (4*3);
|
i = m_MapSprite->numframes / (4*3);
|
||||||
i = sqrt(i);
|
i = sqrt(float(i));
|
||||||
xTiles = i*4;
|
xTiles = i*4;
|
||||||
yTiles = i*3;
|
yTiles = i*3;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ float rel_pitch;
|
|||||||
#define IMPULSE_DOWN 2
|
#define IMPULSE_DOWN 2
|
||||||
#define IMPULSE_UP 4
|
#define IMPULSE_UP 4
|
||||||
|
|
||||||
bool CL_IsDead();
|
int CL_IsDead( void );
|
||||||
Vector dead_viewangles(0, 0, 0);
|
Vector dead_viewangles(0, 0, 0);
|
||||||
|
|
||||||
void IN_ToggleButtons( float forwardmove, float sidemove )
|
void IN_ToggleButtons( float forwardmove, float sidemove )
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
|
|
||||||
extern vec3_t vec3_origin;
|
extern vec3_t vec3_origin;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
vec3_t vec3_origin;
|
||||||
|
#endif
|
||||||
|
|
||||||
double sqrt( double x );
|
double sqrt( double x );
|
||||||
|
|
||||||
float Length( const float *v )
|
float Length( const float *v )
|
||||||
|
@ -131,7 +131,8 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
|
|||||||
big_cock.cpp \
|
big_cock.cpp \
|
||||||
../pm_shared/pm_debug.c \
|
../pm_shared/pm_debug.c \
|
||||||
../pm_shared/pm_math.c \
|
../pm_shared/pm_math.c \
|
||||||
../pm_shared/pm_shared.c
|
../pm_shared/pm_shared.c \
|
||||||
|
coop.cpp
|
||||||
# ../game_shared/voice_gamemgr.cpp
|
# ../game_shared/voice_gamemgr.cpp
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
@ -51,7 +51,7 @@ extern int gmsgSayText;
|
|||||||
extern int g_teamplay;
|
extern int g_teamplay;
|
||||||
|
|
||||||
void LinkUserMessages( void );
|
void LinkUserMessages( void );
|
||||||
void BecomeSpectator( CBasePlayer *pPlayer );
|
void UTIL_BecomeSpectator( CBasePlayer *pPlayer );
|
||||||
/*
|
/*
|
||||||
* used by kill command and disconnect command
|
* used by kill command and disconnect command
|
||||||
* ROBIN: Moved here from player.cpp, to allow multiple player models
|
* ROBIN: Moved here from player.cpp, to allow multiple player models
|
||||||
@ -85,7 +85,7 @@ BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddres
|
|||||||
{
|
{
|
||||||
pl->m_state = STATE_UNINITIALIZED;
|
pl->m_state = STATE_UNINITIALIZED;
|
||||||
pl->RemoveAllItems( TRUE );
|
pl->RemoveAllItems( TRUE );
|
||||||
BecomeSpectator( pl );
|
UTIL_BecomeSpectator( pl );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ void ClientPutInServer( edict_t *pEntity )
|
|||||||
if( mp_spectator.value )
|
if( mp_spectator.value )
|
||||||
{
|
{
|
||||||
pPlayer->RemoveAllItems( TRUE );
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
BecomeSpectator( pPlayer );
|
UTIL_BecomeSpectator( pPlayer );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset interpolation during first frame
|
// Reset interpolation during first frame
|
||||||
@ -610,6 +610,10 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
|
|||||||
// Set the name
|
// Set the name
|
||||||
g_engfuncs.pfnSetClientKeyValue( ENTINDEX(pEntity), infobuffer, "name", sName );
|
g_engfuncs.pfnSetClientKeyValue( ENTINDEX(pEntity), infobuffer, "name", sName );
|
||||||
|
|
||||||
|
// prevent phantom nickname changed messages
|
||||||
|
if( mp_coop.value && ((CBasePlayer *)pEntity->pvPrivateData)->m_state == STATE_UNINITIALIZED )
|
||||||
|
return;
|
||||||
|
|
||||||
char text[256];
|
char text[256];
|
||||||
snprintf( text, 256, "* %s changed name to %s\n", STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) );
|
snprintf( text, 256, "* %s changed name to %s\n", STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) );
|
||||||
MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL );
|
MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL );
|
||||||
@ -710,7 +714,7 @@ void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
|||||||
{
|
{
|
||||||
plr->m_state = STATE_UNINITIALIZED;
|
plr->m_state = STATE_UNINITIALIZED;
|
||||||
plr->RemoveAllItems( TRUE );
|
plr->RemoveAllItems( TRUE );
|
||||||
BecomeSpectator( plr );
|
UTIL_BecomeSpectator( plr );
|
||||||
//plr->Spawn();
|
//plr->Spawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
629
dlls/coop.cpp
Normal file
629
dlls/coop.cpp
Normal file
@ -0,0 +1,629 @@
|
|||||||
|
#include "extdll.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "cbase.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "coop_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
GlobalMenu g_GlobalMenu;
|
||||||
|
|
||||||
|
|
||||||
|
struct SavedCoords g_SavedCoords, s_SavedCoords;
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CleanSpawnPoint( Vector origin, float dist )
|
||||||
|
{
|
||||||
|
CBaseEntity *ent = NULL;
|
||||||
|
while( ( ent = UTIL_FindEntityInSphere( ent, origin, dist ) ) != NULL )
|
||||||
|
{
|
||||||
|
if( ent->IsPlayer() )
|
||||||
|
{
|
||||||
|
TraceResult tr;
|
||||||
|
UTIL_TraceHull( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), dont_ignore_monsters, human_hull, ent->edict(), &tr);
|
||||||
|
//UTIL_TraceModel( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), 0, ent->edict(), &tr);
|
||||||
|
if( !tr.fAllSolid )
|
||||||
|
UTIL_SetOrigin(ent->pev, tr.vecEndPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector UTIL_FixupSpawnPoint(Vector spawn)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
// predict that spawn point is almost correct
|
||||||
|
while( i < 2 ) // 2 player heights
|
||||||
|
{
|
||||||
|
Vector point = spawn + Vector( 0, 0, 36 * i );
|
||||||
|
TraceResult tr;
|
||||||
|
UTIL_TraceHull( point, point, ignore_monsters, (mp_unduck.value&&g_fSavedDuck)?head_hull:human_hull, NULL, &tr );
|
||||||
|
if( !tr.fStartSolid && !tr.fAllSolid )
|
||||||
|
return point;
|
||||||
|
i = -i;
|
||||||
|
if( i >= 0 )
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_CoopSaveTrain( CBaseEntity *pPlayer, SavedCoords *coords)
|
||||||
|
{
|
||||||
|
if( coords->trainsaved )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CBaseEntity *train = UTIL_CoopGetPlayerTrain(pPlayer);
|
||||||
|
if( !train )
|
||||||
|
{
|
||||||
|
ALERT( at_console, "^1NO TRAIN!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ALERT( at_console, "^1TRAIN IS %s\n", STRING( train->pev->classname ) );
|
||||||
|
|
||||||
|
if( !pPlayer->IsPlayer() )
|
||||||
|
{
|
||||||
|
// it is trainnitself, try find player on it
|
||||||
|
CBaseEntity *pList;
|
||||||
|
Vector mins = pPlayer->pev->absmin;
|
||||||
|
Vector maxs = pPlayer->pev->absmax;
|
||||||
|
maxs.z += 72;
|
||||||
|
int count = UTIL_EntitiesInBox( &pList, 1, mins, maxs, FL_ONGROUND );
|
||||||
|
if( count && pList && pList->IsPlayer() )
|
||||||
|
pPlayer = pList;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ALERT( at_console, "Train without players\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy( coords->trainglobal, STRING(train->pev->globalname) );
|
||||||
|
coords->trainoffset = pPlayer->pev->origin - VecBModelOrigin(train->pev);
|
||||||
|
coords->trainsaved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_BecomeSpectator( CBasePlayer *pPlayer )
|
||||||
|
{
|
||||||
|
//pPlayer->m_bDoneFirstSpawn = true;
|
||||||
|
pPlayer->pev->takedamage = DAMAGE_NO;
|
||||||
|
pPlayer->pev->flags |= FL_SPECTATOR;
|
||||||
|
pPlayer->pev->flags |= FL_NOTARGET;
|
||||||
|
pPlayer->pev->effects |= EF_NODRAW;
|
||||||
|
pPlayer->pev->solid = SOLID_NOT;
|
||||||
|
pPlayer->pev->movetype = MOVETYPE_NOCLIP;
|
||||||
|
pPlayer->pev->modelindex = 0;
|
||||||
|
pPlayer->pev->health = 1;
|
||||||
|
pPlayer->m_pGoalEnt = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_SpawnPlayer( CBasePlayer *pPlayer )
|
||||||
|
{
|
||||||
|
pPlayer->m_state = STATE_SPAWNED;
|
||||||
|
pPlayer->m_iRespawnFrames = 0;
|
||||||
|
pPlayer->pev->effects &= ~EF_NODRAW;
|
||||||
|
|
||||||
|
pPlayer->pev->takedamage = DAMAGE_YES;
|
||||||
|
pPlayer->pev->flags &= ~FL_SPECTATOR;
|
||||||
|
pPlayer->pev->movetype = MOVETYPE_WALK;
|
||||||
|
pPlayer->Spawn();
|
||||||
|
CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char * UTIL_CoopPlayerName( CBaseEntity *pPlayer )
|
||||||
|
{
|
||||||
|
if( !pPlayer )
|
||||||
|
return (char*)"unnamed(NULL)";
|
||||||
|
return (char*)( ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected" );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool g_fSavedDuck;
|
||||||
|
|
||||||
|
char *badlist[256] = {
|
||||||
|
"player", // does not even can set own name
|
||||||
|
"talat",
|
||||||
|
"hmse",
|
||||||
|
"mhmd",
|
||||||
|
"aeman",
|
||||||
|
"famas",
|
||||||
|
"danek",
|
||||||
|
"ame syia",
|
||||||
|
"melih",
|
||||||
|
"aliance",
|
||||||
|
"vladick"
|
||||||
|
};
|
||||||
|
|
||||||
|
void UTIL_CoopKickPlayer(CBaseEntity *pPlayer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if( !pPlayer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *name = UTIL_CoopPlayerName( pPlayer );
|
||||||
|
SERVER_COMMAND( UTIL_VarArgs( "kick %d\n", ENTINDEX(pPlayer->pev->pContainingEntity) - 1 ) );
|
||||||
|
|
||||||
|
if( strlen( name ) < 5 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// find last slot
|
||||||
|
for( i = 0; badlist[i]; i++ );
|
||||||
|
|
||||||
|
badlist[i] = strdup( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTIL_CoopIsBadPlayer( CBaseEntity *plr )
|
||||||
|
{
|
||||||
|
if( !plr )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for( int i = 0; badlist[i];i++ )
|
||||||
|
if( strcasestr( (char*)UTIL_CoopPlayerName( plr ), badlist[i] ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct checkpoint_s
|
||||||
|
{
|
||||||
|
char str[32];
|
||||||
|
float time;
|
||||||
|
Vector origin;
|
||||||
|
Vector angles;
|
||||||
|
} g_checkpoints[4];
|
||||||
|
|
||||||
|
|
||||||
|
void CoopClearData( void )
|
||||||
|
{
|
||||||
|
// nullify
|
||||||
|
SavedCoords l_SavedCoords = {0};
|
||||||
|
g_SavedCoords = l_SavedCoords;
|
||||||
|
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool g_fPause;
|
||||||
|
void CoopApplyData( void )
|
||||||
|
{
|
||||||
|
if( s_SavedCoords.valid )
|
||||||
|
{
|
||||||
|
struct SavedCoords null1 = {0};
|
||||||
|
g_SavedCoords = s_SavedCoords;
|
||||||
|
s_SavedCoords = null1;
|
||||||
|
g_fSavedDuck = g_SavedCoords.fDuck;
|
||||||
|
}
|
||||||
|
g_fPause = false;
|
||||||
|
ALERT( at_console, "^2CoopApplyData()\n" );
|
||||||
|
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int g_iMenu;
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopLocalConfirmMenu(CBasePlayer *pPlayer)
|
||||||
|
{
|
||||||
|
const char *menu[] = {
|
||||||
|
"No",
|
||||||
|
"Cancel",
|
||||||
|
"Do not confirm",
|
||||||
|
"Don't confirm",
|
||||||
|
"Единая Россия"
|
||||||
|
};
|
||||||
|
|
||||||
|
menu[pPlayer->m_iConfirmKey = RANDOM_LONG(2,4)] = "Confirm";
|
||||||
|
UTIL_CoopShowMenu(pPlayer, "Confirm changing map BACK (NOT RECOMMENDED)?", ARRAYSIZE(menu), menu);
|
||||||
|
pPlayer->m_iMenuState = MENUSTATE_LOCAL_CONFIRM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlobalMenu::Process( CBasePlayer *pPlayer, int imenu )
|
||||||
|
{
|
||||||
|
if( pPlayer->pev->flags & FL_SPECTATOR )
|
||||||
|
return;
|
||||||
|
if( gpGlobals->time - m_flTime > 30 )
|
||||||
|
{
|
||||||
|
g_iMenu = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( g_iMenu )
|
||||||
|
{
|
||||||
|
case 1: // touch blue trigger
|
||||||
|
m_iVoteCount++;
|
||||||
|
|
||||||
|
if( imenu == 1 ) // confirm
|
||||||
|
{
|
||||||
|
if( m_iBanCount >= 2 )
|
||||||
|
{
|
||||||
|
UTIL_CoopKickPlayer( pPlayer );
|
||||||
|
m_iConfirm-= 5;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_iConfirm++;
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 confirmed map change\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
||||||
|
MESSAGE_END();
|
||||||
|
|
||||||
|
}
|
||||||
|
if( imenu == 2 ) // cancel
|
||||||
|
{
|
||||||
|
m_iConfirm--;
|
||||||
|
if( pPlayer == m_pPlayer )
|
||||||
|
m_iConfirm -= 100; // player mistake
|
||||||
|
}
|
||||||
|
if( imenu == 3 )
|
||||||
|
{
|
||||||
|
m_iBanCount++;
|
||||||
|
if( m_iBanCount >= 2 && m_iConfirm > -50 )
|
||||||
|
UTIL_CoopKickPlayer( m_pPlayer );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // vote by request
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 selected ^3%s\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected", maps[imenu - 1] ));
|
||||||
|
MESSAGE_END();
|
||||||
|
|
||||||
|
if( imenu < m_iConfirm )
|
||||||
|
{
|
||||||
|
votes[imenu-1]++;
|
||||||
|
m_iVoteCount++;
|
||||||
|
|
||||||
|
if( votes[1] >= 2 )
|
||||||
|
{
|
||||||
|
// two players vote for ban
|
||||||
|
UTIL_CoopKickPlayer( m_pPlayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_iVoteCount >= m_iMaxCount )
|
||||||
|
{
|
||||||
|
for( int i = 0; i <= m_iConfirm; i++ )
|
||||||
|
if( votes[i] >= m_iMaxCount )
|
||||||
|
{
|
||||||
|
UTIL_CoopActivateChangeLevel( triggers[i] );
|
||||||
|
g_iMenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void GlobalMenu::ShowGlobalMenu( const char *title, int count, const char **menu )
|
||||||
|
{
|
||||||
|
int count2 = 0;
|
||||||
|
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
||||||
|
|
||||||
|
if( plr && plr->IsPlayer() && !UTIL_CoopIsBadPlayer( plr ) )
|
||||||
|
{
|
||||||
|
count2++;
|
||||||
|
CBasePlayer *player = (CBasePlayer *) plr;
|
||||||
|
UTIL_CoopShowMenu( player, title, count, menu, 30 );
|
||||||
|
player->m_iMenuState = MENUSTATE_GLOBAL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_iMaxCount = count2;
|
||||||
|
m_iBanCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalMenu::ConfirmMenu( CBasePlayer *pPlayer, CBaseEntity *trigger, const char *mapname )
|
||||||
|
{
|
||||||
|
if( g_iMenu && gpGlobals->time - m_flTime < 30 )
|
||||||
|
return; // wait 30s befor new confirm vote
|
||||||
|
if( pPlayer->m_iMenuState == MENUSTATE_LOCAL_CONFIRM )
|
||||||
|
return;
|
||||||
|
if( pPlayer->m_iLocalConfirm < 3 )
|
||||||
|
{
|
||||||
|
UTIL_CoopLocalConfirmMenu( pPlayer );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_iMenu = 1;
|
||||||
|
m_flTime = gpGlobals->time;
|
||||||
|
m_pTrigger = trigger;
|
||||||
|
m_pPlayer = pPlayer;
|
||||||
|
const char *menu[] = {
|
||||||
|
"Confirm",
|
||||||
|
"Cancel",
|
||||||
|
"BAN"
|
||||||
|
};
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 wants to change map ^1BACKWARDS\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
||||||
|
MESSAGE_END();
|
||||||
|
ShowGlobalMenu(UTIL_VarArgs("Confirm changing map BACK TO %s?", mapname), ARRAYSIZE(menu), menu);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopCheckpointMenu( CBasePlayer *pPlayer )
|
||||||
|
{
|
||||||
|
//if( pPlayer->m_state == STATE_SPAWNED )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( mp_coop_checkpoints.value )
|
||||||
|
{
|
||||||
|
const char *menu[5] = {
|
||||||
|
"New checkpoint"
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
if( pPlayer->m_state == STATE_SPECTATOR || pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
||||||
|
menu[0] = "Just spawn";
|
||||||
|
for( i = 1; g_checkpoints[i-1].time; i++ )
|
||||||
|
menu[i] = g_checkpoints[i-1].str;
|
||||||
|
UTIL_CoopShowMenu( pPlayer, "Select checkpoint", i, menu );
|
||||||
|
pPlayer->m_iMenuState = MENUSTATE_CHECKPOINT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopNewCheckpoint( entvars_t *pevPlayer )
|
||||||
|
{
|
||||||
|
memmove( &g_checkpoints[1], &g_checkpoints[0], sizeof ( g_checkpoints[0] ) * 3 );
|
||||||
|
g_checkpoints[0].time = gpGlobals->time;
|
||||||
|
snprintf( g_checkpoints[0].str, 31, "%5s %d", STRING( pevPlayer->netname ), (int)( gpGlobals->time / 60 ) );
|
||||||
|
g_checkpoints[0].origin = pevPlayer->origin;
|
||||||
|
g_checkpoints[0].angles = pevPlayer->angles;
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( "New checkpoint availiable\n" );
|
||||||
|
MESSAGE_END();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopVoteMenu( CBasePlayer *pPlayer )
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
||||||
|
|
||||||
|
if( plr && plr->IsPlayer() )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( count < 4 )
|
||||||
|
{
|
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "Need at least 4 players to vote changelevel!\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_GlobalMenu.VoteMenu(pPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_CoopMenu( CBasePlayer *pPlayer )
|
||||||
|
{
|
||||||
|
if( pPlayer->m_state == STATE_SPAWNED )
|
||||||
|
{
|
||||||
|
pPlayer->m_iMenuState = MENUSTATE_COOPMENU;
|
||||||
|
if( mp_coop.value )
|
||||||
|
{
|
||||||
|
const char *menu[] = {
|
||||||
|
"Force respawn",
|
||||||
|
"Unblock",
|
||||||
|
"Become spectator",
|
||||||
|
"Vote changelevel",
|
||||||
|
"Checkpoint/restore"
|
||||||
|
};
|
||||||
|
int count1 = ARRAYSIZE( menu ) - 1;
|
||||||
|
if( mp_coop_checkpoints.value )
|
||||||
|
count1++;
|
||||||
|
UTIL_CoopShowMenu( pPlayer, "Coop menu", count1, menu );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( pPlayer->m_state == STATE_SPECTATOR )
|
||||||
|
{
|
||||||
|
pPlayer->m_iMenuState = MENUSTATE_COOPMENU_SPEC;
|
||||||
|
if( mp_coop.value )
|
||||||
|
{
|
||||||
|
const char *menu[] = {
|
||||||
|
"Spawn",
|
||||||
|
"Close menu"
|
||||||
|
};
|
||||||
|
UTIL_CoopShowMenu( pPlayer, "Spectator menu", ARRAYSIZE( menu ), menu );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopProcessMenu( CBasePlayer *pPlayer, int imenu )
|
||||||
|
{
|
||||||
|
switch( pPlayer->m_iMenuState )
|
||||||
|
{
|
||||||
|
case MENUSTATE_COOPMENU_SPEC:
|
||||||
|
if( imenu == 1 )
|
||||||
|
{
|
||||||
|
if( g_checkpoints[0].time )
|
||||||
|
UTIL_CoopCheckpointMenu( pPlayer );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
|
pPlayer->m_state = STATE_SPAWNED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( imenu == 2 )
|
||||||
|
{
|
||||||
|
pPlayer->m_state = STATE_SPECTATOR;
|
||||||
|
CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENUSTATE_COOPMENU:
|
||||||
|
if( pPlayer->m_state != STATE_SPAWNED )
|
||||||
|
break;
|
||||||
|
if( imenu == 1 )
|
||||||
|
{
|
||||||
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
|
}
|
||||||
|
if( imenu == 2 )
|
||||||
|
{
|
||||||
|
UTIL_CleanSpawnPoint( pPlayer->pev->origin, 150 );
|
||||||
|
}
|
||||||
|
if( imenu == 3 )
|
||||||
|
{
|
||||||
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
|
UTIL_BecomeSpectator( pPlayer );
|
||||||
|
pPlayer->m_state = STATE_SPECTATOR;
|
||||||
|
}
|
||||||
|
if( imenu == 4 )
|
||||||
|
{
|
||||||
|
UTIL_CoopVoteMenu( pPlayer );
|
||||||
|
}
|
||||||
|
if( imenu == 5 )
|
||||||
|
{
|
||||||
|
UTIL_CoopCheckpointMenu( pPlayer );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENUSTATE_GLOBAL:
|
||||||
|
if( !UTIL_CoopIsBadPlayer( pPlayer ) )
|
||||||
|
g_GlobalMenu.Process( pPlayer, imenu );
|
||||||
|
break;
|
||||||
|
case MENUSTATE_CHECKPOINT:
|
||||||
|
if( imenu == 1 )
|
||||||
|
{
|
||||||
|
if( pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
||||||
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
|
else if( !UTIL_CoopIsBadPlayer( pPlayer ) )
|
||||||
|
UTIL_CoopNewCheckpoint( pPlayer->pev );
|
||||||
|
}
|
||||||
|
else if( imenu > 1 && imenu < 5 )
|
||||||
|
{
|
||||||
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
|
pPlayer->pev->origin = g_checkpoints[imenu-2].origin;
|
||||||
|
pPlayer->pev->angles = g_checkpoints[imenu-2].angles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENUSTATE_LOCAL_CONFIRM:
|
||||||
|
if( imenu - 1 == pPlayer->m_iConfirmKey )
|
||||||
|
pPlayer->m_iLocalConfirm++;
|
||||||
|
else
|
||||||
|
pPlayer->m_iLocalConfirm = 0;
|
||||||
|
pPlayer->m_iMenuState = MENUSTATE_NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//pPlayer->m_iMenuState = MENUSTATE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTIL_CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles )
|
||||||
|
{
|
||||||
|
if(!g_SavedCoords.valid)
|
||||||
|
return false;
|
||||||
|
UTIL_CoopValidateOffset();
|
||||||
|
// compute player by IQ
|
||||||
|
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( player->edict() ), "ip" );
|
||||||
|
for( int i = 0;i < g_SavedCoords.iCount;i++)
|
||||||
|
{
|
||||||
|
if(ip && ip[0] && !strcmp(ip, g_SavedCoords.ip[i]) )
|
||||||
|
{
|
||||||
|
TraceResult tr;
|
||||||
|
Vector point = g_SavedCoords.origin[i] + g_SavedCoords.offset;
|
||||||
|
|
||||||
|
UTIL_TraceHull( point, point, missile, (mp_unduck.value&&g_fSavedDuck)?head_hull:human_hull, NULL, &tr );
|
||||||
|
|
||||||
|
g_SavedCoords.ip[i][0] = 0;
|
||||||
|
|
||||||
|
if( tr.fStartSolid || tr.fAllSolid )
|
||||||
|
return false;
|
||||||
|
*origin = point;
|
||||||
|
*angles = g_SavedCoords.angles[i];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTIL_CoopGetSpawnPoint( Vector *origin, Vector *angles)
|
||||||
|
{
|
||||||
|
if(!g_SavedCoords.valid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// spawn on elevator or train
|
||||||
|
if( g_SavedCoords.trainsaved )
|
||||||
|
{
|
||||||
|
CBaseEntity *train = UTIL_FindEntityByString( NULL, "globalname", g_SavedCoords.trainglobal );
|
||||||
|
if( !train ) train = UTIL_FindEntityByString( NULL, "classname", g_SavedCoords.trainglobal );
|
||||||
|
if( train && ( !g_SavedCoords.trainuser1 || train->pev->iuser1 == g_SavedCoords.trainuser1 ) )
|
||||||
|
{
|
||||||
|
*angles = g_SavedCoords.triggerangles;
|
||||||
|
*origin = VecBModelOrigin(train->pev) + g_SavedCoords.trainoffset;
|
||||||
|
g_SavedCoords.trainuser1 = train->pev->iuser1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ALERT( at_console, "Failed to get train %s (map design error?)\n", g_SavedCoords.trainglobal );
|
||||||
|
}
|
||||||
|
Vector point = g_SavedCoords.triggerorigin;
|
||||||
|
*angles = g_SavedCoords.triggerangles;
|
||||||
|
if( !g_SavedCoords.validspawnpoint )
|
||||||
|
{
|
||||||
|
TraceResult tr;
|
||||||
|
Vector angle;
|
||||||
|
UTIL_MakeVectorsPrivate( *angles, (float*)&angle, NULL, NULL );
|
||||||
|
UTIL_CoopValidateOffset();
|
||||||
|
point = point + g_SavedCoords.offset;
|
||||||
|
//UTIL_TraceHull( point, point, ignore_monsters, human_hull, NULL, &tr );
|
||||||
|
|
||||||
|
if( mp_unduck.value && g_fSavedDuck && !g_SavedCoords.fUsed )
|
||||||
|
UTIL_TraceHull( point, point + angle * 100, missile, head_hull, NULL, &tr );
|
||||||
|
else
|
||||||
|
UTIL_TraceHull( point, point + angle * 100, ignore_monsters, human_hull, NULL, &tr );
|
||||||
|
|
||||||
|
if( !tr.fStartSolid && !tr.fAllSolid || ENTINDEX( tr.pHit ) && ENTINDEX( tr.pHit ) <= gpGlobals->maxClients )
|
||||||
|
{
|
||||||
|
//g_SavedCoords.triggerorigin = tr.vecEndPos;
|
||||||
|
//g_SavedCoords.validspawnpoint = true;
|
||||||
|
if( tr.pHit && FClassnameIs( tr.pHit, "func_door" ) )
|
||||||
|
tr.pHit->v.solid = SOLID_NOT;
|
||||||
|
ALERT( at_console, "CoopGetSpawnPoint: ^2offset set\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//g_SavedCoords.valid = false;
|
||||||
|
ALERT( at_console, "CoopGetSpawnPoint: ^2trace failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*origin = point;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CBaseEntity *UTIL_CoopGetPlayerTrain( CBaseEntity *pPlayer)
|
||||||
|
{
|
||||||
|
CBaseEntity *train = NULL;
|
||||||
|
|
||||||
|
if( !pPlayer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if( !pPlayer->IsPlayer() )
|
||||||
|
{
|
||||||
|
// activated by path track
|
||||||
|
train = pPlayer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( FNullEnt(pPlayer->pev->groundentity))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
train = CBaseEntity::Instance(pPlayer->pev->groundentity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !train )
|
||||||
|
return NULL;
|
||||||
|
if( !train->pev->globalname ||!STRING(train->pev->globalname) || !STRING(train->pev->globalname)[0] )
|
||||||
|
return NULL;
|
||||||
|
// doors are elevators
|
||||||
|
if( strcmp( STRING( train->pev->classname ), "func_train") && strcmp( STRING( train->pev->classname ), "func_tracktrain") && strcmp( STRING( train->pev->classname ), "func_door") )
|
||||||
|
return NULL;
|
||||||
|
return train;
|
||||||
|
}
|
108
dlls/coop_util.h
Normal file
108
dlls/coop_util.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#ifndef COOP_UTIL_H
|
||||||
|
#define COOP_UTIL_H
|
||||||
|
extern cvar_t cvar_allow_gravgun;
|
||||||
|
extern cvar_t cvar_allow_ar2;
|
||||||
|
extern cvar_t cvar_ar2_mp5;
|
||||||
|
extern cvar_t cvar_ar2_bullets;
|
||||||
|
extern cvar_t cvar_ar2_balls;
|
||||||
|
extern cvar_t cvar_wresptime;
|
||||||
|
extern cvar_t cvar_iresptime;
|
||||||
|
|
||||||
|
extern cvar_t cvar_gibtime;
|
||||||
|
extern cvar_t cvar_hgibcount;
|
||||||
|
extern cvar_t cvar_agibcount;
|
||||||
|
|
||||||
|
extern cvar_t mp_gravgun_players;
|
||||||
|
extern cvar_t mp_coop;
|
||||||
|
extern cvar_t mp_coop_changelevel;
|
||||||
|
extern cvar_t mp_coop_nofriendlyfire;
|
||||||
|
extern cvar_t mp_coop_disabledmap;
|
||||||
|
extern cvar_t mp_coop_checkpoints;
|
||||||
|
|
||||||
|
extern cvar_t mp_unduck;
|
||||||
|
extern cvar_t mp_semclip;
|
||||||
|
extern cvar_t mp_coop_reconnect_hack;
|
||||||
|
extern cvar_t mp_coop_noangry;
|
||||||
|
extern cvar_t mp_spectator;
|
||||||
|
|
||||||
|
extern cvar_t sentences_txt;
|
||||||
|
extern cvar_t materials_txt;
|
||||||
|
|
||||||
|
extern bool g_fSavedDuck;
|
||||||
|
extern bool g_fPause;
|
||||||
|
|
||||||
|
struct SavedCoords
|
||||||
|
{
|
||||||
|
char ip[32][32];
|
||||||
|
Vector origin[32];
|
||||||
|
Vector angles[32];
|
||||||
|
char landmark[32];
|
||||||
|
Vector triggerorigin;
|
||||||
|
Vector triggerangles;
|
||||||
|
Vector offset;
|
||||||
|
int iCount;
|
||||||
|
bool valid;
|
||||||
|
bool validoffset;
|
||||||
|
bool validspawnpoint;
|
||||||
|
int changeback;
|
||||||
|
bool trainsaved;
|
||||||
|
Vector trainoffset;
|
||||||
|
char trainglobal[256];
|
||||||
|
int trainuser1;
|
||||||
|
bool fUsed;
|
||||||
|
bool fDuck;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopValidateOffset( void );
|
||||||
|
void UTIL_CleanSpawnPoint( Vector origin, float radius );
|
||||||
|
char *UTIL_CoopPlayerName( CBaseEntity *pPlayer );
|
||||||
|
|
||||||
|
bool UTIL_CoopGetSpawnPoint( Vector *point, Vector *angles);
|
||||||
|
|
||||||
|
bool UTIL_CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles );
|
||||||
|
void UTIL_CoopSaveTrain( CBaseEntity *pPlayer, SavedCoords *coords);
|
||||||
|
Vector UTIL_FixupSpawnPoint(Vector spawn);
|
||||||
|
void UTIL_CoopActivateChangeLevel( CBaseEntity *pTrigger );
|
||||||
|
|
||||||
|
#ifdef PLAYER_H
|
||||||
|
void UTIL_CoopKickPlayer(CBaseEntity *pPlayer);
|
||||||
|
bool UTIL_CoopIsBadPlayer( CBaseEntity *plr );
|
||||||
|
void UTIL_CoopNewCheckpoint( entvars_t *pevPlayer );
|
||||||
|
CBaseEntity *UTIL_CoopGetPlayerTrain( CBaseEntity *pPlayer);
|
||||||
|
void UTIL_CoopMenu( CBasePlayer *pPlayer );
|
||||||
|
void UTIL_SpawnPlayer( CBasePlayer *pPlayer );
|
||||||
|
void UTIL_BecomeSpectator( CBasePlayer *pPlayer );
|
||||||
|
void UTIL_CoopCheckpointMenu( CBasePlayer *pPlayer );
|
||||||
|
void UTIL_CoopVoteMenu( CBasePlayer *pPlayer );
|
||||||
|
void UTIL_CoopShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 );
|
||||||
|
extern int g_iMenu;
|
||||||
|
|
||||||
|
// Show to all spawned players: voting, etc..
|
||||||
|
class GlobalMenu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int m_iConfirm;
|
||||||
|
int m_iVoteCount;
|
||||||
|
int m_iMaxCount;
|
||||||
|
int m_iBanCount;
|
||||||
|
float m_flTime;
|
||||||
|
const char *maps[5];
|
||||||
|
int votes[5];
|
||||||
|
CBaseEntity *triggers[5];
|
||||||
|
EHANDLE m_pTrigger;
|
||||||
|
EHANDLE m_pPlayer;
|
||||||
|
void VoteMenu( CBasePlayer *pPlayer );
|
||||||
|
void ConfirmMenu( CBasePlayer *pPlayer, CBaseEntity *trigger, const char *mapname );
|
||||||
|
void ShowGlobalMenu( const char *title, int count, const char **menu );
|
||||||
|
void Process( CBasePlayer *pPlayer, int imenu );
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GlobalMenu g_GlobalMenu;
|
||||||
|
#endif
|
||||||
|
extern struct SavedCoords g_SavedCoords, s_SavedCoords;
|
||||||
|
|
||||||
|
#endif // COOP_UTIL_H
|
||||||
|
|
@ -27,6 +27,8 @@
|
|||||||
#define BOLT_AIR_VELOCITY 2000
|
#define BOLT_AIR_VELOCITY 2000
|
||||||
#define BOLT_WATER_VELOCITY 1000
|
#define BOLT_WATER_VELOCITY 1000
|
||||||
|
|
||||||
|
extern BOOL gPhysicsInterfaceInitialized;
|
||||||
|
|
||||||
// UNDONE: Save/restore this? Don't forget to set classname and LINK_ENTITY_TO_CLASS()
|
// UNDONE: Save/restore this? Don't forget to set classname and LINK_ENTITY_TO_CLASS()
|
||||||
//
|
//
|
||||||
// OVERLOADS SOME ENTVARS:
|
// OVERLOADS SOME ENTVARS:
|
||||||
@ -181,9 +183,11 @@ void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
|
|||||||
pev->angles.z = RANDOM_LONG( 0, 360 );
|
pev->angles.z = RANDOM_LONG( 0, 360 );
|
||||||
pev->nextthink = gpGlobals->time + 60.0;
|
pev->nextthink = gpGlobals->time + 60.0;
|
||||||
|
|
||||||
// g-cont. Setup movewith feature
|
if (gPhysicsInterfaceInitialized) {
|
||||||
pev->movetype = MOVETYPE_COMPOUND; // set movewith type
|
// g-cont. Setup movewith feature
|
||||||
pev->aiment = ENT( pOther->pev ); // set parent
|
pev->movetype = MOVETYPE_COMPOUND; // set movewith type
|
||||||
|
pev->aiment = ENT( pOther->pev ); // set parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( UTIL_PointContents( pev->origin ) != CONTENTS_WATER )
|
if( UTIL_PointContents( pev->origin ) != CONTENTS_WATER )
|
||||||
|
@ -411,7 +411,7 @@ LINK_ENTITY_TO_CLASS( trip_beam, CTripBeam )
|
|||||||
void CTripBeam::Spawn( void )
|
void CTripBeam::Spawn( void )
|
||||||
{
|
{
|
||||||
CLightning::Spawn();
|
CLightning::Spawn();
|
||||||
SetTouch( &TriggerTouch );
|
SetTouch( &CLightning::TriggerTouch );
|
||||||
pev->solid = SOLID_TRIGGER;
|
pev->solid = SOLID_TRIGGER;
|
||||||
RelinkBeam();
|
RelinkBeam();
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,15 @@ cvar_t mp_coop_nofriendlyfire = { "mp_coop_nofriendlyfire", "0", FCVAR_SERVER };
|
|||||||
cvar_t mp_coop_disabledmap = { "mp_coop_disabledmap", "", FCVAR_SERVER };
|
cvar_t mp_coop_disabledmap = { "mp_coop_disabledmap", "", FCVAR_SERVER };
|
||||||
cvar_t mp_coop_reconnect_hack = { "mp_coop_reconnect_hack", "0", FCVAR_SERVER };
|
cvar_t mp_coop_reconnect_hack = { "mp_coop_reconnect_hack", "0", FCVAR_SERVER };
|
||||||
cvar_t mp_coop_noangry = { "mp_coop_noangry", "0", FCVAR_SERVER };
|
cvar_t mp_coop_noangry = { "mp_coop_noangry", "0", FCVAR_SERVER };
|
||||||
|
cvar_t mp_coop_checkpoints = { "mp_coop_checkpoints", "1", FCVAR_SERVER };
|
||||||
|
|
||||||
cvar_t mp_unduck = { "mp_unduck", "0", FCVAR_SERVER };
|
cvar_t mp_unduck = { "mp_unduck", "0", FCVAR_SERVER };
|
||||||
cvar_t mp_semclip = { "mp_semclip", "0", FCVAR_SERVER };
|
cvar_t mp_semclip = { "mp_semclip", "0", FCVAR_SERVER };
|
||||||
cvar_t mp_spectator = { "mp_spectator", "0", FCVAR_SERVER };
|
cvar_t mp_spectator = { "mp_spectator", "0", FCVAR_SERVER };
|
||||||
|
|
||||||
|
cvar_t materials_txt = { "materials_txt", "sound/materials.txt", FCVAR_SERVER };
|
||||||
|
cvar_t sentences_txt = { "sentences_txt", "sound/sentences.txt", FCVAR_SERVER };
|
||||||
|
|
||||||
// Engine Cvars
|
// Engine Cvars
|
||||||
cvar_t *g_psv_gravity = NULL;
|
cvar_t *g_psv_gravity = NULL;
|
||||||
cvar_t *g_psv_aim = NULL;
|
cvar_t *g_psv_aim = NULL;
|
||||||
@ -510,6 +515,10 @@ void GameDLLInit( void )
|
|||||||
CVAR_REGISTER( &mp_coop_reconnect_hack );
|
CVAR_REGISTER( &mp_coop_reconnect_hack );
|
||||||
CVAR_REGISTER( &mp_coop_noangry );
|
CVAR_REGISTER( &mp_coop_noangry );
|
||||||
CVAR_REGISTER( &mp_spectator );
|
CVAR_REGISTER( &mp_spectator );
|
||||||
|
CVAR_REGISTER( &mp_coop_checkpoints );
|
||||||
|
|
||||||
|
CVAR_REGISTER( &sentences_txt );
|
||||||
|
CVAR_REGISTER( &materials_txt );
|
||||||
|
|
||||||
|
|
||||||
CVAR_REGISTER( &mp_chattime );
|
CVAR_REGISTER( &mp_chattime );
|
||||||
|
25
dlls/game.h
25
dlls/game.h
@ -35,31 +35,8 @@ extern cvar_t teamlist;
|
|||||||
extern cvar_t teamoverride;
|
extern cvar_t teamoverride;
|
||||||
extern cvar_t defaultteam;
|
extern cvar_t defaultteam;
|
||||||
extern cvar_t allowmonsters;
|
extern cvar_t allowmonsters;
|
||||||
extern cvar_t cvar_allow_gravgun;
|
|
||||||
extern cvar_t cvar_allow_ar2;
|
|
||||||
extern cvar_t cvar_ar2_mp5;
|
|
||||||
extern cvar_t cvar_ar2_bullets;
|
|
||||||
extern cvar_t cvar_ar2_balls;
|
|
||||||
extern cvar_t cvar_wresptime;
|
|
||||||
extern cvar_t cvar_iresptime;
|
|
||||||
|
|
||||||
extern cvar_t cvar_gibtime;
|
#include "coop_util.h"
|
||||||
extern cvar_t cvar_hgibcount;
|
|
||||||
extern cvar_t cvar_agibcount;
|
|
||||||
|
|
||||||
extern cvar_t mp_gravgun_players;
|
|
||||||
extern cvar_t mp_coop;
|
|
||||||
extern cvar_t mp_coop_changelevel;
|
|
||||||
extern cvar_t mp_coop_nofriendlyfire;
|
|
||||||
extern cvar_t mp_coop_disabledmap;
|
|
||||||
extern cvar_t mp_unduck;
|
|
||||||
extern cvar_t mp_semclip;
|
|
||||||
extern cvar_t mp_coop_reconnect_hack;
|
|
||||||
extern cvar_t mp_coop_noangry;
|
|
||||||
extern cvar_t mp_spectator;
|
|
||||||
|
|
||||||
extern bool g_fSavedDuck;
|
|
||||||
extern bool g_fPause;
|
|
||||||
|
|
||||||
// Engine Cvars
|
// Engine Cvars
|
||||||
extern cvar_t *g_psv_gravity;
|
extern cvar_t *g_psv_gravity;
|
||||||
|
@ -57,27 +57,8 @@ BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
bool CoopGetSpawnPoint( Vector *point, Vector *angles);
|
|
||||||
|
|
||||||
bool CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles );
|
|
||||||
|
|
||||||
Vector FixupSpawnPoint(Vector spawn)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
// predict that spawn point is almost correct
|
|
||||||
while( i < 2 ) // 2 player heights
|
|
||||||
{
|
|
||||||
Vector point = spawn + Vector( 0, 0, 36 * i );
|
|
||||||
TraceResult tr;
|
|
||||||
UTIL_TraceHull( point, point, ignore_monsters, (mp_unduck.value&&g_fSavedDuck)?head_hull:human_hull, NULL, &tr );
|
|
||||||
if( !tr.fStartSolid && !tr.fAllSolid )
|
|
||||||
return point;
|
|
||||||
i = -i;
|
|
||||||
if( i >= 0 )
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return spawn;
|
|
||||||
}
|
|
||||||
extern EHANDLE g_pLastSpawn;
|
extern EHANDLE g_pLastSpawn;
|
||||||
//=========================================================
|
//=========================================================
|
||||||
//=========================================================
|
//=========================================================
|
||||||
@ -107,8 +88,8 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
|||||||
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
|
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
|
||||||
pPlayer->pev->punchangle = g_vecZero;
|
pPlayer->pev->punchangle = g_vecZero;
|
||||||
if( !(pPlayer->pev->flags & FL_SPECTATOR ) )
|
if( !(pPlayer->pev->flags & FL_SPECTATOR ) )
|
||||||
if( mp_coop_changelevel.value && !CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles ))
|
if( mp_coop_changelevel.value && !UTIL_CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles ))
|
||||||
if( !CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles ) )
|
if( !UTIL_CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles ) )
|
||||||
{
|
{
|
||||||
if( !g_pLastSpawn )
|
if( !g_pLastSpawn )
|
||||||
{
|
{
|
||||||
@ -117,11 +98,11 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
|||||||
params.fadeoutTime = .5;
|
params.fadeoutTime = .5;
|
||||||
params.holdTime = 10;
|
params.holdTime = 10;
|
||||||
params.channel = 0;
|
params.channel = 0;
|
||||||
params.y = 0;
|
params.x = params.y = -1;
|
||||||
params.r2 = params.g2 = params.b2 = params.a2 = params.r1 = params.g1 = params.b1 = params.a1 = 255;
|
params.r2 = params.g2 = params.b2 = params.a2 = params.r1 = params.g1 = params.b1 = params.a1 = 255;
|
||||||
|
|
||||||
|
|
||||||
UTIL_HudMessage( pPlayer, params, "Server cannot select a spawnpoint, please fly to it manually and press attack button" );
|
UTIL_HudMessage( pPlayer, params, "Server cannot select a spawnpoint\nplease fly to it manually\nand press attack button" );
|
||||||
// select spawn point
|
// select spawn point
|
||||||
pPlayer->m_state = STATE_POINT_SELECT;
|
pPlayer->m_state = STATE_POINT_SELECT;
|
||||||
pPlayer->m_afButtonPressed = 0;
|
pPlayer->m_afButtonPressed = 0;
|
||||||
@ -133,7 +114,7 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pPlayer->pev->fixangle = TRUE;
|
pPlayer->pev->fixangle = TRUE;
|
||||||
pPlayer->pev->origin = FixupSpawnPoint( pPlayer->pev->origin );
|
pPlayer->pev->origin = UTIL_FixupSpawnPoint( pPlayer->pev->origin );
|
||||||
if( g_fSavedDuck )
|
if( g_fSavedDuck )
|
||||||
pPlayer->pev->flags |= FL_DUCKING;
|
pPlayer->pev->flags |= FL_DUCKING;
|
||||||
|
|
||||||
|
@ -96,38 +96,11 @@ void CoopClearWeaponList( void )
|
|||||||
}
|
}
|
||||||
extern int g_iMenu;
|
extern int g_iMenu;
|
||||||
|
|
||||||
void BecomeSpectator( CBasePlayer *pPlayer )
|
|
||||||
{
|
|
||||||
//pPlayer->m_bDoneFirstSpawn = true;
|
|
||||||
pPlayer->pev->takedamage = DAMAGE_NO;
|
|
||||||
pPlayer->pev->flags |= FL_SPECTATOR;
|
|
||||||
pPlayer->pev->flags |= FL_NOTARGET;
|
|
||||||
pPlayer->pev->effects |= EF_NODRAW;
|
|
||||||
pPlayer->pev->solid = SOLID_NOT;
|
|
||||||
pPlayer->pev->movetype = MOVETYPE_NOCLIP;
|
|
||||||
pPlayer->pev->modelindex = 0;
|
|
||||||
pPlayer->pev->health = 1;
|
|
||||||
pPlayer->m_pGoalEnt = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpawnPlayer( CBasePlayer *pPlayer )
|
|
||||||
{
|
|
||||||
pPlayer->m_state = STATE_SPAWNED;
|
|
||||||
pPlayer->m_iRespawnFrames = 0;
|
|
||||||
pPlayer->pev->effects &= ~EF_NODRAW;
|
|
||||||
|
|
||||||
pPlayer->pev->takedamage = DAMAGE_YES;
|
|
||||||
pPlayer->pev->flags &= ~FL_SPECTATOR;
|
|
||||||
pPlayer->pev->movetype = MOVETYPE_WALK;
|
|
||||||
pPlayer->Spawn();
|
|
||||||
CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int gmsgShowMenu;
|
extern int gmsgShowMenu;
|
||||||
|
|
||||||
void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 )
|
void UTIL_CoopShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time )
|
||||||
{
|
{
|
||||||
if( pPlayer->m_fTouchMenu)
|
if( pPlayer->m_fTouchMenu)
|
||||||
{
|
{
|
||||||
@ -161,9 +134,9 @@ void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **
|
|||||||
//CLIENT_COMMAND( pPlayer->edict(), "exec touch_default/numbers.cfg\n");
|
//CLIENT_COMMAND( pPlayer->edict(), "exec touch_default/numbers.cfg\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoopMenu( CBasePlayer *pPlayer );
|
void UTIL_CoopMenu( CBasePlayer *pPlayer );
|
||||||
|
|
||||||
void CoopVoteMenu( CBasePlayer *pPlayer );
|
void UTIL_CoopVoteMenu( CBasePlayer *pPlayer );
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
@ -217,7 +190,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoopProcessMenu( CBasePlayer *pPlayer, int imenu );
|
void UTIL_CoopProcessMenu( CBasePlayer *pPlayer, int imenu );
|
||||||
|
|
||||||
BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
||||||
{
|
{
|
||||||
@ -230,7 +203,7 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
|||||||
if( FStrEq( pcmd, "joincoop" ) )
|
if( FStrEq( pcmd, "joincoop" ) )
|
||||||
{
|
{
|
||||||
if( pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
if( pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
||||||
SpawnPlayer( pPlayer );
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
else
|
else
|
||||||
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "You cannot use joincoop now!\n\n" );
|
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "You cannot use joincoop now!\n\n" );
|
||||||
|
|
||||||
@ -240,57 +213,13 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
|||||||
{
|
{
|
||||||
int imenu = atoi( CMD_ARGV( 1 ) );
|
int imenu = atoi( CMD_ARGV( 1 ) );
|
||||||
|
|
||||||
switch( pPlayer->m_state )
|
UTIL_CoopProcessMenu( pPlayer, imenu );
|
||||||
{
|
|
||||||
case STATE_SPECTATOR_BEGIN:
|
|
||||||
case STATE_SPECTATOR:
|
|
||||||
if( imenu == 1 )
|
|
||||||
{
|
|
||||||
SpawnPlayer( pPlayer );
|
|
||||||
pPlayer->m_state = STATE_SPAWNED;
|
|
||||||
}
|
|
||||||
if( imenu == 2 )
|
|
||||||
{
|
|
||||||
pPlayer->m_state = STATE_SPECTATOR;
|
|
||||||
CLIENT_COMMAND( pPlayer->edict(), "touch_show _coopm*\n" );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STATE_SPAWNED:
|
|
||||||
if( g_iMenu )
|
|
||||||
{
|
|
||||||
CoopProcessMenu( pPlayer, imenu );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
if( imenu == 1 )
|
|
||||||
{
|
|
||||||
pPlayer->RemoveAllItems( TRUE );
|
|
||||||
SpawnPlayer( pPlayer );
|
|
||||||
}
|
|
||||||
if( imenu == 2 )
|
|
||||||
{
|
|
||||||
UTIL_CleanSpawnPoint( pPlayer->pev->origin, 150 );
|
|
||||||
}
|
|
||||||
if( imenu == 3 )
|
|
||||||
{
|
|
||||||
pPlayer->RemoveAllItems( TRUE );
|
|
||||||
BecomeSpectator( pPlayer );
|
|
||||||
pPlayer->m_state = STATE_SPECTATOR;
|
|
||||||
}
|
|
||||||
if( imenu == 4 )
|
|
||||||
{
|
|
||||||
CoopVoteMenu( pPlayer );
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if( FStrEq( pcmd, "coopmenu" ) )
|
if( FStrEq( pcmd, "coopmenu" ) )
|
||||||
{
|
{
|
||||||
if( !g_iMenu )
|
UTIL_CoopMenu( pPlayer );
|
||||||
CoopMenu( pPlayer );
|
|
||||||
else
|
|
||||||
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "You cannot use coopmenu now!\n\n" );
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -309,7 +238,8 @@ void CHalfLifeMultiplay::RefreshSkillData( void )
|
|||||||
// override some values for multiplay.
|
// override some values for multiplay.
|
||||||
|
|
||||||
// suitcharger
|
// suitcharger
|
||||||
gSkillData.suitchargerCapacity = 30;
|
if( !mp_coop.value )
|
||||||
|
gSkillData.suitchargerCapacity = 30;
|
||||||
|
|
||||||
// Crowbar whack
|
// Crowbar whack
|
||||||
gSkillData.plrDmgCrowbar = 25;
|
gSkillData.plrDmgCrowbar = 25;
|
||||||
@ -660,6 +590,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl )
|
|||||||
|
|
||||||
if( pl->m_state == STATE_SPECTATOR_BEGIN )
|
if( pl->m_state == STATE_SPECTATOR_BEGIN )
|
||||||
{
|
{
|
||||||
|
pl->m_iMenuState = MENUSTATE_COOPMENU_SPEC;
|
||||||
|
|
||||||
if( mp_coop.value )
|
if( mp_coop.value )
|
||||||
{
|
{
|
||||||
@ -667,7 +598,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl )
|
|||||||
"Join coop",
|
"Join coop",
|
||||||
"Join spectators"
|
"Join spectators"
|
||||||
};
|
};
|
||||||
ShowMenu( pl, "COOP SERVER", ARRAYSIZE( menu ), menu );
|
UTIL_CoopShowMenu( pl, "COOP SERVER", ARRAYSIZE( menu ), menu );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -745,7 +676,7 @@ void CHalfLifeMultiplay::PlayerThink( CBasePlayer *pPlayer )
|
|||||||
{
|
{
|
||||||
if( !mp_coop.value && pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
if( !mp_coop.value && pPlayer->m_state == STATE_SPECTATOR_BEGIN )
|
||||||
if( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) )
|
if( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) )
|
||||||
SpawnPlayer( pPlayer );
|
UTIL_SpawnPlayer( pPlayer );
|
||||||
if( pPlayer->m_state == STATE_UNINITIALIZED )
|
if( pPlayer->m_state == STATE_UNINITIALIZED )
|
||||||
if( pPlayer->m_afButtonPressed || pPlayer->pev->button )
|
if( pPlayer->m_afButtonPressed || pPlayer->pev->button )
|
||||||
{
|
{
|
||||||
@ -792,14 +723,14 @@ void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer )
|
|||||||
{
|
{
|
||||||
pPlayer->m_state = STATE_SPECTATOR_BEGIN;
|
pPlayer->m_state = STATE_SPECTATOR_BEGIN;
|
||||||
pPlayer->RemoveAllItems( TRUE );
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
BecomeSpectator( pPlayer );
|
UTIL_BecomeSpectator( pPlayer );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mp_coop.value && pPlayer->m_state == STATE_POINT_SELECT && !(pPlayer->pev->flags & FL_SPECTATOR) )
|
if( mp_coop.value && pPlayer->m_state == STATE_POINT_SELECT && !(pPlayer->pev->flags & FL_SPECTATOR) )
|
||||||
{
|
{
|
||||||
pPlayer->RemoveAllItems( TRUE );
|
pPlayer->RemoveAllItems( TRUE );
|
||||||
BecomeSpectator( pPlayer );
|
UTIL_BecomeSpectator( pPlayer );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1339,12 +1270,12 @@ Vector CHalfLifeMultiplay::VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo )
|
|||||||
//=========================================================
|
//=========================================================
|
||||||
float CHalfLifeMultiplay::FlHealthChargerRechargeTime( void )
|
float CHalfLifeMultiplay::FlHealthChargerRechargeTime( void )
|
||||||
{
|
{
|
||||||
return 60;
|
return cvar_iresptime.value * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CHalfLifeMultiplay::FlHEVChargerRechargeTime( void )
|
float CHalfLifeMultiplay::FlHEVChargerRechargeTime( void )
|
||||||
{
|
{
|
||||||
return 30;
|
return cvar_iresptime.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
@ -45,6 +45,8 @@ LINK_ENTITY_TO_CLASS( info_node_air, CNodeEnt )
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#define CreateDirectory(p, n) mkdir(p, 0777)
|
#define CreateDirectory(p, n) mkdir(p, 0777)
|
||||||
|
#else
|
||||||
|
#define CreateDirectory(p, n) CreateDirectoryA(p, n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
@ -92,9 +92,9 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
|
|||||||
DEFINE_ARRAY( CBasePlayer, m_rgflSuitNoRepeatTime, FIELD_TIME, CSUITNOREPEAT ),
|
DEFINE_ARRAY( CBasePlayer, m_rgflSuitNoRepeatTime, FIELD_TIME, CSUITNOREPEAT ),
|
||||||
DEFINE_FIELD( CBasePlayer, m_lastDamageAmount, FIELD_INTEGER ),
|
DEFINE_FIELD( CBasePlayer, m_lastDamageAmount, FIELD_INTEGER ),
|
||||||
|
|
||||||
DEFINE_ARRAY( CBasePlayer, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ),
|
DEFINE_ARRAY( CBasePlayer, m_rgpPlayerItems, FIELD_EHANDLE, MAX_ITEM_TYPES ),
|
||||||
DEFINE_FIELD( CBasePlayer, m_pActiveItem, FIELD_CLASSPTR ),
|
DEFINE_FIELD( CBasePlayer, m_pActiveItem, FIELD_EHANDLE ),
|
||||||
DEFINE_FIELD( CBasePlayer, m_pLastItem, FIELD_CLASSPTR ),
|
DEFINE_FIELD( CBasePlayer, m_pLastItem, FIELD_EHANDLE ),
|
||||||
|
|
||||||
DEFINE_ARRAY( CBasePlayer, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
|
DEFINE_ARRAY( CBasePlayer, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
|
||||||
DEFINE_FIELD( CBasePlayer, m_idrowndmg, FIELD_INTEGER ),
|
DEFINE_FIELD( CBasePlayer, m_idrowndmg, FIELD_INTEGER ),
|
||||||
|
@ -93,6 +93,18 @@ enum PlayerState
|
|||||||
STATE_POINT_SELECT
|
STATE_POINT_SELECT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PlayerMenuState
|
||||||
|
{
|
||||||
|
MENUSTATE_NONE = 0,
|
||||||
|
MENUSTATE_COOPMENU,
|
||||||
|
MENUSTATE_COOPMENU_SPEC,
|
||||||
|
MENUSTATE_CHECKPOINT,
|
||||||
|
MENUSTATE_GLOBAL,
|
||||||
|
MENUSTATE_LOCAL_CONFIRM
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "whandle.h"
|
||||||
|
|
||||||
class CBasePlayer : public CBaseMonster
|
class CBasePlayer : public CBaseMonster
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -173,10 +185,10 @@ public:
|
|||||||
int m_iClientFOV; // client's known FOV
|
int m_iClientFOV; // client's known FOV
|
||||||
|
|
||||||
// usable player items
|
// usable player items
|
||||||
CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];
|
EHBasePlayerItem m_rgpPlayerItems[MAX_ITEM_TYPES];
|
||||||
CBasePlayerItem *m_pActiveItem;
|
EHBasePlayerItem m_pActiveItem;
|
||||||
CBasePlayerItem *m_pClientActiveItem; // client version of the active item
|
EHBasePlayerItem m_pClientActiveItem; // client version of the active item
|
||||||
CBasePlayerItem *m_pLastItem;
|
EHBasePlayerItem m_pLastItem;
|
||||||
|
|
||||||
// shared ammo slots
|
// shared ammo slots
|
||||||
int m_rgAmmo[MAX_AMMO_SLOTS];
|
int m_rgAmmo[MAX_AMMO_SLOTS];
|
||||||
@ -323,6 +335,9 @@ public:
|
|||||||
float m_flSpawnTime;
|
float m_flSpawnTime;
|
||||||
PlayerState m_state;
|
PlayerState m_state;
|
||||||
bool m_fTouchMenu;
|
bool m_fTouchMenu;
|
||||||
|
int m_iMenuState;
|
||||||
|
int m_iLocalConfirm;
|
||||||
|
int m_iConfirmKey;
|
||||||
virtual void Touch( CBaseEntity *pOther );
|
virtual void Touch( CBaseEntity *pOther );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "talkmonster.h"
|
#include "talkmonster.h"
|
||||||
#include "gamerules.h"
|
#include "gamerules.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize );
|
static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize );
|
||||||
|
|
||||||
@ -1264,7 +1265,7 @@ void SENTENCEG_Init()
|
|||||||
isentencegs = -1;
|
isentencegs = -1;
|
||||||
|
|
||||||
int filePos = 0, fileSize;
|
int filePos = 0, fileSize;
|
||||||
byte *pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/sentences.txt", &fileSize );
|
byte *pMemFile = g_engfuncs.pfnLoadFileForMe( sentences_txt.string, &fileSize );
|
||||||
if( !pMemFile )
|
if( !pMemFile )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1528,7 +1529,7 @@ void TEXTURETYPE_Init()
|
|||||||
|
|
||||||
gcTextures = 0;
|
gcTextures = 0;
|
||||||
|
|
||||||
pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/materials.txt", &fileSize );
|
pMemFile = g_engfuncs.pfnLoadFileForMe( materials_txt.string, &fileSize );
|
||||||
if( !pMemFile )
|
if( !pMemFile )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1342,6 +1342,8 @@ BOOL CTalkMonster::CanFollow( void )
|
|||||||
{
|
{
|
||||||
if( m_MonsterState == MONSTERSTATE_SCRIPT )
|
if( m_MonsterState == MONSTERSTATE_SCRIPT )
|
||||||
{
|
{
|
||||||
|
if( !m_pCine )
|
||||||
|
return FALSE;
|
||||||
if( !m_pCine->CanInterrupt() )
|
if( !m_pCine->CanInterrupt() )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ void CBaseTrigger::HurtTouch( CBaseEntity *pOther )
|
|||||||
// HACKHACK -- In multiplayer, players touch this based on packet receipt.
|
// HACKHACK -- In multiplayer, players touch this based on packet receipt.
|
||||||
// So the players who send packets later aren't always hurt. Keep track of
|
// So the players who send packets later aren't always hurt. Keep track of
|
||||||
// how much time has passed and whether or not you've touched that player
|
// how much time has passed and whether or not you've touched that player
|
||||||
if( g_pGameRules->IsMultiplayer() )
|
if( !mp_coop.value && g_pGameRules->IsMultiplayer() )
|
||||||
{
|
{
|
||||||
if( pev->dmgtime > gpGlobals->time )
|
if( pev->dmgtime > gpGlobals->time )
|
||||||
{
|
{
|
||||||
@ -1350,6 +1350,7 @@ public:
|
|||||||
bool m_fSpawnSaved;
|
bool m_fSpawnSaved;
|
||||||
bool m_fIsBack;
|
bool m_fIsBack;
|
||||||
bool m_fSkipSpawnCheck; // skip 30 seconds check when called by multimanager or trigger_once
|
bool m_fSkipSpawnCheck; // skip 30 seconds check when called by multimanager or trigger_once
|
||||||
|
float m_flRepeatTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
LINK_ENTITY_TO_CLASS( trigger_changelevel, CChangeLevel )
|
LINK_ENTITY_TO_CLASS( trigger_changelevel, CChangeLevel )
|
||||||
@ -1486,223 +1487,62 @@ void CChangeLevel::UseChangeLevel( CBaseEntity *pActivator, CBaseEntity *pCaller
|
|||||||
ChangeLevelNow( pActivator );
|
ChangeLevelNow( pActivator );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SavedCoords
|
void UTIL_CoopActivateChangeLevel( CBaseEntity *pTrigger )
|
||||||
{
|
{
|
||||||
char ip[32][32];
|
CChangeLevel *trigger = (CChangeLevel*) pTrigger;
|
||||||
Vector origin[32];
|
|
||||||
Vector angles[32];
|
|
||||||
char landmark[32];
|
|
||||||
Vector triggerorigin;
|
|
||||||
Vector triggerangles;
|
|
||||||
Vector offset;
|
|
||||||
int iCount;
|
|
||||||
bool valid;
|
|
||||||
bool validoffset;
|
|
||||||
bool validspawnpoint;
|
|
||||||
int changeback;
|
|
||||||
bool trainsaved;
|
|
||||||
Vector trainoffset;
|
|
||||||
char trainglobal[256];
|
|
||||||
int trainuser1;
|
|
||||||
bool fUsed;
|
|
||||||
bool fDuck;
|
|
||||||
} g_SavedCoords, s_SavedCoords;
|
|
||||||
|
|
||||||
|
if( !trigger )
|
||||||
|
|
||||||
void CoopClearData( void )
|
|
||||||
{
|
|
||||||
// nullify
|
|
||||||
SavedCoords l_SavedCoords = {};
|
|
||||||
g_SavedCoords = l_SavedCoords;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool g_fPause;
|
|
||||||
void CoopApplyData( void )
|
|
||||||
{
|
|
||||||
if( s_SavedCoords.valid )
|
|
||||||
{
|
|
||||||
g_SavedCoords = s_SavedCoords;
|
|
||||||
s_SavedCoords = {};
|
|
||||||
g_fSavedDuck = g_SavedCoords.fDuck;
|
|
||||||
}
|
|
||||||
g_fPause = false;
|
|
||||||
ALERT( at_console, "^2CoopApplyData()\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
int g_iMenu;
|
|
||||||
|
|
||||||
void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 );
|
|
||||||
|
|
||||||
bool g_fSavedDuck;
|
|
||||||
|
|
||||||
#define CoopPlayerName( pPlayer ) ( ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected" )
|
|
||||||
|
|
||||||
void CoopKickPlayer(CBaseEntity *pPlayer)
|
|
||||||
{
|
|
||||||
if( !pPlayer )
|
|
||||||
return;
|
return;
|
||||||
SERVER_COMMAND( UTIL_VarArgs( "kick %d\n", ENTINDEX(pPlayer->pev->pContainingEntity) - 1 ) );
|
|
||||||
|
trigger->m_bUsed = true;
|
||||||
|
trigger->ChangeLevelNow( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show to all spawned players: voting, etc..
|
void GlobalMenu::VoteMenu( CBasePlayer *pPlayer )
|
||||||
class GlobalMenu
|
|
||||||
{
|
{
|
||||||
public:
|
if( g_iMenu && gpGlobals->time - m_flTime < 30 )
|
||||||
|
return; // wait 30s befor new confirm vote
|
||||||
int m_iConfirm;
|
CBaseEntity *pTrigger = NULL;
|
||||||
int m_iVoteCount;
|
int i = 0;
|
||||||
int m_iMaxCount;
|
g_iMenu = 2;
|
||||||
int m_iBanCount;
|
m_flTime = gpGlobals->time;
|
||||||
float m_flTime;
|
maps[i++] = "Keep this map";
|
||||||
const char *maps[5];
|
maps[i++] = "BAN";
|
||||||
int votes[5];
|
while( (pTrigger = UTIL_FindEntityByClassname( pTrigger, "trigger_changelevel" )) && (i < 5) )
|
||||||
CChangeLevel *triggers[5];
|
|
||||||
EHANDLE m_pTrigger;
|
|
||||||
EHANDLE m_pPlayer;
|
|
||||||
|
|
||||||
void Process( CBasePlayer *pPlayer, int imenu )
|
|
||||||
{
|
{
|
||||||
if( pPlayer->pev->flags & FL_SPECTATOR )
|
CChangeLevel *ent = (CChangeLevel *)pTrigger;
|
||||||
return;
|
votes[i] = 0;
|
||||||
if( gpGlobals->time - m_flTime > 30 )
|
triggers[i] = ent;
|
||||||
{
|
maps[i++] = ent->m_szMapName;
|
||||||
g_iMenu = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( g_iMenu )
|
|
||||||
{
|
|
||||||
case 1: // touch blue trigger
|
|
||||||
m_iVoteCount++;
|
|
||||||
|
|
||||||
if( imenu == 1 ) // confirm
|
|
||||||
{
|
|
||||||
if( m_iBanCount >= 2 )
|
|
||||||
{
|
|
||||||
CoopKickPlayer( pPlayer );
|
|
||||||
m_iConfirm-= 5;
|
|
||||||
return;
|
|
||||||
} m_iConfirm++;
|
|
||||||
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
|
||||||
WRITE_BYTE( 3 ); // PRINT_CHAT
|
|
||||||
WRITE_STRING( UTIL_VarArgs( "%s^7 confirmed map change\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
|
||||||
MESSAGE_END();
|
|
||||||
|
|
||||||
}
|
|
||||||
if( imenu == 2 ) // cancel
|
|
||||||
{
|
|
||||||
m_iConfirm--;
|
|
||||||
if( pPlayer == m_pPlayer )
|
|
||||||
m_iConfirm -= 100; // player mistake
|
|
||||||
}
|
|
||||||
if( imenu == 3 )
|
|
||||||
{
|
|
||||||
m_iBanCount++;
|
|
||||||
if( m_iBanCount >= 2 && m_iConfirm > -50 )
|
|
||||||
CoopKickPlayer( m_pPlayer );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: // vote by request
|
|
||||||
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
|
||||||
WRITE_BYTE( 3 ); // PRINT_CHAT
|
|
||||||
WRITE_STRING( UTIL_VarArgs( "%s^7 selected ^3%s\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected", maps[imenu - 1] ));
|
|
||||||
MESSAGE_END();
|
|
||||||
|
|
||||||
if( imenu < m_iConfirm )
|
|
||||||
{
|
|
||||||
votes[imenu-1]++;
|
|
||||||
m_iVoteCount++;
|
|
||||||
|
|
||||||
if( votes[1] >= 2 )
|
|
||||||
{
|
|
||||||
// two players vote for ban
|
|
||||||
CoopKickPlayer( m_pPlayer );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_iVoteCount >= m_iMaxCount )
|
|
||||||
{
|
|
||||||
for( int i = 0; i <= m_iConfirm; i++ )
|
|
||||||
if( votes[i] >= m_iMaxCount )
|
|
||||||
{
|
|
||||||
if( triggers[i])
|
|
||||||
{
|
|
||||||
triggers[i]->m_bUsed = true;
|
|
||||||
triggers[i]->ChangeLevelNow( NULL );
|
|
||||||
}
|
|
||||||
g_iMenu = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ShowGlobalMenu( const char *title, int count, const char **menu )
|
|
||||||
{
|
|
||||||
int count2 = 0;
|
|
||||||
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
|
||||||
{
|
|
||||||
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
|
||||||
|
|
||||||
if( plr && plr->IsPlayer() )
|
|
||||||
{
|
|
||||||
count2++;
|
|
||||||
ShowMenu( (CBasePlayer *)plr, title, count, menu, 30 );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_iMaxCount = count2;
|
|
||||||
m_iBanCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfirmMenu( CBasePlayer *pPlayer, CBaseEntity *trigger, const char *mapname )
|
|
||||||
{
|
|
||||||
if( g_iMenu && gpGlobals->time - m_flTime < 30 )
|
|
||||||
return; // wait 30s befor new confirm vote
|
|
||||||
g_iMenu = 1;
|
|
||||||
m_flTime = gpGlobals->time;
|
|
||||||
m_pTrigger = trigger;
|
|
||||||
m_pPlayer = pPlayer;
|
|
||||||
const char *menu[] = {
|
|
||||||
"Confirm",
|
|
||||||
"Cancel",
|
|
||||||
"BAN"
|
|
||||||
};
|
|
||||||
ShowGlobalMenu(UTIL_VarArgs("Confirm changing map to %s?", mapname), ARRAYSIZE(menu), menu);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void VoteMenu( CBasePlayer *pPlayer )
|
votes[i] = 0;
|
||||||
|
triggers[i] = NULL;
|
||||||
|
m_iConfirm = i;
|
||||||
|
m_iVoteCount = 0;
|
||||||
|
m_pPlayer = pPlayer;
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 opened vote menu\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
||||||
|
MESSAGE_END();
|
||||||
|
ShowGlobalMenu(UTIL_VarArgs("%s requested to force change map", UTIL_CoopPlayerName( pPlayer ) ), i, maps);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UTIL_CoopValidateOffset( void )
|
||||||
|
{
|
||||||
|
if( !g_SavedCoords.validoffset)
|
||||||
{
|
{
|
||||||
if( g_iMenu && gpGlobals->time - m_flTime < 30 )
|
edict_t *landmark = CChangeLevel::FindLandmark(g_SavedCoords.landmark);
|
||||||
return; // wait 30s befor new confirm vote
|
if(landmark)
|
||||||
CBaseEntity *pTrigger = NULL;
|
g_SavedCoords.offset = landmark->v.origin - g_SavedCoords.offset;
|
||||||
int i = 0;
|
else
|
||||||
g_iMenu = 2;
|
g_SavedCoords.offset = g_vecZero - g_SavedCoords.offset;
|
||||||
m_flTime = gpGlobals->time;
|
g_SavedCoords.validoffset = true;
|
||||||
maps[i++] = "Keep this map";
|
|
||||||
maps[i++] = "BAN";
|
|
||||||
while( (pTrigger = UTIL_FindEntityByClassname( pTrigger, "trigger_changelevel" )) && (i < 5) )
|
|
||||||
{
|
|
||||||
CChangeLevel *ent = (CChangeLevel *)pTrigger;
|
|
||||||
votes[i] = 0;
|
|
||||||
triggers[i] = ent;
|
|
||||||
maps[i++] = ent->m_szMapName;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
votes[i] = 0;
|
|
||||||
triggers[i] = NULL;
|
|
||||||
m_iConfirm = i;
|
|
||||||
m_iVoteCount = 0;
|
|
||||||
m_pPlayer = pPlayer;
|
|
||||||
ShowGlobalMenu(UTIL_VarArgs("%s requested to force change map", CoopPlayerName( pPlayer ) ), i, maps);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
|
||||||
GlobalMenu g_GlobalMenu;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1716,7 +1556,7 @@ void CChangeLevel::UpdateColor( void )
|
|||||||
if( !m_fIsBack && (pPlayer = UTIL_FindEntityByClassname( NULL, "info_player_start" )) )
|
if( !m_fIsBack && (pPlayer = UTIL_FindEntityByClassname( NULL, "info_player_start" )) )
|
||||||
if( (origin - pPlayer->pev->origin).Length() < 500 )
|
if( (origin - pPlayer->pev->origin).Length() < 500 )
|
||||||
m_fIsBack = true;
|
m_fIsBack = true;
|
||||||
if( !m_fIsBack && CoopGetSpawnPoint( &point, &angles ) )
|
if( !m_fIsBack && UTIL_CoopGetSpawnPoint( &point, &angles ) )
|
||||||
if( (origin - point).Length() < 500 )
|
if( (origin - point).Length() < 500 )
|
||||||
m_fIsBack = true;
|
m_fIsBack = true;
|
||||||
pev->rendercolor = g_vecZero;
|
pev->rendercolor = g_vecZero;
|
||||||
@ -1732,224 +1572,7 @@ void CChangeLevel::UpdateColor( void )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoopVoteMenu( CBasePlayer *pPlayer )
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
|
||||||
{
|
|
||||||
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
|
||||||
|
|
||||||
if( plr && plr->IsPlayer() )
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( count < 4 )
|
|
||||||
{
|
|
||||||
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "Need at least 4 players to vote changelevel!\n" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_GlobalMenu.VoteMenu(pPlayer);
|
|
||||||
}
|
|
||||||
void CoopMenu( CBasePlayer *pPlayer )
|
|
||||||
{
|
|
||||||
if( g_iMenu && gpGlobals->time - g_GlobalMenu.m_flTime < 30 )
|
|
||||||
return; // global menu active
|
|
||||||
if( pPlayer->m_state == STATE_SPAWNED )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( mp_coop.value )
|
|
||||||
{
|
|
||||||
const char *menu[] = {
|
|
||||||
"Force respawn",
|
|
||||||
"Unblock",
|
|
||||||
"Become spectator",
|
|
||||||
"Vote changelevel"
|
|
||||||
};
|
|
||||||
ShowMenu( pPlayer, "Coop menu", ARRAYSIZE( menu ), menu );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( pPlayer->m_state == STATE_SPECTATOR )
|
|
||||||
{
|
|
||||||
if( mp_coop.value )
|
|
||||||
{
|
|
||||||
const char *menu[] = {
|
|
||||||
"Spawn",
|
|
||||||
"Close menu"
|
|
||||||
};
|
|
||||||
ShowMenu( pPlayer, "Spectator menu", ARRAYSIZE( menu ), menu );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoopProcessMenu( CBasePlayer *pPlayer, int imenu )
|
|
||||||
{
|
|
||||||
return g_GlobalMenu.Process( pPlayer, imenu );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void validateoffset( void )
|
|
||||||
{
|
|
||||||
if( !g_SavedCoords.validoffset)
|
|
||||||
{
|
|
||||||
edict_t *landmark = CChangeLevel::FindLandmark(g_SavedCoords.landmark);
|
|
||||||
if(landmark)
|
|
||||||
g_SavedCoords.offset = landmark->v.origin - g_SavedCoords.offset;
|
|
||||||
else
|
|
||||||
g_SavedCoords.offset = g_vecZero - g_SavedCoords.offset;
|
|
||||||
g_SavedCoords.validoffset = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CoopRestorePlayerCoords(CBaseEntity *player, Vector *origin, Vector *angles )
|
|
||||||
{
|
|
||||||
if(!g_SavedCoords.valid)
|
|
||||||
return false;
|
|
||||||
validateoffset();
|
|
||||||
// compute player by IQ
|
|
||||||
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( player->edict() ), "ip" );
|
|
||||||
for( int i = 0;i < g_SavedCoords.iCount;i++)
|
|
||||||
{
|
|
||||||
if(ip && ip[0] && !strcmp(ip, g_SavedCoords.ip[i]) )
|
|
||||||
{
|
|
||||||
TraceResult tr;
|
|
||||||
Vector point = g_SavedCoords.origin[i] + g_SavedCoords.offset;
|
|
||||||
|
|
||||||
UTIL_TraceHull( point, point, missile, (mp_unduck.value&&g_fSavedDuck)?head_hull:human_hull, NULL, &tr );
|
|
||||||
|
|
||||||
g_SavedCoords.ip[i][0] = 0;
|
|
||||||
|
|
||||||
if( tr.fStartSolid || tr.fAllSolid )
|
|
||||||
return false;
|
|
||||||
*origin = point;
|
|
||||||
*angles = g_SavedCoords.angles[i];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CoopGetSpawnPoint( Vector *origin, Vector *angles)
|
|
||||||
{
|
|
||||||
if(!g_SavedCoords.valid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// spawn on elevator or train
|
|
||||||
if( g_SavedCoords.trainsaved )
|
|
||||||
{
|
|
||||||
CBaseEntity *train = UTIL_FindEntityByString( NULL, "globalname", g_SavedCoords.trainglobal );
|
|
||||||
if( !train ) train = UTIL_FindEntityByString( NULL, "classname", g_SavedCoords.trainglobal );
|
|
||||||
if( train && ( !g_SavedCoords.trainuser1 || train->pev->iuser1 == g_SavedCoords.trainuser1 ) )
|
|
||||||
{
|
|
||||||
*angles = g_SavedCoords.triggerangles;
|
|
||||||
*origin = VecBModelOrigin(train->pev) + g_SavedCoords.trainoffset;
|
|
||||||
g_SavedCoords.trainuser1 = train->pev->iuser1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ALERT( at_console, "Failed to get train %s (map design error?)\n", g_SavedCoords.trainglobal );
|
|
||||||
}
|
|
||||||
Vector point = g_SavedCoords.triggerorigin;
|
|
||||||
*angles = g_SavedCoords.triggerangles;
|
|
||||||
if( !g_SavedCoords.validspawnpoint )
|
|
||||||
{
|
|
||||||
TraceResult tr;
|
|
||||||
Vector angle;
|
|
||||||
UTIL_MakeVectorsPrivate( *angles, (float*)&angle, NULL, NULL );
|
|
||||||
validateoffset();
|
|
||||||
point = point + g_SavedCoords.offset;
|
|
||||||
//UTIL_TraceHull( point, point, ignore_monsters, human_hull, NULL, &tr );
|
|
||||||
|
|
||||||
if( mp_unduck.value && g_fSavedDuck && !g_SavedCoords.fUsed )
|
|
||||||
UTIL_TraceHull( point, point + angle * 100, missile, head_hull, NULL, &tr );
|
|
||||||
else
|
|
||||||
UTIL_TraceHull( point, point + angle * 100, ignore_monsters, human_hull, NULL, &tr );
|
|
||||||
|
|
||||||
if( !tr.fStartSolid && !tr.fAllSolid || ENTINDEX( tr.pHit ) && ENTINDEX( tr.pHit ) <= gpGlobals->maxClients )
|
|
||||||
{
|
|
||||||
//g_SavedCoords.triggerorigin = tr.vecEndPos;
|
|
||||||
//g_SavedCoords.validspawnpoint = true;
|
|
||||||
if( tr.pHit && FClassnameIs( tr.pHit, "func_door" ) )
|
|
||||||
tr.pHit->v.solid = SOLID_NOT;
|
|
||||||
ALERT( at_console, "CoopGetSpawnPoint: ^2offset set\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//g_SavedCoords.valid = false;
|
|
||||||
ALERT( at_console, "CoopGetSpawnPoint: ^2trace failed\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*origin = point;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CBaseEntity *CoopGetPlayerTrain( CBaseEntity *pPlayer)
|
|
||||||
{
|
|
||||||
CBaseEntity *train = NULL;
|
|
||||||
|
|
||||||
if( !pPlayer)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if( !pPlayer->IsPlayer() )
|
|
||||||
{
|
|
||||||
// activated by path track
|
|
||||||
train = pPlayer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( FNullEnt(pPlayer->pev->groundentity))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
train = CBaseEntity::Instance(pPlayer->pev->groundentity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !train )
|
|
||||||
return NULL;
|
|
||||||
if( !train->pev->globalname ||!STRING(train->pev->globalname) || !STRING(train->pev->globalname)[0] )
|
|
||||||
return NULL;
|
|
||||||
// doors are elevators
|
|
||||||
if( strcmp( STRING( train->pev->classname ), "func_train") && strcmp( STRING( train->pev->classname ), "func_tracktrain") && strcmp( STRING( train->pev->classname ), "func_door") )
|
|
||||||
return NULL;
|
|
||||||
return train;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If some player is on train with global state, save id
|
// If some player is on train with global state, save id
|
||||||
void CoopSaveTrain( CBaseEntity *pPlayer, SavedCoords *coords)
|
|
||||||
{
|
|
||||||
if( coords->trainsaved )
|
|
||||||
return;
|
|
||||||
|
|
||||||
CBaseEntity *train = CoopGetPlayerTrain(pPlayer);
|
|
||||||
if( !train )
|
|
||||||
{
|
|
||||||
ALERT( at_console, "^1NO TRAIN!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ALERT( at_console, "^1TRAIN IS %s\n", STRING( train->pev->classname ) );
|
|
||||||
|
|
||||||
if( !pPlayer->IsPlayer() )
|
|
||||||
{
|
|
||||||
// it is trainnitself, try find player on it
|
|
||||||
CBaseEntity *pList;
|
|
||||||
Vector mins = pPlayer->pev->absmin;
|
|
||||||
Vector maxs = pPlayer->pev->absmax;
|
|
||||||
maxs.z += 72;
|
|
||||||
int count = UTIL_EntitiesInBox( &pList, 1, mins, maxs, FL_ONGROUND );
|
|
||||||
if( count && pList && pList->IsPlayer() )
|
|
||||||
pPlayer = pList;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ALERT( at_console, "Train without players\n" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy( coords->trainglobal, STRING(train->pev->globalname) );
|
|
||||||
coords->trainoffset = pPlayer->pev->origin - VecBModelOrigin(train->pev);
|
|
||||||
coords->trainsaved = true;
|
|
||||||
}
|
|
||||||
void BecomeSpectator( CBasePlayer *pPlayer );
|
|
||||||
|
|
||||||
CBaseEntity *FindTriggerTransition( char *pVolumeName )
|
CBaseEntity *FindTriggerTransition( char *pVolumeName )
|
||||||
{
|
{
|
||||||
@ -2011,7 +1634,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
m_vecSpawnOrigin = pActivator->pev->origin;
|
m_vecSpawnOrigin = pActivator->pev->origin;
|
||||||
m_vecSpawnAngles = pActivator->pev->angles;
|
m_vecSpawnAngles = pActivator->pev->angles;
|
||||||
m_fSpawnSaved = true;
|
m_fSpawnSaved = true;
|
||||||
CoopSaveTrain( pActivator, &l_SavedCoords );
|
UTIL_CoopSaveTrain( pActivator, &l_SavedCoords );
|
||||||
}
|
}
|
||||||
unsigned int count1 = 0;
|
unsigned int count1 = 0;
|
||||||
unsigned int count2 = 0;
|
unsigned int count2 = 0;
|
||||||
@ -2021,9 +1644,13 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
for( i = 1; i <= gpGlobals->maxClients; i++ )
|
for( i = 1; i <= gpGlobals->maxClients; i++ )
|
||||||
{
|
{
|
||||||
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
||||||
|
CBaseEntity *pTrain = UTIL_CoopGetPlayerTrain( plr );
|
||||||
|
|
||||||
|
if( !pTrain && UTIL_CoopIsBadPlayer( plr ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
// count only players spawned more 30 seconds ago
|
// count only players spawned more 30 seconds ago
|
||||||
if( plr && plr->IsPlayer() && (CoopGetPlayerTrain(plr) || (gpGlobals->time -((CBasePlayer*)plr)->m_flSpawnTime ) > 30 ) )
|
if( plr && plr->IsPlayer() && (pTrain || (gpGlobals->time -((CBasePlayer*)plr)->m_flSpawnTime ) > 30 ) )
|
||||||
{
|
{
|
||||||
count2++;
|
count2++;
|
||||||
|
|
||||||
@ -2034,7 +1661,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
if( InTransitionVolume( plr, m_szLandmarkName ))
|
if( InTransitionVolume( plr, m_szLandmarkName ))
|
||||||
{
|
{
|
||||||
l_SavedCoords.fDuck |= !!(plr->pev->flags & FL_DUCKING);
|
l_SavedCoords.fDuck |= !!(plr->pev->flags & FL_DUCKING);
|
||||||
CoopSaveTrain( plr, &l_SavedCoords );
|
UTIL_CoopSaveTrain( plr, &l_SavedCoords );
|
||||||
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( plr->edict() ), "ip" );
|
char *ip = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( plr->edict() ), "ip" );
|
||||||
strcpy(l_SavedCoords.ip[l_SavedCoords.iCount], ip );
|
strcpy(l_SavedCoords.ip[l_SavedCoords.iCount], ip );
|
||||||
l_SavedCoords.origin[l_SavedCoords.iCount] = plr->pev->origin;
|
l_SavedCoords.origin[l_SavedCoords.iCount] = plr->pev->origin;
|
||||||
@ -2049,53 +1676,74 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
i = 0;
|
i = 0;
|
||||||
if( !l_SavedCoords.trainsaved )
|
if( !l_SavedCoords.trainsaved )
|
||||||
{
|
{
|
||||||
if( !count2 )
|
if( !count2 )
|
||||||
{
|
{
|
||||||
UTIL_HudMessageAll( params, "Cannot change level: Not enough players! Wait 30 sec before you may changelevel!" );
|
if( pActivator && pActivator->IsPlayer() && m_flRepeatTimer - gpGlobals->time < -1 )
|
||||||
return;
|
{
|
||||||
}
|
CBasePlayer *pPlayer = (CBasePlayer*)pActivator;
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 trying activate changelevel too soon\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
||||||
|
MESSAGE_END();
|
||||||
|
UTIL_CleanSpawnPoint( pPlayer->pev->origin, 50 );
|
||||||
|
m_flRepeatTimer = gpGlobals->time;
|
||||||
|
pPlayer->m_iLocalConfirm = -2;
|
||||||
|
}
|
||||||
|
|
||||||
if( count1 > 1 && count1 < count2 / 3 )
|
UTIL_HudMessageAll( params, "Cannot change level: Not enough players!\nWait 30 sec before you may changelevel!" );
|
||||||
i = count1 - count1 < count2 / 3;
|
return;
|
||||||
if( count1 > 1 && count1 < count2 / 3 )
|
}
|
||||||
i = 1;
|
|
||||||
|
if( count1 > 1 && count1 < count2 / 3 )
|
||||||
|
i = count1 - count1 < count2 / 3;
|
||||||
|
if( count1 > 1 && count1 < count2 / 3 )
|
||||||
|
i = 1;
|
||||||
|
|
||||||
|
if( i )
|
||||||
|
UTIL_HudMessageAll( params, UTIL_VarArgs( "%s touched end of map\nnext is %s %s, %d to go\n",
|
||||||
|
( pActivator->pev->netname && STRING( pActivator->pev->netname )[0] != 0 ) ? STRING( pActivator->pev->netname ) : "unconnected",
|
||||||
|
st_szNextMap, st_szNextSpot, i ) );
|
||||||
|
if( count2 )
|
||||||
|
{
|
||||||
|
pev->rendercolor.x = count1 * 255 / count2;
|
||||||
|
if( m_fIsBack )
|
||||||
|
pev->rendercolor.z = 255 - pev->rendercolor.x;
|
||||||
|
else
|
||||||
|
pev->rendercolor.y = 255 - pev->rendercolor.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALERT( at_console, "^3CHANGELEVEL:^7 %d %d\n", count2, count1 );
|
||||||
|
|
||||||
|
if( count1 > 1 && count1 < count2 / 3 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if( count1 <= 1 && count2 == 2 )
|
||||||
|
// return;
|
||||||
|
|
||||||
if( i )
|
|
||||||
UTIL_HudMessageAll( params, UTIL_VarArgs( "%s touched end of map, next is %s %s, %d to go",
|
|
||||||
( pActivator->pev->netname && STRING( pActivator->pev->netname )[0] != 0 ) ? STRING( pActivator->pev->netname ) : "unconnected",
|
|
||||||
st_szNextMap, st_szNextSpot, i ) );
|
|
||||||
if( count2 )
|
|
||||||
{
|
|
||||||
pev->rendercolor.x = count1 * 255 / count2;
|
|
||||||
if( m_fIsBack )
|
if( m_fIsBack )
|
||||||
pev->rendercolor.z = 255 - pev->rendercolor.x;
|
|
||||||
else
|
|
||||||
pev->rendercolor.y = 255 - pev->rendercolor.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALERT( at_console, "^3CHANGELEVEL:^7 %d %d\n", count2, count1 );
|
|
||||||
|
|
||||||
if( count1 > 1 && count1 < count2 / 3 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
//if( count1 <= 1 && count2 == 2 )
|
|
||||||
// return;
|
|
||||||
|
|
||||||
if( m_fIsBack )
|
|
||||||
{
|
|
||||||
if( gpGlobals->time - g_GlobalMenu.m_flTime > 30 )
|
|
||||||
{
|
{
|
||||||
g_iMenu = 0;
|
if( gpGlobals->time - g_GlobalMenu.m_flTime > 30 )
|
||||||
g_GlobalMenu.m_iConfirm = 0;
|
{
|
||||||
|
g_iMenu = 0;
|
||||||
|
g_GlobalMenu.m_iConfirm = 0;
|
||||||
|
}
|
||||||
|
if( g_iMenu != 1 )
|
||||||
|
{
|
||||||
|
if( !UTIL_CoopIsBadPlayer( pActivator ) )
|
||||||
|
g_GlobalMenu.ConfirmMenu( (CBasePlayer*)pActivator, this, m_szMapName );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( g_GlobalMenu.m_iConfirm < count2 )
|
||||||
|
return;
|
||||||
|
//if( mp_coop_strongpolicy.value )
|
||||||
|
/*{
|
||||||
|
// do not allow go back if there are checkpoints, but not near changelevel
|
||||||
|
if( g_checkpoints[0].time && (g_checkpoints[0].origin - VecBModelOrigin(pev)).Length() > 150 )
|
||||||
|
return;
|
||||||
|
if( count2 < 2 )
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
if( g_iMenu != 1 )
|
|
||||||
{
|
|
||||||
g_GlobalMenu.ConfirmMenu( (CBasePlayer*)pActivator, this, m_szMapName );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( g_GlobalMenu.m_iConfirm < count2 )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_fSpawnSaved )
|
if( m_fSpawnSaved )
|
||||||
@ -2119,7 +1767,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
CoopSaveTrain( pActivator, &l_SavedCoords );
|
UTIL_CoopSaveTrain( pActivator, &l_SavedCoords );
|
||||||
s_SavedCoords = l_SavedCoords;
|
s_SavedCoords = l_SavedCoords;
|
||||||
|
|
||||||
|
|
||||||
@ -2145,18 +1793,18 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
||||||
|
|
||||||
|
if( plr && plr->IsPlayer() && ( !FindTriggerTransition( m_szLandmarkName ) || (gpGlobals->time -((CBasePlayer*)plr)->m_flSpawnTime ) > 30 || m_fSkipSpawnCheck ) )
|
||||||
{
|
{
|
||||||
CBaseEntity *plr = UTIL_PlayerByIndex( i );
|
if( InTransitionVolume( plr, m_szLandmarkName ))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
if( plr && plr->IsPlayer() && ( !FindTriggerTransition( m_szLandmarkName ) || (gpGlobals->time -((CBasePlayer*)plr)->m_flSpawnTime ) > 30 ) || m_fSkipSpawnCheck )
|
|
||||||
{
|
|
||||||
if( InTransitionVolume( plr, m_szLandmarkName ))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if( !count )
|
if( !count )
|
||||||
{
|
{
|
||||||
ALERT( at_console, "There are no players in transition volume %s, aborting\n", m_szLandmarkName );
|
ALERT( at_console, "There are no players in transition volume %s, aborting\n", m_szLandmarkName );
|
||||||
@ -2170,19 +1818,11 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
ALERT( at_console, "Player isn't in the transition volume %s, aborting\n", m_szLandmarkName );
|
ALERT( at_console, "Player isn't in the transition volume %s, aborting\n", m_szLandmarkName );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//else
|
|
||||||
/* if !pPlayer
|
|
||||||
{
|
|
||||||
ALERT( at_console, ", aborting\n" );
|
|
||||||
return;
|
|
||||||
|
|
||||||
}*/
|
MESSAGE_BEGIN( MSG_ALL, 8, NULL ); // svc_print
|
||||||
|
WRITE_BYTE( 3 ); // PRINT_CHAT
|
||||||
|
WRITE_STRING( UTIL_VarArgs( "%s^7 activated changelevel\n", ( pPlayer->pev->netname && STRING( pPlayer->pev->netname )[0] != 0 ) ? STRING( pPlayer->pev->netname ) : "unconnected"));
|
||||||
// shedule remove ke^w on first info_player_start
|
MESSAGE_END();
|
||||||
/*edict_t *playerstart = FIND_ENTITY_BY_CLASSNAME( NULL, "info_player_start" );
|
|
||||||
if( !FNullEnt(playerstart) )
|
|
||||||
playerstart->v.flags |= FL_KILLME;*/
|
|
||||||
|
|
||||||
// This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory
|
// This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory
|
||||||
strcpy( st_szNextMap, m_szMapName );
|
strcpy( st_szNextMap, m_szMapName );
|
||||||
@ -2226,33 +1866,27 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
|
|||||||
// loop through all clients, reset state
|
// loop through all clients, reset state
|
||||||
if( mp_coop_changelevel.value )
|
if( mp_coop_changelevel.value )
|
||||||
{
|
{
|
||||||
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
for( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||||
{
|
|
||||||
CBasePlayer *plr = (CBasePlayer*)UTIL_PlayerByIndex( i );
|
|
||||||
|
|
||||||
// reset all players state
|
|
||||||
if( plr )
|
|
||||||
{
|
{
|
||||||
plr->m_state = STATE_UNINITIALIZED;
|
CBasePlayer *plr = (CBasePlayer*)UTIL_PlayerByIndex( i );
|
||||||
plr->RemoveAllItems( TRUE );
|
|
||||||
BecomeSpectator( plr );
|
// reset all players state to make it spawn again after restart
|
||||||
//plr->SetThink( &CBasePlayer::Spawn );
|
if( plr )
|
||||||
//plr->pev->nextthink = gpGlobals->time + 1;
|
{
|
||||||
// HACK: force perform reconnection
|
plr->m_state = STATE_UNINITIALIZED;
|
||||||
if( mp_coop_reconnect_hack.value )
|
plr->RemoveAllItems( TRUE );
|
||||||
CLIENT_COMMAND( plr->edict(), "reconnect\n" );
|
UTIL_BecomeSpectator( plr );
|
||||||
|
// HACK: force perform reconnection
|
||||||
//CLIENT_COMMAND( plr->edict(), "alias cmd \"reconnect;unalias cmd\"\n" );
|
if( mp_coop_reconnect_hack.value )
|
||||||
//MESSAGE_BEGIN( MSG_ONE, 2, NULL, plr->pev ); // svc_disconnect after stufftext
|
CLIENT_COMMAND( plr->edict(), "reconnect\n" );
|
||||||
//MESSAGE_END();
|
}
|
||||||
//SERVER_COMMAND( UTIL_VarArgs( "kick %d\n", i-1 ) );
|
|
||||||
//SERVER_EXECUTE();
|
|
||||||
}
|
}
|
||||||
}
|
g_fPause = true;
|
||||||
g_fPause = true;
|
|
||||||
}
|
}
|
||||||
s_SavedCoords.fUsed = m_bUsed;
|
s_SavedCoords.fUsed = m_bUsed;
|
||||||
s_SavedCoords.valid = valid;
|
s_SavedCoords.valid = valid;
|
||||||
|
|
||||||
|
// wait 5 frames to make sure all players are in reconnected state
|
||||||
if( mp_coop_reconnect_hack.value )
|
if( mp_coop_reconnect_hack.value )
|
||||||
SERVER_COMMAND( UTIL_VarArgs( "wait;wait;wait;wait;wait;changelevel %s %s\n", st_szNextMap, st_szNextSpot ) );
|
SERVER_COMMAND( UTIL_VarArgs( "wait;wait;wait;wait;wait;changelevel %s %s\n", st_szNextMap, st_szNextSpot ) );
|
||||||
else
|
else
|
||||||
|
@ -1578,21 +1578,6 @@ void UTIL_StripToken( const char *pKey, char *pDest )
|
|||||||
pDest[i] = 0;
|
pDest[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_CleanSpawnPoint( Vector origin, float dist )
|
|
||||||
{
|
|
||||||
CBaseEntity *ent = NULL;
|
|
||||||
while( ( ent = UTIL_FindEntityInSphere( ent, origin, dist ) ) != NULL )
|
|
||||||
{
|
|
||||||
if( ent->IsPlayer() )
|
|
||||||
{
|
|
||||||
TraceResult tr;
|
|
||||||
UTIL_TraceHull( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), dont_ignore_monsters, human_hull, ent->edict(), &tr);
|
|
||||||
//UTIL_TraceModel( ent->pev->origin + Vector( 0, 0, 36), ent->pev->origin + Vector( RANDOM_FLOAT( -150, 150 ), RANDOM_FLOAT( -150, 150 ), 0 ), 0, ent->edict(), &tr);
|
|
||||||
if( !tr.fAllSolid )
|
|
||||||
UTIL_SetOrigin(ent->pev, tr.vecEndPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -568,4 +568,3 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high );
|
|||||||
float UTIL_SharedRandomFloat( unsigned int seed, float low, float high );
|
float UTIL_SharedRandomFloat( unsigned int seed, float low, float high );
|
||||||
|
|
||||||
float UTIL_WeaponTimeBase( void );
|
float UTIL_WeaponTimeBase( void );
|
||||||
void UTIL_CleanSpawnPoint( Vector origin, float radius );
|
|
||||||
|
@ -394,7 +394,7 @@ void W_Precache( void )
|
|||||||
TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] =
|
TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] =
|
||||||
{
|
{
|
||||||
DEFINE_FIELD( CBasePlayerItem, m_pPlayer, FIELD_CLASSPTR ),
|
DEFINE_FIELD( CBasePlayerItem, m_pPlayer, FIELD_CLASSPTR ),
|
||||||
DEFINE_FIELD( CBasePlayerItem, m_pNext, FIELD_CLASSPTR ),
|
DEFINE_FIELD( CBasePlayerItem, m_pNext, FIELD_EHANDLE ),
|
||||||
//DEFINE_FIELD( CBasePlayerItem, m_fKnown, FIELD_INTEGER ),Reset to zero on load
|
//DEFINE_FIELD( CBasePlayerItem, m_fKnown, FIELD_INTEGER ),Reset to zero on load
|
||||||
DEFINE_FIELD( CBasePlayerItem, m_iId, FIELD_INTEGER ),
|
DEFINE_FIELD( CBasePlayerItem, m_iId, FIELD_INTEGER ),
|
||||||
// DEFINE_FIELD( CBasePlayerItem, m_iIdPrimary, FIELD_INTEGER ),
|
// DEFINE_FIELD( CBasePlayerItem, m_iIdPrimary, FIELD_INTEGER ),
|
||||||
@ -1244,7 +1244,7 @@ void CBasePlayerAmmo::DefaultTouch( CBaseEntity *pOther )
|
|||||||
//=========================================================
|
//=========================================================
|
||||||
int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon )
|
int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon )
|
||||||
{
|
{
|
||||||
int iReturn;
|
int iReturn = 0;
|
||||||
|
|
||||||
if( pszAmmo1() != NULL )
|
if( pszAmmo1() != NULL )
|
||||||
{
|
{
|
||||||
@ -1304,7 +1304,7 @@ TYPEDESCRIPTION CWeaponBox::m_SaveData[] =
|
|||||||
{
|
{
|
||||||
DEFINE_ARRAY( CWeaponBox, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
|
DEFINE_ARRAY( CWeaponBox, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ),
|
||||||
DEFINE_ARRAY( CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ),
|
DEFINE_ARRAY( CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ),
|
||||||
DEFINE_ARRAY( CWeaponBox, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ),
|
DEFINE_ARRAY( CWeaponBox, m_rgpPlayerItems, FIELD_EHANDLE, MAX_ITEM_TYPES ),
|
||||||
DEFINE_FIELD( CWeaponBox, m_cAmmoTypes, FIELD_INTEGER ),
|
DEFINE_FIELD( CWeaponBox, m_cAmmoTypes, FIELD_INTEGER ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,6 +217,9 @@ typedef struct
|
|||||||
int iId;
|
int iId;
|
||||||
} AmmoInfo;
|
} AmmoInfo;
|
||||||
|
|
||||||
|
#include "whandle.h"
|
||||||
|
|
||||||
|
|
||||||
// Items that the player has in their inventory that they can use
|
// Items that the player has in their inventory that they can use
|
||||||
class CBasePlayerItem : public CBaseAnimating
|
class CBasePlayerItem : public CBaseAnimating
|
||||||
{
|
{
|
||||||
@ -265,7 +268,7 @@ public:
|
|||||||
static AmmoInfo AmmoInfoArray[ MAX_AMMO_SLOTS ];
|
static AmmoInfo AmmoInfoArray[ MAX_AMMO_SLOTS ];
|
||||||
|
|
||||||
CBasePlayer *m_pPlayer;
|
CBasePlayer *m_pPlayer;
|
||||||
CBasePlayerItem *m_pNext;
|
EHBasePlayerItem m_pNext;
|
||||||
int m_iId; // WEAPON_???
|
int m_iId; // WEAPON_???
|
||||||
|
|
||||||
virtual int iItemSlot( void ) { return 0; } // return 0 to MAX_ITEMS_SLOTS, used in hud
|
virtual int iItemSlot( void ) { return 0; } // return 0 to MAX_ITEMS_SLOTS, used in hud
|
||||||
@ -456,7 +459,7 @@ public:
|
|||||||
BOOL PackWeapon( CBasePlayerItem *pWeapon );
|
BOOL PackWeapon( CBasePlayerItem *pWeapon );
|
||||||
BOOL PackAmmo( int iszName, int iCount );
|
BOOL PackAmmo( int iszName, int iCount );
|
||||||
|
|
||||||
CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each
|
EHBasePlayerItem m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each
|
||||||
|
|
||||||
int m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names
|
int m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names
|
||||||
int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
|
int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities
|
||||||
|
46
dlls/whandle.h
Normal file
46
dlls/whandle.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef WHANDLE_H
|
||||||
|
#define WHANDLE_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CBasePlayerItem;
|
||||||
|
|
||||||
|
class EHBasePlayerItem : public EHANDLE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
operator CBasePlayerItem *()
|
||||||
|
{
|
||||||
|
return (CBasePlayerItem *)GET_PRIVATE( Get() );
|
||||||
|
}
|
||||||
|
CBasePlayerItem *operator ->()
|
||||||
|
{
|
||||||
|
return (CBasePlayerItem *)GET_PRIVATE( Get() );
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
operator T()
|
||||||
|
{
|
||||||
|
return (T)GET_PRIVATE( Get() );
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
T *operator = ( T *pEntity )
|
||||||
|
{
|
||||||
|
edict_t *e = NULL;
|
||||||
|
if( pEntity )
|
||||||
|
e = pEntity->edict();
|
||||||
|
return (T*)CBaseEntity::Instance( Set ( e ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle = NULL correctly
|
||||||
|
int operator = ( int null1 )
|
||||||
|
{
|
||||||
|
//assert( !null1 );
|
||||||
|
Set(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !=(EHBasePlayerItem &other)
|
||||||
|
{
|
||||||
|
return Get() != other.Get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
@ -230,6 +230,9 @@ void CopyToBodyQue( entvars_t *pev )
|
|||||||
if( pev->effects & EF_NODRAW )
|
if( pev->effects & EF_NODRAW )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if( !g_pBodyQueueHead )
|
||||||
|
InitBodyQue();
|
||||||
|
|
||||||
entvars_t *pevHead = VARS( g_pBodyQueueHead );
|
entvars_t *pevHead = VARS( g_pBodyQueueHead );
|
||||||
|
|
||||||
pevHead->angles = pev->angles;
|
pevHead->angles = pev->angles;
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
#ifdef CLIENT_DLL
|
#ifdef CLIENT_DLL
|
||||||
// Spectator Mode
|
// Spectator Mode
|
||||||
int iJumpSpectator;
|
int iJumpSpectator;
|
||||||
float vJumpOrigin[3];
|
extern float vJumpOrigin[3];
|
||||||
float vJumpAngles[3];
|
extern float vJumpAngles[3];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int pm_shared_initialized = 0;
|
static int pm_shared_initialized = 0;
|
||||||
@ -122,6 +122,14 @@ static char grgchTextureType[CTEXTURESMAX];
|
|||||||
|
|
||||||
int g_onladder = 0;
|
int g_onladder = 0;
|
||||||
|
|
||||||
|
#ifdef CLIENT_DLL
|
||||||
|
#define materials_path "sound/materials.txt"
|
||||||
|
#else
|
||||||
|
#include "cvardef.h"
|
||||||
|
extern cvar_t materials_txt;
|
||||||
|
#define materials_path materials_txt.string
|
||||||
|
#endif
|
||||||
|
|
||||||
void PM_SwapTextures( int i, int j )
|
void PM_SwapTextures( int i, int j )
|
||||||
{
|
{
|
||||||
char chTemp;
|
char chTemp;
|
||||||
@ -173,8 +181,8 @@ void PM_InitTextureTypes()
|
|||||||
|
|
||||||
gcTextures = 0;
|
gcTextures = 0;
|
||||||
|
|
||||||
fileSize = pmove->COM_FileSize( "sound/materials.txt" );
|
fileSize = pmove->COM_FileSize( materials_path );
|
||||||
pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL );
|
pMemFile = pmove->COM_LoadFile( materials_path, 5, NULL );
|
||||||
if( !pMemFile )
|
if( !pMemFile )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user