Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
PiecePlacement.cpp
Go to the documentation of this file.
1#include "PiecePlacement.hpp"
2
3#include "BoardGeometry.hpp"
4
5#include <array>
6#include <numbers>
7
8namespace monopoly::pieces
9{
10 namespace
11 {
12 constexpr float TokenXOffset = 19.0F;
13 constexpr float TokenZOffset = 30.0F;
14 constexpr std::uint8_t JustVisiting = 10;
15 constexpr std::uint8_t FreeParking = 20;
16 constexpr std::uint8_t GoToJail = 30;
17 constexpr std::uint8_t InJail = 40;
18 constexpr std::uint8_t OffBoard = 41;
19
21
22 struct RestingOffset { int x; int z; int degrees; };
23 using RestingRow = std::array<RestingOffset, RestingPositionCount>;
24
25 constexpr std::array<RestingRow, 5> RestingOffsets{{
26 RestingRow{{{-22, 7, 45}, {-22, -34, 45}, {23, 6, -45},
27 {-22, -14, 45}, {0, -38, -45}, {24, -40, -45}}},
28 RestingRow{{{9, -25, -135}, {-4, -24, -118}, {9, -13, -150},
29 {-6, -14, -40}, {-10, -25, -90}, {9, -10, -180}}},
30 RestingRow{{{7, 22, 45}, {-26, 22, 45}, {-38, -10, -45},
31 {-38, 11, 45}, {-9, 22, 45}, {-38, 27, -45}}},
32 RestingRow{{{-21, 10, 90}, {15, -10, -45}, {15, 10, -45},
33 {-21, -10, 90}, {-25, 0, 0}, {-29, -10, 0}}},
34 RestingRow{{{-20, 10, 90}, {20, -10, -90}, {20, 10, -90},
35 {-20, -10, 90}, {30, 0, 0}, {-15, 0, 0}}}
36 }};
37
38 constexpr std::array<RestingType, 41> RestingTypes{{
39 RestingType::GoFreeParking, RestingType::Property, RestingType::RailroadUtilityChance,
40 RestingType::Property, RestingType::RailroadUtilityChance, RestingType::RailroadUtilityChance,
41 RestingType::Property, RestingType::RailroadUtilityChance, RestingType::Property,
42 RestingType::Property, RestingType::JustVisiting, RestingType::Property,
43 RestingType::RailroadUtilityChance, RestingType::Property, RestingType::Property,
44 RestingType::RailroadUtilityChance, RestingType::Property, RestingType::RailroadUtilityChance,
45 RestingType::Property, RestingType::Property, RestingType::GoFreeParking,
46 RestingType::Property, RestingType::RailroadUtilityChance, RestingType::Property,
47 RestingType::Property, RestingType::RailroadUtilityChance, RestingType::Property,
48 RestingType::Property, RestingType::RailroadUtilityChance, RestingType::Property,
49 RestingType::GoFreeParking, RestingType::Property, RestingType::Property,
50 RestingType::RailroadUtilityChance, RestingType::Property, RestingType::RailroadUtilityChance,
51 RestingType::RailroadUtilityChance, RestingType::Property, RestingType::RailroadUtilityChance,
52 RestingType::Property, RestingType::InJail
53 }};
54
55 constexpr std::size_t typeIndex(RestingType value) noexcept
56 { return static_cast<std::size_t>(value); }
57
58 constexpr bool tokenHasRestingRotation(std::uint8_t token) noexcept
59 { return token == 0 || token == 1 || token == 2 || token == 6 || token == 7 || token == 9; }
60 }
61
62 std::optional<RestingIdleCategory> restingIdleCategory(
63 std::uint8_t boardSquare) noexcept
64 {
65 if (boardSquare >= BoardSquareCountWithSpecials) return std::nullopt;
67 if (boardSquare == OffBoard) return RestingIdleCategory::GoFreeParking;
69 return std::nullopt;
70 }
71 std::optional<TokenPose> tokenOrientation(std::uint8_t boardSquare) noexcept
72 {
73 if (boardSquare >= BoardSquareCountWithSpecials) return std::nullopt;
74 const auto square = boardSquare == InJail ? JustVisiting : boardSquare;
75 const auto& point = boardgeometry::locations3D()[square];
77 if (square < JustVisiting)
78 { pose.x = point.x + TokenZOffset; pose.z = point.z - TokenXOffset; pose.yaw = 0.0F; }
79 else if (square < FreeParking)
80 { pose.x = point.x - TokenXOffset; pose.z = point.z - TokenZOffset; pose.yaw = std::numbers::pi_v<float> / 2.0F; }
81 else if (square < GoToJail)
82 { pose.x = point.x - TokenZOffset; pose.z = point.z + TokenXOffset; pose.yaw = std::numbers::pi_v<float>; }
83 else
84 { pose.x = point.x + TokenXOffset; pose.z = point.z + TokenZOffset; pose.yaw = -std::numbers::pi_v<float> / 2.0F; }
85 return pose;
86 }
87
88 std::optional<TokenPose> tokenAnimationStartOrientation(
89 std::uint8_t boardSquare, data::DataId sequenceId) noexcept
90 {
92 if (!pose || boardSquare % 10 != 0) return pose;
93
94 constexpr data::DataTag CornerBase = 0x00F6;
95 constexpr std::uint32_t PerToken = 0x0063;
99 (static_cast<std::uint32_t>(data::dataTag(sequenceId)) - CornerBase) %
100 PerToken != 0U)
101 return pose;
102
103 pose->yaw -= std::numbers::pi_v<float> / 2.0F;
104 switch (boardSquare / 10)
105 {
106 case 3: pose->x += 15.0F; pose->z += 16.0F; break;
107 case 2: pose->x -= 15.0F; pose->z += 16.0F; break;
108 case 1: pose->x -= 16.0F; pose->z -= 15.0F; break;
109 default: pose->x += 16.0F; pose->z -= 15.0F; break;
110 }
111 return pose;
112 }
113
114 std::optional<TokenPose> tokenRestingOrientation(std::uint8_t boardSquare,
115 std::uint8_t restingPosition, std::uint8_t token) noexcept
116 {
118 restingPosition >= RestingPositionCount) return std::nullopt;
120 if (!pose) return std::nullopt;
121
122 RestingType type = RestingType::GoFreeParking;
123 bool applyPositionOffset = boardSquare != OffBoard;
124 if (boardSquare == InJail) type = RestingType::InJail;
125 else if (boardSquare < RestingTypes.size()) type = RestingTypes[boardSquare];
126 const auto& offset = RestingOffsets[typeIndex(type)][restingPosition];
127
129 {
131 { pose->x += static_cast<float>(offset.x); pose->z += static_cast<float>(offset.z); }
132 else if (boardSquare < FreeParking)
133 { pose->x += static_cast<float>(offset.z); pose->z -= static_cast<float>(offset.x); }
134 else if (boardSquare <= GoToJail)
135 { pose->x -= static_cast<float>(offset.x); pose->z -= static_cast<float>(offset.z); }
136 else
137 { pose->x -= static_cast<float>(offset.z); pose->z += static_cast<float>(offset.x); }
138 }
140 pose->yaw += std::numbers::pi_v<float> * static_cast<float>(offset.degrees) / 180.0F;
141 return pose;
142 }
143}
144
145namespace monopoly::pieces
146{
147 namespace
148 {
149 constexpr float HouseXLength = 9.0F;
150 constexpr float PropertyXWidth = 38.0F;
151 constexpr float PropertyZHeight = 64.5F;
152 constexpr float SwatchZHeight = 12.5F;
153 constexpr float HouseSpacing =
154 (PropertyXWidth - (4.0F * HouseXLength)) / 5.0F;
155 constexpr float BuildingZOffset = PropertyZHeight - (SwatchZHeight / 2.0F);
156 constexpr float HotelXOffset = PropertyXWidth / 2.0F;
157 constexpr std::array<float, 4> HouseXOffsets{{
158 HouseSpacing + (HouseXLength * 0.5F),
159 (HouseSpacing * 2.0F) + (HouseXLength * 1.5F),
160 (HouseSpacing * 3.0F) + (HouseXLength * 2.5F),
161 (HouseSpacing * 4.0F) + (HouseXLength * 3.5F)}};
162
163 std::optional<BuildingPose> buildingPosition(
164 std::uint8_t boardSquare, float xOffset) noexcept
165 {
166 if (boardSquare >= BoardSquareCountWithSpecials) return std::nullopt;
167 const auto square = boardSquare == InJail ? JustVisiting : boardSquare;
168 const auto& point = boardgeometry::locations3D()[square];
169 BuildingPose pose{};
170 if (square < JustVisiting)
171 {
172 pose.x = point.x + BuildingZOffset;
173 pose.z = point.z - xOffset;
174 pose.yaw = 0.0F;
175 }
176 else if (square < FreeParking)
177 {
178 pose.x = point.x - xOffset;
179 pose.z = point.z - BuildingZOffset;
180 pose.yaw = std::numbers::pi_v<float> / 2.0F;
181 }
182 else if (square < GoToJail)
183 {
184 pose.x = point.x - BuildingZOffset;
185 pose.z = point.z + xOffset;
186 pose.yaw = std::numbers::pi_v<float>;
187 }
188 else
189 {
190 pose.x = point.x + xOffset;
191 pose.z = point.z + BuildingZOffset;
192 pose.yaw = -std::numbers::pi_v<float> / 2.0F;
193 }
194 return pose;
195 }
196 }
197
198 std::optional<BuildingPose> hotelPosition(std::uint8_t boardSquare) noexcept
199 {
201 }
202
203 std::optional<BuildingPose> housePosition(
204 std::uint8_t boardSquare, std::uint8_t house) noexcept
205 {
206 if (house >= HouseXOffsets.size()) return std::nullopt;
208 }
209}
std::size_t offset
unsigned index
int token
int degrees
int z
std::uint16_t value
Definition Timers.cpp:16
const std::array< Point3D, 42 > & locations3D()
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataTag dataTag(DataId id) noexcept
Definition DataBanks.hpp:64
std::uint16_t DataTag
Definition DataBanks.hpp:11
constexpr std::uint16_t legacyGroupValue(LegacyGroupId group) noexcept
Definition DataBanks.hpp:30
constexpr std::uint16_t dataGroup(DataId id) noexcept
Definition DataBanks.hpp:57
std::optional< BuildingPose > housePosition(std::uint8_t boardSquare, std::uint8_t house) noexcept
std::optional< BuildingPose > hotelPosition(std::uint8_t boardSquare) noexcept
constexpr std::uint8_t BoardSquareCountWithSpecials
std::optional< RestingIdleCategory > restingIdleCategory(std::uint8_t boardSquare) noexcept
std::optional< TokenPose > tokenOrientation(std::uint8_t boardSquare) noexcept
constexpr std::uint8_t RestingPositionCount
std::optional< TokenPose > tokenAnimationStartOrientation(std::uint8_t boardSquare, data::DataId sequenceId) noexcept
std::optional< TokenPose > tokenRestingOrientation(std::uint8_t boardSquare, std::uint8_t restingPosition, std::uint8_t token) noexcept