Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
TradeBackdropPlayback.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <memory>
5#include <utility>
6#include <variant>
7#include <vector>
8
9namespace monopoly::tradeui
10{
11 namespace
12 {
13 struct BackdropSpec
14 {
16 std::uint16_t priority{};
17 std::int32_t x{};
18 std::int32_t y{};
19 bool loop{};
20 };
21
22 using Specs = std::array<BackdropSpec, 11>;
23
24 [[nodiscard]] std::expected<data::DataId, std::string> colourRail(
25 const State& state,
26 const rules::GameState& gameState,
27 bool right)
28 {
29 const auto player = right ? state.playerB : state.playerA;
31 if (player >= rules::MaxPlayers)
32 return tradeBackdropSequence(static_cast<data::DataTag>(base + 6u));
33
34 const auto colour = gameState.players[player].colour;
35 if (colour > 5)
36 return std::unexpected("Trade colour rail player colour is out of range");
37
39 static_cast<data::DataTag>(base + colour));
40 }
41
42 [[nodiscard]] std::expected<Specs, std::string> desiredBackdrop(
43 const State& state,
44 const rules::GameState& gameState,
46 {
47 Specs specs{};
48 specs[0].priority = TradeBackdropPriority;
49 specs[1].priority = TradeDisplayBoardPriority;
50 specs[2].priority = TradeTurntablePriority;
51 specs[3].priority = TradeArrowPriority;
52 specs[4].priority = TradeDisplayPanelPriority;
53 specs[5].priority = TradeDisplayPanelPriority;
54 specs[6].priority = TradeColourRailPriority;
55 specs[7].priority = TradeColourRailPriority;
56 specs[8].priority = TradeCreateButtonPriority;
57 specs[9].priority = TradeFutureButtonPriority;
60 if (!tradeVisible)
61 return specs;
62
63 const auto leftRail = colourRail(state, gameState, false);
64 if (!leftRail) return std::unexpected(leftRail.error());
65 const auto rightRail = colourRail(state, gameState, true);
66 if (!rightRail) return std::unexpected(rightRail.error());
68 TradeBackdropPriority, 0, 0, false};
70 TradeDisplayBoardPriority, 0, 0, false};
72 TradeTurntablePriority, 1, 0, false};
74 TradeArrowPriority, 0, 0, false};
76 TradeDisplayPanelPriority, 0, 0, false};
78 TradeDisplayPanelPriority, 0, 0, false};
80 state.playerA >= rules::MaxPlayers ? 1 : 0, 0, false};
81 specs[7] = {*rightRail, TradeColourRailPriority, 0, 0, false};
82
83 if (gameState.options.futureRentTradingAllowed ||
84 gameState.options.immunitiesTradingAllowed)
86 TradeCreateButtonPriority, 0, 0, true};
87 if (gameState.options.futureRentTradingAllowed)
89 TradeFutureButtonPriority, 0, 0, true};
90 if (gameState.options.immunitiesTradingAllowed)
92 TradeImmunityButtonPriority, 0, 0, true};
93 return specs;
94 }
95 }
96
98 {
99 return static_cast<std::size_t>(std::count_if(
100 current_.begin(), current_.end(),
101 [](data::DataId id) { return id != data::EmptyDataId; }));
102 }
103
104 std::expected<void, std::string> BackdropPlayback::sync(
105 const State& state,
109 {
110 const auto desiredResult = desiredBackdrop(state, gameState, desiredView);
111 if (!desiredResult) return std::unexpected(desiredResult.error());
112 const auto& specs = *desiredResult;
113 std::array<std::shared_ptr<const sequence::SequenceProgram>, 11> programs{};
114 for (std::size_t index = 0; index < specs.size(); ++index)
115 {
116 if (specs[index].id == data::EmptyDataId ||
117 specs[index].id == current_[index])
118 continue;
120 playback.resources(), specs[index].id);
121 if (!loaded)
122 return std::unexpected(loaded.error().detail);
123 programs[index] = std::move(*loaded);
124 }
125
126 std::vector<sequence::SequenceCommand> commands;
127 for (std::size_t index = 0; index < specs.size(); ++index)
128 {
129 if (current_[index] == specs[index].id)
130 continue;
131 if (current_[index] != data::EmptyDataId)
132 commands.push_back(sequence::StopSequenceCommand{
133 current_[index], specs[index].priority, false});
134 }
135
136 for (std::size_t index = 0; index < specs.size(); ++index)
137 {
138 if (specs[index].id == data::EmptyDataId ||
139 current_[index] == specs[index].id)
140 continue;
141 commands.push_back(sequence::StartSequenceCommand{
143 commands.push_back(sequence::makeMoveXY(
145 specs[index].x, specs[index].y));
146 if (specs[index].loop)
149 TradeLoopToBeginning, false});
150 }
151
152 if (commands.size() > sequence::SequenceCommandQueue::Capacity -
153 playback.commands().pendingCount())
154 return std::unexpected(
155 "sequence command queue cannot fit Trade backdrop transition");
156
157 for (auto& command : commands)
158 {
159 const auto queued = std::visit(
160 [&](auto value)
161 {
162 return playback.commands().enqueue(std::move(value));
163 },
164 std::move(command));
165 if (!queued)
166 return std::unexpected("validated Trade backdrop command rejected");
167 }
168
169 for (std::size_t index = 0; index < specs.size(); ++index)
170 current_[index] = specs[index].id;
171 return {};
172 }
173}
std::atomic< float > right
std::uint16_t priority
unsigned state
unsigned index
int colour
std::uint16_t value
Definition Timers.cpp:16
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, display::Screen2D desiredView, engine::SequencePlayback &playback)
std::size_t activeCount() const noexcept
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataId EmptyDataId
Definition DataBanks.hpp:13
std::uint16_t DataTag
Definition DataBanks.hpp:11
std::expected< data::DataId, std::string > desiredBackdrop(const rules::GameState &state, bool visible, rules::PlayerNumber activePlayer)
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
MoveSequenceCommand makeMoveXY(data::DataId dataId, std::uint16_t priority, std::int32_t x, std::int32_t y) noexcept
constexpr data::DataTag TradeImmunityButtonTag
constexpr std::uint16_t TradeDisplayBoardPriority
constexpr data::DataTag TradeDisplayBoardTag
constexpr data::DataTag TradeTurntableTag
constexpr data::DataTag TradeCreateButtonTag
constexpr std::uint16_t TradeTurntablePriority
constexpr std::uint16_t TradeArrowPriority
constexpr std::uint16_t TradeDisplayPanelPriority
constexpr std::uint16_t TradeCreateButtonPriority
constexpr std::uint8_t TradeLoopToBeginning
constexpr data::DataTag TradeDisplayRightTag
constexpr std::uint16_t TradeColourRailPriority
constexpr std::uint16_t TradeFutureButtonPriority
constexpr data::DataTag TradeBackgroundTag
constexpr data::DataTag TradeLeftColourBaseTag
constexpr data::DataTag TradeArrowTag
constexpr data::DataTag TradeFutureButtonTag
constexpr data::DataTag TradeDisplayLeftTag
constexpr data::DataTag TradeRightColourBaseTag
constexpr std::uint16_t TradeImmunityButtonPriority
constexpr std::uint16_t TradeBackdropPriority
constexpr data::DataId tradeBackdropSequence(data::DataTag tag) noexcept