diff --git a/Source/Features/Hud/PostRoundTimer/PostRoundTimerContext.h b/Source/Features/Hud/PostRoundTimer/PostRoundTimerContext.h index 3b4a09bd235..08c93e6363b 100644 --- a/Source/Features/Hud/PostRoundTimer/PostRoundTimerContext.h +++ b/Source/Features/Hud/PostRoundTimer/PostRoundTimerContext.h @@ -51,7 +51,7 @@ struct PostRoundTimerContext { [[nodiscard]] decltype(auto) localPlayerTeamNumber() const noexcept { - return _hookContext.localPlayerController2().teamNumber(); + return _hookContext.localPlayerController().teamNumber(); } private: diff --git a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerInformationThroughWalls.h b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerInformationThroughWalls.h index af9538bb0ab..70a29d9e38e 100644 --- a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerInformationThroughWalls.h +++ b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerInformationThroughWalls.h @@ -17,8 +17,6 @@ #include #include -#include "PlayerPositionArrow/PlayerColorCalculator.h" -#include "PlayerPositionArrow/PlayerColorIndexAccessor.h" #include "PlayerInformationPanel.h" #include "PlayerPositionArrow/PlayerPositionArrowColorCalculator.h" #include "PlayerPositionArrow/TeamColorCalculator.h" @@ -215,10 +213,6 @@ class PlayerInformationThroughWalls { if (!shouldDrawOnPawn(pawn)) return; - const auto playerController = pawn.playerController(); - if (!playerController) - return; - const auto absOrigin = pawn.absOrigin(); if (!absOrigin) return; @@ -250,7 +244,7 @@ class PlayerInformationThroughWalls { if (!playerInformationPanel.isValid()) return; - setArrowColor(PanoramaUiPanel{PanoramaUiPanelContext{dependencies, playerInformationPanel.positionArrowPanel}}, *playerController, pawn.teamNumber()); + setArrowColor(PanoramaUiPanel{PanoramaUiPanelContext{dependencies, playerInformationPanel.positionArrowPanel}}, pawn.playerController(), pawn.teamNumber()); setHealth(PanoramaUiPanel{PanoramaUiPanelContext{dependencies, playerInformationPanel.healthPanel}}, pawn.health().value_or(0)); setActiveWeapon(PanoramaUiPanel{PanoramaUiPanelContext{dependencies, playerInformationPanel.weaponIconPanel}}, pawn); setActiveWeaponAmmo(PanoramaUiPanel{PanoramaUiPanelContext{dependencies, playerInformationPanel.weaponAmmoPanel}}, pawn); @@ -304,17 +298,12 @@ class PlayerInformationThroughWalls { && (!state.showOnlyEnemies || playerPawn.isEnemy().value_or(true)); } - [[nodiscard]] PlayerColorCalculator getPlayerColorCalculator(cs2::CCSPlayerController& playerController) const noexcept - { - return PlayerColorCalculator{PlayerColorIndexAccessor{playerController, dependencies.gameDependencies().playerControllerDeps.offsetToPlayerColor}}; - } - - [[nodiscard]] auto getPlayerPositionArrowColorCalculator(cs2::CCSPlayerController& playerController, TeamNumber teamNumber) const noexcept + [[nodiscard]] auto getPlayerPositionArrowColorCalculator(TeamNumber teamNumber) const noexcept { - return PlayerPositionArrowColorCalculator{getPlayerColorCalculator(playerController), TeamColorCalculator{teamNumber}}; + return PlayerPositionArrowColorCalculator{TeamColorCalculator{teamNumber}}; } - void setArrowColor(auto arrowPanel, cs2::CCSPlayerController& playerController, TeamNumber teamNumber) const noexcept + void setArrowColor(auto arrowPanel, auto&& playerController, TeamNumber teamNumber) const noexcept { if (!state.showPlayerPosition) { arrowPanel.setVisible(false); @@ -322,7 +311,7 @@ class PlayerInformationThroughWalls { } arrowPanel.setVisible(true); - arrowPanel.setWashColor(getPlayerPositionArrowColorCalculator(playerController, teamNumber).getArrowColor(state.playerPositionArrowColor)); + arrowPanel.setWashColor(getPlayerPositionArrowColorCalculator(teamNumber).getArrowColor(playerController, state.playerPositionArrowColor)); } [[nodiscard]] cs2::C_CSWeaponBase::m_iClip1 getActiveWeaponClip(auto&& playerPawn) const noexcept diff --git a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorCalculator.h b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorCalculator.h deleted file mode 100644 index 273b03337eb..00000000000 --- a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorCalculator.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -template -struct PlayerColorCalculator { - PlayerColorIndexAccessor playerColorIndexAccessor; - - [[nodiscard]] bool getPlayerColor(cs2::Color* color) const noexcept - { - return getPlayerColor(playerColorIndexAccessor.getPlayerColorIndex(), color); - } - -private: - [[nodiscard]] bool getPlayerColor(cs2::CCSPlayerController::m_iCompTeammateColor playerColorIndex, cs2::Color* color) const noexcept - { - if (playerColorIndex >= 0 && std::cmp_less(playerColorIndex, cs2::kPlayerColors.size())) { - *color = cs2::kPlayerColors[playerColorIndex]; - return true; - } - return false; - } -}; - -template -PlayerColorCalculator(PlayerColorIndexAccessor) -> PlayerColorCalculator; diff --git a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorIndexAccessor.h b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorIndexAccessor.h deleted file mode 100644 index 4611a062bc1..00000000000 --- a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerColorIndexAccessor.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include - -struct PlayerColorIndexAccessor { - [[nodiscard]] cs2::CCSPlayerController::m_iCompTeammateColor getPlayerColorIndex() const noexcept - { - constexpr auto kInvalidPlayerColorIndex = cs2::CCSPlayerController::m_iCompTeammateColor{-1}; - return offsetToPlayerColor.of(&playerController).valueOr(kInvalidPlayerColorIndex); - } - - cs2::CCSPlayerController& playerController; - OffsetToPlayerColor offsetToPlayerColor; -}; diff --git a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerPositionArrowColorCalculator.h b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerPositionArrowColorCalculator.h index caf609a77b0..bd77bdb3312 100644 --- a/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerPositionArrowColorCalculator.h +++ b/Source/Features/Visuals/PlayerInformationThroughWalls/PlayerPositionArrow/PlayerPositionArrowColorCalculator.h @@ -5,19 +5,21 @@ #include "PlayerPositionArrowColorType.h" -template +template struct PlayerPositionArrowColorCalculator { - [[nodiscard]] cs2::Color getArrowColor(PlayerPositionArrowColorType colorType) const noexcept + [[nodiscard]] cs2::Color getArrowColor(auto&& playerController, PlayerPositionArrowColorType colorType) const noexcept { - if (cs2::Color color{cs2::kColorWhite}; colorType == PlayerPositionArrowColorType::PlayerOrTeamColor && playerColorCalculator.getPlayerColor(&color)) - return color; + if (colorType == PlayerPositionArrowColorType::PlayerOrTeamColor) { + const auto playerColor = playerController.getPlayerColor(); + if (playerColor.has_value()) + return *playerColor; + } return teamColorCalculator.getTeamColor(); } - PlayerColorCalculator playerColorCalculator; TeamColorCalculator teamColorCalculator; }; -template -PlayerPositionArrowColorCalculator(PlayerColorCalculator, TeamColorCalculator) -> - PlayerPositionArrowColorCalculator; +template +PlayerPositionArrowColorCalculator(TeamColorCalculator) -> + PlayerPositionArrowColorCalculator; diff --git a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlow.h b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlow.h index b289364c2a3..8b42a756387 100644 --- a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlow.h +++ b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlow.h @@ -5,6 +5,7 @@ #include #include #include "PlayerOutlineGlowContext.h" +#include "PlayerOutlineGlowColorType.h" template class PlayerOutlineGlow { @@ -44,6 +45,11 @@ class PlayerOutlineGlow { [[nodiscard]] cs2::Color getColor(auto&& playerPawn) const noexcept { + if (context.state().colorType == PlayerOutlineGlowColorType::PlayerOrTeamColor) { + if (const auto playerColor = playerPawn.playerController().getPlayerColor(); playerColor.has_value()) + return *playerColor; + } + switch (playerPawn.teamNumber()) { case TeamNumber::TT: return cs2::kColorTeamTT; case TeamNumber::CT: return cs2::kColorTeamCT; diff --git a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowColorType.h b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowColorType.h new file mode 100644 index 00000000000..979fd945c1f --- /dev/null +++ b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowColorType.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +enum class PlayerOutlineGlowColorType : std::uint8_t { + PlayerOrTeamColor, + TeamColor +}; diff --git a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowContext.h b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowContext.h index 5fae879172c..ea4fc60f0f4 100644 --- a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowContext.h +++ b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowContext.h @@ -38,7 +38,7 @@ class PlayerOutlineGlowContext { [[nodiscard]] bool isLocalPlayerAlive() const noexcept { - return hookContext.localPlayerController2().playerPawn().isAlive().value_or(true); + return hookContext.localPlayerController().playerPawn().isAlive().value_or(true); } private: diff --git a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowState.h b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowState.h index d5bbdfcf44b..256d81cdb2d 100644 --- a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowState.h +++ b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowState.h @@ -1,6 +1,9 @@ #pragma once +#include "PlayerOutlineGlowColorType.h" + struct PlayerOutlineGlowState { bool enabled{false}; bool showOnlyEnemies{false}; + PlayerOutlineGlowColorType colorType{PlayerOutlineGlowColorType::PlayerOrTeamColor}; }; diff --git a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowToggle.h b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowToggle.h index 17b42b89983..bb2240da2f3 100644 --- a/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowToggle.h +++ b/Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlowToggle.h @@ -1,6 +1,7 @@ #pragma once #include +#include "PlayerOutlineGlowColorType.h" template struct PlayerOutlineGlowToggle : FeatureToggleOnOff> { @@ -19,6 +20,14 @@ struct PlayerOutlineGlowToggle : FeatureToggleOnOff(static_cast(hookContext.template getDependency().getEntityFromHandle(*playerPawnHandle))); } + [[nodiscard]] std::optional getPlayerColor() const noexcept + { + const auto playerColorIndex = hookContext.gameDependencies().playerControllerDeps.offsetToPlayerColor.of(playerControllerPointer).get(); + if (playerColorIndex && *playerColorIndex >= 0 && std::cmp_less(*playerColorIndex, cs2::kPlayerColors.size())) + return cs2::kPlayerColors[*playerColorIndex]; + return {}; + } + private: [[nodiscard]] const auto& entityDeps() const noexcept { diff --git a/Source/GameClasses/PlayerPawn.h b/Source/GameClasses/PlayerPawn.h index 92495b41c8d..db67cfae853 100644 --- a/Source/GameClasses/PlayerPawn.h +++ b/Source/GameClasses/PlayerPawn.h @@ -12,6 +12,9 @@ class EntityFromHandleFinder; +template +class PlayerController; + template class PlayerPawn { public: @@ -47,15 +50,15 @@ class PlayerPawn { return {}; } - [[nodiscard]] cs2::CCSPlayerController* playerController() const noexcept + [[nodiscard]] decltype(auto) playerController() const noexcept { if (!hookContext.template requestDependency()) - return nullptr; + return hookContext.template make(nullptr); const auto playerControllerHandle = hookContext.gameDependencies().playerPawnDeps.offsetToPlayerController.of(playerPawn).get(); if (!playerControllerHandle) - return nullptr; - return static_cast(hookContext.template getDependency().getEntityFromHandle(*playerControllerHandle)); + return hookContext.template make(nullptr); + return hookContext.template make(static_cast(hookContext.template getDependency().getEntityFromHandle(*playerControllerHandle))); } [[nodiscard]] std::optional health() const noexcept @@ -88,12 +91,12 @@ class PlayerPawn { [[nodiscard]] bool isControlledByLocalPlayer() const noexcept { - return playerController() && playerController() == hookContext.localPlayerController(); + return playerController() == hookContext.localPlayerController(); } [[nodiscard]] std::optional isEnemy() const noexcept { - return teamNumber() != hookContext.localPlayerController2().teamNumber() || teammatesAreEnemies(); + return teamNumber() != hookContext.localPlayerController().teamNumber() || teammatesAreEnemies(); } [[nodiscard]] bool isTTorCT() const noexcept diff --git a/Source/HookDependencies/HookDependencies.h b/Source/HookDependencies/HookDependencies.h index 8eb0d4bbad6..eed8f9772a7 100644 --- a/Source/HookDependencies/HookDependencies.h +++ b/Source/HookDependencies/HookDependencies.h @@ -114,14 +114,7 @@ struct HookDependencies { return Hud{HudContext{*this}}; } - [[nodiscard]] cs2::CCSPlayerController* localPlayerController() const noexcept - { - if (_gameDependencies.localPlayerController) - return *_gameDependencies.localPlayerController; - return nullptr; - } - - [[nodiscard]] auto localPlayerController2() noexcept + [[nodiscard]] auto localPlayerController() noexcept { if (_gameDependencies.localPlayerController) return PlayerController{*this, *_gameDependencies.localPlayerController}; diff --git a/Source/Osiris.vcxproj b/Source/Osiris.vcxproj index 50ed742ba1d..d704ab8eea9 100644 --- a/Source/Osiris.vcxproj +++ b/Source/Osiris.vcxproj @@ -169,8 +169,6 @@ - - @@ -178,6 +176,7 @@ + diff --git a/Source/Osiris.vcxproj.filters b/Source/Osiris.vcxproj.filters index 6024b3f3a2b..597540d69ad 100644 --- a/Source/Osiris.vcxproj.filters +++ b/Source/Osiris.vcxproj.filters @@ -908,12 +908,6 @@ Features\Visuals\PlayerInformationThroughWalls - - Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow - - - Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow - Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow @@ -1418,6 +1412,9 @@ GameClasses + + Features\Visuals\PlayerOutlineGlow + diff --git a/Source/UI/Panorama/CreateGUI.js b/Source/UI/Panorama/CreateGUI.js index 77009647bd7..57570f32ea1 100644 --- a/Source/UI/Panorama/CreateGUI.js +++ b/Source/UI/Panorama/CreateGUI.js @@ -225,8 +225,9 @@ $.Osiris = (function () { createYesNoDropDown(playerInfo, 'Show Blinded By Flashbang Icon', 'visuals', 'player_info_blinded', 0); var playerOutlineGlow = createSection(visuals, 'Player Outline Glow'); - $.CreatePanel('Panel', playerOutlineGlow, '', { class: "horizontal-separator" }); createDropDown(playerOutlineGlow, "Enabled", 'visuals', 'player_outline_glow', ['Enemies', 'All Players', 'Off'], 2); + $.CreatePanel('Panel', playerOutlineGlow, '', { class: "horizontal-separator" }); + createDropDown(playerOutlineGlow, "Player Outline Glow Color", 'visuals', 'player_outline_glow_color', ['Player / Team Color', 'Team Color'], 0); var sound = createTab('sound'); diff --git a/Source/UI/Panorama/SetCommandHandler.h b/Source/UI/Panorama/SetCommandHandler.h index 0dd23b20314..51f5c87ad9f 100644 --- a/Source/UI/Panorama/SetCommandHandler.h +++ b/Source/UI/Panorama/SetCommandHandler.h @@ -79,6 +79,8 @@ struct SetCommandHandler { handleFeature(features.visualFeatures().blindedIconToggle()); } else if (feature == "player_outline_glow") { handleFeature(features.visualFeatures().playerOutlineGlowToggle()); + } else if (feature == "player_outline_glow_color") { + features.visualFeatures().playerOutlineGlowToggle().updateColor(parser.getChar()); } }