51 0, 1u<<0, 0, 1u<<1, 0, 1u<<2, 1u<<3, 0, 1u<<4, 1u<<5,
52 0, 1u<<6, 1u<<7, 1u<<8, 1u<<9, 1u<<10, 1u<<11, 0, 1u<<12, 1u<<13,
53 0, 1u<<14, 0, 1u<<15, 1u<<16, 1u<<17, 1u<<18, 1u<<19, 1u<<20, 1u<<21,
54 0, 1u<<22, 1u<<23, 0, 1u<<24, 1u<<25, 0, 1u<<26, 0, 1u<<27, 0, 0
78 rules::GameState&
state,
79 const std::vector<std::uint8_t>& data,
87 if (
data.size() != expected ||
data[0] != 1)
return false;
92 std::uint32_t
value{};
101 return std::bit_cast<std::int64_t>(
raw);
108 std::array<std::uint32_t, rules::MaxPlayers>
owned{};
110 const std::uint32_t mortgaged =
readU32();
112 for (
auto& square :
next.squares)
115 square.mortgaged =
false;
122 if (
bit == 0)
continue;
126 if ((
owned[player] &
bit) == 0)
continue;
136 const auto square =
readU8();
138 next.players[player].currentSquare = square;
142 const auto owner =
readU8();
149 const auto cause =
readU8();
150 if (cause > 4)
return false;
154 next.players[player].firstMoveMade = (
firstMoves & (1u << player)) != 0;
314 std::optional<udsound::PennybagsVoice> voice;
317 if (
uiRuleState.players[playerA].aiPlayerLevel == 0)
326 else if (
uiRuleState.players[playerA].aiPlayerLevel != 0 &&
336 const std::optional<penny::TokenReaction>&
reaction)
noexcept
346 const std::optional<penny::PennybagsReaction>&
reaction)
noexcept
355 const auto count = std::min<rules::PlayerNumber>(
371 std::uint32_t
mask{};
376 mask |= 1u << player;
382 std::uint32_t
mask{};
383 const auto count = std::min<rules::PlayerNumber>(
387 mask |= (1u << player);
422 player.currentSquare = 41;
433 const auto count = std::min<rules::PlayerNumber>(
449 return std::unexpected(
450 "message queue cannot fit I_AM_HERE responses");
463 return std::unexpected(
464 "validated I_AM_HERE response was rejected");
472 const std::vector<actions::Message>&
batch)
474 if (
batch.empty())
return true;
479 for (
const auto& action :
batch)
596 if (
const auto reset =
accounts->resetGame(); !reset)
597 SDL_Log(
"Stats account reset: %s", reset.error().c_str());
654 std::uint8_t cause{};
661 if (
const auto reset =
accounts->resetGame(); !reset)
662 SDL_Log(
"Stats loaded-game history reset: %s", reset.error().c_str());
668 hit.tradedItem =
false;
791 square.mortgaged = message.
numberB != 0;
796 message.
numberB != 0 ? 2U : 3U);
807 square.houses =
static_cast<std::uint8_t
>(message.
numberB);
842 message.
numberB >= std::numeric_limits<std::int32_t>::min() &&
843 message.
numberB <= std::numeric_limits<std::int32_t>::max() &&
845 message.
numberE <= std::numeric_limits<std::uint32_t>::max())
854 static_cast<std::int32_t
>(message.
numberB),
855 static_cast<std::uint32_t
>(message.
numberE),
false);
880 const auto property =
uiRuleState.players[player].currentSquare;
917 ?
static_cast<std::uint32_t
>(message.
numberE)
954 ? (1u << tradeBPlayer)
960 ?
static_cast<std::uint32_t
>(message.
numberA)
1060 const auto random100 =
static_cast<std::uint32_t
>(std::rand() % 100);
1061 std::optional<std::uint32_t>
random8;
1064 random8 =
static_cast<std::uint32_t
>(std::rand() % 8);
1123 const std::int64_t
count =
1124 std::clamp<std::int64_t>(
1127 static_cast<std::int64_t
>(
1187 hit.tradedItem =
false;
1343 action.fromPlayer =
bid->player;
1345 action.numberA =
bid->amount;
1388 const auto opened = resources
1392 : std::expected<void, std::string>(std::unexpected(
"Help resources unavailable"));
1402 : std::expected<void, std::string>(
1403 std::unexpected(selection.error()));
1463 const int language =
static_cast<int>(resources->context().language);
1475 action.binaryDataA = *
blob;
1608 : std::expected<void, std::string>(
1609 std::unexpected(
"custom-board executable directory is unavailable"));
1651 static_cast<int>(message.
numberA),
1652 static_cast<int>(message.
numberB)))
std::array< rules::PlayerNumber, rules::MaxPlayers > players
decision::EconomicActionPlan plan
std::vector< std::uint8_t > data
LegacyBitmapMetadata metadata
std::shared_ptr< const data::HmdTextureImage > source
@ NotifyJailCardOwnership
@ NotifyTradeAcceptanceDecision
@ NotifyBuyOrAuctionDecision
@ NotifyFlatOrFractionTaxDecision
@ NotifyProposedConfiguration
@ NotifyPlayerBuySellMort
std::optional< BidRequest > planBid(const State &state, rules::PlayerNumber numberOfPlayers, display::Screen2D desiredView, const uimsg::Message &message, std::uint32_t localHumanMask) noexcept
void reset(State &state) noexcept
RuleUpdate processRuleMessage(State &state, const rules::GameState &gameState, const actions::Message &message, display::Screen2D desiredView) noexcept
bool processInput(const uimsg::Message &message, rules::PlayerNumber sender, std::uint32_t eligibleRecipients, bool networkMode)
void setPlayerNames(const rules::GameState &gameState)
bool processRuleMessage(const actions::Message &message)
void processBoardInput(const uimsg::Message &message)
void applyMusicOption(bool musicOn) noexcept
void applyRuntimeOptions(bool tokenAnimationsOn, bool cameraMovementOn, bool lightingOn, bool board3DOn) noexcept
constexpr bool isIBarVisible(Screen2D screen) noexcept
void applyHostCommentsOption(bool enabled) noexcept
void requestBssmCamera(std::int32_t square, std::uint8_t action) noexcept
void noteBoardActivity() noexcept
void setBackdrop(Screen2D screen)
const State & stateReadOnly()
void applyTokenVoicesOption(bool enabled) noexcept
void applyMusicTune(std::uint8_t tuneIndex) noexcept
bool consumeOpeningMovieInput(const uimsg::Message &message)
void playTokenVoice(std::uint8_t token, udsound::TokenVoiceLine line, udsound::TokenVoiceClipPolicy policy, bool watchAfterStart) noexcept
void playClickSound() noexcept
bool modernTradePresentationEnabled() noexcept
void stopVoiceChat() noexcept
void playWarningSound() noexcept
void playJailChoiceHostComment() noexcept
statsui::AccountRuntime * statsAccounts() noexcept
fonts::Runtime * fontPlayback()
bool isUsaBoardEdition() noexcept
bool startVoiceChat() noexcept
void playBuildSound() noexcept
void playPennybagsVoice(udsound::PennybagsVoice line, udsound::TokenVoiceClipPolicy policy, bool watchAfterStart) noexcept
void playSaveFailureSound() noexcept
void playUnbuildSound() noexcept
bool spokenPostLockSlotEmpty() noexcept
bool activateProperty(int square)
void processRuleMessage(const actions::Message &message, RuleMode projectedMode, std::uint64_t tick) noexcept
bool requestNewGameConfirmation() noexcept
void processLibraryMessage(const uimsg::Message &message)
bool requestExitConfirmation() noexcept
void restoreRuleTracking() noexcept
RuleMode resolveRuleMode(RuleMode projectedMode, rules::PlayerNumber projectedPlayer) noexcept
rules::PlayerNumber resolveRulePlayer(rules::PlayerNumber projectedPlayer) noexcept
const State & stateReadOnly()
constexpr std::int64_t ErrorSaveGameFailure
std::size_t queuedActionCount()
constexpr std::size_t MessageQueueCapacity
bool sendAction(const actions::Message &message)
void noteClientResynchronized()
CustomBoardInput processCustomBoardInput(CustomBoardState &state, const uimsg::Message &message) noexcept
void closeCustomBoardDialog(CustomBoardState &state) noexcept
bool beginFromIBar(State &state, display::Screen2D previousView) noexcept
void closeSaveDialog(SaveRuntimeState &state) noexcept
std::expected< std::optional< std::filesystem::path >, std::string > restoreSavedCustomBoard(std::string_view savedAssetRoot, const data::ResourceSnapshot &resources, int monetarySystem)
SaveDialogInput processSaveDialogInput(SaveRuntimeState &state, const uimsg::Message &message, fonts::Runtime *fontRuntime, std::shared_ptr< const data::ResourceSnapshot > resources)
void reset(State &state) noexcept
std::expected< void, std::string > openQuickHelp(State &state, const data::ResourceSnapshot &resources)
InputResult processInput(State &state, display::Screen2D desiredView, const uimsg::Message &message) noexcept
std::expected< void, std::string > persistPendingSave(SaveRuntimeState &state, std::span< const std::uint8_t > gameBlob)
std::expected< void, std::string > openCustomBoardDialog(CustomBoardState &state, const std::filesystem::path &moduleDirectory, display::Screen2D previousView)
void loadSupportedOptionValues(State &state, bool tokenVoicesOn, bool hostCommentsOn, bool musicOn, std::uint8_t musicTuneIndex, bool tokenAnimationsOn, bool cameraMovementOn, bool lightingOn, bool board3DOn, bool filteringOn) noexcept
std::expected< std::vector< std::uint8_t >, std::string > readSelectedGameBlob(const SaveRuntimeState &state)
void clearPendingSave(SaveRuntimeState &state) noexcept
std::expected< void, std::string > openFullHelp(const data::ResourceSnapshot &resources, const FullHelpOptions &options)
std::expected< CustomBoardSelection, std::string > validateSelectedCustomBoard(const CustomBoardState &state)
std::expected< void, std::string > refreshSaveSlots(SaveRuntimeState &state, FileDialogMode mode)
std::expected< void, std::string > applySelectedMetadata(const SaveRuntimeState &state, rules::GameState &ruleState, int &city, int &system)
std::expected< void, std::string > beginPendingSave(SaveRuntimeState &state, const rules::GameState &ruleState, int city, int system, std::string customBoardName, rules::PlayerNumber requester)
std::optional< PennybagsReaction > goToJailPennybagsReaction(const rules::GameState &state, rules::PlayerNumber player, bool localHuman) noexcept
std::optional< PennybagsReaction > boughtPropertyPennybagsReaction(const rules::GameState &state, rules::PlayerNumber player, std::uint8_t property) noexcept
std::optional< TokenReaction > goToJailReaction(const rules::GameState &state, rules::PlayerNumber player, bool localHuman) noexcept
std::optional< PennybagsReaction > buyOrAuctionPennybagsReaction(const rules::GameState &state, rules::PlayerNumber player) noexcept
std::optional< TurnStartReactions > nextPlayerReactions(const rules::GameState &state, rules::PlayerNumber player, std::uint32_t random100, std::optional< std::uint32_t > random8) noexcept
std::optional< TokenReaction > boughtPropertyReaction(const rules::GameState &state, rules::PlayerNumber player, std::uint8_t property) noexcept
std::optional< TokenReaction > choseAuctionReaction(const rules::GameState &state, rules::PlayerNumber player) noexcept
BoardCameraView pickCameraFor3Squares(std::int32_t square) noexcept
BoardCameraView selectAppropriateView(BoardViewSelectionType type, BoardCameraView desired, std::int32_t currentSquare, std::int32_t variable) noexcept
bool consumeCustomBoardRequest() noexcept
const State & stateReadOnly()
void processLibraryMessage(const uimsg::Message &message)
std::expected< void, std::string > commitCustomBoard(std::filesystem::path assetRoot)
void processMessage(const actions::Message &message)
bool consumeLoadRequest() noexcept
bool decodeOptions(std::span< const std::uint8_t > data, GameOptions &result)
const PendingPhase & current(const GameState &state)
constexpr PlayerNumber BankPlayer
std::uint8_t PlayerNumber
constexpr PlayerNumber SpectatorPlayer
constexpr PlayerNumber EscrowPlayer
constexpr std::size_t SquareCount
constexpr PlayerNumber MaxPlayers
constexpr PlayerNumber NobodyPlayer
std::shared_ptr< const data::ResourceSnapshot > resources() noexcept
bool processCalculatorInput(CalculatorUIState &state, const rules::GameState &gameState, display::Screen2D view, const uimsg::Message &message) noexcept
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
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
void syncView(State &state, const rules::GameState &gameState, display::Screen2D view) noexcept
void reset(State &state) noexcept
void resetCalculatorUI(CalculatorUIState &state) noexcept
void resetFutureImmunity(FutureImmunityState &state) noexcept
void syncCalculatorView(CalculatorUIState &state, display::Screen2D view) noexcept
void syncFutureImmunityView(FutureImmunityState &state, Screen statsScreen, display::Screen2D view) noexcept
int historyScrollInput(State &state, display::Screen2D view, const uimsg::Message &message) noexcept
bool processInput(State &state, const rules::GameState &gameState, display::Screen2D view, const uimsg::Message &message) noexcept
std::uint64_t tickCount()
bool addUiImmunity(rules::GameState &gameState, rules::PlayerNumber from, rules::PlayerNumber to, rules::CountHitType hitType, std::int32_t hitCount, std::uint32_t properties, bool tradingItem) noexcept
bool abortIfParticipantOffBoard(State &state, rules::GameState &gameState, display::Screen2D desiredView) noexcept
RuleUpdate processRuleMessage(State &state, rules::GameState &gameState, const actions::Message &message, display::Screen2D currentView, std::uint32_t localHumanMask, bool restoreAutonomousPortfolio)
bool beginLocalTrade(State &state, const rules::GameState &gameState, rules::PlayerNumber source) noexcept
bool selectPartner(State &state, const rules::GameState &gameState, rules::PlayerNumber player) noexcept
InputUpdate processInput(State &state, const rules::GameState &gameState, display::Screen2D desiredView, const uimsg::Message &message)
std::vector< actions::Message > planEditorSubmission(const State &state, rules::PlayerNumber editor, std::uint32_t localHumanMask)
void reset(State &state) noexcept
constexpr std::uint8_t OffBoardSquare
std::optional< rules::PlayerNumber > planPartnerSelection(State &state, const rules::GameState &gameState, display::Screen2D desiredView, const uimsg::Message &message) noexcept
@ WaitForAnyOldSoundThenPlay
@ HumanReplacedByComputerPlayer
@ HousingShortage_NotFirstTime
@ TradeScreen_PickTradePartner
@ TradeScreen_TradeCancelled
@ TradeScreen_TradeComplete
@ TradeScreen_ProposeClickedButOneSideHasNotOfferedAnything
PlayerNumber anyLocalPlayer(const GameState &uiState)
PlayerNumber tradeSourcePlayer(const GameState &uiState, PlayerNumber iBarCurrentPlayer)
void setCurrentUIPlayerFromPlayerSet(const GameState &uiState, std::uint32_t playerSet)
bool isLocalRecipient(PlayerNumber recipient)
bool slotIsLocalHumanPlayer(PlayerNumber slot)
bool slotIsLocalPlayer(PlayerNumber slot)
void setCurrentUIPlayerFromPlayerNumber(PlayerNumber player)
PlayerNumber tradeAcceptanceIBarPlayer(const GameState &uiState, PlayerNumber tradeBPlayer, std::uint32_t pendingPlayers)
PlayerNumber housingShortageIBarPlayer(const GameState &uiState, PlayerNumber originalBuyer, std::uint32_t allowedPlayers)
void processRuleMessage(GameState &uiState, const actions::Message &message)
optionsui::CustomBoardState & optionsCustomBoardState() noexcept
bool processUIMessage(const uimsg::Message &message)
void resetRuleProjection()
rules::PlayerNumber chatSenderPlayer() noexcept
const optionsui::CustomBoardState & optionsCustomBoardStateReadOnly() noexcept
statsui::FutureImmunityState & statsFutureImmunityState() noexcept
std::expected< void, std::string > sendReadyResponses(std::uint32_t playerMask, std::int64_t serial)
bool dispatchTradeBatch(const std::vector< actions::Message > &batch)
const rules::GameState & ruleStateReadOnly()
std::optional< pieces::PieceMoveSpecialRequest > takePendingPieceMoveSpecial()
const optionsui::State & optionsStateReadOnly() noexcept
const optionsui::SaveRuntimeState & optionsSaveStateReadOnly() noexcept
const statsui::State & statsStateReadOnly() noexcept
bool beginTradeFromIBar(rules::PlayerNumber iBarPlayer) noexcept
statsui::CalculatorUIState & statsCalculatorState() noexcept
auctionui::State & auctionState() noexcept
bool beginOptionsFromIBar() noexcept
std::optional< pieces::PieceMovePlan > takePendingPieceMovePlan()
void processRuleMessage(const actions::Message &message)
std::optional< pieces::PieceIdleTransitionPlan > takePendingPieceIdleTransitionPlan()
const pieces::PieceIdleState & pieceIdleStateReadOnly()
const statsui::FutureImmunityState & statsFutureImmunityStateReadOnly() noexcept
std::optional< dice::RollRequest > takePendingDiceRoll()
const tradeui::State & tradeStateReadOnly() noexcept
statsui::State & statsState() noexcept
dice::PromptState & dicePromptState() noexcept
rules::GameState & ruleState()
tradeui::State & tradeState() noexcept
const ibar::RuleProjection & iBarRuleStateReadOnly() noexcept
optionsui::SaveRuntimeState & optionsSaveState() noexcept
const auctionui::State & auctionStateReadOnly() noexcept
const statsui::CalculatorUIState & statsCalculatorStateReadOnly() noexcept
optionsui::State & optionsState() noexcept
bool processRuleMessage(const actions::Message &message)
void resetSession() noexcept
rules::PlayerNumber toPlayer
rules::PlayerNumber fromPlayer
std::vector< std::uint8_t > binaryDataA
pieces::BoardCameraView desiredBoardCamera
bool firstTimeInitializationDone
bool modernHoldingsLayout