Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsDeedPlayback.cpp
Go to the documentation of this file.
2
3#include <map>
4#include <memory>
5#include <set>
6#include <utility>
7
8namespace monopoly::statsui
9{
10 namespace
11 {
12 using Objects = std::vector<DeedPlayback::Published>;
13
14 [[nodiscard]] constexpr bool bssmMode(ibar::RuleMode mode) noexcept
15 {
16 return mode == ibar::RuleMode::Build ||
17 mode == ibar::RuleMode::Sell ||
20 }
21
22 [[nodiscard]] data::DataId deedId(int square, bool mortgaged) noexcept
23 {
24 const int property = ibar::layout::propertyIndex(square);
25 if (property < 0) return data::EmptyDataId;
26 const auto base = mortgaged
29 static_cast<data::DataTag>(base + property));
30 }
31 [[nodiscard]] bool deedVisible(
32 const rules::GameState& gameState, int square,
33 const PlayerPlaybackInputs& inputs) noexcept
34 {
35 const auto bit = ibar::layout::propertyBit(square);
36 switch (inputs.mode)
37 {
39 return bit != 0 && (inputs.mortgageProperties & bit) != 0;
41 return gameState.squares[static_cast<std::size_t>(square)].mortgaged;
43 return bit != 0 && (inputs.buildProperties & bit) != 0;
45 return bit != 0 && (inputs.sellProperties & bit) != 0;
46 default:
47 return true;
48 }
49 }
50
52 const rules::GameState& gameState, int square,
53 ibar::RuleMode mode) noexcept
54 {
55 if (mode == ibar::RuleMode::Mortgage ||
57 return false;
58 return gameState.squares[static_cast<std::size_t>(square)].mortgaged;
59 }
60 [[nodiscard]] std::expected<Objects, std::string> desiredObjects(
61 const State& state, const rules::GameState& gameState,
62 const PlayerPlaybackInputs& inputs)
63 {
64 Objects result;
65 const bool localBssm = bssmMode(inputs.mode) &&
66 inputs.iBarPlayerLocalHuman;
67 int displayed = 0;
68
69 for (std::size_t rank = 0; rank < rules::SquareCount; ++rank)
70 {
71 const int square = state.deedOrder[rank];
72 if (square < 0 || square >= static_cast<int>(rules::SquareCount))
73 return std::unexpected("UDStats Deed sort references invalid square");
74 if (ibar::layout::propertyIndex(square) < 0) continue;
75 if (state.activeSort == 3 && state.deedMetric[rank] == 0) continue;
76
77 const auto owner = gameState.squares[static_cast<std::size_t>(square)].owner;
78 if (localBssm)
79 {
80 if (owner != inputs.iBarPlayer) continue;
81 if (!deedVisible(gameState, square, inputs)) continue;
82 }
83
84 const auto id = deedId(square,
85 useMortgagedFace(gameState, square, inputs.mode));
86 if (id == data::EmptyDataId)
87 return std::unexpected("UDStats Deed square has no deed sequence");
88 const int x = DeedGridX + DeedGridColumnStep *
90 const int y = DeedGridY + DeedGridRowStep *
92 result.push_back({square, id, DeedGridPriority, x, y});
93 ++displayed;
94 }
95 return result;
96 }
97 }
98
99 std::expected<std::vector<DeedPlayback::Published>, std::string>
105
106 std::expected<void, std::string> DeedPlayback::sync(
107 const State& state, const rules::GameState& gameState,
110 {
113 state.screen == Screen::Deed)
114 {
116 if (!planned) return std::unexpected(planned.error());
117 desired = std::move(*planned);
118 }
119
120 if (desired == current_) return {};
121 std::map<data::DataId,
122 std::shared_ptr<const sequence::SequenceProgram>> programs;
123 for (const auto& object : desired)
124 {
125 if (programs.contains(object.id)) continue;
127 playback.resources(), object.id);
128 if (!loaded)
129 return std::unexpected(
130 "UDStats Deed resource failed: " + loaded.error().detail);
131 programs.emplace(object.id, std::move(*loaded));
132 }
133
134 std::set<std::pair<data::DataId, std::uint16_t>> stops;
135 for (const auto& object : current_)
136 stops.emplace(object.id, object.priority);
137
138 const std::size_t required = stops.size() + desired.size();
140 playback.commands().pendingCount())
141 {
142 return std::unexpected(
143 "sequence command queue cannot fit UDStats Deed transition");
144 }
145 for (const auto& [id, priority] : stops)
146 {
147 if (!playback.commands().enqueue(
149 return std::unexpected("validated UDStats Deed stop rejected");
150 }
151
152 for (const auto& object : desired)
153 {
154 if (!playback.commands().enqueue(sequence::StartSequenceCommand{
155 programs.at(object.id), object.priority, {},
156 sequence::moveXYTransform(object.x, object.y)}))
157 return std::unexpected("validated UDStats Deed start rejected");
158 }
159
160 current_ = std::move(desired);
161 return {};
162 }
163}
data::DataId id
std::uint16_t priority
unsigned state
unsigned index
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 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
int propertyIndex(int square) noexcept
PropertyMask propertyBit(int square) noexcept
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
constexpr int DeedGridColumns
constexpr int DeedGridColumnStep
constexpr data::DataTag PlayerDeedMortgagedBaseTag
std::expected< std::vector< DeedPlayback::Published >, std::string > planDeedGrid(const State &state, const rules::GameState &gameState, const PlayerPlaybackInputs &inputs)
constexpr data::DataTag PlayerDeedNormalBaseTag
constexpr std::uint16_t DeedGridPriority
constexpr int DeedGridRowStep