15 template <std::
size_t N>
17 std::array<std::int64_t, N>& values,
18 std::array<std::uint8_t, N>& indices,
19 std::size_t
count)
noexcept
21 for (std::size_t
i = 0;
i <
count; ++
i)
23 std::size_t maximum =
i;
26 if (values[
j] > values[maximum]) maximum =
j;
28 std::swap(values[
i], values[maximum]);
29 std::swap(indices[
i], indices[maximum]);
35 const auto count = std::min<std::size_t>(
38 state.playerMetric.fill(0);
42 if (
state.activeSort == 0 ||
count == 0)
return;
44 std::array<std::int64_t, rules::MaxPlayers> values{};
45 std::array<std::uint8_t, rules::MaxPlayers> indices{};
47 indices[
i] =
static_cast<std::uint8_t
>(
i);
49 for (std::size_t
i = 0;
i <
count; ++
i)
52 switch (
state.activeSort)
56 case 3: values[
i] =
gameState.players[
i].cash;
break;
62 for (std::size_t
i = 0;
i <
count; ++
i)
64 state.playerOrder[
i] = indices[
i];
65 state.playerMetric[
i] = values[
i];
71 std::array<std::int64_t, rules::SquareCount> values{};
72 std::array<std::uint8_t, rules::SquareCount> indices{};
75 indices[
i] =
static_cast<std::uint8_t
>(
i);
77 switch (
state.activeSort)
101 if (
state.activeSort == 1)
108 if (values[
i] > values[
i + 1])
110 std::swap(values[
i], values[
i + 1]);
111 std::swap(indices[
i], indices[
i + 1]);
123 state.deedOrder[
i] = indices[
i];
124 state.deedMetric[
i] = values[
i];
130 state.bankPlayerHouses.fill(0);
131 state.bankPlayerHotels.fill(0);
135 state.activeDatasetAvailable =
true;
137 if (
state.activeSort == 0)
147 if (owner >=
gameState.numberOfPlayers ||
154 if (houses <= 0)
continue;
155 if (houses ==
gameState.options.housesPerHotel)
156 ++
state.bankPlayerHotels[owner];
158 state.bankPlayerHouses[owner] += houses;
163 state.bankHousesRemaining -=
state.bankPlayerHouses[player];
164 state.bankHotelsRemaining -=
state.bankPlayerHotels[player];
169 if (
state.activeSort == 1)
196 const rules::GameState&
gameState,
int square)
noexcept
201 gameState.squares[
static_cast<std::size_t
>(square)].owner !=
202 state.propertyActionPlayer)
205 if (
bit == 0)
return false;
206 switch (
state.propertyActionMode)
212 return gameState.squares[
static_cast<std::size_t
>(square)].mortgaged;
213 default:
return false;
218 const rules::GameState&
gameState,
int mouseX,
int mouseY)
noexcept
220 const auto count = std::min<std::size_t>(
state.playerCount,
231 if (order < 0)
continue;
250 const rules::GameState&
gameState,
int mouseX,
int mouseY)
noexcept
255 const int square =
state.deedOrder[
rank];
260 if (
state.activeSort == 3 &&
state.deedMetric[
rank] == 0)
continue;
264 if (mouseX >=
x && mouseX <
x + 36 &&
265 mouseY >=
y && mouseY <
y + 42)
277 state.deedOrder[
i] =
static_cast<std::uint8_t
>(
i);
284 state.activeSort =
state.lastSort[
static_cast<std::size_t
>(
state.screen)];
285 state.activeDatasetAvailable =
true;
286 switch (
state.screen)
294 state.initialized =
true;
302 if (visible && !
state.portfolioVisible)
304 state.portfolioVisible = visible;
305 if (!visible)
state.mouseKnown =
false;
311 state.screen = screen;
328 for (std::uint8_t
i = 0;
i < 3; ++
i)
335 std::optional<std::uint8_t>
sortHit(
int x,
int y)
noexcept
337 for (std::uint8_t
i = 0;
i < 4; ++
i)
349 bool modernPlayerLayout)
noexcept
351 state.modernPlayerLayout = modernPlayerLayout;
352 if (!modernPlayerLayout)
state.modernJailLayoutQualified =
false;
353 state.propertyActionMode = mode;
354 state.propertyActionPlayer = player;
355 state.propertyActionPlayerLocalHuman = localHuman;
364 const auto count = std::min<std::size_t>(
state.playerCount,
370 if (
gameState.squares[
static_cast<std::size_t
>(square)].owner == player &&
373 { return hit.toPlayer == player && (hit.hitType == rules::CountHitType::FutureRent ||
374 hit.hitType == rules::CountHitType::RentImmunity); }))
return false;
376 [&](
const auto&
card) { return card.jailOwner == player; });
382 std::size_t
column,
int square)
noexcept
384 const auto count = std::min<std::size_t>(
state.playerCount,
391 gameState.squares[
static_cast<std::size_t
>(square)].owner != player)
393 std::array<bool, 11>
counted{};
397 if (
gameState.squares[
static_cast<std::size_t
>(
other)].owner != player)
continue;
407 const int gap =
state.propertyActionPlayerLocalHuman &&
410 const int y = 224 + 84 + (
rank / 3) * 44;
423 const int y = (
count > 4 ? 300 : 275) + 20 * (order % 3);
430 if (!
state.portfolioVisible || !
state.propertyActionPlayerLocalHuman ||
431 !propertyActionMode(
state.propertyActionMode))
444 state.activeSort != 3)
446 state.historyArrowPressed = -1;
450 state.historyArrowPressed = -1;
452 const int x =
static_cast<int>(message.numberA);
453 const int y =
static_cast<int>(message.numberB);
459 return arrow == 0 ? 1 : -1;
461 state.historyArrowPressed = -1;
470 if (!
state.portfolioVisible)
return false;
473 state.mouseX =
static_cast<int>(message.numberA);
474 state.mouseY =
static_cast<int>(message.numberB);
475 state.mouseKnown =
true;
480 const int x =
static_cast<int>(message.numberA);
481 const int y =
static_cast<int>(message.numberB);
ibar::layout::PropertyMask mortgageProperties
ibar::layout::PropertyMask sellProperties
ibar::layout::PropertyMask buildProperties
std::int64_t potentialIncome(const rules::GameState &state, rules::PlayerNumber player) noexcept
std::int64_t rentIfSteppedOn(const rules::GameState &state, SquareType square, rules::board::PropertySet propertiesOwned) noexcept
std::int64_t totalWorth(const rules::GameState &state, rules::PlayerNumber player) noexcept
rules::board::PropertySet propertiesOwnedByPlayer(const rules::GameState &state, rules::PlayerNumber player) noexcept
int propertyIndex(int square) noexcept
std::uint32_t PropertyMask
PropertyMask propertyBit(int square) noexcept
int propertyBarOrder(int square) noexcept
const SquareDefinition & definition(SquareType square)
bool isOwnable(SquareType square)
constexpr PlayerNumber BankPlayer
std::uint8_t PlayerNumber
constexpr std::size_t SquareCount
constexpr PlayerNumber MaxPlayers
std::optional< std::uint8_t > sortHit(int x, int y) noexcept
constexpr Rect sortRect(std::uint8_t index) noexcept
void refresh(State &state, const rules::GameState &gameState) noexcept
std::optional< int > propertyActionHit(const State &state, const rules::GameState &gameState, int x, int y) noexcept
bool selectSort(State &state, std::uint8_t sortIndex, const rules::GameState &gameState) noexcept
std::optional< Screen > categoryHit(int x, int y) noexcept
void syncView(State &state, const rules::GameState &gameState, display::Screen2D view) noexcept
constexpr Rect categoryRect(std::uint8_t index) noexcept
void reset(State &state) noexcept
std::optional< Rect > playerPropertyRect(const State &state, const rules::GameState &gameState, std::size_t column, int square) noexcept
bool modernPlayerGridActive(const State &state, const rules::GameState &gameState, rules::PlayerNumber player) noexcept
void setPropertyActionContext(State &state, ibar::RuleMode mode, rules::PlayerNumber player, bool localHuman, ibar::layout::PropertyMask buildProperties, ibar::layout::PropertyMask sellProperties, ibar::layout::PropertyMask mortgageProperties, bool modernPlayerLayout) noexcept
int historyScrollInput(State &state, display::Screen2D view, const uimsg::Message &message) noexcept
bool selectCategory(State &state, Screen screen, const rules::GameState &gameState) noexcept
bool processInput(State &state, const rules::GameState &gameState, display::Screen2D view, const uimsg::Message &message) noexcept
std::int64_t purchaseCost
constexpr bool contains(int x, int y) const noexcept