#include "precompiled.h" /* * Globals initialization */ #ifndef HOOK_GAMEDLL static char mp_com_token[ COM_TOKEN_LEN ]; cvar_t *sv_clienttrace = NULL; #else char mp_com_token[ COM_TOKEN_LEN ]; cvar_t *sv_clienttrace; #endif // HOOK_GAMEDLL CCStrikeGameMgrHelper g_GameMgrHelper; CHalfLifeMultiplay *g_pMPGameRules = NULL; /* <1153e2> ../cstrike/dlls/multiplay_gamerules.cpp:92 */ bool IsBotSpeaking(void) { for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *pPlayer = reinterpret_cast(UTIL_PlayerByIndex(i)); if (pPlayer == NULL || !pPlayer->IsBot()) continue; CCSBot *pBot = reinterpret_cast(pPlayer); if (pBot->IsUsingVoice()) return true; } return false; } /* <1116dd> ../cstrike/dlls/multiplay_gamerules.cpp:111 */ void SV_Continue_f(void) { CHalfLifeMultiplay *mp = g_pGameRules; if (mp->IsCareer() && mp->m_fTeamCount > 100000.0) { mp->m_fTeamCount = gpGlobals->time; // go continue MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer); WRITE_STRING("GOGOGO"); MESSAGE_END(); for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *pPlayer = reinterpret_cast(UTIL_PlayerByIndex(i)); if (pPlayer && !pPlayer->IsBot()) { // at the end of the round is showed window with the proposal surrender or continue // now of this time HUD is completely hidden // we must to restore HUD after entered continued pPlayer->m_iHideHUD &= ~HIDEHUD_ALL; } } } } /* <112860> ../cstrike/dlls/multiplay_gamerules.cpp:133 */ void SV_Tutor_Toggle_f(void) { CVAR_SET_FLOAT("tutor_enable", (CVAR_GET_FLOAT("tutor_enable") <= 0.0)); } /* <11538f> ../cstrike/dlls/multiplay_gamerules.cpp:139 */ void SV_Career_Restart_f(void) { CHalfLifeMultiplay *mp = g_pGameRules; if (mp->IsCareer()) { mp->CareerRestart(); } } /* <111695> ../cstrike/dlls/multiplay_gamerules.cpp:149 */ void SV_Career_EndRound_f(void) { CHalfLifeMultiplay *mp = g_pGameRules; if (!mp->IsCareer() || !mp->IsInCareerRound()) { return; } CBasePlayer *localPlayer = UTIL_GetLocalPlayer(); if (localPlayer != NULL) { SERVER_COMMAND("kill\n"); for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *player = reinterpret_cast(UTIL_PlayerByIndex(i)); if (!player || FNullEnt(player->pev)) continue; if (player->IsBot() && player->m_iTeam == localPlayer->m_iTeam) { SERVER_COMMAND(UTIL_VarArgs("bot_kill \"%s\"\n", STRING(player->pev->netname))); } } } } /* <1145dd> ../cstrike/dlls/multiplay_gamerules.cpp:173 */ bool CHalfLifeMultiplay::IsInCareerRound(void) { return IsMatchStarted() ? false : true; } /* <110ba1> ../cstrike/dlls/multiplay_gamerules.cpp:180 */ void SV_CareerAddTask_f(void) { if (CMD_ARGC() != 7) return; const char *taskName = CMD_ARGV(1); const char *weaponName = CMD_ARGV(2); int reps = Q_atoi(CMD_ARGV(3)); bool mustLive = Q_atoi(CMD_ARGV(4)) != 0; bool crossRounds = Q_atoi(CMD_ARGV(5)) != 0; bool isComplete = Q_atoi(CMD_ARGV(6)) != 0; if (TheCareerTasks != NULL) { TheCareerTasks->AddTask(taskName, weaponName, reps, mustLive, crossRounds, isComplete); } } /* <111640> ../cstrike/dlls/multiplay_gamerules.cpp:213 */ void SV_CareerMatchLimit_f(void) { if (CMD_ARGC() != 3) { return; } CHalfLifeMultiplay *mp = g_pGameRules; if (mp->IsCareer()) { mp->SetCareerMatchLimit(Q_atoi(CMD_ARGV(1)), Q_atoi(CMD_ARGV(2))); } } /* <114600> ../cstrike/dlls/multiplay_gamerules.cpp:227 */ void CHalfLifeMultiplay::SetCareerMatchLimit(int minWins, int winDifference) { if (!IsCareer()) { return; } if (!m_iCareerMatchWins) { m_iCareerMatchWins = minWins; m_iRoundWinDifference = winDifference; } } /* <114650> ../cstrike/dlls/multiplay_gamerules.cpp:238 */ BOOL CHalfLifeMultiplay::IsCareer(void) { return IS_CAREER_MATCH(); } /* <113ca2> ../cstrike/dlls/multiplay_gamerules.cpp:241 */ void CHalfLifeMultiplay::__MAKE_VHOOK(ServerDeactivate)(void) { if (!IsCareer()) { return; } CVAR_SET_FLOAT("pausable", 0); CVAR_SET_FLOAT("mp_windifference", 1); UTIL_LogPrintf("Career End\n"); } /* <113e08> ../cstrike/dlls/multiplay_gamerules.cpp:263 */ void CMapInfo::__MAKE_VHOOK(KeyValue)(KeyValueData *pkvd) { if (FStrEq(pkvd->szKeyName, "buying")) { m_iBuyingStatus = Q_atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (FStrEq(pkvd->szKeyName, "bombradius")) { m_flBombRadius = Q_atoi(pkvd->szValue); if (m_flBombRadius > MAX_BOMB_RADIUS) m_flBombRadius = MAX_BOMB_RADIUS; pkvd->fHandled = TRUE; } } /* <112879> ../cstrike/dlls/multiplay_gamerules.cpp:280 */ void CMapInfo::__MAKE_VHOOK(Spawn)(void) { pev->movetype = MOVETYPE_NONE; pev->solid = SOLID_NOT; pev->effects |= EF_NODRAW; } /* <114673> ../cstrike/dlls/multiplay_gamerules.cpp:288 */ LINK_ENTITY_TO_CLASS(info_map_parameters, CMapInfo); /* <11124e> ../cstrike/dlls/multiplay_gamerules.cpp:293 */ bool CCStrikeGameMgrHelper::__MAKE_VHOOK(CanPlayerHearPlayer)(CBasePlayer *pListener, CBasePlayer *pSender) { if (!pSender->IsPlayer() || pListener->m_iTeam != pSender->m_iTeam) { return false; } BOOL bListenerAlive = pListener->IsAlive(); BOOL bSenderAlive = pSender->IsAlive(); if (pListener->IsObserver()) { return true; } if (bListenerAlive) { if (!bSenderAlive) return false; } else { if (bSenderAlive) return true; } return (bListenerAlive == bSenderAlive); } /* <11474f> ../cstrike/dlls/multiplay_gamerules.cpp:331 */ void Broadcast(const char *sentence) { char text[32]; if (!sentence) { return; } Q_strcpy(text, "%!MRAD_"); Q_strcat(text, UTIL_VarArgs("%s", sentence)); MESSAGE_BEGIN(MSG_BROADCAST, gmsgSendAudio); WRITE_BYTE(0); WRITE_STRING(text); WRITE_SHORT(100); MESSAGE_END(); } /* <111767> ../cstrike/dlls/multiplay_gamerules.cpp:348 */ char *GetTeam(int teamNo) { switch (teamNo) { case TERRORIST: return "TERRORIST"; case CT: return "CT"; case SPECTATOR: return "SPECTATOR"; default: break; } return ""; } /* <114805> ../cstrike/dlls/multiplay_gamerules.cpp:364 */ void EndRoundMessage(const char *sentence, int event) { CHalfLifeMultiplay *mp = g_pGameRules; char *team = NULL; const char *message = &(sentence[1]); int teamTriggered = 1; UTIL_ClientPrintAll(HUD_PRINTCENTER, sentence); switch (event) { case ROUND_TARGET_BOMB: case ROUND_VIP_ASSASSINATED: case ROUND_TERRORISTS_ESCAPED: case ROUND_TERRORISTS_WIN: case ROUND_HOSTAGE_NOT_RESCUED: case ROUND_VIP_NOT_ESCAPED: team = GetTeam(TERRORIST); // tell bots the terrorists won the round if (TheBots != NULL) { 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 != NULL) { TheBots->OnEvent(EVENT_CTS_WIN); } break; default: teamTriggered = false; // tell bots the round was a draw if (TheBots != NULL) { TheBots->OnEvent(EVENT_ROUND_DRAW); } break; } if (mp != NULL) { if (teamTriggered) { UTIL_LogPrintf ( "Team \"%s\" triggered \"%s\" (CT \"%i\") (T \"%i\")\n", team, message, mp->m_iNumCTWins, mp->m_iNumTerroristWins ); } else { UTIL_LogPrintf ( "World triggered \"%s\" (CT \"%i\") (T \"%i\")\n", message, mp->m_iNumCTWins, mp->m_iNumTerroristWins ); } } UTIL_LogPrintf("World triggered \"Round_End\"\n"); } /* <1128a1> ../cstrike/dlls/multiplay_gamerules.cpp:419 */ void ReadMultiplayCvars(CHalfLifeMultiplay *mp) { mp->m_iRoundTime = (int)(CVAR_GET_FLOAT("mp_roundtime") * 60); mp->m_iC4Timer = (int)CVAR_GET_FLOAT("mp_c4timer"); mp->m_iIntroRoundTime = (int)CVAR_GET_FLOAT("mp_freezetime"); mp->m_iLimitTeams = (int)CVAR_GET_FLOAT("mp_limitteams"); if (mp->m_iRoundTime > 540) { CVAR_SET_FLOAT("mp_roundtime", 9); mp->m_iRoundTime = 540; } else if (mp->m_iRoundTime < 60) { CVAR_SET_FLOAT("mp_roundtime", 1); mp->m_iRoundTime = 60; } if (mp->m_iIntroRoundTime > 60) { CVAR_SET_FLOAT("mp_freezetime", 60); mp->m_iIntroRoundTime = 60; } else if (mp->m_iIntroRoundTime < 0) { CVAR_SET_FLOAT("mp_freezetime", 0); mp->m_iIntroRoundTime = 0; } if (mp->m_iC4Timer > 90) { CVAR_SET_FLOAT("mp_c4timer", 90); mp->m_iC4Timer = 90; } else if (mp->m_iC4Timer < 10) { CVAR_SET_FLOAT("mp_c4timer", 10); mp->m_iC4Timer = 10; } if (mp->m_iLimitTeams > 20) { CVAR_SET_FLOAT("mp_limitteams", 20); mp->m_iLimitTeams = 20; } else if (mp->m_iLimitTeams < 0) { CVAR_SET_FLOAT("mp_limitteams", 0); mp->m_iLimitTeams = 0; } } /* <11492c> ../cstrike/dlls/multiplay_gamerules.cpp:479 */ CHalfLifeMultiplay::CHalfLifeMultiplay(void) { UNTESTED m_VoiceGameMgr.Init(&g_GameMgrHelper, gpGlobals->maxClients); RefreshSkillData(); m_flIntermissionEndTime = 0; m_flIntermissionStartTime = 0; m_fTeamCount = 0; m_iAccountCT = 0; m_iAccountTerrorist = 0; m_iHostagesRescued = 0; m_iRoundWinStatus = 0; m_iNumCTWins = 0; m_iNumTerroristWins = 0; m_pVIP = NULL; m_iNumCT = 0; m_iNumTerrorist = 0; m_iNumSpawnableCT = 0; m_iNumSpawnableTerrorist = 0; m_bMapHasCameras = MAP_HAS_CAMERAS_INIT; g_fGameOver = FALSE; m_iLoserBonus = REWARD_LOSER_BONUS_DEFAULT; m_iNumConsecutiveCTLoses = 0; m_iNumConsecutiveTerroristLoses = 0; m_iC4Guy = 0; m_bBombDefused = false; m_bTargetBombed = false; m_bFreezePeriod = TRUE; m_bLevelInitialized = false; m_tmNextPeriodicThink = 0; m_bFirstConnected = 0; m_bCompleteReset = false; m_flRequiredEscapeRatio = 0.5; m_iNumEscapers = 0; m_bCTCantBuy = false; m_bTCantBuy = false; m_flBombRadius = 500.0; m_iTotalGunCount = 0; m_iTotalGrenadeCount = 0; m_iTotalArmourCount = 0; m_iConsecutiveVIP = 0; m_iUnBalancedRounds = 0; m_iNumEscapeRounds = 0; m_bRoundTerminating = false; g_iHostageNumber = 0; m_bBombDropped = FALSE; m_iMaxRounds = (int)CVAR_GET_FLOAT("mp_maxrounds"); if (m_iMaxRounds < 0) { m_iMaxRounds = 0; CVAR_SET_FLOAT("mp_maxrounds", 0); } m_iTotalRoundsPlayed = 0; m_iMaxRoundsWon = (int)CVAR_GET_FLOAT("mp_winlimit"); if (m_iMaxRoundsWon < 0) { m_iMaxRoundsWon = 0; CVAR_SET_FLOAT("mp_winlimit", 0); } Q_memset(m_iMapVotes, 0, sizeof(m_iMapVotes)); m_iLastPick = 1; m_bMapHasEscapeZone = false; m_iMapHasVIPSafetyZone = 0; m_bMapHasBombZone = false; m_bMapHasRescueZone = false; m_iStoredSpectValue = (int)allow_spectators.value; for (int j = 0; j < MAX_VIP_QUEUES; j++) { VIPQueue[j] = NULL; } CVAR_SET_FLOAT("cl_himodels", 0); ReadMultiplayCvars(this); m_iIntroRoundTime += 2; m_fMaxIdlePeriod = m_iRoundTime * 2; float flAutoKickIdle = CVAR_GET_FLOAT("mp_autokick_timeout"); if (flAutoKickIdle > 0.0) { m_fMaxIdlePeriod = flAutoKickIdle; } m_bInCareerGame = false; m_iRoundTimeSecs = m_iIntroRoundTime; if (IS_DEDICATED_SERVER()) { CVAR_SET_FLOAT("pausable", 0); } 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"); } else { CVAR_SET_FLOAT("pausable", 0); const char *lservercfgfile = CVAR_GET_STRING("lservercfgfile"); if (lservercfgfile && *lservercfgfile != '\0') { ALERT(at_console, "Executing listen server config file\n"); char szCommand[256]; Q_sprintf(szCommand, "exec %s\n", lservercfgfile); SERVER_COMMAND(szCommand); } } m_fRoundCount = 0; m_fIntroRoundCount = 0; InstallBotControl(); InstallHostageManager(); m_bSkipSpawn = m_bInCareerGame; static bool installedCommands = false; if (!installedCommands) { if (UTIL_IsGame("czero")) { #if defined(HOOK_GAMEDLL) && !defined(REGAMEDLL_UNIT_TESTS) ADD_SERVER_COMMAND("career_continue", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z13SV_Continue_fv", (void *)SV_Continue_f)); ADD_SERVER_COMMAND("career_matchlimit", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z21SV_CareerMatchLimit_fv", (void *)SV_CareerMatchLimit_f)); ADD_SERVER_COMMAND("career_add_task", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z18SV_CareerAddTask_fv", (void *)SV_CareerAddTask_f)); ADD_SERVER_COMMAND("career_endround", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z20SV_Career_EndRound_fv", (void *)SV_Career_EndRound_f)); ADD_SERVER_COMMAND("career_restart", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z19SV_Career_Restart_fv", (void *)SV_Career_Restart_f)); ADD_SERVER_COMMAND("tutor_toggle", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z17SV_Tutor_Toggle_fv", (void *)SV_Tutor_Toggle_f)); #else ADD_SERVER_COMMAND("career_continue", SV_Continue_f); ADD_SERVER_COMMAND("career_matchlimit", SV_CareerMatchLimit_f); ADD_SERVER_COMMAND("career_add_task", SV_CareerAddTask_f); ADD_SERVER_COMMAND("career_endround", SV_Career_EndRound_f); ADD_SERVER_COMMAND("career_restart", SV_Career_Restart_f); ADD_SERVER_COMMAND("tutor_toggle", SV_Tutor_Toggle_f); #endif // HOOK_GAMEDLL } #if defined(HOOK_GAMEDLL) && !defined(REGAMEDLL_UNIT_TESTS) ADD_SERVER_COMMAND("perf_test", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z15loopPerformancev", (void *)loopPerformance)); ADD_SERVER_COMMAND("print_ent", (xcommand_t)GetOriginalFuncAddrOrDefault("_Z13printEntitiesv", (void *)printEntities)); #else ADD_SERVER_COMMAND("perf_test", loopPerformance); ADD_SERVER_COMMAND("print_ent", printEntities); #endif // HOOK_GAMEDLL installedCommands = true; } m_fCareerRoundMenuTime = 0; m_fCareerMatchMenuTime = 0; m_iCareerMatchWins = 0; m_iRoundWinDifference = (int)CVAR_GET_FLOAT("mp_windifference"); CCareerTaskManager::Create(); if (m_iRoundWinDifference < 1) { m_iRoundWinDifference = 1; CVAR_SET_FLOAT("mp_windifference", 1); } sv_clienttrace = CVAR_GET_POINTER("sv_clienttrace"); InstallTutor(CVAR_GET_FLOAT("tutor_enable") != 0.0f); g_pMPGameRules = this; } /* <113b92> ../cstrike/dlls/multiplay_gamerules.cpp:678 */ void CHalfLifeMultiplay::__MAKE_VHOOK(RefreshSkillData)(void) { CGameRules::RefreshSkillData(); gSkillData.plrDmg9MM = 12; gSkillData.plrDmgMP5 = 12; gSkillData.suitchargerCapacity = 30; gSkillData.plrDmg357 = 40; gSkillData.plrDmgM203Grenade = 100; gSkillData.plrDmgBuckshot = 20; gSkillData.plrDmgCrossbowClient = 20; gSkillData.plrDmgRPG = 120; } /* <113b51> ../cstrike/dlls/multiplay_gamerules.cpp:713 */ void CHalfLifeMultiplay::__MAKE_VHOOK(RemoveGuns)(void) { CBaseEntity *toremove = NULL; while ((toremove = UTIL_FindEntityByClassname(toremove, "weaponbox")) != NULL) ((CWeaponBox *)toremove)->Kill(); toremove = NULL; while ((toremove = UTIL_FindEntityByClassname(toremove, "weapon_shield")) != NULL) { toremove->SetThink(&CBaseEntity::SUB_Remove); toremove->pev->nextthink = gpGlobals->time + 0.1; } } /* <1149e8> ../cstrike/dlls/multiplay_gamerules.cpp:733 */ void CHalfLifeMultiplay::UpdateTeamScores(void) { 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(); } /* <113aee> ../cstrike/dlls/multiplay_gamerules.cpp:747 */ void CHalfLifeMultiplay::__MAKE_VHOOK(CleanUpMap)(void) { // Recreate all the map entities from the map data (preserving their indices), // then remove everything else except the players. CBaseEntity *torestart = NULL; CBaseEntity *toremove = NULL; torestart = UTIL_FindEntityByClassname(NULL, "cycler_sprite"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "cycler_sprite"); } torestart = UTIL_FindEntityByClassname(NULL, "light"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "light"); } torestart = UTIL_FindEntityByClassname(NULL, "func_breakable"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_breakable"); } torestart = UTIL_FindEntityByClassname(NULL, "func_door"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_door"); } torestart = UTIL_FindEntityByClassname(NULL, "func_water"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_water"); } torestart = UTIL_FindEntityByClassname(NULL, "func_door_rotating"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_door_rotating"); } torestart = UTIL_FindEntityByClassname(NULL, "func_tracktrain"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_tracktrain"); } torestart = UTIL_FindEntityByClassname(NULL, "func_vehicle"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_vehicle"); } torestart = UTIL_FindEntityByClassname(NULL, "func_train"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "func_train"); } torestart = UTIL_FindEntityByClassname(NULL, "armoury_entity"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "armoury_entity"); } torestart = UTIL_FindEntityByClassname(NULL, "ambient_generic"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "ambient_generic"); } torestart = UTIL_FindEntityByClassname(NULL, "env_sprite"); while (torestart != NULL) { torestart->Restart(); torestart = UTIL_FindEntityByClassname(torestart, "env_sprite"); } // Remove grenades and C4 int icount = 0; toremove = UTIL_FindEntityByClassname(NULL, "grenade"); while (toremove != NULL && icount < 20) { UTIL_Remove(toremove); toremove = UTIL_FindEntityByClassname(toremove, "grenade"); icount++; } // Remove defuse kit // Old code only removed 4 kits and stopped. toremove = UTIL_FindEntityByClassname(NULL, "item_thighpack"); while (toremove != NULL) { UTIL_Remove(toremove); toremove = UTIL_FindEntityByClassname(toremove, "item_thighpack"); } RemoveGuns(); PLAYBACK_EVENT((FEV_GLOBAL | FEV_RELIABLE), 0, m_usResetDecals); } /* <118585> ../cstrike/dlls/multiplay_gamerules.cpp:862 */ void CHalfLifeMultiplay::__MAKE_VHOOK(GiveC4)(void) { int iTeamCount; int iTemp = 0; int humansPresent = 0; iTeamCount = m_iNumTerrorist; m_iC4Guy++; bool giveToHumans = (cv_bot_defer_to_human.value > 0.0); if (giveToHumans) { for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *player = reinterpret_cast(UTIL_PlayerByIndex(i)); if (!player || FNullEnt(player->edict())) continue; if (player->pev->deadflag != DEAD_NO || player->m_iTeam != TERRORIST) continue; if (!player->IsBot()) humansPresent++; } if (humansPresent) iTeamCount = humansPresent; else giveToHumans = false; } // if we've looped past the last Terrorist.. then give the C4 to the first one. if (m_iC4Guy > iTeamCount) { m_iC4Guy = 1; } // Give the C4 to the specified T player.. CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (!pPlayer->IsPlayer()) continue; if (pPlayer->pev->flags == FL_DORMANT) continue; CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (player->pev->deadflag != DEAD_NO || player->m_iTeam != TERRORIST || (giveToHumans && player->IsBot())) continue; iTemp++; if (iTemp == m_iC4Guy) { player->m_bHasC4 = true; player->GiveNamedItem("weapon_c4"); player->SetBombIcon(); player->pev->body = 1; player->m_flDisplayHistory |= DHF_BOMB_RETRIEVED; player->HintMessage("#Hint_you_have_the_bomb", FALSE, TRUE); // Log this information UTIL_LogPrintf ( "\"%s<%i><%s>\" triggered \"Spawned_With_The_Bomb\"\n", STRING(player->pev->netname), GETPLAYERUSERID(player->edict()), GETPLAYERAUTHID(player->edict()) ); m_bBombDropped = FALSE; } } // if there are no players with a bomb if (!IsThereABomber()) { m_iC4Guy = 0; pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (!pPlayer->IsPlayer()) continue; if (pPlayer->pev->flags == FL_DORMANT) continue; CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (player->pev->deadflag != DEAD_NO || player->m_iTeam != TERRORIST) continue; player->m_bHasC4 = true; player->GiveNamedItem("weapon_c4"); player->SetBombIcon(FALSE); player->pev->body = 1; player->m_flDisplayHistory |= DHF_BOMB_RETRIEVED; player->HintMessage("#Hint_you_have_the_bomb", FALSE, TRUE); // Log this information UTIL_LogPrintf ( "\"%s<%i><%s>\" triggered \"Spawned_With_The_Bomb\"\n", STRING(player->pev->netname), GETPLAYERUSERID(player->edict()), GETPLAYERAUTHID(player->edict()) ); m_bBombDropped = FALSE; return; } } } /* <11541f> ../cstrike/dlls/multiplay_gamerules.cpp:981 */ void CHalfLifeMultiplay::TerminateRound(float tmDelay, int iWinStatus) { m_iRoundWinStatus = iWinStatus; m_fTeamCount = gpGlobals->time + tmDelay; m_bRoundTerminating = true; } /* <114a6a> ../cstrike/dlls/multiplay_gamerules.cpp:995 */ void CHalfLifeMultiplay::QueueCareerRoundEndMenu(float tmDelay, int iWinStatus) { if (TheCareerTasks == NULL) return; if (m_fCareerMatchMenuTime != 0.0f) return; m_fCareerRoundMenuTime = tmDelay + gpGlobals->time; bool humansAreCTs = (Q_strcmp(humans_join_team.string, "CT") == 0); if (humansAreCTs) { CBaseEntity *hostage = NULL; int numHostagesInMap = 0; int numHostagesFollowingHumans = 0; int numHostagesAlive = 0; while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL) { numHostagesInMap++; CHostage *pHostage = reinterpret_cast(hostage); if (pHostage->pev->takedamage != DAMAGE_YES) { continue; } CBasePlayer *pLeader = NULL; if (pHostage->m_improv != NULL) { if (pHostage->IsFollowingSomeone()) { pLeader = reinterpret_cast(pHostage->GetLeader()); } } else if (pHostage->m_hTargetEnt != NULL && pHostage->m_State == CHostage::FOLLOW) { pLeader = (CBasePlayer *)((CBaseEntity *)pHostage->m_hTargetEnt); } if (pLeader == NULL) { numHostagesAlive++; } else { if (!pLeader->IsBot()) { ++numHostagesFollowingHumans; TheCareerTasks->HandleEvent(EVENT_HOSTAGE_RESCUED, pLeader, 0); } } } if (!numHostagesAlive) { if ((numHostagesInMap * 0.5) <= (numHostagesFollowingHumans + m_iHostagesRescued)) { TheCareerTasks->HandleEvent(EVENT_ALL_HOSTAGES_RESCUED); } } } switch (iWinStatus) { case WINSTATUS_CTS: TheCareerTasks->HandleEvent(humansAreCTs ? EVENT_ROUND_WIN : EVENT_ROUND_LOSS); break; case WINSTATUS_TERRORISTS: TheCareerTasks->HandleEvent(humansAreCTs ? EVENT_ROUND_LOSS : EVENT_ROUND_WIN); break; default: TheCareerTasks->HandleEvent(EVENT_ROUND_DRAW); break; } if (m_fCareerMatchMenuTime == 0.0f && m_iCareerMatchWins) { bool canTsWin = true; bool canCTsWin = true; if (m_iNumCTWins < m_iCareerMatchWins || (m_iNumCTWins - m_iNumTerroristWins < m_iRoundWinDifference)) canCTsWin = false; if (m_iNumTerroristWins < m_iCareerMatchWins || (m_iNumTerroristWins - m_iNumCTWins < m_iRoundWinDifference)) canTsWin = false; if (!TheCareerTasks->AreAllTasksComplete()) { if (humansAreCTs) return; canTsWin = false; } if (canCTsWin || canTsWin) { m_fCareerRoundMenuTime = 0; m_fCareerMatchMenuTime = gpGlobals->time + 3.0f; } } } /* <117750> ../cstrike/dlls/multiplay_gamerules.cpp:1084 */ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void) { // If a winner has already been determined and game of started.. then get the heck out of here if (m_bFirstConnected && m_iRoundWinStatus != 0) { return; } // Initialize the player counts.. int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT; InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT); // other player's check bool bNeededPlayers = false; if (NeededPlayersCheck(bNeededPlayers)) return; // Assasination/VIP scenarion check if (VIPRoundEndCheck(bNeededPlayers)) return; // Prison escape check if (PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) return; // Bomb check if (BombRoundEndCheck(bNeededPlayers)) return; // Team Extermination check // CounterTerrorists won by virture of elimination if (TeamExterminationCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) return; // Hostage rescue check if (HostageRescueRoundEndCheck(bNeededPlayers)) return; } 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; m_iHaveEscaped = 0; // initialize count dead/alive players CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) { break; } CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (pPlayer->pev->flags == FL_DORMANT) { continue; } // TODO: check it out, for what here used player->IsBot() ? // maybe body this conditions is located under the wrapper #ifdef 0 // if (player->IsBot()) // { // #ifdef 0 // .... // #endif // } switch (player->m_iTeam) { case CT: { m_iNumCT++; if (player->m_iMenu != Menu_ChooseAppearance) { m_iNumSpawnableCT++; //player->IsBot(); } //player->IsBot(); if (player->pev->deadflag != DEAD_NO) NumDeadCT++; else NumAliveCT++; break; } case TERRORIST: { m_iNumTerrorist++; if (player->m_iMenu != Menu_ChooseAppearance) { m_iNumSpawnableTerrorist++; //player->IsBot(); } //player->IsBot(); if (player->pev->deadflag != DEAD_NO) NumDeadTerrorist++; else NumAliveTerrorist++; // Check to see if this guy escaped. if (player->m_bEscaped) m_iHaveEscaped++; break; } default: break; } } } bool CHalfLifeMultiplay::NeededPlayersCheck(bool &bNeededPlayers) { // We needed players to start scoring // Do we have them now? // start the game, after the players entered in game if (!m_iNumSpawnableTerrorist || !m_iNumSpawnableCT) { UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_scoring"); bNeededPlayers = true; m_bFirstConnected = false; } if (!m_bFirstConnected && m_iNumSpawnableTerrorist != 0 && m_iNumSpawnableCT != 0) { if (IsCareer()) { CBasePlayer *player = reinterpret_cast(UTIL_PlayerByIndex(gpGlobals->maxClients)); if (!player || !player->IsBot()) { return true; } } // Start the round immediately when the first person joins UTIL_LogPrintf("World triggered \"Game_Commencing\"\n"); // Make sure we are not on the FreezePeriod. m_bFreezePeriod = FALSE; m_bCompleteReset = true; EndRoundMessage("#Game_Commencing", ROUND_END_DRAW); TerminateRound(IsCareer() ? 0 : 3, WINSTATUS_DRAW); m_bFirstConnected = true; if (TheBots != NULL) { TheBots->OnEvent(EVENT_GAME_COMMENCE); } return true; } return false; } bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers) { // checks to scenario Escaped VIP on map with vip safety zones if (m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && m_pVIP != NULL) { if (m_pVIP->m_bEscaped) { Broadcast("ctwin"); m_iAccountCT += REWARD_VIP_ESCAPED; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR); WRITE_BYTE(9); // command length in bytes WRITE_BYTE(DRC_CMD_EVENT); // VIP rescued WRITE_SHORT(ENTINDEX(m_pVIP->edict())); // index number of primary entity WRITE_SHORT(0); // index number of secondary entity WRITE_LONG(15 | DRC_FLAG_FINAL); // eventflags (priority and flags) MESSAGE_END(); EndRoundMessage("#VIP_Escaped", ROUND_VIP_ESCAPED); if (TheBots != NULL) { TheBots->OnEvent(EVENT_VIP_ESCAPED); } TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } return true; } // The VIP is dead else if (m_pVIP->pev->deadflag != DEAD_NO) { Broadcast("terwin"); m_iAccountTerrorist += REWARD_VIP_ASSASSINATED; if (!bNeededPlayers) { m_iNumTerroristWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#VIP_Assassinated", ROUND_VIP_ASSASSINATED); if (TheBots != NULL) { TheBots->OnEvent(EVENT_VIP_ASSASSINATED); } TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } return true; } } return false; } bool CHalfLifeMultiplay::PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers) { // checks to scenario Escaped Terrorist's if (m_bMapHasEscapeZone) { float_precision flEscapeRatio = (float_precision)m_iHaveEscaped / (float_precision)m_iNumEscapers; if (flEscapeRatio >= m_flRequiredEscapeRatio) { Broadcast("terwin"); m_iAccountTerrorist += REWARD_TERRORISTS_ESCAPED; if (!bNeededPlayers) { m_iNumTerroristWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#Terrorists_Escaped", ROUND_TERRORISTS_ESCAPED); TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } return true; } else if (NumAliveTerrorist == 0 && flEscapeRatio < m_flRequiredEscapeRatio) { Broadcast("ctwin"); // CTs are rewarded based on how many terrorists have escaped... m_iAccountCT += (1 - flEscapeRatio) * REWARD_CTS_PREVENT_ESCAPE; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#CTs_PreventEscape", ROUND_CTS_PREVENT_ESCAPE); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } return true; } else if (NumAliveTerrorist == 0 && NumDeadTerrorist != 0 && m_iNumSpawnableCT > 0) { Broadcast("ctwin"); // CTs are rewarded based on how many terrorists have escaped... m_iAccountCT += (1 - flEscapeRatio) * REWARD_ESCAPING_TERRORISTS_NEUTRALIZED; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#Escaping_Terrorists_Neutralized", ROUND_ESCAPING_TERRORISTS_NEUTRALIZED); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } return true; } // else return true; } return false; } bool CHalfLifeMultiplay::BombRoundEndCheck(bool bNeededPlayers) { // 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) { Broadcast("terwin"); m_iAccountTerrorist += REWARD_TARGET_BOMB; if (!bNeededPlayers) { m_iNumTerroristWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#Target_Bombed", ROUND_TARGET_BOMB); TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } return true; } else if (m_bBombDefused && m_bMapHasBombTarget) { Broadcast("ctwin"); m_iAccountCT += REWARD_BOMB_DEFUSED; m_iAccountTerrorist += REWARD_BOMB_PLANTED; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#Bomb_Defused", ROUND_BOMB_DEFUSED); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } return true; } return false; } bool CHalfLifeMultiplay::TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers) { if ((m_iNumCT > 0 && m_iNumSpawnableCT > 0) && (m_iNumTerrorist > 0 && m_iNumSpawnableTerrorist > 0)) { if (!NumAliveTerrorist && NumDeadTerrorist && NumAliveCT > 0) { CBaseEntity *temp = NULL; bool nowin = false; while ((temp = UTIL_FindEntityByClassname(temp, "grenade")) != NULL) { CGrenade *C4 = reinterpret_cast(temp); if (C4->m_bIsC4 && !C4->m_bJustBlew) { nowin = true; #ifdef REGAMEDLL_FIXES break; #endif // REGAMEDLL_FIXES } } if (!nowin) { Broadcast("ctwin"); m_iAccountCT += m_bMapHasBombTarget ? REWARD_BOMB_DEFUSED : REWARD_CTS_WIN; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#CTs_Win", ROUND_CTS_WIN); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } } return true; } // Terrorists WON if (NumAliveCT == 0 && NumDeadCT != 0) { Broadcast("terwin"); m_iAccountTerrorist += m_bMapHasBombTarget ? REWARD_BOMB_EXPLODED : REWARD_TERRORISTS_WIN; if (!bNeededPlayers) { m_iNumTerroristWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#Terrorists_Win", ROUND_TERRORISTS_WIN); TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } return true; } } else if (NumAliveCT == 0 && NumAliveTerrorist == 0) { EndRoundMessage("#Round_Draw", ROUND_END_DRAW); Broadcast("rounddraw"); TerminateRound(5, WINSTATUS_DRAW); return true; } return false; } bool CHalfLifeMultiplay::HostageRescueRoundEndCheck(bool bNeededPlayers) { // Check to see if 50% of the hostages have been rescued. CBaseEntity *hostage = NULL; int iHostages = 0; // Assume that all hostages are either rescued or dead.. bool bHostageAlive = false; while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL) { iHostages++; // We've found a live hostage. don't end the round if (hostage->pev->takedamage == DAMAGE_YES) { bHostageAlive = true; } } // There are no hostages alive.. check to see if the CTs have rescued atleast 50% of them. if (!bHostageAlive && iHostages > 0) { if (m_iHostagesRescued >= (iHostages * 0.5)) { Broadcast("ctwin"); m_iAccountCT += REWARD_ALL_HOSTAGES_RESCUED; if (!bNeededPlayers) { m_iNumCTWins++; // Update the clients team score UpdateTeamScores(); } EndRoundMessage("#All_Hostages_Rescued", ROUND_ALL_HOSTAGES_RESCUED); if (TheBots != NULL) { TheBots->OnEvent(EVENT_ALL_HOSTAGES_RESCUED); } if (IsCareer()) { if (TheCareerTasks != NULL) { TheCareerTasks->HandleEvent(EVENT_ALL_HOSTAGES_RESCUED); } } TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } return true; } } return false; } /* <117336> ../cstrike/dlls/multiplay_gamerules.cpp:1499 */ void CHalfLifeMultiplay::SwapAllPlayers(void) { CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (pPlayer->pev->flags == FL_DORMANT) continue; CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); player->SwitchTeam(); } // Swap Team victories int iTemp; iTemp = m_iNumTerroristWins; m_iNumTerroristWins = m_iNumCTWins; m_iNumCTWins = iTemp; // Update the clients team score UpdateTeamScores(); } /* <1171eb> ../cstrike/dlls/multiplay_gamerules.cpp:1525 */ void CHalfLifeMultiplay::BalanceTeams(void) { int iTeamToSwap = UNASSIGNED; int iNumToSwap; // The ratio for teams is different for Assasination maps if (m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES) { int iDesiredNumCT, iDesiredNumTerrorist; // uneven number of players if ((m_iNumCT + m_iNumTerrorist) % 2 != 0) iDesiredNumCT = (int)((m_iNumCT + m_iNumTerrorist) * 0.55f) + 1; else iDesiredNumCT = (int)((m_iNumCT + m_iNumTerrorist) / 2); iDesiredNumTerrorist = (m_iNumCT + m_iNumTerrorist) - iDesiredNumCT; if (m_iNumCT < iDesiredNumCT) { iTeamToSwap = TERRORIST; iNumToSwap = iDesiredNumCT - m_iNumCT; } else if (m_iNumTerrorist < iDesiredNumTerrorist) { iTeamToSwap = CT; iNumToSwap = iDesiredNumTerrorist - m_iNumTerrorist; } else { return; } } else { if (m_iNumCT > m_iNumTerrorist) { iTeamToSwap = CT; iNumToSwap = (m_iNumCT - m_iNumTerrorist) / 2; } else if (m_iNumTerrorist > m_iNumCT) { iTeamToSwap = TERRORIST; iNumToSwap = (m_iNumTerrorist - m_iNumCT) / 2; } else { // Teams are even.. Get out of here. return; } } // Don't swap more than 4 players at a time.. This is a naive method of avoiding infinite loops. if (iNumToSwap > 4) iNumToSwap = 4; // last person to join the server int iHighestUserID = 0; CBasePlayer *toSwap = NULL; for (int i = 1; i <= iNumToSwap; i++) { iHighestUserID = 0; toSwap = NULL; CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (pPlayer->pev->flags == FL_DORMANT) continue; CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (player->m_iTeam == iTeamToSwap && GETPLAYERUSERID(player->edict()) > iHighestUserID && m_pVIP != player) { iHighestUserID = GETPLAYERUSERID(player->edict()); toSwap = player; } } if (toSwap != NULL) { toSwap->SwitchTeam(); } } } /* <113158> ../cstrike/dlls/multiplay_gamerules.cpp:1608 */ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckMapConditions)(void) { if (UTIL_FindEntityByClassname(NULL, "func_bomb_target")) { m_bMapHasBombTarget = true; m_bMapHasBombZone = true; } else if (UTIL_FindEntityByClassname(NULL, "info_bomb_target")) { m_bMapHasBombTarget = true; m_bMapHasBombZone = false; } else { m_bMapHasBombTarget = false; m_bMapHasBombZone = false; } // Check to see if this map has hostage rescue zones m_bMapHasRescueZone = (UTIL_FindEntityByClassname(NULL, "func_hostage_rescue") != NULL); // See if the map has func_buyzone entities // Used by CBasePlayer::HandleSignals() to support maps without these entities m_bMapHasBuyZone = (UTIL_FindEntityByClassname(NULL, "func_buyzone") != NULL); // GOOSEMAN : See if this map has func_escapezone entities m_bMapHasEscapeZone = (UTIL_FindEntityByClassname(NULL, "func_escapezone") != NULL); // Check to see if this map has VIP safety zones if ((UTIL_FindEntityByClassname(NULL, "func_vip_safetyzone")) != NULL) m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_YES; else m_iMapHasVIPSafetyZone = MAP_HAVE_VIP_SAFETYZONE_NO; } /* <11745e> ../cstrike/dlls/multiplay_gamerules.cpp:1676 */ void CHalfLifeMultiplay::__MAKE_VHOOK(RestartRound)(void) { // tell bots that the round is restarting if (TheBots != NULL) { TheBots->RestartRound(); } if (g_pHostages != NULL) { g_pHostages->RestartRound(); } m_iTotalRoundsPlayed++; ClearBodyQue(); // Hardlock the player accelaration to 5.0 CVAR_SET_FLOAT("sv_accelerate", 5.0); CVAR_SET_FLOAT("sv_friction", 4.0); CVAR_SET_FLOAT("sv_stopspeed", 75); // Tabulate the number of players on each team. m_iNumCT = CountTeamPlayers(CT); m_iNumTerrorist = CountTeamPlayers(TERRORIST); // reset the dropped bomb on everyone's radar if (m_bMapHasBombTarget) { MESSAGE_BEGIN(MSG_ALL, gmsgBombPickup); MESSAGE_END(); MESSAGE_BEGIN(MSG_ALL, gmsgShowTimer); MESSAGE_END(); } m_bBombDropped = FALSE; // reset all players health for HLTV MESSAGE_BEGIN(MSG_SPEC, gmsgHLTV); WRITE_BYTE(0); // 0 = all players WRITE_BYTE(100 | DRC_FLAG_FACEPLAYER); // 100 health + msg flag MESSAGE_END(); // reset all players FOV for HLTV MESSAGE_BEGIN(MSG_SPEC, gmsgHLTV); WRITE_BYTE(0); // all players WRITE_BYTE(0); // to default FOV value MESSAGE_END(); if (CVAR_GET_FLOAT("mp_autoteambalance") != 0.0f && m_iUnBalancedRounds >= 1) { BalanceTeams(); } if ((m_iNumCT - m_iNumTerrorist) >= 2 || (m_iNumTerrorist - m_iNumCT) >= 2) { m_iUnBalancedRounds++; } else m_iUnBalancedRounds = 0; // Warn the players of an impending auto-balance next round... if (CVAR_GET_FLOAT("mp_autoteambalance") != 0.0f && m_iUnBalancedRounds == 1) { UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Auto_Team_Balance_Next_Round"); } if (m_bCompleteReset) { // bounds check if (timelimit.value < 0) { CVAR_SET_FLOAT("mp_timelimit", 0); } g_flResetTime = gpGlobals->time; // Reset timelimit if (timelimit.value) g_flTimeLimit = gpGlobals->time + (timelimit.value * 60); // Reset total # of rounds played m_iTotalRoundsPlayed = 0; m_iMaxRounds = (int)CVAR_GET_FLOAT("mp_maxrounds"); if (m_iMaxRounds < 0) { m_iMaxRounds = 0; CVAR_SET_FLOAT("mp_maxrounds", 0); } m_iMaxRoundsWon = (int)CVAR_GET_FLOAT("mp_winlimit"); if (m_iMaxRoundsWon < 0) { m_iMaxRoundsWon = 0; CVAR_SET_FLOAT("mp_winlimit", 0); } // Reset score info m_iNumTerroristWins = 0; m_iNumCTWins = 0; m_iNumConsecutiveTerroristLoses = 0; m_iNumConsecutiveCTLoses = 0; // Reset team scores UpdateTeamScores(); // Reset the player stats for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *plr = reinterpret_cast(UTIL_PlayerByIndex(i)); if (plr && !FNullEnt(plr->pev)) plr->Reset(); } if (TheBots != NULL) { TheBots->OnEvent(EVENT_NEW_MATCH); } } m_bFreezePeriod = TRUE; m_bRoundTerminating = false; ReadMultiplayCvars(this); float flAutoKickIdle = CVAR_GET_FLOAT("mp_autokick_timeout"); // set the idlekick max time (in seconds) if (flAutoKickIdle > 0) m_fMaxIdlePeriod = flAutoKickIdle; else m_fMaxIdlePeriod = (m_iRoundTime * 2); // This makes the round timer function as the intro timer on the client side m_iRoundTimeSecs = m_iIntroRoundTime; // Check to see if there's a mapping info paramater entity CMapInfo *mi = (CMapInfo *)UTIL_FindEntityByClassname(NULL, "info_map_parameters"); if (mi != NULL) { switch (mi->m_iBuyingStatus) { case BUYING_EVERYONE: m_bCTCantBuy = false; m_bTCantBuy = false; ALERT(at_console, "EVERYONE CAN BUY!\n"); break; case BUYING_ONLY_CTS: m_bCTCantBuy = false; m_bTCantBuy = true; ALERT(at_console, "Only CT's can buy!!\n"); break; case BUYING_ONLY_TERRORISTS: m_bCTCantBuy = true; m_bTCantBuy = false; ALERT(at_console, "Only T's can buy!!\n"); break; case BUYING_NO_ONE: m_bCTCantBuy = true; m_bTCantBuy = true; ALERT(at_console, "No one can buy!!\n"); break; default: m_bCTCantBuy = false; m_bTCantBuy = false; break; } m_flBombRadius = mi->m_flBombRadius; } CheckMapConditions(); if (m_bMapHasEscapeZone) { // Will increase this later when we count how many Ts are starting m_iNumEscapers = m_iHaveEscaped = 0; if (m_iNumEscapeRounds >= 3) { SwapAllPlayers(); m_iNumEscapeRounds = 0; } // Increment the number of rounds played... After 8 rounds, the players will do a whole sale switch.. m_iNumEscapeRounds++; } if (m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES) { PickNextVIP(); m_iConsecutiveVIP++; } int acct_tmp = 0; CBaseEntity *hostage = NULL; while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL) { if (acct_tmp >= 2000) break; CHostage *temp = reinterpret_cast(hostage); if (hostage->pev->solid != SOLID_NOT) { acct_tmp += 150; if (hostage->pev->deadflag == DEAD_DEAD) { hostage->pev->deadflag = DEAD_RESPAWNABLE; } } temp->RePosition(); } // Scale up the loser bonus when teams fall into losing streaks if (m_iRoundWinStatus == WINSTATUS_TERRORISTS) // terrorists won { // check to see if they just broke a losing streak if (m_iNumConsecutiveTerroristLoses > 1) { // this is the default losing bonus m_iLoserBonus = REWARD_LOSER_BONUS_MIN; } m_iNumConsecutiveTerroristLoses = 0; // starting fresh m_iNumConsecutiveCTLoses++; // increment the number of wins the CTs have had } else if (m_iRoundWinStatus == WINSTATUS_CTS) { // check to see if they just broke a losing streak if (m_iNumConsecutiveCTLoses > 1) { // this is the default losing bonus m_iLoserBonus = REWARD_LOSER_BONUS_MIN; } m_iNumConsecutiveCTLoses = 0; // starting fresh m_iNumConsecutiveTerroristLoses++; // increment the number of wins the Terrorists have had } // check if the losing team is in a losing streak & that the loser bonus hasen't maxed out. if(m_iNumConsecutiveTerroristLoses > 1 && m_iLoserBonus < REWARD_LOSER_BONUS_MAX) { // help out the team in the losing streak m_iLoserBonus += REWARD_LOSER_BONUS_ADD; } else if(m_iNumConsecutiveCTLoses > 1 && m_iLoserBonus < REWARD_LOSER_BONUS_MAX) { // help out the team in the losing streak m_iLoserBonus += REWARD_LOSER_BONUS_ADD; } // assign the wining and losing bonuses if (m_iRoundWinStatus == WINSTATUS_TERRORISTS) // terrorists won { m_iAccountTerrorist += acct_tmp; m_iAccountCT += m_iLoserBonus; } else if (m_iRoundWinStatus == WINSTATUS_CTS) // CT Won { m_iAccountCT += acct_tmp; if (!m_bMapHasEscapeZone) { // only give them the bonus if this isn't an escape map m_iAccountTerrorist += m_iLoserBonus; } } // Update CT account based on number of hostages rescued m_iAccountCT += m_iHostagesRescued * REWARD_RESCUED_HOSTAGE; // Update individual players accounts and respawn players // the round time stamp must be set before players are spawned m_fIntroRoundCount = m_fRoundCount = gpGlobals->time; // Adrian - No cash for anyone at first rounds! ( well, only the default. ) if (m_bCompleteReset) { // No extra cash!. m_iAccountTerrorist = m_iAccountCT = 0; // We are starting fresh. So it's like no one has ever won or lost. m_iNumTerroristWins = 0; m_iNumCTWins = 0; m_iNumConsecutiveTerroristLoses = 0; m_iNumConsecutiveCTLoses = 0; m_iLoserBonus = REWARD_LOSER_BONUS_DEFAULT; } // tell bots that the round is restarting CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (pPlayer->pev->flags == FL_DORMANT) continue; CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); player->m_iNumSpawns = 0; player->m_bTeamChanged = false; if (!player->IsPlayer()) { player->SyncRoundTimer(); } if (player->m_iTeam == CT) { if (!player->m_bReceivesNoMoneyNextRound) { player->AddAccount(m_iAccountCT); } } else if (player->m_iTeam == TERRORIST) { // Add another potential escaper to the mix! m_iNumEscapers++; if (!player->m_bReceivesNoMoneyNextRound) { player->AddAccount(m_iAccountTerrorist); } // If it's a prison scenario then remove the Ts guns if (m_bMapHasEscapeZone) { // this will cause them to be reset with default weapons, armor, and items player->m_bNotKilled = false; } } if (player->m_iTeam != UNASSIGNED && player->m_iTeam != SPECTATOR) { // drop the c4 if the player is carrying it if (player->m_bHasC4) { player->DropPlayerItem("weapon_c4"); } player->RoundRespawn(); } // 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) } // Respawn entities (glass, doors, etc..) CleanUpMap(); // Give C4 to the terrorists if (m_bMapHasBombTarget) { GiveC4(); } if (TheBots != NULL) { TheBots->OnEvent(EVENT_BUY_TIME_START); } // Reset game variables m_flIntermissionEndTime = 0; m_flIntermissionStartTime = 0; m_fTeamCount = 0.0; m_iAccountTerrorist = m_iAccountCT = 0; m_iHostagesRescued = 0; m_iHostagesTouched = 0; m_iRoundWinStatus = 0; m_bTargetBombed = m_bBombDefused = false; m_bLevelInitialized = false; m_bCompleteReset = false; } /* <114ca3> ../cstrike/dlls/multiplay_gamerules.cpp:2073 */ BOOL CHalfLifeMultiplay::IsThereABomber(void) { CBasePlayer *pPlayer = NULL; while ((pPlayer = (CBasePlayer *)UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (FNullEnt(pPlayer->edict())) break; if (pPlayer->m_iTeam != CT && pPlayer->IsBombGuy()) { // There you are. return TRUE; } } // Didn't find a bomber. return FALSE; } /* <114d20> ../cstrike/dlls/multiplay_gamerules.cpp:2097 */ BOOL CHalfLifeMultiplay::IsThereABomb(void) { CGrenade *pC4 = NULL; CBaseEntity *pWeaponC4 = NULL; BOOL bFoundBomb = FALSE; while ((pWeaponC4 = UTIL_FindEntityByClassname(pWeaponC4, "grenade")) != NULL) { if (!pWeaponC4) continue; pC4 = (CGrenade *)pWeaponC4; if (pC4->m_bIsC4) { bFoundBomb = TRUE; break; } } if (bFoundBomb || (UTIL_FindEntityByClassname(NULL, "weapon_c4")) != NULL) { return TRUE; } return FALSE; } /* <114d83> ../cstrike/dlls/multiplay_gamerules.cpp:2129 */ BOOL CHalfLifeMultiplay::TeamFull(int team_id) { switch (team_id) { case TERRORIST: return (m_iNumTerrorist >= m_iSpawnPointCount_Terrorist); case CT: return (m_iNumCT >= m_iSpawnPointCount_CT); } return FALSE; } // checks to see if the desired team is stacked, returns true if it is /* <114dbb> ../cstrike/dlls/multiplay_gamerules.cpp:2144 */ BOOL CHalfLifeMultiplay::TeamStacked(int newTeam_id, int curTeam_id) { // players are allowed to change to their own team if (newTeam_id == curTeam_id) return FALSE; if (!m_iLimitTeams) return FALSE; switch (newTeam_id) { 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)); } return FALSE; } /* <114e2b> ../cstrike/dlls/multiplay_gamerules.cpp:2214 */ void CHalfLifeMultiplay::StackVIPQueue(void) { for (int i = 0; i < MAX_VIP_QUEUES - 2; i++) { if (VIPQueue[i - 1]) { if (!VIPQueue[i]) { VIPQueue[i] = VIPQueue[i + 1]; VIPQueue[i + 1] = NULL; } } else { VIPQueue[i - 1] = VIPQueue[i]; VIPQueue[i] = VIPQueue[i + 1]; VIPQueue[i + 1] = NULL; } } } /* <114e63> ../cstrike/dlls/multiplay_gamerules.cpp:2232 */ bool CHalfLifeMultiplay::IsVIPQueueEmpty(void) { for (int i = 0; i < MAX_VIP_QUEUES; i++) { CBasePlayer *toCheck = VIPQueue[i]; if (toCheck != NULL && toCheck->m_iTeam != CT) { VIPQueue[i] = NULL; } } StackVIPQueue(); return (VIPQueue[0] == NULL && VIPQueue[1] == NULL && VIPQueue[2] == NULL && VIPQueue[3] == NULL && VIPQueue[4] == NULL); } /* <114eea> ../cstrike/dlls/multiplay_gamerules.cpp:2257 */ bool CHalfLifeMultiplay::AddToVIPQueue(CBasePlayer *toAdd) { for (int i = 0; i < MAX_VIP_QUEUES; i++) { CBasePlayer *toCheck = VIPQueue[i]; if (toCheck && toCheck->m_iTeam != CT) { VIPQueue[i] = NULL; } } StackVIPQueue(); if (toAdd->m_iTeam == CT) { int j; for (j = 0; j < MAX_VIP_QUEUES; j++) { if (VIPQueue[j] == toAdd) { ClientPrint(toAdd->pev, HUD_PRINTCENTER, "#Game_in_position", UTIL_dtos1(j + 1)); return FALSE; } } for (j = 0; j < MAX_VIP_QUEUES; j++) { if (!VIPQueue[j]) { VIPQueue[j] = toAdd; StackVIPQueue(); ClientPrint(toAdd->pev, HUD_PRINTCENTER, "#Game_added_position", UTIL_dtos1(j + 1)); return TRUE; } } ClientPrint(toAdd->pev, HUD_PRINTCENTER, "#All_VIP_Slots_Full"); } return FALSE; } /* <114f80> ../cstrike/dlls/multiplay_gamerules.cpp:2290 */ void CHalfLifeMultiplay::ResetCurrentVIP(void) { char *infobuffer = GET_INFO_BUFFER(m_pVIP->edict()); int numSkins = UTIL_IsGame("czero") ? CZ_NUM_SKIN : CS_NUM_SKIN; switch (RANDOM_LONG(0, numSkins)) { case 1: m_pVIP->m_iModelName = MODEL_GSG9; SET_CLIENT_KEY_VALUE(m_pVIP->entindex(), infobuffer, "model", "gsg9"); break; case 2: m_pVIP->m_iModelName = MODEL_SAS; SET_CLIENT_KEY_VALUE(m_pVIP->entindex(), infobuffer, "model", "sas"); break; case 3: m_pVIP->m_iModelName = MODEL_GIGN; SET_CLIENT_KEY_VALUE(m_pVIP->entindex(), infobuffer, "model", "gign"); break; case 4: if (UTIL_IsGame("czero")) { m_pVIP->m_iModelName = MODEL_SPETSNAZ; SET_CLIENT_KEY_VALUE(m_pVIP->entindex(), infobuffer, "model", "spetsnaz"); break; } default: m_pVIP->m_iModelName = MODEL_URBAN; SET_CLIENT_KEY_VALUE(m_pVIP->entindex(), infobuffer, "model", "urban"); break; } m_pVIP->m_bIsVIP = false; m_pVIP->m_bNotKilled = false; } /* <11706f> ../cstrike/dlls/multiplay_gamerules.cpp:2335 */ void CHalfLifeMultiplay::PickNextVIP(void) { if (!IsVIPQueueEmpty()) { // Remove the current VIP from his VIP status and make him a regular CT. if (m_pVIP != NULL) { ResetCurrentVIP(); } for (int i = 0; i < MAX_VIP_QUEUES; i++) { if (VIPQueue[i] != NULL) { m_pVIP = VIPQueue[i]; m_pVIP->MakeVIP(); VIPQueue[i] = NULL; // remove this player from the VIP queue StackVIPQueue(); // and re-organize the queue m_iConsecutiveVIP = 0; return; } } } // If it's been the same VIP for 3 rounds already.. then randomly pick a new one else if (m_iConsecutiveVIP >= 3) { m_iLastPick++; if (m_iLastPick > m_iNumCT) m_iLastPick = 1; int iCount = 1; CBaseEntity *pPlayer = NULL; CBasePlayer *player = NULL; CBasePlayer *pLastPlayer = NULL; pPlayer = UTIL_FindEntityByClassname(pPlayer, "player"); while ((pPlayer != NULL) && (!FNullEnt(pPlayer->edict()))) { if (!(pPlayer->pev->flags & FL_DORMANT)) { player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (player->m_iTeam == CT && iCount == m_iLastPick) { if (player == m_pVIP && pLastPlayer != NULL) player = pLastPlayer; // Remove the current VIP from his VIP status and make him a regular CT. if (m_pVIP != NULL) { ResetCurrentVIP(); } player->MakeVIP(); m_iConsecutiveVIP = 0; return; } else if (player->m_iTeam == CT) iCount++; if (player->m_iTeam != SPECTATOR) pLastPlayer = player; } pPlayer = UTIL_FindEntityByClassname(pPlayer, "player"); } } // There is no VIP and there is no one waiting to be the VIP.. therefore just pick the first CT player we can find. else if (m_pVIP == NULL) { CBaseEntity *pPlayer = NULL; CBasePlayer *player = NULL; pPlayer = UTIL_FindEntityByClassname(pPlayer, "player"); while ((pPlayer != NULL) && (!FNullEnt(pPlayer->edict()))) { if (pPlayer->pev->flags != FL_DORMANT) { player = GetClassPtr((CBasePlayer *)pPlayer->pev); if (player->m_iTeam == CT) { player->MakeVIP(); m_iConsecutiveVIP = 0; return; } } pPlayer = UTIL_FindEntityByClassname(pPlayer, "player"); } } } /* <115458> ../cstrike/dlls/multiplay_gamerules.cpp:2435 */ void CHalfLifeMultiplay::__MAKE_VHOOK(Think)(void) { MonitorTutorStatus(); m_VoiceGameMgr.Update(gpGlobals->frametime); if (sv_clienttrace->value != 1.0f) { CVAR_SET_FLOAT("sv_clienttrace", 1); } if (!m_fRoundCount) { // intialize the timer time stamps, this happens once only m_fIntroRoundCount = m_fRoundCount = gpGlobals->time; } 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; } // Check game rules if (CheckGameOver()) return; // have we hit the timelimit? if (CheckTimeLimit()) return; if (!IsCareer()) { // have we hit the max rounds? if (CheckMaxRounds()) return; if (CheckWinLimit()) 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); WRITE_BYTE((int)allow_spectators.value); MESSAGE_END(); } // Check for the end of the round. if (IsFreezePeriod()) { CheckFreezePeriodExpired(); } else { CheckRoundTimeExpired(); } if (m_fTeamCount != 0.0f && m_fTeamCount <= gpGlobals->time) { if (!IsCareer() || !m_fCareerRoundMenuTime) { RestartRound(); } else if (TheCareerTasks != NULL) { bool isBotSpeaking = false; if (m_fTeamCount + 10.0 > gpGlobals->time) { 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; for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *pPlayer = reinterpret_cast(UTIL_PlayerByIndex(i)); if (pPlayer != NULL && !pPlayer->IsBot()) { MESSAGE_BEGIN(MSG_ONE, gmsgCZCareerHUD, NULL, pPlayer->pev); WRITE_STRING("ROUND"); WRITE_LONG(m_iNumCTWins); WRITE_LONG(m_iNumTerroristWins); WRITE_BYTE(m_iCareerMatchWins); WRITE_BYTE(m_iRoundWinDifference); WRITE_BYTE(m_iRoundWinStatus); MESSAGE_END(); pPlayer->m_iHideHUD |= HIDEHUD_ALL; m_fTeamCount = gpGlobals->time + 100000.0; UTIL_LogPrintf("Career Round %d %d %d %d\n", m_iRoundWinStatus, m_iNumCTWins, m_iNumTerroristWins, TheCareerTasks->AreAllTasksComplete()); break; } } m_fCareerRoundMenuTime = 0; } } if (TheTutor != NULL) { TheTutor->PurgeMessages(); } } CheckLevelInitialized(); if (gpGlobals->time > m_tmNextPeriodicThink) { CheckRestartRound(); m_tmNextPeriodicThink = gpGlobals->time + 1.0f; if (g_psv_accelerate->value != 5.0f) { CVAR_SET_FLOAT("sv_accelerate", 5.0); } if (g_psv_friction->value != 4.0f) { CVAR_SET_FLOAT("sv_friction", 4.0); } if (g_psv_stopspeed->value != 75.0f) { CVAR_SET_FLOAT("sv_stopspeed", 75.0); } m_iMaxRounds = (int)maxrounds.value; if (m_iMaxRounds < 0) { m_iMaxRounds = 0; CVAR_SET_FLOAT("mp_maxrounds", 0); } m_iMaxRoundsWon = (int)winlimit.value; if (m_iMaxRoundsWon < 0) { m_iMaxRoundsWon = 0; CVAR_SET_FLOAT("mp_winlimit", 0); } } } else { 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"); } } } bool CHalfLifeMultiplay::CheckGameOver(void) { // someone else quit the game already if (g_fGameOver) { int time = (int)CVAR_GET_FLOAT("mp_chattime"); if (time < 1) CVAR_SET_STRING("mp_chattime", "1"); else if (time > MAX_INTERMISSION_TIME) CVAR_SET_STRING("mp_chattime", UTIL_dtos1(MAX_INTERMISSION_TIME)); // bounds check m_flIntermissionEndTime = m_flIntermissionStartTime + mp_chattime.value; // check to see if we should change levels now if (m_flIntermissionEndTime < gpGlobals->time && !IsCareer()) { if (!UTIL_HumansInGame(false) // if only bots, just change immediately || 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; } bool CHalfLifeMultiplay::CheckTimeLimit(void) { float fTimeLimit = timelimit.value; if (fTimeLimit < 0) { CVAR_SET_FLOAT("mp_timelimit", 0); return false; } if (!IsCareer()) { if (fTimeLimit != 0.0f) { g_flTimeLimit = g_flResetTime + fTimeLimit * 60.0f; } if (fTimeLimit > 0 && gpGlobals->time >= g_flTimeLimit) { ALERT(at_console, "Changing maps because time limit has been met\n"); GoToIntermission(); return true; } } return false; } bool CHalfLifeMultiplay::CheckMaxRounds(void) { 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; } bool CHalfLifeMultiplay::CheckWinLimit(void) { // 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; } void CHalfLifeMultiplay::CheckFreezePeriodExpired(void) { if (TimeRemaining() > 0) return; // Log this information UTIL_LogPrintf("World triggered \"Round_Start\"\n"); // Freeze period expired: kill the flag m_bFreezePeriod = FALSE; char CT_sentence[40]; char T_sentence[40]; switch (RANDOM_LONG(0, 3)) { case 0: Q_strncpy(CT_sentence, "%!MRAD_MOVEOUT", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_MOVEOUT", sizeof(T_sentence)); break; case 1: Q_strncpy(CT_sentence, "%!MRAD_LETSGO", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_LETSGO", sizeof(T_sentence)); break; case 2: Q_strncpy(CT_sentence, "%!MRAD_LOCKNLOAD", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_LOCKNLOAD", sizeof(T_sentence)); break; default: Q_strncpy(CT_sentence, "%!MRAD_GO", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_GO", sizeof(T_sentence)); break; } // More specific radio commands for the new scenarios : Prison & Assasination if (m_bMapHasEscapeZone) { Q_strncpy(CT_sentence, "%!MRAD_ELIM", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_GETOUT", sizeof(T_sentence)); } else if (m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES) { Q_strncpy(CT_sentence, "%!MRAD_VIP", sizeof(CT_sentence)); Q_strncpy(T_sentence, "%!MRAD_LOCKNLOAD", sizeof(T_sentence)); } // Reset the round time m_fRoundCount = gpGlobals->time; // in seconds m_iRoundTimeSecs = m_iRoundTime; bool bCTPlayed = false; bool bTPlayed = false; if (TheCareerTasks != NULL) { TheCareerTasks->HandleEvent(EVENT_ROUND_START); } for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *plr = reinterpret_cast(UTIL_PlayerByIndex(i)); if (!plr || plr->pev->flags == FL_DORMANT) { continue; } if (plr->m_iJoiningState == JOINED) { if (plr->m_iTeam == CT && !bCTPlayed) { plr->Radio(CT_sentence, NULL); bCTPlayed = true; } else if (plr->m_iTeam == TERRORIST && !bTPlayed) { plr->Radio(T_sentence, NULL); bTPlayed = true; } if (plr->m_iTeam != SPECTATOR) { plr->ResetMaxSpeed(); plr->m_bCanShoot = true; } } plr->SyncRoundTimer(); } if (TheBots != NULL) { TheBots->OnEvent(EVENT_ROUND_START); } if (TheCareerTasks != NULL) { TheCareerTasks->HandleEvent(EVENT_ROUND_START); } } void CHalfLifeMultiplay::CheckRoundTimeExpired(void) { if (!HasRoundTimeExpired()) return; #if 0 // Round time expired float flEndRoundTime; // Check to see if there's still a live C4 hanging around.. if so, wait until this C4 blows before ending the round CGrenade *C4 = (CGrenade *)UTIL_FindEntityByClassname(NULL, "grenade"); if (C4 != NULL) { if (!C4->m_bJustBlew) flEndRoundTime = C4->m_flC4Blow; else flEndRoundTime = gpGlobals->time + 5.0; } #endif // New code to get rid of round draws!! if (m_bMapHasBombTarget) { Broadcast("ctwin"); m_iAccountCT += REWARD_TARGET_BOMB_SAVED; m_iNumCTWins++; EndRoundMessage("#Target_Saved", ROUND_TARGET_SAVED); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } UpdateTeamScores(); MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(TERRORIST); } else if (UTIL_FindEntityByClassname(NULL, "hostage_entity") != NULL) { Broadcast("terwin"); m_iAccountTerrorist += REWARD_HOSTAGE_NOT_RESCUED; m_iNumTerroristWins++; EndRoundMessage("#Hostages_Not_Rescued", ROUND_HOSTAGE_NOT_RESCUED); TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } UpdateTeamScores(); MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(CT); } else if (m_bMapHasEscapeZone) { Broadcast("ctwin"); m_iNumCTWins++; EndRoundMessage("#Terrorists_Not_Escaped", ROUND_TERRORISTS_NOT_ESCAPED); TerminateRound(5, WINSTATUS_CTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_CTS); } UpdateTeamScores(); } else if (m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES) { Broadcast("terwin"); m_iAccountTerrorist += REWARD_VIP_NOT_ESCAPED; m_iNumTerroristWins++; EndRoundMessage("#VIP_Not_Escaped", ROUND_VIP_NOT_ESCAPED); TerminateRound(5, WINSTATUS_TERRORISTS); if (IsCareer()) { QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); } UpdateTeamScores(); } // This is done so that the portion of code has enough time to do it's thing. m_fRoundCount = gpGlobals->time + 60.0f; } void CHalfLifeMultiplay::CheckLevelInitialized(void) { if (!m_bLevelInitialized) { // Count the number of spawn points for each team // This determines the maximum number of players allowed on each CBaseEntity *ent = NULL; m_iSpawnPointCount_Terrorist = 0; m_iSpawnPointCount_CT = 0; while ((ent = UTIL_FindEntityByClassname(ent, "info_player_deathmatch")) != NULL) m_iSpawnPointCount_Terrorist++; while ((ent = UTIL_FindEntityByClassname(ent, "info_player_start")) != NULL) m_iSpawnPointCount_CT++; m_bLevelInitialized = true; } } void CHalfLifeMultiplay::CheckRestartRound(void) { // Restart the round if specified by the server int iRestartDelay = (int)restartround.value; if (!iRestartDelay) { iRestartDelay = sv_restart.value; } if (iRestartDelay > 0) { if (iRestartDelay > 60) iRestartDelay = 60; // log the restart UTIL_LogPrintf("World triggered \"Restart_Round_(%i_%s)\"\n", iRestartDelay, (iRestartDelay == 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(iRestartDelay), (iRestartDelay == 1) ? "SECOND" : "SECONDS"); UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_will_restart_in_console", UTIL_dtos1(iRestartDelay), (iRestartDelay == 1) ? "SECOND" : "SECONDS"); m_fTeamCount = gpGlobals->time + iRestartDelay; m_bCompleteReset = true; CVAR_SET_FLOAT("sv_restartround", 0); CVAR_SET_FLOAT("sv_restart", 0); CareerRestart(); } } /* <115189> ../cstrike/dlls/multiplay_gamerules.cpp:2922 */ bool CHalfLifeMultiplay::HasRoundTimeExpired(void) { // We haven't completed other objectives, so go for this!. if (TimeRemaining() > 0 || m_iRoundWinStatus != 0) { return false; } if (!IsBombPlanted()) { if (cv_bot_nav_edit.value == 0.0f || IS_DEDICATED_SERVER() || UTIL_HumansInGame(false) != 1) { return true; } } return false; } /* <1151f4> ../cstrike/dlls/multiplay_gamerules.cpp:2945 */ bool CHalfLifeMultiplay::IsBombPlanted(void) { if (m_bMapHasBombTarget) { CGrenade *bomb = NULL; if ((bomb = (CGrenade *)UTIL_FindEntityByClassname(bomb, "grenade")) != NULL) { if (bomb->m_bIsC4) { return true; } } } return false; } /* <115229> ../cstrike/dlls/multiplay_gamerules.cpp:2971 */ void CHalfLifeMultiplay::MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int iTeam) { for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *player = reinterpret_cast(UTIL_PlayerByIndex(i)); if (!player || FNullEnt(player->pev)) continue; if (player->m_iTeam == iTeam) { if (player->pev->health > 0 && player->pev->deadflag == DEAD_NO) { player->m_bReceivesNoMoneyNextRound = true; } } } } /* <1152e2> ../cstrike/dlls/multiplay_gamerules.cpp:2987 */ void CHalfLifeMultiplay::CareerRestart(void) { g_fGameOver = FALSE; if (m_fTeamCount == 0.0f) { m_fTeamCount = gpGlobals->time + 1.0f; } // for reset everything m_bCompleteReset = true; m_fCareerRoundMenuTime = 0; m_fCareerMatchMenuTime = 0; if (TheCareerTasks != NULL) { TheCareerTasks->Reset(false); } m_bSkipSpawn = false; for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *player = reinterpret_cast(UTIL_PlayerByIndex(i)); if (!player || FNullEnt(player->pev)) continue; if (!player->IsBot()) { player->ForceClientDllUpdate(); } } } /* <1128cb> ../cstrike/dlls/multiplay_gamerules.cpp:3017 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(IsMultiplayer)(void) { return TRUE; } /* <1128f3> ../cstrike/dlls/multiplay_gamerules.cpp:3024 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(IsDeathmatch)(void) { return TRUE; } /* <11291b> ../cstrike/dlls/multiplay_gamerules.cpp:3031 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(IsCoOp)(void) { return gpGlobals->coop; } /* <113fcf> ../cstrike/dlls/multiplay_gamerules.cpp:3038 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FShouldSwitchWeapon)(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon) { if (!pWeapon->CanDeploy()) return FALSE; if (!pPlayer->m_pActiveItem) return TRUE; if (!pPlayer->m_iAutoWepSwitch) return FALSE; if (!pPlayer->m_pActiveItem->CanHolster()) return FALSE; if (pWeapon->iWeight() > pPlayer->m_pActiveItem->iWeight()) return TRUE; return FALSE; } /* <113eec> ../cstrike/dlls/multiplay_gamerules.cpp:3071 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(GetNextBestWeapon)(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon) { 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; if (!pCurrentWeapon->CanHolster()) { // can't put this gun away right now, so can't switch. return FALSE; } iBestWeight = -1; // no weapon lower than -1 can be autoswitched to pBest = NULL; for (i = 0; i < MAX_ITEM_TYPES; i++) { pCheck = pPlayer->m_rgpPlayerItems[i]; while (pCheck != NULL) { // don't reselect the weapon we're trying to get rid of if (pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon) { //ALERT (at_console, "Considering %s\n", STRING(pCheck->pev->classname)); // we keep updating the 'best' weapon just in case we can't find a weapon of the same weight // that the player was using. This will end up leaving the player with his heaviest-weighted // weapon. if (pCheck->CanDeploy()) { // if this weapon is useable, flag it as the best iBestWeight = pCheck->iWeight(); pBest = pCheck; } } pCheck = pCheck->m_pNext; } } // if we make it here, we've checked all the weapons and found no useable // weapon in the same catagory as the current weapon. // if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always // at least get the crowbar, but ya never know. if (pBest == NULL) { return FALSE; } pPlayer->SwitchWeapon(pBest); return TRUE; } /* <113aa5> ../cstrike/dlls/multiplay_gamerules.cpp:3132 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(ClientCommand_DeadOrAlive)(CBasePlayer *pPlayer, const char *pcmd) { return m_VoiceGameMgr.ClientCommand(pPlayer, pcmd); } /* <113afe> ../cstrike/dlls/multiplay_gamerules.cpp:3138 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(ClientCommand)(CBasePlayer *pPlayer, const char *pcmd) { return FALSE; } /* <113a3c> ../cstrike/dlls/multiplay_gamerules.cpp:3145 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(ClientConnected)(edict_t *pEntity, const char *pszName, const char *pszAddress, char *szRejectReason) { m_VoiceGameMgr.ClientConnected(pEntity); return TRUE; } /* <11298b> ../cstrike/dlls/multiplay_gamerules.cpp:3156 */ void CHalfLifeMultiplay::__MAKE_VHOOK(UpdateGameMode)(CBasePlayer *pPlayer) { MESSAGE_BEGIN(MSG_ONE, gmsgGameMode, NULL, pPlayer->edict()); WRITE_BYTE(1); MESSAGE_END(); } /* <11642b> ../cstrike/dlls/multiplay_gamerules.cpp:3163 */ void CHalfLifeMultiplay::__MAKE_VHOOK(InitHUD)(CBasePlayer *pl) { int i; // notify other clients of player joining the game UTIL_LogPrintf ( "\"%s<%i><%s><>\" entered the game\n", STRING(pl->pev->netname), GETPLAYERUSERID(pl->edict()), GETPLAYERAUTHID(pl->edict()) ); UpdateGameMode(pl); if (!g_flWeaponCheat) { MESSAGE_BEGIN(MSG_ONE, gmsgViewMode, NULL, pl->edict()); MESSAGE_END(); } // sending just one score makes the hud scoreboard active; otherwise // it is just disabled for single play MESSAGE_BEGIN(MSG_ONE, gmsgScoreInfo, NULL, pl->edict()); WRITE_BYTE(ENTINDEX(pl->edict())); WRITE_SHORT(0); WRITE_SHORT(0); WRITE_SHORT(0); WRITE_SHORT(pl->m_iTeam); MESSAGE_END(); MESSAGE_BEGIN(MSG_ONE, gmsgShadowIdx, NULL, pl->edict()); WRITE_LONG(g_iShadowSprite); MESSAGE_END(); if (IsCareer()) { MESSAGE_BEGIN(MSG_ONE, gmsgCZCareer, NULL, pl->edict()); WRITE_STRING("START"); WRITE_SHORT(m_iRoundTime); MESSAGE_END(); } else SendMOTDToClient(pl->edict()); // loop through all active players and send their score info to the new client for (i = 1; i <= gpGlobals->maxClients; i++) { // FIXME: Probably don't need to cast this just to read m_iDeaths CBasePlayer *plr = reinterpret_cast(UTIL_PlayerByIndex(i)); if (plr != NULL) { MESSAGE_BEGIN(MSG_ONE, gmsgScoreInfo, NULL, pl->edict()); 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(); } } MESSAGE_BEGIN(MSG_ONE, gmsgTeamScore, NULL, pl->edict()); WRITE_STRING("TERRORIST"); WRITE_SHORT(m_iNumTerroristWins); MESSAGE_END(); MESSAGE_BEGIN(MSG_ONE, gmsgTeamScore, NULL, pl->edict()); WRITE_STRING("CT"); WRITE_SHORT(m_iNumCTWins); MESSAGE_END(); MESSAGE_BEGIN(MSG_ONE, gmsgAllowSpec, NULL, pl->edict()); WRITE_BYTE((int)allow_spectators.value); MESSAGE_END(); MESSAGE_BEGIN(MSG_ONE, gmsgForceCam, NULL, pl->edict()); WRITE_BYTE(forcecamera.value != 0); WRITE_BYTE(forcechasecam.value != 0); WRITE_BYTE(fadetoblack.value != 0); MESSAGE_END(); if (g_fGameOver) { MESSAGE_BEGIN(MSG_ONE, SVC_INTERMISSION, NULL, pl->edict()); MESSAGE_END(); } for (i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer *plr = reinterpret_cast(UTIL_PlayerByIndex(i)); if (plr != NULL) { MESSAGE_BEGIN(MSG_ONE, gmsgTeamInfo, NULL, pl->edict()); WRITE_BYTE(plr->entindex()); switch (plr->m_iTeam) { case CT: WRITE_STRING("CT"); break; case TERRORIST: WRITE_STRING("TERRORIST"); break; case SPECTATOR: WRITE_STRING("SPECTATOR"); break; default: WRITE_STRING("UNASSIGNED"); break; } MESSAGE_END(); plr->SetScoreboardAttributes(pl); if (i != pl->entindex()) { if (plr->pev->flags == FL_DORMANT) continue; if (plr->pev->deadflag == DEAD_NO) { MESSAGE_BEGIN(MSG_ONE, gmsgRadar, NULL, pl->edict()); WRITE_BYTE(plr->entindex()); WRITE_COORD(plr->pev->origin.x); WRITE_COORD(plr->pev->origin.y); WRITE_COORD(plr->pev->origin.z); MESSAGE_END(); } } } } if (m_bBombDropped) { CBaseEntity *pWeaponC4 = UTIL_FindEntityByClassname(NULL, "weapon_c4"); if (pWeaponC4 != NULL) { MESSAGE_BEGIN(MSG_ONE, gmsgBombDrop, NULL, pl->edict()); WRITE_COORD(pWeaponC4->pev->origin.x); WRITE_COORD(pWeaponC4->pev->origin.y); WRITE_COORD(pWeaponC4->pev->origin.z); WRITE_BYTE(0); MESSAGE_END(); } } } /* <1137c1> ../cstrike/dlls/multiplay_gamerules.cpp:3318 */ void CHalfLifeMultiplay::__MAKE_VHOOK(ClientDisconnected)(edict_t *pClient) { if (pClient != NULL) { CBasePlayer *pPlayer = reinterpret_cast(CBaseEntity::Instance(pClient)); if (pPlayer != NULL) { pPlayer->has_disconnected = true; pPlayer->pev->deadflag = DEAD_DEAD; pPlayer->SetScoreboardAttributes(); if (pPlayer->m_bHasC4) { pPlayer->DropPlayerItem("weapon_c4"); } if (pPlayer->m_bHasDefuser) { pPlayer->DropPlayerItem("item_thighpack"); } if (pPlayer->m_bIsVIP) { m_pVIP = NULL; } pPlayer->m_iCurrentKickVote = 0; if (pPlayer->m_iMapVote) { m_iMapVotes[ pPlayer->m_iMapVote ]--; if (m_iMapVotes[ pPlayer->m_iMapVote ] < 0) { m_iMapVotes[ pPlayer->m_iMapVote ] = 0; } } MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo); WRITE_BYTE(ENTINDEX(pClient)); WRITE_SHORT(0); WRITE_SHORT(0); WRITE_SHORT(0); WRITE_SHORT(0); MESSAGE_END(); MESSAGE_BEGIN(MSG_ALL, gmsgTeamInfo); WRITE_BYTE(ENTINDEX(pClient)); WRITE_STRING("UNASSIGNED"); MESSAGE_END(); MESSAGE_BEGIN(MSG_ALL, gmsgLocation); WRITE_BYTE(ENTINDEX(pClient)); WRITE_STRING(""); MESSAGE_END(); char *team = GetTeam(pPlayer->m_iTeam); FireTargets("game_playerleave", pPlayer, pPlayer, USE_TOGGLE, 0); UTIL_LogPrintf ( "\"%s<%i><%s><%s>\" disconnected\n", STRING(pPlayer->pev->netname), GETPLAYERUSERID(pPlayer->edict()), GETPLAYERAUTHID(pPlayer->edict()), team ); // destroy all of the players weapons and items pPlayer->RemoveAllItems(TRUE); if (pPlayer->m_pObserver != NULL) { pPlayer->m_pObserver->SUB_Remove(); } CBasePlayer *client = NULL; while ((client = (CBasePlayer *)UTIL_FindEntityByClassname(client, "player")) != NULL) { if (FNullEnt(client->edict())) break; if (!client->pev || client == pPlayer) continue; if (client->m_hObserverTarget == pPlayer) { int iMode = client->pev->iuser1; client->pev->iuser1 = OBS_NONE; client->Observer_SetMode(iMode); } } } } CheckWinConditions(); } /* <112a05> ../cstrike/dlls/multiplay_gamerules.cpp:3428 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlPlayerFallDamage)(CBasePlayer *pPlayer) { pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED * 1.25; } /* <112a3d> ../cstrike/dlls/multiplay_gamerules.cpp:3436 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FPlayerCanTakeDamage)(CBasePlayer *pPlayer, CBaseEntity *pAttacker) { if (!pAttacker || PlayerRelationship(pPlayer, pAttacker) != GR_TEAMMATE) { return TRUE; } if (CVAR_GET_FLOAT("mp_friendlyfire") != 0 || pAttacker == pPlayer) { return TRUE; } return FALSE; } /* <11370c> ../cstrike/dlls/multiplay_gamerules.cpp:3454 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerThink)(CBasePlayer *pPlayer) { if (g_fGameOver) { // check for button presses if (!IsCareer() && (pPlayer->m_afButtonPressed & (IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP))) { m_iEndIntermissionButtonHit = TRUE; } // clear attack/use commands from player pPlayer->m_afButtonPressed = 0; pPlayer->pev->button = 0; pPlayer->m_afButtonReleased = 0; } if (!pPlayer->m_bCanShoot && !IsFreezePeriod()) { pPlayer->m_bCanShoot = true; } if (pPlayer->m_pActiveItem && pPlayer->m_pActiveItem->IsWeapon()) { CBasePlayerWeapon *pWeapon = reinterpret_cast(pPlayer->m_pActiveItem->GetWeaponPtr()); if (pWeapon->m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { pPlayer->m_bCanShoot = false; } } if (pPlayer->m_iMenu != Menu_ChooseTeam && pPlayer->m_iJoiningState == SHOWTEAMSELECT) { int team = MENU_SLOT_TEAM_UNDEFINED; if (!Q_stricmp(humans_join_team.string, "T")) { team = MENU_SLOT_TEAM_TERRORIST; } else if (!Q_stricmp(humans_join_team.string, "CT")) { team = MENU_SLOT_TEAM_CT; } else { if (allow_spectators.value == 0.0f) ShowVGUIMenu(pPlayer, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5), "#Team_Select"); else ShowVGUIMenu(pPlayer, VGUI_Menu_Team, (MENU_KEY_1 | MENU_KEY_2 | MENU_KEY_5 | MENU_KEY_6), "#Team_Select_Spect"); } pPlayer->m_iMenu = Menu_ChooseTeam; pPlayer->m_iJoiningState = PICKINGTEAM; if (team != MENU_SLOT_TEAM_UNDEFINED && !pPlayer->IsBot()) { HandleMenu_ChooseTeam(pPlayer, team); if (team != MENU_SLOT_TEAM_SPECT && IsCareer()) { // slot 6 - chooses randomize the appearance to model player HandleMenu_ChooseAppearance(pPlayer, 6); } } } } // Purpose: Player has just spawned. Equip them. /* <113bcf> ../cstrike/dlls/multiplay_gamerules.cpp:3523 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerSpawn)(CBasePlayer *pPlayer) { // This is tied to the joining state (m_iJoiningState).. add it when the joining state is there. if (pPlayer->m_bJustConnected) { return; } pPlayer->pev->weapons |= (1 << WEAPON_SUIT); bool addDefault = true; CBaseEntity *pWeaponEntity = NULL; while ((pWeaponEntity = UTIL_FindEntityByClassname(pWeaponEntity, "game_player_equip")) != NULL) { pWeaponEntity->Touch(pPlayer); addDefault = false; } if (pPlayer->m_bNotKilled) addDefault = false; if (addDefault || pPlayer->m_bIsVIP) { pPlayer->GiveDefaultItems(); } pPlayer->SetPlayerModel(false); } /* <113d74> ../cstrike/dlls/multiplay_gamerules.cpp:3553 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FPlayerCanRespawn)(CBasePlayer *pPlayer) { // Player cannot respawn twice in a round if (pPlayer->m_iNumSpawns > 0) { return FALSE; } // Player cannot respawn until next round if more than 20 seconds in // Tabulate the number of players on each team. m_iNumCT = CountTeamPlayers(CT); m_iNumTerrorist = CountTeamPlayers(TERRORIST); if (m_iNumTerrorist > 0 && m_iNumCT > 0) { // If this player just connected and fadetoblack is on, then maybe // the server admin doesn't want him peeking around. if (gpGlobals->time > m_fRoundCount + 20.0f) { if (fadetoblack.value != 0.0f) { UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT)); } return FALSE; } } // Player cannot respawn while in the Choose Appearance menu if (pPlayer->m_iMenu == Menu_ChooseAppearance) { return FALSE; } return TRUE; } /* <112a86> ../cstrike/dlls/multiplay_gamerules.cpp:3591 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlPlayerSpawnTime)(CBasePlayer *pPlayer) { return gpGlobals->time;//now! } /* <112abe> ../cstrike/dlls/multiplay_gamerules.cpp:3596 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(AllowAutoTargetCrosshair)(void) { return FALSE; } // IPointsForKill - how many points awarded to anyone // that kills this player? /* <112ae6> ../cstrike/dlls/multiplay_gamerules.cpp:3619 */ int CHalfLifeMultiplay::__MAKE_VHOOK(IPointsForKill)(CBasePlayer *pAttacker, CBasePlayer *pKilled) { return 1; } /* <116cbd> ../cstrike/dlls/multiplay_gamerules.cpp:3627 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerKilled)(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor) { DeathNotice(pVictim, pKiller, pInflictor); pVictim->m_afPhysicsFlags &= ~PFLAG_ONTRAIN; pVictim->m_iDeaths++; pVictim->m_bNotKilled = false; pVictim->m_bEscaped = false; pVictim->m_iTrain = (TRAIN_NEW | TRAIN_OFF); SET_VIEW(ENT(pVictim->pev), ENT(pVictim->pev)); CBasePlayer *peKiller = NULL; CBaseEntity *ktmp = CBaseEntity::Instance(pKiller); if (ktmp && ktmp->Classify() == CLASS_PLAYER) { peKiller = reinterpret_cast(ktmp); } else if (ktmp && ktmp->Classify() == CLASS_VEHICLE) { CBasePlayer *pDriver = reinterpret_cast(((CFuncVehicle *)ktmp)->m_pDriver); if (pDriver != NULL) { pKiller = pDriver->pev; peKiller = reinterpret_cast(pDriver); } } FireTargets("game_playerdie", pVictim, pVictim, USE_TOGGLE, 0); // Did the player kill himself? if (pVictim->pev == pKiller) { // Players lose a frag for killing themselves pKiller->frags -= 1; } else if (peKiller && peKiller->IsPlayer()) { // if a player dies in a deathmatch game and the killer is a client, award the killer some points CBasePlayer *killer = GetClassPtr((CBasePlayer *)pKiller); if (killer->m_iTeam == pVictim->m_iTeam) { // if a player dies by from teammate pKiller->frags -= IPointsForKill(peKiller, pVictim); killer->AddAccount(PAYBACK_FOR_KILLED_TEAMMATES); killer->m_iTeamKills++; killer->m_bJustKilledTeammate = true; ClientPrint(killer->pev, HUD_PRINTCENTER, "#Killed_Teammate"); ClientPrint(killer->pev, HUD_PRINTCONSOLE, "#Game_teammate_kills", UTIL_dtos1(killer->m_iTeamKills)); if (killer->m_iTeamKills == 3 && CVAR_GET_FLOAT("mp_autokick") != 0.0f) { ClientPrint(killer->pev, HUD_PRINTCONSOLE, "#Banned_For_Killing_Teamates"); int iUserID = GETPLAYERUSERID(killer->edict()); if (iUserID != -1) { SERVER_COMMAND(UTIL_VarArgs("kick # %d\n", iUserID)); } } if (!(killer->m_flDisplayHistory & DHF_FRIEND_KILLED)) { killer->m_flDisplayHistory |= DHF_FRIEND_KILLED; killer->HintMessage("#Hint_careful_around_teammates"); } } else { // if a player dies in a deathmatch game and the killer is a client, award the killer some points pKiller->frags += IPointsForKill(peKiller, pVictim); if (pVictim->m_bIsVIP) { killer->HintMessage("#Hint_reward_for_killing_vip", TRUE); killer->AddAccount(REWARD_KILLED_VIP); 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(); UTIL_LogPrintf ( "\"%s<%i><%s>\" triggered \"Assassinated_The_VIP\"\n", STRING(killer->pev->netname), GETPLAYERUSERID(killer->edict()), GETPLAYERAUTHID(killer->edict()) ); } else killer->AddAccount(REWARD_KILLED_ENEMY); if (!(killer->m_flDisplayHistory & DHF_ENEMY_KILLED)) { killer->m_flDisplayHistory |= DHF_ENEMY_KILLED; killer->HintMessage("#Hint_win_round_by_killing_enemy"); } } FireTargets("game_playerkill", peKiller, peKiller, USE_TOGGLE, 0); } else { // killed by the world pKiller->frags -= 1; } // update the scores // killed scores MESSAGE_BEGIN(MSG_BROADCAST, gmsgScoreInfo); WRITE_BYTE(ENTINDEX(pVictim->edict())); WRITE_SHORT((int)pVictim->pev->frags); 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) { CBasePlayer *PK = reinterpret_cast(ep); MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo); WRITE_BYTE(ENTINDEX(PK->edict())); WRITE_SHORT((int)PK->pev->frags); 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; } } /* <113273> ../cstrike/dlls/multiplay_gamerules.cpp:3772 */ void CHalfLifeMultiplay::__MAKE_VHOOK(DeathNotice)(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor) { // Work out what killed the player, and send a message to all clients about it // CBaseEntity *Killer = CBaseEntity::Instance(pKiller); // by default, the player is killed by the world const char *killer_weapon_name = "world"; int killer_index = 0; // Hack to fix name change char *tau = "tau_cannon"; char *gluon = "gluon gun"; // Is the killer a client? if (pKiller->flags & FL_CLIENT) { killer_index = ENTINDEX(ENT(pKiller)); if (pevInflictor) { if (pevInflictor == pKiller) { // If the inflictor is the killer, then it must be their current weapon doing the damage CBasePlayer *pPlayer = reinterpret_cast(CBaseEntity::Instance(pKiller)); if (pPlayer && pPlayer->m_pActiveItem) { killer_weapon_name = pPlayer->m_pActiveItem->pszName(); } } else { // it's just that easy killer_weapon_name = STRING(pevInflictor->classname); } } } else killer_weapon_name = STRING(pevInflictor->classname); // strip the monster_* or weapon_* from the inflictor's classname if (!Q_strncmp(killer_weapon_name, "weapon_", 7)) killer_weapon_name += 7; else if (!Q_strncmp(killer_weapon_name, "monster_", 8)) killer_weapon_name += 8; else if (!Q_strncmp(killer_weapon_name, "func_", 5)) killer_weapon_name += 5; int iGotHeadshot = 0; if (pVictim->m_bHeadshotKilled) iGotHeadshot = 1; if (TheTutor == NULL) { MESSAGE_BEGIN(MSG_ALL, gmsgDeathMsg); WRITE_BYTE(killer_index); // the killer WRITE_BYTE(ENTINDEX(pVictim->edict())); // the victim WRITE_BYTE(iGotHeadshot); // is killed headshot WRITE_STRING(killer_weapon_name); // what they were killed by (should this be a string?) MESSAGE_END(); } // replace the code names with the 'real' names if (!Q_strcmp(killer_weapon_name, "egon")) killer_weapon_name = gluon; else if (!Q_strcmp(killer_weapon_name, "gauss")) killer_weapon_name = tau; // Did he kill himself? if (pVictim->pev == pKiller) { // killed self char *team = GetTeam(pVictim->m_iTeam); 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 ); } else if (pKiller->flags & FL_CLIENT) { CBasePlayer *pPlayer = reinterpret_cast(CBaseEntity::Instance(pKiller)); char *VictimTeam = GetTeam(pVictim->m_iTeam); char *KillerTeam = GetTeam(pPlayer->m_iTeam); 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 ); } else { // killed by the world char *team = GetTeam(pVictim->m_iTeam); 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 ); } CheckWinConditions(); MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR); WRITE_BYTE(9); // command length in bytes WRITE_BYTE(DRC_CMD_EVENT); // player killed WRITE_SHORT(ENTINDEX(pVictim->edict())); // index number of primary entity if (pevInflictor) WRITE_SHORT(ENTINDEX(ENT(pevInflictor))); // index number of secondary entity else WRITE_SHORT(ENTINDEX(ENT(pKiller))); // index number of secondary entity if (iGotHeadshot) WRITE_LONG(9 | DRC_FLAG_DRAMATIC | DRC_FLAG_SLOWMOTION); else WRITE_LONG(7 | DRC_FLAG_DRAMATIC); // eventflags (priority and flags) MESSAGE_END(); } // PlayerGotWeapon - player has grabbed a weapon that was // sitting in the world /* <112b2e> ../cstrike/dlls/multiplay_gamerules.cpp:3916 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerGotWeapon)(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon) { ; } // FlWeaponRespawnTime - what is the time in the future // at which this weapon may spawn? /* <112b76> ../cstrike/dlls/multiplay_gamerules.cpp:3924 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlWeaponRespawnTime)(CBasePlayerItem *pWeapon) { return gpGlobals->time + WEAPON_RESPAWN_TIME; } // FlWeaponRespawnTime - Returns 0 if the weapon can respawn // now, otherwise it returns the time at which it can try // to spawn again. /* <114058> ../cstrike/dlls/multiplay_gamerules.cpp:3938 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlWeaponTryRespawn)(CBasePlayerItem *pWeapon) { if (pWeapon && pWeapon->m_iId && (pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD)) { if (NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE)) return 0; // we're past the entity tolerance level, so delay the respawn return FlWeaponRespawnTime(pWeapon); } return 0; } /* <112bae> ../cstrike/dlls/multiplay_gamerules.cpp:3956 */ Vector CHalfLifeMultiplay::__MAKE_VHOOK(VecWeaponRespawnSpot)(CBasePlayerItem *pWeapon) { return pWeapon->pev->origin; } /* <112c11> ../cstrike/dlls/multiplay_gamerules.cpp:3965 */ int CHalfLifeMultiplay::__MAKE_VHOOK(WeaponShouldRespawn)(CBasePlayerItem *pWeapon) { if (pWeapon->pev->spawnflags & SF_NORESPAWN) { return GR_WEAPON_RESPAWN_NO; } return GR_WEAPON_RESPAWN_YES; } /* <11322b> ../cstrike/dlls/multiplay_gamerules.cpp:3979 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(CanHavePlayerItem)(CBasePlayer *pPlayer, CBasePlayerItem *pItem) { return CGameRules::CanHavePlayerItem(pPlayer, pItem); } /* <112c49> ../cstrike/dlls/multiplay_gamerules.cpp:3986 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(CanHaveItem)(CBasePlayer *pPlayer, CItem *pItem) { return TRUE; } /* <112c91> ../cstrike/dlls/multiplay_gamerules.cpp:3993 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerGotItem)(CBasePlayer *pPlayer, CItem *pItem) { ; } /* <112cd9> ../cstrike/dlls/multiplay_gamerules.cpp:3999 */ int CHalfLifeMultiplay::__MAKE_VHOOK(ItemShouldRespawn)(CItem *pItem) { if (pItem->pev->spawnflags & SF_NORESPAWN) { return GR_ITEM_RESPAWN_NO; } return GR_ITEM_RESPAWN_YES; } /* <112d11> ../cstrike/dlls/multiplay_gamerules.cpp:4013 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlItemRespawnTime)(CItem *pItem) { return gpGlobals->time + ITEM_RESPAWN_TIME; } /* <112d49> ../cstrike/dlls/multiplay_gamerules.cpp:4022 */ Vector CHalfLifeMultiplay::__MAKE_VHOOK(VecItemRespawnSpot)(CItem *pItem) { return pItem->pev->origin; } /* <112dac> ../cstrike/dlls/multiplay_gamerules.cpp:4029 */ void CHalfLifeMultiplay::__MAKE_VHOOK(PlayerGotAmmo)(CBasePlayer *pPlayer, char *szName, int iCount) { ; } /* <112e04> ../cstrike/dlls/multiplay_gamerules.cpp:4035 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(IsAllowedToSpawn)(CBaseEntity *pEntity) { return TRUE; } /* <112e3c> ../cstrike/dlls/multiplay_gamerules.cpp:4045 */ int CHalfLifeMultiplay::__MAKE_VHOOK(AmmoShouldRespawn)(CBasePlayerAmmo *pAmmo) { if (pAmmo->pev->spawnflags & SF_NORESPAWN) { return GR_AMMO_RESPAWN_NO; } return GR_AMMO_RESPAWN_YES; } /* <112e74> ../cstrike/dlls/multiplay_gamerules.cpp:4057 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlAmmoRespawnTime)(CBasePlayerAmmo *pAmmo) { return gpGlobals->time + 20.0f; } /* <112eac> ../cstrike/dlls/multiplay_gamerules.cpp:4064 */ Vector CHalfLifeMultiplay::__MAKE_VHOOK(VecAmmoRespawnSpot)(CBasePlayerAmmo *pAmmo) { return pAmmo->pev->origin; } /* <112f0f> ../cstrike/dlls/multiplay_gamerules.cpp:4071 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlHealthChargerRechargeTime)(void) { return 60; } /* <112f37> ../cstrike/dlls/multiplay_gamerules.cpp:4077 */ float CHalfLifeMultiplay::__MAKE_VHOOK(FlHEVChargerRechargeTime)(void) { return 30; } /* <112f5f> ../cstrike/dlls/multiplay_gamerules.cpp:4084 */ int CHalfLifeMultiplay::__MAKE_VHOOK(DeadPlayerWeapons)(CBasePlayer *pPlayer) { return GR_PLR_DROP_GUN_ACTIVE; } /* <112f97> ../cstrike/dlls/multiplay_gamerules.cpp:4091 */ int CHalfLifeMultiplay::__MAKE_VHOOK(DeadPlayerAmmo)(CBasePlayer *pPlayer) { return GR_PLR_DROP_AMMO_ACTIVE; } /* <1131d6> ../cstrike/dlls/multiplay_gamerules.cpp:4096 */ edict_t *CHalfLifeMultiplay::__MAKE_VHOOK(GetPlayerSpawnSpot)(CBasePlayer *pPlayer) { edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot(pPlayer); if (IsMultiplayer()) { if (pentSpawnSpot->v.target) { FireTargets(STRING(pentSpawnSpot->v.target), pPlayer, pPlayer, USE_TOGGLE, 0); } } return pentSpawnSpot; } /* <116c24> ../cstrike/dlls/multiplay_gamerules.cpp:4110 */ int CHalfLifeMultiplay::__MAKE_VHOOK(PlayerRelationship)(CBasePlayer *pPlayer, CBaseEntity *pTarget) { if (!pPlayer || !pTarget) { return GR_NOTTEAMMATE; } if (!pTarget->IsPlayer()) { return GR_NOTTEAMMATE; } CBasePlayer *player = GetClassPtr((CBasePlayer *)pPlayer->pev); CBasePlayer *target = GetClassPtr((CBasePlayer *)pTarget->pev); if (player->m_iTeam != target->m_iTeam) { return GR_NOTTEAMMATE; } return GR_TEAMMATE; } /* <112fcf> ../cstrike/dlls/multiplay_gamerules.cpp:4128 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FAllowFlashlight)(void) { static cvar_t *mp_flashlight = NULL; if (!mp_flashlight) mp_flashlight = CVAR_GET_POINTER("mp_flashlight"); if (mp_flashlight) return mp_flashlight->value != 0; return FALSE; } /* <113012> ../cstrike/dlls/multiplay_gamerules.cpp:4145 */ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FAllowMonsters)(void) { return CVAR_GET_FLOAT("mp_allowmonsters") != 0; } /* <114155> ../cstrike/dlls/multiplay_gamerules.cpp:4156 */ void CHalfLifeMultiplay::__MAKE_VHOOK(GoToIntermission)(void) { if (g_fGameOver) return; 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); if (IsCareer()) { 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(); if (TheCareerTasks != NULL) { UTIL_LogPrintf("Career Match %d %d %d %d\n", m_iRoundWinStatus, m_iNumCTWins, m_iNumTerroristWins, TheCareerTasks->AreAllTasksComplete()); } } MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION); MESSAGE_END(); if (IsCareer()) { SERVER_COMMAND("setpause\n"); } int time = (int)CVAR_GET_FLOAT("mp_chattime"); 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 = gpGlobals->time + (int)mp_chattime.value; m_flIntermissionStartTime = gpGlobals->time; g_fGameOver = TRUE; m_iEndIntermissionButtonHit = FALSE; m_iSpawnPointCount_Terrorist = 0; m_iSpawnPointCount_CT = 0; m_bLevelInitialized = false; } // Clean up memory used by mapcycle when switching it /* <115c98> ../cstrike/dlls/multiplay_gamerules.cpp:4241 */ void DestroyMapCycle(mapcycle_t *cycle) { mapcycle_item_t *p, *n, *start; p = cycle->items; if (p != NULL) { start = p; p = p->next; while (p != start) { n = p->next; delete p; p = n; } delete cycle->items; } cycle->items = NULL; cycle->next_item = NULL; } /* <115d30> ../cstrike/dlls/multiplay_gamerules.cpp:4271 */ char *MP_COM_GetToken(void) { return mp_com_token; } /* <115d4d> ../cstrike/dlls/multiplay_gamerules.cpp:4283 */ char *MP_COM_Parse(char *data) { int c; int len; len = 0; mp_com_token[0] = '\0'; if (!data) { return NULL; } skipwhite: // skip whitespace while (*data <= ' ') { if (!data[0]) return NULL; data++; } c = *data; // skip // comments till the next line if (c == '/' && data[1] == '/') { while (*data && *data != '\n') data++; goto skipwhite; // start over new line } // handle quoted strings specially: copy till the end or another quote if (c == '\"') { data++; // skip starting quote while (true) { // get char and advance c = *data++; if (c == '\"' || !c) { mp_com_token[ len ] = '\0'; return data; } mp_com_token[ len++ ] = c; } } // parse single characters if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ',') { mp_com_token[ len++ ] = c; mp_com_token[ len ] = '\0'; return data + 1; } // parse a regular word do { mp_com_token[ len++ ] = c; data++; c = *data; if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ',') break; } while (c > 32); mp_com_token[ len ] = '\0'; return data; } /* <115db1> ../cstrike/dlls/multiplay_gamerules.cpp:4360 */ int MP_COM_TokenWaiting(char *buffer) { char *p; p = buffer; while (*p && *p != '\n') { if (!isspace(*p) || isalnum(*p)) return 1; p++; } return 0; } /* <115e11> ../cstrike/dlls/multiplay_gamerules.cpp:4384 */ int ReloadMapCycleFile(char *filename, mapcycle_t *cycle) { char szBuffer[ MAX_RULE_BUFFER ]; char szMap[ 32 ]; int length; char *pFileList; char *aFileList = pFileList = (char *)LOAD_FILE_FOR_ME(filename, &length); int hasbuffer; mapcycle_item_s *item, *newlist = NULL, *next; if (pFileList && length) { // the first map name in the file becomes the default while (true) { hasbuffer = 0; Q_memset(szBuffer, 0, sizeof(szBuffer)); pFileList = MP_COM_Parse(pFileList); if (Q_strlen(mp_com_token) <= 0) break; Q_strcpy(szMap, mp_com_token); // Any more tokens on this line? if (MP_COM_TokenWaiting(pFileList)) { pFileList = MP_COM_Parse(pFileList); if (Q_strlen(mp_com_token) > 0) { hasbuffer = 1; Q_strcpy(szBuffer, mp_com_token); } } // Check map if (IS_MAP_VALID(szMap)) { // Create entry char *s; item = new mapcycle_item_s; Q_strcpy(item->mapname, szMap); item->minplayers = 0; item->maxplayers = 0; Q_memset(item->rulebuffer, 0, sizeof(item->rulebuffer)); if (hasbuffer) { s = GET_KEY_VALUE(szBuffer, "minplayers"); if (s && s[0] != '\0') { item->minplayers = Q_atoi(s); item->minplayers = Q_max(item->minplayers, 0); item->minplayers = Q_min(item->minplayers, gpGlobals->maxClients); } s = GET_KEY_VALUE(szBuffer, "maxplayers"); if (s && s[0] != '\0') { item->maxplayers = Q_atoi(s); item->maxplayers = Q_max(item->maxplayers, 0); item->maxplayers = Q_min(item->maxplayers, gpGlobals->maxClients); } // Remove keys REMOVE_KEY_VALUE(szBuffer, "minplayers"); REMOVE_KEY_VALUE(szBuffer, "maxplayers"); Q_strcpy(item->rulebuffer, szBuffer); } item->next = cycle->items; cycle->items = item; } else ALERT(at_console, "Skipping %s from mapcycle, not a valid map\n", szMap); } FREE_FILE(aFileList); } // Fixup circular list pointer item = cycle->items; // Reverse it to get original order while (item) { next = item->next; item->next = newlist; newlist = item; item = next; } cycle->items = newlist; item = cycle->items; // Didn't parse anything if (!item) { return 0; } while (item->next != NULL) { item = item->next; } item->next = cycle->items; cycle->next_item = item->next; return 1; } // Determine the current # of active players on the server for map cycling logic /* <115f76> ../cstrike/dlls/multiplay_gamerules.cpp:4510 */ int CountPlayers(void) { int num = 0; for (int i = 1; i <= gpGlobals->maxClients; i++) { CBaseEntity *pEnt = UTIL_PlayerByIndex(i); if (pEnt != NULL) { num = num + 1; } } return num; } // Parse commands/key value pairs to issue right after map xxx command is issued on server level transition /* <116002> ../cstrike/dlls/multiplay_gamerules.cpp:4535 */ void ExtractCommandString(char *s, char *szCommand) { // Now make rules happen char pkey[512]; char value[512]; // use two buffers so compares // work without stomping on each other char *o; if (*s == '\\') s++; while (true) { o = pkey; while (*s != '\\') { if (!*s) { return; } *o++ = *s++; } *o = '\0'; s++; o = value; while (*s != '\\' && *s) { if (!*s) { return; } *o++ = *s++; } *o = '\0'; Q_strcat(szCommand, pkey); if (Q_strlen(value) > 0) { Q_strcat(szCommand, " "); Q_strcat(szCommand, value); } Q_strcat(szCommand, "\n"); if (!*s) { return; } s++; } } /* <116b52> ../cstrike/dlls/multiplay_gamerules.cpp:4582 */ void CHalfLifeMultiplay::ResetAllMapVotes(void) { CBaseEntity *pTempEntity = NULL; while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) { if (FNullEnt(pTempEntity->edict())) break; CBasePlayer *pTempPlayer = GetClassPtr((CBasePlayer *)pTempEntity->pev); if (pTempPlayer->m_iTeam != UNASSIGNED) { pTempPlayer->m_iMapVote = 0; } } for (int j = 0; j < MAX_VOTE_MAPS; j++) m_iMapVotes[j] = 0; } /* <11624e> ../cstrike/dlls/multiplay_gamerules.cpp:4608 */ int GetMapCount(void) { static mapcycle_t mapcycle2; char *mapcfile = (char *)CVAR_GET_STRING("mapcyclefile"); DestroyMapCycle(&mapcycle2); ReloadMapCycleFile(mapcfile, &mapcycle2); int iCount = 0, iDone = 0; for (mapcycle_item_s *item = mapcycle2.next_item; item != NULL && iDone != 1; item = item->next) { if (item == mapcycle2.next_item) iDone = 1; ++iCount; } return iCount; } /* <1187d2> ../cstrike/dlls/multiplay_gamerules.cpp:4629 */ void CHalfLifeMultiplay::DisplayMaps(CBasePlayer *player, int iVote) { static mapcycle_t mapcycle2; char *mapcfile = (char *)CVAR_GET_STRING("mapcyclefile"); char *pszNewMap = NULL; int iCount = 0, done = 0; DestroyMapCycle(&mapcycle2); ReloadMapCycleFile(mapcfile, &mapcycle2); mapcycle_item_s *item = mapcycle2.next_item; while (!done && item != NULL) { if (item->next == mapcycle2.next_item) done = 1; ++iCount; if (player != NULL) { if (m_iMapVotes[iCount] == 1) { ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Vote", UTIL_dtos1(iCount), item->mapname, UTIL_dtos2(1)); } else ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Votes", UTIL_dtos1(iCount), item->mapname, UTIL_dtos2(m_iMapVotes[iCount])); } if (iCount == iVote) { pszNewMap = item->mapname; } item = item->next; } if (!pszNewMap || !iVote) { return; } if (Q_strcmp(pszNewMap, STRING(gpGlobals->mapname))) { CHANGE_LEVEL(pszNewMap, NULL); return; } if (timelimit.value) { timelimit.value += 30; UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Map_Vote_Extend"); } ResetAllMapVotes(); } /* <11895b> ../cstrike/dlls/multiplay_gamerules.cpp:4702 */ void CHalfLifeMultiplay::ProcessMapVote(CBasePlayer *player, int iVote) { CBaseEntity *pTempEntity = NULL; int iValidVotes = 0, iNumPlayers = 0; while ((pTempEntity = UTIL_FindEntityByClassname(pTempEntity, "player")) != NULL) { if (FNullEnt(pTempEntity->edict())) break; CBasePlayer *pTempPlayer = GetClassPtr((CBasePlayer *)pTempEntity->pev); if (pTempPlayer->m_iTeam != UNASSIGNED) { iNumPlayers++; if (pTempPlayer->m_iMapVote = iVote) iValidVotes++; } } m_iMapVotes[iVote] = iValidVotes; float ratio = mapvoteratio.value; if (mapvoteratio.value > 1) { ratio = 1; CVAR_SET_STRING("mp_mapvoteratio", "1.0"); } else if (mapvoteratio.value < 0.35) { ratio = 0.35; CVAR_SET_STRING("mp_mapvoteratio", "0.35"); } int iRequiredVotes = 2; if (iNumPlayers > 2) { iRequiredVotes = (int)(iNumPlayers * ratio + 0.5); } if (iValidVotes < iRequiredVotes) { DisplayMaps(player, 0); ClientPrint(player->pev, HUD_PRINTCONSOLE, "#Game_required_votes", UTIL_dtos1(iRequiredVotes)); } else DisplayMaps(NULL, iVote); } // Server is changing to a new level, check mapcycle.txt for map name and setup info /* <116089> ../cstrike/dlls/multiplay_gamerules.cpp:4773 */ void CHalfLifeMultiplay::__MAKE_VHOOK(ChangeLevel)(void) { static char szPreviousMapCycleFile[256]; static mapcycle_t mapcycle; char szNextMap[32]; char szFirstMapInList[32]; char szCommands[1500]; char szRules[1500]; int minplayers = 0, maxplayers = 0; // the absolute default level is hldm1 Q_strcpy(szFirstMapInList, "hldm1"); int curplayers; BOOL do_cycle = TRUE; // find the map to change to char *mapcfile = (char *)CVAR_GET_STRING("mapcyclefile"); assert(mapcfile != NULL); szCommands[0] = '\0'; szRules[0] = '\0'; curplayers = CountPlayers(); // Has the map cycle filename changed? if (Q_stricmp(mapcfile, szPreviousMapCycleFile)) { Q_strcpy(szPreviousMapCycleFile, mapcfile); DestroyMapCycle(&mapcycle); if (!ReloadMapCycleFile(mapcfile, &mapcycle) || !mapcycle.items) { ALERT(at_console, "Unable to load map cycle file %s\n", mapcfile); do_cycle = FALSE; } } if (do_cycle && mapcycle.items) { BOOL keeplooking = FALSE; BOOL found = FALSE; 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) { keeplooking = FALSE; assert(item != NULL); if (item->minplayers != 0) { if (curplayers >= item->minplayers) { found = TRUE; minplayers = item->minplayers; } else { keeplooking = TRUE; } } if (item->maxplayers != 0) { if (curplayers <= item->maxplayers) { found = TRUE; maxplayers = item->maxplayers; } else { keeplooking = TRUE; } } if (keeplooking) { continue; } found = TRUE; break; } if (!found) { item = mapcycle.next_item; } // Increment next item pointer mapcycle.next_item = item->next; // Perform logic on current item Q_strcpy(szNextMap, item->mapname); ExtractCommandString(item->rulebuffer, szCommands); Q_strcpy(szRules, item->rulebuffer); } if (!IS_MAP_VALID(szNextMap)) { Q_strcpy(szNextMap, szFirstMapInList); } g_fGameOver = TRUE; ALERT(at_console, "CHANGE LEVEL: %s\n", szNextMap); if (minplayers || maxplayers) { ALERT(at_console, "PLAYER COUNT: min %i max %i current %i\n", minplayers, maxplayers, curplayers); } if (Q_strlen(szRules) > 0) { ALERT(at_console, "RULES: %s\n", szRules); } CHANGE_LEVEL(szNextMap, NULL); if (Q_strlen(szCommands) > 0) { SERVER_COMMAND(szCommands); } } /* <116317> ../cstrike/dlls/multiplay_gamerules.cpp:4903 */ void CHalfLifeMultiplay::SendMOTDToClient(edict_t *client) { // read from the MOTD.txt file int length, char_count = 0; char *pFileList; char *aFileList = pFileList = (char *)LOAD_FILE_FOR_ME((char *)CVAR_GET_STRING("motdfile"), &length); // send the server name MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client); WRITE_STRING(CVAR_GET_STRING("hostname")); MESSAGE_END(); // Send the message of the day // read it chunk-by-chunk, and send it in parts while (pFileList && *pFileList && char_count < MAX_MOTD_LENGTH) { char chunk[MAX_MOTD_CHUNK + 1]; if (Q_strlen(pFileList) < sizeof(chunk)) { Q_strcpy(chunk, pFileList); } else { Q_strncpy(chunk, pFileList, sizeof(chunk) - 1); // Q_strncpy doesn't always append the null terminator chunk[sizeof(chunk) - 1] = '\0'; } char_count += Q_strlen(chunk); if (char_count < MAX_MOTD_LENGTH) pFileList = aFileList + char_count; else *pFileList = '\0'; MESSAGE_BEGIN(MSG_ONE, gmsgMOTD, NULL, client); WRITE_BYTE((*pFileList != '\0') ? FALSE : TRUE); // FALSE means there is still more message to come WRITE_STRING(chunk); MESSAGE_END(); } FREE_FILE(aFileList); } /* <1181ac> ../cstrike/dlls/multiplay_gamerules.cpp:4961 */ void CHalfLifeMultiplay::__MAKE_VHOOK(ClientUserInfoChanged)(CBasePlayer *pPlayer, char *infobuffer) { pPlayer->SetPlayerModel(pPlayer->m_bHasC4); pPlayer->SetPrefsFromUserinfo(infobuffer); } #ifdef HOOK_GAMEDLL void CMapInfo::Spawn(void) { Spawn_(); } void CMapInfo::KeyValue(KeyValueData *pkvd) { KeyValue_(pkvd); } bool CCStrikeGameMgrHelper::CanPlayerHearPlayer(CBasePlayer *pListener, CBasePlayer *pSender) { return CanPlayerHearPlayer_(pListener, pSender); } void CHalfLifeMultiplay::RefreshSkillData(void) { RefreshSkillData_(); } void CHalfLifeMultiplay::Think(void) { Think_(); } BOOL CHalfLifeMultiplay::IsAllowedToSpawn(CBaseEntity *pEntity) { return IsAllowedToSpawn_(pEntity); } BOOL CHalfLifeMultiplay::FAllowFlashlight(void) { return FAllowFlashlight_(); } BOOL CHalfLifeMultiplay::FShouldSwitchWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon) { return FShouldSwitchWeapon_(pPlayer, pWeapon); } BOOL CHalfLifeMultiplay::GetNextBestWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon) { return GetNextBestWeapon_(pPlayer, pCurrentWeapon); } BOOL CHalfLifeMultiplay::IsMultiplayer(void) { return IsMultiplayer_(); } BOOL CHalfLifeMultiplay::IsDeathmatch(void) { return IsDeathmatch_(); } BOOL CHalfLifeMultiplay::IsCoOp(void) { return IsCoOp_(); } BOOL CHalfLifeMultiplay::ClientConnected(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]) { return ClientConnected_(pEntity, pszName, pszAddress, szRejectReason); } void CHalfLifeMultiplay::InitHUD(CBasePlayer *pl) { InitHUD_(pl); } void CHalfLifeMultiplay::ClientDisconnected(edict_t *pClient) { ClientDisconnected_(pClient); } void CHalfLifeMultiplay::UpdateGameMode(CBasePlayer *pPlayer) { UpdateGameMode_(pPlayer); } float CHalfLifeMultiplay::FlPlayerFallDamage(CBasePlayer *pPlayer) { return FlPlayerFallDamage_(pPlayer); } BOOL CHalfLifeMultiplay::FPlayerCanTakeDamage(CBasePlayer *pPlayer, CBaseEntity *pAttacker) { return FPlayerCanTakeDamage_(pPlayer, pAttacker); } void CHalfLifeMultiplay::PlayerSpawn(CBasePlayer *pPlayer) { PlayerSpawn_(pPlayer); } void CHalfLifeMultiplay::PlayerThink(CBasePlayer *pPlayer) { PlayerThink_(pPlayer); } BOOL CHalfLifeMultiplay::FPlayerCanRespawn(CBasePlayer *pPlayer) { return FPlayerCanRespawn_(pPlayer); } float CHalfLifeMultiplay::FlPlayerSpawnTime(CBasePlayer *pPlayer) { return FlPlayerSpawnTime_(pPlayer); } edict_t *CHalfLifeMultiplay::GetPlayerSpawnSpot(CBasePlayer *pPlayer) { return GetPlayerSpawnSpot_(pPlayer); } BOOL CHalfLifeMultiplay::AllowAutoTargetCrosshair(void) { return AllowAutoTargetCrosshair_(); } BOOL CHalfLifeMultiplay::ClientCommand_DeadOrAlive(CBasePlayer *pPlayer, const char *pcmd) { return ClientCommand_DeadOrAlive_(pPlayer, pcmd); } BOOL CHalfLifeMultiplay::ClientCommand(CBasePlayer *pPlayer, const char *pcmd) { return ClientCommand_(pPlayer, pcmd); } void CHalfLifeMultiplay::ClientUserInfoChanged(CBasePlayer *pPlayer, char *infobuffer) { ClientUserInfoChanged_(pPlayer, infobuffer); } int CHalfLifeMultiplay::IPointsForKill(CBasePlayer *pAttacker, CBasePlayer *pKilled) { return IPointsForKill_(pAttacker, pKilled); } void CHalfLifeMultiplay::PlayerKilled(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor) { PlayerKilled_(pVictim, pKiller, pInflictor); } void CHalfLifeMultiplay::DeathNotice(CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor) { DeathNotice_(pVictim, pKiller, pInflictor); } BOOL CHalfLifeMultiplay::CanHavePlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon) { return CanHavePlayerItem_(pPlayer, pWeapon); } void CHalfLifeMultiplay::PlayerGotWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon) { PlayerGotWeapon_(pPlayer, pWeapon); } int CHalfLifeMultiplay::WeaponShouldRespawn(CBasePlayerItem *pWeapon) { return WeaponShouldRespawn_(pWeapon); } float CHalfLifeMultiplay::FlWeaponRespawnTime(CBasePlayerItem *pWeapon) { return FlWeaponRespawnTime_(pWeapon); } float CHalfLifeMultiplay::FlWeaponTryRespawn(CBasePlayerItem *pWeapon) { return FlWeaponTryRespawn_(pWeapon); } Vector CHalfLifeMultiplay::VecWeaponRespawnSpot(CBasePlayerItem *pWeapon) { return VecWeaponRespawnSpot_(pWeapon); } BOOL CHalfLifeMultiplay::CanHaveItem(CBasePlayer *pPlayer, CItem *pItem) { return CanHaveItem_(pPlayer, pItem); } void CHalfLifeMultiplay::PlayerGotItem(CBasePlayer *pPlayer, CItem *pItem) { PlayerGotItem_(pPlayer, pItem); } int CHalfLifeMultiplay::ItemShouldRespawn(CItem *pItem) { return ItemShouldRespawn_(pItem); } float CHalfLifeMultiplay::FlItemRespawnTime(CItem *pItem) { return FlItemRespawnTime_(pItem); } Vector CHalfLifeMultiplay::VecItemRespawnSpot(CItem *pItem) { return VecItemRespawnSpot_(pItem); } void CHalfLifeMultiplay::PlayerGotAmmo(CBasePlayer *pPlayer, char *szName, int iCount) { PlayerGotAmmo_(pPlayer, szName, iCount); } int CHalfLifeMultiplay::AmmoShouldRespawn(CBasePlayerAmmo *pAmmo) { return AmmoShouldRespawn_(pAmmo); } float CHalfLifeMultiplay::FlAmmoRespawnTime(CBasePlayerAmmo *pAmmo) { return FlAmmoRespawnTime_(pAmmo); } Vector CHalfLifeMultiplay::VecAmmoRespawnSpot(CBasePlayerAmmo *pAmmo) { return VecAmmoRespawnSpot_(pAmmo); } float CHalfLifeMultiplay::FlHealthChargerRechargeTime(void) { return FlHealthChargerRechargeTime_(); } float CHalfLifeMultiplay::FlHEVChargerRechargeTime(void) { return FlHEVChargerRechargeTime_(); } int CHalfLifeMultiplay::DeadPlayerWeapons(CBasePlayer *pPlayer) { return DeadPlayerWeapons_(pPlayer); } int CHalfLifeMultiplay::DeadPlayerAmmo(CBasePlayer *pPlayer) { return DeadPlayerAmmo_(pPlayer); } int CHalfLifeMultiplay::PlayerRelationship(CBasePlayer *pPlayer, CBaseEntity *pTarget) { return PlayerRelationship_(pPlayer, pTarget); } BOOL CHalfLifeMultiplay::FAllowMonsters(void) { return FAllowMonsters_(); } void CHalfLifeMultiplay::ServerDeactivate(void) { ServerDeactivate_(); } void CHalfLifeMultiplay::CheckMapConditions(void) { CheckMapConditions_(); } void CHalfLifeMultiplay::CleanUpMap(void) { CleanUpMap_(); } void CHalfLifeMultiplay::RestartRound(void) { RestartRound_(); } void CHalfLifeMultiplay::CheckWinConditions(void) { CheckWinConditions_(); } void CHalfLifeMultiplay::RemoveGuns(void) { RemoveGuns_(); } void CHalfLifeMultiplay::GiveC4(void) { GiveC4_(); } void CHalfLifeMultiplay::ChangeLevel(void) { ChangeLevel_(); } void CHalfLifeMultiplay::GoToIntermission(void) { GoToIntermission_(); } #endif // HOOK_GAMEDLL