Skip to content

Commit

Permalink
Implement bomb carrier icon in "Player Info in World" (#4346)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkrupinski authored Oct 2, 2024
1 parent 1691c70 commit 0669554
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ using PlayerDefuseIconToggle = PlayerStateIconToggle<DefuseIconPanel>;
using HostagePickupIconToggle = PlayerStateIconToggle<HostagePickupPanel>;
using HostageRescueIconToggle = PlayerStateIconToggle<HostageRescuePanel>;
using BlindedIconToggle = PlayerStateIconToggle<BlindedIconPanel>;
using BombIconToggle = PlayerStateIconToggle<BombIconPanel>;

template <typename HookContext>
struct PlayerInfoInWorldToggle : FeatureToggleOnOff<PlayerInfoInWorldToggle<HookContext>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class PlayerInfoInWorldPanelFactory {
createHostagePickupPanel(panel);
createHostageRescuePanel(panel);
createBlindedIconPanel(panel);
createBombIconPanel(panel);
}

void createPanel(std::type_identity<PlayerActiveWeaponIconPanel<HookContext>>, cs2::CUIPanel* containerPanel) const noexcept
Expand Down Expand Up @@ -175,6 +176,19 @@ class PlayerInfoInWorldPanelFactory {
uiPanel.setImageShadow(kShadowParams);
}

void createBombIconPanel(cs2::CUIPanel* containerPanel) const noexcept
{
using namespace player_state_icons_panel_params::bomb_icon_panel_params;

auto&& imagePanel = hookContext.panelFactory().createImagePanel(containerPanel);
imagePanel.setImageSvg(kImageUrl, kTextureHeight);

auto&& uiPanel = imagePanel.uiPanel();
uiPanel.setAlign(kAlignment);
uiPanel.setImageShadow(kShadowParams);
uiPanel.setWashColor(kWashColorCarryingC4);
}

void createHealthIconPanel(cs2::CUIPanel* containerPanel) const
{
using namespace player_health_panel_params::health_icon_panel_params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PlayerStateIconsPanel {
playerStateChildren[1].setVisible(context.state().playerStateIconsToShow.template has<HostagePickupPanel>() && playerPawn.isPickingUpHostage().valueOr(false));
playerStateChildren[2].setVisible(context.state().playerStateIconsToShow.template has<HostageRescuePanel>() && playerPawn.isRescuingHostage());
updateBlindedIconPanel(playerStateChildren[3], playerPawn);
playerStateChildren[4].setVisible(context.state().playerStateIconsToShow.template has<BombIconPanel>() && playerPawn.isCarryingC4());
}

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,20 @@ namespace player_state_icons_panel_params::blinded_icon_panel_params
.color{cs2::kColorBlack}
};
}

