From f8136978c8fba8c473a034f775ea818db7863134 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Sun, 24 Apr 2016 19:52:16 +0600 Subject: [PATCH] Using a reference to Vector into interfaces wrapper Regamedll API: Added hook RoundEnd Added API EndRoundMessage --- .../groovy/versioning/GitVersioner.groovy | 27 +- regamedll/build.gradle | 5 +- regamedll/dlls/gamerules.h | 53 +- regamedll/dlls/multiplay_gamerules.cpp | 747 ++++++++++-------- regamedll/extra/cssdk/dlls/gamerules.h | 16 +- regamedll/extra/cssdk/dlls/hookchains.h | 10 + regamedll/extra/cssdk/dlls/regamedll_api.h | 7 + .../extra/cssdk/dlls/regamedll_interfaces.h | 14 +- regamedll/public/regamedll/hookchains.h | 10 + regamedll/public/regamedll/regamedll_api.h | 7 + .../public/regamedll/regamedll_interfaces.h | 14 +- regamedll/regamedll/hookchains_impl.h | 58 ++ regamedll/regamedll/regamedll_api_impl.cpp | 3 + regamedll/regamedll/regamedll_api_impl.h | 5 + .../regamedll/regamedll_interfaces_impl.h | 14 +- 15 files changed, 624 insertions(+), 366 deletions(-) diff --git a/buildSrc/src/main/groovy/versioning/GitVersioner.groovy b/buildSrc/src/main/groovy/versioning/GitVersioner.groovy index 04fef278..4a5aac29 100644 --- a/buildSrc/src/main/groovy/versioning/GitVersioner.groovy +++ b/buildSrc/src/main/groovy/versioning/GitVersioner.groovy @@ -40,6 +40,11 @@ class GitVersioner { return null; } static String prepareUrlToCommits(String url) { + if (url == null) { + // default remote url + return "https://github.com/s1lentq/ReGameDLL_CS/commit/"; + } + StringBuilder sb = new StringBuilder(); String childPath; int pos = url.indexOf('@'); @@ -72,9 +77,29 @@ class GitVersioner { def branch = repo.getBranch() def commitDate = new DateTime(1000L * commit.commitTime, DateTimeZone.UTC) + String url = null; String remote_name = cfg.getString("branch", branch, "remote"); - String url = cfg.getString("remote", remote_name, "url"); + if (remote_name == null) { + for (String remotes : cfg.getSubsections("remote")) { + if (url != null) { + println 'Found a second remote: (' + remotes + '), url: (' + cfg.getString("remote", remotes, "url") + ')' + continue; + } + + url = cfg.getString("remote", remotes, "url"); + } + } else { + url = cfg.getString("remote", remote_name, "url"); + } + + println 'Debug: Start'; + println ' cfg: (' + cfg + ')'; + println ' branch: (' + branch + ')'; + println ' remote_name: (' + remote_name + ')'; + println ' url: (' + url + ')'; + println 'Debug: End'; + String urlCommits = prepareUrlToCommits(url); if (!commit) { diff --git a/regamedll/build.gradle b/regamedll/build.gradle index 4718ecad..eef5be37 100644 --- a/regamedll/build.gradle +++ b/regamedll/build.gradle @@ -120,6 +120,9 @@ void setupToolchain(NativeBinarySpec b) cfg.compilerOptions.floatingPointModel = FloatingPointModel.PRECISE cfg.compilerOptions.enhancedInstructionsSet = EnhancedInstructionsSet.DISABLED } + else { + cfg.compilerOptions.args '/Oi', '/GF', '/GS-' + } if (mpLib) { @@ -372,6 +375,6 @@ task generateAppVersion { renderedFile.delete() renderedFile.write(content, 'utf-8') - println 'The current ReGameDLL version is ' + verInfo.asVersion().toString() + ', maven version is ' + verInfo.asMavenVersion().toString() + ', commit id: ' + verInfo.commitID.toString() + ', commit author: ' + verInfo.authorCommit.toString(); + println 'The current ReGameDLL version is ' + verInfo.asVersion().toString() + ', maven version is ' + verInfo.asMavenVersion().toString() + ', commit id: ' + verInfo.commitID.toString() + ', commit author: ' + verInfo.authorCommit.toString() + ', url: (' + verInfo.urlCommits.toString() + ')'; } } diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index 8eb955a6..e893ecd8 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -74,9 +74,10 @@ enum // custom enum // used for EndRoundMessage() logged messages -enum ScenarionEventEndRound +enum ScenarioEventEndRound { - ROUND_TARGET_BOMB = 1, + ROUND_NONE, + ROUND_TARGET_BOMB, ROUND_VIP_ESCAPED, ROUND_VIP_ASSASSINATED, ROUND_TERRORISTS_ESCAPED, @@ -500,21 +501,44 @@ public: public: // Checks if it still needs players to start a round, or if it has enough players to start rounds. // Starts a round and returns true if there are enough players. - bool NeededPlayersCheck(bool &bNeededPlayers); + bool NeededPlayersCheck(); // Setup counts for m_iNumTerrorist, m_iNumCT, m_iNumSpawnableTerrorist, m_iNumSpawnableCT, etc. void InitializePlayerCounts(int &NumAliveTerrorist, int &NumAliveCT, int &NumDeadTerrorist, int &NumDeadCT); // Check to see if the round is over for the various game types. Terminates the round // and returns true if the round should end. - bool PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers); - bool BombRoundEndCheck(bool bNeededPlayers); - bool HostageRescueRoundEndCheck(bool bNeededPlayers); - bool VIPRoundEndCheck(bool bNeededPlayers); + bool PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT); + bool BombRoundEndCheck(); + bool HostageRescueRoundEndCheck(); + bool VIPRoundEndCheck(); // Check to see if the teams exterminated each other. Ends the round and returns true if so. - bool TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers); - void TerminateRound(float tmDelay, int iWinStatus); + bool TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT); + + // for internal functions API + bool NeededPlayersCheck_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + + bool VIP_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool VIP_Died_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool VIP_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + + bool Prison_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Prison_PreventEscape_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Prison_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Prison_Neutralized_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + + bool Target_Bombed_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Target_Saved_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Target_Defused_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + + // Team extermination + bool Round_Cts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Round_Ts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Round_Draw_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + + bool Hostage_Rescue_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); + bool Hostage_NotRescued_internal(int winStatus, ScenarioEventEndRound event, float tmDelay); // Check various conditions to end the map. bool CheckGameOver(); @@ -561,6 +585,13 @@ public: bool IsMatchStarted() { return (m_fTeamCount != 0.0f || m_fCareerRoundMenuTime != 0.0f || m_fCareerMatchMenuTime != 0.0f); } void SendMOTDToClient(edict_t *client); + inline void TerminateRound(float tmDelay, int iWinStatus) + { + m_iRoundWinStatus = iWinStatus; + m_fTeamCount = gpGlobals->time + tmDelay; + m_bRoundTerminating = true; + } + // allow the mode of fire on a friendly player (FFA) inline bool IsFriendlyFireAttack() const { @@ -669,6 +700,10 @@ protected: int m_iRoundWinDifference; float m_fCareerMatchMenuTime; bool m_bSkipSpawn; + + // custom + bool m_bNeededPlayers; + float m_flEscapeRatio; }; typedef struct mapcycle_item_s diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index 37c6c258..fa305f5e 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -258,7 +258,7 @@ char *GetTeam(int teamNo) return ""; } -void EndRoundMessage(const char *sentence, int event) +void EXT_FUNC EndRoundMessage(const char *sentence, int event) { char *team = NULL; const char *message = &(sentence[1]); @@ -562,7 +562,12 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() sv_clienttrace = CVAR_GET_POINTER("sv_clienttrace"); InstallTutor(CVAR_GET_FLOAT("tutor_enable") != 0.0f); + m_bNeededPlayers = false; + m_flEscapeRatio = 0.0f; + +#ifndef REGAMEDLL_FIXES g_pMPGameRules = this; +#endif } void CHalfLifeMultiplay::__MAKE_VHOOK(RefreshSkillData)() @@ -834,13 +839,6 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(GiveC4)() } } -void CHalfLifeMultiplay::TerminateRound(float tmDelay, int iWinStatus) -{ - m_iRoundWinStatus = iWinStatus; - m_fTeamCount = gpGlobals->time + tmDelay; - m_bRoundTerminating = true; -} - void CHalfLifeMultiplay::QueueCareerRoundEndMenu(float tmDelay, int iWinStatus) { if (TheCareerTasks == NULL) @@ -947,9 +945,7 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)() // If a winner has already been determined and game of started.. then get the heck out of here if (m_bFirstConnected && m_iRoundWinStatus != WINNER_NONE) - { return; - } #ifdef REGAMEDLL_ADD int scenarioFlags = UTIL_ReadFlags(round_infinite.string); @@ -963,29 +959,29 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)() InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT); // other player's check - bool bNeededPlayers = false; - if (!(scenarioFlags & SCENARIO_BLOCK_NEED_PLAYERS) && NeededPlayersCheck(bNeededPlayers)) + m_bNeededPlayers = false; + if (!(scenarioFlags & SCENARIO_BLOCK_NEED_PLAYERS) && NeededPlayersCheck()) return; // Assasination/VIP scenarion check - if (!(scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPRE) && VIPRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_VIP_ESCAPRE) && VIPRoundEndCheck()) return; // Prison escape check - if (!(scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPRE) && PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_PRISON_ESCAPRE) && PrisonRoundEndCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT)) return; // Bomb check - if (!(scenarioFlags & SCENARIO_BLOCK_BOMB) && BombRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_BOMB) && BombRoundEndCheck()) return; // Team Extermination check // CounterTerrorists won by virture of elimination - if (!(scenarioFlags & SCENARIO_BLOCK_TEAM_EXTERMINATION) && TeamExterminationCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT, bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_TEAM_EXTERMINATION) && TeamExterminationCheck(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT)) return; // Hostage rescue check - if (!(scenarioFlags & SCENARIO_BLOCK_HOSTAGE_RESCUE) && HostageRescueRoundEndCheck(bNeededPlayers)) + if (!(scenarioFlags & SCENARIO_BLOCK_HOSTAGE_RESCUE) && HostageRescueRoundEndCheck()) return; // scenario not won - still in progress @@ -1072,7 +1068,28 @@ void CHalfLifeMultiplay::InitializePlayerCounts(int &NumAliveTerrorist, int &Num } } -bool CHalfLifeMultiplay::NeededPlayersCheck(bool &bNeededPlayers) +bool CHalfLifeMultiplay::NeededPlayersCheck_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + // 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", event); + TerminateRound(tmDelay, winStatus); + + m_bFirstConnected = true; + if (TheBots != NULL) + { + TheBots->OnEvent(EVENT_GAME_COMMENCE); + } + + return true; +} + +bool CHalfLifeMultiplay::NeededPlayersCheck() { // We needed players to start scoring // Do we have them now? @@ -1080,7 +1097,7 @@ bool CHalfLifeMultiplay::NeededPlayersCheck(bool &bNeededPlayers) if (!m_iNumSpawnableTerrorist || !m_iNumSpawnableCT) { UTIL_ClientPrintAll(HUD_PRINTCONSOLE, "#Game_scoring"); - bNeededPlayers = true; + m_bNeededPlayers = true; m_bFirstConnected = false; } @@ -1096,178 +1113,186 @@ bool CHalfLifeMultiplay::NeededPlayersCheck(bool &bNeededPlayers) } } - // 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 g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::NeededPlayersCheck_internal, this, WINSTATUS_DRAW, ROUND_GAME_COMMENCE, IsCareer() ? 0 : 3); } return false; } -bool CHalfLifeMultiplay::VIPRoundEndCheck(bool bNeededPlayers) +bool CHalfLifeMultiplay::VIP_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iAccountCT += REWARD_VIP_ESCAPED; + + if (!m_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", event); + + // tell the bots the VIP got out + if (TheBots != NULL) + { + TheBots->OnEvent(EVENT_VIP_ESCAPED); + } + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::VIP_Died_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += REWARD_VIP_ASSASSINATED; + + if (!m_bNeededPlayers) + { + ++m_iNumTerroristWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#VIP_Assassinated", event); + + // tell the bots the VIP was killed + if (TheBots != NULL) + { + TheBots->OnEvent(EVENT_VIP_ASSASSINATED); + } + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::VIPRoundEndCheck() { // 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); - - // tell the bots the VIP got out - if (TheBots != NULL) - { - TheBots->OnEvent(EVENT_VIP_ESCAPED); - } - TerminateRound(5, WINSTATUS_CTS); - - if (IsCareer()) - { - QueueCareerRoundEndMenu(5, WINSTATUS_CTS); - } - - return true; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::VIP_Escaped_internal, this, WINSTATUS_CTS, ROUND_VIP_ESCAPED, 5); } // 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); - - // tell the bots the VIP was killed - if (TheBots != NULL) - { - TheBots->OnEvent(EVENT_VIP_ASSASSINATED); - } - TerminateRound(5, WINSTATUS_TERRORISTS); - - if (IsCareer()) - { - QueueCareerRoundEndMenu(5, WINSTATUS_TERRORISTS); - } - - return true; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::VIP_Died_internal, this, WINSTATUS_TERRORISTS, ROUND_VIP_ASSASSINATED, 5); } } return false; } -bool CHalfLifeMultiplay::PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers) +bool CHalfLifeMultiplay::Prison_Escaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += REWARD_TERRORISTS_ESCAPED; + + if (!m_bNeededPlayers) + { + ++m_iNumTerroristWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#Terrorists_Escaped", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::Prison_PreventEscape_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + // CTs are rewarded based on how many terrorists have escaped... + m_iAccountCT += (1 - m_flEscapeRatio) * REWARD_CTS_PREVENT_ESCAPE; + + if (!m_bNeededPlayers) + { + ++m_iNumCTWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#CTs_PreventEscape", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::Prison_Neutralized_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + // CTs are rewarded based on how many terrorists have escaped... + m_iAccountCT += (1 - m_flEscapeRatio) * REWARD_ESCAPING_TERRORISTS_NEUTRALIZED; + + if (!m_bNeededPlayers) + { + ++m_iNumCTWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#Escaping_Terrorists_Neutralized", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::PrisonRoundEndCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT) { // checks to scenario Escaped Terrorist's if (m_bMapHasEscapeZone) { - float_precision flEscapeRatio = float_precision(m_iHaveEscaped) / float_precision(m_iNumEscapers); + m_flEscapeRatio = float_precision(m_iHaveEscaped) / float_precision(m_iNumEscapers); - if (flEscapeRatio >= m_flRequiredEscapeRatio) + if (m_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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Prison_Escaped_internal, this, WINSTATUS_TERRORISTS, ROUND_TERRORISTS_ESCAPED, 5); } - else if (NumAliveTerrorist == 0 && flEscapeRatio < m_flRequiredEscapeRatio) + else if (NumAliveTerrorist == 0 && m_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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Prison_PreventEscape_internal, this, WINSTATUS_CTS, ROUND_CTS_PREVENT_ESCAPE, 5); } 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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Prison_Neutralized_internal, this, WINSTATUS_CTS, ROUND_ESCAPING_TERRORISTS_NEUTRALIZED, 5); } // else return true; } @@ -1275,59 +1300,124 @@ bool CHalfLifeMultiplay::PrisonRoundEndCheck(int NumAliveTerrorist, int NumAlive return false; } -bool CHalfLifeMultiplay::BombRoundEndCheck(bool bNeededPlayers) + +bool CHalfLifeMultiplay::Target_Bombed_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += REWARD_TARGET_BOMB; + + if (!m_bNeededPlayers) + { + ++m_iNumTerroristWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#Target_Bombed", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::Target_Defused_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iAccountCT += REWARD_BOMB_DEFUSED; + m_iAccountTerrorist += REWARD_BOMB_PLANTED; + + if (!m_bNeededPlayers) + { + ++m_iNumCTWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#Bomb_Defused", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::BombRoundEndCheck() { // 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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Target_Bombed_internal, this, WINSTATUS_TERRORISTS, ROUND_TARGET_BOMB, 5); } 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 g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Target_Defused_internal, this, WINSTATUS_CTS, ROUND_BOMB_DEFUSED, 5); } return false; } -bool CHalfLifeMultiplay::TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT, bool bNeededPlayers) +bool CHalfLifeMultiplay::Round_Cts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iAccountCT += m_bMapHasBombTarget ? REWARD_BOMB_DEFUSED : REWARD_CTS_WIN; + + if (!m_bNeededPlayers) + { + ++m_iNumCTWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#CTs_Win", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::Round_Ts_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += m_bMapHasBombTarget ? REWARD_BOMB_EXPLODED : REWARD_TERRORISTS_WIN; + + if (!m_bNeededPlayers) + { + ++m_iNumTerroristWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#Terrorists_Win", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::Round_Draw_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + EndRoundMessage("#Round_Draw", event); + Broadcast("rounddraw"); + TerminateRound(tmDelay, winStatus); + return true; +} + +bool CHalfLifeMultiplay::TeamExterminationCheck(int NumAliveTerrorist, int NumAliveCT, int NumDeadTerrorist, int NumDeadCT) { if ((m_iNumCT > 0 && m_iNumSpawnableCT > 0) && (m_iNumTerrorist > 0 && m_iNumSpawnableTerrorist > 0)) { @@ -1351,65 +1441,62 @@ bool CHalfLifeMultiplay::TeamExterminationCheck(int NumAliveTerrorist, int NumAl 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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Round_Cts_internal, this, WINSTATUS_CTS, ROUND_CTS_WIN, 5); } } // Terrorists WON else 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; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Round_Ts_internal, this, WINSTATUS_TERRORISTS, ROUND_TERRORISTS_WIN, 5); } } else if (NumAliveCT == 0 && NumAliveTerrorist == 0) { - EndRoundMessage("#Round_Draw", ROUND_END_DRAW); - Broadcast("rounddraw"); - TerminateRound(5, WINSTATUS_DRAW); - - return true; + return g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Round_Draw_internal, this, WINSTATUS_DRAW, ROUND_END_DRAW, 5); } return false; } -bool CHalfLifeMultiplay::HostageRescueRoundEndCheck(bool bNeededPlayers) +bool CHalfLifeMultiplay::Hostage_Rescue_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iAccountCT += REWARD_ALL_HOSTAGES_RESCUED; + + if (!m_bNeededPlayers) + { + ++m_iNumCTWins; + // Update the clients team score + UpdateTeamScores(); + } + + EndRoundMessage("#All_Hostages_Rescued", event); + + // tell the bots all the hostages have been rescued + if (TheBots != NULL) + { + TheBots->OnEvent(EVENT_ALL_HOSTAGES_RESCUED); + } + + if (IsCareer()) + { + if (TheCareerTasks != NULL) + { + TheCareerTasks->HandleEvent(EVENT_ALL_HOSTAGES_RESCUED); + } + } + + TerminateRound(tmDelay, winStatus); + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + return true; +} + +bool CHalfLifeMultiplay::HostageRescueRoundEndCheck() { // Check to see if 50% of the hostages have been rescued. CBaseEntity *hostage = NULL; @@ -1432,41 +1519,9 @@ bool CHalfLifeMultiplay::HostageRescueRoundEndCheck(bool bNeededPlayers) // 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)) + if (m_iHostagesRescued >= (iHostages * 0.5f)) { - 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); - - // tell the bots all the hostages have been 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 g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Hostage_Rescue_internal, this, WINSTATUS_CTS, ROUND_ALL_HOSTAGES_RESCUED, 5); } } @@ -2730,6 +2785,80 @@ void CHalfLifeMultiplay::CheckFreezePeriodExpired() } } +bool CHalfLifeMultiplay::Target_Saved_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iAccountCT += REWARD_TARGET_BOMB_SAVED; + m_iNumCTWins++; + + EndRoundMessage("#Target_Saved", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + UpdateTeamScores(); + MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(TERRORIST); + + return true; +} + +bool CHalfLifeMultiplay::Hostage_NotRescued_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += REWARD_HOSTAGE_NOT_RESCUED; + m_iNumTerroristWins++; + + EndRoundMessage("#Hostages_Not_Rescued", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + UpdateTeamScores(); + MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(CT); + return true; +} + +bool CHalfLifeMultiplay::Prison_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("ctwin"); + m_iNumCTWins++; + + EndRoundMessage("#Terrorists_Not_Escaped", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + UpdateTeamScores(); + return true; +} + +bool CHalfLifeMultiplay::VIP_NotEscaped_internal(int winStatus, ScenarioEventEndRound event, float tmDelay) { + + Broadcast("terwin"); + m_iAccountTerrorist += REWARD_VIP_NOT_ESCAPED; + m_iNumTerroristWins++; + + EndRoundMessage("#VIP_Not_Escaped", event); + TerminateRound(tmDelay, winStatus); + + if (IsCareer()) + { + QueueCareerRoundEndMenu(tmDelay, winStatus); + } + + UpdateTeamScores(); + return true; +} + void CHalfLifeMultiplay::CheckRoundTimeExpired() { if (HasRoundInfinite(true)) @@ -2757,69 +2886,23 @@ void CHalfLifeMultiplay::CheckRoundTimeExpired() // 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); + if (!g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Target_Saved_internal, this, WINSTATUS_CTS, ROUND_TARGET_SAVED, 5)) + return; } 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); + if (!g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Hostage_NotRescued_internal, this, WINSTATUS_TERRORISTS, ROUND_HOSTAGE_NOT_RESCUED, 5)) + return; } 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(); + if (!g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::Prison_NotEscaped_internal, this, WINSTATUS_CTS, ROUND_TERRORISTS_NOT_ESCAPED, 5)) + return; } 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(); + if (!g_ReGameHookchains.m_RoundEnd.callChain(&CHalfLifeMultiplay::VIP_NotEscaped_internal, this, WINSTATUS_TERRORISTS, ROUND_VIP_NOT_ESCAPED, 5)) + return; } // This is done so that the portion of code has enough time to do it's thing. diff --git a/regamedll/extra/cssdk/dlls/gamerules.h b/regamedll/extra/cssdk/dlls/gamerules.h index c4914fd3..95afeb0f 100644 --- a/regamedll/extra/cssdk/dlls/gamerules.h +++ b/regamedll/extra/cssdk/dlls/gamerules.h @@ -69,9 +69,10 @@ enum // custom enum // used for EndRoundMessage() logged messages -enum ScenarionEventEndRound +enum ScenarioEventEndRound { - ROUND_TARGET_BOMB = 1, + ROUND_NONE, + ROUND_TARGET_BOMB, ROUND_VIP_ESCAPED, ROUND_VIP_ASSASSINATED, ROUND_TERRORISTS_ESCAPED, @@ -375,6 +376,13 @@ public: void MarkSpawnSkipped() { m_bSkipSpawn = false; } float TimeRemaining() { return m_iRoundTimeSecs - gpGlobals->time + m_fRoundCount; } bool IsMatchStarted() { return (m_fTeamCount != 0.0f || m_fCareerRoundMenuTime != 0.0f || m_fCareerMatchMenuTime != 0.0f); } + + inline void TerminateRound(float tmDelay, int iWinStatus) + { + m_iRoundWinStatus = iWinStatus; + m_fTeamCount = gpGlobals->time + tmDelay; + m_bRoundTerminating = true; + } public: CVoiceGameMgr m_VoiceGameMgr; float m_fTeamCount; // m_flRestartRoundTime, the global time when the round is supposed to end, if this is not 0 @@ -458,6 +466,10 @@ public: int m_iRoundWinDifference; float m_fCareerMatchMenuTime; bool m_bSkipSpawn; + + // custom + bool m_bNeededPlayers; + float m_flEscapeRatio; }; typedef struct mapcycle_item_s diff --git a/regamedll/extra/cssdk/dlls/hookchains.h b/regamedll/extra/cssdk/dlls/hookchains.h index f2993e8b..b4190a16 100644 --- a/regamedll/extra/cssdk/dlls/hookchains.h +++ b/regamedll/extra/cssdk/dlls/hookchains.h @@ -68,6 +68,16 @@ public: virtual void unregisterHook(hookfunc_t hook) = 0; }; +// Hook chain registry(for hooks [un]registration) +template +class IHookChainRegistryClassEmpty { +public: + typedef t_ret(*hookfunc_t)(IHookChain*, t_args...); + + virtual void registerHook(hookfunc_t hook) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; + // Hook chain registry(for hooks [un]registration) template class IVoidHookChainRegistry { diff --git a/regamedll/extra/cssdk/dlls/regamedll_api.h b/regamedll/extra/cssdk/dlls/regamedll_api.h index ef3a47dc..1f6ea12d 100644 --- a/regamedll/extra/cssdk/dlls/regamedll_api.h +++ b/regamedll/extra/cssdk/dlls/regamedll_api.h @@ -170,6 +170,10 @@ typedef IVoidHookChainRegistry IReGameHook_RadiusFlash_TraceLine; typedef IVoidHookChainRegistry IReGameHookRegistry_RadiusFlash_TraceLine; +// RoundEnd hook +typedef IHookChain IReGameHook_RoundEnd; +typedef IHookChainRegistryClassEmpty IReGameHookRegistry_RoundEnd; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -211,6 +215,7 @@ public: virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0; virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; + virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; }; @@ -229,6 +234,8 @@ struct ReGameFuncs_t { void (*ApplyMultiDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker); void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); + void (*EndRoundMessage)(const char *sentence, int event); + }; class IReGameApi { diff --git a/regamedll/extra/cssdk/dlls/regamedll_interfaces.h b/regamedll/extra/cssdk/dlls/regamedll_interfaces.h index 6c411cd1..e2d3fd08 100644 --- a/regamedll/extra/cssdk/dlls/regamedll_interfaces.h +++ b/regamedll/extra/cssdk/dlls/regamedll_interfaces.h @@ -68,12 +68,12 @@ public: virtual void SetObjectCollisionBox() = 0; virtual int Classify() = 0; virtual void DeathNotice(struct entvars_s *pevChild) = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; virtual int BloodColor() = 0; - virtual void TraceBleed(float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceBleed(float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual bool IsTriggered(CCSEntity *pActivator) = 0; virtual ICSMonster *MyMonsterPointer() = 0; virtual ICSquadMonster *MySquadMonsterPointer() = 0; @@ -118,8 +118,8 @@ public: public: virtual struct entvars_s *GetEntVars() const = 0; virtual class CBaseEntity *GetEntity() const = 0; - virtual void FireBullets(int iShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) = 0; - virtual Vector FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) = 0; + virtual void FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) = 0; + virtual Vector FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) = 0; }; class ICSDelay: public ICSEntity { @@ -208,7 +208,7 @@ public: class ICSMonster: public ICSToggle { public: virtual void KeyValue(struct KeyValueData_s *pkvd) = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; @@ -260,7 +260,7 @@ public: virtual int Restore(CRestore &restore) = 0; virtual int ObjectCaps() = 0; virtual int Classify() = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; @@ -846,7 +846,7 @@ public: virtual int Save(CSave &save) = 0; virtual int Restore(CRestore &restore) = 0; virtual int ObjectCaps() = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int DamageDecal(int bitsDamageType) = 0; virtual void Use(CCSEntity *pActivator, CCSEntity *pCaller, USE_TYPE useType, float value) = 0; diff --git a/regamedll/public/regamedll/hookchains.h b/regamedll/public/regamedll/hookchains.h index f2993e8b..b4190a16 100644 --- a/regamedll/public/regamedll/hookchains.h +++ b/regamedll/public/regamedll/hookchains.h @@ -68,6 +68,16 @@ public: virtual void unregisterHook(hookfunc_t hook) = 0; }; +// Hook chain registry(for hooks [un]registration) +template +class IHookChainRegistryClassEmpty { +public: + typedef t_ret(*hookfunc_t)(IHookChain*, t_args...); + + virtual void registerHook(hookfunc_t hook) = 0; + virtual void unregisterHook(hookfunc_t hook) = 0; +}; + // Hook chain registry(for hooks [un]registration) template class IVoidHookChainRegistry { diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index ef3a47dc..1f6ea12d 100644 --- a/regamedll/public/regamedll/regamedll_api.h +++ b/regamedll/public/regamedll/regamedll_api.h @@ -170,6 +170,10 @@ typedef IVoidHookChainRegistry IReGameHook_RadiusFlash_TraceLine; typedef IVoidHookChainRegistry IReGameHookRegistry_RadiusFlash_TraceLine; +// RoundEnd hook +typedef IHookChain IReGameHook_RoundEnd; +typedef IHookChainRegistryClassEmpty IReGameHookRegistry_RoundEnd; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -211,6 +215,7 @@ public: virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0; virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; + virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; }; @@ -229,6 +234,8 @@ struct ReGameFuncs_t { void (*ApplyMultiDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker); void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); + void (*EndRoundMessage)(const char *sentence, int event); + }; class IReGameApi { diff --git a/regamedll/public/regamedll/regamedll_interfaces.h b/regamedll/public/regamedll/regamedll_interfaces.h index 6c411cd1..e2d3fd08 100644 --- a/regamedll/public/regamedll/regamedll_interfaces.h +++ b/regamedll/public/regamedll/regamedll_interfaces.h @@ -68,12 +68,12 @@ public: virtual void SetObjectCollisionBox() = 0; virtual int Classify() = 0; virtual void DeathNotice(struct entvars_s *pevChild) = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; virtual int BloodColor() = 0; - virtual void TraceBleed(float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceBleed(float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual bool IsTriggered(CCSEntity *pActivator) = 0; virtual ICSMonster *MyMonsterPointer() = 0; virtual ICSquadMonster *MySquadMonsterPointer() = 0; @@ -118,8 +118,8 @@ public: public: virtual struct entvars_s *GetEntVars() const = 0; virtual class CBaseEntity *GetEntity() const = 0; - virtual void FireBullets(int iShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) = 0; - virtual Vector FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) = 0; + virtual void FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) = 0; + virtual Vector FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) = 0; }; class ICSDelay: public ICSEntity { @@ -208,7 +208,7 @@ public: class ICSMonster: public ICSToggle { public: virtual void KeyValue(struct KeyValueData_s *pkvd) = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; @@ -260,7 +260,7 @@ public: virtual int Restore(CRestore &restore) = 0; virtual int ObjectCaps() = 0; virtual int Classify() = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(struct entvars_s *pevAttacker, int iGib) = 0; @@ -846,7 +846,7 @@ public: virtual int Save(CSave &save) = 0; virtual int Restore(CRestore &restore) = 0; virtual int ObjectCaps() = 0; - virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; + virtual void TraceAttack(struct entvars_s *pevAttacker, float flDamage, Vector &vecDir, struct TraceResult *ptr, int bitsDamageType) = 0; virtual int TakeDamage(struct entvars_s *pevInflictor, struct entvars_s *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual int DamageDecal(int bitsDamageType) = 0; virtual void Use(CCSEntity *pActivator, CCSEntity *pCaller, USE_TYPE useType, float value) = 0; diff --git a/regamedll/regamedll/hookchains_impl.h b/regamedll/regamedll/hookchains_impl.h index d9353222..d2fe4672 100644 --- a/regamedll/regamedll/hookchains_impl.h +++ b/regamedll/regamedll/hookchains_impl.h @@ -103,6 +103,43 @@ private: origfunc_t m_OriginalFunc; }; +// Implementation for chains in modules +template +class IHookChainClassEmptyImpl : public IHookChain { +public: + typedef t_ret(*hookfunc_t)(IHookChain*, t_args...); + typedef t_ret(t_class::*origfunc_t)(t_args...); + + IHookChainClassEmptyImpl(void** hooks, origfunc_t orig, t_class *object) : m_Hooks(hooks), m_OriginalFunc(orig), m_Object(object) + { + if (orig == NULL) + regamedll_syserror("Non-void HookChain without original function."); + } + + virtual ~IHookChainClassEmptyImpl() {} + + virtual t_ret callNext(t_args... args) { + hookfunc_t nexthook = (hookfunc_t)m_Hooks[0]; + + if (nexthook) + { + IHookChainClassEmptyImpl nextChain(m_Hooks + 1, m_OriginalFunc, m_Object); + return nexthook(&nextChain, args...); + } + + return (m_Object->*m_OriginalFunc)(args...); + } + + virtual t_ret callOriginal(t_args... args) { + return (m_Object->*m_OriginalFunc)(args...); + } + +private: + void** m_Hooks; + t_class *m_Object; + origfunc_t m_OriginalFunc; +}; + // Implementation for void chains in modules template class IVoidHookChainImpl : public IVoidHookChain { @@ -228,6 +265,27 @@ public: } }; +template +class IHookChainRegistryClassEmptyImpl : public IHookChainRegistryClassEmpty , public AbstractHookChainRegistry { +public: + typedef t_ret(*hookfunc_t)(IHookChain*, t_args...); + typedef t_ret(t_class::*origfunc_t)(t_args...); + + virtual ~IHookChainRegistryClassEmptyImpl() { } + + t_ret callChain(origfunc_t origFunc, t_class *object, t_args... args) { + IHookChainClassEmptyImpl chain(m_Hooks, origFunc, object); + return chain.callNext(args...); + } + + virtual void registerHook(hookfunc_t hook) { + addHook((void*)hook); + } + virtual void unregisterHook(hookfunc_t hook) { + removeHook((void*)hook); + } +}; + template class IVoidHookChainRegistryImpl : public IVoidHookChainRegistry , public AbstractHookChainRegistry { public: diff --git a/regamedll/regamedll/regamedll_api_impl.cpp b/regamedll/regamedll/regamedll_api_impl.cpp index 0bc09c59..027084c7 100644 --- a/regamedll/regamedll/regamedll_api_impl.cpp +++ b/regamedll/regamedll/regamedll_api_impl.cpp @@ -44,6 +44,8 @@ ReGameFuncs_t g_ReGameApiFuncs = { &ClearMultiDamage_api, &ApplyMultiDamage_api, &AddMultiDamage_api, + + &EndRoundMessage }; IReGameHookRegistry_CBasePlayer_Spawn* CReGameHookchains::CBasePlayer_Spawn() { return &m_CBasePlayer_Spawn; } @@ -82,6 +84,7 @@ IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo* CReGameHookchains::CBaseAn IReGameHookRegistry_GetForceCamera* CReGameHookchains::GetForceCamera() { return &m_GetForceCamera; } IReGameHookRegistry_PlayerBlind* CReGameHookchains::PlayerBlind() { return &m_PlayerBlind; } IReGameHookRegistry_RadiusFlash_TraceLine* CReGameHookchains::RadiusFlash_TraceLine() { return &m_RadiusFlash_TraceLine; } +IReGameHookRegistry_RoundEnd* CReGameHookchains::RoundEnd() { return &m_RoundEnd; } int CReGameApi::GetMajorVersion() { diff --git a/regamedll/regamedll/regamedll_api_impl.h b/regamedll/regamedll/regamedll_api_impl.h index 6882054b..3c64bf14 100644 --- a/regamedll/regamedll/regamedll_api_impl.h +++ b/regamedll/regamedll/regamedll_api_impl.h @@ -164,6 +164,9 @@ typedef IVoidHookChainRegistryImpl CReGameHook_RadiusFlash_TraceLine; typedef IVoidHookChainRegistryImpl CReGameHookRegistry_RadiusFlash_TraceLine; +typedef IHookChainClassImpl CReGameHook_RoundEnd; +typedef IHookChainRegistryClassEmptyImpl CReGameHookRegistry_RoundEnd; + class CReGameHookchains: public IReGameHookchains { public: // CBasePlayer virtual @@ -203,6 +206,7 @@ public: CReGameHookRegistry_GetForceCamera m_GetForceCamera; CReGameHookRegistry_PlayerBlind m_PlayerBlind; CReGameHookRegistry_RadiusFlash_TraceLine m_RadiusFlash_TraceLine; + CReGameHookRegistry_RoundEnd m_RoundEnd; public: virtual IReGameHookRegistry_CBasePlayer_Spawn* CBasePlayer_Spawn(); @@ -241,6 +245,7 @@ public: virtual IReGameHookRegistry_GetForceCamera* GetForceCamera(); virtual IReGameHookRegistry_PlayerBlind* PlayerBlind(); virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine(); + virtual IReGameHookRegistry_RoundEnd* RoundEnd(); }; diff --git a/regamedll/regamedll/regamedll_interfaces_impl.h b/regamedll/regamedll/regamedll_interfaces_impl.h index 9af0bf4d..65f6c6f9 100644 --- a/regamedll/regamedll/regamedll_interfaces_impl.h +++ b/regamedll/regamedll/regamedll_interfaces_impl.h @@ -99,12 +99,12 @@ public: virtual void SetObjectCollisionBox() { m_pEntity->SetObjectCollisionBox(); } virtual int Classify() { return m_pEntity->Classify(); } virtual void DeathNotice(entvars_t *pevChild) { m_pEntity->DeathNotice(pevChild); } - virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } + virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector &vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return m_pEntity->TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); } virtual int TakeHealth(float flHealth, int bitsDamageType) { return m_pEntity->TakeHealth(flHealth, bitsDamageType); } virtual void Killed(entvars_t *pevAttacker, int iGib) { m_pEntity->Killed(pevAttacker, iGib); } virtual int BloodColor() { return m_pEntity->BloodColor(); } - virtual void TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceBleed(flDamage, vecDir, ptr, bitsDamageType); } + virtual void TraceBleed(float flDamage, Vector &vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceBleed(flDamage, vecDir, ptr, bitsDamageType); } virtual bool IsTriggered(CCSEntity *pActivator) { return m_pEntity->IsTriggered(pActivator->m_pEntity) ? true : false; } virtual ICSMonster *MyMonsterPointer() { return reinterpret_cast(CBASE_TO_CSENTITY(m_pEntity->MyMonsterPointer())); } virtual ICSquadMonster *MySquadMonsterPointer() { return (ICSquadMonster *)m_pEntity->MySquadMonsterPointer(); } @@ -149,8 +149,8 @@ public: public: virtual entvars_t *GetEntVars() const { return m_pEntity->pev; } virtual CBaseEntity *GetEntity() const { return m_pEntity; } - virtual void FireBullets(int iShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) { m_pEntity->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker); }; - virtual Vector FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) { return m_pEntity->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand); }; + virtual void FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) { m_pEntity->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker); }; + virtual Vector FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) { return m_pEntity->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand); }; }; class CCSDelay: public CCSEntity { @@ -218,7 +218,7 @@ public: CCSMonster(CBaseEntity *pEntity) : CCSToggle(pEntity) {} public: virtual void KeyValue(KeyValueData *pkvd) { m_pEntity->KeyValue(pkvd); } - virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } + virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector &vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return m_pEntity->TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); } virtual int TakeHealth(float flHealth, int bitsDamageType) { return m_pEntity->TakeHealth(flHealth, bitsDamageType); } virtual void Killed(entvars_t *pevAttacker, int iGib) { m_pEntity->Killed(pevAttacker, iGib); } @@ -276,7 +276,7 @@ public: virtual int Restore(CRestore &restore) { return m_pEntity->Restore(restore); } virtual int ObjectCaps() { return m_pEntity->ObjectCaps(); } virtual int Classify() { return m_pEntity->Classify(); } - virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } + virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector &vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return m_pEntity->TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); } virtual int TakeHealth(float flHealth, int bitsDamageType) { return m_pEntity->TakeHealth(flHealth, bitsDamageType); } virtual void Killed(entvars_t *pevAttacker, int iGib) { m_pEntity->Killed(pevAttacker, iGib); } @@ -1021,7 +1021,7 @@ public: virtual int Save(CSave &save) { return m_pEntity->Save(save); } virtual int Restore(CRestore &restore) { return m_pEntity->Restore(restore); } virtual int ObjectCaps() { return m_pEntity->ObjectCaps(); } - virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } + virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector &vecDir, TraceResult *ptr, int bitsDamageType) { m_pEntity->TraceAttack(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); } virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { return m_pEntity->TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType); } virtual int DamageDecal(int bitsDamageType) { return m_pEntity->DamageDecal(bitsDamageType); } virtual void Use(CCSEntity *pActivator, CCSEntity *pCaller, USE_TYPE useType, float value) { m_pEntity->Use(pActivator->m_pEntity, pCaller->m_pEntity, useType, value); }