Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
PieceShadowDisplay.cpp
Go to the documentation of this file.
2
4
5#include <cstddef>
6
7namespace monopoly::pieces
8{
9 namespace
10 {
11 constexpr std::uint8_t StayAtEnd = 2;
12
13 [[nodiscard]] bool samePose(
14 const TokenPose& left, const TokenPose& right) noexcept
15 {
16 return left.x == right.x && left.y == right.y &&
17 left.z == right.z && left.yaw == right.yaw;
18 }
19
20 [[nodiscard]] bool shadowVisible(
21 const rules::GameState& state,
22 const PieceShadowDisplayContext& context,
23 rules::PlayerNumber player) noexcept
24 {
25 if (!context.boardVisible || !context.lightingOn ||
26 !context.game3DOn || player >= state.numberOfPlayers)
27 return false;
28
29 if (context.paddywagonPlayer == player &&
30 context.goingToJailStatus == 8)
31 return false;
32
33 const auto square = state.players[player].currentSquare;
34 return square < 41 ||
35 (player == context.currentUIPlayer &&
36 context.currentPlayerTokenSequenceActive);
37 }
38
39 [[nodiscard]] sequence::Matrix3D shadowTransform(
40 const TokenPose& pose) noexcept
41 {
43 pose.yaw, 1.0F, pose.x, pose.z);
44 result.values[13] = ShadowGroundY;
45 return result;
46 }
47 }
48
50 {
51 shown_.fill(data::EmptyDataId);
52 for (auto& pose : poses_) pose.reset();
53 poseTracker_ = {};
54 }
55
57 rules::PlayerNumber player) const noexcept
58 {
59 return player < shown_.size() ? shown_[player] : data::EmptyDataId;
60 }
61
62 std::expected<PieceShadowDisplayUpdate, std::string>
65 const PieceShadowDisplayContext& context,
67 {
68 struct Desired
69 {
70 data::DataId id = data::EmptyDataId;
72 bool visible{};
73 };
74
75 std::array<Desired, rules::MaxPlayers> desired{};
76 std::size_t requiredCommands{};
77
78 for (rules::PlayerNumber player = 0;
79 player < rules::MaxPlayers; ++player)
80 {
81 if (!shadowVisible(state, context, player))
82 {
83 if (shown_[player] != data::EmptyDataId)
85 continue;
86 }
87
88 const auto token = state.players[player].token;
90 return std::unexpected("piece shadow token is outside legacy range");
91
92 const auto tag = static_cast<std::uint32_t>(ShadowSequenceBaseTag) + token;
93 if (tag > 0xFFFFU)
94 return std::unexpected("piece shadow sequence tag overflow");
95
96 auto& target = desired[player];
97 target.visible = true;
100 target.pose = poseTracker_.locate(
101 player, state.numberOfPlayers,
102 context.runtimeSources, playback.runtime());
103
104 if (shown_[player] != target.id)
105 requiredCommands += shown_[player] == data::EmptyDataId ? 3U : 4U;
106 else if (!poses_[player] || !samePose(*poses_[player], target.pose))
108 }
109
111 playback.commands().pendingCount() >
113 return std::unexpected("piece shadow command queue capacity exceeded");
114
116 for (rules::PlayerNumber player = 0;
117 player < rules::MaxPlayers; ++player)
118 {
119 const auto priority = static_cast<std::uint16_t>(
120 ShadowPriorityBase + player);
121 const auto& target = desired[player];
122
123 if (!target.visible)
124 {
125 if (shown_[player] == data::EmptyDataId) continue;
126 const auto stopped = playback.stop(shown_[player], priority);
127 if (!stopped) return std::unexpected(stopped.error());
128 shown_[player] = data::EmptyDataId;
129 poses_[player].reset();
130 ++update.stopped;
131 continue;
132 }
133
134 const auto transform = shadowTransform(target.pose);
135 if (shown_[player] != target.id)
136 {
137 const std::optional<data::DataId> previous =
138 shown_[player] == data::EmptyDataId ? std::nullopt :
139 std::optional<data::DataId>(shown_[player]);
140 const auto transitioned = playback.transitionMovedDrop(
141 previous, target.id, priority, transform, StayAtEnd);
142 if (!transitioned) return std::unexpected(transitioned.error());
143 if (previous) ++update.stopped;
144 ++update.started;
145 shown_[player] = target.id;
146 poses_[player] = target.pose;
147 continue;
148 }
149
150 if (!poses_[player] || !samePose(*poses_[player], target.pose))
151 {
152 const auto moved = playback.move(target.id, priority, transform);
153 if (!moved) return std::unexpected(moved.error());
154 poses_[player] = target.pose;
155 ++update.moved;
156 }
157 }
158
159 return update;
160 }
161}
std::atomic< float > left
std::atomic< float > right
std::uint16_t priority
unsigned state
unsigned index
int token
data::DataId shownSequence(rules::PlayerNumber player) const noexcept
std::expected< PieceShadowDisplayUpdate, std::string > sync(const rules::GameState &state, const PieceShadowDisplayContext &context, engine::SequencePlayback &playback)
TokenPose locate(rules::PlayerNumber player, rules::PlayerNumber numberOfPlayers, const TokenRuntimeSources &sources, const sequence::SequenceRuntime &runtime) noexcept
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
constexpr std::uint16_t ShadowPriorityBase
constexpr data::DataTag ShadowSequenceBaseTag
constexpr float ShadowGroundY
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
constexpr std::size_t MaxTokens
Definition RuleTypes.hpp:30
constexpr PlayerNumber MaxPlayers
Definition RuleTypes.hpp:14
Matrix3D moveRySTxzTransform(float yaw, float scale, float x, float z) noexcept