Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
ChatRecipientPlayback.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <map>
5#include <memory>
6#include <set>
7#include <utility>
8
9namespace monopoly::chat
10{
11 namespace
12 {
13 [[nodiscard]] constexpr data::DataId mainId(data::DataTag tag) noexcept
14 {
16 }
17
18 using Objects = std::vector<RecipientPlayback::Published>;
19
21 const State& state,
22 const rules::GameState& gameState)
23 {
24 Objects result;
25 if (!state.boxActive) return result;
26
27 result.push_back({mainId(ChatAllTag), ChatBarPriority,
28 state.windowX + state.windowWidth - 73, state.windowY + 2});
29 std::size_t ordinal{};
30 const auto playerCount = std::min<std::size_t>(
31 gameState.numberOfPlayers, rules::MaxPlayers);
32 for (int player = static_cast<int>(playerCount) - 1;
33 player >= 0; --player)
34 {
35 const auto bit = 1u << static_cast<unsigned>(player);
36 if ((state.eligibleRecipients & bit) == 0u) continue;
37
38 const auto colour = gameState.players[static_cast<std::size_t>(player)].colour;
39 if (colour >= rules::MaxPlayerColours) continue;
40
41 const int baseX = state.windowX + state.windowWidth -
42 (static_cast<int>(ordinal) + 5) * 19 + 3;
43 result.push_back({mainId(static_cast<data::DataTag>(
45 baseX, state.windowY + 3});
46 if ((state.recipientMask & bit) != 0u)
47 {
48 result.push_back({mainId(static_cast<data::DataTag>(
50 baseX + 4, state.windowY + 5});
51 }
52 ++ordinal;
53 }
54 return result;
55 }
56 }
57 std::expected<void, std::string> RecipientPlayback::sync(
58 const State& state,
61 {
63 if (desired == current_) return {};
64
65 std::map<data::DataId,
66 std::shared_ptr<const sequence::SequenceProgram>> programs;
67 for (const auto& object : desired)
68 {
69 if (programs.contains(object.id)) continue;
71 playback.resources(), object.id);
72 if (!loaded)
73 return std::unexpected(
74 "UDChat recipient resource failed: " + loaded.error().detail);
75 programs.emplace(object.id, std::move(*loaded));
76 }
77
78 std::set<std::pair<data::DataId, std::uint16_t>> stops;
79 for (const auto& object : current_)
80 stops.emplace(object.id, object.priority);
81 const std::size_t required = stops.size() + desired.size();
83 playback.commands().pendingCount())
84 {
85 return std::unexpected(
86 "sequence command queue cannot fit UDChat recipient transition");
87 }
88
89 for (const auto& [id, priority] : stops)
90 {
91 if (!playback.commands().enqueue(
93 return std::unexpected("validated UDChat recipient stop rejected");
94 }
95 for (const auto& object : desired)
96 {
97 if (!playback.commands().enqueue(sequence::StartSequenceCommand{
98 programs.at(object.id), object.priority, {},
99 sequence::moveXYTransform(object.x, object.y)}))
100 return std::unexpected("validated UDChat recipient start rejected");
101 }
102
103 current_ = std::move(desired);
104 return {};
105 }
106}
data::DataId id
std::uint16_t priority
unsigned state
unsigned index
int colour
std::expected< void, std::string > sync(const State &state, const rules::GameState &gameState, engine::SequencePlayback &playback)
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > load(const data::DataSource &source, data::DataId id, std::size_t offset=0, DescriptionLimits limits={})
constexpr std::uint16_t ChatBarPriority
constexpr data::DataTag ChatAllTag
constexpr data::DataTag ChatPlayerColourBaseTag
constexpr data::DataTag ChatPlayerFocusBaseTag
std::uint32_t DataId
Definition DataBanks.hpp:10
std::uint16_t DataTag
Definition DataBanks.hpp:11
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
Definition DataBanks.hpp:39
constexpr std::size_t MaxPlayerColours
Definition RuleTypes.hpp:33
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept