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