Added #13 by user request IgnacioFDM

This commit is contained in:
s1lentq 2016-01-28 08:51:34 +06:00
parent c0df05d418
commit 9f9fdb721a
6 changed files with 73 additions and 15 deletions

14
dist/game.cfg vendored
View File

@ -15,8 +15,18 @@ mp_friendlyfire 0
mp_maxmoney 16000 mp_maxmoney 16000
// Disable round end by game scenario // Disable round end by game scenario
// 0 - disabled // 0 - disabled (default behaviour)
// 1 - enabled // 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" // Default value: "0"
mp_round_infinite 0 mp_round_infinite 0

View File

@ -162,6 +162,18 @@ enum
GR_PLR_DROP_AMMO_NO, 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 enum
{ {
GR_NOTTEAMMATE = 0, GR_NOTTEAMMATE = 0,

View File

@ -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 */ /* <117750> ../cstrike/dlls/multiplay_gamerules.cpp:1084 */
void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void) void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void)
{ {
@ -1010,35 +1012,44 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void)
return; 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.. // Initialize the player counts..
int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT; int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT;
InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT); InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT);
// other player's check // other player's check
bool bNeededPlayers = false; bool bNeededPlayers = false;
if (NeededPlayersCheck(bNeededPlayers)) if (!(scenarioFlags & SCENARIO_BLOCK_NEED_PLAYERS) && NeededPlayersCheck(bNeededPlayers))
return; return;
// Assasination/VIP scenarion check // Assasination/VIP scenarion check
if (VIPRoundEndCheck(bNeededPlayers)) if (!(scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPRE) && VIPRoundEndCheck(bNeededPlayers))
return; return;
// Prison escape check // Prison escape check
if (PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) if (!(scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPRE) && PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers))
return; return;
// Bomb check // Bomb check
if (BombRoundEndCheck(bNeededPlayers)) if (!(scenarioFlags & SCENARIO_BLOCK_BOMB) && BombRoundEndCheck(bNeededPlayers))
return; return;
// Team Extermination check // Team Extermination check
// CounterTerrorists won by virture of elimination // 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; return;
// Hostage rescue check // Hostage rescue check
if (HostageRescueRoundEndCheck(bNeededPlayers)) if (!(scenarioFlags & SCENARIO_BLOCK_HOSTAGE_RESCUE) && HostageRescueRoundEndCheck(bNeededPlayers))
return; return;
// scenario not won - still in progress
} }
void CHalfLifeMultiplay::InitializePlayerCounts(int &NumAliveTerrorist, int &NumAliveCT, int &NumDeadTerrorist, int &NumDeadCT) 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; m_iHaveEscaped = 0;
// initialize count dead/alive players // initialize count dead/alive players
// Count how many dead players there are on each team.
CBaseEntity *pPlayer = NULL; CBaseEntity *pPlayer = NULL;
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")) != NULL)
{ {
@ -1191,6 +1204,8 @@ bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers)
MESSAGE_END(); MESSAGE_END();
EndRoundMessage("#VIP_Escaped", ROUND_VIP_ESCAPED); EndRoundMessage("#VIP_Escaped", ROUND_VIP_ESCAPED);
// tell the bots the VIP got out
if (TheBots != NULL) if (TheBots != NULL)
{ {
TheBots->OnEvent(EVENT_VIP_ESCAPED); TheBots->OnEvent(EVENT_VIP_ESCAPED);
@ -1218,6 +1233,8 @@ bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers)
} }
EndRoundMessage("#VIP_Assassinated", ROUND_VIP_ASSASSINATED); EndRoundMessage("#VIP_Assassinated", ROUND_VIP_ASSASSINATED);
// tell the bots the VIP was killed
if (TheBots != NULL) if (TheBots != NULL)
{ {
TheBots->OnEvent(EVENT_VIP_ASSASSINATED); TheBots->OnEvent(EVENT_VIP_ASSASSINATED);
@ -1489,6 +1506,8 @@ bool CHalfLifeMultiplay::HostageRescueRoundEndCheck(bool bNeededPlayers)
} }
EndRoundMessage("#All_Hostages_Rescued", ROUND_ALL_HOSTAGES_RESCUED); EndRoundMessage("#All_Hostages_Rescued", ROUND_ALL_HOSTAGES_RESCUED);
// tell the bots all the hostages have been rescued
if (TheBots != NULL) if (TheBots != NULL)
{ {
TheBots->OnEvent(EVENT_ALL_HOSTAGES_RESCUED); TheBots->OnEvent(EVENT_ALL_HOSTAGES_RESCUED);
@ -1637,6 +1656,7 @@ void CHalfLifeMultiplay::BalanceTeams(void)
/* <113158> ../cstrike/dlls/multiplay_gamerules.cpp:1608 */ /* <113158> ../cstrike/dlls/multiplay_gamerules.cpp:1608 */
void CHalfLifeMultiplay::__MAKE_VHOOK(CheckMapConditions)(void) 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")) if (UTIL_FindEntityByClassname(NULL, "func_bomb_target"))
{ {
m_bMapHasBombTarget = true; m_bMapHasBombTarget = true;
@ -2618,7 +2638,7 @@ bool CHalfLifeMultiplay::CheckGameOver(void)
// check to see if we should change levels now // check to see if we should change levels now
if (m_flIntermissionEndTime < gpGlobals->time && !IsCareer()) 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_iEndIntermissionButtonHit // check that someone has pressed a key, or the max intermission time is over
|| ((m_flIntermissionStartTime + MAX_INTERMISSION_TIME) < gpGlobals->time)) || ((m_flIntermissionStartTime + MAX_INTERMISSION_TIME) < gpGlobals->time))
{ {
@ -2762,12 +2782,12 @@ void CHalfLifeMultiplay::CheckFreezePeriodExpired(void)
{ {
if (plr->m_iTeam == CT && !bCTPlayed) if (plr->m_iTeam == CT && !bCTPlayed)
{ {
plr->Radio(CT_sentence, NULL); plr->Radio(CT_sentence);
bCTPlayed = true; bCTPlayed = true;
} }
else if (plr->m_iTeam == TERRORIST && !bTPlayed) else if (plr->m_iTeam == TERRORIST && !bTPlayed)
{ {
plr->Radio(T_sentence, NULL); plr->Radio(T_sentence);
bTPlayed = true; bTPlayed = true;
} }
@ -2795,7 +2815,7 @@ void CHalfLifeMultiplay::CheckFreezePeriodExpired(void)
void CHalfLifeMultiplay::CheckRoundTimeExpired(void) void CHalfLifeMultiplay::CheckRoundTimeExpired(void)
{ {
#ifdef REGAMEDLL_ADD #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; return;
#endif // REGAMEDLL_ADD #endif // REGAMEDLL_ADD
@ -2954,9 +2974,11 @@ bool CHalfLifeMultiplay::HasRoundTimeExpired(void)
return false; 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 (!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; return true;
} }
@ -2984,6 +3006,9 @@ bool CHalfLifeMultiplay::IsBombPlanted(void)
return false; 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 */ /* <115229> ../cstrike/dlls/multiplay_gamerules.cpp:2971 */
void CHalfLifeMultiplay::MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int iTeam) 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 // If the inflictor is the killer, then it must be their current weapon doing the damage
CBasePlayer *pPlayer = static_cast<CBasePlayer*>(CBaseEntity::Instance(pKiller)); CBasePlayer *pPlayer = static_cast<CBasePlayer*>(CBaseEntity::Instance(pKiller));
if (pPlayer && pPlayer->m_pActiveItem) if (pPlayer && pPlayer->m_pActiveItem != NULL)
{ {
killer_weapon_name = pPlayer->m_pActiveItem->pszName(); 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 */ /* <1131d6> ../cstrike/dlls/multiplay_gamerules.cpp:4096 */
edict_t *CHalfLifeMultiplay::__MAKE_VHOOK(GetPlayerSpawnSpot)(CBasePlayer *pPlayer) edict_t *CHalfLifeMultiplay::__MAKE_VHOOK(GetPlayerSpawnSpot)(CBasePlayer *pPlayer)
{ {
// gat valid spawn point
edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot(pPlayer); edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot(pPlayer);
if (IsMultiplayer()) if (IsMultiplayer())

View File

@ -2463,3 +2463,12 @@ float_precision UTIL_GetPlayerGaitYaw(int playerIndex)
return 0; return 0;
} }
int UTIL_ReadFlags(const char *c)
{
int flags = 0;
while (*c)
flags |= (1 << (*c++ - 'a'));
return flags;
}

View File

@ -490,6 +490,7 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd);
NOXREF int GetPlayerTeam(int index); NOXREF int GetPlayerTeam(int index);
bool UTIL_IsGame(const char *gameName); bool UTIL_IsGame(const char *gameName);
float_precision UTIL_GetPlayerGaitYaw(int playerIndex); float_precision UTIL_GetPlayerGaitYaw(int playerIndex);
int UTIL_ReadFlags(const char *c);
/* /*
* Declared for function overload * Declared for function overload

View File

@ -1322,7 +1322,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>REGAMEDLL_ADD;REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;NDEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FloatingPointModel>Precise</FloatingPointModel> <FloatingPointModel>Precise</FloatingPointModel>
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>