Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bomb defuse sound visualization #4191

Merged
merged 1 commit into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Source/CS2/Constants/SoundNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ constexpr std::string_view kBombSoundsPath = "sounds/weapons/c4/";

constexpr std::string_view kPlayerSuitSoundPrefix = "suit";
constexpr std::string_view kBombBeepSoundsPrefix = "c4_beep";
constexpr std::string_view kBombDefuseStartSoundName = "c4_disarmstart.vsnd";

}
6 changes: 6 additions & 0 deletions Source/FeatureHelpers/FeatureHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
#include "Hud/DefusingAlertHelpers.h"
#include "Hud/KillfeedPreserverHelpers.h"
#include "Sound/BombBeepVisualizerHelpers.h"
#include "Sound/BombDefuseVisualizerHelpers.h"
#include "Sound/BombPlantVisualizerHelpers.h"
#include "Sound/FootstepVisualizerHelpers.h"
#include "WorldToClipSpaceConverter.h"

struct FeatureHelpers {
[[nodiscard]] BombDefuseVisualizerHelpers getBombDefuseVisualizerHelpers() noexcept
{
return BombDefuseVisualizerHelpers{ HudInWorldPanelFactory{hudInWorldPanelContainer, hudProvider}, globalVarsProvider, transformFactory, worldtoClipSpaceConverter };
}

[[nodiscard]] BombBeepVisualizerHelpers getBombBeepVisualizerHelpers() noexcept
{
return BombBeepVisualizerHelpers{ HudInWorldPanelFactory{hudInWorldPanelContainer, hudProvider}, globalVarsProvider, transformFactory, worldtoClipSpaceConverter };
Expand Down
3 changes: 2 additions & 1 deletion Source/FeatureHelpers/HudInWorldPanelZOrder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
enum class HudInWorldPanelZOrder {
Footstep,
BombBeep,
BombPlant
BombPlant,
BombDefuse
};
31 changes: 31 additions & 0 deletions Source/FeatureHelpers/Sound/BombDefuseSound.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <algorithm>
#include <cassert>
#include <string_view>

#include <CS2/Constants/SoundNames.h>

struct BombDefuseSound {
static constexpr auto kFadeAwayStart = 2.0f;
static constexpr auto kFadeAwayDuration = 1.0f;

[[nodiscard]] static constexpr float getScale(float clipSpaceZ) noexcept
{
return (std::max)(1.0f - clipSpaceZ / 1000.0f, 0.4f);
}

[[nodiscard]] static constexpr float getOpacity(float timeAlive) noexcept
{
if (timeAlive >= kFadeAwayStart) {
return 1.0f - (std::min)((timeAlive - kFadeAwayStart) / kFadeAwayDuration, 1.0f);
} else {
return 1.0f;
}
}

[[nodiscard]] static constexpr bool isSound(std::string_view soundName) noexcept
{
return soundName.starts_with(cs2::kBombSoundsPath) && std::string_view{ soundName.data() + cs2::kBombSoundsPath.length(), soundName.length() - cs2::kBombSoundsPath.length() }.starts_with(cs2::kBombDefuseStartSoundName);
}
};
13 changes: 13 additions & 0 deletions Source/FeatureHelpers/Sound/BombDefuseVisualizerHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <FeatureHelpers/GlobalVarsProvider.h>
#include <FeatureHelpers/HudInWorldPanelFactory.h>
#include <FeatureHelpers/WorldToClipSpaceConverter.h>
#include <Helpers/PanoramaTransformFactory.h>

struct BombDefuseVisualizerHelpers {
HudInWorldPanelFactory hudInWorldPanelFactory;
GlobalVarsProvider globalVarsProvider;
PanoramaTransformFactory transformFactory;
WorldToClipSpaceConverter worldtoClipSpaceConverter;
};
3 changes: 2 additions & 1 deletion Source/FeatureHelpers/Sound/SoundWatcher.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once

#include "BombBeepSound.h"
#include "BombDefuseSound.h"
#include "BombPlantSound.h"
#include "FootstepSound.h"
#include "SoundWatcherImpl.h"

using SoundWatcher = SoundWatcherImpl<FootstepSound, BombPlantSound, BombBeepSound>;
using SoundWatcher = SoundWatcherImpl<FootstepSound, BombPlantSound, BombBeepSound, BombDefuseSound>;
124 changes: 124 additions & 0 deletions Source/Features/Sound/BombDefuseVisualizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#pragma once

#include <CS2/Classes/Panorama.h>
#include <FeatureHelpers/HudInWorldPanels.h>
#include <FeatureHelpers/HudInWorldPanelFactory.h>
#include <FeatureHelpers/Sound/BombDefuseSound.h>
#include <FeatureHelpers/Sound/BombDefuseVisualizerHelpers.h>
#include <FeatureHelpers/Sound/SoundWatcher.h>
#include <FeatureHelpers/TogglableFeature.h>
#include <GameClasses/PanoramaUiEngine.h>
#include <Hooks/ViewRenderHook.h>

struct BombDefusePanels {
[[nodiscard]] static cs2::CPanel2D* createContainerPanel(const HudInWorldPanelFactory& inWorldFactory) noexcept
{
return inWorldFactory.createPanel("BombDefuseContainer", HudInWorldPanelZOrder::BombDefuse);
}

static void createContentPanels(cs2::CUIPanel& containerPanel) noexcept
{
for (std::size_t i = 0; i < kMaxNumberOfPanels; ++i) {
PanoramaUiEngine::runScript(&containerPanel,
R"(
(function() {
var bombDefusePanel = $.CreatePanel('Panel', $.GetContextPanel().FindChildInLayoutFile("BombDefuseContainer"), '', {
style: 'width: 100px; height: 100px; x: -50px; y: -50px;'
});

$.CreatePanel('Image', bombDefusePanel, '', {
src: "s2r://panorama/images/icons/equipment/defuser.vsvg",
style: "horizontal-align: center; vertical-align: center; img-shadow: 0px 0px 1px 3 #000000;",
textureheight: "40"
});
})();)", "", 0);
}
}

static constexpr auto kMaxNumberOfPanels = 5;
};

class BombDefuseVisualizer : public TogglableFeature<BombDefuseVisualizer> {
public:
explicit BombDefuseVisualizer(ViewRenderHook& viewRenderHook, SoundWatcher& soundWatcher) noexcept
: viewRenderHook{ viewRenderHook }
, soundWatcher{ soundWatcher }
{
}

void run(const BombDefuseVisualizerHelpers& params) noexcept
{
if (!isEnabled())
return;

if (!params.globalVarsProvider || !params.globalVarsProvider.getGlobalVars())
return;

if (!params.worldtoClipSpaceConverter)
return;

panels.createPanels(params.hudInWorldPanelFactory);

std::size_t currentIndex = 0;
std::as_const(soundWatcher).getSoundsOfType<BombDefuseSound>().forEach([this, &currentIndex, params](const PlayedSound& sound) {
const auto soundInClipSpace = params.worldtoClipSpaceConverter.toClipSpace(sound.origin);
if (!soundInClipSpace.onScreen())
return;

const auto opacity = BombDefuseSound::getOpacity(sound.getTimeAlive(params.globalVarsProvider.getGlobalVars()->curtime));
if (opacity <= 0.0f)
return;

const auto panel = panels.getPanel(currentIndex);
if (!panel)
return;

const auto style = panel.getStyle();
if (!style)
return;

style.setOpacity(opacity);
style.setZIndex(-soundInClipSpace.z);

const auto deviceCoordinates = soundInClipSpace.toNormalizedDeviceCoordinates();
cs2::CTransform3D* transformations[]{ params.transformFactory.create<cs2::CTransformScale3D>(
BombDefuseSound::getScale(soundInClipSpace.z), BombDefuseSound::getScale(soundInClipSpace.z), 1.0f
), params.transformFactory.create<cs2::CTransformTranslate3D>(
deviceCoordinates.getX(),
deviceCoordinates.getY(),
cs2::CUILength{ 0.0f, cs2::CUILength::k_EUILengthLength }
) };

cs2::CUtlVector<cs2::CTransform3D*> dummyVector;
dummyVector.allocationCount = 2;
dummyVector.memory = transformations;
dummyVector.growSize = 0;
dummyVector.size = 2;

style.setTransform3D(dummyVector);
++currentIndex;
});

panels.hidePanels(currentIndex);
}

private:
friend TogglableFeature;

void onEnable() noexcept
{
viewRenderHook.incrementReferenceCount();
soundWatcher.startWatching<BombDefuseSound>();
}

void onDisable() noexcept
{
viewRenderHook.decrementReferenceCount();
soundWatcher.stopWatching<BombDefuseSound>();
panels.hidePanels(0);
}

HudInWorldPanels<BombDefusePanels> panels;
ViewRenderHook& viewRenderHook;
SoundWatcher& soundWatcher;
};
3 changes: 3 additions & 0 deletions Source/Features/Sound/SoundFeatures.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "BombBeepVisualizer.h"
#include "BombDefuseVisualizer.h"
#include "BombPlantVisualizer.h"
#include "FootstepVisualizer.h"
#include <Helpers/HudProvider.h>
Expand All @@ -11,10 +12,12 @@ struct SoundFeatures {
: footstepVisualizer{ viewRenderHook, soundWatcher }
, bombPlantVisualizer{ viewRenderHook, soundWatcher }
, bombBeepVisualizer{ viewRenderHook, soundWatcher }
, bombDefuseVisualizer{ viewRenderHook, soundWatcher }
{
}

FootstepVisualizer footstepVisualizer;
BombPlantVisualizer bombPlantVisualizer;
BombBeepVisualizer bombBeepVisualizer;
BombDefuseVisualizer bombDefuseVisualizer;
};
1 change: 1 addition & 0 deletions Source/GlobalContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct GlobalContext {
features->soundFeatures.footstepVisualizer.run(featureHelpers->getFootstepVisualizerHelpers());
features->soundFeatures.bombPlantVisualizer.run(featureHelpers->getBombPlantVisualizerHelpers());
features->soundFeatures.bombBeepVisualizer.run(featureHelpers->getBombBeepVisualizerHelpers());
features->soundFeatures.bombDefuseVisualizer.run(featureHelpers->getBombDefuseVisualizerHelpers());
}

private:
Expand Down
3 changes: 3 additions & 0 deletions Source/Osiris.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
<ClInclude Include="FeatureHelpers\NormalizedDeviceCoordinates.h" />
<ClInclude Include="FeatureHelpers\Sound\BombBeepSound.h" />
<ClInclude Include="FeatureHelpers\Sound\BombBeepVisualizerHelpers.h" />
<ClInclude Include="FeatureHelpers\Sound\BombDefuseSound.h" />
<ClInclude Include="FeatureHelpers\Sound\BombDefuseVisualizerHelpers.h" />
<ClInclude Include="FeatureHelpers\Sound\BombPlantSound.h" />
<ClInclude Include="FeatureHelpers\Sound\BombPlantVisualizerHelpers.h" />
<ClInclude Include="FeatureHelpers\Sound\FootstepSound.h" />
Expand All @@ -63,6 +65,7 @@
<ClInclude Include="Features\Hud\HudFeatures.h" />
<ClInclude Include="Features\Hud\KillfeedPreserver.h" />
<ClInclude Include="Features\Sound\BombBeepVisualizer.h" />
<ClInclude Include="Features\Sound\BombDefuseVisualizer.h" />
<ClInclude Include="Features\Sound\BombPlantVisualizer.h" />
<ClInclude Include="Features\Sound\FootstepVisualizer.h" />
<ClInclude Include="Features\Sound\SoundFeatures.h" />
Expand Down
9 changes: 9 additions & 0 deletions Source/Osiris.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,15 @@
<ClInclude Include="FeatureHelpers\HudInWorldPanels.h">
<Filter>FeatureHelpers</Filter>
</ClInclude>
<ClInclude Include="FeatureHelpers\Sound\BombDefuseSound.h">
<Filter>FeatureHelpers\Sound</Filter>
</ClInclude>
<ClInclude Include="FeatureHelpers\Sound\BombDefuseVisualizerHelpers.h">
<Filter>FeatureHelpers\Sound</Filter>
</ClInclude>
<ClInclude Include="Features\Sound\BombDefuseVisualizer.h">
<Filter>Features\Sound</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 @@ -206,6 +206,8 @@ $.Osiris = (function () {
createYesNoDropDown(visualization, "Visualize Bomb Plant", 'sound', 'visualize_bomb_plant');
$.CreatePanel('Panel', visualization, '', { class: "horizontal-separator" });
createYesNoDropDown(visualization, "Visualize Bomb Beep", 'sound', 'visualize_bomb_beep');
$.CreatePanel('Panel', visualization, '', { class: "horizontal-separator" });
createYesNoDropDown(visualization, "Visualize Bomb Defuse", 'sound', 'visualize_bomb_defuse');

$.Osiris.navigateToTab('hud');
})();
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 @@ -41,6 +41,8 @@ struct SetCommandHandler {
handleTogglableFeature(features.soundFeatures.bombPlantVisualizer);
} else if (feature == "visualize_bomb_beep") {
handleTogglableFeature(features.soundFeatures.bombBeepVisualizer);
} else if (feature == "visualize_bomb_defuse") {
handleTogglableFeature(features.soundFeatures.bombDefuseVisualizer);
}
}

Expand Down