namespace player_state_icons_panel_params::bomb_icon_panel_params
{
static constexpr auto kImageUrl = "s2r://panorama/images/icons/equipment/c4.svg";
static constexpr auto kTextureHeight = 26;
static constexpr auto kAlignment = PanelAlignmentParams{
.verticalAlignment = cs2::k_EVerticalAlignmentCenter
};
static constexpr auto kWashColorCarryingC4 = cs2::Color{255, 255, 77};
static constexpr auto kShadowParams = PanelShadowParams{
.horizontalOffset{cs2::CUILength::pixels(0)},
.verticalOffset{cs2::CUILength::pixels(0)},
.blurRadius{cs2::CUILength::pixels(3)},
.strength = 3,
.color{cs2::kColorBlack}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ struct DefuseIconPanel;
struct HostagePickupPanel;
struct HostageRescuePanel;
struct BlindedIconPanel;
struct BombIconPanel;

using PlayerStateIconsToShow = TypeBitFlags<DefuseIconPanel, HostagePickupPanel, HostageRescuePanel, BlindedIconPanel>;
using PlayerStateIconsToShow = TypeBitFlags<DefuseIconPanel, HostagePickupPanel, HostageRescuePanel, BlindedIconPanel, BombIconPanel>;
5 changes: 5 additions & 0 deletions Source/Features/Visuals/VisualFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ struct VisualFeatures {
return BlindedIconToggle{states.playerInfoInWorldState.playerStateIconsToShow};
}

[[nodiscard]] BombIconToggle bombIconToggle() const noexcept
{
return BombIconToggle{states.playerInfoInWorldState.playerStateIconsToShow};
}

[[nodiscard]] decltype(auto) playerOutlineGlowToggle() const noexcept
{
return hookContext.template make<PlayerOutlineGlowToggle>();
Expand Down
9 changes: 9 additions & 0 deletions Source/GameClasses/BaseEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ class BaseEntity {
return hookContext.template make<T>(static_cast<typename T<HookContext>::RawType*>(entity));
}

template <typename EntityType>
[[nodiscard]] decltype(auto) cast() const noexcept
{
if (entity && entity->vmt && entity->vmt == hookContext.gameDependencies().entitiesVMTs.vmts[utils::typeIndex<typename EntityType::RawType, KnownEntityTypes>()]) {
return hookContext.template make<EntityType>(static_cast<typename EntityType::RawType*>(entity));
}
return hookContext.template make<EntityType>(nullptr);
}

[[nodiscard]] decltype(auto) renderComponent() const noexcept
{
return hookContext.template make<RenderComponent>(deps().offsetToRenderComponent.of(entity).valueOr(nullptr));
Expand Down
24 changes: 24 additions & 0 deletions Source/GameClasses/C4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <CS2/Classes/Entities/WeaponEntities.h>

template <typename HookContext>
class C4 {
public:
C4(HookContext& hookContext, cs2::C_C4* c4) noexcept
: hookContext{hookContext}
, c4{c4}
{
}

[[nodiscard]] explicit operator bool() const noexcept
{
return c4 != nullptr;
}

using RawType = cs2::C_C4;

private:
HookContext& hookContext;
cs2::C_C4* c4;
};
6 changes: 6 additions & 0 deletions Source/GameClasses/PlayerPawn.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Utils/ColorUtils.h>

#include "BaseEntity.h"
#include "C4.h"
#include "GameSceneNode.h"
#include "HostageServices.h"
#include "PlayerWeapons.h"
Expand Down Expand Up @@ -114,6 +115,11 @@ class PlayerPawn {
return hostageServices().hasCarriedHostage();
}

[[nodiscard]] bool isCarryingC4() const noexcept
{
return weapons().template has<C4<HookContext>>();
}

[[nodiscard]] float getRemainingFlashBangTime() const noexcept
{
const auto curTime = hookContext.globalVars().curtime();
Expand Down
15 changes: 15 additions & 0 deletions Source/GameClasses/PlayerWeapons.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ class PlayerWeapons {
{
}

template <typename WeaponType>
[[nodiscard]] bool has() const noexcept
{
if (!weaponHandles)
return false;

for (int i = 0; i < weaponHandles->size; ++i) {
auto&& weapon = hookContext.template make<BaseEntity>(static_cast<cs2::C_BaseEntity*>(hookContext.template make<EntitySystem>().getEntityFromHandle(weaponHandles->memory[i]))).template cast<WeaponType>();
if (weapon)
return true;
}
return false;
}


template <typename F>
void forEach(F f) const noexcept
{
Expand Down
2 changes: 1 addition & 1 deletion Source/GameClasses/WeaponServices.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class WeaponServices {

[[nodiscard]] decltype(auto) weapons() const noexcept
{
return hookContext.template make<PlayerWeapons>(deps().offsetToWeapons.of(weaponServices).valueOr(nullptr));
return hookContext.template make<PlayerWeapons>(deps().offsetToWeapons.of(weaponServices).get());
}

[[nodiscard]] auto getActiveWeapon() const noexcept
Expand Down
1 change: 1 addition & 0 deletions Source/Osiris.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
<ClInclude Include="FileUtils\FileSlice.h" />
<ClInclude Include="GameClasses\BaseEntity.h" />
<ClInclude Include="GameClasses\BaseWeapon.h" />
<ClInclude Include="GameClasses\C4.h" />
<ClInclude Include="GameClasses\ClientPanel.h" />
<ClInclude Include="GameClasses\EntitySystem.h" />
<ClInclude Include="GameClasses\GameSceneNode.h" />
Expand Down
3 changes: 3 additions & 0 deletions Source/Osiris.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,9 @@
<ClInclude Include="GameClasses\HostageServices.h">
<Filter>GameClasses</Filter>
</ClInclude>
<ClInclude Include="GameClasses\C4.h">
<Filter>GameClasses</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="UI\Panorama\CreateGUI.js">
Expand Down
2 changes: 2 additions & 0 deletions Source/UI/Panorama/CreateGUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ $.Osiris = (function () {
createYesNoDropDown(playerInfo, 'Show Rescuing Hostage Icon', 'visuals', 'player_info_hostage_rescue', 0);
$.CreatePanel('Panel', playerInfo, '', { class: "horizontal-separator" });
createYesNoDropDown(playerInfo, 'Show Blinded By Flashbang Icon', 'visuals', 'player_info_blinded', 0);
$.CreatePanel('Panel', playerInfo, '', { class: "horizontal-separator" });
createYesNoDropDown(playerInfo, 'Show Bomb Carrier Icon', 'visuals', 'player_info_bomb_carrier', 0);

var outlineGlowTab = createSubTab(visuals, 'outline_glow');

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 @@ -78,6 +78,8 @@ struct SetCommandHandler {
handleFeature(features.visualFeatures().hostageRescueIconToggle());
} else if (feature == "player_info_blinded") {
handleFeature(features.visualFeatures().blindedIconToggle());
} else if (feature == "player_info_bomb_carrier") {
handleFeature(features.visualFeatures().bombIconToggle());
} else if (feature == "player_outline_glow") {
handleFeature(features.visualFeatures().playerOutlineGlowToggle());
} else if (feature == "player_outline_glow_color") {
Expand Down

0 comments on commit 0669554

Please sign in to comment.