18 std::array<PropertyPlayback::ObjectState, TradePropertyPlaybackObjectCount>;
21 const PropertyProjection& projection,
22 std::size_t
box)
noexcept
26 case 0:
return {projection.before[0], projection.beforeMortgaged[0]};
27 case 1:
return {projection.before[1], projection.beforeMortgaged[1]};
28 case 2:
return {projection.offered[0], projection.offeredMortgaged[0]};
29 case 3:
return {projection.offered[1], projection.offeredMortgaged[1]};
36 std::uint8_t toBox)
noexcept
38 return (fromBox == 0 && toBox == 2) ||
39 (fromBox == 1 && toBox == 3) ||
40 (fromBox == 2 && toBox == 0) ||
41 (fromBox == 3 && toBox == 1);
48 const PropertyMoveRequest* moving)
57 const auto [normal, mortgaged] =
boxMasks(projection,
box);
58 const auto visible = normal | mortgaged;
61 if (moving && moving->toBox ==
box && moving->square == square)
65 if (
bit == 0 || (visible &
bit) == 0)
70 const auto&
rect = projection.hitRects[
box][
static_cast<std::size_t
>(square)];
72 return std::unexpected(
"trade deed projection contains invalid property geometry");
74 const auto offset = projection.priorities[
box][
static_cast<std::size_t
>(square)];
76 return std::unexpected(
"trade deed projection contains invalid priority");
78 static_cast<std::size_t
>(square);
81 static_cast<std::uint16_t
>(
96 const auto base = mortgaged
114 std::optional<MovingState>
nextMoving = moving_;
128 const auto& request = *
state.propertyMove;
129 if (request.square < 0 ||
132 request.from.right <= request.from.left ||
133 request.from.bottom <= request.from.top ||
134 request.to.right <= request.to.left ||
135 request.to.bottom <= request.to.top)
137 return std::unexpected(
"trade deed move request is invalid");
142 return std::unexpected(
"trade deed move request references non-property square");
143 if (
gameState.squares[
static_cast<std::size_t
>(request.square)].mortgaged !=
146 return std::unexpected(
"trade deed move request mortgage state changed");
150 move.request = request;
155 move.x = request.from.left + move.deltaX;
156 move.y = request.from.top + move.deltaY;
158 move.lastMoveMs =
nowMs;
165 return std::unexpected(
"trade deed move request changed during playback");
194 return std::unexpected(
desired.error());
196 std::array<std::shared_ptr<const sequence::SequenceProgram>,
200 const auto& before = current_[
index];
201 const auto& after = (*desired)[
index];
203 (before.id != after.id || before.priority != after.priority);
209 return std::unexpected(
loaded.error().detail);
213 std::shared_ptr<const sequence::SequenceProgram>
movingProgram;
219 return std::unexpected(
loaded.error().detail);
227 !
state.cashDialogVisible)
238 else if (
hover == checkedHover_)
243 const int square =
hover % 100;
244 const bool mortgaged =
gameState.squares[
245 static_cast<std::size_t
>(square)].mortgaged;
251 + 28 * std::max(city, 0)));
259 if (checkedHover_ == -1)
263 std::shared_ptr<const sequence::SequenceProgram>
hoverProgram;
268 return std::unexpected(
loaded.error());
272 std::vector<sequence::SequenceCommand> commands;
276 moving_->id, moving_->priority,
false});
281 const auto& before = current_[
index];
282 const auto& after = (*desired)[
index];
284 before.id != after.id || before.priority != after.priority;
289 before.id, before.
priority,
false});
296 after.id, after.priority, after.x, after.y));
299 (before.x != after.x || before.y != after.y))
302 after.id, after.priority, after.x, after.y));
338 return std::unexpected(
339 "sequence command queue cannot fit trade deed transition");
342 for (
auto& command : commands)
344 const auto queued = std::visit(
351 return std::unexpected(
"validated trade deed command rejected");
364 state.propertyMove.reset();
375 hoverDeedRightPanel_ =
false;
static constexpr std::size_t Capacity
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(State &state, const rules::GameState &gameState, display::Screen2D desiredView, std::uint64_t nowMs, engine::SequencePlayback &playback, const mouse::State &pointer={}, std::uint64_t hoverTick=0, int city=0)
constexpr DataId EmptyDataId
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
int propertyIndex(int square) noexcept
PropertyMask propertyBit(int square) noexcept
constexpr data::DataTag PropertyHoverNormalBaseTag
constexpr data::DataTag PropertyHoverMortgagedBaseTag
constexpr std::size_t SquareCount
MoveSequenceCommand makeMoveXY(data::DataId dataId, std::uint16_t priority, std::int32_t x, std::int32_t y) noexcept
PropertyProjection projectProperties(const State &state, const rules::GameState &gameState) noexcept
constexpr std::uint64_t TradeDeedHoverDelayTicks
constexpr std::uint16_t TradeDeedHoverPriority
std::optional< int > propertyHit(const PropertyProjection &projection, int x, int y) noexcept
constexpr std::array< std::uint16_t, 4 > TradePropertyBasePriorities
constexpr data::DataTag TradePropertyNormalBaseTag
constexpr int TradePropertyMoveSteps
constexpr std::uint64_t TradePropertyMoveStepMs
constexpr data::DataTag TradePropertyMortgagedBaseTag
constexpr std::array< std::uint16_t, 4 > TradePropertyMovingPriorities
constexpr std::size_t TradePropertyPlaybackObjectCount
data::DataId tradePropertyDataId(int square, bool mortgaged) noexcept