Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsFutureImmunityUI.cpp
Go to the documentation of this file.
2
3#include "IBarLayout.hpp"
4
5#include <algorithm>
6#include <cstddef>
7#include <utility>
8
9namespace monopoly::statsui
10{
11 namespace
12 {
13 [[nodiscard]] constexpr rules::CountHitType hitType(
14 FutureImmunityKind kind) noexcept
15 {
19 }
20
21 void rebuildRows(
22 FutureImmunityState& state,
23 const rules::GameState& gameState) noexcept
24 {
25 std::vector<FutureImmunityRow> raw;
26 raw.reserve(rules::SquareCount);
28
29 for (const auto& hit : gameState.countHits)
30 {
31 if (hit.toPlayer != state.player ||
32 hit.hitType != hitType(state.kind))
33 continue;
34 propertySet |= hit.properties;
35 for (int square = 0;
37 ++square)
38 {
39 const auto bit = ibar::layout::propertyBit(square);
40 if (bit == 0 || (hit.properties & bit) == 0)
41 continue;
42 if (raw.size() < rules::SquareCount)
43 {
44 raw.push_back({
45 square, hit.hitCount, hit.fromPlayer});
46 }
47 }
48 }
49
50 std::size_t visibleCount{};
51 for (int square = 0;
53 ++square)
54 {
55 const auto bit = ibar::layout::propertyBit(square);
56 if (bit != 0 && (propertySet & bit) != 0)
58 }
59
60 state.rows.assign(raw.begin(),
61 raw.begin() + static_cast<std::ptrdiff_t>(
62 std::min(visibleCount, raw.size())));
63 }
64 void closePopup(FutureImmunityState& state) noexcept
65 {
66 state.rows.clear();
68 state.scrollIndex = 0;
69 state.upEnabled = false;
70 state.downEnabled = false;
71 state.open = false;
72 }
73
74 void updateScrolledArrows(FutureImmunityState& state) noexcept
75 {
76 state.upEnabled = state.scrollIndex > 0;
77 const auto offset = static_cast<std::size_t>(
78 std::max(state.scrollIndex, 0));
79 const auto remaining = offset < state.rows.size()
80 ? state.rows.size() - offset : 0U;
81 // UDStats_ScrollFuturesNImmunities: linecnt starts at 4 and
82 // disables Down when linecnt < 14.
83 state.downEnabled = remaining >= 10;
84 }
85
86 void openPopup(
87 FutureImmunityState& state,
88 const rules::GameState& gameState,
90 rules::PlayerNumber player) noexcept
91 {
92 state.kind = kind;
93 state.player = player;
94 state.scrollIndex = 0;
95 state.open = true;
97 state.upEnabled = false;
98 // Initial display uses linecnt > 11 with linecnt starting at 4.
99 state.downEnabled = state.rows.size() > 7;
100 }
101 [[nodiscard]] bool clickIcon(
102 FutureImmunityState& state,
103 const rules::GameState& gameState,
105 int x,
106 int y) noexcept
107 {
108 for (const auto& icon : state.icons)
109 {
110 if (icon.kind != kind || !icon.rect.contains(x, y))
111 continue;
112 openPopup(state, gameState, kind, icon.player);
113 return true;
114 }
115 return false;
116 }
117 }
118
120 {
121 state = {};
122 }
123
126 std::vector<FutureImmunityIcon> icons)
127 {
128 state.icons = std::move(icons);
129 }
130
133 const rules::GameState& gameState) noexcept
134 {
135 if (!state.open) return;
137 state.scrollIndex = std::clamp(
138 state.scrollIndex, 0,
139 static_cast<int>(rules::SquareCount) - 1);
140 if (state.scrollIndex == 0)
141 {
142 state.upEnabled = false;
143 state.downEnabled = state.rows.size() > 7;
144 }
145 else
147 }
156
162 const uimsg::Message& message) noexcept
163 {
164 if (view != display::Screen2D::Portfolio ||
166 {
168 return false;
169 }
170
171 if (message.type != uimsg::Type::MouseLeftDown)
172 return false;
173
174 const int x = static_cast<int>(message.numberA);
175 const int y = static_cast<int>(message.numberB);
176 if (state.open)
177 {
178 if (state.downEnabled &&
180 {
181 state.scrollIndex = std::min(
182 state.scrollIndex + 1,
183 static_cast<int>(rules::SquareCount) - 1);
185 return true;
186 }
187
188 if (state.upEnabled &&
190 {
191 state.scrollIndex = std::max(state.scrollIndex - 1, 0);
193 return true;
194 }
195 return false;
196 }
197 // Retail checks Immunities before Futures when their hotspots overlap.
200 return true;
201 return clickIcon(state, gameState,
203 }
204}
std::size_t offset
unsigned state
unsigned index
Kind kind
std::uint32_t PropertyMask
PropertyMask propertyBit(int square) noexcept
std::uint8_t PlayerNumber
Definition RuleTypes.hpp:12
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24
constexpr PlayerNumber NobodyPlayer
Definition RuleTypes.hpp:16
void setFutureImmunityIcons(FutureImmunityState &state, std::vector< FutureImmunityIcon > icons)
bool processFutureImmunityInput(FutureImmunityState &state, const rules::GameState &gameState, Screen statsScreen, display::Screen2D view, const uimsg::Message &message) noexcept
void refreshFutureImmunity(FutureImmunityState &state, const rules::GameState &gameState) noexcept
constexpr Rect FutureImmunityDownRect
void resetFutureImmunity(FutureImmunityState &state) noexcept
constexpr Rect FutureImmunityUpRect
void syncFutureImmunityView(FutureImmunityState &state, Screen statsScreen, display::Screen2D view) noexcept
constexpr bool contains(int x, int y) const noexcept
Definition StatsUI.hpp:38