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/mLib/m_vec.hpp>
4
5class dActor_c;
6
7///< @unofficial
8enum CC_SHAPE_e {
9 CC_SHAPE_BOX, ///< Rectangular collider
10 CC_SHAPE_CIRCLE, ///< Circular / elliptical collider
11 CC_SHAPE_DAIKEI_UD, ///< Trapezoid-shaped collider (left/right sides are parallel)
12 CC_SHAPE_DAIKEI_LR, ///< Trapezoid-shaped collider (top/bottom sides are parallel)
13};
14
15///< @unofficial
16enum CC_STATUS_FLAG_e {
17 CC_STATUS_NONE = 0,
18 CC_STATUS_NO_REVISION = BIT_FLAG(0), ///< Don't set the collision offset if a collision occurs
19 /**
20 * When another collider collides with this one,
21 * don't update the result or execute the callback
22 * on the other collider.
23 */
24 CC_STATUS_NO_PASS_INFO = BIT_FLAG(2),
25 CC_STATUS_8 = BIT_FLAG(8),
26};
27
28///< @unofficial
29enum CC_INFO_e {
30 CC_NO_HIT = BIT_FLAG(1), ///< Disables all collisions with this collider
31};
32
33///< @unofficial
34enum CC_KIND_e {
35 CC_KIND_PLAYER,
36 /**
37 * This collider can attack, which means it will use mAttackCategory and
38 * mAttackCategoryInteract to further check if the colliders will collide.
39 */
40 CC_KIND_PLAYER_ATTACK,
41 CC_KIND_YOSHI,
42 CC_KIND_ENEMY,
43 CC_KIND_BALLOON,
44 CC_KIND_ITEM,
45 CC_KIND_TAMA,
46 CC_KIND_KILLER,
47 CC_KIND_GOAL_POLE,
48 CC_KIND_COUNT = CC_KIND_GOAL_POLE // Goal pole is special and doesn't count
49};
50
51///< @unofficial
52enum CC_ATTACK_e {
53 CC_ATTACK_NONE,
54 CC_ATTACK_FIREBALL,
55 CC_ATTACK_ICEBALL,
56 CC_ATTACK_STAR,
57 CC_ATTACK_ICE_BREAK,
58 CC_ATTACK_SLIP,
59 CC_ATTACK_KOOPA_FIRE,
60 CC_ATTACK_HIP_ATTACK,
61 CC_ATTACK_WIRE_NET,
62 CC_ATTACK_SHELL,
63 CC_ATTACK_PENGUIN_SLIDE,
64 CC_ATTACK_SPIN,
65 CC_ATTACK_UNK12,
66 CC_ATTACK_SPIN_FALL,
67 CC_ATTACK_FIRE_2,
68 CC_ATTACK_YOSHI_EAT,
69 CC_ATTACK_YOSHI_MOUTH,
70 CC_ATTACK_CANNON,
71 CC_ATTACK_SPIN_LIFT_UP,
72 CC_ATTACK_YOSHI_BULLET,
73 CC_ATTACK_YOSHI_FIRE,
74 CC_ATTACK_ICE_2,
75 CC_ATTACK_SAND_PILLAR,
76};
77
78class dCc_c;
79
80/// @unofficial
81struct sCcDatNew {
82 mVec2_POD_c mOffset; ///< The offset of the collider.
83
84 ///< @brief The size of the collider.
85 ///< Note: This is the distance from the center to the edge, so half the actual size.
86 mVec2_POD_c mSize;
87
88 void set(const sCcDatNew &other) {
89 mOffset = other.mOffset;
90 mSize = other.mSize;
91 }
92};
93
94/**
95* @brief A structure that contains information about a collider.
96* @unofficial
97*/
98struct sCcDatNewF {
99 sCcDatNew mBase; ///< Base collider data.
100
101 u8 mKind; ///< The type of this collider. See CC_KIND_e.
102 u8 mAttack; ///< The attack type of this collider. See CC_ATTACK_e.
103
104 ///< @brief Which types this collider should be able to collide with.
105 ///< This is a bitfield with the bits enumerated by CC_KIND_e.
107
108 ///< @brief Which attack types this collider should be able to receive.
109 ///< This is a bitfield with the bits enumerated by CC_ATTACK_e.
110 u32 mVsDamage;
111
112 u16 mStatus; ///< Status flags for this collider. See CC_STATUS_FLAG_e.
113
114 void (*mCallback)(dCc_c *self, dCc_c *target); ///< The callback to execute when a collision occurs.
115
116 void set(const sCcDatNewF &other) {
117 mBase.set(other.mBase);
118 mKind = other.mKind;
119 mAttack = other.mAttack;
120 mVsKind = other.mVsKind;
121 mVsDamage = other.mVsDamage;
122 mStatus = other.mStatus;
123 mCallback = other.mCallback;
124 }
125};
126
127/**
128 * @brief Collider ("Collision Check") class - handles collisions between actors.
129 *
130 * It also includes logic that handles collisions
131 * within a horizontally looping stage (like 2-C).
132 */
133class dCc_c {
134public:
135 ///< @unofficial
136 class U32Holder {
137 public:
138 U32Holder(u32 value) : mValue(value) {}
139
140 u32 mValue;
141 };
142
143 ///< @unofficial
145 u32 a;
146 U32Holder b;
147 U32Holder c;
148 bool d, e;
149 };
150
151public:
152 dCc_c(); ///< Constructs a new collider.
153 virtual ~dCc_c(); ///< Destroys the collider.
154
155 void clear(); ///< Clear the data related to previous collisions.
156
157 void entry(); ///< Places this collider in the collider list.
158 void release(); ///< Removes this collider from the collider list.
159
160 /**
161 * @brief Registers an owner actor to this collider and sets the collider data.
162 * @param actor The actor to register.
163 * @param collInfo The collider data to set.
164 */
165 void set(dActor_c *actor, sCcDatNewF *collInfo);
166
167 /**
168 * @brief Registers an owner actor to this collider and sets the collider data.
169 * @param actor The actor to register.
170 * @param collInfo The collider data to set.
171 * @param amiLine The chainline fence layer to set.
172 */
173 void set(dActor_c *actor, sCcDatNewF *collInfo, u8 amiLine);
174
175 /// Sets a friend actor for this collider.
176 void setFriendActor(dActor_c *actor) { mpFriendActor = actor; }
177
178 dActor_c *getOwner() const { return mpOwner; } ///< Gets the owner actor of this collider.
179
180 /**
181 * @brief Gets the result of a hit check.
182 * @param mask The mask to check.
183 * @return The result of the hit check.
184 */
185 u16 isHit(u16 mask) const;
186
187 /**
188 * @brief Gets the result of an attack hit check.
189 * @param mask The mask to check.
190 * @return The result of the attack hit check.
191 */
192 u16 isHitAtDmg(u16 mask) const;
193
194 float getTopPos(); ///< Gets the Y position of the top of the collider.
195 float getUnderPos(); ///< Gets the Y position of the bottom of the collider.
196 float getCenterPosY(); ///< Gets the Y position of the center of the collider.
197
198 float getRightPos(); ///< Gets the X position of the right side of the collider.
199 float getLeftPos(); ///< Gets the X position of the left side of the collider.
200 float getCenterPosX(); ///< Gets the X position of the center of the collider.
201
202 /// Gets the center of the collider as a vector.
205 }
206
207 /**
208 * @brief Checks if this collider is inside another collider.
209 *
210 * @param other The collider to check against.
211 */
212 bool isInside(dCc_c *other);
213
214private:
215 float getTrpOffset(int idx) {
216 return mTrpOffsets[idx];
217 }
218
219public:
220 /**
221 * @brief Checks for collisions between two colliders.
222 *
223 * @param c1 The first collider.
224 * @param c2 The second collider.
225 * @param active Whether to update the result and execute the callback if a collision occurs.
226 * @return Whether the first collider collided with the second collider.
227 */
228 static bool checkCollision(dCc_c *c1, dCc_c *c2, int active);
229
230 static void execute(); ///< Check all colliders against each other for collisions.
231
232 /**
233 * @brief Clears the collider list.
234 *
235 * It also sets the hit check to the correct type (normal / looping stage).
236 * Note that this does not clean up the colliders themselves!
237 */
238 static void reset();
239
240 float getCollPosX() const { return mCollPos.x; }
241 float getCollPosY() const { return mCollPos.y; }
242
243private:
244 /**
245 * @brief A hit check function for rectangular colliders. Used in _hitCheckNormal and _hitCheckLoop.
246 * @param c1 The first collider.
247 * @param c2 The second collider.
248 * @param pos1 The position of the first collider.
249 * @param pos2 The position of the second collider.
250 */
251 static bool _hitCheckSquare(dCc_c *c1, dCc_c *c2, mVec2_c pos1, mVec2_c pos2);
252
253 /// Check two rectangular colliders against each other for collisions without stage looping.
254 static bool _hitCheckNormal(dCc_c *c1, dCc_c *c2);
255 /// Check two rectangular colliders against each other for collisions with stage looping.
256 static bool _hitCheckLoop(dCc_c *c1, dCc_c *c2);
257 /// Check two circle colliders against each other for collisions.
258 static bool _hitCheckCircle(dCc_c *c1, dCc_c *c2);
259 /// Check a rectangular and a circle collider against each other for collisions.
260 static bool _hitCheckBoxCircle(dCc_c *c1, dCc_c *c2);
261
262 static int _lineCheckUD(mVec2_c p1, mVec2_c p2, float p3, float p4);
263 /// Check a rectangular collider against a trapezoid-shaped collider for collisions.
264 static bool _hitCheckDaikeiUD_R(dCc_c *ccBox, dCc_c *ccTrp);
265 /// Check a trapezoid-shaped collider against a rectangular collider for collisions.
266 static bool _hitCheckDaikeiUD(dCc_c *ccTrp, dCc_c *ccBox);
267
268 static int _lineCheckLR(mVec2_c p1, mVec2_c p2, float p3, float p4);
269 /// Check a rectangular collider against a trapezoid-shaped collider for collisions.
270 static bool _hitCheckDaikeiLR_R(dCc_c *ccBox, dCc_c *ccTrp);
271 /// Check a trapezoid-shaped collider against a rectangular collider for collisions.
272 static bool _hitCheckDaikeiLR(dCc_c *ccTrp, dCc_c *ccBox);
273
274public:
275 float getXOffset(int idx) { return mCollOffsetX[idx]; }
276 float getYOffset(int idx) { return mCollOffsetY[idx]; }
277
278 dActor_c *mpOwner; ///< The actor this collider belongs to.
279 dActor_c *mpFriendActor; ///< A second actor that this collider will not collide with.
280
281 u32 unk2; ///< [Unused (?)].
282
283 dCc_c *mpNext; ///< The next collider in the list.
284 dCc_c *mpPrev; ///< The previous collider in the list.
285
286 u32 mCanBounce; ///< [used by Giant Wigglers to allow jumping].
287
288 sCcDatNewF mCcData; ///< The collision data of this collider.
289
290 /**
291 * @brief The X or Y offset of the four corners of a trapezoid-shaped collider.
292 *
293 * Relative to the center of the collider.
294 * If mShape is CC_SHAPE_DAIKEI_UD, this is the Y offset.
295 * If mShape is CC_SHAPE_DAIKEI_LR, this is the X offset.
296 */
297 float mTrpOffsets[4];
298
299 /**
300 * @brief The X offset for a collision.
301 *
302 * One entry per kind. Each entry describes by how much the collider must be
303 * offset in the X direction in order to not collide with the other collider.
304 */
305 float mCollOffsetX[CC_KIND_COUNT];
306 /**
307 * @brief The Y offset for a collision.
308 *
309 * One entry per kind. Each entry describes by how much the collider must be
310 * offset in the Y direction in order to not collide with the other collider.
311 */
312 float mCollOffsetY[CC_KIND_COUNT];
313
314 mVec2_c mCollPos; ///< The position where the last collision occurred.
315
316 u16 mCollidedWith; ///< The categories of the previously collided with colliders.
317 u16 mAttSent; ///< The attack types sent by this collider in the previous collisions.
318 u16 mAttReceived; ///< The attack types received by this collider in the previous collisions.
319
320 u8 mShape; ///< The shape of the collider. See @ref CC_SHAPE_e .
321
322 /**
323 * @brief The non-collide mask for this collider.
324 *
325 * If the same bit is set in a second actor's non-collide mask,
326 * the two actors will not collide.
327 */
329
330 /**
331 * @brief The layer this collider is on.
332 *
333 * Colliders can only collide with other colliders on the same layer.
334 */
336
337 u8 mInfo; ///< Info flags for this collider. See CC_INFO_e.
338
339private:
340 bool mIsLinked; ///< Whether this collider has been placed in the collider list.
341
342private:
343 typedef bool (*hitCheck)(dCc_c *, dCc_c *);
344
345 /**
346 * @brief The hit check function for each combination of collider shapes.
347 *
348 * The first index is the shape of the first collider and the second index
349 * is the shape of the second collider.
350 */
351 static hitCheck _hitCheck[4][4];
352
353 static dCc_c *mEntryN; ///< The first collider in the list.
354 static dCc_c *mEntryB; ///< The last collider in the list.
355};
The minimum required implementation for a stage actor.
Definition d_actor.hpp:15
Collider ("Collision Check") class - handles collisions between actors.
Definition d_cc.hpp:133
void set(dActor_c *actor, sCcDatNewF *collInfo)
Registers an owner actor to this collider and sets the collider data.
Definition d_cc.cpp:91
mVec2_c getCenterVec()
Gets the center of the collider as a vector.
Definition d_cc.hpp:203
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:272
bool mIsLinked
Whether this collider has been placed in the collider list.
Definition d_cc.hpp:340
static bool checkCollision(dCc_c *c1, dCc_c *c2, int active)
Checks for collisions between two colliders.
Definition d_cc.cpp:168
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:508
dActor_c * mpOwner
The actor this collider belongs to.
Definition d_cc.hpp:278
float getUnderPos()
Gets the Y position of the bottom of the collider.
Definition d_cc.cpp:128
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:321
float getTopPos()
Gets the Y position of the top of the collider.
Definition d_cc.cpp:124
static dCc_c * mEntryN
The first collider in the list.
Definition d_cc.hpp:353
u16 isHitAtDmg(u16 mask) const
Gets the result of an attack hit check.
Definition d_cc.cpp:120
u8 mInfo
Info flags for this collider. See CC_INFO_e.
Definition d_cc.hpp:337
float mTrpOffsets[4]
The X or Y offset of the four corners of a trapezoid-shaped collider.
Definition d_cc.hpp:297
dCc_c * mpPrev
The previous collider in the list.
Definition d_cc.hpp:284
void clear()
Clear the data related to previous collisions.
Definition d_cc.cpp:41
float getCenterPosY()
Gets the Y position of the center of the collider.
Definition d_cc.cpp:132
void entry()
Places this collider in the collider list.
Definition d_cc.cpp:52
u16 mCollidedWith
The categories of the previously collided with colliders.
Definition d_cc.hpp:316
float mCollOffsetY[CC_KIND_COUNT]
The Y offset for a collision.
Definition d_cc.hpp:312
u8 mShape
The shape of the collider. See CC_SHAPE_e .
Definition d_cc.hpp:320
u16 mAttSent
The attack types sent by this collider in the previous collisions.
Definition d_cc.hpp:317
u32 unk2
[Unused (?)].
Definition d_cc.hpp:281
u16 isHit(u16 mask) const
Gets the result of a hit check.
Definition d_cc.cpp:116
static hitCheck _hitCheck[4][4]
The hit check function for each combination of collider shapes.
Definition d_cc.hpp:20
u16 mAttReceived
The attack types received by this collider in the previous collisions.
Definition d_cc.hpp:318
u8 mLayer
The layer this collider is on.
Definition d_cc.hpp:335
float getCenterPosX()
Gets the X position of the center of the collider.
Definition d_cc.cpp:144
static bool _hitCheckCircle(dCc_c *c1, dCc_c *c2)
Check two circle colliders against each other for collisions.
Definition d_cc.cpp:345
float getLeftPos()
Gets the X position of the left side of the collider.
Definition d_cc.cpp:140
mVec2_c mCollPos
The position where the last collision occurred.
Definition d_cc.hpp:314
float mCollOffsetX[CC_KIND_COUNT]
The X offset for a collision.
Definition d_cc.hpp:305
float getRightPos()
Gets the X position of the right side of the collider.
Definition d_cc.cpp:136
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:580
virtual ~dCc_c()
Destroys the collider.
Definition d_cc.cpp:37
static void execute()
Check all colliders against each other for collisions.
Definition d_cc.cpp:264
dActor_c * getOwner() const
Gets the owner actor of this collider.
Definition d_cc.hpp:178
void release()
Removes this collider from the collider list.
Definition d_cc.cpp:70
u32 mCanBounce
[used by Giant Wigglers to allow jumping].
Definition d_cc.hpp:286
sCcDatNewF mCcData
The collision data of this collider.
Definition d_cc.hpp:288
static bool _hitCheckDaikeiLR(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
Definition d_cc.cpp:584
u8 mAmiLine
The non-collide mask for this collider.
Definition d_cc.hpp:328
void setFriendActor(dActor_c *actor)
Sets a friend actor for this collider.
Definition d_cc.hpp:176
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:391
static void reset()
Clears the collider list.
Definition d_cc.cpp:102
dCc_c * mpNext
The next collider in the list.
Definition d_cc.hpp:283
dCc_c()
Constructs a new collider.
Definition d_cc.cpp:27
static dCc_c * mEntryB
The last collider in the list.
Definition d_cc.hpp:354
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:315
static bool _hitCheckDaikeiUD(dCc_c *ccTrp, dCc_c *ccBox)
Check a trapezoid-shaped collider against a rectangular collider for collisions.
Definition d_cc.cpp:512
dActor_c * mpFriendActor
A second actor that this collider will not collide with.
Definition d_cc.hpp:279
bool isInside(dCc_c *other)
Checks if this collider is inside another collider.
Definition d_cc.cpp:148
A two-dimensional floating point vector.
Definition m_vec.hpp:26
A structure that contains information about a collider.
Definition d_cc.hpp:98
void(* mCallback)(dCc_c *self, dCc_c *target)
The callback to execute when a collision occurs.
Definition d_cc.hpp:114
u8 mKind
The type of this collider. See CC_KIND_e.
Definition d_cc.hpp:101
u8 mAttack
The attack type of this collider. See CC_ATTACK_e.
Definition d_cc.hpp:102
sCcDatNew mBase
Base collider data.
Definition d_cc.hpp:99
u16 mStatus
Status flags for this collider. See CC_STATUS_FLAG_e.
Definition d_cc.hpp:112
u32 mVsKind
Which attack types this collider should be able to receive. This is a bitfield with the bits enumerat...
Definition d_cc.hpp:106
mVec2_POD_c mOffset
The offset of the collider.
Definition d_cc.hpp:82