Last active
March 30, 2024 04:29
-
-
Save sigsegv-mvm/a032eaf0f95281ea847b6515388d72a2 to your computer and use it in GitHub Desktop.
TF2 game mode determination logic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on TF2 server_srv.so version 20161111a | |
// Reverse engineering by sigsegv | |
void CTFGameRules::Activate() | |
{ | |
m_nGameType = TF_GAMETYPE_UNDEFINED; | |
tf_gamemode_arena .SetValue(0); | |
tf_gamemode_cp .SetValue(0); | |
tf_gamemode_ctf .SetValue(0); | |
tf_gamemode_sd .SetValue(0); | |
tf_gamemode_payload .SetValue(0); | |
tf_gamemode_mvm .SetValue(0); | |
tf_gamemode_rd .SetValue(0); | |
tf_gamemode_pd .SetValue(0); | |
tf_gamemode_tc .SetValue(0); | |
tf_beta_content .SetValue(0); | |
tf_gamemode_passtime.SetValue(0); | |
tf_gamemode_misc .SetValue(0); | |
tf_bot_count .SetValue(0); | |
m_bPlayingMannVsMachine = false; | |
m_bBountyModeEnabled = false; | |
m_bMannVsMachineAlarmStatus = false; | |
m_bPlayingKoth = false; | |
m_bPlayingMedieval = false; | |
m_bPlayingHybrid_CTF_CP = false; | |
m_bPlayingSpecialDeliveryMode = false; | |
m_bPlayingRobotDestructionMode = false; | |
m_bPowerupMode = false; | |
// dword @ +0x6F8 = 0 | |
// dword @ +0x6FC = 0 | |
// CHandle @ +0xC70 = nullptr | |
// CHandle @ +0xC74 = nullptr | |
// CHandle @ +0xC78 = nullptr | |
// CHandle @ +0xC7C = nullptr | |
// float @ +0xCBC = -1.0f | |
// dword @ +0xCC0 = 0 | |
// dword @ +0x6E8 = 0 | |
m_nMapHolidayType = 0; | |
auto logic_arena = dynamic_cast<CArenaLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_arena")); | |
if (logic_arena != nullptr) { | |
// handle @ +0xC7C = logic_arena | |
m_nGameType = TF_GAMETYPE_ARENA; | |
tf_gamemode_arena.SetValue(1); | |
Msg("Executing server arena config file\n"); | |
engine->ServerCommand("exec config_arena.cfg\n"); | |
} | |
// SKIPPED: item schema stuff related to setting tf_beta_content | |
if (V_strncmp(STRING(gpGlobals->mapname), "tc_", 3) == 0) { | |
tf_gamemode_tc.SetValue(1); | |
} | |
// This checks for the existence of a tf_logic_robot_destruction entity | |
if (CTFRobotDestructionLogic::GetRobotDestructionLogic() != nullptr) { | |
m_bPlayingRobotDestructionMode = true; | |
if (CTFRobotDestructionLogic::GetRobotDestructionLogic()->GetType() != 0) { | |
tf_gamemode_pd.SetValue(1); | |
m_nGameType = TF_GAMETYPE_PD; | |
} else { | |
tf_gamemode_rd.SetValue(1); | |
m_nGameType = TF_GAMETYPE_RD; | |
tf_beta_content.SetValue(1); | |
} | |
} else if (dynamic_cast<CMannVsMachineLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_mann_vs_machine")) != nullptr) { | |
m_bPlayingMannVsMachine = true; | |
tf_gamemode_mvm.SetValue(1); | |
m_nGameType = TF_GAMETYPE_MVM; | |
} else if (StringAfterPrefix(STRING(gpGlobals->mapname), "sd_")) { | |
m_bPlayingSpecialDeliveryMode = true; | |
tf_gamemode_sd.SetValue(1); | |
} else if (ICaptureFlagAutoList::AutoList().Count() > 0) { | |
m_nGameType = TF_GAMETYPE_CTF; | |
tf_gamemode_ctf.SetValue(1); | |
} else if (dynamic_cast<CTeamTrainWatcher *>(gEntList.FindEntityByClassname(nullptr, "team_train_watcher")) != nullptr) { | |
m_nGameType = TF_GAMETYPE_ESCORT; | |
tf_gamemode_payload.SetValue(1); | |
if (dynamic_cast<CMultipleEscort *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_multiple_escort")) != nullptr) { | |
m_bMultipleTrains = true; | |
} else { | |
m_bMultipleTrains = false; | |
} | |
} else if (g_hControlPointMasters.Count() != 0 && m_nGameType != TF_GAMETYPE_ARENA) { | |
m_nGameType = TF_GAMETYPE_CP; | |
tf_gamemode_cp.SetValue(1); | |
} | |
if (dynamic_cast<CTFPasstimeLogic *>(gEntList.FindEntityByClassname(nullptr, "passtime_logic")) != nullptr) { | |
m_nGameType = TF_GAMETYPE_PASSTIME; | |
tf_gamemode_passtime.SetValue(1); | |
} | |
auto logic_training = dynamic_cast<CTrainingModeLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_training_mode")); | |
if (logic_training != nullptr) { | |
m_bIsInTraining = true; | |
m_bAllowTrainingAchievements = false; | |
mp_humans_must_join_team.SetValue("blue"); | |
m_bIsTrainingHUDVisible = true; | |
tf_training_client_message.SetValue(0); | |
} | |
// handle @ +0x6A4 = logic_training | |
m_bIsInItemTestingMode = false; | |
if (dynamic_cast<CKothLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_koth")) != nullptr) { | |
m_bPlayingKoth = true; | |
} | |
if (dynamic_cast<CMedievalLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_medieval")) != nullptr) { | |
m_bPlayingMedieval = true; | |
} | |
auto logic_competitive = dynamic_cast<CCompetitiveLogic *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_competitive")); | |
if (logic_competitive != nullptr) { | |
// handle @ +0x6A0 = logic_competitive | |
} | |
if (dynamic_cast<CHybridMap_CTF_CP *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_hybrid_ctf_cp")) != nullptr) { | |
m_bPlayingHybrid_CTF_CP = true; | |
} | |
auto logic_holiday = dynamic_cast<CTFHolidayEntity *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_holiday")); | |
if (logic_holiday != nullptr) { | |
m_nMapHolidayType = logic_holiday->m_nHolidayType; | |
} | |
// SKIPPED: bot_roster stuff | |
// SKIPPED: tf_logic_cp_timer stuff | |
if (IsInTraining() || TheTFBots().IsInOfflinePractice() || IsInItemTestingMode()) { | |
hide_server.SetValue(1); | |
} | |
// byte @ +0x6D4 = 0 | |
// byte @ +0x6D5 = 0 | |
// dword @ +0x6D8 = 0 | |
if (tf_powerup_mode.GetBool() && !m_bPowerupMode) { | |
SetPowerupMode(true); | |
} | |
if (IsInTournamentMode() && m_nGameType != TF_GAMETYPE_MVM && /* last gametype was TF_GAMETYPE_MVM */) { | |
mp_tournament.SetValue(0); | |
} | |
if (m_bPlayingMannVsMachine && g_pPopulationManager == nullptr) { | |
CreateEntityByName("info_populator"); | |
} | |
if (tf_gamemode_tc.GetBool() || tf_gamemode_sd.GetBool() || tf_gamemode_pd.GetBool() || m_bPlayingMedieval) { | |
tf_gamemode_misc.SetValue(1); | |
} | |
if (gEntList.FindEntityByName(nullptr, "competitive_stage_logic_case") != nullptr) { | |
m_bPlayersAreOnMatchSummaryStage = true; | |
} | |
m_bCompetitiveMode = false; | |
auto match_group_desc = GetMatchGroupDescription(GetCurrentMatchGroup()); | |
if (match_group_desc != nullptr) { | |
match_group_desc->InitGameRulesSettings(); | |
} | |
if (dynamic_cast<CLogicMannPower *>(gEntList.FindEntityByClassname(nullptr, "tf_logic_mannpower")) != nullptr) { | |
tf_powerup_mode.SetValue(1); | |
} else { | |
tf_powerup_mode.SetValue(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment