Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsPlayerCashPlayback.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <memory>
5#include <utility>
6
7namespace monopoly::statsui
8{
9 namespace
10 {
11 [[nodiscard]] constexpr bool bssmMode(ibar::RuleMode mode) noexcept
12 {
13 return mode == ibar::RuleMode::Build ||
14 mode == ibar::RuleMode::Sell ||
17 }
18
19 [[nodiscard]] constexpr int playerBoxWidth(
20 std::size_t playerCount) noexcept
21 {
22 return playerCount > 4 ? 130 : 198;
23 }
24
26 {
27 return data::packDataId(
29 }
30 [[nodiscard]] std::expected<std::vector<PlayerCashPlayback::Published>,
31 std::string> desiredCash(
32 const State& state,
33 const rules::GameState& gameState,
34 const PlayerPlaybackInputs& inputs)
35 {
36 std::vector<PlayerCashPlayback::Published> result;
37 const auto count = std::min<std::size_t>(
38 state.playerCount,
39 std::min<std::size_t>(gameState.numberOfPlayers,
41 const int boxWidth = playerBoxWidth(count);
42 const bool localBssm = bssmMode(inputs.mode) &&
43 inputs.iBarPlayerLocalHuman;
44
45 int boxGapOffset = 3;
46 for (std::size_t column = 0; column < count; ++column)
47 {
48 const auto player = state.playerOrder[column];
49 if (player >= gameState.numberOfPlayers ||
50 player >= rules::MaxPlayers)
51 {
52 return std::unexpected(
53 "UDStats Player cash references invalid player");
54 }
55 if (localBssm && player != inputs.iBarPlayer)
56 continue;
57 result.push_back({
58 static_cast<int>(column) * boxWidth + boxGapOffset +
60 224 + PlayerCashLocalY});
61 boxGapOffset += 3;
62 }
63 return result;
64 }
65 }
66
67 std::expected<void, std::string> PlayerCashPlayback::sync(
68 const State& state,
73 {
74 std::vector<Published> desired;
76 state.screen == Screen::Player)
77 {
79 if (!planned) return std::unexpected(planned.error());
80 desired = std::move(*planned);
81 }
82
83 if (desired == current_) return {};
84 std::shared_ptr<const sequence::SequenceProgram> program;
85 if (!desired.empty())
86 {
88 playback.resources(), cashIconId());
89 if (!loaded)
90 {
91 return std::unexpected(
92 "UDStats Player cash icon failed: " + loaded.error().detail);
93 }
94 program = std::move(*loaded);
95 }
96
97 const std::size_t required =
98 (current_.empty() ? 0U : 1U) + desired.size();
100 playback.commands().pendingCount())
101 {
102 return std::unexpected(
103 "sequence command queue cannot fit UDStats Player cash transition");
104 }
105
106 if (!current_.empty() &&
107 !playback.commands().enqueue(sequence::StopSequenceCommand{
108 cashIconId(), PlayerCashPriority, false}))
109 {
110 return std::unexpected(
111 "validated UDStats Player cash stop rejected");
112 }
113 for (const auto& object : desired)
114 {
115 if (!playback.commands().enqueue(sequence::StartSequenceCommand{
116 program, PlayerCashPriority, {},
117 sequence::moveXYTransform(object.x, object.y)}))
118 {
119 return std::unexpected(
120 "validated UDStats Player cash start rejected");
121 }
122 }
123
124 current_ = std::move(desired);
125 return {};
126 }
127}
std::size_t count
unsigned state
unsigned index
int boxWidth
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > load(const data::DataSource &source, data::DataId id, std::size_t offset=0, DescriptionLimits limits={})
std::expected< void, std::string > sync(const State &state, const rules::GameState &gameState, const PlayerPlaybackInputs &inputs, display::Screen2D desiredView, engine::SequencePlayback &playback)
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
Definition DataBanks.hpp:39
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
constexpr data::DataTag PlayerCashIconTag
constexpr std::uint16_t PlayerCashPriority