2023-09-06 00:25:25 +00:00
|
|
|
|
/***
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2002 The Wastes Project, All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* This product contains software technology from Valve Software, LLC,
|
|
|
|
|
* Copyright <EFBFBD> 1996-2001, Valve LLC, All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
|
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
|
|
|
* The Wastes Project. All other use, distribution, or modification is prohibited
|
|
|
|
|
* without written permission from The Wastes Project.
|
|
|
|
|
*
|
|
|
|
|
***/
|
|
|
|
|
//
|
|
|
|
|
// lastmanstanding_gamerules.cpp
|
|
|
|
|
//
|
|
|
|
|
#include "extdll.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "cbase.h"
|
|
|
|
|
#include "shake.h"
|
|
|
|
|
#include "player.h"
|
|
|
|
|
#include "weapons.h"
|
|
|
|
|
#include "gamerules.h"
|
|
|
|
|
|
|
|
|
|
#include "game.h"
|
|
|
|
|
#include "items.h"
|
|
|
|
|
#include "voice_gamemgr.h"
|
|
|
|
|
#include "thewastes.h"
|
|
|
|
|
|
|
|
|
|
extern int gmsgScoreInfo;
|
|
|
|
|
extern int gmsgLmsStart;
|
|
|
|
|
extern void respawn(entvars_t *pev, BOOL fCopyCorpse);
|
|
|
|
|
|
|
|
|
|
extern DLL_GLOBAL BOOL g_fGameOver;
|
|
|
|
|
|
|
|
|
|
#define RESTART_TIME_LONG 10.0f
|
|
|
|
|
#define RESTART_TIME_SHORT 5.0f
|
|
|
|
|
#define DELAY_TIME 5.0f
|
|
|
|
|
|
|
|
|
|
enum lms_state_e {
|
|
|
|
|
RS_CHECKING,
|
|
|
|
|
RS_BEGIN_MATCH,
|
|
|
|
|
RS_MATCH_IN_PROGRESS,
|
|
|
|
|
RS_END_MATCH,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CWastesLMS::CWastesLMS() : CHalfLifeMultiplay()
|
|
|
|
|
{
|
|
|
|
|
m_bRoundInProgress = FALSE;
|
|
|
|
|
m_iRoundState = RS_CHECKING;
|
|
|
|
|
m_flNextStateCheck = gpGlobals->time + 30.0f;
|
|
|
|
|
m_flRoundDelay = 0.0f;
|
|
|
|
|
|
|
|
|
|
// Validate cvars
|
|
|
|
|
if( CVAR_GET_FLOAT( "mp_lives" ) < 1.0f )
|
|
|
|
|
CVAR_SET_FLOAT( "mp_lives", 1.0f );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CWastesLMS::Think()
|
|
|
|
|
{
|
|
|
|
|
CHalfLifeMultiplay::Think();
|
|
|
|
|
|
|
|
|
|
if( g_fGameOver )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch( m_iRoundState )
|
|
|
|
|
{
|
|
|
|
|
case RS_CHECKING:
|
|
|
|
|
break;
|
|
|
|
|
case RS_BEGIN_MATCH:
|
|
|
|
|
break;
|
|
|
|
|
case RS_MATCH_IN_PROGRESS:
|
|
|
|
|
break;
|
|
|
|
|
case RS_END_MATCH:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* // Round Delay Timer
|
|
|
|
|
if(m_flRoundDelay && gpGlobals->time >= m_flRoundDelay)
|
|
|
|
|
m_flRoundDelay = 0.0f;
|
|
|
|
|
|
|
|
|
|
// Round is over; do not run code if game is doing a restart round check
|
|
|
|
|
// Do not run if no round is in progress.
|
|
|
|
|
#if 0
|
|
|
|
|
if(m_bRoundInProgress && m_flRoundTimeLimit && !m_flNextStateCheck && gpGlobals->time >= m_flRoundTimeLimit)
|
|
|
|
|
{
|
|
|
|
|
UTIL_SayText("ROUND IS OVER O NO",UTIL_FindEntityByClassname(NULL,"player"));
|
|
|
|
|
m_flRoundTimeLimit = 0.0;
|
|
|
|
|
|
|
|
|
|
StartRound();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Game Timer, check it
|
|
|
|
|
if(m_flNextStateCheck && gpGlobals->time >= m_flNextStateCheck)
|
|
|
|
|
{
|
|
|
|
|
m_flNextStateCheck = gpGlobals->time + RESTART_TIME_SHORT;
|
|
|
|
|
|
|
|
|
|
// Round in progress
|
|
|
|
|
if(m_bRoundInProgress)
|
|
|
|
|
{
|
|
|
|
|
int iPlayersLeft = GetActivePlayers();
|
|
|
|
|
|
|
|
|
|
// Should round be over?
|
|
|
|
|
if(iPlayersLeft < 2)
|
|
|
|
|
{
|
|
|
|
|
// Go through active players list, find the one left alive.
|
|
|
|
|
if(iPlayersLeft)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 1;i <= gpGlobals->maxClients;i++)
|
|
|
|
|
{
|
|
|
|
|
CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex(i);
|
|
|
|
|
|
|
|
|
|
if(pPlayer != NULL && pPlayer->IsAlive())
|
|
|
|
|
{
|
|
|
|
|
pPlayer->pev->frags += pPlayer->m_iTempFrags;
|
|
|
|
|
pPlayer->m_iTempFrags = 0;
|
|
|
|
|
|
|
|
|
|
MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo );
|
|
|
|
|
WRITE_BYTE( ENTINDEX(pPlayer->edict()) );
|
|
|
|
|
WRITE_SHORT( pPlayer->pev->frags );
|
|
|
|
|
WRITE_SHORT( pPlayer->m_iDeaths );
|
|
|
|
|
WRITE_SHORT( 0 );
|
|
|
|
|
WRITE_SHORT( GetTeamIndex( pPlayer->m_szTeamName ) + 1 );
|
|
|
|
|
MESSAGE_END();
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UTIL_SayTextAll("ROUND OVER, HERE IS YOUR MONEY KTHX",UTIL_FindEntityByClassname(NULL,"player"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
UTIL_SayTextAll("NO ONE ALIVE WTS",UTIL_FindEntityByClassname(NULL,"observer"));
|
|
|
|
|
|
|
|
|
|
StartRound();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( GetActivePlayers() > 1 )
|
|
|
|
|
StartRound();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHalfLifeMultiplay::Think();*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL CWastesLMS::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker )
|
|
|
|
|
{
|
|
|
|
|
if(gpGlobals->time >= m_flRoundDelay && m_bRoundInProgress)
|
|
|
|
|
return CHalfLifeMultiplay::FPlayerCanTakeDamage(pPlayer,pAttacker);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CWastesLMS::PlayerSpawn(CBasePlayer *pPlayer)
|
|
|
|
|
{
|
|
|
|
|
if(!ShouldSpectate())
|
|
|
|
|
{
|
|
|
|
|
CHalfLifeMultiplay::PlayerSpawn(pPlayer);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pPlayer->pev->health = 0;
|
|
|
|
|
pPlayer->StartObserver(pPlayer->pev->origin,Vector(0,0,0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CWastesLMS::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor)
|
|
|
|
|
{
|
|
|
|
|
if(m_bRoundInProgress)
|
|
|
|
|
{
|
|
|
|
|
CHalfLifeMultiplay::PlayerKilled(pVictim,pKiller,pInflictor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL CWastesLMS::ShouldSpectate()
|
|
|
|
|
{
|
|
|
|
|
if(m_bRoundInProgress)
|
|
|
|
|
return TRUE;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CWastesLMS::EndMultiplayerGame()
|
|
|
|
|
{
|
|
|
|
|
// Quit
|
|
|
|
|
m_bRoundInProgress = FALSE;
|
|
|
|
|
m_iRoundState = RS_CHECKING;
|
|
|
|
|
m_flNextStateCheck = 0.0;
|
|
|
|
|
|
|
|
|
|
CHalfLifeMultiplay::EndMultiplayerGame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CWastesLMS::GetActivePlayers()
|
|
|
|
|
{
|
|
|
|
|
int iRet = 0;
|
|
|
|
|
for(int i = 1;i <= gpGlobals->maxClients;i++)
|
|
|
|
|
{
|
|
|
|
|
CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex(i);
|
|
|
|
|
|
|
|
|
|
if(pPlayer == NULL )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if(pPlayer->IsAlive())
|
|
|
|
|
iRet++;
|
|
|
|
|
}
|
|
|
|
|
// char szText[1024];
|
|
|
|
|
// sprintf( szText, "Active Players: %i", iRet );
|
|
|
|
|
// UTIL_SayTextAll( szText, UTIL_FindEntityByClassname( NULL, "player" ) );
|
|
|
|
|
return iRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CWastesLMS::StartRound()
|
|
|
|
|
{
|
|
|
|
|
int lives = (int)CVAR_GET_FLOAT( "mp_lives" );
|
|
|
|
|
|
|
|
|
|
ClearLevel();
|
|
|
|
|
|
|
|
|
|
for( int i = 1;i <= gpGlobals->maxClients;i++ )
|
|
|
|
|
{
|
|
|
|
|
CBaseEntity *pEnt = UTIL_PlayerByIndex( i );
|
|
|
|
|
|
|
|
|
|
if( pEnt == NULL )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if( pEnt->IsPlayer() )
|
|
|
|
|
{
|
|
|
|
|
CBasePlayer *pPlayer = (CBasePlayer*)pEnt;
|
|
|
|
|
|
|
|
|
|
pPlayer->m_iLivesLeft = lives;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if 0
|
|
|
|
|
m_bRoundInProgress = FALSE;
|
|
|
|
|
ClearLevel();
|
|
|
|
|
|
|
|
|
|
// Go through each player, let them respawn,
|
|
|
|
|
// And start the round! :D
|
|
|
|
|
for(int i = 1;i <= gpGlobals->maxClients;i++)
|
|
|
|
|
{
|
|
|
|
|
CBasePlayer *pEnt = (CBasePlayer*)UTIL_PlayerByIndex(i);
|
|
|
|
|
if(pEnt == NULL || !pEnt->IsPlayer() || !pEnt->pev->netname)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pEnt->RemoveAllItems();
|
|
|
|
|
respawn(pEnt->pev,FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_flRoundDelay = gpGlobals->time + DELAY_TIME; // 3 seconds after round starts we can start inflicting pain on our enemies
|
|
|
|
|
m_bRoundInProgress = TRUE;
|
|
|
|
|
|
|
|
|
|
MESSAGE_BEGIN( MSG_ALL, gmsgLmsStart );
|
|
|
|
|
WRITE_COORD( DELAY_TIME );
|
|
|
|
|
MESSAGE_END();
|
|
|
|
|
#endif
|
2023-09-04 20:28:44 +00:00
|
|
|
|
}
|