2015-07-12 23:32:09 +03:00
# include "precompiled.h"
/*
* Globals initialization
*/
# ifndef HOOK_GAMEDLL
2016-04-21 04:00:02 +03:00
static char mp_com_token [ 1500 ] ;
2015-08-20 13:35:01 +03:00
cvar_t * sv_clienttrace = NULL ;
2015-07-12 23:32:09 +03:00
2016-02-23 02:13:52 +03:00
# endif
2015-07-12 23:32:09 +03:00
CCStrikeGameMgrHelper g_GameMgrHelper ;
2016-06-08 00:41:07 +03:00
CHalfLifeMultiplay * g_pMPGameRules = nullptr ;
RewardAccount CHalfLifeMultiplay : : m_rgRewardAccountRules [ ] = {
REWARD_CTS_WIN , // RR_CTS_WIN
REWARD_TERRORISTS_WIN , // RR_TERRORISTS_WIN
REWARD_TARGET_BOMB , // RR_TARGET_BOMB
REWARD_VIP_ESCAPED , // RR_VIP_ESCAPED
REWARD_VIP_ASSASSINATED , // RR_VIP_ASSASSINATED
REWARD_TERRORISTS_ESCAPED , // RR_TERRORISTS_ESCAPED
REWARD_CTS_PREVENT_ESCAPE , // RR_CTS_PREVENT_ESCAPE
REWARD_ESCAPING_TERRORISTS_NEUTRALIZED , // RR_ESCAPING_TERRORISTS_NEUTRALIZED
REWARD_BOMB_DEFUSED , // RR_BOMB_DEFUSED
REWARD_BOMB_PLANTED , // RR_BOMB_PLANTED
REWARD_BOMB_EXPLODED , // RR_BOMB_EXPLODED
REWARD_ALL_HOSTAGES_RESCUED , // RR_ALL_HOSTAGES_RESCUED
REWARD_TARGET_BOMB_SAVED , // RR_TARGET_BOMB_SAVED
REWARD_HOSTAGE_NOT_RESCUED , // RR_HOSTAGE_NOT_RESCUED
REWARD_VIP_NOT_ESCAPED , // RR_VIP_NOT_ESCAPED
REWARD_LOSER_BONUS_DEFAULT , // RR_LOSER_BONUS_DEFAULT
REWARD_LOSER_BONUS_MIN , // RR_LOSER_BONUS_MIN
REWARD_LOSER_BONUS_MAX , // RR_LOSER_BONUS_MAX
REWARD_LOSER_BONUS_ADD , // RR_LOSER_BONUS_ADD
REWARD_RESCUED_HOSTAGE , // RR_RESCUED_HOSTAGE
2016-06-14 01:13:13 +03:00
REWARD_TOOK_HOSTAGE_ACC , // RR_TOOK_HOSTAGE_ACC
2016-06-08 00:41:07 +03:00
REWARD_TOOK_HOSTAGE , // RR_TOOK_HOSTAGE
} ;
2015-07-12 23:32:09 +03:00
2016-01-28 07:48:09 +03:00
bool IsBotSpeaking ( )
2015-07-12 23:32:09 +03:00
{
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( pPlayer = = NULL | | ! pPlayer - > IsBot ( ) )
continue ;
2016-01-25 20:02:57 +03:00
CCSBot * pBot = static_cast < CCSBot * > ( pPlayer ) ;
2015-08-20 13:35:01 +03:00
if ( pBot - > IsUsingVoice ( ) )
return true ;
}
return false ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_Continue_f ( )
2015-07-12 23:32:09 +03:00
{
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > IsCareer ( ) & & CSGameRules ( ) - > m_fTeamCount > 100000.0 )
2015-08-20 13:35:01 +03:00
{
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > m_fTeamCount = gpGlobals - > time ;
2015-08-20 13:35:01 +03:00
// go continue
MESSAGE_BEGIN ( MSG_ALL , gmsgCZCareer ) ;
WRITE_STRING ( " GOGOGO " ) ;
MESSAGE_END ( ) ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( pPlayer & & ! pPlayer - > IsBot ( ) )
{
// at the end of the round is showed window with the proposal surrender or continue
// now of this time HUD is completely hidden
// we must to restore HUD after entered continued
pPlayer - > m_iHideHUD & = ~ HIDEHUD_ALL ;
}
}
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_Tutor_Toggle_f ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
CVAR_SET_FLOAT ( " tutor_enable " , ( CVAR_GET_FLOAT ( " tutor_enable " ) < = 0.0 ) ) ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_Career_Restart_f ( )
2015-07-12 23:32:09 +03:00
{
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > IsCareer ( ) )
2015-08-20 13:35:01 +03:00
{
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > CareerRestart ( ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_Career_EndRound_f ( )
2015-07-12 23:32:09 +03:00
{
2016-02-23 02:13:52 +03:00
if ( ! CSGameRules ( ) - > IsCareer ( ) | | ! CSGameRules ( ) - > IsInCareerRound ( ) )
2015-08-20 13:35:01 +03:00
{
return ;
}
2015-07-12 23:32:09 +03:00
2015-08-20 13:35:01 +03:00
CBasePlayer * localPlayer = UTIL_GetLocalPlayer ( ) ;
if ( localPlayer ! = NULL )
{
SERVER_COMMAND ( " kill \n " ) ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * player = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( ! player | | FNullEnt ( player - > pev ) )
continue ;
if ( player - > IsBot ( ) & & player - > m_iTeam = = localPlayer - > m_iTeam )
{
SERVER_COMMAND ( UTIL_VarArgs ( " bot_kill \" %s \" \n " , STRING ( player - > pev - > netname ) ) ) ;
}
}
}
}
2015-07-12 23:32:09 +03:00
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : IsInCareerRound ( )
2015-08-20 13:35:01 +03:00
{
return IsMatchStarted ( ) ? false : true ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_CareerAddTask_f ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( CMD_ARGC ( ) ! = 7 )
return ;
const char * taskName = CMD_ARGV ( 1 ) ;
const char * weaponName = CMD_ARGV ( 2 ) ;
int reps = Q_atoi ( CMD_ARGV ( 3 ) ) ;
bool mustLive = Q_atoi ( CMD_ARGV ( 4 ) ) ! = 0 ;
bool crossRounds = Q_atoi ( CMD_ARGV ( 5 ) ) ! = 0 ;
bool isComplete = Q_atoi ( CMD_ARGV ( 6 ) ) ! = 0 ;
2015-12-05 22:40:30 +03:00
if ( TheCareerTasks ! = NULL )
{
TheCareerTasks - > AddTask ( taskName , weaponName , reps , mustLive , crossRounds , isComplete ) ;
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void SV_CareerMatchLimit_f ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( CMD_ARGC ( ) ! = 3 )
{
return ;
}
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > IsCareer ( ) )
2015-08-20 13:35:01 +03:00
{
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > SetCareerMatchLimit ( Q_atoi ( CMD_ARGV ( 1 ) ) , Q_atoi ( CMD_ARGV ( 2 ) ) ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : SetCareerMatchLimit ( int minWins , int winDifference )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( ! IsCareer ( ) )
{
return ;
}
if ( ! m_iCareerMatchWins )
{
m_iCareerMatchWins = minWins ;
m_iRoundWinDifference = winDifference ;
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : IsCareer ( )
2015-07-12 23:32:09 +03:00
{
return IS_CAREER_MATCH ( ) ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , ServerDeactivate ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( ServerDeactivate ) ( )
2015-08-20 13:35:01 +03:00
{
if ( ! IsCareer ( ) )
{
return ;
}
CVAR_SET_FLOAT ( " pausable " , 0 ) ;
CVAR_SET_FLOAT ( " mp_windifference " , 1 ) ;
UTIL_LogPrintf ( " Career End \n " ) ;
}
void CMapInfo : : __MAKE_VHOOK ( KeyValue ) ( KeyValueData * pkvd )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( FStrEq ( pkvd - > szKeyName , " buying " ) )
{
m_iBuyingStatus = Q_atoi ( pkvd - > szValue ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " bombradius " ) )
{
m_flBombRadius = Q_atoi ( pkvd - > szValue ) ;
if ( m_flBombRadius > MAX_BOMB_RADIUS )
m_flBombRadius = MAX_BOMB_RADIUS ;
pkvd - > fHandled = TRUE ;
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CMapInfo : : __MAKE_VHOOK ( Spawn ) ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
pev - > movetype = MOVETYPE_NONE ;
pev - > solid = SOLID_NOT ;
pev - > effects | = EF_NODRAW ;
2015-07-12 23:32:09 +03:00
}
2016-03-17 20:44:52 +03:00
LINK_ENTITY_TO_CLASS ( info_map_parameters , CMapInfo , CCSMapInfo ) ;
2015-07-12 23:32:09 +03:00
2015-08-20 13:35:01 +03:00
bool CCStrikeGameMgrHelper : : __MAKE_VHOOK ( CanPlayerHearPlayer ) ( CBasePlayer * pListener , CBasePlayer * pSender )
{
if ( ! pSender - > IsPlayer ( ) | | pListener - > m_iTeam ! = pSender - > m_iTeam )
{
return false ;
}
BOOL bListenerAlive = pListener - > IsAlive ( ) ;
BOOL bSenderAlive = pSender - > IsAlive ( ) ;
if ( pListener - > IsObserver ( ) )
{
return true ;
}
if ( bListenerAlive )
{
if ( ! bSenderAlive )
return false ;
}
else
{
if ( bSenderAlive )
return true ;
}
return ( bListenerAlive = = bSenderAlive ) ;
}
2015-08-02 20:45:57 +03:00
void Broadcast ( const char * sentence )
2015-07-12 23:32:09 +03:00
{
2015-08-02 20:45:57 +03:00
char text [ 32 ] ;
if ( ! sentence )
2015-08-20 13:35:01 +03:00
{
2015-08-02 20:45:57 +03:00
return ;
2015-08-20 13:35:01 +03:00
}
2015-08-02 20:45:57 +03:00
Q_strcpy ( text , " %!MRAD_ " ) ;
Q_strcat ( text , UTIL_VarArgs ( " %s " , sentence ) ) ;
MESSAGE_BEGIN ( MSG_BROADCAST , gmsgSendAudio ) ;
2015-08-20 13:35:01 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_STRING ( text ) ;
WRITE_SHORT ( 100 ) ;
2015-08-02 20:45:57 +03:00
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
char * GetTeam ( int teamNo )
{
2015-06-30 12:46:07 +03:00
switch ( teamNo )
{
2015-07-05 14:05:26 +03:00
case TERRORIST :
return " TERRORIST " ;
case CT :
return " CT " ;
case SPECTATOR :
return " SPECTATOR " ;
default :
break ;
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
2015-07-12 23:32:09 +03:00
return " " ;
}
2016-06-08 00:41:07 +03:00
void CHalfLifeMultiplay : : EndRoundMessage ( const char * sentence , int event )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
char * team = NULL ;
2015-09-30 03:49:22 +03:00
const char * message = & ( sentence [ 1 ] ) ;
2016-02-23 02:13:52 +03:00
bool bTeamTriggered = true ;
2015-08-20 13:35:01 +03:00
UTIL_ClientPrintAll ( HUD_PRINTCENTER , sentence ) ;
switch ( event )
{
case ROUND_TARGET_BOMB :
case ROUND_VIP_ASSASSINATED :
case ROUND_TERRORISTS_ESCAPED :
case ROUND_TERRORISTS_WIN :
case ROUND_HOSTAGE_NOT_RESCUED :
case ROUND_VIP_NOT_ESCAPED :
team = GetTeam ( TERRORIST ) ;
2015-09-30 03:49:22 +03:00
// tell bots the terrorists won the round
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_TERRORISTS_WIN ) ;
}
2015-08-20 13:35:01 +03:00
break ;
case ROUND_VIP_ESCAPED :
case ROUND_CTS_PREVENT_ESCAPE :
case ROUND_ESCAPING_TERRORISTS_NEUTRALIZED :
case ROUND_BOMB_DEFUSED :
case ROUND_CTS_WIN :
case ROUND_ALL_HOSTAGES_RESCUED :
case ROUND_TARGET_SAVED :
case ROUND_TERRORISTS_NOT_ESCAPED :
team = GetTeam ( CT ) ;
2015-09-30 03:49:22 +03:00
// tell bots the CTs won the round
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_CTS_WIN ) ;
}
2015-08-20 13:35:01 +03:00
break ;
default :
2016-02-23 02:13:52 +03:00
bTeamTriggered = false ;
2015-09-30 03:49:22 +03:00
// tell bots the round was a draw
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_ROUND_DRAW ) ;
}
2015-08-20 13:35:01 +03:00
break ;
}
2016-06-08 00:41:07 +03:00
if ( bTeamTriggered )
2015-08-20 13:35:01 +03:00
{
2016-06-08 00:41:07 +03:00
UTIL_LogPrintf ( " Team \" %s \" triggered \" %s \" (CT \" %i \" ) (T \" %i \" ) \n " , team , message , m_iNumCTWins , m_iNumTerroristWins ) ;
}
else
{
UTIL_LogPrintf ( " World triggered \" %s \" (CT \" %i \" ) (T \" %i \" ) \n " , message , m_iNumCTWins , m_iNumTerroristWins ) ;
2015-08-20 13:35:01 +03:00
}
UTIL_LogPrintf ( " World triggered \" Round_End \" \n " ) ;
2015-07-12 23:32:09 +03:00
}
2016-06-02 01:08:22 +03:00
void CHalfLifeMultiplay : : ReadMultiplayCvars ( )
2015-07-12 23:32:09 +03:00
{
2016-06-02 01:08:22 +03:00
m_iRoundTime = int ( CVAR_GET_FLOAT ( " mp_roundtime " ) * 60 ) ;
m_iC4Timer = int ( CVAR_GET_FLOAT ( " mp_c4timer " ) ) ;
m_iIntroRoundTime = int ( CVAR_GET_FLOAT ( " mp_freezetime " ) ) ;
m_iLimitTeams = int ( CVAR_GET_FLOAT ( " mp_limitteams " ) ) ;
2015-08-20 13:35:01 +03:00
2015-12-29 01:54:08 +03:00
# ifndef REGAMEDLL_ADD
2016-06-02 01:08:22 +03:00
if ( m_iRoundTime > 540 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_roundtime " , 9 ) ;
2016-06-02 01:08:22 +03:00
m_iRoundTime = 540 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
else if ( m_iRoundTime < 60 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_roundtime " , 1 ) ;
2016-06-02 01:08:22 +03:00
m_iRoundTime = 60 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iIntroRoundTime > 60 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_freezetime " , 60 ) ;
2016-06-02 01:08:22 +03:00
m_iIntroRoundTime = 60 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
else if ( m_iIntroRoundTime < 0 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_freezetime " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iIntroRoundTime = 0 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iC4Timer > 90 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_c4timer " , 90 ) ;
2016-06-02 01:08:22 +03:00
m_iC4Timer = 90 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
else if ( m_iC4Timer < 10 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_c4timer " , 10 ) ;
2016-06-02 01:08:22 +03:00
m_iC4Timer = 10 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iLimitTeams > 20 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_limitteams " , 20 ) ;
2016-06-02 01:08:22 +03:00
m_iLimitTeams = 20 ;
2015-08-20 13:35:01 +03:00
}
2016-06-02 01:08:22 +03:00
else if ( m_iLimitTeams < 0 )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " mp_limitteams " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iLimitTeams = 0 ;
2015-08-20 13:35:01 +03:00
}
2016-05-23 01:51:21 +03:00
# else
// a limit of 500 minutes because
// if you do more minutes would be a bug in the HUD RoundTime in the form 00:00
2016-06-02 01:08:22 +03:00
if ( m_iRoundTime > 30000 )
2016-05-23 01:51:21 +03:00
{
CVAR_SET_FLOAT ( " mp_roundtime " , 500 ) ;
2016-06-02 01:08:22 +03:00
m_iRoundTime = 30000 ;
2016-05-23 01:51:21 +03:00
}
2016-06-02 01:08:22 +03:00
else if ( m_iRoundTime < 0 )
2016-05-23 01:51:21 +03:00
{
CVAR_SET_FLOAT ( " mp_roundtime " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iRoundTime = 0 ;
2016-05-23 01:51:21 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iIntroRoundTime < 0 )
2016-05-23 01:51:21 +03:00
{
CVAR_SET_FLOAT ( " mp_freezetime " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iIntroRoundTime = 0 ;
2016-05-23 01:51:21 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iC4Timer < 0 )
2016-05-23 01:51:21 +03:00
{
CVAR_SET_FLOAT ( " mp_c4timer " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iC4Timer = 0 ;
2016-05-23 01:51:21 +03:00
}
2016-06-02 01:08:22 +03:00
if ( m_iLimitTeams < 0 )
2016-05-23 01:51:21 +03:00
{
CVAR_SET_FLOAT ( " mp_limitteams " , 0 ) ;
2016-06-02 01:08:22 +03:00
m_iLimitTeams = 0 ;
2016-05-23 01:51:21 +03:00
}
# endif
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
CHalfLifeMultiplay : : CHalfLifeMultiplay ( )
2015-07-02 00:22:46 +03:00
{
m_VoiceGameMgr . Init ( & g_GameMgrHelper , gpGlobals - > maxClients ) ;
RefreshSkillData ( ) ;
m_flIntermissionEndTime = 0 ;
m_flIntermissionStartTime = 0 ;
m_fTeamCount = 0 ;
2015-08-20 13:35:01 +03:00
2015-07-02 00:22:46 +03:00
m_iAccountCT = 0 ;
m_iAccountTerrorist = 0 ;
m_iHostagesRescued = 0 ;
2016-01-19 14:54:31 +03:00
m_iRoundWinStatus = WINNER_NONE ;
2015-07-02 00:22:46 +03:00
m_iNumCTWins = 0 ;
m_iNumTerroristWins = 0 ;
m_pVIP = NULL ;
m_iNumCT = 0 ;
m_iNumTerrorist = 0 ;
m_iNumSpawnableCT = 0 ;
m_iNumSpawnableTerrorist = 0 ;
2015-08-20 13:35:01 +03:00
m_bMapHasCameras = MAP_HAS_CAMERAS_INIT ;
2015-07-02 00:22:46 +03:00
g_fGameOver = FALSE ;
2016-06-08 00:41:07 +03:00
m_iLoserBonus = m_rgRewardAccountRules [ RR_LOSER_BONUS_DEFAULT ] ;
2015-07-12 23:32:09 +03:00
m_iNumConsecutiveCTLoses = 0 ;
m_iNumConsecutiveTerroristLoses = 0 ;
m_iC4Guy = 0 ;
m_bBombDefused = false ;
m_bTargetBombed = false ;
m_bFreezePeriod = TRUE ;
m_bLevelInitialized = false ;
m_tmNextPeriodicThink = 0 ;
m_bFirstConnected = 0 ;
m_bCompleteReset = false ;
m_flRequiredEscapeRatio = 0.5 ;
m_iNumEscapers = 0 ;
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
m_flBombRadius = 500.0 ;
m_iTotalGunCount = 0 ;
m_iTotalGrenadeCount = 0 ;
m_iTotalArmourCount = 0 ;
m_iConsecutiveVIP = 0 ;
m_iUnBalancedRounds = 0 ;
m_iNumEscapeRounds = 0 ;
m_bRoundTerminating = false ;
2015-07-02 00:22:46 +03:00
g_iHostageNumber = 0 ;
m_bBombDropped = FALSE ;
2015-08-20 13:35:01 +03:00
2016-02-23 02:13:52 +03:00
m_iMaxRounds = int ( CVAR_GET_FLOAT ( " mp_maxrounds " ) ) ;
2015-07-02 00:22:46 +03:00
if ( m_iMaxRounds < 0 )
{
m_iMaxRounds = 0 ;
CVAR_SET_FLOAT ( " mp_maxrounds " , 0 ) ;
}
m_iTotalRoundsPlayed = 0 ;
2016-02-23 02:13:52 +03:00
m_iMaxRoundsWon = int ( CVAR_GET_FLOAT ( " mp_winlimit " ) ) ;
2015-07-02 00:22:46 +03:00
if ( m_iMaxRoundsWon < 0 )
{
m_iMaxRoundsWon = 0 ;
CVAR_SET_FLOAT ( " mp_winlimit " , 0 ) ;
}
2015-08-20 13:35:01 +03:00
Q_memset ( m_iMapVotes , 0 , sizeof ( m_iMapVotes ) ) ;
2015-07-02 00:22:46 +03:00
m_iLastPick = 1 ;
m_bMapHasEscapeZone = false ;
m_iMapHasVIPSafetyZone = 0 ;
m_bMapHasBombZone = false ;
m_bMapHasRescueZone = false ;
2016-02-23 02:13:52 +03:00
m_iStoredSpectValue = int ( allow_spectators . value ) ;
2015-07-02 00:22:46 +03:00
2016-01-28 02:50:27 +03:00
for ( int j = 0 ; j < MAX_VIP_QUEUES ; + + j )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ j ] = NULL ;
2015-08-20 13:35:01 +03:00
}
2015-07-02 00:22:46 +03:00
CVAR_SET_FLOAT ( " cl_himodels " , 0 ) ;
2016-06-02 01:08:22 +03:00
ReadMultiplayCvars ( ) ;
2015-07-02 00:22:46 +03:00
m_iIntroRoundTime + = 2 ;
m_fMaxIdlePeriod = m_iRoundTime * 2 ;
float flAutoKickIdle = CVAR_GET_FLOAT ( " mp_autokick_timeout " ) ;
2015-08-20 13:35:01 +03:00
2015-07-02 00:22:46 +03:00
if ( flAutoKickIdle > 0.0 )
2015-08-20 13:35:01 +03:00
{
2015-07-02 00:22:46 +03:00
m_fMaxIdlePeriod = flAutoKickIdle ;
2015-08-20 13:35:01 +03:00
}
2015-07-02 00:22:46 +03:00
m_bInCareerGame = false ;
m_iRoundTimeSecs = m_iIntroRoundTime ;
if ( IS_DEDICATED_SERVER ( ) )
{
CVAR_SET_FLOAT ( " pausable " , 0 ) ;
}
2015-08-20 13:35:01 +03:00
else if ( IsCareer ( ) )
{
CVAR_SET_FLOAT ( " pausable " , 1 ) ;
CVAR_SET_FLOAT ( " sv_aim " , 0 ) ;
CVAR_SET_FLOAT ( " sv_maxspeed " , 322 ) ;
CVAR_SET_FLOAT ( " sv_cheats " , 0 ) ;
CVAR_SET_FLOAT ( " mp_windifference " , 2 ) ;
m_bInCareerGame = true ;
UTIL_LogPrintf ( " Career Start \n " ) ;
}
2015-07-02 00:22:46 +03:00
else
{
2015-08-20 13:35:01 +03:00
CVAR_SET_FLOAT ( " pausable " , 0 ) ;
2015-07-02 00:22:46 +03:00
2015-08-20 13:35:01 +03:00
const char * lservercfgfile = CVAR_GET_STRING ( " lservercfgfile " ) ;
2015-07-02 00:22:46 +03:00
2015-08-20 13:35:01 +03:00
if ( lservercfgfile & & * lservercfgfile ! = ' \0 ' )
{
ALERT ( at_console , " Executing listen server config file \n " ) ;
2015-07-02 00:22:46 +03:00
2015-08-20 13:35:01 +03:00
char szCommand [ 256 ] ;
Q_sprintf ( szCommand , " exec %s \n " , lservercfgfile ) ;
SERVER_COMMAND ( szCommand ) ;
2015-07-02 00:22:46 +03:00
}
}
m_fRoundCount = 0 ;
m_fIntroRoundCount = 0 ;
2015-12-22 21:07:49 +03:00
# ifndef CSTRIKE
2015-07-02 00:22:46 +03:00
InstallBotControl ( ) ;
2016-02-23 02:13:52 +03:00
# endif
2015-12-22 21:07:49 +03:00
2015-07-02 00:22:46 +03:00
InstallHostageManager ( ) ;
m_bSkipSpawn = m_bInCareerGame ;
static bool installedCommands = false ;
if ( ! installedCommands )
{
2016-02-23 02:13:52 +03:00
installedCommands = true ;
2016-02-04 03:18:26 +03:00
if ( g_bIsCzeroGame )
2015-07-12 23:32:09 +03:00
{
2015-07-02 00:22:46 +03:00
ADD_SERVER_COMMAND ( " career_continue " , SV_Continue_f ) ;
ADD_SERVER_COMMAND ( " career_matchlimit " , SV_CareerMatchLimit_f ) ;
ADD_SERVER_COMMAND ( " career_add_task " , SV_CareerAddTask_f ) ;
ADD_SERVER_COMMAND ( " career_endround " , SV_Career_EndRound_f ) ;
ADD_SERVER_COMMAND ( " career_restart " , SV_Career_Restart_f ) ;
ADD_SERVER_COMMAND ( " tutor_toggle " , SV_Tutor_Toggle_f ) ;
}
2015-07-12 23:32:09 +03:00
2015-07-02 00:22:46 +03:00
ADD_SERVER_COMMAND ( " perf_test " , loopPerformance ) ;
ADD_SERVER_COMMAND ( " print_ent " , printEntities ) ;
}
m_fCareerRoundMenuTime = 0 ;
m_fCareerMatchMenuTime = 0 ;
m_iCareerMatchWins = 0 ;
2016-02-23 02:13:52 +03:00
m_iRoundWinDifference = int ( CVAR_GET_FLOAT ( " mp_windifference " ) ) ;
2015-07-02 00:22:46 +03:00
CCareerTaskManager : : Create ( ) ;
if ( m_iRoundWinDifference < 1 )
{
m_iRoundWinDifference = 1 ;
CVAR_SET_FLOAT ( " mp_windifference " , 1 ) ;
}
sv_clienttrace = CVAR_GET_POINTER ( " sv_clienttrace " ) ;
2015-08-20 13:35:01 +03:00
InstallTutor ( CVAR_GET_FLOAT ( " tutor_enable " ) ! = 0.0f ) ;
2015-07-02 00:22:46 +03:00
2016-04-24 16:52:16 +03:00
m_bNeededPlayers = false ;
m_flEscapeRatio = 0.0f ;
# ifndef REGAMEDLL_FIXES
2015-07-12 23:32:09 +03:00
g_pMPGameRules = this ;
2016-04-24 16:52:16 +03:00
# endif
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( RefreshSkillData ) ( )
2015-07-12 23:32:09 +03:00
{
CGameRules : : RefreshSkillData ( ) ;
2015-06-30 12:46:07 +03:00
gSkillData . plrDmg9MM = 12 ;
gSkillData . plrDmgMP5 = 12 ;
gSkillData . suitchargerCapacity = 30 ;
gSkillData . plrDmg357 = 40 ;
gSkillData . plrDmgM203Grenade = 100 ;
gSkillData . plrDmgBuckshot = 20 ;
gSkillData . plrDmgCrossbowClient = 20 ;
2015-07-12 23:32:09 +03:00
gSkillData . plrDmgRPG = 120 ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , RemoveGuns ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( RemoveGuns ) ( )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
CBaseEntity * toremove = NULL ;
while ( ( toremove = UTIL_FindEntityByClassname ( toremove , " weaponbox " ) ) ! = NULL )
( ( CWeaponBox * ) toremove ) - > Kill ( ) ;
toremove = NULL ;
while ( ( toremove = UTIL_FindEntityByClassname ( toremove , " weapon_shield " ) ) ! = NULL )
{
toremove - > SetThink ( & CBaseEntity : : SUB_Remove ) ;
toremove - > pev - > nextthink = gpGlobals - > time + 0.1 ;
2015-07-12 23:32:09 +03:00
}
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : UpdateTeamScores ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamScore ) ;
WRITE_STRING ( " CT " ) ;
WRITE_SHORT ( m_iNumCTWins ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamScore ) ;
WRITE_STRING ( " TERRORIST " ) ;
WRITE_SHORT ( m_iNumTerroristWins ) ;
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CleanUpMap ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( CleanUpMap ) ( )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
// Recreate all the map entities from the map data (preserving their indices),
// then remove everything else except the players.
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
CBaseEntity * torestart = NULL ;
CBaseEntity * toremove = NULL ;
torestart = UTIL_FindEntityByClassname ( NULL , " cycler_sprite " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " cycler_sprite " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " light " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " light " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_breakable " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_breakable " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_door " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_door " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_water " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_water " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_door_rotating " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_door_rotating " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_tracktrain " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_tracktrain " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_vehicle " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_vehicle " ) ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " func_train " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " func_train " ) ;
2015-08-20 13:35:01 +03:00
}
2015-08-02 20:45:57 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " armoury_entity " ) ;
while ( torestart ! = NULL )
2015-08-02 20:45:57 +03:00
{
2015-08-20 13:35:01 +03:00
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " armoury_entity " ) ;
2015-08-20 13:35:01 +03:00
}
2015-08-02 20:45:57 +03:00
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " ambient_generic " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " ambient_generic " ) ;
2015-08-02 20:45:57 +03:00
}
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( NULL , " env_sprite " ) ;
while ( torestart ! = NULL )
2015-08-20 13:35:01 +03:00
{
torestart - > Restart ( ) ;
2015-09-30 03:49:22 +03:00
torestart = UTIL_FindEntityByClassname ( torestart , " env_sprite " ) ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Remove grenades and C4
int icount = 0 ;
toremove = UTIL_FindEntityByClassname ( NULL , " grenade " ) ;
while ( toremove ! = NULL & & icount < 20 )
2015-08-20 13:35:01 +03:00
{
UTIL_Remove ( toremove ) ;
2015-09-30 03:49:22 +03:00
toremove = UTIL_FindEntityByClassname ( toremove , " grenade " ) ;
2016-02-04 03:18:26 +03:00
+ + icount ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Remove defuse kit
// Old code only removed 4 kits and stopped.
toremove = UTIL_FindEntityByClassname ( NULL , " item_thighpack " ) ;
while ( toremove ! = NULL )
2015-08-20 13:35:01 +03:00
{
UTIL_Remove ( toremove ) ;
2015-09-30 03:49:22 +03:00
toremove = UTIL_FindEntityByClassname ( toremove , " item_thighpack " ) ;
2015-08-20 13:35:01 +03:00
}
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
RemoveGuns ( ) ;
PLAYBACK_EVENT ( ( FEV_GLOBAL | FEV_RELIABLE ) , 0 , m_usResetDecals ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , GiveC4 ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( GiveC4 ) ( )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
int iTeamCount ;
2015-08-20 13:35:01 +03:00
int iTemp = 0 ;
int humansPresent = 0 ;
2015-08-02 20:45:57 +03:00
2015-09-30 03:49:22 +03:00
iTeamCount = m_iNumTerrorist ;
2016-02-04 03:18:26 +03:00
+ + m_iC4Guy ;
2015-09-30 03:49:22 +03:00
2015-08-20 13:35:01 +03:00
bool giveToHumans = ( cv_bot_defer_to_human . value > 0.0 ) ;
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
if ( giveToHumans )
{
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-02 20:45:57 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * player = UTIL_PlayerByIndex ( i ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( ! player | | FNullEnt ( player - > edict ( ) ) )
continue ;
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
if ( player - > pev - > deadflag ! = DEAD_NO | | player - > m_iTeam ! = TERRORIST )
continue ;
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
if ( ! player - > IsBot ( ) )
2016-02-04 03:18:26 +03:00
+ + humansPresent ;
2015-08-20 13:35:01 +03:00
}
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
if ( humansPresent )
iTeamCount = humansPresent ;
else
giveToHumans = false ;
}
2015-07-12 23:32:09 +03:00
2015-09-30 03:49:22 +03:00
// if we've looped past the last Terrorist.. then give the C4 to the first one.
2015-08-20 13:35:01 +03:00
if ( m_iC4Guy > iTeamCount )
2015-08-02 20:45:57 +03:00
{
2015-08-20 13:35:01 +03:00
m_iC4Guy = 1 ;
2015-08-02 20:45:57 +03:00
}
2015-09-30 03:49:22 +03:00
// Give the C4 to the specified T player..
2015-08-20 13:35:01 +03:00
CBaseEntity * pPlayer = NULL ;
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
2015-07-12 23:32:09 +03:00
2015-08-20 13:35:01 +03:00
if ( ! pPlayer - > IsPlayer ( ) )
continue ;
2015-08-02 20:45:57 +03:00
2015-08-20 13:35:01 +03:00
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( player - > pev - > deadflag ! = DEAD_NO | | player - > m_iTeam ! = TERRORIST | | ( giveToHumans & & player - > IsBot ( ) ) )
continue ;
2016-02-04 03:18:26 +03:00
if ( + + iTemp = = m_iC4Guy )
2015-08-20 13:35:01 +03:00
{
player - > m_bHasC4 = true ;
player - > GiveNamedItem ( " weapon_c4 " ) ;
2015-09-30 03:49:22 +03:00
player - > SetBombIcon ( ) ;
2015-08-20 13:35:01 +03:00
player - > pev - > body = 1 ;
player - > m_flDisplayHistory | = DHF_BOMB_RETRIEVED ;
player - > HintMessage ( " #Hint_you_have_the_bomb " , FALSE , TRUE ) ;
2015-09-30 03:49:22 +03:00
// Log this information
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><TERRORIST> \" triggered \" Spawned_With_The_Bomb \" \n " , STRING ( player - > pev - > netname ) , GETPLAYERUSERID ( player - > edict ( ) ) , GETPLAYERAUTHID ( player - > edict ( ) ) ) ;
2015-11-06 17:58:48 +03:00
m_bBombDropped = FALSE ;
2015-08-20 13:35:01 +03:00
}
}
// if there are no players with a bomb
if ( ! IsThereABomber ( ) )
{
m_iC4Guy = 0 ;
pPlayer = NULL ;
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
if ( ! pPlayer - > IsPlayer ( ) )
continue ;
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( player - > pev - > deadflag ! = DEAD_NO | | player - > m_iTeam ! = TERRORIST )
continue ;
player - > m_bHasC4 = true ;
player - > GiveNamedItem ( " weapon_c4 " ) ;
2016-05-31 17:04:51 +03:00
player - > SetBombIcon ( ) ;
2015-08-20 13:35:01 +03:00
player - > pev - > body = 1 ;
player - > m_flDisplayHistory | = DHF_BOMB_RETRIEVED ;
player - > HintMessage ( " #Hint_you_have_the_bomb " , FALSE , TRUE ) ;
2015-09-30 03:49:22 +03:00
// Log this information
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><TERRORIST> \" triggered \" Spawned_With_The_Bomb \" \n " , STRING ( player - > pev - > netname ) , GETPLAYERUSERID ( player - > edict ( ) ) , GETPLAYERAUTHID ( player - > edict ( ) ) ) ;
2015-11-06 17:58:48 +03:00
m_bBombDropped = FALSE ;
2015-08-20 13:35:01 +03:00
return ;
}
}
}
void CHalfLifeMultiplay : : QueueCareerRoundEndMenu ( float tmDelay , int iWinStatus )
{
2015-12-05 22:40:30 +03:00
if ( TheCareerTasks = = NULL )
return ;
2015-08-20 13:35:01 +03:00
if ( m_fCareerMatchMenuTime ! = 0.0f )
return ;
m_fCareerRoundMenuTime = tmDelay + gpGlobals - > time ;
bool humansAreCTs = ( Q_strcmp ( humans_join_team . string , " CT " ) = = 0 ) ;
if ( humansAreCTs )
{
CBaseEntity * hostage = NULL ;
int numHostagesInMap = 0 ;
int numHostagesFollowingHumans = 0 ;
int numHostagesAlive = 0 ;
while ( ( hostage = UTIL_FindEntityByClassname ( hostage , " hostage_entity " ) ) ! = NULL )
{
2016-02-04 03:18:26 +03:00
+ + numHostagesInMap ;
2015-08-20 13:35:01 +03:00
2016-01-19 14:54:31 +03:00
CHostage * pHostage = static_cast < CHostage * > ( hostage ) ;
2015-08-20 13:35:01 +03:00
if ( pHostage - > pev - > takedamage ! = DAMAGE_YES )
{
continue ;
}
CBasePlayer * pLeader = NULL ;
2016-01-19 14:54:31 +03:00
if ( pHostage - > IsFollowingSomeone ( ) )
pLeader = static_cast < CBasePlayer * > ( pHostage - > GetLeader ( ) ) ;
2015-08-20 13:35:01 +03:00
if ( pLeader = = NULL )
{
2016-02-04 03:18:26 +03:00
+ + numHostagesAlive ;
2015-08-20 13:35:01 +03:00
}
else
{
if ( ! pLeader - > IsBot ( ) )
{
+ + numHostagesFollowingHumans ;
TheCareerTasks - > HandleEvent ( EVENT_HOSTAGE_RESCUED , pLeader , 0 ) ;
}
}
}
if ( ! numHostagesAlive )
{
if ( ( numHostagesInMap * 0.5 ) < = ( numHostagesFollowingHumans + m_iHostagesRescued ) )
{
TheCareerTasks - > HandleEvent ( EVENT_ALL_HOSTAGES_RESCUED ) ;
}
}
}
switch ( iWinStatus )
{
case WINSTATUS_CTS :
TheCareerTasks - > HandleEvent ( humansAreCTs ? EVENT_ROUND_WIN : EVENT_ROUND_LOSS ) ;
break ;
case WINSTATUS_TERRORISTS :
TheCareerTasks - > HandleEvent ( humansAreCTs ? EVENT_ROUND_LOSS : EVENT_ROUND_WIN ) ;
break ;
default :
TheCareerTasks - > HandleEvent ( EVENT_ROUND_DRAW ) ;
break ;
}
if ( m_fCareerMatchMenuTime = = 0.0f & & m_iCareerMatchWins )
{
bool canTsWin = true ;
bool canCTsWin = true ;
if ( m_iNumCTWins < m_iCareerMatchWins | | ( m_iNumCTWins - m_iNumTerroristWins < m_iRoundWinDifference ) )
canCTsWin = false ;
if ( m_iNumTerroristWins < m_iCareerMatchWins | | ( m_iNumTerroristWins - m_iNumCTWins < m_iRoundWinDifference ) )
canTsWin = false ;
2015-12-09 01:39:54 +03:00
if ( ! TheCareerTasks - > AreAllTasksComplete ( ) )
{
if ( humansAreCTs )
return ;
canTsWin = false ;
}
2015-08-20 13:35:01 +03:00
if ( canCTsWin | | canTsWin )
{
m_fCareerRoundMenuTime = 0 ;
m_fCareerMatchMenuTime = gpGlobals - > time + 3.0f ;
}
}
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CheckWinConditions ) ;
2016-01-28 05:51:34 +03:00
// Check if the scenario has been won/lost.
2016-05-17 21:01:46 +03:00
void CHalfLifeMultiplay : : __API_VHOOK ( CheckWinConditions ) ( )
2015-08-20 13:35:01 +03:00
{
2016-04-05 03:12:05 +03:00
if ( HasRoundInfinite ( ) )
2015-12-29 01:54:08 +03:00
return ;
2015-09-30 03:49:22 +03:00
// If a winner has already been determined and game of started.. then get the heck out of here
2016-01-19 14:54:31 +03:00
if ( m_bFirstConnected & & m_iRoundWinStatus ! = WINNER_NONE )
2015-08-20 13:35:01 +03:00
return ;
2016-01-28 05:51:34 +03:00
# ifdef REGAMEDLL_ADD
int scenarioFlags = UTIL_ReadFlags ( round_infinite . string ) ;
# else
// the icc compiler will cut out all of the code which refers to it
int scenarioFlags = 0 ;
2016-02-23 02:13:52 +03:00
# endif
2016-01-28 05:51:34 +03:00
2015-09-30 03:49:22 +03:00
// Initialize the player counts..
int NumDeadCT , NumDeadTerrorist , NumAliveTerrorist , NumAliveCT ;
InitializePlayerCounts ( NumAliveTerrorist , NumAliveCT , NumDeadTerrorist , NumDeadCT ) ;
// other player's check
2016-04-24 16:52:16 +03:00
m_bNeededPlayers = false ;
if ( ! ( scenarioFlags & SCENARIO_BLOCK_NEED_PLAYERS ) & & NeededPlayersCheck ( ) )
2015-09-30 03:49:22 +03:00
return ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Assasination/VIP scenarion check
2016-04-24 16:52:16 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPRE ) & & VIPRoundEndCheck ( ) )
2015-09-30 03:49:22 +03:00
return ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Prison escape check
2016-04-24 16:52:16 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPRE ) & & PrisonRoundEndCheck ( NumAliveTerrorist , NumAliveCT , NumDeadTerrorist , NumDeadCT ) )
2015-09-30 03:49:22 +03:00
return ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Bomb check
2016-04-24 16:52:16 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_BOMB ) & & BombRoundEndCheck ( ) )
2015-09-30 03:49:22 +03:00
return ;
// Team Extermination check
// CounterTerrorists won by virture of elimination
2016-04-24 16:52:16 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_TEAM_EXTERMINATION ) & & TeamExterminationCheck ( NumAliveTerrorist , NumAliveCT , NumDeadTerrorist , NumDeadCT ) )
2015-09-30 03:49:22 +03:00
return ;
// Hostage rescue check
2016-04-24 16:52:16 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_HOSTAGE_RESCUE ) & & HostageRescueRoundEndCheck ( ) )
2015-09-30 03:49:22 +03:00
return ;
2016-01-28 05:51:34 +03:00
// scenario not won - still in progress
2015-09-30 03:49:22 +03:00
}
void CHalfLifeMultiplay : : InitializePlayerCounts ( int & NumAliveTerrorist , int & NumAliveCT , int & NumDeadTerrorist , int & NumDeadCT )
{
NumAliveTerrorist = NumAliveCT = NumDeadCT = NumDeadTerrorist = 0 ;
m_iNumTerrorist = m_iNumCT = m_iNumSpawnableTerrorist = m_iNumSpawnableCT = 0 ;
2015-08-20 13:35:01 +03:00
m_iHaveEscaped = 0 ;
// initialize count dead/alive players
2016-01-28 05:51:34 +03:00
// Count how many dead players there are on each team.
2015-09-30 03:49:22 +03:00
CBaseEntity * pPlayer = NULL ;
2015-08-20 13:35:01 +03:00
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
{
break ;
}
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( pPlayer - > pev - > flags = = FL_DORMANT )
{
continue ;
}
// TODO: check it out, for what here used player->IsBot() ?
// maybe body this conditions is located under the wrapper #ifdef 0
// if (player->IsBot())
// {
// #ifdef 0
// ....
// #endif
// }
switch ( player - > m_iTeam )
{
2015-09-30 03:49:22 +03:00
case CT :
{
2016-02-04 03:18:26 +03:00
+ + m_iNumCT ;
2015-09-30 03:49:22 +03:00
if ( player - > m_iMenu ! = Menu_ChooseAppearance )
2015-08-20 13:35:01 +03:00
{
2016-02-04 03:18:26 +03:00
+ + m_iNumSpawnableCT ;
2015-09-30 03:49:22 +03:00
//player->IsBot();
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
//player->IsBot();
if ( player - > pev - > deadflag ! = DEAD_NO )
2016-02-04 03:18:26 +03:00
+ + NumDeadCT ;
2015-09-30 03:49:22 +03:00
else
2016-02-04 03:18:26 +03:00
+ + NumAliveCT ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
break ;
}
case TERRORIST :
{
2016-02-04 03:18:26 +03:00
+ + m_iNumTerrorist ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( player - > m_iMenu ! = Menu_ChooseAppearance )
2015-08-20 13:35:01 +03:00
{
2016-02-04 03:18:26 +03:00
+ + m_iNumSpawnableTerrorist ;
2015-08-20 13:35:01 +03:00
//player->IsBot();
2015-09-30 03:49:22 +03:00
}
//player->IsBot();
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( player - > pev - > deadflag ! = DEAD_NO )
2016-02-04 03:18:26 +03:00
+ + NumDeadTerrorist ;
2015-09-30 03:49:22 +03:00
else
2016-02-04 03:18:26 +03:00
+ + NumAliveTerrorist ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Check to see if this guy escaped.
if ( player - > m_bEscaped )
2016-02-04 03:18:26 +03:00
+ + m_iHaveEscaped ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
break ;
}
default :
break ;
2015-08-20 13:35:01 +03:00
}
}
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : NeededPlayersCheck_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
// Start the round immediately when the first person joins
UTIL_LogPrintf ( " World triggered \" Game_Commencing \" \n " ) ;
// Make sure we are not on the FreezePeriod.
m_bFreezePeriod = FALSE ;
m_bCompleteReset = true ;
EndRoundMessage ( " #Game_Commencing " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
m_bFirstConnected = true ;
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_GAME_COMMENCE ) ;
}
return true ;
}
bool CHalfLifeMultiplay : : NeededPlayersCheck ( )
2015-09-30 03:49:22 +03:00
{
// We needed players to start scoring
// Do we have them now?
2015-08-20 13:35:01 +03:00
// start the game, after the players entered in game
2015-09-30 03:49:22 +03:00
if ( ! m_iNumSpawnableTerrorist | | ! m_iNumSpawnableCT )
2015-08-20 13:35:01 +03:00
{
UTIL_ClientPrintAll ( HUD_PRINTCONSOLE , " #Game_scoring " ) ;
2016-04-24 16:52:16 +03:00
m_bNeededPlayers = true ;
2015-08-20 13:35:01 +03:00
m_bFirstConnected = false ;
}
2015-09-30 03:49:22 +03:00
if ( ! m_bFirstConnected & & m_iNumSpawnableTerrorist ! = 0 & & m_iNumSpawnableCT ! = 0 )
2015-08-20 13:35:01 +03:00
{
if ( IsCareer ( ) )
{
2016-05-31 17:04:51 +03:00
CBasePlayer * player = UTIL_PlayerByIndex ( gpGlobals - > maxClients ) ;
2015-08-20 13:35:01 +03:00
if ( ! player | | ! player - > IsBot ( ) )
{
2015-09-30 03:49:22 +03:00
return true ;
2015-08-20 13:35:01 +03:00
}
}
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : NeededPlayersCheck_internal , this , WINSTATUS_DRAW , ROUND_GAME_COMMENCE , IsCareer ( ) ? 0 : 3 ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return false ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : VIP_Escaped_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ RR_VIP_ESCAPED ] ;
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // VIP rescued
WRITE_SHORT ( ENTINDEX ( m_pVIP - > edict ( ) ) ) ; // index number of primary entity
WRITE_SHORT ( 0 ) ; // index number of secondary entity
WRITE_LONG ( 15 | DRC_FLAG_FINAL ) ; // eventflags (priority and flags)
MESSAGE_END ( ) ;
EndRoundMessage ( " #VIP_Escaped " , event ) ;
// tell the bots the VIP got out
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_VIP_ESCAPED ) ;
}
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
return true ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : VIP_Died_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_VIP_ASSASSINATED ] ;
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumTerroristWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
EndRoundMessage ( " #VIP_Assassinated " , event ) ;
// tell the bots the VIP was killed
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_VIP_ASSASSINATED ) ;
}
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
return true ;
}
bool CHalfLifeMultiplay : : VIPRoundEndCheck ( )
2015-09-30 03:49:22 +03:00
{
2015-08-20 13:35:01 +03:00
// checks to scenario Escaped VIP on map with vip safety zones
if ( m_iMapHasVIPSafetyZone = = MAP_HAVE_VIP_SAFETYZONE_YES & & m_pVIP ! = NULL )
{
if ( m_pVIP - > m_bEscaped )
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : VIP_Escaped_internal , this , WINSTATUS_CTS , ROUND_VIP_ESCAPED , 5 ) ;
}
// The VIP is dead
else if ( m_pVIP - > pev - > deadflag ! = DEAD_NO )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : VIP_Died_internal , this , WINSTATUS_TERRORISTS , ROUND_VIP_ASSASSINATED , 5 ) ;
}
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return false ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Prison_Escaped_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_TERRORISTS_ESCAPED ] ;
2016-01-28 05:51:34 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumTerroristWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #Terrorists_Escaped " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return true ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Prison_PreventEscape_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2016-01-28 05:51:34 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
// CTs are rewarded based on how many terrorists have escaped...
2016-06-08 00:41:07 +03:00
m_iAccountCT + = ( 1 - m_flEscapeRatio ) * m_rgRewardAccountRules [ RR_CTS_PREVENT_ESCAPE ] ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #CTs_PreventEscape " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
return true ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Prison_Neutralized_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " ctwin " ) ;
// CTs are rewarded based on how many terrorists have escaped...
2016-06-08 00:41:07 +03:00
m_iAccountCT + = ( 1 - m_flEscapeRatio ) * m_rgRewardAccountRules [ RR_ESCAPING_TERRORISTS_NEUTRALIZED ] ;
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
EndRoundMessage ( " #Escaping_Terrorists_Neutralized " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
return true ;
}
bool CHalfLifeMultiplay : : PrisonRoundEndCheck ( int NumAliveTerrorist , int NumAliveCT , int NumDeadTerrorist , int NumDeadCT )
2015-09-30 03:49:22 +03:00
{
2015-08-20 13:35:01 +03:00
// checks to scenario Escaped Terrorist's
if ( m_bMapHasEscapeZone )
{
2016-04-24 16:52:16 +03:00
m_flEscapeRatio = float_precision ( m_iHaveEscaped ) / float_precision ( m_iNumEscapers ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( m_flEscapeRatio > = m_flRequiredEscapeRatio )
2015-08-20 13:35:01 +03:00
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Prison_Escaped_internal , this , WINSTATUS_TERRORISTS , ROUND_TERRORISTS_ESCAPED , 5 ) ;
}
else if ( NumAliveTerrorist = = 0 & & m_flEscapeRatio < m_flRequiredEscapeRatio )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Prison_PreventEscape_internal , this , WINSTATUS_CTS , ROUND_CTS_PREVENT_ESCAPE , 5 ) ;
}
else if ( NumAliveTerrorist = = 0 & & NumDeadTerrorist ! = 0 & & m_iNumSpawnableCT > 0 )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Prison_Neutralized_internal , this , WINSTATUS_CTS , ROUND_ESCAPING_TERRORISTS_NEUTRALIZED , 5 ) ;
}
// else return true;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return false ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Target_Bombed_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_TARGET_BOMB ] ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumTerroristWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #Target_Bombed " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return true ;
}
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Target_Defused_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ RR_BOMB_DEFUSED ] ;
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_BOMB_PLANTED ] ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #Bomb_Defused " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
return true ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : BombRoundEndCheck ( )
2015-09-30 03:49:22 +03:00
{
// Check to see if the bomb target was hit or the bomb defused.. if so, then let's end the round!
if ( m_bTargetBombed & & m_bMapHasBombTarget )
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Target_Bombed_internal , this , WINSTATUS_TERRORISTS , ROUND_TARGET_BOMB , 5 ) ;
}
else if ( m_bBombDefused & & m_bMapHasBombTarget )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Target_Defused_internal , this , WINSTATUS_CTS , ROUND_BOMB_DEFUSED , 5 ) ;
}
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
return false ;
}
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Round_Cts_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ m_bMapHasBombTarget ? RR_BOMB_DEFUSED : RR_CTS_WIN ] ;
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #CTs_Win " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
2015-09-30 03:49:22 +03:00
{
2016-04-24 16:52:16 +03:00
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
return true ;
}
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Round_Ts_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ m_bMapHasBombTarget ? RR_BOMB_EXPLODED : RR_TERRORISTS_WIN ] ;
2015-09-30 03:49:22 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumTerroristWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #Terrorists_Win " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
return true ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Round_Draw_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
EndRoundMessage ( " #Round_Draw " , event ) ;
Broadcast ( " rounddraw " ) ;
TerminateRound ( tmDelay , winStatus ) ;
return true ;
}
bool CHalfLifeMultiplay : : TeamExterminationCheck ( int NumAliveTerrorist , int NumAliveCT , int NumDeadTerrorist , int NumDeadCT )
2015-09-30 03:49:22 +03:00
{
2016-01-12 16:52:42 +03:00
if ( ( m_iNumCT > 0 & & m_iNumSpawnableCT > 0 ) & & ( m_iNumTerrorist > 0 & & m_iNumSpawnableTerrorist > 0 ) )
2015-08-20 13:35:01 +03:00
{
2016-01-14 15:59:01 +03:00
if ( NumAliveTerrorist = = 0 & & NumDeadTerrorist ! = 0 & & NumAliveCT > 0 )
2015-08-20 13:35:01 +03:00
{
CBaseEntity * temp = NULL ;
2015-09-30 03:49:22 +03:00
bool nowin = false ;
2015-08-20 13:35:01 +03:00
while ( ( temp = UTIL_FindEntityByClassname ( temp , " grenade " ) ) ! = NULL )
{
2016-01-25 20:02:57 +03:00
CGrenade * C4 = static_cast < CGrenade * > ( temp ) ;
2015-08-20 13:35:01 +03:00
if ( C4 - > m_bIsC4 & & ! C4 - > m_bJustBlew )
{
2015-09-30 03:49:22 +03:00
nowin = true ;
2015-08-20 13:35:01 +03:00
# ifdef REGAMEDLL_FIXES
break ;
2016-02-23 02:13:52 +03:00
# endif
2015-08-20 13:35:01 +03:00
}
}
if ( ! nowin )
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Round_Cts_internal , this , WINSTATUS_CTS , ROUND_CTS_WIN , 5 ) ;
2015-08-20 13:35:01 +03:00
}
}
2015-09-30 03:49:22 +03:00
// Terrorists WON
2016-01-12 16:52:42 +03:00
else if ( NumAliveCT = = 0 & & NumDeadCT ! = 0 )
2015-08-20 13:35:01 +03:00
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Round_Ts_internal , this , WINSTATUS_TERRORISTS , ROUND_TERRORISTS_WIN , 5 ) ;
}
}
else if ( NumAliveCT = = 0 & & NumAliveTerrorist = = 0 )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Round_Draw_internal , this , WINSTATUS_DRAW , ROUND_END_DRAW , 5 ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
return false ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Hostage_Rescue_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ RR_ALL_HOSTAGES_RESCUED ] ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
+ + m_iNumCTWins ;
// Update the clients team score
UpdateTeamScores ( ) ;
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
EndRoundMessage ( " #All_Hostages_Rescued " , event ) ;
// tell the bots all the hostages have been rescued
if ( TheBots ! = NULL )
2015-08-20 13:35:01 +03:00
{
2016-04-24 16:52:16 +03:00
TheBots - > OnEvent ( EVENT_ALL_HOSTAGES_RESCUED ) ;
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
if ( TheCareerTasks ! = NULL )
{
TheCareerTasks - > HandleEvent ( EVENT_ALL_HOSTAGES_RESCUED ) ;
}
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
return true ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : HostageRescueRoundEndCheck ( )
2015-09-30 03:49:22 +03:00
{
// Check to see if 50% of the hostages have been rescued.
2015-08-20 13:35:01 +03:00
CBaseEntity * hostage = NULL ;
int iHostages = 0 ;
2015-09-30 03:49:22 +03:00
// Assume that all hostages are either rescued or dead..
2015-08-20 13:35:01 +03:00
bool bHostageAlive = false ;
while ( ( hostage = UTIL_FindEntityByClassname ( hostage , " hostage_entity " ) ) ! = NULL )
{
2016-02-04 03:18:26 +03:00
+ + iHostages ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// We've found a live hostage. don't end the round
2015-08-20 13:35:01 +03:00
if ( hostage - > pev - > takedamage = = DAMAGE_YES )
{
bHostageAlive = true ;
}
}
2015-09-30 03:49:22 +03:00
// There are no hostages alive.. check to see if the CTs have rescued atleast 50% of them.
if ( ! bHostageAlive & & iHostages > 0 )
2015-08-20 13:35:01 +03:00
{
2016-04-24 16:52:16 +03:00
if ( m_iHostagesRescued > = ( iHostages * 0.5f ) )
2015-08-20 13:35:01 +03:00
{
2016-04-24 16:52:16 +03:00
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Hostage_Rescue_internal , this , WINSTATUS_CTS , ROUND_ALL_HOSTAGES_RESCUED , 5 ) ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
return false ;
2015-08-20 13:35:01 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : SwapAllPlayers ( )
2015-08-20 13:35:01 +03:00
{
CBaseEntity * pPlayer = NULL ;
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
player - > SwitchTeam ( ) ;
}
2015-09-30 03:49:22 +03:00
// Swap Team victories
int iTemp ;
iTemp = m_iNumTerroristWins ;
2015-08-20 13:35:01 +03:00
m_iNumTerroristWins = m_iNumCTWins ;
m_iNumCTWins = iTemp ;
2015-09-30 03:49:22 +03:00
// Update the clients team score
2015-08-20 13:35:01 +03:00
UpdateTeamScores ( ) ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , BalanceTeams ) ;
void CHalfLifeMultiplay : : __API_HOOK ( BalanceTeams ) ( )
2015-08-20 13:35:01 +03:00
{
int iTeamToSwap = UNASSIGNED ;
int iNumToSwap ;
2015-09-30 03:49:22 +03:00
// The ratio for teams is different for Assasination maps
2015-08-20 13:35:01 +03:00
if ( m_iMapHasVIPSafetyZone = = MAP_HAVE_VIP_SAFETYZONE_YES )
{
2015-09-30 03:49:22 +03:00
int iDesiredNumCT , iDesiredNumTerrorist ;
// uneven number of players
if ( ( m_iNumCT + m_iNumTerrorist ) % 2 ! = 0 )
2016-02-23 02:13:52 +03:00
iDesiredNumCT = int ( ( m_iNumCT + m_iNumTerrorist ) * 0.55f ) + 1 ;
2015-08-20 13:35:01 +03:00
else
2016-02-23 02:13:52 +03:00
iDesiredNumCT = int ( ( m_iNumCT + m_iNumTerrorist ) / 2 ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
iDesiredNumTerrorist = ( m_iNumCT + m_iNumTerrorist ) - iDesiredNumCT ;
2015-08-20 13:35:01 +03:00
if ( m_iNumCT < iDesiredNumCT )
{
iTeamToSwap = TERRORIST ;
iNumToSwap = iDesiredNumCT - m_iNumCT ;
}
else if ( m_iNumTerrorist < iDesiredNumTerrorist )
{
iTeamToSwap = CT ;
iNumToSwap = iDesiredNumTerrorist - m_iNumTerrorist ;
}
else
{
return ;
}
}
else
{
2015-09-30 03:49:22 +03:00
if ( m_iNumCT > m_iNumTerrorist )
2015-08-20 13:35:01 +03:00
{
iTeamToSwap = CT ;
iNumToSwap = ( m_iNumCT - m_iNumTerrorist ) / 2 ;
}
else if ( m_iNumTerrorist > m_iNumCT )
{
iTeamToSwap = TERRORIST ;
iNumToSwap = ( m_iNumTerrorist - m_iNumCT ) / 2 ;
}
else
{
2015-09-30 03:49:22 +03:00
// Teams are even.. Get out of here.
2015-08-20 13:35:01 +03:00
return ;
}
}
2015-09-30 03:49:22 +03:00
// Don't swap more than 4 players at a time.. This is a naive method of avoiding infinite loops.
2015-08-20 13:35:01 +03:00
if ( iNumToSwap > 4 )
iNumToSwap = 4 ;
2015-09-30 03:49:22 +03:00
// last person to join the server
int iHighestUserID = 0 ;
2015-08-20 13:35:01 +03:00
CBasePlayer * toSwap = NULL ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = iNumToSwap ; + + i )
2015-08-20 13:35:01 +03:00
{
iHighestUserID = 0 ;
toSwap = NULL ;
2015-09-30 03:49:22 +03:00
CBaseEntity * pPlayer = NULL ;
2015-08-20 13:35:01 +03:00
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( player - > m_iTeam = = iTeamToSwap & & GETPLAYERUSERID ( player - > edict ( ) ) > iHighestUserID & & m_pVIP ! = player )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
iHighestUserID = GETPLAYERUSERID ( player - > edict ( ) ) ;
toSwap = player ;
2015-08-20 13:35:01 +03:00
}
}
if ( toSwap ! = NULL )
{
toSwap - > SwitchTeam ( ) ;
}
}
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CheckMapConditions ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( CheckMapConditions ) ( )
2015-08-20 13:35:01 +03:00
{
2016-01-28 05:51:34 +03:00
// Check to see if this map has a bomb target in it
2015-08-20 13:35:01 +03:00
if ( UTIL_FindEntityByClassname ( NULL , " func_bomb_target " ) )
{
m_bMapHasBombTarget = true ;
m_bMapHasBombZone = true ;
}
else if ( UTIL_FindEntityByClassname ( NULL , " info_bomb_target " ) )
{
m_bMapHasBombTarget = true ;
m_bMapHasBombZone = false ;
}
else
{
m_bMapHasBombTarget = false ;
m_bMapHasBombZone = false ;
}
2015-09-30 03:49:22 +03:00
// Check to see if this map has hostage rescue zones
2015-08-20 13:35:01 +03:00
m_bMapHasRescueZone = ( UTIL_FindEntityByClassname ( NULL , " func_hostage_rescue " ) ! = NULL ) ;
2015-09-30 03:49:22 +03:00
// See if the map has func_buyzone entities
// Used by CBasePlayer::HandleSignals() to support maps without these entities
2015-08-20 13:35:01 +03:00
m_bMapHasBuyZone = ( UTIL_FindEntityByClassname ( NULL , " func_buyzone " ) ! = NULL ) ;
2015-09-30 03:49:22 +03:00
// GOOSEMAN : See if this map has func_escapezone entities
2015-08-20 13:35:01 +03:00
m_bMapHasEscapeZone = ( UTIL_FindEntityByClassname ( NULL , " func_escapezone " ) ! = NULL ) ;
2015-09-30 03:49:22 +03:00
// Check to see if this map has VIP safety zones
2015-08-20 13:35:01 +03:00
if ( ( UTIL_FindEntityByClassname ( NULL , " func_vip_safetyzone " ) ) ! = NULL )
m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_YES ;
else
m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_NO ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , RestartRound ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( RestartRound ) ( )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// tell bots that the round is restarting
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > RestartRound ( ) ;
}
2015-08-20 13:35:01 +03:00
2015-11-06 17:58:48 +03:00
if ( g_pHostages ! = NULL )
2015-08-20 13:35:01 +03:00
{
g_pHostages - > RestartRound ( ) ;
}
2016-02-04 03:18:26 +03:00
+ + m_iTotalRoundsPlayed ;
2015-08-20 13:35:01 +03:00
ClearBodyQue ( ) ;
2015-09-30 03:49:22 +03:00
// Hardlock the player accelaration to 5.0
CVAR_SET_FLOAT ( " sv_accelerate " , 5.0 ) ;
CVAR_SET_FLOAT ( " sv_friction " , 4.0 ) ;
2015-08-20 13:35:01 +03:00
CVAR_SET_FLOAT ( " sv_stopspeed " , 75 ) ;
2015-09-30 03:49:22 +03:00
// Tabulate the number of players on each team.
2015-08-20 13:35:01 +03:00
m_iNumCT = CountTeamPlayers ( CT ) ;
m_iNumTerrorist = CountTeamPlayers ( TERRORIST ) ;
2015-09-30 03:49:22 +03:00
// reset the dropped bomb on everyone's radar
2015-08-20 13:35:01 +03:00
if ( m_bMapHasBombTarget )
{
MESSAGE_BEGIN ( MSG_ALL , gmsgBombPickup ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgShowTimer ) ;
MESSAGE_END ( ) ;
}
2015-11-06 17:58:48 +03:00
m_bBombDropped = FALSE ;
2015-09-16 23:19:21 +03:00
2015-09-30 03:49:22 +03:00
// reset all players health for HLTV
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_SPEC , gmsgHLTV ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ; // 0 = all players
WRITE_BYTE ( 100 | DRC_FLAG_FACEPLAYER ) ; // 100 health + msg flag
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
2015-09-30 03:49:22 +03:00
// reset all players FOV for HLTV
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_SPEC , gmsgHLTV ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ; // all players
WRITE_BYTE ( 0 ) ; // to default FOV value
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
if ( CVAR_GET_FLOAT ( " mp_autoteambalance " ) ! = 0.0f & & m_iUnBalancedRounds > = 1 )
2015-09-30 03:49:22 +03:00
{
2015-08-20 13:35:01 +03:00
BalanceTeams ( ) ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
if ( ( m_iNumCT - m_iNumTerrorist ) > = 2 | | ( m_iNumTerrorist - m_iNumCT ) > = 2 )
2015-09-30 03:49:22 +03:00
{
2016-02-04 03:18:26 +03:00
+ + m_iUnBalancedRounds ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
else
m_iUnBalancedRounds = 0 ;
2015-09-30 03:49:22 +03:00
// Warn the players of an impending auto-balance next round...
2015-08-20 13:35:01 +03:00
if ( CVAR_GET_FLOAT ( " mp_autoteambalance " ) ! = 0.0f & & m_iUnBalancedRounds = = 1 )
{
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Auto_Team_Balance_Next_Round " ) ;
}
if ( m_bCompleteReset )
{
2015-09-30 03:49:22 +03:00
// bounds check
2015-08-20 13:35:01 +03:00
if ( timelimit . value < 0 )
2015-09-30 03:49:22 +03:00
{
2015-08-20 13:35:01 +03:00
CVAR_SET_FLOAT ( " mp_timelimit " , 0 ) ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
g_flResetTime = gpGlobals - > time ;
2015-09-30 03:49:22 +03:00
// Reset timelimit
2015-08-20 13:35:01 +03:00
if ( timelimit . value )
2015-09-30 03:49:22 +03:00
g_flTimeLimit = gpGlobals - > time + ( timelimit . value * 60 ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Reset total # of rounds played
2015-08-20 13:35:01 +03:00
m_iTotalRoundsPlayed = 0 ;
2016-02-23 02:13:52 +03:00
m_iMaxRounds = int ( CVAR_GET_FLOAT ( " mp_maxrounds " ) ) ;
2015-08-20 13:35:01 +03:00
if ( m_iMaxRounds < 0 )
{
m_iMaxRounds = 0 ;
CVAR_SET_FLOAT ( " mp_maxrounds " , 0 ) ;
}
2016-02-23 02:13:52 +03:00
m_iMaxRoundsWon = int ( CVAR_GET_FLOAT ( " mp_winlimit " ) ) ;
2015-08-20 13:35:01 +03:00
if ( m_iMaxRoundsWon < 0 )
{
m_iMaxRoundsWon = 0 ;
CVAR_SET_FLOAT ( " mp_winlimit " , 0 ) ;
}
2015-09-30 03:49:22 +03:00
// Reset score info
2015-08-20 13:35:01 +03:00
m_iNumTerroristWins = 0 ;
m_iNumCTWins = 0 ;
m_iNumConsecutiveTerroristLoses = 0 ;
m_iNumConsecutiveCTLoses = 0 ;
2015-09-30 03:49:22 +03:00
// Reset team scores
2015-08-20 13:35:01 +03:00
UpdateTeamScores ( ) ;
2015-09-30 03:49:22 +03:00
// Reset the player stats
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * plr = UTIL_PlayerByIndex ( i ) ;
2015-11-24 00:01:09 +03:00
2015-08-20 13:35:01 +03:00
if ( plr & & ! FNullEnt ( plr - > pev ) )
plr - > Reset ( ) ;
}
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_NEW_MATCH ) ;
}
2015-08-20 13:35:01 +03:00
}
m_bFreezePeriod = TRUE ;
m_bRoundTerminating = false ;
2016-06-02 01:08:22 +03:00
ReadMultiplayCvars ( ) ;
2015-08-20 13:35:01 +03:00
float flAutoKickIdle = CVAR_GET_FLOAT ( " mp_autokick_timeout " ) ;
2015-09-30 03:49:22 +03:00
// set the idlekick max time (in seconds)
2015-08-20 13:35:01 +03:00
if ( flAutoKickIdle > 0 )
m_fMaxIdlePeriod = flAutoKickIdle ;
else
m_fMaxIdlePeriod = ( m_iRoundTime * 2 ) ;
2015-09-30 03:49:22 +03:00
// This makes the round timer function as the intro timer on the client side
2015-08-20 13:35:01 +03:00
m_iRoundTimeSecs = m_iIntroRoundTime ;
2015-09-30 03:49:22 +03:00
// Check to see if there's a mapping info paramater entity
2015-08-20 13:35:01 +03:00
CMapInfo * mi = ( CMapInfo * ) UTIL_FindEntityByClassname ( NULL , " info_map_parameters " ) ;
if ( mi ! = NULL )
{
switch ( mi - > m_iBuyingStatus )
{
case BUYING_EVERYONE :
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
ALERT ( at_console , " EVERYONE CAN BUY! \n " ) ;
break ;
case BUYING_ONLY_CTS :
m_bCTCantBuy = false ;
m_bTCantBuy = true ;
ALERT ( at_console , " Only CT's can buy!! \n " ) ;
break ;
case BUYING_ONLY_TERRORISTS :
m_bCTCantBuy = true ;
m_bTCantBuy = false ;
ALERT ( at_console , " Only T's can buy!! \n " ) ;
break ;
case BUYING_NO_ONE :
m_bCTCantBuy = true ;
m_bTCantBuy = true ;
ALERT ( at_console , " No one can buy!! \n " ) ;
break ;
default :
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
break ;
}
m_flBombRadius = mi - > m_flBombRadius ;
}
CheckMapConditions ( ) ;
if ( m_bMapHasEscapeZone )
{
2015-11-06 17:58:48 +03:00
// Will increase this later when we count how many Ts are starting
m_iNumEscapers = m_iHaveEscaped = 0 ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( m_iNumEscapeRounds > = 3 )
2015-08-20 13:35:01 +03:00
{
SwapAllPlayers ( ) ;
m_iNumEscapeRounds = 0 ;
}
2015-09-30 03:49:22 +03:00
// Increment the number of rounds played... After 8 rounds, the players will do a whole sale switch..
2016-02-04 03:18:26 +03:00
+ + m_iNumEscapeRounds ;
2015-08-20 13:35:01 +03:00
}
if ( m_iMapHasVIPSafetyZone = = MAP_HAVE_VIP_SAFETYZONE_YES )
{
PickNextVIP ( ) ;
2016-02-04 03:18:26 +03:00
+ + m_iConsecutiveVIP ;
2015-08-20 13:35:01 +03:00
}
int acct_tmp = 0 ;
CBaseEntity * hostage = NULL ;
while ( ( hostage = UTIL_FindEntityByClassname ( hostage , " hostage_entity " ) ) ! = NULL )
{
if ( acct_tmp > = 2000 )
break ;
2016-01-25 20:02:57 +03:00
CHostage * temp = static_cast < CHostage * > ( hostage ) ;
2015-08-20 13:35:01 +03:00
if ( hostage - > pev - > solid ! = SOLID_NOT )
{
2016-06-08 00:41:07 +03:00
acct_tmp + = m_rgRewardAccountRules [ RR_TOOK_HOSTAGE ] ;
2015-08-20 13:35:01 +03:00
if ( hostage - > pev - > deadflag = = DEAD_DEAD )
{
hostage - > pev - > deadflag = DEAD_RESPAWNABLE ;
}
}
temp - > RePosition ( ) ;
}
2015-09-30 03:49:22 +03:00
// Scale up the loser bonus when teams fall into losing streaks
if ( m_iRoundWinStatus = = WINSTATUS_TERRORISTS ) // terrorists won
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// check to see if they just broke a losing streak
2015-08-20 13:35:01 +03:00
if ( m_iNumConsecutiveTerroristLoses > 1 )
{
2015-09-30 03:49:22 +03:00
// this is the default losing bonus
2016-06-08 00:41:07 +03:00
m_iLoserBonus = m_rgRewardAccountRules [ RR_LOSER_BONUS_MIN ] ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
m_iNumConsecutiveTerroristLoses = 0 ; // starting fresh
m_iNumConsecutiveCTLoses + + ; // increment the number of wins the CTs have had
2015-08-20 13:35:01 +03:00
}
else if ( m_iRoundWinStatus = = WINSTATUS_CTS )
{
2015-09-30 03:49:22 +03:00
// check to see if they just broke a losing streak
2015-08-20 13:35:01 +03:00
if ( m_iNumConsecutiveCTLoses > 1 )
{
2015-09-30 03:49:22 +03:00
// this is the default losing bonus
2016-06-08 00:41:07 +03:00
m_iLoserBonus = m_rgRewardAccountRules [ RR_LOSER_BONUS_MIN ] ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
m_iNumConsecutiveCTLoses = 0 ; // starting fresh
m_iNumConsecutiveTerroristLoses + + ; // increment the number of wins the Terrorists have had
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// check if the losing team is in a losing streak & that the loser bonus hasen't maxed out.
2016-06-08 00:41:07 +03:00
if ( m_iNumConsecutiveTerroristLoses > 1 & & m_iLoserBonus < m_rgRewardAccountRules [ RR_LOSER_BONUS_MAX ] )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// help out the team in the losing streak
2016-06-08 00:41:07 +03:00
m_iLoserBonus + = m_rgRewardAccountRules [ RR_LOSER_BONUS_ADD ] ;
2015-09-30 03:49:22 +03:00
}
2016-06-08 00:41:07 +03:00
else if ( m_iNumConsecutiveCTLoses > 1 & & m_iLoserBonus < m_rgRewardAccountRules [ RR_LOSER_BONUS_MAX ] )
2015-09-30 03:49:22 +03:00
{
// help out the team in the losing streak
2016-06-08 00:41:07 +03:00
m_iLoserBonus + = m_rgRewardAccountRules [ RR_LOSER_BONUS_ADD ] ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// assign the wining and losing bonuses
if ( m_iRoundWinStatus = = WINSTATUS_TERRORISTS ) // terrorists won
2015-08-20 13:35:01 +03:00
{
m_iAccountTerrorist + = acct_tmp ;
m_iAccountCT + = m_iLoserBonus ;
}
2015-09-30 03:49:22 +03:00
else if ( m_iRoundWinStatus = = WINSTATUS_CTS ) // CT Won
2015-08-20 13:35:01 +03:00
{
m_iAccountCT + = acct_tmp ;
if ( ! m_bMapHasEscapeZone )
{
2015-09-30 03:49:22 +03:00
// only give them the bonus if this isn't an escape map
2015-08-20 13:35:01 +03:00
m_iAccountTerrorist + = m_iLoserBonus ;
}
}
2015-09-30 03:49:22 +03:00
// Update CT account based on number of hostages rescued
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_iHostagesRescued * m_rgRewardAccountRules [ RR_RESCUED_HOSTAGE ] ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Update individual players accounts and respawn players
// the round time stamp must be set before players are spawned
m_fIntroRoundCount = m_fRoundCount = gpGlobals - > time ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Adrian - No cash for anyone at first rounds! ( well, only the default. )
2015-08-20 13:35:01 +03:00
if ( m_bCompleteReset )
{
2015-09-30 03:49:22 +03:00
// No extra cash!.
m_iAccountTerrorist = m_iAccountCT = 0 ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// We are starting fresh. So it's like no one has ever won or lost.
2015-08-20 13:35:01 +03:00
m_iNumTerroristWins = 0 ;
m_iNumCTWins = 0 ;
m_iNumConsecutiveTerroristLoses = 0 ;
m_iNumConsecutiveCTLoses = 0 ;
2016-06-08 00:41:07 +03:00
m_iLoserBonus = m_rgRewardAccountRules [ RR_LOSER_BONUS_DEFAULT ] ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// tell bots that the round is restarting
2015-08-20 13:35:01 +03:00
CBaseEntity * pPlayer = NULL ;
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
2015-09-16 23:19:21 +03:00
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
player - > m_iNumSpawns = 0 ;
player - > m_bTeamChanged = false ;
if ( ! player - > IsPlayer ( ) )
{
player - > SyncRoundTimer ( ) ;
}
if ( player - > m_iTeam = = CT )
{
if ( ! player - > m_bReceivesNoMoneyNextRound )
{
2016-05-25 16:56:48 +03:00
player - > AddAccount ( m_iAccountCT , RT_ROUND_BONUS ) ;
2015-08-20 13:35:01 +03:00
}
}
else if ( player - > m_iTeam = = TERRORIST )
{
2015-09-30 03:49:22 +03:00
// Add another potential escaper to the mix!
2016-02-04 03:18:26 +03:00
+ + m_iNumEscapers ;
2015-08-20 13:35:01 +03:00
if ( ! player - > m_bReceivesNoMoneyNextRound )
{
2016-05-25 16:56:48 +03:00
player - > AddAccount ( m_iAccountTerrorist , RT_ROUND_BONUS ) ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// If it's a prison scenario then remove the Ts guns
2015-08-20 13:35:01 +03:00
if ( m_bMapHasEscapeZone )
{
2015-09-30 03:49:22 +03:00
// this will cause them to be reset with default weapons, armor, and items
2015-08-20 13:35:01 +03:00
player - > m_bNotKilled = false ;
}
}
if ( player - > m_iTeam ! = UNASSIGNED & & player - > m_iTeam ! = SPECTATOR )
{
2015-09-30 03:49:22 +03:00
// drop the c4 if the player is carrying it
2015-08-20 13:35:01 +03:00
if ( player - > m_bHasC4 )
{
player - > DropPlayerItem ( " weapon_c4 " ) ;
}
player - > RoundRespawn ( ) ;
}
2015-09-30 03:49:22 +03:00
// Gooseman : The following code fixes the HUD icon bug
// by removing the C4 and DEFUSER icons from the HUD regardless
// for EVERY player (regardless of what team they're on)
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Respawn entities (glass, doors, etc..)
2015-08-20 13:35:01 +03:00
CleanUpMap ( ) ;
2015-09-30 03:49:22 +03:00
// Give C4 to the terrorists
2015-08-20 13:35:01 +03:00
if ( m_bMapHasBombTarget )
{
GiveC4 ( ) ;
}
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_BUY_TIME_START ) ;
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Reset game variables
2015-08-20 13:35:01 +03:00
m_flIntermissionEndTime = 0 ;
m_flIntermissionStartTime = 0 ;
2015-09-30 03:49:22 +03:00
m_fTeamCount = 0.0 ;
m_iAccountTerrorist = m_iAccountCT = 0 ;
2015-08-20 13:35:01 +03:00
m_iHostagesRescued = 0 ;
m_iHostagesTouched = 0 ;
2016-01-19 14:54:31 +03:00
m_iRoundWinStatus = WINNER_NONE ;
2015-09-30 03:49:22 +03:00
m_bTargetBombed = m_bBombDefused = false ;
2015-08-20 13:35:01 +03:00
m_bLevelInitialized = false ;
m_bCompleteReset = false ;
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : IsThereABomber ( )
2015-08-20 13:35:01 +03:00
{
CBasePlayer * pPlayer = NULL ;
while ( ( pPlayer = ( CBasePlayer * ) UTIL_FindEntityByClassname ( pPlayer , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pPlayer - > edict ( ) ) )
break ;
if ( pPlayer - > m_iTeam ! = CT & & pPlayer - > IsBombGuy ( ) )
2015-09-30 03:49:22 +03:00
{
// There you are.
2015-08-20 13:35:01 +03:00
return TRUE ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Didn't find a bomber.
2015-08-20 13:35:01 +03:00
return FALSE ;
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : IsThereABomb ( )
2015-08-20 13:35:01 +03:00
{
CGrenade * pC4 = NULL ;
CBaseEntity * pWeaponC4 = NULL ;
2016-02-23 02:13:52 +03:00
bool bFoundBomb = false ;
2015-08-20 13:35:01 +03:00
while ( ( pWeaponC4 = UTIL_FindEntityByClassname ( pWeaponC4 , " grenade " ) ) ! = NULL )
{
if ( ! pWeaponC4 )
continue ;
2016-02-23 02:13:52 +03:00
pC4 = static_cast < CGrenade * > ( pWeaponC4 ) ;
2015-08-20 13:35:01 +03:00
if ( pC4 - > m_bIsC4 )
{
2016-02-23 02:13:52 +03:00
bFoundBomb = true ;
2015-08-20 13:35:01 +03:00
break ;
}
}
if ( bFoundBomb | | ( UTIL_FindEntityByClassname ( NULL , " weapon_c4 " ) ) ! = NULL )
return TRUE ;
return FALSE ;
}
BOOL CHalfLifeMultiplay : : TeamFull ( int team_id )
{
switch ( team_id )
{
2015-09-30 03:49:22 +03:00
case TERRORIST :
return ( m_iNumTerrorist > = m_iSpawnPointCount_Terrorist ) ;
case CT :
return ( m_iNumCT > = m_iSpawnPointCount_CT ) ;
2015-08-20 13:35:01 +03:00
}
return FALSE ;
}
2015-09-30 03:49:22 +03:00
// checks to see if the desired team is stacked, returns true if it is
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : TeamStacked ( int newTeam_id , int curTeam_id )
{
2015-09-30 03:49:22 +03:00
// players are allowed to change to their own team
2015-08-20 13:35:01 +03:00
if ( newTeam_id = = curTeam_id )
return FALSE ;
if ( ! m_iLimitTeams )
return FALSE ;
2015-08-02 20:45:57 +03:00
switch ( newTeam_id )
{
2015-09-30 03:49:22 +03:00
case TERRORIST :
if ( curTeam_id ! = UNASSIGNED & & curTeam_id ! = SPECTATOR )
return ( ( m_iNumTerrorist + 1 ) > ( m_iNumCT + m_iLimitTeams - 1 ) ) ;
else
return ( ( m_iNumTerrorist + 1 ) > ( m_iNumCT + m_iLimitTeams ) ) ;
case CT :
if ( curTeam_id ! = UNASSIGNED & & curTeam_id ! = SPECTATOR )
return ( ( m_iNumCT + 1 ) > ( m_iNumTerrorist + m_iLimitTeams - 1 ) ) ;
else
return ( ( m_iNumCT + 1 ) > ( m_iNumTerrorist + m_iLimitTeams ) ) ;
2015-08-20 13:35:01 +03:00
}
return FALSE ;
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : StackVIPQueue ( )
2015-08-20 13:35:01 +03:00
{
2016-01-12 16:52:42 +03:00
for ( int i = MAX_VIP_QUEUES - 2 ; i > 0 ; - - i )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
if ( m_pVIPQueue [ i - 1 ] )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
if ( ! m_pVIPQueue [ i ] )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ i ] = m_pVIPQueue [ i + 1 ] ;
m_pVIPQueue [ i + 1 ] = NULL ;
2015-08-20 13:35:01 +03:00
}
}
else
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ i - 1 ] = m_pVIPQueue [ i ] ;
m_pVIPQueue [ i ] = m_pVIPQueue [ i + 1 ] ;
m_pVIPQueue [ i + 1 ] = NULL ;
2015-08-20 13:35:01 +03:00
}
}
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : IsVIPQueueEmpty ( )
2015-08-20 13:35:01 +03:00
{
2016-01-25 20:02:57 +03:00
for ( int i = 0 ; i < MAX_VIP_QUEUES ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
CBasePlayer * toCheck = m_pVIPQueue [ i ] ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( toCheck ! = NULL & & toCheck - > m_iTeam ! = CT )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ i ] = NULL ;
2015-08-20 13:35:01 +03:00
}
}
StackVIPQueue ( ) ;
2016-06-02 01:08:22 +03:00
return ( m_pVIPQueue [ 0 ] = = NULL & & m_pVIPQueue [ 1 ] = = NULL & & m_pVIPQueue [ 2 ] = = NULL & & m_pVIPQueue [ 3 ] = = NULL & & m_pVIPQueue [ 4 ] = = NULL ) ;
2015-08-20 13:35:01 +03:00
}
bool CHalfLifeMultiplay : : AddToVIPQueue ( CBasePlayer * toAdd )
{
2016-01-25 20:02:57 +03:00
for ( int i = 0 ; i < MAX_VIP_QUEUES ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
CBasePlayer * toCheck = m_pVIPQueue [ i ] ;
2015-08-20 13:35:01 +03:00
2016-02-04 03:18:26 +03:00
if ( toCheck ! = NULL & & toCheck - > m_iTeam ! = CT )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ i ] = NULL ;
2015-08-20 13:35:01 +03:00
}
}
StackVIPQueue ( ) ;
if ( toAdd - > m_iTeam = = CT )
{
int j ;
2016-02-04 03:18:26 +03:00
for ( j = 0 ; j < MAX_VIP_QUEUES ; + + j )
2015-08-02 20:45:57 +03:00
{
2016-06-02 01:08:22 +03:00
if ( m_pVIPQueue [ j ] = = toAdd )
2015-08-20 13:35:01 +03:00
{
ClientPrint ( toAdd - > pev , HUD_PRINTCENTER , " #Game_in_position " , UTIL_dtos1 ( j + 1 ) ) ;
return FALSE ;
}
2015-08-02 20:45:57 +03:00
}
2015-08-20 13:35:01 +03:00
2016-02-04 03:18:26 +03:00
for ( j = 0 ; j < MAX_VIP_QUEUES ; + + j )
2015-08-02 20:45:57 +03:00
{
2016-06-02 01:08:22 +03:00
if ( ! m_pVIPQueue [ j ] )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ j ] = toAdd ;
2015-08-20 13:35:01 +03:00
StackVIPQueue ( ) ;
ClientPrint ( toAdd - > pev , HUD_PRINTCENTER , " #Game_added_position " , UTIL_dtos1 ( j + 1 ) ) ;
return TRUE ;
}
2015-08-02 20:45:57 +03:00
}
2015-08-20 13:35:01 +03:00
ClientPrint ( toAdd - > pev , HUD_PRINTCENTER , " #All_VIP_Slots_Full " ) ;
2015-08-02 20:45:57 +03:00
}
return FALSE ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : ResetCurrentVIP ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
char * infobuffer = GET_INFO_BUFFER ( m_pVIP - > edict ( ) ) ;
2016-02-04 03:18:26 +03:00
int numSkins = g_bIsCzeroGame ? CZ_NUM_SKIN : CS_NUM_SKIN ;
2015-07-12 23:32:09 +03:00
2015-08-20 13:35:01 +03:00
switch ( RANDOM_LONG ( 0 , numSkins ) )
{
case 1 :
m_pVIP - > m_iModelName = MODEL_GSG9 ;
2016-05-30 14:19:56 +03:00
m_pVIP - > SetClientUserInfoModel ( infobuffer , " gsg9 " ) ;
2015-08-20 13:35:01 +03:00
break ;
case 2 :
m_pVIP - > m_iModelName = MODEL_SAS ;
2016-05-30 14:19:56 +03:00
m_pVIP - > SetClientUserInfoModel ( infobuffer , " sas " ) ;
2015-08-20 13:35:01 +03:00
break ;
case 3 :
m_pVIP - > m_iModelName = MODEL_GIGN ;
2016-05-30 14:19:56 +03:00
m_pVIP - > SetClientUserInfoModel ( infobuffer , " gign " ) ;
2015-08-20 13:35:01 +03:00
break ;
case 4 :
2016-02-04 03:18:26 +03:00
if ( g_bIsCzeroGame )
2015-08-20 13:35:01 +03:00
{
m_pVIP - > m_iModelName = MODEL_SPETSNAZ ;
2016-05-30 14:19:56 +03:00
m_pVIP - > SetClientUserInfoModel ( infobuffer , " spetsnaz " ) ;
2015-08-20 13:35:01 +03:00
break ;
}
default :
m_pVIP - > m_iModelName = MODEL_URBAN ;
2016-05-30 14:19:56 +03:00
m_pVIP - > SetClientUserInfoModel ( infobuffer , " urban " ) ;
2015-08-20 13:35:01 +03:00
break ;
}
2015-07-12 23:32:09 +03:00
2015-08-20 13:35:01 +03:00
m_pVIP - > m_bIsVIP = false ;
m_pVIP - > m_bNotKilled = false ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : PickNextVIP ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( ! IsVIPQueueEmpty ( ) )
{
2015-09-30 03:49:22 +03:00
// Remove the current VIP from his VIP status and make him a regular CT.
2015-08-20 13:35:01 +03:00
if ( m_pVIP ! = NULL )
{
ResetCurrentVIP ( ) ;
}
2015-07-12 23:32:09 +03:00
2016-01-25 20:02:57 +03:00
for ( int i = 0 ; i < MAX_VIP_QUEUES ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
if ( m_pVIPQueue [ i ] ! = NULL )
2015-08-20 13:35:01 +03:00
{
2016-06-02 01:08:22 +03:00
m_pVIP = m_pVIPQueue [ i ] ;
2015-08-20 13:35:01 +03:00
m_pVIP - > MakeVIP ( ) ;
2016-06-02 01:08:22 +03:00
m_pVIPQueue [ i ] = NULL ; // remove this player from the VIP queue
2015-09-30 03:49:22 +03:00
StackVIPQueue ( ) ; // and re-organize the queue
2015-08-20 13:35:01 +03:00
m_iConsecutiveVIP = 0 ;
2015-09-30 03:49:22 +03:00
return ;
2015-08-20 13:35:01 +03:00
}
}
}
2015-09-30 03:49:22 +03:00
// If it's been the same VIP for 3 rounds already.. then randomly pick a new one
else if ( m_iConsecutiveVIP > = 3 )
2015-08-20 13:35:01 +03:00
{
2016-03-17 20:44:52 +03:00
if ( + + m_iLastPick > m_iNumCT )
2015-08-20 13:35:01 +03:00
m_iLastPick = 1 ;
int iCount = 1 ;
2015-09-30 03:49:22 +03:00
CBaseEntity * pPlayer = NULL ;
CBasePlayer * player = NULL ;
CBasePlayer * pLastPlayer = NULL ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
while ( ( pPlayer ! = NULL ) & & ( ! FNullEnt ( pPlayer - > edict ( ) ) ) )
{
if ( ! ( pPlayer - > pev - > flags & FL_DORMANT ) )
2015-08-20 13:35:01 +03:00
{
2016-03-17 20:44:52 +03:00
player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
if ( player - > m_iTeam = = CT & & iCount = = m_iLastPick )
2015-08-20 13:35:01 +03:00
{
if ( player = = m_pVIP & & pLastPlayer ! = NULL )
player = pLastPlayer ;
2015-09-30 03:49:22 +03:00
// Remove the current VIP from his VIP status and make him a regular CT.
2015-08-20 13:35:01 +03:00
if ( m_pVIP ! = NULL )
{
ResetCurrentVIP ( ) ;
}
player - > MakeVIP ( ) ;
m_iConsecutiveVIP = 0 ;
2015-09-30 03:49:22 +03:00
return ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
else if ( player - > m_iTeam = = CT )
2016-02-04 03:18:26 +03:00
+ + iCount ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
if ( player - > m_iTeam ! = SPECTATOR )
pLastPlayer = player ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ;
2015-08-20 13:35:01 +03:00
}
}
2015-09-30 03:49:22 +03:00
// There is no VIP and there is no one waiting to be the VIP.. therefore just pick the first CT player we can find.
else if ( m_pVIP = = NULL )
2015-08-20 13:35:01 +03:00
{
CBaseEntity * pPlayer = NULL ;
2015-09-30 03:49:22 +03:00
CBasePlayer * player = NULL ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ;
while ( ( pPlayer ! = NULL ) & & ( ! FNullEnt ( pPlayer - > edict ( ) ) ) )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
if ( pPlayer - > pev - > flags ! = FL_DORMANT )
2015-08-20 13:35:01 +03:00
{
2016-03-17 20:44:52 +03:00
player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
if ( player - > m_iTeam = = CT )
{
player - > MakeVIP ( ) ;
m_iConsecutiveVIP = 0 ;
return ;
}
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ;
2015-08-20 13:35:01 +03:00
}
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( Think ) ( )
2015-08-20 13:35:01 +03:00
{
MonitorTutorStatus ( ) ;
m_VoiceGameMgr . Update ( gpGlobals - > frametime ) ;
if ( sv_clienttrace - > value ! = 1.0f )
{
CVAR_SET_FLOAT ( " sv_clienttrace " , 1 ) ;
}
if ( ! m_fRoundCount )
{
2015-09-30 03:49:22 +03:00
// intialize the timer time stamps, this happens once only
m_fIntroRoundCount = m_fRoundCount = gpGlobals - > time ;
2015-08-20 13:35:01 +03:00
}
if ( m_flForceCameraValue ! = forcecamera . value
| | m_flForceChaseCamValue ! = forcechasecam . value
| | m_flFadeToBlackValue ! = fadetoblack . value )
{
MESSAGE_BEGIN ( MSG_ALL , gmsgForceCam ) ;
WRITE_BYTE ( forcecamera . value ! = 0 ) ;
WRITE_BYTE ( forcechasecam . value ! = 0 ) ;
WRITE_BYTE ( fadetoblack . value ! = 0 ) ;
MESSAGE_END ( ) ;
m_flForceCameraValue = forcecamera . value ;
m_flForceChaseCamValue = forcechasecam . value ;
m_flFadeToBlackValue = fadetoblack . value ;
}
2015-09-30 03:49:22 +03:00
// Check game rules
if ( CheckGameOver ( ) )
2015-08-20 13:35:01 +03:00
return ;
2015-09-30 03:49:22 +03:00
// have we hit the timelimit?
if ( CheckTimeLimit ( ) )
return ;
2015-08-20 13:35:01 +03:00
if ( ! IsCareer ( ) )
{
2015-09-30 03:49:22 +03:00
// have we hit the max rounds?
if ( CheckMaxRounds ( ) )
2015-08-20 13:35:01 +03:00
return ;
2015-09-30 03:49:22 +03:00
if ( CheckWinLimit ( ) )
2015-08-20 13:35:01 +03:00
return ;
}
if ( ! IsCareer ( ) | | ( m_fCareerMatchMenuTime < = 0.0 | | m_fCareerMatchMenuTime > = gpGlobals - > time ) )
{
if ( m_iStoredSpectValue ! = allow_spectators . value )
{
m_iStoredSpectValue = allow_spectators . value ;
MESSAGE_BEGIN ( MSG_ALL , gmsgAllowSpec ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( allow_spectators . value ) ) ;
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
}
2015-09-30 03:49:22 +03:00
// Check for the end of the round.
2015-08-20 13:35:01 +03:00
if ( IsFreezePeriod ( ) )
{
2015-09-30 03:49:22 +03:00
CheckFreezePeriodExpired ( ) ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
else
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
CheckRoundTimeExpired ( ) ;
2015-08-20 13:35:01 +03:00
}
if ( m_fTeamCount ! = 0.0f & & m_fTeamCount < = gpGlobals - > time )
{
if ( ! IsCareer ( ) | | ! m_fCareerRoundMenuTime )
{
RestartRound ( ) ;
}
2015-12-05 22:40:30 +03:00
else if ( TheCareerTasks ! = NULL )
2015-08-20 13:35:01 +03:00
{
bool isBotSpeaking = false ;
2016-02-23 02:13:52 +03:00
if ( m_fTeamCount + 10.0f > gpGlobals - > time )
2015-08-20 13:35:01 +03:00
{
isBotSpeaking = IsBotSpeaking ( ) ;
}
if ( ! isBotSpeaking )
{
if ( m_fCareerMatchMenuTime = = 0.0f & & m_iCareerMatchWins )
{
bool canCTsWin = true ;
bool canTsWin = true ;
if ( m_iNumCTWins < m_iCareerMatchWins | | ( m_iNumCTWins - m_iNumTerroristWins < m_iRoundWinDifference ) )
canCTsWin = false ;
if ( m_iNumTerroristWins < m_iCareerMatchWins | | ( m_iNumTerroristWins - m_iNumCTWins < m_iRoundWinDifference ) )
canTsWin = false ;
if ( ! Q_strcmp ( humans_join_team . string , " CT " ) )
{
if ( ! TheCareerTasks - > AreAllTasksComplete ( ) )
{
canCTsWin = false ;
}
}
else if ( ! TheCareerTasks - > AreAllTasksComplete ( ) )
{
canTsWin = false ;
}
if ( canCTsWin | | canTsWin )
{
m_fCareerRoundMenuTime = 0 ;
m_fCareerMatchMenuTime = gpGlobals - > time + 3.0f ;
return ;
}
}
m_bFreezePeriod = TRUE ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( pPlayer ! = NULL & & ! pPlayer - > IsBot ( ) )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgCZCareerHUD , NULL , pPlayer - > pev ) ;
WRITE_STRING ( " ROUND " ) ;
WRITE_LONG ( m_iNumCTWins ) ;
WRITE_LONG ( m_iNumTerroristWins ) ;
WRITE_BYTE ( m_iCareerMatchWins ) ;
WRITE_BYTE ( m_iRoundWinDifference ) ;
WRITE_BYTE ( m_iRoundWinStatus ) ;
MESSAGE_END ( ) ;
pPlayer - > m_iHideHUD | = HIDEHUD_ALL ;
m_fTeamCount = gpGlobals - > time + 100000.0 ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " Career Round %d %d %d %d \n " , m_iRoundWinStatus , m_iNumCTWins , m_iNumTerroristWins , TheCareerTasks - > AreAllTasksComplete ( ) ) ;
2015-08-20 13:35:01 +03:00
break ;
}
}
m_fCareerRoundMenuTime = 0 ;
}
}
2015-09-30 03:49:22 +03:00
if ( TheTutor ! = NULL )
2015-08-20 13:35:01 +03:00
{
TheTutor - > PurgeMessages ( ) ;
}
}
2015-09-30 03:49:22 +03:00
CheckLevelInitialized ( ) ;
2015-08-20 13:35:01 +03:00
if ( gpGlobals - > time > m_tmNextPeriodicThink )
{
2015-09-30 03:49:22 +03:00
CheckRestartRound ( ) ;
2015-08-20 13:35:01 +03:00
m_tmNextPeriodicThink = gpGlobals - > time + 1.0f ;
if ( g_psv_accelerate - > value ! = 5.0f )
{
2016-02-23 02:13:52 +03:00
CVAR_SET_FLOAT ( " sv_accelerate " , 5.0f ) ;
2015-08-20 13:35:01 +03:00
}
if ( g_psv_friction - > value ! = 4.0f )
{
2016-02-23 02:13:52 +03:00
CVAR_SET_FLOAT ( " sv_friction " , 4.0f ) ;
2015-08-20 13:35:01 +03:00
}
if ( g_psv_stopspeed - > value ! = 75.0f )
{
2016-02-23 02:13:52 +03:00
CVAR_SET_FLOAT ( " sv_stopspeed " , 75.0f ) ;
2015-08-20 13:35:01 +03:00
}
2016-02-23 02:13:52 +03:00
m_iMaxRounds = int ( maxrounds . value ) ;
2015-08-20 13:35:01 +03:00
if ( m_iMaxRounds < 0 )
{
m_iMaxRounds = 0 ;
CVAR_SET_FLOAT ( " mp_maxrounds " , 0 ) ;
}
2016-02-23 02:13:52 +03:00
m_iMaxRoundsWon = int ( winlimit . value ) ;
2015-08-20 13:35:01 +03:00
if ( m_iMaxRoundsWon < 0 )
{
m_iMaxRoundsWon = 0 ;
CVAR_SET_FLOAT ( " mp_winlimit " , 0 ) ;
}
}
}
else
{
2015-12-09 01:39:54 +03:00
if ( m_fCareerMatchMenuTime + 10 < = gpGlobals - > time | | ! IsBotSpeaking ( ) )
{
UTIL_CareerDPrintf ( " Ending career match...one team has won the specified number of rounds \n " ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgCZCareer ) ;
WRITE_STRING ( " MATCH " ) ;
WRITE_LONG ( m_iNumCTWins ) ;
WRITE_LONG ( m_iNumTerroristWins ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgCZCareerHUD ) ;
WRITE_STRING ( " MATCH " ) ;
WRITE_LONG ( m_iNumCTWins ) ;
WRITE_LONG ( m_iNumTerroristWins ) ;
WRITE_BYTE ( m_iCareerMatchWins ) ;
WRITE_BYTE ( m_iRoundWinDifference ) ;
WRITE_BYTE ( m_iRoundWinStatus ) ;
MESSAGE_END ( ) ;
UTIL_LogPrintf ( " Career Match %d %d %d %d \n " , m_iRoundWinStatus , m_iNumCTWins , m_iNumTerroristWins , TheCareerTasks - > AreAllTasksComplete ( ) ) ;
SERVER_COMMAND ( " setpause \n " ) ;
2015-08-20 13:35:01 +03:00
}
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : CheckGameOver ( )
2015-09-30 03:49:22 +03:00
{
// someone else quit the game already
if ( g_fGameOver )
{
2016-02-23 02:13:52 +03:00
int time = int ( CVAR_GET_FLOAT ( " mp_chattime " ) ) ;
2015-09-30 03:49:22 +03:00
if ( time < 1 )
CVAR_SET_STRING ( " mp_chattime " , " 1 " ) ;
else if ( time > MAX_INTERMISSION_TIME )
CVAR_SET_STRING ( " mp_chattime " , UTIL_dtos1 ( MAX_INTERMISSION_TIME ) ) ;
// bounds check
m_flIntermissionEndTime = m_flIntermissionStartTime + mp_chattime . value ;
// check to see if we should change levels now
if ( m_flIntermissionEndTime < gpGlobals - > time & & ! IsCareer ( ) )
{
2016-01-28 05:51:34 +03:00
if ( ! UTIL_HumansInGame ( ) // if only bots, just change immediately
2015-09-30 03:49:22 +03:00
| | m_iEndIntermissionButtonHit // check that someone has pressed a key, or the max intermission time is over
| | ( ( m_flIntermissionStartTime + MAX_INTERMISSION_TIME ) < gpGlobals - > time ) )
{
// intermission is over
ChangeLevel ( ) ;
}
}
return true ;
}
return false ;
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : CheckTimeLimit ( )
2015-09-30 03:49:22 +03:00
{
float fTimeLimit = timelimit . value ;
if ( fTimeLimit < 0 )
{
CVAR_SET_FLOAT ( " mp_timelimit " , 0 ) ;
return false ;
}
if ( ! IsCareer ( ) )
{
2015-12-09 01:39:54 +03:00
if ( fTimeLimit ! = 0.0f )
{
g_flTimeLimit = g_flResetTime + fTimeLimit * 60.0f ;
2015-09-30 03:49:22 +03:00
}
if ( fTimeLimit > 0 & & gpGlobals - > time > = g_flTimeLimit )
{
ALERT ( at_console , " Changing maps because time limit has been met \n " ) ;
GoToIntermission ( ) ;
return true ;
}
}
return false ;
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : CheckMaxRounds ( )
2015-09-30 03:49:22 +03:00
{
if ( m_iMaxRounds ! = 0 & & m_iTotalRoundsPlayed > = m_iMaxRounds )
{
ALERT ( at_console , " Changing maps due to maximum rounds have been met \n " ) ;
GoToIntermission ( ) ;
return true ;
}
return false ;
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : CheckWinLimit ( )
2015-09-30 03:49:22 +03:00
{
// has one team won the specified number of rounds?
if ( m_iMaxRoundsWon ! = 0 & & ( m_iNumCTWins > = m_iMaxRoundsWon | | m_iNumTerroristWins > = m_iMaxRoundsWon ) )
{
if ( ( m_iNumCTWins - m_iNumTerroristWins > = m_iRoundWinDifference ) | | ( m_iNumTerroristWins - m_iNumCTWins > = m_iRoundWinDifference ) )
{
ALERT ( at_console , " Changing maps...one team has won the specified number of rounds \n " ) ;
GoToIntermission ( ) ;
return true ;
}
}
return false ;
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CheckFreezePeriodExpired ( )
2015-09-30 03:49:22 +03:00
{
if ( TimeRemaining ( ) > 0 )
return ;
// Log this information
UTIL_LogPrintf ( " World triggered \" Round_Start \" \n " ) ;
// Freeze period expired: kill the flag
m_bFreezePeriod = FALSE ;
char CT_sentence [ 40 ] ;
char T_sentence [ 40 ] ;
switch ( RANDOM_LONG ( 0 , 3 ) )
{
case 0 :
Q_strncpy ( CT_sentence , " %!MRAD_MOVEOUT " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_MOVEOUT " , sizeof ( T_sentence ) ) ;
break ;
case 1 :
Q_strncpy ( CT_sentence , " %!MRAD_LETSGO " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_LETSGO " , sizeof ( T_sentence ) ) ;
break ;
case 2 :
Q_strncpy ( CT_sentence , " %!MRAD_LOCKNLOAD " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_LOCKNLOAD " , sizeof ( T_sentence ) ) ;
break ;
default :
Q_strncpy ( CT_sentence , " %!MRAD_GO " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_GO " , sizeof ( T_sentence ) ) ;
break ;
}
// More specific radio commands for the new scenarios : Prison & Assasination
if ( m_bMapHasEscapeZone )
{
Q_strncpy ( CT_sentence , " %!MRAD_ELIM " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_GETOUT " , sizeof ( T_sentence ) ) ;
}
else if ( m_iMapHasVIPSafetyZone = = MAP_HAVE_VIP_SAFETYZONE_YES )
{
Q_strncpy ( CT_sentence , " %!MRAD_VIP " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_LOCKNLOAD " , sizeof ( T_sentence ) ) ;
}
// Reset the round time
m_fRoundCount = gpGlobals - > time ;
// in seconds
m_iRoundTimeSecs = m_iRoundTime ;
bool bCTPlayed = false ;
bool bTPlayed = false ;
2015-12-05 22:40:30 +03:00
if ( TheCareerTasks ! = NULL )
{
TheCareerTasks - > HandleEvent ( EVENT_ROUND_START ) ;
}
2015-09-30 03:49:22 +03:00
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * plr = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( ! plr | | plr - > pev - > flags = = FL_DORMANT )
{
continue ;
}
if ( plr - > m_iJoiningState = = JOINED )
{
if ( plr - > m_iTeam = = CT & & ! bCTPlayed )
{
2016-01-28 05:51:34 +03:00
plr - > Radio ( CT_sentence ) ;
2015-09-30 03:49:22 +03:00
bCTPlayed = true ;
}
else if ( plr - > m_iTeam = = TERRORIST & & ! bTPlayed )
{
2016-01-28 05:51:34 +03:00
plr - > Radio ( T_sentence ) ;
2015-09-30 03:49:22 +03:00
bTPlayed = true ;
}
if ( plr - > m_iTeam ! = SPECTATOR )
{
plr - > ResetMaxSpeed ( ) ;
plr - > m_bCanShoot = true ;
}
}
plr - > SyncRoundTimer ( ) ;
}
2015-12-05 22:40:30 +03:00
if ( TheBots ! = NULL )
{
TheBots - > OnEvent ( EVENT_ROUND_START ) ;
}
if ( TheCareerTasks ! = NULL )
{
TheCareerTasks - > HandleEvent ( EVENT_ROUND_START ) ;
}
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
bool CHalfLifeMultiplay : : Target_Saved_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ RR_TARGET_BOMB_SAVED ] ;
2016-04-24 16:52:16 +03:00
m_iNumCTWins + + ;
EndRoundMessage ( " #Target_Saved " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
UpdateTeamScores ( ) ;
MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound ( TERRORIST ) ;
return true ;
}
bool CHalfLifeMultiplay : : Hostage_NotRescued_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_HOSTAGE_NOT_RESCUED ] ;
2016-04-24 16:52:16 +03:00
m_iNumTerroristWins + + ;
EndRoundMessage ( " #Hostages_Not_Rescued " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
UpdateTeamScores ( ) ;
MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound ( CT ) ;
return true ;
}
bool CHalfLifeMultiplay : : Prison_NotEscaped_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " ctwin " ) ;
m_iNumCTWins + + ;
EndRoundMessage ( " #Terrorists_Not_Escaped " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
UpdateTeamScores ( ) ;
return true ;
}
bool CHalfLifeMultiplay : : VIP_NotEscaped_internal ( int winStatus , ScenarioEventEndRound event , float tmDelay ) {
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_VIP_NOT_ESCAPED ] ;
2016-04-24 16:52:16 +03:00
m_iNumTerroristWins + + ;
EndRoundMessage ( " #VIP_Not_Escaped " , event ) ;
TerminateRound ( tmDelay , winStatus ) ;
if ( IsCareer ( ) )
{
QueueCareerRoundEndMenu ( tmDelay , winStatus ) ;
}
UpdateTeamScores ( ) ;
return true ;
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CheckRoundTimeExpired ( )
2015-09-30 03:49:22 +03:00
{
2016-04-05 03:12:05 +03:00
if ( HasRoundInfinite ( true ) )
2015-12-29 01:54:08 +03:00
return ;
2015-09-30 03:49:22 +03:00
if ( ! HasRoundTimeExpired ( ) )
return ;
#if 0
// Round time expired
float flEndRoundTime ;
// Check to see if there's still a live C4 hanging around.. if so, wait until this C4 blows before ending the round
CGrenade * C4 = ( CGrenade * ) UTIL_FindEntityByClassname ( NULL , " grenade " ) ;
if ( C4 ! = NULL )
{
if ( ! C4 - > m_bJustBlew )
flEndRoundTime = C4 - > m_flC4Blow ;
else
2016-03-17 20:44:52 +03:00
flEndRoundTime = gpGlobals - > time + 5.0f ;
2015-09-30 03:49:22 +03:00
}
# endif
// New code to get rid of round draws!!
if ( m_bMapHasBombTarget )
{
2016-04-24 16:52:16 +03:00
if ( ! g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Target_Saved_internal , this , WINSTATUS_CTS , ROUND_TARGET_SAVED , 5 ) )
return ;
2015-09-30 03:49:22 +03:00
}
else if ( UTIL_FindEntityByClassname ( NULL , " hostage_entity " ) ! = NULL )
{
2016-04-24 16:52:16 +03:00
if ( ! g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Hostage_NotRescued_internal , this , WINSTATUS_TERRORISTS , ROUND_HOSTAGE_NOT_RESCUED , 5 ) )
return ;
2015-09-30 03:49:22 +03:00
}
else if ( m_bMapHasEscapeZone )
{
2016-04-24 16:52:16 +03:00
if ( ! g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : Prison_NotEscaped_internal , this , WINSTATUS_CTS , ROUND_TERRORISTS_NOT_ESCAPED , 5 ) )
return ;
2015-09-30 03:49:22 +03:00
}
else if ( m_iMapHasVIPSafetyZone = = MAP_HAVE_VIP_SAFETYZONE_YES )
{
2016-04-24 16:52:16 +03:00
if ( ! g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : VIP_NotEscaped_internal , this , WINSTATUS_TERRORISTS , ROUND_VIP_NOT_ESCAPED , 5 ) )
return ;
2015-09-30 03:49:22 +03:00
}
// This is done so that the portion of code has enough time to do it's thing.
m_fRoundCount = gpGlobals - > time + 60.0f ;
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CheckLevelInitialized ( )
2015-09-30 03:49:22 +03:00
{
if ( ! m_bLevelInitialized )
{
// Count the number of spawn points for each team
// This determines the maximum number of players allowed on each
CBaseEntity * ent = NULL ;
m_iSpawnPointCount_Terrorist = 0 ;
m_iSpawnPointCount_CT = 0 ;
while ( ( ent = UTIL_FindEntityByClassname ( ent , " info_player_deathmatch " ) ) ! = NULL )
2016-02-04 03:18:26 +03:00
+ + m_iSpawnPointCount_Terrorist ;
2015-09-30 03:49:22 +03:00
while ( ( ent = UTIL_FindEntityByClassname ( ent , " info_player_start " ) ) ! = NULL )
2016-02-04 03:18:26 +03:00
+ + m_iSpawnPointCount_CT ;
2015-09-30 03:49:22 +03:00
m_bLevelInitialized = true ;
}
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CheckRestartRound ( )
2015-09-30 03:49:22 +03:00
{
// Restart the round if specified by the server
2016-02-23 02:13:52 +03:00
int iRestartDelay = int ( restartround . value ) ;
2015-09-30 03:49:22 +03:00
if ( ! iRestartDelay )
{
iRestartDelay = sv_restart . value ;
}
if ( iRestartDelay > 0 )
{
2016-05-23 01:51:21 +03:00
# ifndef REGAMEDLL_ADD
2015-09-30 03:49:22 +03:00
if ( iRestartDelay > 60 )
iRestartDelay = 60 ;
2016-05-23 01:51:21 +03:00
# endif
2015-09-30 03:49:22 +03:00
// log the restart
UTIL_LogPrintf ( " World triggered \" Restart_Round_(%i_%s) \" \n " , iRestartDelay , ( iRestartDelay = = 1 ) ? " second " : " seconds " ) ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " Team \" CT \" scored \" %i \" with \" %i \" players \n " , m_iNumCTWins , m_iNumCT ) ;
UTIL_LogPrintf ( " Team \" TERRORIST \" scored \" %i \" with \" %i \" players \n " , m_iNumTerroristWins , m_iNumTerrorist ) ;
2015-09-30 03:49:22 +03:00
// let the players know
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Game_will_restart_in " , UTIL_dtos1 ( iRestartDelay ) , ( iRestartDelay = = 1 ) ? " SECOND " : " SECONDS " ) ;
UTIL_ClientPrintAll ( HUD_PRINTCONSOLE , " #Game_will_restart_in_console " , UTIL_dtos1 ( iRestartDelay ) , ( iRestartDelay = = 1 ) ? " SECOND " : " SECONDS " ) ;
m_fTeamCount = gpGlobals - > time + iRestartDelay ;
m_bCompleteReset = true ;
CVAR_SET_FLOAT ( " sv_restartround " , 0 ) ;
CVAR_SET_FLOAT ( " sv_restart " , 0 ) ;
CareerRestart ( ) ;
}
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : HasRoundTimeExpired ( )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
// We haven't completed other objectives, so go for this!.
2016-01-19 14:54:31 +03:00
if ( TimeRemaining ( ) > 0 | | m_iRoundWinStatus ! = WINNER_NONE )
2015-08-20 13:35:01 +03:00
{
return false ;
}
2016-01-28 05:51:34 +03:00
// If the bomb is planted, don't let the round timer end the round.
// keep going until the bomb explodes or is defused
2015-08-20 13:35:01 +03:00
if ( ! IsBombPlanted ( ) )
{
2016-01-28 05:51:34 +03:00
if ( cv_bot_nav_edit . value = = 0.0f | | IS_DEDICATED_SERVER ( ) | | UTIL_HumansInGame ( ) ! = 1 )
2015-08-20 13:35:01 +03:00
{
return true ;
}
}
return false ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : IsBombPlanted ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( m_bMapHasBombTarget )
{
CGrenade * bomb = NULL ;
2016-01-14 15:59:01 +03:00
while ( ( bomb = ( CGrenade * ) UTIL_FindEntityByClassname ( bomb , " grenade " ) ) ! = NULL )
2015-08-20 13:35:01 +03:00
{
if ( bomb - > m_bIsC4 )
{
return true ;
}
}
}
return false ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 05:51:34 +03:00
// living players on the given team need to be marked as not receiving any money
// next round.
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound ( int iTeam )
2015-07-12 23:32:09 +03:00
{
2016-01-14 15:59:01 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * player = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( ! player | | FNullEnt ( player - > pev ) )
continue ;
if ( player - > m_iTeam = = iTeam )
{
if ( player - > pev - > health > 0 & & player - > pev - > deadflag = = DEAD_NO )
{
player - > m_bReceivesNoMoneyNextRound = true ;
}
}
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CareerRestart ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
g_fGameOver = FALSE ;
if ( m_fTeamCount = = 0.0f )
{
m_fTeamCount = gpGlobals - > time + 1.0f ;
}
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
// for reset everything
m_bCompleteReset = true ;
m_fCareerRoundMenuTime = 0 ;
m_fCareerMatchMenuTime = 0 ;
2015-12-05 22:40:30 +03:00
if ( TheCareerTasks ! = NULL )
{
TheCareerTasks - > Reset ( false ) ;
}
2015-08-20 13:35:01 +03:00
m_bSkipSpawn = false ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * player = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( ! player | | FNullEnt ( player - > pev ) )
continue ;
if ( ! player - > IsBot ( ) )
{
player - > ForceClientDllUpdate ( ) ;
}
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( IsMultiplayer ) ( )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( IsDeathmatch ) ( )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( IsCoOp ) ( )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > coop ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FShouldSwitchWeapon , ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon ) , pPlayer , pWeapon ) ;
BOOL CHalfLifeMultiplay : : __API_VHOOK ( FShouldSwitchWeapon ) ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
if ( ! pWeapon - > CanDeploy ( ) )
return FALSE ;
if ( ! pPlayer - > m_pActiveItem )
return TRUE ;
if ( ! pPlayer - > m_iAutoWepSwitch )
return FALSE ;
if ( ! pPlayer - > m_pActiveItem - > CanHolster ( ) )
return FALSE ;
if ( pWeapon - > iWeight ( ) > pPlayer - > m_pActiveItem - > iWeight ( ) )
return TRUE ;
2015-07-12 23:32:09 +03:00
return FALSE ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , GetNextBestWeapon , ( CBasePlayer * pPlayer , CBasePlayerItem * pCurrentWeapon ) , pPlayer , pCurrentWeapon ) ;
BOOL CHalfLifeMultiplay : : __API_VHOOK ( GetNextBestWeapon ) ( CBasePlayer * pPlayer , CBasePlayerItem * pCurrentWeapon )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
CBasePlayerItem * pCheck ;
CBasePlayerItem * pBest ; // this will be used in the event that we don't find a weapon in the same category.
int iBestWeight ;
int i ;
2015-06-30 12:46:07 +03:00
if ( ! pCurrentWeapon - > CanHolster ( ) )
2015-09-30 03:49:22 +03:00
{
// can't put this gun away right now, so can't switch.
2015-06-30 12:46:07 +03:00
return FALSE ;
2015-09-30 03:49:22 +03:00
}
2015-06-30 12:46:07 +03:00
2015-09-30 03:49:22 +03:00
iBestWeight = - 1 ; // no weapon lower than -1 can be autoswitched to
pBest = NULL ;
2015-06-30 12:46:07 +03:00
2016-01-25 20:02:57 +03:00
for ( i = 0 ; i < MAX_ITEM_TYPES ; + + i )
2015-06-30 12:46:07 +03:00
{
2015-09-30 03:49:22 +03:00
pCheck = pPlayer - > m_rgpPlayerItems [ i ] ;
2015-08-20 13:35:01 +03:00
while ( pCheck ! = NULL )
2015-06-30 12:46:07 +03:00
{
2015-09-30 03:49:22 +03:00
// don't reselect the weapon we're trying to get rid of
if ( pCheck - > iWeight ( ) > iBestWeight & & pCheck ! = pCurrentWeapon )
2015-06-30 12:46:07 +03:00
{
2015-09-30 03:49:22 +03:00
//ALERT (at_console, "Considering %s\n", STRING(pCheck->pev->classname));
// we keep updating the 'best' weapon just in case we can't find a weapon of the same weight
// that the player was using. This will end up leaving the player with his heaviest-weighted
// weapon.
if ( pCheck - > CanDeploy ( ) )
{
// if this weapon is useable, flag it as the best
iBestWeight = pCheck - > iWeight ( ) ;
pBest = pCheck ;
}
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
2015-06-30 12:46:07 +03:00
pCheck = pCheck - > m_pNext ;
}
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// if we make it here, we've checked all the weapons and found no useable
// weapon in the same catagory as the current weapon.
// if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always
// at least get the crowbar, but ya never know.
if ( pBest = = NULL )
2015-06-30 12:46:07 +03:00
{
2015-09-30 03:49:22 +03:00
return FALSE ;
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
pPlayer - > SwitchWeapon ( pBest ) ;
return TRUE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( ClientCommand_DeadOrAlive ) ( CBasePlayer * pPlayer , const char * pcmd )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return m_VoiceGameMgr . ClientCommand ( pPlayer , pcmd ) ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( ClientCommand ) ( CBasePlayer * pPlayer , const char * pcmd )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return FALSE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( ClientConnected ) ( edict_t * pEntity , const char * pszName , const char * pszAddress , char * szRejectReason )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
m_VoiceGameMgr . ClientConnected ( pEntity ) ;
return TRUE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( UpdateGameMode ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgGameMode , NULL , pPlayer - > edict ( ) ) ;
WRITE_BYTE ( 1 ) ;
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( InitHUD ) ( CBasePlayer * pl )
{
int i ;
// notify other clients of player joining the game
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><> \" entered the game \n " , STRING ( pl - > pev - > netname ) , GETPLAYERUSERID ( pl - > edict ( ) ) , GETPLAYERAUTHID ( pl - > edict ( ) ) ) ;
2015-08-20 13:35:01 +03:00
UpdateGameMode ( pl ) ;
if ( ! g_flWeaponCheat )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgViewMode , NULL , pl - > edict ( ) ) ;
MESSAGE_END ( ) ;
}
2015-09-30 03:49:22 +03:00
// sending just one score makes the hud scoreboard active; otherwise
2015-08-20 13:35:01 +03:00
// it is just disabled for single play
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreInfo , NULL , pl - > edict ( ) ) ;
WRITE_BYTE ( ENTINDEX ( pl - > edict ( ) ) ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( pl - > m_iTeam ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgShadowIdx , NULL , pl - > edict ( ) ) ;
WRITE_LONG ( g_iShadowSprite ) ;
MESSAGE_END ( ) ;
if ( IsCareer ( ) )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgCZCareer , NULL , pl - > edict ( ) ) ;
WRITE_STRING ( " START " ) ;
WRITE_SHORT ( m_iRoundTime ) ;
MESSAGE_END ( ) ;
}
else
SendMOTDToClient ( pl - > edict ( ) ) ;
// loop through all active players and send their score info to the new client
2016-01-25 20:02:57 +03:00
for ( i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// FIXME: Probably don't need to cast this just to read m_iDeaths
2016-05-31 17:04:51 +03:00
CBasePlayer * plr = UTIL_PlayerByIndex ( i ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( plr ! = NULL )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreInfo , NULL , pl - > edict ( ) ) ;
WRITE_BYTE ( i ) ; // client number
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( plr - > pev - > frags ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_SHORT ( plr - > m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( plr - > m_iTeam ) ;
MESSAGE_END ( ) ;
}
}
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , NULL , pl - > edict ( ) ) ;
WRITE_STRING ( " TERRORIST " ) ;
WRITE_SHORT ( m_iNumTerroristWins ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , NULL , pl - > edict ( ) ) ;
WRITE_STRING ( " CT " ) ;
WRITE_SHORT ( m_iNumCTWins ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgAllowSpec , NULL , pl - > edict ( ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( allow_spectators . value ) ) ;
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgForceCam , NULL , pl - > edict ( ) ) ;
WRITE_BYTE ( forcecamera . value ! = 0 ) ;
WRITE_BYTE ( forcechasecam . value ! = 0 ) ;
WRITE_BYTE ( fadetoblack . value ! = 0 ) ;
MESSAGE_END ( ) ;
if ( g_fGameOver )
{
MESSAGE_BEGIN ( MSG_ONE , SVC_INTERMISSION , NULL , pl - > edict ( ) ) ;
MESSAGE_END ( ) ;
}
2016-01-25 20:02:57 +03:00
for ( i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * plr = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
if ( plr ! = NULL )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamInfo , NULL , pl - > edict ( ) ) ;
WRITE_BYTE ( plr - > entindex ( ) ) ;
2016-05-04 00:53:03 +03:00
WRITE_STRING ( GetTeamName ( plr - > m_iTeam ) ) ;
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
plr - > SetScoreboardAttributes ( pl ) ;
if ( i ! = pl - > entindex ( ) )
{
if ( plr - > pev - > flags = = FL_DORMANT )
continue ;
if ( plr - > pev - > deadflag = = DEAD_NO )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgRadar , NULL , pl - > edict ( ) ) ;
WRITE_BYTE ( plr - > entindex ( ) ) ;
WRITE_COORD ( plr - > pev - > origin . x ) ;
WRITE_COORD ( plr - > pev - > origin . y ) ;
WRITE_COORD ( plr - > pev - > origin . z ) ;
MESSAGE_END ( ) ;
}
}
}
}
2015-11-06 17:58:48 +03:00
if ( m_bBombDropped )
2015-08-20 13:35:01 +03:00
{
CBaseEntity * pWeaponC4 = UTIL_FindEntityByClassname ( NULL , " weapon_c4 " ) ;
if ( pWeaponC4 ! = NULL )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgBombDrop , NULL , pl - > edict ( ) ) ;
WRITE_COORD ( pWeaponC4 - > pev - > origin . x ) ;
WRITE_COORD ( pWeaponC4 - > pev - > origin . y ) ;
WRITE_COORD ( pWeaponC4 - > pev - > origin . z ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
}
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( ClientDisconnected ) ( edict_t * pClient )
{
if ( pClient ! = NULL )
{
2016-01-25 20:02:57 +03:00
CBasePlayer * pPlayer = static_cast < CBasePlayer * > ( CBaseEntity : : Instance ( pClient ) ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( pPlayer ! = NULL )
{
pPlayer - > has_disconnected = true ;
pPlayer - > pev - > deadflag = DEAD_DEAD ;
pPlayer - > SetScoreboardAttributes ( ) ;
if ( pPlayer - > m_bHasC4 )
{
pPlayer - > DropPlayerItem ( " weapon_c4 " ) ;
}
if ( pPlayer - > m_bHasDefuser )
{
pPlayer - > DropPlayerItem ( " item_thighpack " ) ;
}
if ( pPlayer - > m_bIsVIP )
{
m_pVIP = NULL ;
}
pPlayer - > m_iCurrentKickVote = 0 ;
if ( pPlayer - > m_iMapVote )
{
2016-02-04 03:18:26 +03:00
- - m_iMapVotes [ pPlayer - > m_iMapVote ] ;
2015-08-20 13:35:01 +03:00
if ( m_iMapVotes [ pPlayer - > m_iMapVote ] < 0 )
{
m_iMapVotes [ pPlayer - > m_iMapVote ] = 0 ;
}
}
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( pClient ) ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamInfo ) ;
WRITE_BYTE ( ENTINDEX ( pClient ) ) ;
WRITE_STRING ( " UNASSIGNED " ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgLocation ) ;
WRITE_BYTE ( ENTINDEX ( pClient ) ) ;
WRITE_STRING ( " " ) ;
MESSAGE_END ( ) ;
char * team = GetTeam ( pPlayer - > m_iTeam ) ;
FireTargets ( " game_playerleave " , pPlayer , pPlayer , USE_TOGGLE , 0 ) ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" disconnected \n " , STRING ( pPlayer - > pev - > netname ) , GETPLAYERUSERID ( pPlayer - > edict ( ) ) , GETPLAYERAUTHID ( pPlayer - > edict ( ) ) , team ) ;
2015-08-20 13:35:01 +03:00
// destroy all of the players weapons and items
pPlayer - > RemoveAllItems ( TRUE ) ;
if ( pPlayer - > m_pObserver ! = NULL )
{
pPlayer - > m_pObserver - > SUB_Remove ( ) ;
}
CBasePlayer * client = NULL ;
while ( ( client = ( CBasePlayer * ) UTIL_FindEntityByClassname ( client , " player " ) ) ! = NULL )
{
if ( FNullEnt ( client - > edict ( ) ) )
break ;
if ( ! client - > pev | | client = = pPlayer )
continue ;
if ( client - > m_hObserverTarget = = pPlayer )
{
int iMode = client - > pev - > iuser1 ;
client - > pev - > iuser1 = OBS_NONE ;
client - > Observer_SetMode ( iMode ) ;
}
}
}
}
CheckWinConditions ( ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( float , CHalfLifeMultiplay , CSGameRules , FlPlayerFallDamage , ( CBasePlayer * pPlayer ) , pPlayer ) ;
float CHalfLifeMultiplay : : __API_VHOOK ( FlPlayerFallDamage ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-08-02 20:45:57 +03:00
pPlayer - > m_flFallVelocity - = PLAYER_MAX_SAFE_FALL_SPEED ;
return pPlayer - > m_flFallVelocity * DAMAGE_FOR_FALL_SPEED * 1.25 ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FPlayerCanTakeDamage , ( CBasePlayer * pPlayer , CBaseEntity * pAttacker ) , pPlayer , pAttacker ) ;
BOOL CHalfLifeMultiplay : : __API_VHOOK ( FPlayerCanTakeDamage ) ( CBasePlayer * pPlayer , CBaseEntity * pAttacker )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( ! pAttacker | | PlayerRelationship ( pPlayer , pAttacker ) ! = GR_TEAMMATE )
{
return TRUE ;
}
if ( CVAR_GET_FLOAT ( " mp_friendlyfire " ) ! = 0 | | pAttacker = = pPlayer )
{
return TRUE ;
}
return FALSE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( PlayerThink ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( g_fGameOver )
{
// check for button presses
if ( ! IsCareer ( ) & & ( pPlayer - > m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) ) )
{
m_iEndIntermissionButtonHit = TRUE ;
}
// clear attack/use commands from player
pPlayer - > m_afButtonPressed = 0 ;
pPlayer - > pev - > button = 0 ;
pPlayer - > m_afButtonReleased = 0 ;
}
if ( ! pPlayer - > m_bCanShoot & & ! IsFreezePeriod ( ) )
{
pPlayer - > m_bCanShoot = true ;
}
if ( pPlayer - > m_pActiveItem & & pPlayer - > m_pActiveItem - > IsWeapon ( ) )
{
2016-01-25 20:02:57 +03:00
CBasePlayerWeapon * pWeapon = static_cast < CBasePlayerWeapon * > ( pPlayer - > m_pActiveItem - > GetWeaponPtr ( ) ) ;
2015-08-20 13:35:01 +03:00
if ( pWeapon - > m_iWeaponState & WPNSTATE_SHIELD_DRAWN )
{
pPlayer - > m_bCanShoot = false ;
}
}
if ( pPlayer - > m_iMenu ! = Menu_ChooseTeam & & pPlayer - > m_iJoiningState = = SHOWTEAMSELECT )
{
int team = MENU_SLOT_TEAM_UNDEFINED ;
if ( ! Q_stricmp ( humans_join_team . string , " T " ) )
{
team = MENU_SLOT_TEAM_TERRORIST ;
}
else if ( ! Q_stricmp ( humans_join_team . string , " CT " ) )
{
team = MENU_SLOT_TEAM_CT ;
}
else
{
if ( allow_spectators . value = = 0.0f )
ShowVGUIMenu ( pPlayer , VGUI_Menu_Team , ( MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 ) , " #Team_Select " ) ;
else
ShowVGUIMenu ( pPlayer , VGUI_Menu_Team , ( MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6 ) , " #Team_Select_Spect " ) ;
}
pPlayer - > m_iMenu = Menu_ChooseTeam ;
pPlayer - > m_iJoiningState = PICKINGTEAM ;
if ( team ! = MENU_SLOT_TEAM_UNDEFINED & & ! pPlayer - > IsBot ( ) )
{
HandleMenu_ChooseTeam ( pPlayer , team ) ;
if ( team ! = MENU_SLOT_TEAM_SPECT & & IsCareer ( ) )
{
// slot 6 - chooses randomize the appearance to model player
HandleMenu_ChooseAppearance ( pPlayer , 6 ) ;
}
}
}
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , PlayerSpawn , ( CBasePlayer * pPlayer ) , pPlayer ) ;
2015-09-30 03:49:22 +03:00
// Purpose: Player has just spawned. Equip them.
2016-05-17 21:01:46 +03:00
void CHalfLifeMultiplay : : __API_VHOOK ( PlayerSpawn ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
// This is tied to the joining state (m_iJoiningState).. add it when the joining state is there.
2015-08-20 13:35:01 +03:00
if ( pPlayer - > m_bJustConnected )
{
return ;
}
pPlayer - > pev - > weapons | = ( 1 < < WEAPON_SUIT ) ;
2015-09-30 03:49:22 +03:00
bool addDefault = true ;
CBaseEntity * pWeaponEntity = NULL ;
2015-08-20 13:35:01 +03:00
while ( ( pWeaponEntity = UTIL_FindEntityByClassname ( pWeaponEntity , " game_player_equip " ) ) ! = NULL )
{
pWeaponEntity - > Touch ( pPlayer ) ;
2015-09-30 03:49:22 +03:00
addDefault = false ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
if ( pPlayer - > m_bNotKilled )
addDefault = false ;
if ( addDefault | | pPlayer - > m_bIsVIP )
2015-08-20 13:35:01 +03:00
{
pPlayer - > GiveDefaultItems ( ) ;
}
pPlayer - > SetPlayerModel ( false ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FPlayerCanRespawn , ( CBasePlayer * pPlayer ) , pPlayer ) ;
BOOL CHalfLifeMultiplay : : __API_VHOOK ( FPlayerCanRespawn ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-09-30 03:49:22 +03:00
// Player cannot respawn twice in a round
2015-08-20 13:35:01 +03:00
if ( pPlayer - > m_iNumSpawns > 0 )
{
return FALSE ;
}
2015-09-30 03:49:22 +03:00
// Player cannot respawn until next round if more than 20 seconds in
// Tabulate the number of players on each team.
2015-08-20 13:35:01 +03:00
m_iNumCT = CountTeamPlayers ( CT ) ;
m_iNumTerrorist = CountTeamPlayers ( TERRORIST ) ;
2015-09-30 03:49:22 +03:00
if ( m_iNumTerrorist > 0 & & m_iNumCT > 0 )
2015-08-20 13:35:01 +03:00
{
2016-05-01 17:33:54 +03:00
if ( gpGlobals - > time > m_fRoundCount + GetRoundRespawnTime ( ) )
2015-08-20 13:35:01 +03:00
{
2016-05-01 17:33:54 +03:00
// If this player just connected and fadetoblack is on, then maybe
// the server admin doesn't want him peeking around.
2015-09-30 03:49:22 +03:00
if ( fadetoblack . value ! = 0.0f )
{
UTIL_ScreenFade ( pPlayer , Vector ( 0 , 0 , 0 ) , 3 , 3 , 255 , ( FFADE_OUT | FFADE_STAYOUT ) ) ;
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
return FALSE ;
}
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Player cannot respawn while in the Choose Appearance menu
2015-08-20 13:35:01 +03:00
if ( pPlayer - > m_iMenu = = Menu_ChooseAppearance )
{
return FALSE ;
}
return TRUE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlPlayerSpawnTime ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return gpGlobals - > time ; //now!
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( AllowAutoTargetCrosshair ) ( )
2015-07-12 23:32:09 +03:00
{
return FALSE ;
}
2015-08-20 13:35:01 +03:00
// IPointsForKill - how many points awarded to anyone
// that kills this player?
int CHalfLifeMultiplay : : __MAKE_VHOOK ( IPointsForKill ) ( CBasePlayer * pAttacker , CBasePlayer * pKilled )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return 1 ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , PlayerKilled , ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pInflictor ) , pVictim , pKiller , pInflictor ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( PlayerKilled ) ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pInflictor )
2015-08-20 13:35:01 +03:00
{
DeathNotice ( pVictim , pKiller , pInflictor ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
pVictim - > m_afPhysicsFlags & = ~ PFLAG_ONTRAIN ;
pVictim - > m_iDeaths + + ;
pVictim - > m_bNotKilled = false ;
pVictim - > m_bEscaped = false ;
pVictim - > m_iTrain = ( TRAIN_NEW | TRAIN_OFF ) ;
SET_VIEW ( ENT ( pVictim - > pev ) , ENT ( pVictim - > pev ) ) ;
CBasePlayer * peKiller = NULL ;
CBaseEntity * ktmp = CBaseEntity : : Instance ( pKiller ) ;
if ( ktmp & & ktmp - > Classify ( ) = = CLASS_PLAYER )
{
2016-01-25 20:02:57 +03:00
peKiller = static_cast < CBasePlayer * > ( ktmp ) ;
2015-08-20 13:35:01 +03:00
}
else if ( ktmp & & ktmp - > Classify ( ) = = CLASS_VEHICLE )
{
2016-01-25 20:02:57 +03:00
CBasePlayer * pDriver = static_cast < CBasePlayer * > ( ( ( CFuncVehicle * ) ktmp ) - > m_pDriver ) ;
2015-08-20 13:35:01 +03:00
if ( pDriver ! = NULL )
{
pKiller = pDriver - > pev ;
2016-01-25 20:02:57 +03:00
peKiller = static_cast < CBasePlayer * > ( pDriver ) ;
2015-08-20 13:35:01 +03:00
}
}
FireTargets ( " game_playerdie " , pVictim , pVictim , USE_TOGGLE , 0 ) ;
2015-09-30 03:49:22 +03:00
// Did the player kill himself?
2015-08-20 13:35:01 +03:00
if ( pVictim - > pev = = pKiller )
{
2015-09-30 03:49:22 +03:00
// Players lose a frag for killing themselves
2015-08-20 13:35:01 +03:00
pKiller - > frags - = 1 ;
}
else if ( peKiller & & peKiller - > IsPlayer ( ) )
{
2015-09-30 03:49:22 +03:00
// if a player dies in a deathmatch game and the killer is a client, award the killer some points
2016-03-17 20:44:52 +03:00
CBasePlayer * killer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pKiller ) ;
2016-06-14 18:00:27 +03:00
bool killedByFFA = CSGameRules ( ) - > IsFreeForAll ( ) ;
2015-08-20 13:35:01 +03:00
2015-12-29 01:54:08 +03:00
if ( killer - > m_iTeam = = pVictim - > m_iTeam & & ! killedByFFA )
2015-08-20 13:35:01 +03:00
{
// if a player dies by from teammate
pKiller - > frags - = IPointsForKill ( peKiller , pVictim ) ;
2016-05-25 16:56:48 +03:00
killer - > AddAccount ( PAYBACK_FOR_KILLED_TEAMMATES , RT_TEAMMATES_KILLED ) ;
2015-08-20 13:35:01 +03:00
killer - > m_iTeamKills + + ;
killer - > m_bJustKilledTeammate = true ;
ClientPrint ( killer - > pev , HUD_PRINTCENTER , " #Killed_Teammate " ) ;
ClientPrint ( killer - > pev , HUD_PRINTCONSOLE , " #Game_teammate_kills " , UTIL_dtos1 ( killer - > m_iTeamKills ) ) ;
if ( killer - > m_iTeamKills = = 3 & & CVAR_GET_FLOAT ( " mp_autokick " ) ! = 0.0f )
{
ClientPrint ( killer - > pev , HUD_PRINTCONSOLE , " #Banned_For_Killing_Teamates " ) ;
int iUserID = GETPLAYERUSERID ( killer - > edict ( ) ) ;
if ( iUserID ! = - 1 )
{
SERVER_COMMAND ( UTIL_VarArgs ( " kick # %d \n " , iUserID ) ) ;
}
}
if ( ! ( killer - > m_flDisplayHistory & DHF_FRIEND_KILLED ) )
{
killer - > m_flDisplayHistory | = DHF_FRIEND_KILLED ;
killer - > HintMessage ( " #Hint_careful_around_teammates " ) ;
}
}
else
{
// if a player dies in a deathmatch game and the killer is a client, award the killer some points
pKiller - > frags + = IPointsForKill ( peKiller , pVictim ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( pVictim - > m_bIsVIP )
{
killer - > HintMessage ( " #Hint_reward_for_killing_vip " , TRUE ) ;
2016-05-25 16:56:48 +03:00
killer - > AddAccount ( REWARD_KILLED_VIP , RT_VIP_KILLED ) ;
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
WRITE_BYTE ( 9 ) ;
WRITE_BYTE ( DRC_CMD_EVENT ) ;
WRITE_SHORT ( ENTINDEX ( pVictim - > edict ( ) ) ) ;
WRITE_SHORT ( ENTINDEX ( ENT ( pInflictor ) ) ) ;
WRITE_LONG ( DRC_FLAG_PRIO_MASK | DRC_FLAG_DRAMATIC | DRC_FLAG_FINAL ) ;
MESSAGE_END ( ) ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><TERRORIST> \" triggered \" Assassinated_The_VIP \" \n " , STRING ( killer - > pev - > netname ) , GETPLAYERUSERID ( killer - > edict ( ) ) , GETPLAYERAUTHID ( killer - > edict ( ) ) ) ;
2015-08-20 13:35:01 +03:00
}
else
2016-05-25 16:56:48 +03:00
killer - > AddAccount ( REWARD_KILLED_ENEMY , RT_ENEMY_KILLED ) ;
2015-08-20 13:35:01 +03:00
if ( ! ( killer - > m_flDisplayHistory & DHF_ENEMY_KILLED ) )
{
killer - > m_flDisplayHistory | = DHF_ENEMY_KILLED ;
killer - > HintMessage ( " #Hint_win_round_by_killing_enemy " ) ;
}
}
FireTargets ( " game_playerkill " , peKiller , peKiller , USE_TOGGLE , 0 ) ;
}
else
{
// killed by the world
pKiller - > frags - = 1 ;
}
// update the scores
// killed scores
MESSAGE_BEGIN ( MSG_BROADCAST , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( pVictim - > edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( pVictim - > pev - > frags ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_SHORT ( pVictim - > m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( pVictim - > m_iTeam ) ;
MESSAGE_END ( ) ;
// killers score, if it's a player
CBaseEntity * ep = CBaseEntity : : Instance ( pKiller ) ;
if ( ep & & ep - > Classify ( ) = = CLASS_PLAYER )
{
2016-01-25 20:02:57 +03:00
CBasePlayer * PK = static_cast < CBasePlayer * > ( ep ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( PK - > edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( PK - > pev - > frags ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_SHORT ( PK - > m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( PK - > m_iTeam ) ;
MESSAGE_END ( ) ;
// let the killer paint another decal as soon as he'd like.
PK - > m_flNextDecalTime = gpGlobals - > time ;
}
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , DeathNotice , ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pevInflictor ) , pVictim , pKiller , pevInflictor ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( DeathNotice ) ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pevInflictor )
2015-08-20 13:35:01 +03:00
{
// Work out what killed the player, and send a message to all clients about it
// CBaseEntity *Killer = CBaseEntity::Instance(pKiller);
// by default, the player is killed by the world
const char * killer_weapon_name = " world " ;
int killer_index = 0 ;
2016-06-02 01:08:22 +03:00
# ifndef REGAMEDLL_FIXES
2015-08-20 13:35:01 +03:00
// Hack to fix name change
char * tau = " tau_cannon " ;
char * gluon = " gluon gun " ;
2016-06-02 01:08:22 +03:00
# endif
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Is the killer a client?
2015-08-20 13:35:01 +03:00
if ( pKiller - > flags & FL_CLIENT )
{
killer_index = ENTINDEX ( ENT ( pKiller ) ) ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( pevInflictor )
{
if ( pevInflictor = = pKiller )
{
2015-09-30 03:49:22 +03:00
// If the inflictor is the killer, then it must be their current weapon doing the damage
2016-06-14 01:13:13 +03:00
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pKiller ) ;
if ( pAttacker & & pAttacker - > IsPlayer ( ) )
2015-08-20 13:35:01 +03:00
{
2016-06-14 01:13:13 +03:00
if ( pAttacker - > m_pActiveItem )
killer_weapon_name = pAttacker - > m_pActiveItem - > pszName ( ) ;
2015-08-20 13:35:01 +03:00
}
}
else
{
2015-09-30 03:49:22 +03:00
// it's just that easy
killer_weapon_name = STRING ( pevInflictor - > classname ) ;
2015-08-20 13:35:01 +03:00
}
}
}
else
2016-06-02 01:08:22 +03:00
# ifdef REGAMEDLL_FIXES
if ( pevInflictor )
# endif
2016-06-14 01:13:13 +03:00
{
2015-08-20 13:35:01 +03:00
killer_weapon_name = STRING ( pevInflictor - > classname ) ;
2016-06-14 01:13:13 +03:00
}
2015-08-20 13:35:01 +03:00
// strip the monster_* or weapon_* from the inflictor's classname
2016-06-14 01:13:13 +03:00
const char cut_weapon [ ] = " weapon_ " ;
const char cut_monster [ ] = " monster_ " ;
const char cut_func [ ] = " func_ " ;
2015-08-20 13:35:01 +03:00
2016-06-14 01:13:13 +03:00
if ( ! Q_strncmp ( killer_weapon_name , cut_weapon , sizeof ( cut_weapon ) - 1 ) )
killer_weapon_name + = sizeof ( cut_weapon ) - 1 ;
2015-08-20 13:35:01 +03:00
2016-06-14 01:13:13 +03:00
else if ( ! Q_strncmp ( killer_weapon_name , cut_monster , sizeof ( cut_monster ) - 1 ) )
killer_weapon_name + = sizeof ( cut_monster ) - 1 ;
2015-08-20 13:35:01 +03:00
2016-06-14 01:13:13 +03:00
else if ( ! Q_strncmp ( killer_weapon_name , cut_func , sizeof ( cut_func ) - 1 ) )
killer_weapon_name + = sizeof ( cut_func ) - 1 ;
2015-08-20 13:35:01 +03:00
2016-06-14 01:13:13 +03:00
if ( TheTutor = = nullptr )
2015-08-20 13:35:01 +03:00
{
MESSAGE_BEGIN ( MSG_ALL , gmsgDeathMsg ) ;
WRITE_BYTE ( killer_index ) ; // the killer
WRITE_BYTE ( ENTINDEX ( pVictim - > edict ( ) ) ) ; // the victim
2016-06-14 01:13:13 +03:00
WRITE_BYTE ( pVictim - > m_bHeadshotKilled ) ; // is killed headshot
2015-08-20 13:35:01 +03:00
WRITE_STRING ( killer_weapon_name ) ; // what they were killed by (should this be a string?)
MESSAGE_END ( ) ;
}
2016-06-02 01:08:22 +03:00
// This weapons from HL isn't it?
# ifndef REGAMEDLL_FIXES
2015-08-20 13:35:01 +03:00
// replace the code names with the 'real' names
if ( ! Q_strcmp ( killer_weapon_name , " egon " ) )
killer_weapon_name = gluon ;
else if ( ! Q_strcmp ( killer_weapon_name , " gauss " ) )
killer_weapon_name = tau ;
2016-06-02 01:08:22 +03:00
# endif
2015-09-16 23:19:21 +03:00
2015-09-30 03:49:22 +03:00
// Did he kill himself?
2015-08-20 13:35:01 +03:00
if ( pVictim - > pev = = pKiller )
{
// killed self
char * team = GetTeam ( pVictim - > m_iTeam ) ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" committed suicide with \" %s \" \n " , STRING ( pVictim - > pev - > netname ) , GETPLAYERUSERID ( pVictim - > edict ( ) ) ,
GETPLAYERAUTHID ( pVictim - > edict ( ) ) , team , killer_weapon_name ) ;
2015-08-20 13:35:01 +03:00
}
else if ( pKiller - > flags & FL_CLIENT )
{
2016-06-14 01:13:13 +03:00
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pKiller ) ;
2015-08-20 13:35:01 +03:00
2016-02-04 03:18:26 +03:00
const char * VictimTeam = GetTeam ( pVictim - > m_iTeam ) ;
2016-06-14 01:13:13 +03:00
const char * KillerTeam = ( pAttacker & & pAttacker - > IsPlayer ( ) ) ? GetTeam ( pAttacker - > m_iTeam ) : " " ;
2015-08-20 13:35:01 +03:00
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" killed \" %s<%i><%s><%s> \" with \" %s \" \n " , STRING ( pKiller - > netname ) , GETPLAYERUSERID ( ENT ( pKiller ) ) , GETPLAYERAUTHID ( ENT ( pKiller ) ) ,
KillerTeam , STRING ( pVictim - > pev - > netname ) , GETPLAYERUSERID ( pVictim - > edict ( ) ) , GETPLAYERAUTHID ( pVictim - > edict ( ) ) , VictimTeam , killer_weapon_name ) ;
2015-08-20 13:35:01 +03:00
}
else
{
// killed by the world
char * team = GetTeam ( pVictim - > m_iTeam ) ;
2016-01-28 02:50:27 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" committed suicide with \" %s \" (world) \n " , STRING ( pVictim - > pev - > netname ) , GETPLAYERUSERID ( pVictim - > edict ( ) ) ,
GETPLAYERAUTHID ( pVictim - > edict ( ) ) , team , killer_weapon_name ) ;
2015-08-20 13:35:01 +03:00
}
CheckWinConditions ( ) ;
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // player killed
WRITE_SHORT ( ENTINDEX ( pVictim - > edict ( ) ) ) ; // index number of primary entity
if ( pevInflictor )
WRITE_SHORT ( ENTINDEX ( ENT ( pevInflictor ) ) ) ; // index number of secondary entity
else
WRITE_SHORT ( ENTINDEX ( ENT ( pKiller ) ) ) ; // index number of secondary entity
2016-06-14 01:13:13 +03:00
if ( pVictim - > m_bHeadshotKilled )
2015-08-20 13:35:01 +03:00
WRITE_LONG ( 9 | DRC_FLAG_DRAMATIC | DRC_FLAG_SLOWMOTION ) ;
else
WRITE_LONG ( 7 | DRC_FLAG_DRAMATIC ) ; // eventflags (priority and flags)
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
// PlayerGotWeapon - player has grabbed a weapon that was
// sitting in the world
void CHalfLifeMultiplay : : __MAKE_VHOOK ( PlayerGotWeapon ) ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
;
}
2015-08-20 13:35:01 +03:00
// FlWeaponRespawnTime - what is the time in the future
// at which this weapon may spawn?
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlWeaponRespawnTime ) ( CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return gpGlobals - > time + WEAPON_RESPAWN_TIME ;
2015-07-12 23:32:09 +03:00
}
2015-09-16 23:19:21 +03:00
// FlWeaponRespawnTime - Returns 0 if the weapon can respawn
2015-09-30 03:49:22 +03:00
// now, otherwise it returns the time at which it can try
2015-08-20 13:35:01 +03:00
// to spawn again.
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlWeaponTryRespawn ) ( CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( pWeapon & & pWeapon - > m_iId & & ( pWeapon - > iFlags ( ) & ITEM_FLAG_LIMITINWORLD ) )
{
if ( NUMBER_OF_ENTITIES ( ) < ( gpGlobals - > maxEntities - ENTITY_INTOLERANCE ) )
return 0 ;
2015-09-30 03:49:22 +03:00
// we're past the entity tolerance level, so delay the respawn
2015-08-20 13:35:01 +03:00
return FlWeaponRespawnTime ( pWeapon ) ;
}
return 0 ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
Vector CHalfLifeMultiplay : : __MAKE_VHOOK ( VecWeaponRespawnSpot ) ( CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return pWeapon - > pev - > origin ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
int CHalfLifeMultiplay : : __MAKE_VHOOK ( WeaponShouldRespawn ) ( CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
if ( pWeapon - > pev - > spawnflags & SF_NORESPAWN )
2015-08-20 13:35:01 +03:00
{
2015-06-30 12:46:07 +03:00
return GR_WEAPON_RESPAWN_NO ;
2015-08-20 13:35:01 +03:00
}
2015-06-30 12:46:07 +03:00
2015-07-12 23:32:09 +03:00
return GR_WEAPON_RESPAWN_YES ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , CanHavePlayerItem , ( CBasePlayer * pPlayer , CBasePlayerItem * pItem ) , pPlayer , pItem ) ;
BOOL CHalfLifeMultiplay : : __API_VHOOK ( CanHavePlayerItem ) ( CBasePlayer * pPlayer , CBasePlayerItem * pItem )
2015-07-12 23:32:09 +03:00
{
return CGameRules : : CanHavePlayerItem ( pPlayer , pItem ) ;
}
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( CanHaveItem ) ( CBasePlayer * pPlayer , CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( PlayerGotItem ) ( CBasePlayer * pPlayer , CItem * pItem )
2015-07-12 23:32:09 +03:00
{
;
}
2015-08-20 13:35:01 +03:00
int CHalfLifeMultiplay : : __MAKE_VHOOK ( ItemShouldRespawn ) ( CItem * pItem )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
if ( pItem - > pev - > spawnflags & SF_NORESPAWN )
2015-08-20 13:35:01 +03:00
{
2015-06-30 12:46:07 +03:00
return GR_ITEM_RESPAWN_NO ;
2015-08-20 13:35:01 +03:00
}
2015-06-30 12:46:07 +03:00
2015-07-12 23:32:09 +03:00
return GR_ITEM_RESPAWN_YES ;
}
2015-08-20 13:35:01 +03:00
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlItemRespawnTime ) ( CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > time + ITEM_RESPAWN_TIME ;
}
2015-08-20 13:35:01 +03:00
Vector CHalfLifeMultiplay : : __MAKE_VHOOK ( VecItemRespawnSpot ) ( CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return pItem - > pev - > origin ;
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : __MAKE_VHOOK ( PlayerGotAmmo ) ( CBasePlayer * pPlayer , char * szName , int iCount )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( IsAllowedToSpawn ) ( CBaseEntity * pEntity )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return TRUE ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
int CHalfLifeMultiplay : : __MAKE_VHOOK ( AmmoShouldRespawn ) ( CBasePlayerAmmo * pAmmo )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
if ( pAmmo - > pev - > spawnflags & SF_NORESPAWN )
2015-08-20 13:35:01 +03:00
{
2015-06-30 12:46:07 +03:00
return GR_AMMO_RESPAWN_NO ;
2015-08-20 13:35:01 +03:00
}
2015-06-30 12:46:07 +03:00
2015-07-12 23:32:09 +03:00
return GR_AMMO_RESPAWN_YES ;
}
2015-08-20 13:35:01 +03:00
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlAmmoRespawnTime ) ( CBasePlayerAmmo * pAmmo )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > time + 20.0f ;
}
2015-08-20 13:35:01 +03:00
Vector CHalfLifeMultiplay : : __MAKE_VHOOK ( VecAmmoRespawnSpot ) ( CBasePlayerAmmo * pAmmo )
2015-07-12 23:32:09 +03:00
{
return pAmmo - > pev - > origin ;
}
2016-01-28 07:48:09 +03:00
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlHealthChargerRechargeTime ) ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return 60 ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
float CHalfLifeMultiplay : : __MAKE_VHOOK ( FlHEVChargerRechargeTime ) ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return 30 ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( int , CHalfLifeMultiplay , CSGameRules , DeadPlayerWeapons , ( CBasePlayer * pPlayer ) , pPlayer ) ;
int CHalfLifeMultiplay : : __API_VHOOK ( DeadPlayerWeapons ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
return GR_PLR_DROP_GUN_ACTIVE ;
}
2015-08-20 13:35:01 +03:00
int CHalfLifeMultiplay : : __MAKE_VHOOK ( DeadPlayerAmmo ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
return GR_PLR_DROP_AMMO_ACTIVE ;
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( edict_t * , CHalfLifeMultiplay , CSGameRules , GetPlayerSpawnSpot , ( CBasePlayer * pPlayer ) , pPlayer ) ;
edict_t * CHalfLifeMultiplay : : __API_VHOOK ( GetPlayerSpawnSpot ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2016-01-28 05:51:34 +03:00
// gat valid spawn point
2015-08-20 13:35:01 +03:00
edict_t * pentSpawnSpot = CGameRules : : GetPlayerSpawnSpot ( pPlayer ) ;
if ( IsMultiplayer ( ) )
{
if ( pentSpawnSpot - > v . target )
{
FireTargets ( STRING ( pentSpawnSpot - > v . target ) , pPlayer , pPlayer , USE_TOGGLE , 0 ) ;
}
}
return pentSpawnSpot ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
int CHalfLifeMultiplay : : __MAKE_VHOOK ( PlayerRelationship ) ( CBasePlayer * pPlayer , CBaseEntity * pTarget )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( ! pPlayer | | ! pTarget )
{
return GR_NOTTEAMMATE ;
}
if ( ! pTarget - > IsPlayer ( ) )
{
return GR_NOTTEAMMATE ;
}
2016-03-17 20:44:52 +03:00
CBasePlayer * player = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pPlayer - > pev ) ;
CBasePlayer * target = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pTarget - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( player - > m_iTeam ! = target - > m_iTeam )
{
return GR_NOTTEAMMATE ;
}
return GR_TEAMMATE ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( FAllowFlashlight ) ( )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
static cvar_t * mp_flashlight = NULL ;
if ( ! mp_flashlight )
mp_flashlight = CVAR_GET_POINTER ( " mp_flashlight " ) ;
if ( mp_flashlight )
return mp_flashlight - > value ! = 0 ;
2015-07-12 23:32:09 +03:00
return FALSE ;
}
2016-01-28 07:48:09 +03:00
BOOL CHalfLifeMultiplay : : __MAKE_VHOOK ( FAllowMonsters ) ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
return CVAR_GET_FLOAT ( " mp_allowmonsters " ) ! = 0 ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , GoToIntermission ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( GoToIntermission ) ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
if ( g_fGameOver )
return ;
2015-11-06 17:58:48 +03:00
UTIL_LogPrintf ( " Team \" CT \" scored \" %i \" with \" %i \" players \n " , m_iNumCTWins , m_iNumCT ) ;
UTIL_LogPrintf ( " Team \" TERRORIST \" scored \" %i \" with \" %i \" players \n " , m_iNumTerroristWins , m_iNumTerrorist ) ;
2015-07-12 23:32:09 +03:00
if ( IsCareer ( ) )
{
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgCZCareer ) ;
WRITE_STRING ( " MATCH " ) ;
WRITE_LONG ( m_iNumCTWins ) ;
WRITE_LONG ( m_iNumTerroristWins ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgCZCareerHUD ) ;
WRITE_STRING ( " MATCH " ) ;
WRITE_LONG ( m_iNumCTWins ) ;
WRITE_LONG ( m_iNumTerroristWins ) ;
WRITE_BYTE ( m_iCareerMatchWins ) ;
WRITE_BYTE ( m_iRoundWinDifference ) ;
WRITE_BYTE ( m_iRoundWinStatus ) ;
MESSAGE_END ( ) ;
2015-12-05 22:40:30 +03:00
if ( TheCareerTasks ! = NULL )
{
UTIL_LogPrintf ( " Career Match %d %d %d %d \n " , m_iRoundWinStatus , m_iNumCTWins , m_iNumTerroristWins , TheCareerTasks - > AreAllTasksComplete ( ) ) ;
}
2015-08-20 13:35:01 +03:00
}
MESSAGE_BEGIN ( MSG_ALL , SVC_INTERMISSION ) ;
MESSAGE_END ( ) ;
if ( IsCareer ( ) )
{
SERVER_COMMAND ( " setpause \n " ) ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
2016-02-23 02:13:52 +03:00
int time = int ( CVAR_GET_FLOAT ( " mp_chattime " ) ) ;
2015-08-20 13:35:01 +03:00
if ( time < 1 )
CVAR_SET_STRING ( " mp_chattime " , " 1 " ) ;
else if ( time > MAX_INTERMISSION_TIME )
CVAR_SET_STRING ( " mp_chattime " , UTIL_dtos1 ( MAX_INTERMISSION_TIME ) ) ;
2016-02-23 02:13:52 +03:00
m_flIntermissionEndTime = gpGlobals - > time + int ( mp_chattime . value ) ;
2015-08-20 13:35:01 +03:00
m_flIntermissionStartTime = gpGlobals - > time ;
g_fGameOver = TRUE ;
m_iEndIntermissionButtonHit = FALSE ;
m_iSpawnPointCount_Terrorist = 0 ;
m_iSpawnPointCount_CT = 0 ;
m_bLevelInitialized = false ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
// Clean up memory used by mapcycle when switching it
void DestroyMapCycle ( mapcycle_t * cycle )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
mapcycle_item_t * p , * n , * start ;
p = cycle - > items ;
if ( p ! = NULL )
{
start = p ;
p = p - > next ;
while ( p ! = start )
{
n = p - > next ;
delete p ;
p = n ;
}
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
delete cycle - > items ;
}
cycle - > items = NULL ;
cycle - > next_item = NULL ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
char * MP_COM_GetToken ( )
2015-07-12 23:32:09 +03:00
{
return mp_com_token ;
}
char * MP_COM_Parse ( char * data )
{
2015-07-05 14:05:26 +03:00
int c ;
int len ;
len = 0 ;
mp_com_token [ 0 ] = ' \0 ' ;
if ( ! data )
{
return NULL ;
}
skipwhite :
// skip whitespace
while ( * data < = ' ' )
{
if ( ! data [ 0 ] )
return NULL ;
2016-02-04 03:18:26 +03:00
+ + data ;
2015-07-05 14:05:26 +03:00
}
c = * data ;
// skip // comments till the next line
if ( c = = ' / ' & & data [ 1 ] = = ' / ' )
{
while ( * data & & * data ! = ' \n ' )
2016-02-04 03:18:26 +03:00
+ + data ;
2015-07-05 14:05:26 +03:00
goto skipwhite ; // start over new line
}
// handle quoted strings specially: copy till the end or another quote
if ( c = = ' \" ' )
{
2016-02-04 03:18:26 +03:00
+ + data ; // skip starting quote
2015-07-05 14:05:26 +03:00
while ( true )
{
// get char and advance
c = * data + + ;
if ( c = = ' \" ' | | ! c )
{
2015-08-20 13:35:01 +03:00
mp_com_token [ len ] = ' \0 ' ;
2015-07-05 14:05:26 +03:00
return data ;
}
mp_com_token [ len + + ] = c ;
}
}
// parse single characters
if ( c = = ' { ' | | c = = ' } ' | | c = = ' ) ' | | c = = ' ( ' | | c = = ' \' ' | | c = = ' , ' )
{
mp_com_token [ len + + ] = c ;
mp_com_token [ len ] = ' \0 ' ;
return data + 1 ;
}
// parse a regular word
do
{
mp_com_token [ len + + ] = c ;
2016-02-04 03:18:26 +03:00
+ + data ;
2015-07-05 14:05:26 +03:00
c = * data ;
if ( c = = ' { ' | | c = = ' } ' | | c = = ' ) ' | | c = = ' ( ' | | c = = ' \' ' | | c = = ' , ' )
break ;
}
while ( c > 32 ) ;
2015-08-20 13:35:01 +03:00
mp_com_token [ len ] = ' \0 ' ;
2015-07-12 23:32:09 +03:00
return data ;
}
2015-08-20 13:35:01 +03:00
int MP_COM_TokenWaiting ( char * buffer )
2015-07-12 23:32:09 +03:00
{
2015-07-05 14:05:26 +03:00
char * p ;
p = buffer ;
while ( * p & & * p ! = ' \n ' )
{
2016-02-23 02:13:52 +03:00
if ( ! Q_isspace ( * p ) | | Q_isalnum ( * p ) )
2015-07-05 14:05:26 +03:00
return 1 ;
2016-02-04 03:18:26 +03:00
+ + p ;
2015-07-05 14:05:26 +03:00
}
2015-07-12 23:32:09 +03:00
return 0 ;
}
2015-08-20 13:35:01 +03:00
int ReloadMapCycleFile ( char * filename , mapcycle_t * cycle )
{
char szBuffer [ MAX_RULE_BUFFER ] ;
char szMap [ 32 ] ;
int length ;
char * pFileList ;
char * aFileList = pFileList = ( char * ) LOAD_FILE_FOR_ME ( filename , & length ) ;
int hasbuffer ;
mapcycle_item_s * item , * newlist = NULL , * next ;
if ( pFileList & & length )
{
// the first map name in the file becomes the default
while ( true )
{
hasbuffer = 0 ;
Q_memset ( szBuffer , 0 , sizeof ( szBuffer ) ) ;
pFileList = MP_COM_Parse ( pFileList ) ;
if ( Q_strlen ( mp_com_token ) < = 0 )
break ;
Q_strcpy ( szMap , mp_com_token ) ;
// Any more tokens on this line?
if ( MP_COM_TokenWaiting ( pFileList ) )
{
pFileList = MP_COM_Parse ( pFileList ) ;
if ( Q_strlen ( mp_com_token ) > 0 )
{
hasbuffer = 1 ;
Q_strcpy ( szBuffer , mp_com_token ) ;
}
}
// Check map
if ( IS_MAP_VALID ( szMap ) )
{
// Create entry
char * s ;
item = new mapcycle_item_s ;
Q_strcpy ( item - > mapname , szMap ) ;
item - > minplayers = 0 ;
item - > maxplayers = 0 ;
Q_memset ( item - > rulebuffer , 0 , sizeof ( item - > rulebuffer ) ) ;
if ( hasbuffer )
{
s = GET_KEY_VALUE ( szBuffer , " minplayers " ) ;
if ( s & & s [ 0 ] ! = ' \0 ' )
{
item - > minplayers = Q_atoi ( s ) ;
2015-09-16 23:19:21 +03:00
item - > minplayers = Q_max ( item - > minplayers , 0 ) ;
item - > minplayers = Q_min ( item - > minplayers , gpGlobals - > maxClients ) ;
2015-08-20 13:35:01 +03:00
}
s = GET_KEY_VALUE ( szBuffer , " maxplayers " ) ;
if ( s & & s [ 0 ] ! = ' \0 ' )
{
item - > maxplayers = Q_atoi ( s ) ;
2015-09-16 23:19:21 +03:00
item - > maxplayers = Q_max ( item - > maxplayers , 0 ) ;
item - > maxplayers = Q_min ( item - > maxplayers , gpGlobals - > maxClients ) ;
2015-08-20 13:35:01 +03:00
}
// Remove keys
REMOVE_KEY_VALUE ( szBuffer , " minplayers " ) ;
REMOVE_KEY_VALUE ( szBuffer , " maxplayers " ) ;
Q_strcpy ( item - > rulebuffer , szBuffer ) ;
}
item - > next = cycle - > items ;
cycle - > items = item ;
}
else
ALERT ( at_console , " Skipping %s from mapcycle, not a valid map \n " , szMap ) ;
}
FREE_FILE ( aFileList ) ;
}
// Fixup circular list pointer
item = cycle - > items ;
// Reverse it to get original order
while ( item )
{
next = item - > next ;
item - > next = newlist ;
newlist = item ;
item = next ;
}
cycle - > items = newlist ;
item = cycle - > items ;
// Didn't parse anything
if ( ! item )
{
return 0 ;
}
while ( item - > next ! = NULL )
{
item = item - > next ;
}
item - > next = cycle - > items ;
cycle - > next_item = item - > next ;
return 1 ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
// Determine the current # of active players on the server for map cycling logic
2016-01-28 07:48:09 +03:00
int CountPlayers ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
int num = 0 ;
2016-01-25 20:02:57 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; + + i )
2015-08-20 13:35:01 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
if ( pPlayer ! = NULL )
2015-08-20 13:35:01 +03:00
{
num = num + 1 ;
}
}
return num ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
// Parse commands/key value pairs to issue right after map xxx command is issued on server level transition
void ExtractCommandString ( char * s , char * szCommand )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
// Now make rules happen
char pkey [ 512 ] ;
char value [ 512 ] ; // use two buffers so compares
// work without stomping on each other
char * o ;
2015-09-16 23:19:21 +03:00
2015-08-20 13:35:01 +03:00
if ( * s = = ' \\ ' )
2016-02-04 03:18:26 +03:00
+ + s ;
2015-08-20 13:35:01 +03:00
while ( true )
{
o = pkey ;
while ( * s ! = ' \\ ' )
{
if ( ! * s )
{
return ;
}
* o + + = * s + + ;
}
* o = ' \0 ' ;
2016-02-04 03:18:26 +03:00
+ + s ;
2015-08-20 13:35:01 +03:00
o = value ;
while ( * s ! = ' \\ ' & & * s )
{
if ( ! * s )
{
return ;
}
* o + + = * s + + ;
}
* o = ' \0 ' ;
Q_strcat ( szCommand , pkey ) ;
if ( Q_strlen ( value ) > 0 )
{
Q_strcat ( szCommand , " " ) ;
Q_strcat ( szCommand , value ) ;
}
Q_strcat ( szCommand , " \n " ) ;
if ( ! * s )
{
return ;
}
2016-02-04 03:18:26 +03:00
+ + s ;
2015-08-20 13:35:01 +03:00
}
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : ResetAllMapVotes ( )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
CBaseEntity * pTempEntity = NULL ;
while ( ( pTempEntity = UTIL_FindEntityByClassname ( pTempEntity , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pTempEntity - > edict ( ) ) )
break ;
2016-03-17 20:44:52 +03:00
CBasePlayer * pTempPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pTempEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( pTempPlayer - > m_iTeam ! = UNASSIGNED )
{
pTempPlayer - > m_iMapVote = 0 ;
}
}
2016-02-04 03:18:26 +03:00
for ( int j = 0 ; j < MAX_VOTE_MAPS ; + + j )
2015-08-20 13:35:01 +03:00
m_iMapVotes [ j ] = 0 ;
2015-07-12 23:32:09 +03:00
}
2016-01-28 07:48:09 +03:00
int GetMapCount ( )
2015-07-12 23:32:09 +03:00
{
2016-06-04 14:43:52 +03:00
static mapcycle_t mapcycle ;
2015-08-20 13:35:01 +03:00
char * mapcfile = ( char * ) CVAR_GET_STRING ( " mapcyclefile " ) ;
2016-06-04 14:43:52 +03:00
DestroyMapCycle ( & mapcycle ) ;
ReloadMapCycleFile ( mapcfile , & mapcycle ) ;
2015-08-20 13:35:01 +03:00
2016-06-04 14:43:52 +03:00
int nCount = 0 ;
auto item = mapcycle . next_item ;
2015-08-20 13:35:01 +03:00
2016-06-04 14:43:52 +03:00
do
{
+ + nCount ;
item = item - > next ;
} while ( item ! = mapcycle . next_item ) ;
2015-08-20 13:35:01 +03:00
2016-06-04 14:43:52 +03:00
return nCount ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : DisplayMaps ( CBasePlayer * player , int iVote )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
static mapcycle_t mapcycle2 ;
char * mapcfile = ( char * ) CVAR_GET_STRING ( " mapcyclefile " ) ;
char * pszNewMap = NULL ;
int iCount = 0 , done = 0 ;
DestroyMapCycle ( & mapcycle2 ) ;
ReloadMapCycleFile ( mapcfile , & mapcycle2 ) ;
mapcycle_item_s * item = mapcycle2 . next_item ;
while ( ! done & & item ! = NULL )
{
if ( item - > next = = mapcycle2 . next_item )
done = 1 ;
+ + iCount ;
if ( player ! = NULL )
{
if ( m_iMapVotes [ iCount ] = = 1 )
{
ClientPrint ( player - > pev , HUD_PRINTCONSOLE , " #Vote " , UTIL_dtos1 ( iCount ) , item - > mapname , UTIL_dtos2 ( 1 ) ) ;
}
else
ClientPrint ( player - > pev , HUD_PRINTCONSOLE , " #Votes " , UTIL_dtos1 ( iCount ) , item - > mapname , UTIL_dtos2 ( m_iMapVotes [ iCount ] ) ) ;
}
if ( iCount = = iVote )
{
pszNewMap = item - > mapname ;
}
item = item - > next ;
}
if ( ! pszNewMap | | ! iVote )
{
return ;
}
2016-02-23 02:13:52 +03:00
if ( Q_strcmp ( pszNewMap , STRING ( gpGlobals - > mapname ) ) ! = 0 )
2015-08-20 13:35:01 +03:00
{
CHANGE_LEVEL ( pszNewMap , NULL ) ;
return ;
}
if ( timelimit . value )
{
timelimit . value + = 30 ;
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Map_Vote_Extend " ) ;
}
ResetAllMapVotes ( ) ;
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : ProcessMapVote ( CBasePlayer * player , int iVote )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
CBaseEntity * pTempEntity = NULL ;
int iValidVotes = 0 , iNumPlayers = 0 ;
while ( ( pTempEntity = UTIL_FindEntityByClassname ( pTempEntity , " player " ) ) ! = NULL )
{
if ( FNullEnt ( pTempEntity - > edict ( ) ) )
break ;
2016-03-17 20:44:52 +03:00
CBasePlayer * pTempPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pTempEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
if ( pTempPlayer - > m_iTeam ! = UNASSIGNED )
{
2016-02-04 03:18:26 +03:00
+ + iNumPlayers ;
2015-08-20 13:35:01 +03:00
2016-06-04 14:43:52 +03:00
if ( pTempPlayer - > m_iMapVote = = iVote )
2016-02-04 03:18:26 +03:00
+ + iValidVotes ;
2015-08-20 13:35:01 +03:00
}
}
m_iMapVotes [ iVote ] = iValidVotes ;
float ratio = mapvoteratio . value ;
if ( mapvoteratio . value > 1 )
{
ratio = 1 ;
CVAR_SET_STRING ( " mp_mapvoteratio " , " 1.0 " ) ;
}
2016-02-23 02:13:52 +03:00
else if ( mapvoteratio . value < 0.35f )
2015-08-20 13:35:01 +03:00
{
2016-02-23 02:13:52 +03:00
ratio = 0.35f ;
2015-08-20 13:35:01 +03:00
CVAR_SET_STRING ( " mp_mapvoteratio " , " 0.35 " ) ;
}
int iRequiredVotes = 2 ;
if ( iNumPlayers > 2 )
{
2016-02-23 02:13:52 +03:00
iRequiredVotes = int ( iNumPlayers * ratio + 0.5f ) ;
2015-08-20 13:35:01 +03:00
}
if ( iValidVotes < iRequiredVotes )
{
DisplayMaps ( player , 0 ) ;
ClientPrint ( player - > pev , HUD_PRINTCONSOLE , " #Game_required_votes " , UTIL_dtos1 ( iRequiredVotes ) ) ;
}
else
DisplayMaps ( NULL , iVote ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , ChangeLevel ) ;
2015-08-20 13:35:01 +03:00
// Server is changing to a new level, check mapcycle.txt for map name and setup info
2016-05-17 21:01:46 +03:00
void CHalfLifeMultiplay : : __API_VHOOK ( ChangeLevel ) ( )
2015-08-20 13:35:01 +03:00
{
static char szPreviousMapCycleFile [ 256 ] ;
static mapcycle_t mapcycle ;
char szNextMap [ 32 ] ;
char szFirstMapInList [ 32 ] ;
char szCommands [ 1500 ] ;
char szRules [ 1500 ] ;
int minplayers = 0 , maxplayers = 0 ;
// the absolute default level is hldm1
Q_strcpy ( szFirstMapInList , " hldm1 " ) ;
int curplayers ;
2016-02-23 02:13:52 +03:00
bool do_cycle = true ;
2015-08-20 13:35:01 +03:00
// find the map to change to
char * mapcfile = ( char * ) CVAR_GET_STRING ( " mapcyclefile " ) ;
assert ( mapcfile ! = NULL ) ;
szCommands [ 0 ] = ' \0 ' ;
szRules [ 0 ] = ' \0 ' ;
curplayers = CountPlayers ( ) ;
// Has the map cycle filename changed?
2016-02-23 02:13:52 +03:00
if ( Q_stricmp ( mapcfile , szPreviousMapCycleFile ) ! = 0 )
2015-08-20 13:35:01 +03:00
{
Q_strcpy ( szPreviousMapCycleFile , mapcfile ) ;
DestroyMapCycle ( & mapcycle ) ;
if ( ! ReloadMapCycleFile ( mapcfile , & mapcycle ) | | ! mapcycle . items )
{
ALERT ( at_console , " Unable to load map cycle file %s \n " , mapcfile ) ;
2016-02-23 02:13:52 +03:00
do_cycle = false ;
2015-08-20 13:35:01 +03:00
}
}
if ( do_cycle & & mapcycle . items )
{
2016-02-23 02:13:52 +03:00
bool keeplooking = false ;
bool found = false ;
2015-08-20 13:35:01 +03:00
mapcycle_item_s * item ;
// Assume current map
Q_strcpy ( szNextMap , STRING ( gpGlobals - > mapname ) ) ;
Q_strcpy ( szFirstMapInList , STRING ( gpGlobals - > mapname ) ) ;
// Traverse list
for ( item = mapcycle . next_item ; item - > next ! = mapcycle . next_item ; item = item - > next )
{
2016-02-23 02:13:52 +03:00
keeplooking = false ;
2015-08-20 13:35:01 +03:00
assert ( item ! = NULL ) ;
if ( item - > minplayers ! = 0 )
{
if ( curplayers > = item - > minplayers )
{
2016-02-23 02:13:52 +03:00
found = true ;
2015-08-20 13:35:01 +03:00
minplayers = item - > minplayers ;
}
else
{
2016-02-23 02:13:52 +03:00
keeplooking = true ;
2015-08-20 13:35:01 +03:00
}
}
if ( item - > maxplayers ! = 0 )
{
if ( curplayers < = item - > maxplayers )
{
2016-02-23 02:13:52 +03:00
found = true ;
2015-08-20 13:35:01 +03:00
maxplayers = item - > maxplayers ;
}
else
{
2016-02-23 02:13:52 +03:00
keeplooking = true ;
2015-08-20 13:35:01 +03:00
}
}
if ( keeplooking )
{
continue ;
}
2016-02-23 02:13:52 +03:00
found = true ;
2015-08-20 13:35:01 +03:00
break ;
}
if ( ! found )
{
item = mapcycle . next_item ;
}
// Increment next item pointer
mapcycle . next_item = item - > next ;
// Perform logic on current item
Q_strcpy ( szNextMap , item - > mapname ) ;
ExtractCommandString ( item - > rulebuffer , szCommands ) ;
Q_strcpy ( szRules , item - > rulebuffer ) ;
}
if ( ! IS_MAP_VALID ( szNextMap ) )
{
Q_strcpy ( szNextMap , szFirstMapInList ) ;
}
g_fGameOver = TRUE ;
ALERT ( at_console , " CHANGE LEVEL: %s \n " , szNextMap ) ;
if ( minplayers | | maxplayers )
{
ALERT ( at_console , " PLAYER COUNT: min %i max %i current %i \n " , minplayers , maxplayers , curplayers ) ;
}
if ( Q_strlen ( szRules ) > 0 )
{
ALERT ( at_console , " RULES: %s \n " , szRules ) ;
}
CHANGE_LEVEL ( szNextMap , NULL ) ;
if ( Q_strlen ( szCommands ) > 0 )
{
SERVER_COMMAND ( szCommands ) ;
}
2015-07-12 23:32:09 +03:00
}
2015-08-20 13:35:01 +03:00
void CHalfLifeMultiplay : : SendMOTDToClient ( edict_t * client )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
// read from the MOTD.txt file
int length , char_count = 0 ;
char * pFileList ;
char * aFileList = pFileList = ( char * ) LOAD_FILE_FOR_ME ( ( char * ) CVAR_GET_STRING ( " motdfile " ) , & length ) ;
// send the server name
MESSAGE_BEGIN ( MSG_ONE , gmsgServerName , NULL , client ) ;
WRITE_STRING ( CVAR_GET_STRING ( " hostname " ) ) ;
MESSAGE_END ( ) ;
// Send the message of the day
2015-09-30 03:49:22 +03:00
// read it chunk-by-chunk, and send it in parts
2015-08-20 13:35:01 +03:00
while ( pFileList & & * pFileList & & char_count < MAX_MOTD_LENGTH )
{
char chunk [ MAX_MOTD_CHUNK + 1 ] ;
if ( Q_strlen ( pFileList ) < sizeof ( chunk ) )
{
Q_strcpy ( chunk , pFileList ) ;
}
else
{
Q_strncpy ( chunk , pFileList , sizeof ( chunk ) - 1 ) ;
// Q_strncpy doesn't always append the null terminator
chunk [ sizeof ( chunk ) - 1 ] = ' \0 ' ;
}
char_count + = Q_strlen ( chunk ) ;
if ( char_count < MAX_MOTD_LENGTH )
pFileList = aFileList + char_count ;
else
* pFileList = ' \0 ' ;
MESSAGE_BEGIN ( MSG_ONE , gmsgMOTD , NULL , client ) ;
WRITE_BYTE ( ( * pFileList ! = ' \0 ' ) ? FALSE : TRUE ) ; // FALSE means there is still more message to come
WRITE_STRING ( chunk ) ;
MESSAGE_END ( ) ;
}
FREE_FILE ( aFileList ) ;
2015-07-12 23:32:09 +03:00
}
2016-05-17 21:01:46 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , ClientUserInfoChanged , ( CBasePlayer * pPlayer , char * infobuffer ) , pPlayer , infobuffer ) ;
void CHalfLifeMultiplay : : __API_VHOOK ( ClientUserInfoChanged ) ( CBasePlayer * pPlayer , char * infobuffer )
2015-07-12 23:32:09 +03:00
{
2015-08-20 13:35:01 +03:00
pPlayer - > SetPlayerModel ( pPlayer - > m_bHasC4 ) ;
pPlayer - > SetPrefsFromUserinfo ( infobuffer ) ;
2015-07-12 23:32:09 +03:00
}
2016-06-02 01:08:22 +03:00
void CHalfLifeMultiplay : : ServerActivate ( )
{
// Check to see if there's a mapping info paramater entity
CMapInfo * mi = ( CMapInfo * ) UTIL_FindEntityByClassname ( NULL , " info_map_parameters " ) ;
if ( mi ! = nullptr )
{
switch ( mi - > m_iBuyingStatus )
{
case BUYING_EVERYONE :
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
ALERT ( at_console , " EVERYONE CAN BUY! \n " ) ;
break ;
case BUYING_ONLY_CTS :
m_bCTCantBuy = false ;
m_bTCantBuy = true ;
ALERT ( at_console , " Only CT's can buy!! \n " ) ;
break ;
case BUYING_ONLY_TERRORISTS :
m_bCTCantBuy = true ;
m_bTCantBuy = false ;
ALERT ( at_console , " Only T's can buy!! \n " ) ;
break ;
case BUYING_NO_ONE :
m_bCTCantBuy = true ;
m_bTCantBuy = true ;
ALERT ( at_console , " No one can buy!! \n " ) ;
break ;
default :
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
break ;
}
m_flBombRadius = mi - > m_flBombRadius ;
}
ReadMultiplayCvars ( ) ;
CheckMapConditions ( ) ;
}