VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
ScreenManager.cpp
Go to the documentation of this file.
1#include "Ui/LayoutPath.hpp"
2#include "Ui/ScreenEntity.hpp"
3
7#include <format>
8#include <string>
9#include <string_view>
10#include <utility>
11
12namespace VoltMod
13{
14
17 : Pressed({.OnFirst = [this] { return ListenForPresses(); }, .OnLast = [this] { _host.Reset(); }}),
18 _entities(entities),
19 _bindings(bindings),
20 _slots(slots),
21 _visibility(visibility),
22 _connect(std::move(connect))
23{}
24
25bool ScreenManager::ListenForPresses()
26{
27 if (!_bindings.FilterMessage || !_bindings.ClientMessageFilter)
28 {
29 Log::Warn("Screens: the FilterMessage bindings are missing; button presses will not arrive.");
30 return false;
31 }
32 _host = _connect(*this);
33 return true;
34}
35
36void ScreenManager::OnPress(int slot, std::string_view buttonId)
37{
38 Pressed.Raise({.Slot = slot, .ButtonId = std::string(buttonId)});
39}
40
42{
43 return Create(layout, EveryoneSlot);
44}
45
47{
48 if (!IsValidSlot(slot))
49 {
50 return std::unexpected(Error::Invalid(std::format("slot {} is not a player slot", slot)));
51 }
52
53 if (auto visible = _visibility.Available(); !visible)
54 {
55 return std::unexpected(
56 Error::Unsupported(std::format("a player screen needs the Visibility filter: {}", visible.error().Detail)));
57 }
58
59 return Create(layout, slot);
60}
61
63{
64 const std::pair<bool, std::string_view> needed[] = {
65 {static_cast<bool>(_bindings.CustomHudSetHasClass), "CCSCustomHudLayout::SetHasClass"},
66 {static_cast<bool>(_bindings.CustomHudSetHasClassForPlayer), "CCSCustomHudLayout::SetHasClassForPlayer"},
67 {static_cast<bool>(_bindings.CustomHudSetDialogVariable), "CCSCustomHudLayout::SetDialogVariableString"},
68 {static_cast<bool>(_bindings.CustomHudSetDialogVariableForPlayer),
69 "CCSCustomHudLayout::SetDialogVariableStringForPlayer"},
70 {static_cast<bool>(_bindings.CustomHudSetInputCapture), "CCSCustomHudLayout::SetInputCaptureEnabled"},
71 {static_cast<bool>(_bindings.FilterMessage), "INetworkMessageProcessingPreFilter::FilterMessage"},
72 {static_cast<bool>(_bindings.ClientMessageFilter), "CServerSideClient::INetworkMessageProcessingPreFilter"},
73 {static_cast<bool>(_bindings.ClientSlot), "CServerSideClientBase::m_nClientSlot"},
74 };
75 for (const auto& [bound, key] : needed)
76 {
77 if (!bound)
78 {
79 return std::unexpected(Error::Unsupported(std::format("gamedata '{}' did not bind", key)));
80 }
81 }
82 return _visibility.Available();
83}
84
85Result<Screen> ScreenManager::Create(std::string_view layout, int owner)
86{
87 auto path = LayoutPath::Parse(layout);
88 if (!path)
89 {
90 return std::unexpected(path.error());
91 }
92
93 return Screen(std::make_unique<ScreenEntity>(_entities, _slots, _visibility, std::move(*path), owner));
94}
95
96} // namespace VoltMod
runtime.Entities: finds and creates entities. Everything it returns is valid for this frame only; see...
static Result< LayoutPath > Parse(std::string_view layout)
Result< Screen > Shared(std::string_view layout)
Event< const ButtonPress & > Pressed
Result< Screen > ForPlayer(std::string_view layout, int slot)
void OnPress(int slot, std::string_view buttonId)
std::function< Subscription(ScreenManager &)> Connector
ScreenManager(EntitySystem &entities, const Bindings &bindings, SlotEvents &slots, Visibility &visibility, Connector connect)
"The occupant of this slot changed" - raised by PlayerManager, consumed below it.
Which clients receive which entities, filtered after CheckTransmit.
Status Available() const
void Warn(std::format_string< Args... > fmt, Args &&... args)
Definition Log.hpp:88
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56
constexpr bool IsValidSlot(int slot)
Definition Slot.hpp:13
std::expected< void, Error > Status
Definition Result.hpp:67
constexpr int EveryoneSlot
Definition Slot.hpp:10
std::expected< T, Error > Result
Definition Result.hpp:64
Fn< void(void *, int32_t, bool)> CustomHudSetInputCapture
Definition Bindings.hpp:61
Fn< void(void *, int32_t, const CUtlString *, const CUtlString *, int32_t)> CustomHudSetHasClassForPlayer
Definition Bindings.hpp:57
VirtualFn< bool(INetworkMessageProcessingPreFilter *, const CNetMessage *, INetChannel *)> FilterMessage
Definition Bindings.hpp:65
Fn< void(void *, const CUtlString *, const CUtlString *, int32_t)> CustomHudSetHasClass
Definition Bindings.hpp:56
Offset< int > ClientSlot
Definition Bindings.hpp:97
Offset< void > ClientMessageFilter
Definition Bindings.hpp:101
Fn< void(void *, const CUtlString *, const CUtlString *, const CUtlString *)> CustomHudSetDialogVariable
Definition Bindings.hpp:58
Fn< void(void *, int32_t, const CUtlString *, const CUtlString *, const CUtlString *)> CustomHudSetDialogVariableForPlayer
Definition Bindings.hpp:60
static Error Invalid(std::string detail)
Definition Result.hpp:51
static Error Unsupported(std::string detail)
Definition Result.hpp:57