Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
AuctionPlayback.cpp
Go to the documentation of this file.
1#include "AuctionPlayback.hpp"
2
3#include <algorithm>
4#include <array>
5#include <memory>
6#include <utility>
7#include <variant>
8#include <vector>
9
10namespace monopoly::auctionui
11{
12 namespace
13 {
14 constexpr std::array<data::DataTag, rules::MaxTokens> AuctionTokenTags{{
15 0x0004, 0x0005, 0x0006, 0x000A, 0x0008, 0x0007,
16 0x0003, 0x000C, 0x0009, 0x000D, 0x000B
17 }};
18
19 using ObjectState = Playback::ObjectState;
20
21 [[nodiscard]] std::expected<std::array<ObjectState, AuctionPlaybackObjectCount>, std::string>
23 const State& state,
24 const rules::GameState& gameState,
26 int city, engine::SequencePlayback& playback)
27 {
28 std::array<ObjectState, AuctionPlaybackObjectCount> desired{};
30 return desired;
31
32 if (gameState.numberOfPlayers > rules::MaxPlayers)
33 return std::unexpected("auction player count exceeds legacy maximum");
34
35 desired[0] = {
38
39 auto property = auctionPropertyDataId(state.propertyForSale,
40 playback.resources() && playback.resources()->context().board ==
42 if (property && state.propertyForSale >= 0 && state.propertyForSale < 28)
43 {
44 static constexpr std::array<int, 28> squares{
45 1,3,5,6,8,9,11,12,13,14,15,16,18,19,
46 21,23,24,25,26,27,28,29,31,32,34,35,37,39};
47 *property = playback.deedDataId(
48 squares[static_cast<std::size_t>(state.propertyForSale)], true, *property);
49 }
50 if (!property)
51 return std::unexpected(property.error());
52 if (*property != data::EmptyDataId)
53 {
54 desired[1] = {
55 *property, AuctionPropertyPriority,
57 }
58
59 for (rules::PlayerNumber player = 0;
60 player < gameState.numberOfPlayers;
61 ++player)
62 {
64 state, gameState.numberOfPlayers, desiredView, player))
65 {
66 continue;
67 }
68
69 const auto& source = gameState.players[player];
71 state.backdropWidth, source.colour);
72 if (!backdrop)
73 return std::unexpected(backdrop.error());
74 const auto token = auctionTokenDataId(source.token);
75 if (!token)
76 return std::unexpected(token.error());
77
78 const auto base = 2 + static_cast<std::size_t>(player) * 4;
79 const auto priority = static_cast<std::uint16_t>(AuctionBasePriority + player);
80 const auto center = state.backdropCenterX[player];
81
82 desired[base] = {
84 center - state.backdropWidth / 2, BackdropY};
85 desired[base + 1] = {
89 center - BillTrayWidth / 2, BillTraysY};
90 desired[base + 2] = {
95 desired[base + 3] = {
96 *token, static_cast<std::uint16_t>(priority + 1),
97 center, AuctionTokenY};
98 }
99
100 return desired;
101 }
102 }
103
104 std::expected<data::DataId, std::string> auctionPropertyDataId(
105 int propertyForSale,
106 int city)
107 {
108 if (propertyForSale < 0)
109 return data::EmptyDataId;
110 if (propertyForSale > 29)
111 return std::unexpected("auction property-for-sale index is outside legacy 0..29 range");
112
113 if (propertyForSale == 28)
114 {
115 return data::packDataId(
118 }
119 if (propertyForSale == 29)
120 {
121 return data::packDataId(
124 }
125
126 if (city > 10)
127 return std::unexpected("auction city is outside USA 0..10 range");
128 const auto cityIndex = std::max(city, 0);
129 const auto tag = static_cast<data::DataTag>(
130 AuctionDeedBaseTag + propertyForSale + 28 * cityIndex);
132 }
133
134 std::expected<data::DataId, std::string> auctionPlayerBackdropDataId(
135 int backdropWidth,
136 std::uint8_t colour)
137 {
139 return std::unexpected("auction player colour is outside legacy 0..5 range");
140
142 if (backdropWidth == BackdropBigWidth)
144 else if (backdropWidth == BackdropSmallWidth)
146 else
147 return std::unexpected("auction backdrop width is neither retail 200 nor 134");
148
149 return data::packDataId(
151 static_cast<data::DataTag>(base + colour));
152 }
153
154 std::expected<data::DataId, std::string> auctionTokenDataId(
155 std::uint8_t token)
156 {
157 if (token >= AuctionTokenTags.size())
158 return std::unexpected("auction token is outside legacy 0..10 range");
159 return data::packDataId(
162 }
163
164 std::expected<void, std::string> Playback::sync(
165 const State& state,
168 int city,
170 {
171 const auto desired = desiredObjects(
173 if (!desired)
174 return std::unexpected(desired.error());
175
176 std::array<std::shared_ptr<const sequence::SequenceProgram>, AuctionPlaybackObjectCount>
177 programs{};
178 for (std::size_t index = 0; index < desired->size(); ++index)
179 {
180 const auto& before = current_[index];
181 const auto& after = (*desired)[index];
182 const bool needsStart = after.id != data::EmptyDataId &&
183 (before.id != after.id || before.priority != after.priority);
184 if (!needsStart)
185 continue;
186
187 auto loaded = playback.loadProgram(after.id);
188 if (!loaded)
189 return std::unexpected(loaded.error());
190 programs[index] = std::move(*loaded);
191 }
192
193 std::vector<sequence::SequenceCommand> commands;
194 for (std::size_t index = 0; index < desired->size(); ++index)
195 {
196 const auto& before = current_[index];
197 const auto& after = (*desired)[index];
198 const bool identityChanged =
199 before.id != after.id || before.priority != after.priority;
200
201 if (identityChanged && before.id != data::EmptyDataId)
202 {
203 commands.push_back(sequence::StopSequenceCommand{
204 before.id, before.priority, false});
205 }
206
207 if (identityChanged && after.id != data::EmptyDataId)
208 {
209 commands.push_back(sequence::StartSequenceCommand{
210 programs[index], after.priority, {}});
211 commands.push_back(sequence::makeMoveXY(
212 after.id, after.priority, after.x, after.y));
213 }
214 else if (!identityChanged && after.id != data::EmptyDataId &&
215 (before.x != after.x || before.y != after.y))
216 {
217 commands.push_back(sequence::makeMoveXY(
218 after.id, after.priority, after.x, after.y));
219 }
220 }
221
222 if (commands.size() >
224 playback.commands().pendingCount())
225 {
226 return std::unexpected(
227 "sequence command queue cannot fit auction static transition");
228 }
229
230 for (auto& command : commands)
231 {
232 const auto queued = std::visit(
233 [&](auto value)
234 {
235 return playback.commands().enqueue(std::move(value));
236 },
237 std::move(command));
238 if (!queued)
239 return std::unexpected("validated auction static command rejected");
240 }
241
242 current_ = *desired;
243 return {};
244 }
245
247 {
248 current_ = {};
249 }
250}
std::uint16_t priority
std::shared_ptr< const data::HmdTextureImage > source
unsigned state
unsigned index
int token
int colour
std::uint16_t value
Definition Timers.cpp:16
std::expected< void, std::string > sync(const State &state, const rules::GameState &gameState, display::Screen2D desiredView, int city, engine::SequencePlayback &playback)
constexpr int BillTrayWidth
Definition AuctionUI.hpp:22
constexpr data::DataTag AuctionHouseDeedTag
std::expected< data::DataId, std::string > auctionPlayerBackdropDataId(int backdropWidth, std::uint8_t colour)
constexpr data::DataTag AuctionHotelDeedTag
constexpr std::uint16_t AuctionPropertyPriority
constexpr data::DataTag AuctionBidPlateTag
constexpr std::uint16_t AuctionBottomBarPriority
constexpr int BackdropBigWidth
Definition AuctionUI.hpp:21
constexpr int BackdropSmallWidth
Definition AuctionUI.hpp:20
constexpr std::int32_t AuctionBottomBarY
constexpr std::uint16_t AuctionBasePriority
constexpr std::int32_t AuctionPropertyX
std::expected< data::DataId, std::string > auctionPropertyDataId(int propertyForSale, int city)
constexpr data::DataTag AuctionDeedBaseTag
constexpr int BackdropY
Definition AuctionUI.hpp:27
constexpr std::size_t AuctionPlaybackObjectCount
constexpr data::DataTag AuctionBillTrayTag
constexpr int BillTraysY
Definition AuctionUI.hpp:28
constexpr std::int32_t AuctionBidTextWidth
bool playerPanelWanted(const State &state, rules::PlayerNumber numberOfPlayers, display::Screen2D desiredView, rules::PlayerNumber player) noexcept
constexpr data::DataTag AuctionBigBackdropBaseTag
constexpr std::int32_t AuctionTokenY
constexpr data::DataId auctionBottomBarDataId() noexcept
constexpr std::int32_t AuctionPropertyY
constexpr data::DataTag AuctionSmallBackdropBaseTag
std::expected< data::DataId, std::string > auctionTokenDataId(std::uint8_t token)
constexpr std::int32_t AuctionBidTextY
constexpr std::int32_t AuctionBottomBarX
constexpr DataId EmptyDataId
Definition DataBanks.hpp:13
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
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
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