NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_cc.hpp
1#pragma once
2#include <types.h>
3#include <game/bases/d_actor.hpp>
4
5/**
6 * @brief Collider ("Collision Check") class - handles collisions between actors.
7 *
8 * It also includes logic that handles collisions
9 * within a horizontally looping stage (like 2-C).
10 */
11class dCc_c {
12public:
14 CC_SHAPE_BOX, ///< Rectangular collider
15 CC_SHAPE_CIRCLE, ///< Circular / elliptical collider
16 CC_SHAPE_DAIKEI_UD, ///< Trapezoid-shaped collider (left/right sides are parallel)
17 CC_SHAPE_DAIKEI_LR, ///< Trapezoid-shaped collider (top/bottom sides are parallel)
18 };
19
21 CC_DATA_NO_OFFSET = 1, ///< Don't set the collision offset if a collision occurs
22 /**
23 * When another collider collides with this one,
24 * don't update the result or execute the callback
25 * on the other collider.
26 */
28 };
29
30 enum CC_FLAG_e {
31 CC_DISABLE = 2, ///< Disables all collisions with this collider
32 };
33
35 CAT_PLAYER_GENERIC,
36 /**
37 * This collider can attack, which means it will use mAttackCategory and
38 * mAttackCategoryInteract to further check if the colliders will collide.
39 */
41 CAT_YOSHI,
42 CAT_ENTITY,
43 CAT_BALLOON,
44 CAT_ITEM,
45 CAT_PROJECTILE,
46 CAT_CANNON,
47 CAT_GOAL_POLE
48 };
49
50 enum CC_ATTACK_e {
51 ATTACK_FIRE = 1,
52 ATTACK_ICE,
53 ATTACK_STAR,
54 ATTACK_ICE_BREAK,
55 ATTACK_SLIP,
56 ATTACK_KOOPA_FIRE,
57 ATTACK_HIP_ATTK,
58 ATTACK_WIRE_NET,
59 ATTACK_SHELL,
60 ATTACK_PENGUIN_SLIDE,
61 ATTACK_SPIN,
62 ATTACK_UNK12,
63 ATTACK_SPIN_FALL,
64 ATTACK_FIRE_2,
65 ATTACK_YOSHI_EAT,
66 ATTACK_YOSHI_MOUTH,
67 ATTACK_CANNON,
68 ATTACK_YOSHI_BULLET,
69 ATTACK_YOSHI_FIRE,
70 ATTACK_ICE_2,
71 ATTACK_SAND_PILLAR
72 };
73
74 /**
75 * @brief A structure that contains information about a collider.
76 * @unofficial
77 */
78 struct CcData_s {
79 float mOffsetX; ///< The X offset of the collider.
80 float mOffsetY; ///< The Y offset of the collider.
81
82 /**
83 * @brief The width of the collider.
84 *
85 * Note: This is the distance from the center to the edge, so half the actual width.
86 */
87 float mWidth;
88
89 /**
90 * @brief The height of the collider.
91 *
92 * Note: This is the distance from the center to the edge, so half the actual height.
93 */
94 float mHeight;
95
96 u8 mCategory; ///< The category of this collider. See @ref CC_CATEGORY_e .
97 u8 mAttackCategory; ///< The attack category of this collider. See @ref CC_ATTACK_e .
98 /**
99 * @brief Which categories this collider should be able to collide with.
100 *
101 * This is a bitfield with the bits enumerated by @ref CC_CATEGORY_e .
102 */
104 /**
105 * @brief Which attack categories this collider should be able to receive.
106 *
107 * This is a bitfield with the bits enumerated by @ref CC_ATTACK_e .
108 */
110
111 u16 mFlag; ///< Flags for this collider. See @ref CC_DATA_FLAG_e .
112
113 void (*mCallback)(dCc_c *, dCc_c *); ///< The callback to execute when a collision occurs.
114 };
115
116private:
117
118 // [Some unused class - but needed here because it has a static initializer.]
120 public:
121 u32 a, b, c;
122 bool d, e;
123
124 static class _init {
125 public:
126 _init() {
127 if (!dCc_c::msIsInitialized) {
128 dCc_c::msInitializedUnkClass.b = 0xa000a0;
129 dCc_c::msInitializedUnkClass.c = 0xa00000a0;
130 dCc_c::msIsInitialized = true;
131 }
132 }
133 } _initializer;
134 };
135 static char msIsInitialized; // [This might also be an auto-generated guard variable]
136 static InitializedUnkClass msInitializedUnkClass;
137
138public:
139 dCc_c(); ///< Constructs a new collider.
140 virtual ~dCc_c(); ///< Destroys the collider.
141
142 void clear(); ///< Clear the data related to previous collisions.
143
144 void entry(); ///< Places this collider in the collider list.
145 void release(); ///< Removes this collider from the collider list.
146
147 /**
148 * @brief Registers an owner actor to this collider and sets the collider data.
149 * @unofficial
150 * @param actor The actor to register.
151 * @param collInfo The collider data to set.
152 */
153 void registerCc(dActor_c *actor, CcData_s *collInfo);
154
155 /**
156 * @brief Registers an owner actor to this collider and sets the collider data.
157 * @unofficial
158 * @param actor The actor to register.
159 * @param collInfo The collider data to set.
160 * @param nonCollideMask The non-collide mask to set.
161 */
162 void registerCc(dActor_c *actor, CcData_s *collInfo, u8 nonCollideMask);
163
164 /// Sets a friend actor for this collider.
165 void setFriendActor(dActor_c *actor) { mFriendActor = actor; }
166
167 /**
168 * @brief Gets the result of a hit check.
169 * @param mask The mask to check.
170 * @return The result of the hit check.
171 */
172 u16 isHit(u16 mask) const;
173
174 /**
175 * @brief Gets the result of an attack hit check.
176 * @param mask The mask to check.
177 * @return The result of the attack hit check.
178 */
179 u16 isHitAtDmg(u16 mask) const;
180
181 float getTopPos(); ///< Gets the Y position of the top of the collider.
182 float getUnderPos(); ///< Gets the Y position of the bottom of the collider.
183 float getCenterPosY(); ///< Gets the Y position of the center of the collider.
184
185 float getRightPos(); ///< Gets the X position of the right side of the collider.
186 float getLeftPos(); ///< Gets the X position of the left side of the collider.
187 float getCenterPosX(); ///< Gets the X position of the center of the collider.
188
189 /// Gets the center of the collider as a vector.
192 }
193
194 /**
195 * @brief Checks if this collider is inside another collider.
196 *
197 * @param other The collider to check against.
198 */
199 bool isInside(dCc_c *other);
200
201private:
202 float getTrpOffset(int idx) {
203 return mTrpOffsets[idx];
204 }
205
206public:
207 /**
208 * @brief Checks for collisions between two colliders.
209 *
210 * @param c1 The first collider.
211 * @param c2 The second collider.
212 * @param active Whether to update the result and execute the callback if a collision occurs.
213 * @return Whether the first collider collided with the second collider.
214 */
215 static bool checkCollision(dCc_c *c1, dCc_c *c2, int active);
216
217 static void execute(); ///< Check all colliders against each other for collisions.
218
219 /**
220 * @brief Clears the collider list.
221 *
222 * It also sets the hit check to the correct type (normal / looping stage).
223 * Note that this does not clean up the colliders themselves!
224 */
225 static void reset();
226
227private:
228 /**
229 * @brief A hit check function for rectangular colliders. Used in _hitCheckNormal and _hitCheckLoop.
230 * @param c1 The first collider.
231 * @param c2 The second collider.
232 * @param pos1 The position of the first collider.
233 * @param pos2 The position of the second collider.
234 */
235 static bool _hitCheckSquare(dCc_c *c1, dCc_c *c2, mVec2_c pos1, mVec2_c pos2);
236
237 /// Check two rectangular colliders against each other for collisions without stage looping.
238 static bool _hitCheckNormal(dCc_c *c1, dCc_c *c2);
239 /// Check two rectangular colliders against each other for collisions with stage looping.
240 static bool _hitCheckLoop(dCc_c *c1, dCc_c *c2);
241 /// Check two circle colliders against each other for collisions.
242 static bool _hitCheckCircle(dCc_c *c1, dCc_c *c2);
243 /// Check a rectangular and a circle collider against each other for collisions.
244 static bool _hitCheckBoxCircle(dCc_c *c1, dCc_c *c2);
245
246 static int _lineCheckUD(mVec2_c p1, mVec2_c p2, float p3, float p4);
247 /// Check a rectangular collider against a trapezoid-shaped collider for collisions.
248 static bool _hitCheckDaikeiUD_R(dCc_c *ccBox, dCc_c *ccTrp);
249 /// Check a trapezoid-shaped collider against a rectangular collider for collisions.
250 static bool _hitCheckDaikeiUD(dCc_c *ccTrp, dCc_c *ccBox);
251
252 static int _lineCheckLR(mVec2_c p1, mVec2_c p2, float p3, float p4);
253 /// Check a rectangular collider against a trapezoid-shaped collider for collisions.
254 static bool _hitCheckDaikeiLR_R(dCc_c *ccBox, dCc_c *ccTrp);
255 /// Check a trapezoid-shaped collider against a rectangular collider for collisions.
256 static bool _hitCheckDaikeiLR(dCc_c *ccTrp, dCc_c *ccBox);
257
258private:
259 dActor_c *mpOwner; ///< The actor this collider belongs to.
260 dActor_c *mFriendActor; ///< A second actor that this collider will not collide with.
261
262 u32 unk2; ///< [Unused (?)].
263
264 dCc_c *mpNext; ///< The next collider in the list.
265 dCc_c *mpPrev; ///< The previous collider in the list.
266
267 u32 unk3; ///< [Unused (?)].
268
269 CcData_s mCcData; ///< The collision data of this collider.
270
271public:
272 /**
273 * @brief The X or Y offset of the four corners of a trapezoid-shaped collider.
274 *
275 * Relative to the center of the collider.
276 * If mShape is CC_SHAPE_DAIKEI_UD, this is the Y offset.
277 * If mShape is CC_SHAPE_DAIKEI_LR, this is the X offset.
278 */
279 float mTrpOffsets[4];
280
281 /**
282 * @brief The X offset for a collision.
283 *
284 * One entry per category. Each entry describes by how much the collider must be
285 * offset in the X direction in order to not collide with the other collider.
286 */
287 float mCollOffsetX[8];
288 /**
289 * @brief The Y offset for a collision.
290 *
291 * One entry per category. Each entry describes by how much the collider must be
292 * offset in the Y direction in order to not collide with the other collider.
293 */
294 float mCollOffsetY[8];
295
296 mVec2_c mCollPos; ///< The position where the last collision occurred.
297
298 u16 mCollidedWith; ///< The categories of the previously collided with colliders.
299 u16 mAttSent; ///< The attack types sent by this collider in the previous collisions.
300 u16 mAttReceived; ///< The attack types received by this collider in the previous collisions.
301
302 u8 mShape; ///< The shape of the collider. See @ref CC_SHAPE_e .
303
304 /**
305 * @brief The non-collide mask for this collider.
306 *
307 * If the same bit is set in a second actor's non-collide mask,
308 * the two actors will not collide.
309 */
311
312 /**
313 * @brief The layer this collider is on.
314 *
315 * Colliders can only collide with other colliders on the same layer.
316 */
318
319 u8 mFlag; ///< Flags for this collider. See @ref CC_FLAG_e .
320
321private:
322 bool mIsLinked; ///< Whether this collider has been placed in the collider list.
323
324 typedef bool (*hitCheck)(dCc_c *, dCc_c *);
325
326 /**
327 * @brief The hit check function for each combination of collider shapes.
328 *
329 * The first index is the shape of the first collider and the second index
330 * is the shape of the second collider.
331 */
332 static hitCheck _hitCheck[4][4];
333
334 static dCc_c *mEntryN; ///< The first collider in the list.
335 static dCc_c *mEntryB; ///< The last collider in the list.
336};
Collider ("Collision Check") class - handles collisions between actors.
Definition d_cc.hpp:11
mVec2_c getCenterVec()
Gets the center of the collider as a vector.
Definition d_cc.hpp:190
static bool _hitCheckSquare(dCc_c *c1, dCc_c *c2, mVec2_c pos1, mVec2_c pos2)
A hit check function for rectangular colliders. Used in _hitCheckNormal and _hitCheckLoop.
Definition d_cc.cpp:268
bool mIsLinked
Whether this collider has been placed in the collider list.
Definition d_cc.hpp:322
u8 mFlag
Flags for this collider. See CC_FLAG_e .
Definition d_cc.hpp:319
static bool checkCollision(dCc_c *c1, dCc_c *c2, int active)
Checks for collisions between two colliders.
Definition d_cc.cpp:164
u8 mNonCollideMask
The non-collide mask for this collider.
Definition d_cc.hpp:310
static bool _hitCheckDaikeiUD_R(dCc_c *ccBox, dCc_c *ccTrp)
Check a rectangular collider against a trapezoid-shaped collider for collisions.
Definition d_cc.cpp:504
dActor_c * mpOwner
The actor this collider belongs to.
Definition d_cc.hpp:259
float getUnderPos()
Gets the Y position of the bottom of the collider.
Definition d_cc.cpp:124
static bool _hitCheckLoop(dCc_c *c1, dCc_c *c2)
Check two rectangular colliders against each other for collisions with stage looping.
Definition d_cc.cpp:317
u32 unk3
[Unused (?)].
Definition d_cc.hpp:267
CC_CATEGORY_e
Definition d_cc.hpp:34
@ CAT_PLAYER_ATTACK
Definition d_cc.hpp:40
float getTopPos()
Gets the Y position of the top of the collider.
Definition d_cc.cpp:120
static dCc_c * mEntryN
The first collider in the list.
Definition d_cc.hpp:334
u16 isHitAtDmg(u16 mask) const
Gets the result of an attack hit check.
Definition d_cc.cpp:116
float mTrpOffsets[4]
The X or Y offset of the four corners of a trapezoid-shaped collider.
Definition d_cc.hpp:279
dCc_c * mpPrev
The previous collider in the list.
Definition d_cc.hpp:265
void clear()
Clear the data related to previous collisions.
Definition d_cc.cpp:37
float getCenterPosY()
Gets the Y position of the center of the collider.
Definition d_cc.cpp:128
float mCollOffsetY[8]
The Y offset for a collision.
Definition d_cc.hpp:294
void entry()
Places this collider in the collider list.
Definition d_cc.cpp:48
u16 mCollidedWith
The categories of the previously collided with colliders.
Definition d_cc.hpp:298
u8 mShape
The shape of the collider. See CC_SHAPE_e .
Definition d_cc.hpp:302
u16 mAttSent
The attack types sent by this collider in the previous collisions.
Definition d_cc.hpp:299
u32 unk2
[Unused (?)].
Definition d_cc.hpp:262
u16 isHit(u16 mask) const
Gets the result of a hit check.
Definition d_cc.cpp:112
static hitCheck _hitCheck[4][4]
The hit check function for each combination of collider shapes.
Definition d_cc.hpp:16
u16 mAttReceived
The attack types received by this collider in the previous collisions.
Definition d_cc.hpp:300
u8 mLayer
The layer this collider is on.
Definition d_cc.hpp:317
CC_SHAPE_e
Definition d_cc.hpp:13
@ CC_SHAPE_BOX
Rectangular collider.
Definition d_cc.hpp:14
@ CC_SHAPE_DAIKEI_UD
Trapezoid-shaped collider (left/right sides are parallel)
Definition d_cc.hpp:16
@ CC_SHAPE_DAIKEI_LR
Trapezoid-shaped collider (top/bottom sides are parallel)
Definition d_cc.hpp:17
@ CC_SHAPE_CIRCLE
Circular / elliptical collider.
Definition d_cc.hpp:15
void registerCc(dActor_c *actor, CcData_s *collInfo)
Registers an owner actor to this collider and sets the collider data.
Definition d_cc.cpp:87
CcData_s mCcData
The collision data of this collider.
Definition d_cc.hpp:269
float getCenterPosX()
Gets the X position of the center of the collider.
Definition d_cc.cpp:140
static bool _hitCheckCircle(dCc_c *c1, dCc_c *c2)
Check two circle colliders against each other for collisions.
Definition d_cc.cpp:341
float getLeftPos()
Gets the X position of the left side of the collider.
Definition d_cc.cpp:136
CC_DATA_FLAG_e
Definition d_cc.hpp:20
@ CC_DATA_NO_OFFSET
Don't set the collision offset if a collision occurs.
Definition d_cc.hpp:21
@ CC_DATA_PASSIVE
Definition d_cc.hpp:27
mVec2_c mCollPos
The position where the last collision occurred.
Definition d_cc.hpp:296
float getRightPos()
Gets the X position of the right side of the collider.
Definition d_cc.cpp:132
static bool _hitCheckDaikeiLR_R(dCc_c *ccBox, dCc_c *ccTrp)
Check a rectangular collider against a trapezoid-shaped collider for collisions.
Definition d_cc.cpp:576
virtual ~dCc_c()
Destroys the collider.
Definition d_cc.cpp:33
static void execute()
Check all colliders against each other for collisions.
Definition d_cc.cpp:260
dActor_c * mFriendActor
A second actor that this collider will not collide with.
Definition d_cc.hpp:260
void release()
Removes this collider from the collider list.
Definition d_cc.cpp:66
float mCollOffsetX[8]
The X offset for a collision.
Definition d_cc.hpp:287
static bool _hitCheckDaikeiLR(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
Definition d_cc.cpp:580
CC_FLAG_e
Definition d_cc.hpp:30
@ CC_DISABLE
Disables all collisions with this collider.
Definition d_cc.hpp:31
void setFriendActor(dActor_c *actor)
Sets a friend actor for this collider.
Definition d_cc.hpp:165
static bool _hitCheckBoxCircle(dCc_c *c1, dCc_c *c2)
Check a rectangular and a circle collider against each other for collisions.
Definition d_cc.cpp:387
static void reset()
Clears the collider list.
Definition d_cc.cpp:98
dCc_c * mpNext
The next collider in the list.
Definition d_cc.hpp:264
dCc_c()
Constructs a new collider.
Definition d_cc.cpp:23
static dCc_c * mEntryB
The last collider in the list.
Definition d_cc.hpp:335
static bool _hitCheckNormal(dCc_c *c1, dCc_c *c2)
Check two rectangular colliders against each other for collisions without stage looping.
Definition d_cc.cpp:311
static bool _hitCheckDaikeiUD(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
Definition d_cc.cpp:508
bool isInside(dCc_c *other)
Checks if this collider is inside another collider.
Definition d_cc.cpp:144
A two-dimensional floating point vector.
Definition m_vec.hpp:9
A structure that contains information about a collider.
Definition d_cc.hpp:78
void(* mCallback)(dCc_c *, dCc_c *)
The callback to execute when a collision occurs.
Definition d_cc.hpp:113
float mHeight
The height of the collider.
Definition d_cc.hpp:94
u32 mAttackCategoryInteract
Which attack categories this collider should be able to receive.
Definition d_cc.hpp:109
u8 mAttackCategory
The attack category of this collider. See CC_ATTACK_e .
Definition d_cc.hpp:97
float mOffsetX
The X offset of the collider.
Definition d_cc.hpp:79
u32 mCategoryInteract
Which categories this collider should be able to collide with.
Definition d_cc.hpp:103
float mWidth
The width of the collider.
Definition d_cc.hpp:87
u16 mFlag
Flags for this collider. See CC_DATA_FLAG_e .
Definition d_cc.hpp:111
float mOffsetY
The Y offset of the collider.
Definition d_cc.hpp:80
u8 mCategory
The category of this collider. See CC_CATEGORY_e .
Definition d_cc.hpp:96