Browse Source

Big refactoring

gravgun
mittorn 8 years ago
parent
commit
578f3b93c1
  1. 3
      dlls/Android.mk
  2. 8
      dlls/client.cpp
  3. 617
      dlls/coop.cpp
  4. 108
      dlls/coop_util.h
  5. 30
      dlls/game.h
  6. 25
      dlls/gamerules.cpp
  7. 49
      dlls/multiplay_gamerules.cpp
  8. 621
      dlls/triggers.cpp
  9. 15
      dlls/util.cpp
  10. 1
      dlls/util.h

3
dlls/Android.mk

@ -131,7 +131,8 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \ @@ -131,7 +131,8 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
big_cock.cpp \
../pm_shared/pm_debug.c \
../pm_shared/pm_math.c \
../pm_shared/pm_shared.c
../pm_shared/pm_shared.c \
coop.cpp
# ../game_shared/voice_gamemgr.cpp
LOCAL_LDLIBS := -llog

8
dlls/client.cpp

@ -51,7 +51,7 @@ extern int gmsgSayText; @@ -51,7 +51,7 @@ extern int gmsgSayText;
extern int g_teamplay;
void LinkUserMessages( void );
void BecomeSpectator( CBasePlayer *pPlayer );
void UTIL_BecomeSpectator( CBasePlayer *pPlayer );
/*
* used by kill command and disconnect command
* 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 @@ -85,7 +85,7 @@ BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddres
{
pl->m_state = STATE_UNINITIALIZED;
pl->RemoveAllItems( TRUE );
BecomeSpectator( pl );
UTIL_BecomeSpectator( pl );
}
}
@ -228,7 +228,7 @@ void ClientPutInServer( edict_t *pEntity ) @@ -228,7 +228,7 @@ void ClientPutInServer( edict_t *pEntity )
if( mp_spectator.value )
{
pPlayer->RemoveAllItems( TRUE );
BecomeSpectator( pPlayer );
UTIL_BecomeSpectator( pPlayer );
}
// Reset interpolation during first frame
@ -710,7 +710,7 @@ void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) @@ -710,7 +710,7 @@ void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
{
plr->m_state = STATE_UNINITIALIZED;
plr->RemoveAllItems( TRUE );
BecomeSpectator( plr );
UTIL_BecomeSpectator( plr );
//plr->Spawn();
}
}

617
dlls/coop.cpp

@ -0,0 +1,617 @@ @@ -0,0 +1,617 @@
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "coop_util.h"
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;
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;
}
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;
}
GlobalMenu g_GlobalMenu;
struct SavedCoords g_SavedCoords, s_SavedCoords;

108
dlls/coop_util.h

@ -0,0 +1,108 @@ @@ -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

30
dlls/game.h

@ -35,36 +35,8 @@ extern cvar_t teamlist; @@ -35,36 +35,8 @@ extern cvar_t teamlist;
extern cvar_t teamoverride;
extern cvar_t defaultteam;
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;
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;
#include "coop_util.h"
// Engine Cvars
extern cvar_t *g_psv_gravity;

25
dlls/gamerules.cpp

@ -57,27 +57,8 @@ BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int @@ -57,27 +57,8 @@ BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int
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;
//=========================================================
//=========================================================
@ -107,8 +88,8 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) @@ -107,8 +88,8 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
pPlayer->pev->angles = VARS( pentSpawnSpot )->angles;
pPlayer->pev->punchangle = g_vecZero;
if( !(pPlayer->pev->flags & FL_SPECTATOR ) )
if( mp_coop_changelevel.value && !CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles ))
if( !CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles ) )
if( mp_coop_changelevel.value && !UTIL_CoopRestorePlayerCoords( pPlayer, &pPlayer->pev->origin, &pPlayer->pev->angles ))
if( !UTIL_CoopGetSpawnPoint( &pPlayer->pev->origin, &pPlayer->pev->angles ) )
{
if( !g_pLastSpawn )
{
@ -133,7 +114,7 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) @@ -133,7 +114,7 @@ edict_t *CGameRules::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
}
}
pPlayer->pev->fixangle = TRUE;
pPlayer->pev->origin = FixupSpawnPoint( pPlayer->pev->origin );
pPlayer->pev->origin = UTIL_FixupSpawnPoint( pPlayer->pev->origin );
if( g_fSavedDuck )
pPlayer->pev->flags |= FL_DUCKING;

49
dlls/multiplay_gamerules.cpp

@ -96,38 +96,11 @@ void CoopClearWeaponList( void ) @@ -96,38 +96,11 @@ void CoopClearWeaponList( void )
}
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;
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)
{
@ -161,9 +134,9 @@ void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char ** @@ -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");
}
void CoopMenu( CBasePlayer *pPlayer );
void UTIL_CoopMenu( CBasePlayer *pPlayer );
void CoopVoteMenu( CBasePlayer *pPlayer );
void UTIL_CoopVoteMenu( CBasePlayer *pPlayer );
//*********************************************************
@ -217,7 +190,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() @@ -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 )
{
@ -230,7 +203,7 @@ 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( pPlayer->m_state == STATE_SPECTATOR_BEGIN )
SpawnPlayer( pPlayer );
UTIL_SpawnPlayer( pPlayer );
else
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "You cannot use joincoop now!\n\n" );
@ -240,13 +213,13 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) @@ -240,13 +213,13 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
{
int imenu = atoi( CMD_ARGV( 1 ) );
CoopProcessMenu( pPlayer, imenu );
UTIL_CoopProcessMenu( pPlayer, imenu );
return TRUE;
}
if( FStrEq( pcmd, "coopmenu" ) )
{
CoopMenu( pPlayer );
UTIL_CoopMenu( pPlayer );
return TRUE;
}
@ -625,7 +598,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl ) @@ -625,7 +598,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl )
"Join coop",
"Join spectators"
};
ShowMenu( pl, "COOP SERVER", ARRAYSIZE( menu ), menu );
UTIL_CoopShowMenu( pl, "COOP SERVER", ARRAYSIZE( menu ), menu );
}
}
}
@ -703,7 +676,7 @@ void CHalfLifeMultiplay::PlayerThink( CBasePlayer *pPlayer ) @@ -703,7 +676,7 @@ void CHalfLifeMultiplay::PlayerThink( CBasePlayer *pPlayer )
{
if( !mp_coop.value && pPlayer->m_state == STATE_SPECTATOR_BEGIN )
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_afButtonPressed || pPlayer->pev->button )
{
@ -750,14 +723,14 @@ void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer ) @@ -750,14 +723,14 @@ void CHalfLifeMultiplay::PlayerSpawn( CBasePlayer *pPlayer )
{
pPlayer->m_state = STATE_SPECTATOR_BEGIN;
pPlayer->RemoveAllItems( TRUE );
BecomeSpectator( pPlayer );
UTIL_BecomeSpectator( pPlayer );
return;
}
if( mp_coop.value && pPlayer->m_state == STATE_POINT_SELECT && !(pPlayer->pev->flags & FL_SPECTATOR) )
{
pPlayer->RemoveAllItems( TRUE );
BecomeSpectator( pPlayer );
UTIL_BecomeSpectator( pPlayer );
return;
}

621
dlls/triggers.cpp

@ -1487,261 +1487,19 @@ void CChangeLevel::UseChangeLevel( CBaseEntity *pActivator, CBaseEntity *pCaller @@ -1487,261 +1487,19 @@ void CChangeLevel::UseChangeLevel( CBaseEntity *pActivator, CBaseEntity *pCaller
ChangeLevelNow( pActivator );
}
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;
} g_SavedCoords, s_SavedCoords;
struct checkpoint_s
{
char str[32];
float time;
Vector origin;
Vector angles;
} g_checkpoints[4];
void CoopClearData( void )
void UTIL_CoopActivateChangeLevel( CBaseEntity *pTrigger )
{
// nullify
SavedCoords l_SavedCoords = {0};
g_SavedCoords = l_SavedCoords;
memset( &g_checkpoints, 0, sizeof( g_checkpoints ) );
}
CChangeLevel *trigger = (CChangeLevel*) pTrigger;
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 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" )
char *badlist[256] = {
"player", // does not even can set own name
"talat",
"hmse",
"mhmd",
"aeman",
"famas",
"danek",
"ame syia",
"melih",
"aliance",
"vladick"
};
void CoopKickPlayer(CBaseEntity *pPlayer)
{
int i;
if( !pPlayer )
return;
char *name = (char*) CoopPlayerName( pPlayer );
SERVER_COMMAND( UTIL_VarArgs( "kick %d\n", ENTINDEX(pPlayer->pev->pContainingEntity) - 1 ) );
if( strlen( name ) < 5 )
if( !trigger )
return;
for( i = 0; badlist[i]; i++ );
badlist[i] = strdup( name );
}
bool IsBadPlayer( CBaseEntity *plr )
{
if( !plr )
return false;
for( int i = 0; badlist[i];i++ )
if( strcasestr( (char*)CoopPlayerName( plr ), badlist[i] ) )
return true;
return false;
}
void CoopLocalConfirmMenu(CBasePlayer *pPlayer)
{
const char *menu[] = {
"No",
"Cancel",
"Do not confirm",
"Don't confirm",
"Единая Россия"
};
menu[pPlayer->m_iConfirmKey = RANDOM_LONG(2,4)] = "Confirm";
ShowMenu(pPlayer, "Confirm changing map BACK (NOT RECOMMENDED)?", ARRAYSIZE(menu), menu);
pPlayer->m_iMenuState = MENUSTATE_LOCAL_CONFIRM;
trigger->m_bUsed = true;
trigger->ChangeLevelNow( NULL );
}
// Show to all spawned players: voting, etc..
class GlobalMenu
void GlobalMenu::VoteMenu( CBasePlayer *pPlayer )
{
public:
int m_iConfirm;
int m_iVoteCount;
int m_iMaxCount;
int m_iBanCount;
float m_flTime;
const char *maps[5];
int votes[5];
CChangeLevel *triggers[5];
EHANDLE m_pTrigger;
EHANDLE m_pPlayer;
void 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 )
{
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() && !IsBadPlayer( plr ) )
{
count2++;
CBasePlayer *player = (CBasePlayer *) plr;
ShowMenu( player, title, count, menu, 30 );
player->m_iMenuState = MENUSTATE_GLOBAL;
}
}
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
if( pPlayer->m_iMenuState == MENUSTATE_LOCAL_CONFIRM )
return;
if( pPlayer->m_iLocalConfirm < 3 )
{
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 VoteMenu( CBasePlayer *pPlayer )
{
if( g_iMenu && gpGlobals->time - m_flTime < 30 )
return; // wait 30s befor new confirm vote
CBaseEntity *pTrigger = NULL;
@ -1768,13 +1526,23 @@ public: @@ -1768,13 +1526,23 @@ public:
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", CoopPlayerName( pPlayer ) ), i, maps);
ShowGlobalMenu(UTIL_VarArgs("%s requested to force change map", UTIL_CoopPlayerName( pPlayer ) ), i, maps);
}
void UTIL_CoopValidateOffset( 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;
}
}
};
GlobalMenu g_GlobalMenu;
void CChangeLevel::UpdateColor( void )
{
@ -1786,7 +1554,7 @@ void CChangeLevel::UpdateColor( void ) @@ -1786,7 +1554,7 @@ void CChangeLevel::UpdateColor( void )
if( !m_fIsBack && (pPlayer = UTIL_FindEntityByClassname( NULL, "info_player_start" )) )
if( (origin - pPlayer->pev->origin).Length() < 500 )
m_fIsBack = true;
if( !m_fIsBack && CoopGetSpawnPoint( &point, &angles ) )
if( !m_fIsBack && UTIL_CoopGetSpawnPoint( &point, &angles ) )
if( (origin - point).Length() < 500 )
m_fIsBack = true;
pev->rendercolor = g_vecZero;
@ -1802,342 +1570,7 @@ void CChangeLevel::UpdateColor( void ) @@ -1802,342 +1570,7 @@ void CChangeLevel::UpdateColor( void )
}
void 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;
ShowMenu( pPlayer, "Select checkpoint", i, menu );
pPlayer->m_iMenuState = MENUSTATE_CHECKPOINT;
}
}
}
void 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 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( 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++;
ShowMenu( 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"
};
ShowMenu( pPlayer, "Spectator menu", ARRAYSIZE( menu ), menu );
}
}
}
void SpawnPlayer( CBasePlayer *pPlayer );
void BecomeSpectator( CBasePlayer *pPlayer );
void CoopProcessMenu( CBasePlayer *pPlayer, int imenu )
{
switch( pPlayer->m_iMenuState )
{
case MENUSTATE_COOPMENU_SPEC:
if( imenu == 1 )
{
if( g_checkpoints[0].time )
CoopCheckpointMenu( pPlayer );
else
{
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 );
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 );
}
if( imenu == 5 )
{
CoopCheckpointMenu( pPlayer );
}
break;
case MENUSTATE_GLOBAL:
if( !IsBadPlayer( pPlayer ) )
g_GlobalMenu.Process( pPlayer, imenu );
break;
case MENUSTATE_CHECKPOINT:
if( imenu == 1 )
{
if( pPlayer->m_state == STATE_SPECTATOR_BEGIN )
SpawnPlayer( pPlayer );
else if( !IsBadPlayer( pPlayer ) )
CoopNewCheckpoint( pPlayer->pev );
}
else if( imenu > 1 && imenu < 5 )
{
pPlayer->RemoveAllItems( TRUE );
SpawnPlayer( pPlayer );
pPlayer->pev->origin = g_checkpoints[imenu-2].origin;
}
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;
}
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
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 )
{
@ -2199,7 +1632,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2199,7 +1632,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
m_vecSpawnOrigin = pActivator->pev->origin;
m_vecSpawnAngles = pActivator->pev->angles;
m_fSpawnSaved = true;
CoopSaveTrain( pActivator, &l_SavedCoords );
UTIL_CoopSaveTrain( pActivator, &l_SavedCoords );
}
unsigned int count1 = 0;
unsigned int count2 = 0;
@ -2209,9 +1642,9 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2209,9 +1642,9 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
for( i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *plr = UTIL_PlayerByIndex( i );
CBaseEntity *pTrain = CoopGetPlayerTrain( plr );
CBaseEntity *pTrain = UTIL_CoopGetPlayerTrain( plr );
if( !pTrain && IsBadPlayer( plr ) )
if( !pTrain && UTIL_CoopIsBadPlayer( plr ) )
continue;
// count only players spawned more 30 seconds ago
@ -2226,7 +1659,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2226,7 +1659,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
if( InTransitionVolume( plr, m_szLandmarkName ))
{
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" );
strcpy(l_SavedCoords.ip[l_SavedCoords.iCount], ip );
l_SavedCoords.origin[l_SavedCoords.iCount] = plr->pev->origin;
@ -2293,7 +1726,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2293,7 +1726,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
}
if( g_iMenu != 1 )
{
if( !IsBadPlayer( pActivator ) )
if( !UTIL_CoopIsBadPlayer( pActivator ) )
g_GlobalMenu.ConfirmMenu( (CBasePlayer*)pActivator, this, m_szMapName );
return;
}
@ -2331,7 +1764,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2331,7 +1764,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
}
}
CoopSaveTrain( pActivator, &l_SavedCoords );
UTIL_CoopSaveTrain( pActivator, &l_SavedCoords );
s_SavedCoords = l_SavedCoords;
@ -2451,7 +1884,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) @@ -2451,7 +1884,7 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator )
{
plr->m_state = STATE_UNINITIALIZED;
plr->RemoveAllItems( TRUE );
BecomeSpectator( plr );
UTIL_BecomeSpectator( plr );
//plr->SetThink( &CBasePlayer::Spawn );
//plr->pev->nextthink = gpGlobals->time + 1;
// HACK: force perform reconnection

15
dlls/util.cpp

@ -1578,21 +1578,6 @@ void UTIL_StripToken( const char *pKey, char *pDest ) @@ -1578,21 +1578,6 @@ void UTIL_StripToken( const char *pKey, char *pDest )
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);
}
}
}
// --------------------------------------------------------------
//

1
dlls/util.h

@ -568,4 +568,3 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); @@ -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_WeaponTimeBase( void );
void UTIL_CleanSpawnPoint( Vector origin, float radius );

Loading…
Cancel
Save