diff --git a/dist/game.cfg b/dist/game.cfg index 70b5ec5f..c394139d 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -15,8 +15,18 @@ mp_friendlyfire 0 mp_maxmoney 16000 // Disable round end by game scenario -// 0 - disabled -// 1 - enabled +// 0 - disabled (default behaviour) +// 1 - enabled (never end round) // +// Flags for fine grained control (choose as many as needed) +// a - block round time round end check +// b - block needed players round end check +// c - block VIP assassination/success round end check +// d - block prison escape round end check +// e - block bomb round end check +// f - block team extermination round end check +// g - block hostage rescue round end check +// +// Example setting: "ae" - blocks round time and bomb round end checks // Default value: "0" mp_round_infinite 0 diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index e8fd9c3f..d29fe2f9 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -162,6 +162,18 @@ enum GR_PLR_DROP_AMMO_NO, }; +// custom enum +enum +{ + SCENARIO_BLOCK_TIME_EXPRIRED = (1 << 0), + SCENARIO_BLOCK_NEED_PLAYERS = (1 << 1), + SCENARIO_BLOCK_VIP_ESCAPRE = (1 << 2), + SCENARIO_BLOCK_PRISON_ESCAPRE = (1 << 3), + SCENARIO_BLOCK_BOMB = (1 << 4), + SCENARIO_BLOCK_TEAM_EXTERMINATION = (1 << 5), + SCENARIO_BLOCK_HOSTAGE_RESCUE = (1 << 6), +}; + enum { GR_NOTTEAMMATE = 0, diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index d8e82341..c1cb9e7a 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -996,6 +996,8 @@ void CHalfLifeMultiplay::QueueCareerRoundEndMenu(float tmDelay, int iWinStatus) } } +// Check if the scenario has been won/lost. + /* <117750> ../cstrike/dlls/multiplay_gamerules.cpp:1084 */ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void) { @@ -1010,35 +1012,44 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void) return; } +#ifdef REGAMEDLL_ADD + int scenarioFlags = UTIL_ReadFlags(round_infinite.string); +#else + // the icc compiler will cut out all of the code which refers to it + int scenarioFlags = 0; +#endif // REGAMEDLL_ADD + // Initialize the player counts.. int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT; InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT); // other player's check bool bNeededPlayers = false; - if (NeededPlayersCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_NEED_PLAYERS) && NeededPlayersCheck(bNeededPlayers)) return; // Assasination/VIP scenarion check - if (VIPRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPRE) && VIPRoundEndCheck(bNeededPlayers)) return; // Prison escape check - if (PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPRE) && PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) return; // Bomb check - if (BombRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_BOMB) && BombRoundEndCheck(bNeededPlayers)) return; // Team Extermination check // CounterTerrorists won by virture of elimination - if (TeamExterminationCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_TEAM_EXTERMINATION) && TeamExterminationCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) return; // Hostage rescue check - if (HostageRescueRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_HOSTAGE_RESCUE) && HostageRescueRoundEndCheck(bNeededPlayers)) return; + + // scenario not won - still in progress } void CHalfLifeMultiplay::InitializePlayerCounts(int &NumAliveTerrorist, int &NumAliveCT, int &NumDeadTerrorist, int &NumDeadCT) @@ -1048,6 +1059,8 @@ void CHalfLifeMultiplay::InitializePlayerCounts(int &NumAliveTerrorist, int &Num m_iHaveEscaped = 0; // initialize count dead/alive players + + // Count how many dead players there are on each team. CBaseEntity *pPlayer = NULL; while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { @@ -1191,6 +1204,8 @@ bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers) MESSAGE_END(); EndRoundMessage("#VIP_Escaped", ROUND_VIP_ESCAPED); + + // tell the bots the VIP got out if (TheBots != NULL) { TheBots->OnEvent(EVENT_VIP_ESCAPED); @@ -1218,6 +1233,8 @@ bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers) } EndRoundMessage("#VIP_Assassinated", ROUND_VIP_ASSASSINATED); + + // tell the bots the VIP was killed if (TheBots != NULL) { TheBots->OnEvent(EVENT_VIP_ASSASSINATED); @@ -1489,6 +1506,8 @@ bool CHalfLifeMultiplay::HostageRescueRoundEndCheck(bool bNeededPlayers) } EndRoundMessage("#All_Hostages_Rescued", ROUND_ALL_HOSTAGES_RESCUED); + + // tell the bots all the hostages have been rescued if (TheBots != NULL) { TheBots->OnEvent(EVENT_ALL_HOSTAGES_RESCUED); @@ -1637,6 +1656,7 @@ void CHalfLifeMultiplay::BalanceTeams(void) /* <113158> ../cstrike/dlls/multiplay_gamerules.cpp:1608 */ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckMapConditions)(void) { + // Check to see if this map has a bomb target in it if (UTIL_FindEntityByClassname(NULL, "func_bomb_target")) { m_bMapHasBombTarget = true; @@ -2618,7 +2638,7 @@ bool CHalfLifeMultiplay::CheckGameOver(void) // 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 + if (!UTIL_HumansInGame() // 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)) { @@ -2762,12 +2782,12 @@ void CHalfLifeMultiplay::CheckFreezePeriodExpired(void) { if (plr->m_iTeam == CT && !bCTPlayed) { - plr->Radio(CT_sentence, NULL); + plr->Radio(CT_sentence); bCTPlayed = true; } else if (plr->m_iTeam == TERRORIST && !bTPlayed) { - plr->Radio(T_sentence, NULL); + plr->Radio(T_sentence); bTPlayed = true; } @@ -2795,7 +2815,7 @@ void CHalfLifeMultiplay::CheckFreezePeriodExpired(void) void CHalfLifeMultiplay::CheckRoundTimeExpired(void) { #ifdef REGAMEDLL_ADD - if (round_infinite.string[0] == '1') + if (round_infinite.string[0] == '1' || (UTIL_ReadFlags(round_infinite.string) & SCENARIO_BLOCK_TIME_EXPRIRED)) return; #endif // REGAMEDLL_ADD @@ -2954,9 +2974,11 @@ bool CHalfLifeMultiplay::HasRoundTimeExpired(void) return false; } + // If the bomb is planted, don't let the round timer end the round. + // keep going until the bomb explodes or is defused if (!IsBombPlanted()) { - if (cv_bot_nav_edit.value == 0.0f || IS_DEDICATED_SERVER() || UTIL_HumansInGame(false) != 1) + if (cv_bot_nav_edit.value == 0.0f || IS_DEDICATED_SERVER() || UTIL_HumansInGame() != 1) { return true; } @@ -2984,6 +3006,9 @@ bool CHalfLifeMultiplay::IsBombPlanted(void) return false; } +// living players on the given team need to be marked as not receiving any money +// next round. + /* <115229> ../cstrike/dlls/multiplay_gamerules.cpp:2971 */ void CHalfLifeMultiplay::MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int iTeam) { @@ -3761,7 +3786,7 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(DeathNotice)(CBasePlayer *pVictim, entvars // If the inflictor is the killer, then it must be their current weapon doing the damage CBasePlayer *pPlayer = static_cast(CBaseEntity::Instance(pKiller)); - if (pPlayer && pPlayer->m_pActiveItem) + if (pPlayer && pPlayer->m_pActiveItem != NULL) { killer_weapon_name = pPlayer->m_pActiveItem->pszName(); } @@ -4011,6 +4036,7 @@ int CHalfLifeMultiplay::__MAKE_VHOOK(DeadPlayerAmmo)(CBasePlayer *pPlayer) /* <1131d6> ../cstrike/dlls/multiplay_gamerules.cpp:4096 */ edict_t *CHalfLifeMultiplay::__MAKE_VHOOK(GetPlayerSpawnSpot)(CBasePlayer *pPlayer) { + // gat valid spawn point edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot(pPlayer); if (IsMultiplayer()) diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp index 33022cbb..f3d64b6c 100644 --- a/regamedll/dlls/util.cpp +++ b/regamedll/dlls/util.cpp @@ -2463,3 +2463,12 @@ float_precision UTIL_GetPlayerGaitYaw(int playerIndex) return 0; } + +int UTIL_ReadFlags(const char *c) +{ + int flags = 0; + while (*c) + flags |= (1 << (*c++ - 'a')); + + return flags; +} diff --git a/regamedll/dlls/util.h b/regamedll/dlls/util.h index e9d3f52c..0a60f1ad 100644 --- a/regamedll/dlls/util.h +++ b/regamedll/dlls/util.h @@ -490,6 +490,7 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd); NOXREF int GetPlayerTeam(int index); bool UTIL_IsGame(const char *gameName); float_precision UTIL_GetPlayerGaitYaw(int playerIndex); +int UTIL_ReadFlags(const char *c); /* * Declared for function overload diff --git a/regamedll/msvc/ReGameDLL.vcxproj b/regamedll/msvc/ReGameDLL.vcxproj index 97bd02a7..c4677948 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj +++ b/regamedll/msvc/ReGameDLL.vcxproj @@ -1322,7 +1322,7 @@ Level3 MaxSpeed true - REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions) + REGAMEDLL_ADD;REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreaded