Skip to content

Commit

Permalink
Implement player outline glow color based on player color
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkrupinski committed Sep 2, 2024
1 parent b50293c commit cce103a
Show file tree
Hide file tree
Showing 17 changed files with 74 additions and 94 deletions.
2 changes: 1 addition & 1 deletion Source/Features/Hud/PostRoundTimer/PostRoundTimerContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct PostRoundTimerContext {

[[nodiscard]] decltype(auto) localPlayerTeamNumber() const noexcept
{
return _hookContext.localPlayerController2().teamNumber();
return _hookContext.localPlayerController().teamNumber();
}

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include <Utils/ColorUtils.h>
#include <Utils/CString.h>

#include "PlayerPositionArrow/PlayerColorCalculator.h"
#include "PlayerPositionArrow/PlayerColorIndexAccessor.h"
#include "PlayerInformationPanel.h"
#include "PlayerPositionArrow/PlayerPositionArrowColorCalculator.h"
#include "PlayerPositionArrow/TeamColorCalculator.h"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -304,25 +298,20 @@ class PlayerInformationThroughWalls {
&& (!state.showOnlyEnemies || playerPawn.isEnemy().value_or(true));
}

[[nodiscard]] PlayerColorCalculator<PlayerColorIndexAccessor> 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);
return;
}

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
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@

#include "PlayerPositionArrowColorType.h"

template <typename PlayerColorCalculator, typename TeamColorCalculator>
template <typename TeamColorCalculator>
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 <typename PlayerColorCalculator, typename TeamColorCalculator>
PlayerPositionArrowColorCalculator(PlayerColorCalculator, TeamColorCalculator) ->
PlayerPositionArrowColorCalculator<PlayerColorCalculator, TeamColorCalculator>;
template <typename TeamColorCalculator>
PlayerPositionArrowColorCalculator(TeamColorCalculator) ->
PlayerPositionArrowColorCalculator<TeamColorCalculator>;
6 changes: 6 additions & 0 deletions Source/Features/Visuals/PlayerOutlineGlow/PlayerOutlineGlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <CS2/Constants/ColorConstants.h>
#include <FeatureHelpers/TeamNumber.h>
#include "PlayerOutlineGlowContext.h"
#include "PlayerOutlineGlowColorType.h"

template <typename Context>
class PlayerOutlineGlow {
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <cstdint>

enum class PlayerOutlineGlowColorType : std::uint8_t {
PlayerOrTeamColor,
TeamColor
};
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include "PlayerOutlineGlowColorType.h"

struct PlayerOutlineGlowState {
bool enabled{false};
bool showOnlyEnemies{false};
PlayerOutlineGlowColorType colorType{PlayerOutlineGlowColorType::PlayerOrTeamColor};
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <FeatureHelpers/FeatureToggle.h>
#include "PlayerOutlineGlowColorType.h"

template <typename Context>
struct PlayerOutlineGlowToggle : FeatureToggleOnOff<PlayerOutlineGlowToggle<Context>> {
Expand All @@ -19,6 +20,14 @@ struct PlayerOutlineGlowToggle : FeatureToggleOnOff<PlayerOutlineGlowToggle<Cont
}
}

void updateColor(char option) noexcept
{
switch (option) {
case '0': context.state().colorType = PlayerOutlineGlowColorType::PlayerOrTeamColor; break;
case '1': context.state().colorType = PlayerOutlineGlowColorType::TeamColor; break;
}
}

[[nodiscard]] auto& enabledVariable(typename PlayerOutlineGlowToggle::ToggleMethod) const noexcept
{
return context.state().enabled;
Expand Down
13 changes: 13 additions & 0 deletions Source/GameClasses/PlayerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class PlayerController {
{
}

[[nodiscard]] bool operator==(const PlayerController& other) const noexcept
{
return playerControllerPointer != nullptr && playerControllerPointer == other.playerControllerPointer;
}

[[nodiscard]] TeamNumber teamNumber() const noexcept
{
return TeamNumber{entityDeps().offsetToTeamNumber.of(playerControllerPointer).valueOr({})};
Expand All @@ -29,6 +34,14 @@ class PlayerController {
return hookContext.template make<PlayerPawn>(static_cast<cs2::C_CSPlayerPawn*>(hookContext.template getDependency<EntityFromHandleFinder>().getEntityFromHandle(*playerPawnHandle)));
}

[[nodiscard]] std::optional<cs2::Color> 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
{
Expand Down
15 changes: 9 additions & 6 deletions Source/GameClasses/PlayerPawn.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

class EntityFromHandleFinder;

template <typename HookContext>
class PlayerController;

template <typename HookContext>
class PlayerPawn {
public:
Expand Down Expand Up @@ -47,15 +50,15 @@ class PlayerPawn {
return {};
}

[[nodiscard]] cs2::CCSPlayerController* playerController() const noexcept
[[nodiscard]] decltype(auto) playerController() const noexcept
{
if (!hookContext.template requestDependency<EntityFromHandleFinder>())
return nullptr;
return hookContext.template make<PlayerController>(nullptr);

const auto playerControllerHandle = hookContext.gameDependencies().playerPawnDeps.offsetToPlayerController.of(playerPawn).get();
if (!playerControllerHandle)
return nullptr;
return static_cast<cs2::CCSPlayerController*>(hookContext.template getDependency<EntityFromHandleFinder>().getEntityFromHandle(*playerControllerHandle));
return hookContext.template make<PlayerController>(nullptr);
return hookContext.template make<PlayerController>(static_cast<cs2::CCSPlayerController*>(hookContext.template getDependency<EntityFromHandleFinder>().getEntityFromHandle(*playerControllerHandle)));
}

[[nodiscard]] std::optional<int> health() const noexcept
Expand Down Expand Up @@ -88,12 +91,12 @@ class PlayerPawn {

[[nodiscard]] bool isControlledByLocalPlayer() const noexcept
{
return playerController() && playerController() == hookContext.localPlayerController();
return playerController() == hookContext.localPlayerController();
}

[[nodiscard]] std::optional<bool> isEnemy() const noexcept
{
return teamNumber() != hookContext.localPlayerController2().teamNumber() || teammatesAreEnemies();
return teamNumber() != hookContext.localPlayerController().teamNumber() || teammatesAreEnemies();
}

[[nodiscard]] bool isTTorCT() const noexcept
Expand Down
9 changes: 1 addition & 8 deletions Source/HookDependencies/HookDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
3 changes: 1 addition & 2 deletions Source/Osiris.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,14 @@
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerInformationThroughWalls.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerInformationThroughWallsPanelFactory.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerInformationThroughWallsState.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerColorCalculator.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerColorIndexAccessor.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerPositionArrowColorCalculator.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerPositionArrowColorType.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerPositionArrowPanelParams.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\TeamColorCalculator.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerStateIcons\PlayerStateIconsPanelParams.h" />
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerStateIcons\PlayerStateIconsToShow.h" />
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlow.h" />
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlowColorType.h" />
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlowCondition.h" />
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlowContext.h" />
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlowState.h" />
Expand Down
9 changes: 3 additions & 6 deletions Source/Osiris.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -908,12 +908,6 @@
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerInformationThroughWallsState.h">
<Filter>Features\Visuals\PlayerInformationThroughWalls</Filter>
</ClInclude>
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerColorCalculator.h">
<Filter>Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow</Filter>
</ClInclude>
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerColorIndexAccessor.h">
<Filter>Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow</Filter>
</ClInclude>
<ClInclude Include="Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow\PlayerPositionArrowColorCalculator.h">
<Filter>Features\Visuals\PlayerInformationThroughWalls\PlayerPositionArrow</Filter>
</ClInclude>
Expand Down Expand Up @@ -1418,6 +1412,9 @@
<ClInclude Include="GameClasses\PlayerWeapons.h">
<Filter>GameClasses</Filter>
</ClInclude>
<ClInclude Include="Features\Visuals\PlayerOutlineGlow\PlayerOutlineGlowColorType.h">
<Filter>Features\Visuals\PlayerOutlineGlow</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="UI\Panorama\CreateGUI.js">
Expand Down
3 changes: 2 additions & 1 deletion Source/UI/Panorama/CreateGUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down
2 changes: 2 additions & 0 deletions Source/UI/Panorama/SetCommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down

0 comments on commit cce103a

Please sign in to comment.