Skip to content

Commit

Permalink
Fix player bomb carrying / planting icon having its shadow cut
Browse files Browse the repository at this point in the history
Panorama has a bug which causes image shadow to be cut when wash-color style property is applied.
As a workaround, svg fill color is set instead of wash-color.
  • Loading branch information
danielkrupinski committed Nov 2, 2024
1 parent af1c049 commit 8c0a11c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 15 deletions.
13 changes: 13 additions & 0 deletions Source/CS2/Panorama/CImagePanel.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <cstdint>
#include <CS2/Classes/CUtlString.h>
#include <Utils/Pad.h>

Expand All @@ -8,11 +9,23 @@
namespace cs2
{

enum class SvgAttributeType {
FillColor = 0,

Count = 11
};

struct SvgAttribute {
std::byte value[4];
};

struct ImageProperties {
PAD(16);
int textureWidth;
int textureHeight;
float scale;
SvgAttribute svgAttributes[static_cast<std::size_t>(SvgAttributeType::Count)];
std::uint32_t presentSvgAttributes;
};

struct CImagePanel : CPanel2D {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class PlayerInfoInWorldPanelFactory {
createHostagePickupPanel(panel);
createHostageRescuePanel(panel);
createBlindedIconPanel(panel);
createBombIconPanel(panel);
createBombIconContainerPanel(panel);
}

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

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

auto&& containerPanel = hookContext.panelFactory().createPanel(parentPanel).uiPanel();
createBombIconPanel(containerPanel, kColorCarryingC4);
createBombIconPanel(containerPanel, kColorPlantingC4);
}

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

auto&& imagePanel = hookContext.panelFactory().createImagePanel(containerPanel);
imagePanel.setImageSvg(kImageUrl, kTextureHeight);
imagePanel.setImageSvg(SvgImageParams{.imageUrl = kImageUrl, .textureHeight = kTextureHeight, .fillColor = color});

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

void createHealthIconPanel(cs2::CUIPanel* containerPanel) const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,11 @@ class PlayerBombIconPanel {
}

context.panel().setVisible(true);
context.panel().setWashColor(getColor(playerPawn));
const auto shouldShowPlantingColor = context.shouldShowPlantingColor(playerPawn);
context.panel().children()[0].setVisible(!shouldShowPlantingColor);
context.panel().children()[1].setVisible(shouldShowPlantingColor);
}

private:
[[nodiscard]] auto getColor(auto&& playerPawn) const noexcept
{
using namespace player_state_icons_panel_params::bomb_icon_panel_params;
return context.shouldShowPlantingColor(playerPawn) ? kWashColorPlantingC4 : kWashColorCarryingC4;
}

Context context;
};
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ namespace player_state_icons_panel_params::bomb_icon_panel_params
static constexpr auto kAlignment = PanelAlignmentParams{
.verticalAlignment = cs2::k_EVerticalAlignmentCenter
};
static constexpr auto kWashColorCarryingC4 = cs2::Color{255, 255, 77};
static constexpr auto kWashColorPlantingC4 = cs2::Color{255, 193, 77};
static constexpr auto kColorCarryingC4 = cs2::Color{255, 255, 77};
static constexpr auto kColorPlantingC4 = cs2::Color{255, 193, 77};
static constexpr auto kShadowParams = PanelShadowParams{
.horizontalOffset{cs2::CUILength::pixels(0)},
.verticalOffset{cs2::CUILength::pixels(0)},
Expand Down
24 changes: 22 additions & 2 deletions Source/GameClasses/PanoramaImagePanel.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
#pragma once

#include <bit>
#include <optional>

#include <CS2/Panorama/CImagePanel.h>
#include <MemoryPatterns/PatternTypes/PanoramaImagePanelPatternTypes.h>

#include "PanoramaImagePanelContext.h"

struct SvgImageParams {
const char* imageUrl;
int textureHeight{-1};
std::optional<cs2::Color> fillColor;
};

template <typename Context>
struct PanoramaImagePanel {
explicit PanoramaImagePanel(Context context) noexcept
Expand Down Expand Up @@ -36,6 +45,11 @@ struct PanoramaImagePanel {
}

void setImageSvg(const char* imageUrl, int textureHeight = -1) const noexcept
{
setImageSvg(SvgImageParams{.imageUrl = imageUrl, .textureHeight = textureHeight});
}

void setImageSvg(const SvgImageParams& params) const noexcept
{
if (context.panel == nullptr)
return;
Expand All @@ -45,9 +59,15 @@ struct PanoramaImagePanel {
return;

properties->scale = context.uiPanel().getUiScaleFactor().valueOr(1.0f);
properties->textureHeight = textureHeight;
properties->textureHeight = params.textureHeight;

if (params.fillColor.has_value()) {
properties->svgAttributes[static_cast<std::size_t>(cs2::SvgAttributeType::FillColor)] = std::bit_cast<cs2::SvgAttribute>(*params.fillColor);
properties->presentSvgAttributes |= 1 << static_cast<std::size_t>(cs2::SvgAttributeType::FillColor);
}

if (context.hookContext.clientPatternSearchResults().template get<SetImageFunctionPointer>())
context.hookContext.clientPatternSearchResults().template get<SetImageFunctionPointer>()(context.panel, imageUrl, nullptr, properties);
context.hookContext.clientPatternSearchResults().template get<SetImageFunctionPointer>()(context.panel, params.imageUrl, nullptr, properties);
}

private:
Expand Down

0 comments on commit 8c0a11c

Please sign in to comment.