2015-07-12 23:32:09 +03:00
# include "precompiled.h"
CCStrikeGameMgrHelper g_GameMgrHelper ;
2016-06-08 00:41:07 +03:00
CHalfLifeMultiplay * g_pMPGameRules = nullptr ;
2017-08-19 20:13:45 +03:00
RewardAccount CHalfLifeMultiplay : : m_rgRewardAccountRules [ RR_END ] ;
2017-11-04 02:16:30 +03:00
RewardAccount CHalfLifeMultiplay : : m_rgRewardAccountRules_default [ ] = {
2017-10-12 17:50:56 +03:00
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
REWARD_TOOK_HOSTAGE_ACC , // RR_TOOK_HOSTAGE_ACC
REWARD_TOOK_HOSTAGE , // RR_TOOK_HOSTAGE
2016-06-08 00:41:07 +03:00
} ;
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
{
2017-10-12 17:50:56 +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
2016-12-06 22:21:52 +03:00
if ( ! pPlayer | | ! pPlayer - > IsBot ( ) )
2015-08-20 13:35:01 +03:00
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
bool CHalfLifeMultiplay : : IsInCareerRound ( )
2015-08-20 13:35:01 +03:00
{
return IsMatchStarted ( ) ? false : true ;
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 ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , ServerDeactivate )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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 " ) ;
}
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( bool , CCStrikeGameMgrHelper , CSGameRules , CanPlayerHearPlayer , ( CBasePlayer * pListener , CBasePlayer * pSender ) , pListener , pSender )
bool CCStrikeGameMgrHelper : : __API_HOOK ( CanPlayerHearPlayer ) ( CBasePlayer * pListener , CBasePlayer * pSender )
2015-08-20 13:35:01 +03:00
{
2017-11-01 19:07:52 +03:00
switch ( ( int ) sv_alltalk . value )
{
2018-01-28 20:21:36 +03:00
case 1 : // allows everyone to talk
return true ;
# ifdef REGAMEDLL_ADD
2017-11-01 19:07:52 +03:00
case 2 :
return ( pListener - > m_iTeam = = pSender - > m_iTeam ) ;
case 3 :
return ( pListener - > m_iTeam = = pSender - > m_iTeam | | pListener - > IsObserver ( ) ) ;
2017-11-02 18:00:21 +03:00
case 4 :
return ( pListener - > IsAlive ( ) = = pSender - > IsAlive ( ) | | pSender - > IsAlive ( ) ) ;
2018-01-28 20:21:36 +03:00
default : // Default behavior
2017-11-01 19:07:52 +03:00
break ;
# endif
2018-01-28 20:21:36 +03:00
}
2017-11-01 19:07:52 +03:00
2017-03-01 23:09:43 +03:00
if (
# ifndef REGAMEDLL_FIXES
! pSender - > IsPlayer ( ) | |
# endif
2017-11-02 13:50:37 +03:00
pListener - > m_iTeam ! = pSender - > m_iTeam ) // Different teams can't hear each other
2015-08-20 13:35:01 +03:00
{
return false ;
}
2017-11-02 13:50:37 +03:00
if ( pListener - > IsObserver ( ) ) // 2 spectators don't need isAlive() checks.
2015-08-20 13:35:01 +03:00
{
return true ;
}
2017-11-02 13:50:37 +03:00
BOOL bListenerAlive = pListener - > IsAlive ( ) ;
BOOL bSenderAlive = pSender - > IsAlive ( ) ;
2015-08-20 13:35:01 +03:00
2017-11-04 02:16:30 +03:00
return ( bListenerAlive = = bSenderAlive | | bSenderAlive ) ; // Dead/alive voice chats are separated, but dead can hear alive.
2015-08-20 13:35:01 +03:00
}
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 ) ;
2018-01-28 17:42:22 +03:00
WRITE_SHORT ( PITCH_NORM ) ;
2015-08-02 20:45:57 +03:00
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2017-01-20 17:52:37 +03:00
char * GetTeam ( int team )
2015-07-12 23:32:09 +03:00
{
2017-01-20 17:52:37 +03:00
switch ( team )
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
case CT : return " CT " ;
2017-01-20 17:52:37 +03:00
case TERRORIST : return " TERRORIST " ;
case SPECTATOR : return " SPECTATOR " ;
2017-10-12 17:50:56 +03:00
default : return " " ;
2015-06-30 12:46:07 +03:00
}
2015-07-12 23:32:09 +03:00
}
2016-06-08 00:41:07 +03:00
void CHalfLifeMultiplay : : EndRoundMessage ( const char * sentence , int event )
2015-07-12 23:32:09 +03:00
{
2017-10-12 17:50:56 +03:00
char * team = nullptr ;
2017-01-20 17:52:37 +03:00
const char * message = sentence ;
2016-02-23 02:13:52 +03:00
bool bTeamTriggered = true ;
2015-08-20 13:35:01 +03:00
2017-01-20 17:52:37 +03:00
if ( sentence [ 0 ] = = ' # ' )
message = sentence + 1 ;
2015-08-20 13:35:01 +03:00
2017-01-20 17:52:37 +03:00
if ( sentence [ 0 ] )
2015-08-20 13:35:01 +03:00
{
2017-01-20 17:52:37 +03:00
UTIL_ClientPrintAll ( HUD_PRINTCENTER , sentence ) ;
switch ( event )
2015-12-05 22:40:30 +03:00
{
2017-01-20 17:52:37 +03:00
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 ) ;
// tell bots the terrorists won the round
if ( TheBots )
{
TheBots - > OnEvent ( EVENT_TERRORISTS_WIN ) ;
}
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 ) ;
// tell bots the CTs won the round
if ( TheBots )
{
TheBots - > OnEvent ( EVENT_CTS_WIN ) ;
}
break ;
default :
bTeamTriggered = false ;
// tell bots the round was a draw
if ( TheBots )
{
TheBots - > OnEvent ( EVENT_ROUND_DRAW ) ;
}
break ;
2015-12-05 22:40:30 +03:00
}
2017-01-20 17:52:37 +03:00
if ( bTeamTriggered )
2015-12-05 22:40:30 +03:00
{
2017-01-20 17:52:37 +03:00
UTIL_LogPrintf ( " Team \" %s \" triggered \" %s \" (CT \" %i \" ) (T \" %i \" ) \n " , team , message , m_iNumCTWins , m_iNumTerroristWins ) ;
2015-12-05 22:40:30 +03:00
}
2017-01-20 17:52:37 +03:00
else
2015-12-05 22:40:30 +03:00
{
2017-01-20 17:52:37 +03:00
UTIL_LogPrintf ( " World triggered \" %s \" (CT \" %i \" ) (T \" %i \" ) \n " , message , m_iNumCTWins , m_iNumTerroristWins ) ;
2015-12-05 22:40:30 +03:00
}
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
}
2016-06-18 17:48:19 +03:00
// auto-disable ff
2016-06-22 22:50:14 +03:00
if ( freeforall . value )
2016-06-18 17:48:19 +03:00
{
CVAR_SET_FLOAT ( " mp_friendlyfire " , 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
{
2016-12-06 22:21:52 +03:00
m_bFreezePeriod = TRUE ;
2015-07-02 00:22:46 +03:00
m_VoiceGameMgr . Init ( & g_GameMgrHelper , gpGlobals - > maxClients ) ;
RefreshSkillData ( ) ;
2017-08-19 20:13:45 +03:00
Q_memcpy ( m_rgRewardAccountRules , m_rgRewardAccountRules_default , sizeof ( m_rgRewardAccountRules ) ) ;
2015-07-02 00:22:46 +03:00
m_flIntermissionEndTime = 0 ;
m_flIntermissionStartTime = 0 ;
2016-10-05 18:27:50 +03:00
m_flRestartRoundTime = 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 ;
2017-11-01 18:27:19 +03:00
m_iRoundWinStatus = WINSTATUS_NONE ;
2015-07-02 00:22:46 +03:00
m_iNumCTWins = 0 ;
m_iNumTerroristWins = 0 ;
2017-10-12 17:50:56 +03:00
m_pVIP = nullptr ;
2015-07-02 00:22:46 +03:00
m_iNumCT = 0 ;
m_iNumTerrorist = 0 ;
m_iNumSpawnableCT = 0 ;
m_iNumSpawnableTerrorist = 0 ;
2016-12-06 22:21:52 +03:00
m_bMapHasCameras = FALSE ;
2015-07-02 00:22:46 +03:00
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_bLevelInitialized = false ;
m_tmNextPeriodicThink = 0 ;
2016-12-06 22:21:52 +03:00
m_bGameStarted = false ;
2015-07-12 23:32:09 +03:00
m_bCompleteReset = false ;
m_flRequiredEscapeRatio = 0.5 ;
m_iNumEscapers = 0 ;
2016-07-14 17:12:17 +03:00
// by default everyone can buy
2015-07-12 23:32:09 +03:00
m_bCTCantBuy = false ;
m_bTCantBuy = false ;
2016-07-14 17:12:17 +03:00
2015-07-12 23:32:09 +03:00
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 ;
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 ;
2016-12-06 22:21:52 +03:00
m_bMapHasVIPSafetyZone = FALSE ;
2015-07-02 00:22:46 +03:00
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
2017-10-12 17:50:56 +03:00
for ( int j = 0 ; j < MAX_VIP_QUEUES ; j + + )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ j ] = nullptr ;
2015-08-20 13:35:01 +03:00
}
2015-07-02 00:22:46 +03:00
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! IS_DEDICATED_SERVER ( ) )
# endif
{
// NOTE: cvar cl_himodels refers for the client side
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 ;
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
m_fMaxIdlePeriod = ( ( ( m_iRoundTime < 60 ) ? 60 : m_iRoundTime ) * 2 ) ;
# else
m_fMaxIdlePeriod = ( m_iRoundTime * 2 ) ;
# endif
2015-07-02 00:22:46 +03:00
2016-07-14 17:12:17 +03:00
float flAutoKickIdle = autokick_timeout . value ;
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
{
2016-07-20 19:44:00 +03:00
// 3/31/99
// Added lservercfg file cvar, since listen and dedicated servers should not
// share a single config file. (sjb)
// listen server
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 " ) ;
2016-07-20 19:44:00 +03:00
if ( lservercfgfile & & lservercfgfile [ 0 ] ! = ' \0 ' )
2015-08-20 13:35:01 +03:00
{
char szCommand [ 256 ] ;
2016-07-20 19:44:00 +03:00
ALERT ( at_console , " Executing listen server config file \n " ) ;
2015-08-20 13:35:01 +03:00
Q_sprintf ( szCommand , " exec %s \n " , lservercfgfile ) ;
SERVER_COMMAND ( szCommand ) ;
2015-07-02 00:22:46 +03:00
}
}
2016-10-05 18:27:50 +03:00
m_fRoundStartTime = 0 ;
2016-12-10 21:27:53 +03:00
m_fRoundStartTimeReal = 0 ;
2015-07-02 00:22:46 +03:00
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 ( ) ;
2017-10-12 17:50:56 +03:00
InstallCommands ( ) ;
2015-07-02 00:22:46 +03:00
m_bSkipSpawn = m_bInCareerGame ;
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 " ) ) ;
2017-11-22 20:27:55 +03:00
if ( IsCareer ( ) )
{
CCareerTaskManager : : Create ( ) ;
}
2015-07-02 00:22:46 +03:00
if ( m_iRoundWinDifference < 1 )
{
m_iRoundWinDifference = 1 ;
CVAR_SET_FLOAT ( " mp_windifference " , 1 ) ;
}
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-06-18 17:48:19 +03:00
m_bSkipShowMenu = false ;
2016-04-24 16:52:16 +03:00
m_bNeededPlayers = false ;
m_flEscapeRatio = 0.0f ;
2016-10-05 18:27:50 +03:00
m_flTimeLimit = 0.0f ;
m_flGameStartTime = 0.0f ;
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
m_bTeamBalanced = false ;
2016-04-24 16:52:16 +03:00
# 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
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : RefreshSkillData ( )
2015-07-12 23:32:09 +03:00
{
2016-07-20 19:44:00 +03:00
// load all default values
2015-07-12 23:32:09 +03:00
CGameRules : : RefreshSkillData ( ) ;
2016-07-20 19:44:00 +03:00
// override some values for multiplay.
2017-10-12 17:50:56 +03:00
gSkillData . plrDmg9MM = 12 ; // Glock Round
gSkillData . plrDmgMP5 = 12 ; // MP5 Round
gSkillData . plrDmg357 = 40 ; // 357 Round
gSkillData . plrDmgRPG = 120 ; // RPG
2016-07-20 19:44:00 +03:00
2017-10-12 17:50:56 +03:00
gSkillData . plrDmgM203Grenade = 100 ; // M203 grenade
gSkillData . plrDmgCrossbowClient = 20 ; // Crossbow
2016-07-20 19:44:00 +03:00
// Shotgun buckshot
// fewer pellets in deathmatch
2015-06-30 12:46:07 +03:00
gSkillData . plrDmgBuckshot = 20 ;
2016-07-20 19:44:00 +03:00
2017-10-12 17:50:56 +03:00
// suitcharger
gSkillData . suitchargerCapacity = 30 ;
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , RemoveGuns )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( RemoveGuns ) ( )
2015-07-12 23:32:09 +03:00
{
2017-10-12 17:50:56 +03:00
CBaseEntity * toremove = nullptr ;
2015-06-30 12:46:07 +03:00
2016-12-06 22:21:52 +03:00
while ( ( toremove = UTIL_FindEntityByClassname ( toremove , " weaponbox " ) ) )
2015-06-30 12:46:07 +03:00
( ( CWeaponBox * ) toremove ) - > Kill ( ) ;
2017-10-12 17:50:56 +03:00
toremove = nullptr ;
2015-06-30 12:46:07 +03:00
2016-12-06 22:21:52 +03:00
while ( ( toremove = UTIL_FindEntityByClassname ( toremove , " weapon_shield " ) ) )
2015-06-30 12:46:07 +03:00
{
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
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CleanUpMap )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( CleanUpMap ) ( )
2015-07-12 23:32:09 +03:00
{
2016-10-07 15:19:51 +03:00
# ifdef REGAMEDLL_FIXES
2017-07-01 23:40:10 +03:00
UTIL_RestartOther ( " multi_manager " ) ;
2016-10-07 15:19:51 +03:00
// Release or reset everything entities in depending of flags ObjectCaps
// (FCAP_MUST_RESET / FCAP_MUST_RELEASE)
UTIL_ResetEntities ( ) ;
# endif
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.
2016-07-14 17:12:17 +03:00
UTIL_RestartOther ( " cycler_sprite " ) ;
UTIL_RestartOther ( " light " ) ;
UTIL_RestartOther ( " func_breakable " ) ;
UTIL_RestartOther ( " func_door " ) ;
2017-07-02 17:25:20 +03:00
# ifdef REGAMEDLL_FIXES
UTIL_RestartOther ( " func_button " ) ;
UTIL_RestartOther ( " func_rot_button " ) ;
2017-07-04 15:31:14 +03:00
UTIL_RestartOther ( " env_render " ) ;
2018-01-28 17:42:22 +03:00
UTIL_RestartOther ( " env_spark " ) ;
2017-07-02 17:25:20 +03:00
UTIL_RestartOther ( " trigger_push " ) ;
# endif
2016-07-14 17:12:17 +03:00
UTIL_RestartOther ( " func_water " ) ;
UTIL_RestartOther ( " func_door_rotating " ) ;
UTIL_RestartOther ( " func_tracktrain " ) ;
UTIL_RestartOther ( " func_vehicle " ) ;
UTIL_RestartOther ( " func_train " ) ;
UTIL_RestartOther ( " armoury_entity " ) ;
UTIL_RestartOther ( " ambient_generic " ) ;
UTIL_RestartOther ( " env_sprite " ) ;
2015-08-20 13:35:01 +03:00
2016-09-08 13:04:00 +03:00
# ifdef REGAMEDLL_FIXES
2017-07-02 17:25:20 +03:00
UTIL_RestartOther ( " trigger_once " ) ;
2017-07-02 19:10:00 +03:00
UTIL_RestartOther ( " func_wall_toggle " ) ;
2018-01-28 17:42:22 +03:00
UTIL_RestartOther ( " trigger_hurt " ) ;
2016-09-15 14:27:39 +03:00
UTIL_RestartOther ( " multisource " ) ;
2018-01-28 17:42:22 +03:00
UTIL_RestartOther ( " env_beam " ) ;
UTIL_RestartOther ( " env_laser " ) ;
2016-09-15 14:27:39 +03:00
UTIL_RestartOther ( " trigger_auto " ) ;
2016-09-08 13:04:00 +03:00
# endif
2015-09-30 03:49:22 +03:00
// Remove grenades and C4
2017-07-02 17:25:20 +03:00
const int grenadesRemoveCount = 20 ;
UTIL_RemoveOther ( " grenade " , grenadesRemoveCount ) ;
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.
2016-07-14 17:12:17 +03:00
UTIL_RemoveOther ( " item_thighpack " ) ;
2015-08-02 20:45:57 +03:00
2016-09-25 13:42:25 +03:00
# ifdef REGAMEDLL_FIXES
UTIL_RemoveOther ( " gib " ) ;
UTIL_RemoveOther ( " DelayedUse " ) ;
# endif
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
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , GiveC4 )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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 ;
2017-10-12 17:50:56 +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 ) ;
if ( giveToHumans )
{
2017-10-12 17:50:56 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-08-02 20:45:57 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-16 23:19:21 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer | | FNullEnt ( pPlayer - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
continue ;
2015-08-02 20:45:57 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > pev - > deadflag ! = DEAD_NO | | pPlayer - > m_iTeam ! = TERRORIST )
2015-08-20 13:35:01 +03:00
continue ;
2015-08-02 20:45:57 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer - > IsBot ( ) )
2017-10-12 17:50:56 +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..
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2015-07-12 23:32:09 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pEntity - > IsPlayer ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2015-08-02 20:45:57 +03:00
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
if ( pPlayer - > pev - > deadflag ! = DEAD_NO | | pPlayer - > m_iTeam ! = TERRORIST | | ( giveToHumans & & pPlayer - > IsBot ( ) ) )
2015-08-20 13:35:01 +03:00
continue ;
2016-02-04 03:18:26 +03:00
if ( + + iTemp = = m_iC4Guy )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > MakeBomber ( ) )
2016-12-06 22:21:52 +03:00
{
# ifdef REGAMEDLL_FIXES
// we already have bomber
return ;
# endif
}
2015-08-20 13:35:01 +03:00
}
}
// if there are no players with a bomb
if ( ! IsThereABomber ( ) )
{
m_iC4Guy = 0 ;
2017-11-22 20:27:55 +03:00
pEntity = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( ! pEntity - > IsPlayer ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > pev - > deadflag ! = DEAD_NO | | pPlayer - > m_iTeam ! = TERRORIST )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
pPlayer - > MakeBomber ( ) ;
2015-08-20 13:35:01 +03:00
return ;
}
}
}
void CHalfLifeMultiplay : : QueueCareerRoundEndMenu ( float tmDelay , int iWinStatus )
{
2016-12-06 22:21:52 +03:00
if ( ! TheCareerTasks )
2015-12-05 22:40:30 +03:00
return ;
2015-08-20 13:35:01 +03:00
if ( m_fCareerMatchMenuTime ! = 0.0f )
return ;
m_fCareerRoundMenuTime = tmDelay + gpGlobals - > time ;
2016-12-18 14:27:39 +03:00
bool humansAreCTs = ( Q_strcmp ( humans_join_team . string , " CT " ) = = 0 ) ;
2015-08-20 13:35:01 +03:00
if ( humansAreCTs )
{
2017-10-12 17:50:56 +03:00
CBaseEntity * hostage = nullptr ;
2015-08-20 13:35:01 +03:00
int numHostagesInMap = 0 ;
int numHostagesFollowingHumans = 0 ;
int numHostagesAlive = 0 ;
2016-12-06 22:21:52 +03:00
while ( ( hostage = UTIL_FindEntityByClassname ( hostage , " hostage_entity " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +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 ) ;
2016-12-06 22:21:52 +03:00
if ( ! pHostage - > IsAlive ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-10-12 17:50:56 +03:00
CBasePlayer * pLeader = nullptr ;
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
2017-10-12 17:50:56 +03:00
if ( pLeader = = nullptr )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
numHostagesAlive + + ;
2015-08-20 13:35:01 +03:00
}
else
{
if ( ! pLeader - > IsBot ( ) )
{
2017-10-12 17:50:56 +03:00
numHostagesFollowingHumans + + ;
2015-08-20 13:35:01 +03:00
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 ;
}
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CheckWinConditions )
2016-05-17 21:01:46 +03:00
2016-01-28 05:51:34 +03:00
// Check if the scenario has been won/lost.
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( CheckWinConditions ) ( )
2015-08-20 13:35:01 +03:00
{
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
// If a winner has already been determined.. then get the heck out of here
2017-11-01 18:27:19 +03:00
if ( m_iRoundWinStatus ! = WINSTATUS_NONE )
2016-12-10 21:27:53 +03:00
return ;
# else
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
2017-11-01 18:27:19 +03:00
if ( m_bGameStarted & & m_iRoundWinStatus ! = WINSTATUS_NONE )
2015-08-20 13:35:01 +03:00
return ;
2016-12-10 21:27:53 +03:00
# endif
2015-08-20 13:35:01 +03:00
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 ) ;
2017-12-17 15:29:56 +03:00
if ( HasRoundInfinite ( ) )
return ;
2015-09-30 03:49:22 +03:00
// 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-12-06 22:21:52 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPE ) & & 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-12-06 22:21:52 +03:00
if ( ! ( scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPE ) & & 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.
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
switch ( pPlayer - > m_iTeam )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
case CT :
{
2017-10-12 17:50:56 +03:00
m_iNumCT + + ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu ! = Menu_ChooseAppearance )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
m_iNumSpawnableCT + + ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > pev - > deadflag ! = DEAD_NO )
2017-10-12 17:50:56 +03:00
NumDeadCT + + ;
2015-09-30 03:49:22 +03:00
else
2017-10-12 17:50:56 +03:00
NumAliveCT + + ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
break ;
}
case TERRORIST :
{
2017-10-12 17:50:56 +03:00
m_iNumTerrorist + + ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu ! = Menu_ChooseAppearance )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
m_iNumSpawnableTerrorist + + ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > pev - > deadflag ! = DEAD_NO )
2017-10-12 17:50:56 +03:00
NumDeadTerrorist + + ;
2015-09-30 03:49:22 +03:00
else
2017-10-12 17:50:56 +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.
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_bEscaped )
2017-10-12 17:50:56 +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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : OnRoundEnd_Intercept ( int winStatus , ScenarioEventEndRound event , float tmDelay )
{
return g_ReGameHookchains . m_RoundEnd . callChain ( & CHalfLifeMultiplay : : OnRoundEnd , this , winStatus , event , tmDelay ) ;
}
bool EXT_FUNC CHalfLifeMultiplay : : OnRoundEnd ( int winStatus , ScenarioEventEndRound event , float tmDelay )
{
switch ( event )
{
case ROUND_TARGET_BOMB : return Target_Bombed ( tmDelay ) ;
case ROUND_VIP_ESCAPED : return VIP_Escaped ( tmDelay ) ;
case ROUND_VIP_ASSASSINATED : return VIP_Died ( tmDelay ) ;
case ROUND_TERRORISTS_ESCAPED : return Prison_Escaped ( tmDelay ) ;
case ROUND_CTS_PREVENT_ESCAPE : return Prison_PreventEscape ( tmDelay ) ;
case ROUND_ESCAPING_TERRORISTS_NEUTRALIZED : return Prison_Neutralized ( tmDelay ) ;
case ROUND_BOMB_DEFUSED : return Target_Defused ( tmDelay ) ;
case ROUND_CTS_WIN : return Round_Cts ( tmDelay ) ;
case ROUND_TERRORISTS_WIN : return Round_Ts ( tmDelay ) ;
case ROUND_END_DRAW : return Round_Draw ( tmDelay ) ;
case ROUND_ALL_HOSTAGES_RESCUED : return Hostage_Rescue ( tmDelay ) ;
case ROUND_TARGET_SAVED : return Target_Saved ( tmDelay ) ;
case ROUND_HOSTAGE_NOT_RESCUED : return Hostage_NotRescued ( tmDelay ) ;
case ROUND_TERRORISTS_NOT_ESCAPED : return Prison_NotEscaped ( tmDelay ) ;
case ROUND_VIP_NOT_ESCAPED : return VIP_NotEscaped ( tmDelay ) ;
case ROUND_GAME_COMMENCE : return NeededPlayersCheck ( tmDelay ) ;
case ROUND_GAME_RESTART : return RestartRoundCheck ( tmDelay ) ;
case ROUND_GAME_OVER : return RoundOver ( tmDelay ) ;
case ROUND_NONE :
default :
break ;
}
return false ;
}
bool EXT_FUNC CHalfLifeMultiplay : : NeededPlayersCheck ( float tmDelay )
2016-12-18 14:27:39 +03:00
{
2016-04-24 16:52:16 +03:00
// 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 ;
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Game_Commencing " , ROUND_GAME_COMMENCE ) ;
TerminateRound ( tmDelay , WINSTATUS_DRAW ) ;
2016-04-24 16:52:16 +03:00
2016-12-06 22:21:52 +03:00
m_bGameStarted = true ;
if ( TheBots )
2016-04-24 16:52:16 +03:00
{
TheBots - > OnEvent ( EVENT_GAME_COMMENCE ) ;
}
return true ;
}
2016-12-18 14:27:39 +03:00
bool EXT_FUNC 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 ;
2016-12-06 22:21:52 +03:00
m_bGameStarted = false ;
2015-08-20 13:35:01 +03:00
}
2016-12-06 22:21:52 +03:00
if ( ! m_bGameStarted & & m_iNumSpawnableTerrorist ! = 0 & & m_iNumSpawnableCT ! = 0 )
2015-08-20 13:35:01 +03:00
{
if ( IsCareer ( ) )
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( gpGlobals - > maxClients ) ;
if ( ! pPlayer | | ! pPlayer - > IsBot ( ) )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
return true ;
2015-08-20 13:35:01 +03:00
}
}
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_DRAW , ROUND_GAME_COMMENCE , IsCareer ( ) ? 0 : 3 ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool EXT_FUNC CHalfLifeMultiplay : : VIP_Escaped ( float tmDelay )
2016-12-18 14:27:39 +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 )
{
2017-10-12 17:50:56 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// 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 ) ;
2017-10-12 17:50:56 +03:00
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // VIP rescued
2016-04-24 16:52:16 +03:00
WRITE_SHORT ( ENTINDEX ( m_pVIP - > edict ( ) ) ) ; // index number of primary entity
2017-10-12 17:50:56 +03:00
WRITE_SHORT ( 0 ) ; // index number of secondary entity
WRITE_LONG ( 15 | DRC_FLAG_FINAL ) ; // eventflags (priority and flags)
2016-04-24 16:52:16 +03:00
MESSAGE_END ( ) ;
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #VIP_Escaped " , ROUND_VIP_ESCAPED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
// tell the bots the VIP got out
2016-12-06 22:21:52 +03:00
if ( TheBots )
2016-04-24 16:52:16 +03:00
{
TheBots - > OnEvent ( EVENT_VIP_ESCAPED ) ;
}
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
return true ;
2015-09-30 03:49:22 +03:00
}
2017-10-12 17:50:56 +03:00
bool EXT_FUNC CHalfLifeMultiplay : : VIP_Died ( float tmDelay )
2016-12-18 14:27:39 +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_VIP_ASSASSINATED ] ;
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
2017-10-12 17:50:56 +03:00
m_iNumTerroristWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #VIP_Assassinated " , ROUND_VIP_ASSASSINATED ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
// tell the bots the VIP was killed
2016-12-06 22:21:52 +03:00
if ( TheBots )
2016-04-24 16:52:16 +03:00
{
TheBots - > OnEvent ( EVENT_VIP_ASSASSINATED ) ;
}
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
return true ;
}
2016-12-18 14:27:39 +03:00
bool EXT_FUNC 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
2016-12-06 22:21:52 +03:00
if ( m_bMapHasVIPSafetyZone & & m_pVIP )
2015-08-20 13:35:01 +03:00
{
if ( m_pVIP - > m_bEscaped )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_VIP_ESCAPED , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
// The VIP is dead
else if ( m_pVIP - > pev - > deadflag ! = DEAD_NO )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_VIP_ASSASSINATED , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
}
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
2017-10-12 17:50:56 +03:00
bool EXT_FUNC CHalfLifeMultiplay : : Prison_Escaped ( float tmDelay )
2016-12-18 14:27:39 +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 )
{
2017-10-12 17:50:56 +03:00
m_iNumTerroristWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Terrorists_Escaped " , ROUND_TERRORISTS_ESCAPED ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool EXT_FUNC CHalfLifeMultiplay : : Prison_PreventEscape ( float tmDelay )
2016-12-18 14:27:39 +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 )
{
2017-10-12 17:50:56 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #CTs_PreventEscape " , ROUND_CTS_PREVENT_ESCAPE ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
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
}
2017-10-12 17:50:56 +03:00
bool EXT_FUNC CHalfLifeMultiplay : : Prison_Neutralized ( float tmDelay )
2016-12-18 14:27:39 +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_ESCAPING_TERRORISTS_NEUTRALIZED ] ;
2016-04-24 16:52:16 +03:00
if ( ! m_bNeededPlayers )
{
2017-10-12 17:50:56 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Escaping_Terrorists_Neutralized " , ROUND_ESCAPING_TERRORISTS_NEUTRALIZED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
return true ;
}
2016-12-18 14:27:39 +03:00
bool EXT_FUNC 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 )
{
2017-11-22 20:27:55 +03:00
m_flEscapeRatio = real_t ( m_iHaveEscaped ) / real_t ( 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
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_TERRORISTS_ESCAPED , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
else if ( NumAliveTerrorist = = 0 & & m_flEscapeRatio < m_flRequiredEscapeRatio )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_CTS_PREVENT_ESCAPE , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
else if ( NumAliveTerrorist = = 0 & & NumDeadTerrorist ! = 0 & & m_iNumSpawnableCT > 0 )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_ESCAPING_TERRORISTS_NEUTRALIZED , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
// 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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Target_Bombed ( float tmDelay )
{
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 )
{
2017-10-12 17:50:56 +03:00
m_iNumTerroristWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Target_Bombed " , ROUND_TARGET_BOMB ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Target_Defused ( float tmDelay )
{
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2017-11-01 18:47:40 +03:00
2018-01-21 12:44:25 +03:00
# ifdef REGAMEDLL_ADD
if ( old_bomb_defused_sound . value )
{
Broadcast ( " BOMBDEF " ) ;
}
2017-11-01 18:47:40 +03:00
# endif
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 )
{
2017-10-12 17:50:56 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
}
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Bomb_Defused " , ROUND_BOMB_DEFUSED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2015-08-20 13:35:01 +03:00
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
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 )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_TARGET_BOMB , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
else if ( m_bBombDefused & & m_bMapHasBombTarget )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_BOMB_DEFUSED , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Round_Cts ( float tmDelay )
{
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 )
{
2017-10-12 17:50:56 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
2015-09-30 03:49:22 +03:00
}
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #CTs_Win " , ROUND_CTS_WIN ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
2015-09-30 03:49:22 +03:00
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Round_Ts ( float tmDelay )
{
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 )
{
2017-10-12 17:50:56 +03:00
m_iNumTerroristWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
2015-08-20 13:35:01 +03:00
}
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Terrorists_Win " , ROUND_TERRORISTS_WIN ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
return true ;
2015-09-30 03:49:22 +03:00
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Round_Draw ( float tmDelay )
{
EndRoundMessage ( " #Round_Draw " , ROUND_END_DRAW ) ;
2016-04-24 16:52:16 +03:00
Broadcast ( " rounddraw " ) ;
2017-10-12 17:50:56 +03:00
TerminateRound ( tmDelay , WINSTATUS_DRAW ) ;
2016-04-24 16:52:16 +03:00
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
{
2017-10-12 17:50:56 +03:00
CGrenade * pBomb = nullptr ;
2015-09-30 03:49:22 +03:00
bool nowin = false ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pBomb = UTIL_FindEntityByClassname ( pBomb , " grenade " ) ) )
2015-08-20 13:35:01 +03:00
{
2016-12-09 15:39:16 +03:00
if ( pBomb - > m_bIsC4 & & ! pBomb - > m_bJustBlew )
2015-08-20 13:35:01 +03:00
{
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 )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_CTS_WIN , GetRoundRestartDelay ( ) ) ;
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
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_TERRORISTS_WIN , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
}
else if ( NumAliveCT = = 0 & & NumAliveTerrorist = = 0 )
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_DRAW , ROUND_END_DRAW , GetRoundRestartDelay ( ) ) ;
2016-04-24 16:52:16 +03:00
}
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
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Hostage_Rescue ( float tmDelay )
{
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 )
{
2017-11-22 20:27:55 +03:00
m_iNumCTWins + + ;
2016-04-24 16:52:16 +03:00
// Update the clients team score
UpdateTeamScores ( ) ;
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #All_Hostages_Rescued " , ROUND_ALL_HOSTAGES_RESCUED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
// tell the bots all the hostages have been rescued
2016-12-06 22:21:52 +03:00
if ( TheBots )
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 ( ) )
{
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2016-04-24 16:52:16 +03:00
{
TheCareerTasks - > HandleEvent ( EVENT_ALL_HOSTAGES_RESCUED ) ;
}
2015-08-20 13:35:01 +03:00
}
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
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.
2017-11-22 20:27:55 +03:00
CBaseEntity * pHostage = nullptr ;
int hostagesCount = 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 ;
2017-11-22 20:27:55 +03:00
while ( ( pHostage = UTIL_FindEntityByClassname ( pHostage , " hostage_entity " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
hostagesCount + + ;
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
2017-11-22 20:27:55 +03:00
if ( pHostage - > IsAlive ( ) )
2015-08-20 13:35:01 +03:00
{
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.
2017-11-22 20:27:55 +03:00
if ( ! bHostageAlive & & hostagesCount > 0 )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( m_iHostagesRescued > = ( hostagesCount * 0.5f ) )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
return OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_ALL_HOSTAGES_RESCUED , GetRoundRestartDelay ( ) ) ;
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
{
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
pPlayer - > SwitchTeam ( ) ;
2015-08-20 13:35:01 +03:00
}
2015-09-30 03:49:22 +03:00
// Swap Team victories
2016-10-05 18:27:50 +03:00
SWAP ( m_iNumTerroristWins , m_iNumCTWins ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Update the clients team score
2015-08-20 13:35:01 +03:00
UpdateTeamScores ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , BalanceTeams )
2016-05-17 21:01:46 +03:00
2016-12-06 22:21:52 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( BalanceTeams ) ( )
2015-08-20 13:35:01 +03:00
{
int iNumToSwap ;
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
TeamName iTeamToSwap = UNASSIGNED ;
m_bTeamBalanced = false ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// The ratio for teams is different for Assasination maps
2016-12-06 22:21:52 +03:00
if ( m_bMapHasVIPSafetyZone )
2015-08-20 13:35:01 +03:00
{
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 ;
2017-10-12 17:50:56 +03:00
CBasePlayer * toSwap = nullptr ;
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
for ( int i = 1 ; i < = iNumToSwap ; i + + )
2015-08-20 13:35:01 +03:00
{
iHighestUserID = 0 ;
2017-10-12 17:50:56 +03:00
toSwap = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2016-12-06 22:21:52 +03:00
// search for player with highest UserID = most recently joined to switch over
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
if ( pPlayer - > CanSwitchTeam ( iTeamToSwap ) & & GETPLAYERUSERID ( pPlayer - > edict ( ) ) > iHighestUserID )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
iHighestUserID = GETPLAYERUSERID ( pPlayer - > edict ( ) ) ;
toSwap = pPlayer ;
2015-08-20 13:35:01 +03:00
}
}
2016-07-14 17:12:17 +03:00
if ( toSwap ) {
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
m_bTeamBalanced = true ;
2015-08-20 13:35:01 +03:00
toSwap - > SwitchTeam ( ) ;
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
m_bTeamBalanced = false ;
2015-08-20 13:35:01 +03:00
}
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , CheckMapConditions )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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
2017-10-12 17:50:56 +03:00
if ( UTIL_FindEntityByClassname ( nullptr , " func_bomb_target " ) )
2015-08-20 13:35:01 +03:00
{
m_bMapHasBombTarget = true ;
m_bMapHasBombZone = true ;
}
2017-10-12 17:50:56 +03:00
else if ( UTIL_FindEntityByClassname ( nullptr , " info_bomb_target " ) )
2015-08-20 13:35:01 +03:00
{
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
2017-10-12 17:50:56 +03:00
m_bMapHasRescueZone = ( UTIL_FindEntityByClassname ( nullptr , " func_hostage_rescue " ) ! = nullptr ) ;
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
2017-10-12 17:50:56 +03:00
m_bMapHasBuyZone = ( UTIL_FindEntityByClassname ( nullptr , " func_buyzone " ) ! = nullptr ) ;
2015-09-30 03:49:22 +03:00
// GOOSEMAN : See if this map has func_escapezone entities
2017-10-12 17:50:56 +03:00
m_bMapHasEscapeZone = ( UTIL_FindEntityByClassname ( nullptr , " func_escapezone " ) ! = nullptr ) ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Check to see if this map has VIP safety zones
2017-10-12 17:50:56 +03:00
m_bMapHasVIPSafetyZone = ( UTIL_FindEntityByClassname ( nullptr , " func_vip_safetyzone " ) ! = nullptr ) ;
2015-08-20 13:35:01 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , RestartRound )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( RestartRound ) ( )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// tell bots that the round is restarting
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > RestartRound ( ) ;
}
2015-08-20 13:35:01 +03:00
2016-12-06 22:21:52 +03:00
if ( g_pHostages )
2015-08-20 13:35:01 +03:00
{
g_pHostages - > RestartRound ( ) ;
}
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bCompleteReset )
2017-01-04 00:52:03 +03:00
# endif
2017-01-20 17:52:37 +03:00
{
2017-11-22 20:27:55 +03:00
m_iTotalRoundsPlayed + + ;
2017-01-20 17:52:37 +03:00
}
2017-01-04 00:52:03 +03:00
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 ( ) ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_iRoundTime > 0 )
# endif
{
MESSAGE_BEGIN ( MSG_ALL , gmsgShowTimer ) ;
MESSAGE_END ( ) ;
}
2015-08-20 13:35:01 +03:00
}
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 ) ;
2017-10-12 17:50:56 +03:00
WRITE_BYTE ( 0 ) ; // 0 = all players
2015-09-30 03:49:22 +03:00
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 ( ) ;
2016-12-06 22:21:52 +03:00
auto shouldBalancedOnNextRound = [ ] ( ) - > bool
{
# ifdef REGAMEDLL_ADD
return autoteambalance . value = = 1 ;
# else
return autoteambalance . value > 0 ;
# endif
} ;
if ( shouldBalancedOnNextRound ( ) & & 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
{
2017-11-22 20:27:55 +03:00
m_iUnBalancedRounds + + ;
2015-09-30 03:49:22 +03:00
}
2015-08-20 13:35:01 +03:00
else
2017-11-22 20:27:55 +03:00
{
2015-08-20 13:35:01 +03:00
m_iUnBalancedRounds = 0 ;
2017-11-22 20:27:55 +03:00
}
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Warn the players of an impending auto-balance next round...
2016-12-06 22:21:52 +03:00
if ( shouldBalancedOnNextRound ( ) & & m_iUnBalancedRounds = = 1 )
2015-08-20 13:35:01 +03:00
{
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Auto_Team_Balance_Next_Round " ) ;
}
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
2017-01-20 17:52:37 +03:00
else if ( autoteambalance . value > = 2 & & m_iUnBalancedRounds > = 1 )
2016-12-06 22:21:52 +03:00
{
BalanceTeams ( ) ;
}
# endif
2015-08-20 13:35:01 +03:00
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
2016-10-05 18:27:50 +03:00
m_flGameStartTime = gpGlobals - > time ;
2015-08-20 13:35:01 +03:00
2015-09-30 03:49:22 +03:00
// Reset timelimit
2015-08-20 13:35:01 +03:00
if ( timelimit . value )
2016-10-05 18:27:50 +03:00
m_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
2017-10-12 17:50:56 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
if ( pPlayer & & ! FNullEnt ( pPlayer - > pev ) )
{
pPlayer - > Reset ( ) ;
}
2015-08-20 13:35:01 +03:00
}
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
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
2016-07-14 17:12:17 +03:00
float flAutoKickIdle = autokick_timeout . value ;
2015-08-20 13:35:01 +03:00
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
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
m_fMaxIdlePeriod = ( ( ( m_iRoundTime < 60 ) ? 60 : m_iRoundTime ) * 2 ) ;
# else
2015-08-20 13:35:01 +03:00
m_fMaxIdlePeriod = ( m_iRoundTime * 2 ) ;
2016-12-10 21:27:53 +03:00
# endif
2015-08-20 13:35:01 +03:00
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
2016-07-14 17:12:17 +03:00
if ( g_pMapInfo )
g_pMapInfo - > CheckMapInfo ( ) ;
2015-08-20 13:35:01 +03:00
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..
2017-10-12 17:50:56 +03:00
m_iNumEscapeRounds + + ;
2015-08-20 13:35:01 +03:00
}
2016-12-06 22:21:52 +03:00
if ( m_bMapHasVIPSafetyZone )
2015-08-20 13:35:01 +03:00
{
PickNextVIP ( ) ;
2017-10-12 17:50:56 +03:00
m_iConsecutiveVIP + + ;
2015-08-20 13:35:01 +03:00
}
int acct_tmp = 0 ;
2017-10-12 17:50:56 +03:00
CBaseEntity * hostage = nullptr ;
2015-08-20 13:35:01 +03:00
2016-12-06 22:21:52 +03:00
while ( ( hostage = UTIL_FindEntityByClassname ( hostage , " hostage_entity " ) ) )
2015-08-20 13:35:01 +03:00
{
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
2017-10-12 17:50:56 +03:00
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
2016-12-10 21:27:53 +03:00
m_fRoundStartTime = m_fRoundStartTimeReal = 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 )
{
2017-10-12 17:50:56 +03:00
// No extra cash!
2015-09-30 03:49:22 +03:00
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
}
2016-09-26 23:16:33 +03:00
# ifdef REGAMEDLL_FIXES
// Respawn entities (glass, doors, etc..)
CleanUpMap ( ) ;
# endif
2015-09-30 03:49:22 +03:00
// tell bots that the round is restarting
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( pEntity - > pev - > flags = = FL_DORMANT )
2015-08-20 13:35:01 +03:00
continue ;
2015-09-16 23:19:21 +03:00
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
pPlayer - > m_iNumSpawns = 0 ;
pPlayer - > m_bTeamChanged = false ;
2015-08-20 13:35:01 +03:00
2016-12-06 22:21:52 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: unreachable code
2017-11-22 20:27:55 +03:00
if ( ! pPlayer - > IsPlayer ( ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > SyncRoundTimer ( ) ;
2015-08-20 13:35:01 +03:00
}
2016-12-06 22:21:52 +03:00
# endif
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = CT )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ! pPlayer - > m_bReceivesNoMoneyNextRound )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > AddAccount ( m_iAccountCT , RT_ROUND_BONUS ) ;
2015-08-20 13:35:01 +03:00
}
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iTeam = = TERRORIST )
2015-08-20 13:35:01 +03:00
{
2015-09-30 03:49:22 +03:00
// Add another potential escaper to the mix!
2017-10-12 17:50:56 +03:00
m_iNumEscapers + + ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer - > m_bReceivesNoMoneyNextRound )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > 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
2017-11-22 20:27:55 +03:00
pPlayer - > m_bNotKilled = false ;
2015-08-20 13:35:01 +03:00
}
}
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam ! = UNASSIGNED & & pPlayer - > m_iTeam ! = SPECTATOR )
2015-08-20 13:35:01 +03:00
{
2016-09-26 23:16:33 +03:00
# ifdef REGAMEDLL_FIXES
// remove the c4 if the player is carrying it
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_bHasC4 ) {
pPlayer - > RemoveBomb ( ) ;
2016-09-26 23:16:33 +03:00
}
# else
2015-09-30 03:49:22 +03:00
// drop the c4 if the player is carrying it
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_bHasC4 ) {
pPlayer - > DropPlayerItem ( " weapon_c4 " ) ;
2015-08-20 13:35:01 +03:00
}
2016-09-26 23:16:33 +03:00
# endif
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
pPlayer - > RoundRespawn ( ) ;
2015-08-20 13:35:01 +03:00
}
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
}
2016-09-26 23:16:33 +03:00
// Moved above the loop spawning the players
# ifndef REGAMEDLL_FIXES
2015-08-20 13:35:01 +03:00
CleanUpMap ( ) ;
2016-09-26 23:16:33 +03:00
# endif
2015-08-20 13:35:01 +03:00
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 ( ) ;
}
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
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 ;
2016-10-05 18:27:50 +03:00
m_flRestartRoundTime = 0.0 ;
2015-09-30 03:49:22 +03:00
m_iAccountTerrorist = m_iAccountCT = 0 ;
2015-08-20 13:35:01 +03:00
m_iHostagesRescued = 0 ;
m_iHostagesTouched = 0 ;
2017-11-01 18:27:19 +03:00
m_iRoundWinStatus = WINSTATUS_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
{
2017-10-12 17:50:56 +03:00
CBasePlayer * pPlayer = nullptr ;
2017-11-22 20:27:55 +03:00
while ( ( pPlayer = UTIL_FindEntityByClassname ( pPlayer , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
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
{
2017-11-20 18:34:43 +03:00
CGrenade * pBomb = nullptr ;
2016-02-23 02:13:52 +03:00
bool bFoundBomb = false ;
2015-08-20 13:35:01 +03:00
2017-11-20 18:34:43 +03:00
while ( ( pBomb = UTIL_FindEntityByClassname ( pBomb , " grenade " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-20 18:34:43 +03:00
if ( pBomb - > m_bIsC4 )
2015-08-20 13:35:01 +03:00
{
2016-02-23 02:13:52 +03:00
bFoundBomb = true ;
2015-08-20 13:35:01 +03:00
break ;
}
}
2017-10-12 17:50:56 +03:00
if ( bFoundBomb | | ( UTIL_FindEntityByClassname ( nullptr , " weapon_c4 " ) ) )
2015-08-20 13:35:01 +03:00
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
{
2017-11-22 20:27:55 +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 ] ;
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ i + 1 ] = nullptr ;
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 ] ;
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ i + 1 ] = nullptr ;
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
{
2017-10-12 17:50:56 +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 ] ;
2016-12-06 22:21:52 +03:00
if ( toCheck & & toCheck - > m_iTeam ! = CT )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ i ] = nullptr ;
2015-08-20 13:35:01 +03:00
}
}
StackVIPQueue ( ) ;
2016-12-06 22:21:52 +03:00
return ( ! m_pVIPQueue [ 0 ] & & ! m_pVIPQueue [ 1 ] & & ! m_pVIPQueue [ 2 ] & & ! m_pVIPQueue [ 3 ] & & ! m_pVIPQueue [ 4 ] ) ;
2015-08-20 13:35:01 +03:00
}
bool CHalfLifeMultiplay : : AddToVIPQueue ( CBasePlayer * toAdd )
{
2017-10-12 17:50:56 +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 ] ;
2016-12-06 22:21:52 +03:00
if ( toCheck & & toCheck - > m_iTeam ! = CT )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ i ] = nullptr ;
2015-08-20 13:35:01 +03:00
}
}
StackVIPQueue ( ) ;
if ( toAdd - > m_iTeam = = CT )
{
int j ;
2017-10-12 17:50:56 +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
2017-10-12 17:50:56 +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 ( ) ) ;
2017-10-12 17:50:56 +03:00
int numSkins = AreRunningCZero ( ) ? 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 :
2017-10-12 17:50:56 +03:00
if ( AreRunningCZero ( ) )
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.
2016-12-06 22:21:52 +03:00
if ( m_pVIP )
2015-08-20 13:35:01 +03:00
{
ResetCurrentVIP ( ) ;
}
2015-07-12 23:32:09 +03:00
2017-10-12 17:50:56 +03:00
for ( int i = 0 ; i < MAX_VIP_QUEUES ; i + + )
2015-08-20 13:35:01 +03:00
{
2016-12-06 22:21:52 +03:00
if ( m_pVIPQueue [ i ] )
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 ( ) ;
2017-10-12 17:50:56 +03:00
m_pVIPQueue [ i ] = nullptr ; // remove this player from the VIP queue
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 ;
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2017-10-12 17:50:56 +03:00
CBasePlayer * pLastPlayer = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ! FNullEnt ( pEntity - > edict ( ) ) )
break ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
continue ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
if ( pPlayer - > m_iTeam = = CT & & iCount = = m_iLastPick )
{
if ( pPlayer = = m_pVIP & & pLastPlayer )
pPlayer = pLastPlayer ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
// Remove the current VIP from his VIP status and make him a regular CT.
if ( m_pVIP )
{
ResetCurrentVIP ( ) ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
pPlayer - > MakeVIP ( ) ;
m_iConsecutiveVIP = 0 ;
break ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = CT )
iCount + + ;
if ( pPlayer - > m_iTeam ! = SPECTATOR )
pLastPlayer = pPlayer ;
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.
2017-10-12 17:50:56 +03:00
else if ( m_pVIP = = nullptr )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ! FNullEnt ( pEntity - > edict ( ) ) )
break ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( pEntity - > IsDormant ( ) )
continue ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
if ( pPlayer - > m_iTeam = = CT )
{
pPlayer - > MakeVIP ( ) ;
m_iConsecutiveVIP = 0 ;
return ;
}
2015-08-20 13:35:01 +03:00
}
}
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : Think ( )
2015-08-20 13:35:01 +03:00
{
MonitorTutorStatus ( ) ;
m_VoiceGameMgr . Update ( gpGlobals - > frametime ) ;
2017-10-19 20:12:02 +03:00
if ( g_psv_clienttrace - > value ! = 1.0f )
2015-08-20 13:35:01 +03:00
{
CVAR_SET_FLOAT ( " sv_clienttrace " , 1 ) ;
}
2016-10-05 18:27:50 +03:00
if ( ! m_fRoundStartTime )
2015-08-20 13:35:01 +03:00
{
2016-10-05 18:27:50 +03:00
// initialize the timer time stamps, this happens once only
2016-12-10 21:27:53 +03:00
m_fRoundStartTime = m_fRoundStartTimeReal = 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
2016-10-05 18:27:50 +03:00
// did somebody hit the fraglimit ?
if ( CheckFragLimit ( ) )
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
}
2016-10-05 18:27:50 +03:00
if ( m_flRestartRoundTime > 0.0f & & m_flRestartRoundTime < = gpGlobals - > time )
2015-08-20 13:35:01 +03:00
{
if ( ! IsCareer ( ) | | ! m_fCareerRoundMenuTime )
{
RestartRound ( ) ;
}
2016-12-06 22:21:52 +03:00
else if ( TheCareerTasks )
2015-08-20 13:35:01 +03:00
{
bool isBotSpeaking = false ;
2016-10-05 18:27:50 +03:00
if ( m_flRestartRoundTime + 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 ;
2017-10-12 17:50:56 +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
2016-12-06 22:21:52 +03:00
if ( pPlayer & & ! pPlayer - > IsBot ( ) )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCZCareerHUD , nullptr , pPlayer - > pev ) ;
2015-08-20 13:35:01 +03:00
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 ;
2016-10-05 18:27:50 +03:00
m_flRestartRoundTime = gpGlobals - > time + 100000.0 ;
2015-08-20 13:35:01 +03:00
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
2016-12-06 22:21:52 +03:00
if ( TheTutor )
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
2016-12-06 22:21:52 +03:00
if ( m_bGameOver )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
// bounds check
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 ) ) ;
m_flIntermissionEndTime = m_flIntermissionStartTime + mp_chattime . value ;
// check to see if we should change levels now
if ( m_flIntermissionEndTime < gpGlobals - > time & & ! IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
if ( ! UTIL_HumansInGame ( ) // if only bots, just change immediately
2017-11-01 18:50:24 +03:00
# ifdef REGAMEDLL_FIXES
| | IsMultiplayer ( )
# endif
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
{
2016-10-05 18:27:50 +03:00
if ( timelimit . value < 0 )
2015-09-30 03:49:22 +03:00
{
CVAR_SET_FLOAT ( " mp_timelimit " , 0 ) ;
return false ;
}
if ( ! IsCareer ( ) )
{
2016-10-05 18:27:50 +03:00
if ( timelimit . value )
2015-12-09 01:39:54 +03:00
{
2016-10-05 18:27:50 +03:00
m_flTimeLimit = m_flGameStartTime + timelimit . value * 60.0f ;
if ( gpGlobals - > time > = m_flTimeLimit )
{
ALERT ( at_console , " Changing maps because time limit has been met \n " ) ;
GoToIntermission ( ) ;
return true ;
}
2015-09-30 03:49:22 +03:00
}
2016-10-05 18:27:50 +03:00
# ifdef REGAMEDLL_ADD
static int lastTime = 0 ;
int timeRemaining = ( int ) ( timelimit . value ? ( m_flTimeLimit - gpGlobals - > time ) : 0 ) ;
// Updates once per second
if ( timeRemaining ! = lastTime )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
lastTime = timeRemaining ;
g_engfuncs . pfnCvar_DirectSet ( & timeleft , UTIL_VarArgs ( " %02d:%02d " , timeRemaining / 60 , timeRemaining % 60 ) ) ;
2015-09-30 03:49:22 +03:00
}
2016-10-05 18:27:50 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
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-10-05 18:27:50 +03:00
bool CHalfLifeMultiplay : : CheckFragLimit ( )
{
# ifdef REGAMEDLL_ADD
int fragsRemaining = 0 ;
if ( fraglimit . value )
{
int bestFrags = fraglimit . value ;
// check if any player is over the frag limit
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
{
auto pPlayer = UTIL_PlayerByIndex ( i ) ;
if ( ! pPlayer | | pPlayer - > has_disconnected )
continue ;
if ( pPlayer - > pev - > frags > = fraglimit . value )
{
ALERT ( at_console , " Changing maps because frag limit has been met \n " ) ;
GoToIntermission ( ) ;
return true ;
}
int remain = ( int ) ( fraglimit . value - pPlayer - > pev - > frags ) ;
if ( remain < bestFrags )
{
bestFrags = remain ;
}
}
fragsRemaining = bestFrags ;
}
static int lastFrags = 0 ;
// Updates when frags change
if ( fragsRemaining ! = lastFrags )
{
lastFrags = fragsRemaining ;
g_engfuncs . pfnCvar_DirectSet ( & fragsleft , UTIL_VarArgs ( " %i " , fragsRemaining ) ) ;
}
# endif
return false ;
}
2016-12-18 14:27:39 +03:00
void EXT_FUNC CHalfLifeMultiplay : : OnRoundFreezeEnd ( )
2015-09-30 03:49:22 +03:00
{
// 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 ) ) ;
}
2016-12-06 22:21:52 +03:00
else if ( m_bMapHasVIPSafetyZone )
2015-09-30 03:49:22 +03:00
{
Q_strncpy ( CT_sentence , " %!MRAD_VIP " , sizeof ( CT_sentence ) ) ;
Q_strncpy ( T_sentence , " %!MRAD_LOCKNLOAD " , sizeof ( T_sentence ) ) ;
}
// Reset the round time
2016-12-18 14:27:39 +03:00
m_fRoundStartTimeReal = m_fRoundStartTime = gpGlobals - > time ;
2015-09-30 03:49:22 +03:00
// in seconds
m_iRoundTimeSecs = m_iRoundTime ;
bool bCTPlayed = false ;
bool bTPlayed = false ;
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-12-05 22:40:30 +03:00
{
TheCareerTasks - > HandleEvent ( EVENT_ROUND_START ) ;
}
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +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 ( ) ;
}
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_ROUND_START ) ;
}
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-12-05 22:40:30 +03:00
{
TheCareerTasks - > HandleEvent ( EVENT_ROUND_START ) ;
}
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
void CHalfLifeMultiplay : : CheckFreezePeriodExpired ( )
{
if ( GetRoundRemainingTime ( ) > 0 )
return ;
g_ReGameHookchains . m_CSGameRules_OnRoundFreezeEnd . callChain ( & CHalfLifeMultiplay : : OnRoundFreezeEnd , this ) ;
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Target_Saved ( float tmDelay )
{
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountCT + = m_rgRewardAccountRules [ RR_TARGET_BOMB_SAVED ] ;
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bNeededPlayers )
{
m_iNumCTWins + + ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
# else
2016-04-24 16:52:16 +03:00
m_iNumCTWins + + ;
2016-12-10 21:27:53 +03:00
# endif
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Target_Saved " , ROUND_TARGET_SAVED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
2016-12-10 21:27:53 +03:00
# ifndef REGAMEDLL_FIXES
2016-04-24 16:52:16 +03:00
UpdateTeamScores ( ) ;
2016-12-10 21:27:53 +03:00
# endif
2017-10-12 17:50:56 +03:00
2016-04-24 16:52:16 +03:00
MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound ( TERRORIST ) ;
return true ;
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Hostage_NotRescued ( float tmDelay )
{
2016-04-24 16:52:16 +03:00
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_HOSTAGE_NOT_RESCUED ] ;
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bNeededPlayers )
{
m_iNumTerroristWins + + ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
# else
2016-04-24 16:52:16 +03:00
m_iNumTerroristWins + + ;
2016-12-10 21:27:53 +03:00
# endif
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Hostages_Not_Rescued " , ROUND_HOSTAGE_NOT_RESCUED ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
2016-12-10 21:27:53 +03:00
# ifndef REGAMEDLL_FIXES
2016-04-24 16:52:16 +03:00
UpdateTeamScores ( ) ;
2016-12-10 21:27:53 +03:00
# endif
2017-10-12 17:50:56 +03:00
2016-04-24 16:52:16 +03:00
MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound ( CT ) ;
return true ;
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : Prison_NotEscaped ( float tmDelay )
{
2016-04-24 16:52:16 +03:00
Broadcast ( " ctwin " ) ;
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bNeededPlayers )
{
m_iNumCTWins + + ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
# else
2016-04-24 16:52:16 +03:00
m_iNumCTWins + + ;
2016-12-10 21:27:53 +03:00
# endif
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #Terrorists_Not_Escaped " , ROUND_TERRORISTS_NOT_ESCAPED ) ;
TerminateRound ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_CTS ) ;
2016-04-24 16:52:16 +03:00
}
2016-12-10 21:27:53 +03:00
# ifndef REGAMEDLL_FIXES
2016-04-24 16:52:16 +03:00
UpdateTeamScores ( ) ;
2016-12-10 21:27:53 +03:00
# endif
2016-04-24 16:52:16 +03:00
return true ;
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : VIP_NotEscaped ( float tmDelay )
{
2016-04-24 16:52:16 +03:00
Broadcast ( " terwin " ) ;
2016-06-08 00:41:07 +03:00
m_iAccountTerrorist + = m_rgRewardAccountRules [ RR_VIP_NOT_ESCAPED ] ;
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bNeededPlayers )
{
m_iNumTerroristWins + + ;
// Update the clients team score
UpdateTeamScores ( ) ;
}
# else
2016-04-24 16:52:16 +03:00
m_iNumTerroristWins + + ;
2016-12-10 21:27:53 +03:00
# endif
2016-04-24 16:52:16 +03:00
2017-10-12 17:50:56 +03:00
EndRoundMessage ( " #VIP_Not_Escaped " , ROUND_VIP_NOT_ESCAPED ) ;
TerminateRound ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
QueueCareerRoundEndMenu ( tmDelay , WINSTATUS_TERRORISTS ) ;
2016-04-24 16:52:16 +03:00
}
2016-12-10 21:27:53 +03:00
# ifndef REGAMEDLL_FIXES
2016-04-24 16:52:16 +03:00
UpdateTeamScores ( ) ;
2016-12-10 21:27:53 +03:00
# endif
2017-10-12 17:50:56 +03:00
2016-04-24 16:52:16 +03:00
return true ;
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : RoundOver ( float tmDelay )
2016-12-06 22:21:52 +03:00
{
2017-11-20 18:34:43 +03:00
EndRoundMessage ( " #Cstrike_Tutor_Round_Over " , ROUND_GAME_OVER ) ;
2016-12-06 22:21:52 +03:00
Broadcast ( " rounddraw " ) ;
2017-10-12 17:50:56 +03:00
TerminateRound ( tmDelay , WINSTATUS_DRAW ) ;
2016-12-06 22:21:52 +03:00
return true ;
}
2016-01-28 07:48:09 +03:00
void CHalfLifeMultiplay : : CheckRoundTimeExpired ( )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
if ( HasRoundInfinite ( SCENARIO_BLOCK_TIME_EXPRIRED ) )
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
2017-10-12 17:50:56 +03:00
CGrenade * pBomb = ( CGrenade * ) UTIL_FindEntityByClassname ( nullptr , " grenade " ) ;
2015-09-30 03:49:22 +03:00
2016-10-05 18:27:50 +03:00
if ( pBomb )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
if ( ! pBomb - > m_bJustBlew )
flEndRoundTime = pBomb - > m_flC4Blow ;
2015-09-30 03:49:22 +03:00
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 )
{
2017-10-12 17:50:56 +03:00
if ( ! OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_TARGET_SAVED , GetRoundRestartDelay ( ) ) )
2016-04-24 16:52:16 +03:00
return ;
2015-09-30 03:49:22 +03:00
}
2017-10-12 17:50:56 +03:00
else if ( UTIL_FindEntityByClassname ( nullptr , " hostage_entity " ) )
2015-09-30 03:49:22 +03:00
{
2017-10-12 17:50:56 +03:00
if ( ! OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_HOSTAGE_NOT_RESCUED , GetRoundRestartDelay ( ) ) )
2016-04-24 16:52:16 +03:00
return ;
2015-09-30 03:49:22 +03:00
}
else if ( m_bMapHasEscapeZone )
{
2017-10-12 17:50:56 +03:00
if ( ! OnRoundEnd_Intercept ( WINSTATUS_CTS , ROUND_TERRORISTS_NOT_ESCAPED , GetRoundRestartDelay ( ) ) )
2016-04-24 16:52:16 +03:00
return ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
else if ( m_bMapHasVIPSafetyZone )
2015-09-30 03:49:22 +03:00
{
2017-10-12 17:50:56 +03:00
if ( ! OnRoundEnd_Intercept ( WINSTATUS_TERRORISTS , ROUND_VIP_NOT_ESCAPED , GetRoundRestartDelay ( ) ) )
2016-04-24 16:52:16 +03:00
return ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
else if ( roundover . value )
{
// round is over
2017-10-12 17:50:56 +03:00
if ( ! OnRoundEnd_Intercept ( WINSTATUS_DRAW , ROUND_GAME_OVER , GetRoundRestartDelay ( ) ) )
2016-12-06 22:21:52 +03:00
return ;
}
# endif
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.
2016-10-05 18:27:50 +03:00
m_fRoundStartTime = gpGlobals - > time + 60.0f ;
2015-09-30 03:49:22 +03:00
}
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
2017-10-12 17:50:56 +03:00
CBaseEntity * pEnt = nullptr ;
2015-09-30 03:49:22 +03:00
m_iSpawnPointCount_Terrorist = 0 ;
m_iSpawnPointCount_CT = 0 ;
2017-10-12 17:50:56 +03:00
while ( ( pEnt = UTIL_FindEntityByClassname ( pEnt , " info_player_deathmatch " ) ) )
m_iSpawnPointCount_Terrorist + + ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
while ( ( pEnt = UTIL_FindEntityByClassname ( pEnt , " info_player_start " ) ) )
m_iSpawnPointCount_CT + + ;
2015-09-30 03:49:22 +03:00
m_bLevelInitialized = true ;
}
}
2017-10-12 17:50:56 +03:00
bool CHalfLifeMultiplay : : RestartRoundCheck ( float tmDelay )
{
// log the restart
UTIL_LogPrintf ( " World triggered \" Restart_Round_(%i_%s) \" \n " , ( int ) tmDelay , ( tmDelay = = 1 ) ? " second " : " seconds " ) ;
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 ) ;
// let the players know
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Game_will_restart_in " , UTIL_dtos1 ( tmDelay ) , ( tmDelay = = 1 ) ? " SECOND " : " SECONDS " ) ;
UTIL_ClientPrintAll ( HUD_PRINTCONSOLE , " #Game_will_restart_in_console " , UTIL_dtos1 ( tmDelay ) , ( tmDelay = = 1 ) ? " SECOND " : " SECONDS " ) ;
m_flRestartRoundTime = gpGlobals - > time + tmDelay ;
m_bCompleteReset = true ;
CVAR_SET_FLOAT ( " sv_restartround " , 0 ) ;
CVAR_SET_FLOAT ( " sv_restart " , 0 ) ;
CareerRestart ( ) ;
2016-12-06 22:21:52 +03:00
return 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
2017-10-12 17:50:56 +03:00
OnRoundEnd_Intercept ( WINSTATUS_NONE , ROUND_GAME_RESTART , iRestartDelay ) ;
2015-09-30 03:49:22 +03:00
}
}
2016-01-28 07:48:09 +03:00
bool CHalfLifeMultiplay : : HasRoundTimeExpired ( )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
if ( ! m_iRoundTime )
return false ;
# endif
2015-09-30 03:49:22 +03:00
// We haven't completed other objectives, so go for this!.
2017-11-01 18:27:19 +03:00
if ( GetRoundRemainingTime ( ) > 0 | | m_iRoundWinStatus ! = WINSTATUS_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 )
{
2016-12-06 22:21:52 +03:00
CGrenade * bomb = nullptr ;
2017-11-22 20:27:55 +03:00
while ( ( bomb = UTIL_FindEntityByClassname ( bomb , " grenade " ) ) )
2015-08-20 13:35:01 +03:00
{
if ( bomb - > m_bIsC4 )
{
return true ;
}
}
}
return false ;
2015-07-12 23:32:09 +03:00
}
2017-11-22 20:27:55 +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
{
2017-10-12 17:50:56 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer | | FNullEnt ( pPlayer - > pev ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = iTeam )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > pev - > health > 0 & & pPlayer - > pev - > deadflag = = DEAD_NO )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_bReceivesNoMoneyNextRound = true ;
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 : : CareerRestart ( )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
m_bGameOver = false ;
2015-08-20 13:35:01 +03:00
2016-10-05 18:27:50 +03:00
if ( m_flRestartRoundTime = = 0.0f )
2015-08-20 13:35:01 +03:00
{
2016-10-05 18:27:50 +03:00
m_flRestartRoundTime = gpGlobals - > time + 1.0f ;
2015-08-20 13:35:01 +03:00
}
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
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-12-05 22:40:30 +03:00
{
TheCareerTasks - > Reset ( false ) ;
}
2015-08-20 13:35:01 +03:00
m_bSkipSpawn = false ;
2017-10-12 17:50:56 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer | | FNullEnt ( pPlayer - > pev ) )
2015-08-20 13:35:01 +03:00
continue ;
2017-11-22 20:27:55 +03:00
if ( ! pPlayer - > IsBot ( ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > ForceClientDllUpdate ( ) ;
2015-08-20 13:35:01 +03:00
}
}
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : IsMultiplayer ( )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : IsDeathmatch ( )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : IsCoOp ( )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > coop ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FShouldSwitchWeapon , ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon ) , pPlayer , pWeapon )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( FShouldSwitchWeapon ) ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
2015-06-30 12:46:07 +03:00
if ( ! pWeapon - > CanDeploy ( ) )
2017-10-12 17:50:56 +03:00
{
// that weapon can't deploy anyway.
2015-06-30 12:46:07 +03:00
return FALSE ;
2017-10-12 17:50:56 +03:00
}
2015-06-30 12:46:07 +03:00
if ( ! pPlayer - > m_pActiveItem )
2017-10-12 17:50:56 +03:00
{
// player doesn't have an active item!
2015-06-30 12:46:07 +03:00
return TRUE ;
2017-10-12 17:50:56 +03:00
}
2015-06-30 12:46:07 +03:00
if ( ! pPlayer - > m_iAutoWepSwitch )
return FALSE ;
if ( ! pPlayer - > m_pActiveItem - > CanHolster ( ) )
2017-10-12 17:50:56 +03:00
{
// can't put away the active item.
2015-06-30 12:46:07 +03:00
return FALSE ;
2017-10-12 17:50:56 +03:00
}
2015-06-30 12:46:07 +03:00
if ( pWeapon - > iWeight ( ) > pPlayer - > m_pActiveItem - > iWeight ( ) )
return TRUE ;
2015-07-12 23:32:09 +03:00
return FALSE ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , GetNextBestWeapon , ( CBasePlayer * pPlayer , CBasePlayerItem * pCurrentWeapon ) , pPlayer , pCurrentWeapon )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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
2017-10-12 17:50:56 +03:00
pBest = nullptr ;
2015-06-30 12:46:07 +03:00
2017-10-12 17:50:56 +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
2016-12-06 22:21:52 +03:00
while ( pCheck )
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
2017-10-12 17:50:56 +03:00
// that the player was using. This will end up leaving the player with his heaviest-weighted weapon.
2015-09-30 03:49:22 +03:00
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.
2016-12-06 22:21:52 +03:00
if ( ! pBest )
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
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : UpdateGameMode ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgGameMode , nullptr , pPlayer - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_BYTE ( 1 ) ;
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : InitHUD ( CBasePlayer * pl )
2015-08-20 13:35:01 +03:00
{
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 )
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgViewMode , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
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
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreInfo , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_BYTE ( ENTINDEX ( pl - > edict ( ) ) ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( pl - > m_iTeam ) ;
MESSAGE_END ( ) ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShadowIdx , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_LONG ( g_iShadowSprite ) ;
MESSAGE_END ( ) ;
if ( IsCareer ( ) )
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCZCareer , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
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
2017-10-12 17:50:56 +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 ) ;
2016-12-06 22:21:52 +03:00
if ( ! plr )
continue ;
2015-09-16 23:19:21 +03:00
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( plr - > IsDormant ( ) )
continue ;
# endif
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreInfo , nullptr , pl - > edict ( ) ) ;
2016-12-06 22:21:52 +03:00
WRITE_BYTE ( i ) ; // client number
WRITE_SHORT ( int ( plr - > pev - > frags ) ) ;
WRITE_SHORT ( plr - > m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( plr - > m_iTeam ) ;
MESSAGE_END ( ) ;
2015-08-20 13:35:01 +03:00
}
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_STRING ( " TERRORIST " ) ;
WRITE_SHORT ( m_iNumTerroristWins ) ;
MESSAGE_END ( ) ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_STRING ( " CT " ) ;
WRITE_SHORT ( m_iNumCTWins ) ;
MESSAGE_END ( ) ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgAllowSpec , nullptr , 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 ( ) ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgForceCam , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
WRITE_BYTE ( forcecamera . value ! = 0 ) ;
WRITE_BYTE ( forcechasecam . value ! = 0 ) ;
WRITE_BYTE ( fadetoblack . value ! = 0 ) ;
MESSAGE_END ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_bGameOver )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , SVC_INTERMISSION , nullptr , pl - > edict ( ) ) ;
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
}
2017-10-12 17:50:56 +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 ) ;
2016-12-06 22:21:52 +03:00
if ( ! plr )
continue ;
2015-08-20 13:35:01 +03:00
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( plr - > IsDormant ( ) )
continue ;
# endif
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamInfo , nullptr , pl - > edict ( ) ) ;
2016-12-06 22:21:52 +03:00
WRITE_BYTE ( plr - > entindex ( ) ) ;
WRITE_STRING ( GetTeamName ( plr - > m_iTeam ) ) ;
MESSAGE_END ( ) ;
2015-08-20 13:35:01 +03:00
2016-12-06 22:21:52 +03:00
plr - > SetScoreboardAttributes ( pl ) ;
2015-08-20 13:35:01 +03:00
2016-12-18 14:27:39 +03:00
if ( pl - > entindex ( ) ! = i )
2016-12-06 22:21:52 +03:00
{
# ifndef REGAMEDLL_FIXES
if ( plr - > pev - > flags = = FL_DORMANT )
continue ;
# endif
if ( plr - > pev - > deadflag = = DEAD_NO )
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgRadar , nullptr , pl - > edict ( ) ) ;
2016-12-06 22:21:52 +03:00
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-08-20 13:35:01 +03:00
}
}
}
2017-01-29 02:56:29 +03:00
auto SendMsgBombDrop = [ & pl ] ( const int flag , const Vector & pos )
2016-12-06 22:21:52 +03:00
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBombDrop , nullptr , pl - > edict ( ) ) ;
2016-12-06 22:21:52 +03:00
WRITE_COORD ( pos . x ) ;
WRITE_COORD ( pos . y ) ;
WRITE_COORD ( pos . z ) ;
2017-01-29 02:56:29 +03:00
WRITE_BYTE ( flag ) ;
2016-12-06 22:21:52 +03:00
MESSAGE_END ( ) ;
} ;
2015-11-06 17:58:48 +03:00
if ( m_bBombDropped )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
CBaseEntity * pWeaponC4 = UTIL_FindEntityByClassname ( nullptr , " weapon_c4 " ) ;
2016-08-02 12:03:01 +03:00
if ( pWeaponC4 )
2015-08-20 13:35:01 +03:00
{
2016-12-06 22:21:52 +03:00
SendMsgBombDrop ( BOMB_FLAG_DROPPED , pWeaponC4 - > pev - > origin ) ;
2015-08-20 13:35:01 +03:00
}
}
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
else
{
CGrenade * bomb = nullptr ;
2017-11-22 20:27:55 +03:00
while ( ( bomb = UTIL_FindEntityByClassname ( bomb , " grenade " ) ) )
2016-12-06 22:21:52 +03:00
{
if ( bomb - > m_bIsC4 )
{
// if the bomb was planted, which will trigger the round timer to hide.
SendMsgBombDrop ( BOMB_FLAG_PLANTED , bomb - > pev - > origin ) ;
if ( m_iRoundTime > 0 | | GetRoundRemainingTime ( ) > = 1.0f )
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowTimer , nullptr , pl - > pev ) ;
2016-12-06 22:21:52 +03:00
MESSAGE_END ( ) ;
}
else
{
// HACK HACK, we need to hide only the timer.
SendMsgBombDrop ( BOMB_FLAG_PLANTED , g_vecZero ) ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBombPickup , nullptr , pl - > pev ) ;
2016-12-06 22:21:52 +03:00
MESSAGE_END ( ) ;
}
break ;
}
}
}
# endif
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : ClientDisconnected ( edict_t * pClient )
2015-08-20 13:35:01 +03:00
{
2016-08-02 12:03:01 +03:00
if ( pClient )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
CBasePlayer * pPlayer = CBasePlayer : : Instance ( pClient ) ;
2016-08-02 12:03:01 +03:00
if ( pPlayer )
2015-08-20 13:35:01 +03:00
{
pPlayer - > has_disconnected = true ;
pPlayer - > pev - > deadflag = DEAD_DEAD ;
pPlayer - > SetScoreboardAttributes ( ) ;
if ( pPlayer - > m_bHasC4 )
{
pPlayer - > DropPlayerItem ( " weapon_c4 " ) ;
}
2017-08-19 20:13:45 +03:00
# ifndef REGAMEDLL_FIXES
// Why ? DropPlayerItem didn't handle item_thighpack
2015-08-20 13:35:01 +03:00
if ( pPlayer - > m_bHasDefuser )
{
pPlayer - > DropPlayerItem ( " item_thighpack " ) ;
}
2017-08-19 20:13:45 +03:00
# endif
2015-08-20 13:35:01 +03:00
if ( pPlayer - > m_bIsVIP )
{
2017-10-12 17:50:56 +03:00
m_pVIP = nullptr ;
2015-08-20 13:35:01 +03:00
}
pPlayer - > m_iCurrentKickVote = 0 ;
if ( pPlayer - > m_iMapVote )
{
2017-11-01 21:23:23 +03:00
m_iMapVotes [ pPlayer - > m_iMapVote ] - - ;
2015-08-20 13:35:01 +03:00
2017-10-19 20:12:02 +03:00
if ( m_iMapVotes [ pPlayer - > m_iMapVote ] < 0 )
2015-08-20 13:35:01 +03:00
{
2017-10-19 20:12:02 +03:00
m_iMapVotes [ pPlayer - > m_iMapVote ] = 0 ;
2015-08-20 13:35:01 +03:00
}
}
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 ) ;
2016-08-02 12:03:01 +03:00
if ( pPlayer - > m_pObserver )
2015-08-20 13:35:01 +03:00
{
pPlayer - > m_pObserver - > SUB_Remove ( ) ;
}
2017-11-22 20:27:55 +03:00
CBasePlayer * pObserver = nullptr ;
while ( ( pObserver = UTIL_FindEntityByClassname ( pObserver , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pObserver - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
if ( ! pObserver - > pev | | pObserver = = pPlayer )
2015-08-20 13:35:01 +03:00
continue ;
2017-10-12 17:50:56 +03:00
// If a spectator was chasing this player, move him/her onto the next player
2017-11-22 20:27:55 +03:00
if ( pObserver - > m_hObserverTarget = = pPlayer )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
int iMode = pObserver - > pev - > iuser1 ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
pObserver - > pev - > iuser1 = OBS_NONE ;
pObserver - > Observer_SetMode ( iMode ) ;
2015-08-20 13:35:01 +03:00
}
}
}
}
CheckWinConditions ( ) ;
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( float , CHalfLifeMultiplay , CSGameRules , FlPlayerFallDamage , ( CBasePlayer * pPlayer ) , pPlayer )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
float EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( FlPlayerFallDamage ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2017-10-12 17:50:56 +03:00
pPlayer - > m_flFallVelocity - = MAX_PLAYER_SAFE_FALL_SPEED ;
2015-08-02 20:45:57 +03:00
return pPlayer - > m_flFallVelocity * DAMAGE_FOR_FALL_SPEED * 1.25 ;
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FPlayerCanTakeDamage , ( CBasePlayer * pPlayer , CBaseEntity * pAttacker ) , pPlayer , pAttacker )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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 ;
}
2016-07-14 17:12:17 +03:00
if ( friendlyfire . value ! = 0.0f | | pAttacker = = pPlayer )
2015-08-20 13:35:01 +03:00
{
return TRUE ;
}
return FALSE ;
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : PlayerThink ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
if ( m_bGameOver )
2015-08-20 13:35:01 +03:00
{
// 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 )
{
2017-01-20 17:52:37 +03:00
int slot = MENU_SLOT_TEAM_UNDEFINED ;
2015-08-20 13:35:01 +03:00
if ( ! Q_stricmp ( humans_join_team . string , " T " ) )
{
2017-01-20 17:52:37 +03:00
slot = MENU_SLOT_TEAM_TERRORIST ;
2015-08-20 13:35:01 +03:00
}
else if ( ! Q_stricmp ( humans_join_team . string , " CT " ) )
{
2017-01-20 17:52:37 +03:00
slot = MENU_SLOT_TEAM_CT ;
2015-08-20 13:35:01 +03:00
}
2016-06-15 12:26:46 +03:00
# ifdef REGAMEDLL_ADD
else if ( ! Q_stricmp ( humans_join_team . string , " any " ) & & auto_join_team . value ! = 0.0f )
{
2017-01-20 17:52:37 +03:00
slot = MENU_SLOT_TEAM_RANDOM ;
2016-06-15 12:26:46 +03:00
}
2017-05-04 13:45:29 +03:00
else if ( ! Q_stricmp ( humans_join_team . string , " SPEC " ) & & auto_join_team . value ! = 0.0f )
{
slot = MENU_SLOT_TEAM_SPECT ;
}
2016-06-15 12:26:46 +03:00
# endif
2015-08-20 13:35:01 +03:00
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 ;
2017-01-20 17:52:37 +03:00
if ( slot ! = MENU_SLOT_TEAM_UNDEFINED & & ! pPlayer - > IsBot ( ) )
2015-08-20 13:35:01 +03:00
{
2016-06-15 12:26:46 +03:00
# ifdef REGAMEDLL_ADD
2017-01-20 17:52:37 +03:00
m_bSkipShowMenu = ( auto_join_team . value ! = 0.0f ) & & ! ( pPlayer - > pev - > flags & FL_FAKECLIENT ) ;
2016-06-15 12:26:46 +03:00
2017-01-20 17:52:37 +03:00
if ( HandleMenu_ChooseTeam ( pPlayer , slot ) )
2016-06-15 12:26:46 +03:00
{
2017-01-20 17:52:37 +03:00
if ( slot ! = MENU_SLOT_TEAM_SPECT & & ( IsCareer ( ) | | m_bSkipShowMenu ) )
{
// slot 6 - chooses randomize the appearance to model player
HandleMenu_ChooseAppearance ( pPlayer , 6 ) ;
}
}
else
{
m_bSkipShowMenu = false ;
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 " ) ;
2016-06-15 12:26:46 +03:00
}
2017-01-20 17:52:37 +03:00
2016-06-15 12:26:46 +03:00
m_bSkipShowMenu = false ;
# else
2017-01-20 17:52:37 +03:00
HandleMenu_ChooseTeam ( pPlayer , slot ) ;
2015-08-20 13:35:01 +03:00
2017-01-20 17:52:37 +03:00
if ( slot ! = MENU_SLOT_TEAM_SPECT & & IsCareer ( ) )
2015-08-20 13:35:01 +03:00
{
// slot 6 - chooses randomize the appearance to model player
HandleMenu_ChooseAppearance ( pPlayer , 6 ) ;
}
2016-06-15 12:26:46 +03:00
# endif
2015-08-20 13:35:01 +03:00
}
}
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , PlayerSpawn , ( CBasePlayer * pPlayer ) , pPlayer )
2016-05-17 21:01:46 +03:00
2015-09-30 03:49:22 +03:00
// Purpose: Player has just spawned. Equip them.
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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 ) ;
2016-12-06 22:21:52 +03:00
pPlayer - > OnSpawnEquip ( ) ;
2015-08-20 13:35:01 +03:00
pPlayer - > SetPlayerModel ( false ) ;
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , FPlayerCanRespawn , ( CBasePlayer * pPlayer ) , pPlayer )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( FPlayerCanRespawn ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
2017-01-20 17:52:37 +03:00
if ( forcerespawn . value < = 0 )
2016-12-06 22:21:52 +03:00
# endif
2015-08-20 13:35:01 +03:00
{
2017-01-20 17:52:37 +03:00
// Player cannot respawn twice in a round
if ( pPlayer - > m_iNumSpawns > 0 )
{
return FALSE ;
}
2015-08-20 13:35:01 +03:00
2017-01-20 17:52:37 +03:00
// Player cannot respawn until next round if more than 20 seconds in
2015-09-30 03:49:22 +03:00
2017-01-20 17:52:37 +03:00
// Tabulate the number of players on each team.
m_iNumCT = CountTeamPlayers ( CT ) ;
m_iNumTerrorist = CountTeamPlayers ( TERRORIST ) ;
2015-08-20 13:35:01 +03:00
2017-01-20 17:52:37 +03:00
if ( m_iNumTerrorist > 0 & & m_iNumCT > 0 )
{
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
2017-01-20 17:52:37 +03:00
// means no time limit
if ( GetRoundRespawnTime ( ) ! = - 1 )
2016-12-06 22:21:52 +03:00
# endif
2017-01-20 17:52:37 +03:00
{
// TODO: to be correct, need use time the real one starts of round, m_fRoundStartTimeReal instead of it.
// m_fRoundStartTime able to extend the time to 60 seconds when there is a remaining time of round.
2016-12-10 21:27:53 +03:00
# ifdef REGAMEDLL_FIXES
2017-01-20 17:52:37 +03:00
if ( gpGlobals - > time > m_fRoundStartTimeReal + GetRoundRespawnTime ( ) )
2016-12-10 21:27:53 +03:00
# else
2017-01-20 17:52:37 +03:00
if ( gpGlobals - > time > m_fRoundStartTime + GetRoundRespawnTime ( ) )
2016-12-10 21:27:53 +03:00
# endif
2016-12-06 22:21:52 +03:00
{
2017-01-20 17:52:37 +03:00
// If this player just connected and fadetoblack is on, then maybe
// the server admin doesn't want him peeking around.
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
2017-01-20 17:52:37 +03:00
return FALSE ;
}
2016-12-06 22:21:52 +03:00
}
2015-09-30 03:49:22 +03:00
}
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
}
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : FlPlayerSpawnTime ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
2017-01-20 17:52:37 +03:00
return gpGlobals - > time ;
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : AllowAutoTargetCrosshair ( )
2015-07-12 23:32:09 +03:00
{
return FALSE ;
}
2017-10-12 17:50:56 +03:00
// How many points awarded to anyone that kills this player?
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : 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
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , PlayerKilled , ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pInflictor ) , pVictim , pKiller , pInflictor )
2016-05-17 21:01:46 +03:00
2017-10-12 17:50:56 +03:00
// Someone/something killed this player
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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 ) ) ;
2017-10-12 17:50:56 +03:00
CBasePlayer * peKiller = nullptr ;
2015-08-20 13:35:01 +03:00
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 ) ;
2016-12-06 22:21:52 +03:00
if ( pDriver )
2015-08-20 13:35:01 +03:00
{
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-07-17 23:31:56 +03:00
bool killedByFFA = 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 ) ) ;
2016-07-27 17:08:42 +03:00
# ifdef REGAMEDLL_ADD
if ( autokick . value & & max_teamkills . value & & killer - > m_iTeamKills > = ( int ) max_teamkills . value )
# else
if ( autokick . value & & killer - > m_iTeamKills = = 3 )
# endif
2015-08-20 13:35:01 +03:00
{
2016-08-23 10:09:21 +03:00
# ifdef REGAMEDLL_FIXES
ClientPrint ( killer - > pev , HUD_PRINTCONSOLE , " #Banned_For_Killing_Teammates " ) ;
# else
2015-08-20 13:35:01 +03:00
ClientPrint ( killer - > pev , HUD_PRINTCONSOLE , " #Banned_For_Killing_Teamates " ) ;
2016-08-23 10:09:21 +03:00
# endif
2015-08-20 13:35:01 +03:00
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
2016-07-14 17:12:17 +03:00
# ifndef REGAMEDLL_FIXES
2015-08-20 13:35:01 +03:00
MESSAGE_BEGIN ( MSG_BROADCAST , gmsgScoreInfo ) ;
2016-07-14 17:12:17 +03:00
# else
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
# endif
2015-08-20 13:35:01 +03:00
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
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN ( CHalfLifeMultiplay , CSGameRules , DeathNotice , ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pevInflictor ) , pVictim , pKiller , pevInflictor )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( DeathNotice ) ( CBasePlayer * pVictim , entvars_t * pKiller , entvars_t * pevInflictor )
2015-08-20 13:35:01 +03:00
{
// 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 )
2017-10-12 17:50:56 +03:00
{
2016-06-14 01:13:13 +03:00
killer_weapon_name = pAttacker - > m_pActiveItem - > pszName ( ) ;
2017-10-12 17:50:56 +03:00
}
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
2017-10-12 17:50:56 +03:00
// replace the code names with the 'real' names
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-12-06 22:21:52 +03:00
if ( ! TheTutor )
2015-08-20 13:35:01 +03:00
{
MESSAGE_BEGIN ( MSG_ALL , gmsgDeathMsg ) ;
2017-10-12 17:50:56 +03:00
WRITE_BYTE ( killer_index ) ; // the killer
WRITE_BYTE ( ENTINDEX ( pVictim - > edict ( ) ) ) ; // the victim
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
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
}
2017-05-24 19:07:37 +03:00
// TODO: It is called in CBasePlayer::Killed too, most likely,
// an unnecessary call. (Need investigate)
2015-08-20 13:35:01 +03:00
CheckWinConditions ( ) ;
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
2017-10-12 17:50:56 +03:00
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // player killed
2015-08-20 13:35:01 +03:00
WRITE_SHORT ( ENTINDEX ( pVictim - > edict ( ) ) ) ; // index number of primary entity
if ( pevInflictor )
WRITE_SHORT ( ENTINDEX ( ENT ( pevInflictor ) ) ) ; // index number of secondary entity
else
2017-10-12 17:50:56 +03:00
WRITE_SHORT ( ENTINDEX ( ENT ( pKiller ) ) ) ; // index number of secondary entity
2015-08-20 13:35:01 +03:00
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
2017-10-12 17:50:56 +03:00
WRITE_LONG ( 7 | DRC_FLAG_DRAMATIC ) ; // eventflags (priority and flags)
2015-08-20 13:35:01 +03:00
MESSAGE_END ( ) ;
2015-07-12 23:32:09 +03:00
}
2017-10-12 17:50:56 +03:00
// Player has grabbed a weapon that was sitting in the world
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : PlayerGotWeapon ( CBasePlayer * pPlayer , CBasePlayerItem * pWeapon )
2015-07-12 23:32:09 +03:00
{
;
}
2017-10-12 17:50:56 +03:00
// What is the time in the future at which this weapon may spawn?
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : 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
}
2017-10-12 17:50:56 +03:00
// Returns 0 if the weapon can respawn now,
2016-07-14 17:12:17 +03:00
// otherwise it returns the time at which it can try to spawn again.
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : 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
}
2017-10-12 17:50:56 +03:00
// Where should this weapon spawn?
// Some game variations may choose to randomize spawn locations
2017-07-01 23:40:10 +03:00
Vector CHalfLifeMultiplay : : 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
}
2017-10-12 17:50:56 +03:00
// Any conditions inhibiting the respawning of this weapon?
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : 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 ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( BOOL , CHalfLifeMultiplay , CSGameRules , CanHavePlayerItem , ( CBasePlayer * pPlayer , CBasePlayerItem * pItem ) , pPlayer , pItem )
2016-05-17 21:01:46 +03:00
2017-10-12 17:50:56 +03:00
// Returns FALSE if the player is not allowed to pick up this weapon
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( CanHavePlayerItem ) ( CBasePlayer * pPlayer , CBasePlayerItem * pItem )
2015-07-12 23:32:09 +03:00
{
return CGameRules : : CanHavePlayerItem ( pPlayer , pItem ) ;
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : CanHaveItem ( CBasePlayer * pPlayer , CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return TRUE ;
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : PlayerGotItem ( CBasePlayer * pPlayer , CItem * pItem )
2015-07-12 23:32:09 +03:00
{
;
}
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : 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 ;
}
2017-10-12 17:50:56 +03:00
// At what time in the future may this Item respawn?
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : FlItemRespawnTime ( CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > time + ITEM_RESPAWN_TIME ;
}
2017-10-12 17:50:56 +03:00
// Where should this item respawn?
// Some game variations may choose to randomize spawn locations
2017-07-01 23:40:10 +03:00
Vector CHalfLifeMultiplay : : VecItemRespawnSpot ( CItem * pItem )
2015-07-12 23:32:09 +03:00
{
return pItem - > pev - > origin ;
}
2017-07-01 23:40:10 +03:00
void CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : 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 ;
}
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : FlAmmoRespawnTime ( CBasePlayerAmmo * pAmmo )
2015-07-12 23:32:09 +03:00
{
return gpGlobals - > time + 20.0f ;
}
2017-07-01 23:40:10 +03:00
Vector CHalfLifeMultiplay : : VecAmmoRespawnSpot ( CBasePlayerAmmo * pAmmo )
2015-07-12 23:32:09 +03:00
{
return pAmmo - > pev - > origin ;
}
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : 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
}
2017-07-01 23:40:10 +03:00
float CHalfLifeMultiplay : : 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
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( int , CHalfLifeMultiplay , CSGameRules , DeadPlayerWeapons , ( CBasePlayer * pPlayer ) , pPlayer )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
int EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( DeadPlayerWeapons ) ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
return GR_PLR_DROP_GUN_ACTIVE ;
}
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : DeadPlayerAmmo ( CBasePlayer * pPlayer )
2015-07-12 23:32:09 +03:00
{
return GR_PLR_DROP_AMMO_ACTIVE ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CUSTOM_CHAIN ( edict_t * , CHalfLifeMultiplay , CSGameRules , GetPlayerSpawnSpot , ( CBasePlayer * pPlayer ) , pPlayer )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
edict_t * EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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
}
2017-07-01 23:40:10 +03:00
int CHalfLifeMultiplay : : PlayerRelationship ( CBasePlayer * pPlayer , CBaseEntity * pTarget )
2015-07-12 23:32:09 +03:00
{
2016-06-18 17:48:19 +03:00
# ifdef REGAMEDLL_ADD
if ( IsFreeForAll ( ) )
{
return GR_NOTTEAMMATE ;
}
# endif
2015-08-20 13:35:01 +03:00
if ( ! pPlayer | | ! pTarget )
{
return GR_NOTTEAMMATE ;
}
if ( ! pTarget - > IsPlayer ( ) )
{
return GR_NOTTEAMMATE ;
}
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam ! = static_cast < CBasePlayer * > ( pTarget ) - > m_iTeam )
2015-08-20 13:35:01 +03:00
{
return GR_NOTTEAMMATE ;
}
return GR_TEAMMATE ;
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : FAllowFlashlight ( )
2015-07-12 23:32:09 +03:00
{
2017-10-19 20:12:02 +03:00
return flashlight . value ? TRUE : FALSE ;
2015-07-12 23:32:09 +03:00
}
2017-07-01 23:40:10 +03:00
BOOL CHalfLifeMultiplay : : FAllowMonsters ( )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
return FALSE ;
# else
2016-07-14 17:12:17 +03:00
return allowmonsters . value ! = 0.0f ;
2016-12-06 22:21:52 +03:00
# endif
2015-07-12 23:32:09 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2 ( CHalfLifeMultiplay , CSGameRules , GoToIntermission )
2016-05-17 21:01:46 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( GoToIntermission ) ( )
2015-07-12 23:32:09 +03:00
{
2016-12-06 22:21:52 +03:00
if ( m_bGameOver )
2017-10-12 17:50:56 +03:00
{
// intermission has already been triggered, so ignore.
2015-08-20 13:35:01 +03:00
return ;
2017-10-12 17:50:56 +03:00
}
2015-08-20 13:35:01 +03:00
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 ( ) ;
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-12-05 22:40:30 +03:00
{
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
2017-10-12 17:50:56 +03:00
// bounds check
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 ;
2016-12-06 22:21:52 +03:00
m_bGameOver = true ;
2015-08-20 13:35:01 +03:00
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 ;
2016-12-06 22:21:52 +03:00
if ( p )
2015-08-20 13:35:01 +03:00
{
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 ;
}
2017-10-12 17:50:56 +03:00
cycle - > items = nullptr ;
cycle - > next_item = nullptr ;
2015-07-12 23:32:09 +03:00
}
2017-10-12 17:50:56 +03:00
// Parses mapcycle.txt file into mapcycle_t structure
2015-08-20 13:35:01 +03:00
int ReloadMapCycleFile ( char * filename , mapcycle_t * cycle )
{
2017-10-12 17:50:56 +03:00
char szBuffer [ MAX_RULE_BUFFER ] ;
char szMap [ MAX_MAPNAME_LENGHT ] ;
2015-08-20 13:35:01 +03:00
int length ;
2017-10-12 17:50:56 +03:00
char * pToken ;
2015-08-20 13:35:01 +03:00
char * pFileList ;
char * aFileList = pFileList = ( char * ) LOAD_FILE_FOR_ME ( filename , & length ) ;
2017-10-12 17:50:56 +03:00
bool hasBuffer ;
mapcycle_item_s * item , * newlist = nullptr , * next ;
2015-08-20 13:35:01 +03:00
if ( pFileList & & length )
{
// the first map name in the file becomes the default
while ( true )
{
2017-10-12 17:50:56 +03:00
hasBuffer = false ;
2015-08-20 13:35:01 +03:00
Q_memset ( szBuffer , 0 , sizeof ( szBuffer ) ) ;
2017-10-12 17:50:56 +03:00
pFileList = SharedParse ( pFileList ) ;
pToken = SharedGetToken ( ) ;
2015-08-20 13:35:01 +03:00
2017-10-12 17:50:56 +03:00
if ( Q_strlen ( pToken ) < = 0 )
2015-08-20 13:35:01 +03:00
break ;
2017-10-12 17:50:56 +03:00
Q_strcpy ( szMap , pToken ) ;
2015-08-20 13:35:01 +03:00
// Any more tokens on this line?
2017-10-12 17:50:56 +03:00
if ( SharedTokenWaiting ( pFileList ) )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
pFileList = SharedParse ( pFileList ) ;
if ( Q_strlen ( pToken ) > 0 )
2015-08-20 13:35:01 +03:00
{
2017-10-12 17:50:56 +03:00
hasBuffer = true ;
Q_strcpy ( szBuffer , pToken ) ;
2015-08-20 13:35:01 +03:00
}
}
// 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 ) ) ;
2017-10-12 17:50:56 +03:00
if ( hasBuffer )
2015-08-20 13:35:01 +03:00
{
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
2017-10-12 17:50:56 +03:00
{
2015-08-20 13:35:01 +03:00
ALERT ( at_console , " Skipping %s from mapcycle, not a valid map \n " , szMap ) ;
2017-10-12 17:50:56 +03:00
}
2015-08-20 13:35:01 +03:00
}
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 ;
}
2016-12-06 22:21:52 +03:00
while ( item - > next )
2015-08-20 13:35:01 +03:00
{
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
{
2016-12-06 22:21:52 +03:00
int nCount = 0 ;
2017-10-12 17:50:56 +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 ) ;
2016-12-06 22:21:52 +03:00
if ( pPlayer )
2015-08-20 13:35:01 +03:00
{
2016-12-06 22:21:52 +03:00
nCount + + ;
2015-08-20 13:35:01 +03:00
}
}
2016-12-06 22:21:52 +03:00
return nCount ;
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
2017-11-22 20:27:55 +03:00
char * c ;
int nCount ;
2015-09-16 23:19:21 +03:00
2017-11-22 20:27:55 +03:00
while ( * s )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( * s = = ' \\ ' )
{
// skip the slash
s + + ;
}
// Copy a key
c = pkey ;
nCount = 0 ;
2015-08-20 13:35:01 +03:00
while ( * s ! = ' \\ ' )
{
if ( ! * s )
{
2017-11-22 20:27:55 +03:00
// allow value to be ended with NULL
break ;
}
if ( nCount > = sizeof ( pkey ) )
{
s + + ;
// skip oversized key chars till the slash or EOL
continue ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
* c + + = * s + + ;
nCount + + ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
* c = ' \0 ' ;
s + + ; // skip the slash
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
// Copy a value
c = value ;
nCount = 0 ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( * s ! = ' \\ ' )
2015-08-20 13:35:01 +03:00
{
if ( ! * s )
{
2017-11-22 20:27:55 +03:00
// allow value to be ended with NULL
break ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
if ( nCount > = sizeof ( value ) )
{
s + + ;
// skip oversized value chars till the slash or EOL
continue ;
}
* c + + = * s + + ;
nCount + + ;
2015-08-20 13:35:01 +03:00
}
2017-11-22 20:27:55 +03:00
* c = ' \0 ' ;
2015-08-20 13:35:01 +03:00
Q_strcat ( szCommand , pkey ) ;
if ( Q_strlen ( value ) > 0 )
{
Q_strcat ( szCommand , " " ) ;
Q_strcat ( szCommand , value ) ;
}
Q_strcat ( szCommand , " \n " ) ;
2017-11-22 20:27:55 +03:00
/*if (!*s)
2015-08-20 13:35:01 +03:00
{
return ;
}
2017-11-22 20:27:55 +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
{
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
if ( pPlayer - > m_iTeam ! = UNASSIGNED )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_iMapVote = 0 ;
2015-08-20 13:35:01 +03:00
}
}
2017-10-12 17:50:56 +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
{
2016-08-23 10:09:21 +03:00
if ( ! item )
break ;
2017-11-22 20:27:55 +03:00
nCount + + ;
2016-06-04 14:43:52 +03:00
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
}
2017-11-22 20:27:55 +03:00
void CHalfLifeMultiplay : : DisplayMaps ( CBasePlayer * pPlayer , 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 " ) ;
2017-10-12 17:50:56 +03:00
char * pszNewMap = nullptr ;
2015-08-20 13:35:01 +03:00
int iCount = 0 , done = 0 ;
DestroyMapCycle ( & mapcycle2 ) ;
ReloadMapCycleFile ( mapcfile , & mapcycle2 ) ;
mapcycle_item_s * item = mapcycle2 . next_item ;
2016-12-06 22:21:52 +03:00
while ( ! done & & item )
2015-08-20 13:35:01 +03:00
{
if ( item - > next = = mapcycle2 . next_item )
done = 1 ;
2017-11-22 20:27:55 +03:00
iCount + + ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer )
2015-08-20 13:35:01 +03:00
{
if ( m_iMapVotes [ iCount ] = = 1 )
{
2017-11-22 20:27:55 +03:00
ClientPrint ( pPlayer - > pev , HUD_PRINTCONSOLE , " #Vote " , UTIL_dtos1 ( iCount ) , item - > mapname , UTIL_dtos2 ( 1 ) ) ;
2015-08-20 13:35:01 +03:00
}
else
2017-11-22 20:27:55 +03:00
{
ClientPrint ( pPlayer - > pev , HUD_PRINTCONSOLE , " #Votes " , UTIL_dtos1 ( iCount ) , item - > mapname , UTIL_dtos2 ( m_iMapVotes [ iCount ] ) ) ;
}
2015-08-20 13:35:01 +03:00
}
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
{
2017-10-12 17:50:56 +03:00
CHANGE_LEVEL ( pszNewMap , nullptr ) ;
2015-08-20 13:35:01 +03:00
return ;
}
if ( timelimit . value )
{
timelimit . value + = 30 ;
UTIL_ClientPrintAll ( HUD_PRINTCENTER , " #Map_Vote_Extend " ) ;
}
ResetAllMapVotes ( ) ;
2015-07-12 23:32:09 +03:00
}
2017-11-22 20:27:55 +03:00
void CHalfLifeMultiplay : : ProcessMapVote ( CBasePlayer * pPlayer , int iVote )
2015-07-12 23:32:09 +03:00
{
2017-11-22 20:27:55 +03:00
CBaseEntity * pEntity = nullptr ;
2015-08-20 13:35:01 +03:00
int iValidVotes = 0 , iNumPlayers = 0 ;
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-08-20 13:35:01 +03:00
break ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam ! = UNASSIGNED )
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
iNumPlayers + + ;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMapVote = = iVote )
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 )
{
2017-11-22 20:27:55 +03:00
DisplayMaps ( pPlayer , 0 ) ;
ClientPrint ( pPlayer - > pev , HUD_PRINTCONSOLE , " #Game_required_votes " , UTIL_dtos1 ( iRequiredVotes ) ) ;
2015-08-20 13:35:01 +03:00
}
else
2017-11-22 20:27:55 +03:00
{
2017-10-12 17:50:56 +03:00
DisplayMaps ( nullptr , iVote ) ;
2017-11-22 20:27:55 +03:00
}
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
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( ChangeLevel ) ( )
2015-08-20 13:35:01 +03:00
{
static char szPreviousMapCycleFile [ 256 ] ;
static mapcycle_t mapcycle ;
2017-10-12 17:50:56 +03:00
char szNextMap [ MAX_MAPNAME_LENGHT ] ;
char szFirstMapInList [ MAX_MAPNAME_LENGHT ] ;
2015-08-20 13:35:01 +03:00
char szCommands [ 1500 ] ;
char szRules [ 1500 ] ;
int minplayers = 0 , maxplayers = 0 ;
2016-10-05 18:27:50 +03:00
# ifdef REGAMEDLL_FIXES
// the absolute default level is de_dust
Q_strcpy ( szFirstMapInList , " de_dust " ) ;
# else
2015-08-20 13:35:01 +03:00
// the absolute default level is hldm1
Q_strcpy ( szFirstMapInList , " hldm1 " ) ;
2016-10-05 18:27:50 +03:00
# endif
2015-08-20 13:35:01 +03:00
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 " ) ;
2017-10-12 17:50:56 +03:00
assert ( mapcfile ! = nullptr ) ;
2015-08-20 13:35:01 +03:00
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
2017-10-12 17:50:56 +03:00
assert ( item ! = nullptr ) ;
2015-08-20 13:35:01 +03:00
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 ) ;
}
2016-12-06 22:21:52 +03:00
m_bGameOver = true ;
2015-08-20 13:35:01 +03:00
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 ) ;
}
2017-10-12 17:50:56 +03:00
CHANGE_LEVEL ( szNextMap , nullptr ) ;
2015-08-20 13:35:01 +03:00
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
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgServerName , nullptr , client ) ;
2015-08-20 13:35:01 +03:00
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 ' ;
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgMOTD , nullptr , client ) ;
2015-08-20 13:35:01 +03:00
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 ) ;
2017-07-01 23:40:10 +03:00
void EXT_FUNC CHalfLifeMultiplay : : __API_HOOK ( 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
2016-07-14 17:12:17 +03:00
if ( g_pMapInfo )
g_pMapInfo - > CheckMapInfo ( ) ;
2016-06-02 01:08:22 +03:00
ReadMultiplayCvars ( ) ;
CheckMapConditions ( ) ;
}
2016-06-15 16:10:40 +03:00
TeamName CHalfLifeMultiplay : : SelectDefaultTeam ( )
{
TeamName team = UNASSIGNED ;
if ( m_iNumTerrorist < m_iNumCT )
{
team = TERRORIST ;
}
else if ( m_iNumTerrorist > m_iNumCT )
{
team = CT ;
}
// Choose the team that's losing
else if ( m_iNumTerroristWins < m_iNumCTWins )
{
team = TERRORIST ;
}
else if ( m_iNumCTWins < m_iNumTerroristWins )
{
team = CT ;
}
else
{
// Teams and scores are equal, pick a random team
team = ( RANDOM_LONG ( 0 , 1 ) = = 0 ) ? CT : TERRORIST ;
}
if ( TeamFull ( team ) )
{
// Pick the opposite team
team = ( team = = TERRORIST ) ? CT : TERRORIST ;
// No choices left
if ( TeamFull ( team ) )
{
return UNASSIGNED ;
}
}
return team ;
2016-10-05 18:27:50 +03:00
}
2017-10-12 17:50:56 +03:00
void CHalfLifeMultiplay : : ChangePlayerTeam ( CBasePlayer * pPlayer , const char * pTeamName , BOOL bKill , BOOL bGib )
{
if ( ! pTeamName | | ! pTeamName [ 0 ] )
return ;
if ( ! pPlayer - > IsAlive ( ) | | pPlayer - > m_iJoiningState ! = JOINED )
return ;
TeamName newTeam ;
if ( ! Q_stricmp ( pTeamName , " CT " ) )
{
newTeam = CT ;
}
else if ( ! Q_stricmp ( pTeamName , " TERRORIST " ) )
{
newTeam = TERRORIST ;
}
else if ( ! Q_stricmp ( pTeamName , " SPECTATOR " ) )
{
newTeam = SPECTATOR ;
}
else
{
return ;
}
if ( pPlayer - > m_iTeam ! = UNASSIGNED & & pPlayer - > m_iTeam ! = newTeam )
{
if ( bKill )
{
pPlayer - > m_LastHitGroup = HITGROUP_GENERIC ;
// have the player kill themself
pPlayer - > pev - > health = 0 ;
pPlayer - > Killed ( pPlayer - > pev , bGib ? GIB_ALWAYS : GIB_NEVER ) ;
// add 1 to frags to balance out the 1 subtracted for killing yourself
pPlayer - > pev - > frags + + ;
}
pPlayer - > m_iTeam = newTeam ;
pPlayer - > SetPlayerModel ( pPlayer - > m_bHasC4 ) ;
pPlayer - > TeamChangeUpdate ( ) ;
CSGameRules ( ) - > CheckWinConditions ( ) ;
}
}
2017-11-11 15:30:31 +03:00
bool CHalfLifeMultiplay : : CanPlayerBuy ( CBasePlayer * pPlayer ) const
{
if ( pPlayer - > m_iTeam = = CT & & m_bCTCantBuy )
{
return false ;
}
else if ( pPlayer - > m_iTeam = = TERRORIST & & m_bTCantBuy )
{
return false ;
}
else if ( m_bCTCantBuy & & m_bTCantBuy )
{
return false ;
}
return true ;
}