NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_enemy.cpp
1#include <game/bases/d_enemy.hpp>
2#include <game/bases/d_bc.hpp>
3#include <game/bases/d_quake.hpp>
4#include <game/mLib/m_effect.hpp>
5#include <game/bases/d_a_player.hpp>
6#include <game/bases/d_a_player_manager.hpp>
7#include <game/bases/d_bg.hpp>
8#include <game/bases/d_score_mng.hpp>
9#include <game/bases/d_ef.hpp>
10#include <game/bases/d_effectmanager.hpp>
11#include <game/bases/d_effactor_mng.hpp>
13#include <game/bases/d_multi_mng.hpp>
14#include <game/bases/d_bg_parameter.hpp>
15#include <game/bases/d_enemy_manager.hpp>
17
18const s8 l_EnMuki[] = { 1, -1 };
19const s16 l_base_angleY[] = { 0x2000, -0x2000 };
20const s16 l_base_angleY_add[] = { 0x400, -0x400 };
21const float l_base_fall_speed_x[] = { 1.5f, -1.5f };
22
23const float dEn_c::smc_WATER_GRAVITY = -0.0625f;
24const float dEn_c::smc_WATER_YMAXSPD = 1.5f;
25const float dEn_c::smc_WATER_FALLMAXSPD = -1.5f;
26const float dEn_c::smc_WATER_ROLL_DEC_RATE = 0.5f;
27
29 m_24(0), mFootPush(mVec3_c(0.0f, 0.0f, 0.0f)),
30 mKilledByLiquid(false), mFootAttr3(false), mFootAttr1(false), mDeathInfo(),
31 mBoyoMng(this), mIceMng(this),
32 mTimer1(0), mTimer2(0), mCombo(dEnCombo_c::COMBO_REGULAR), mFumiProc(this)
33{
34 mFumiProc.refresh(new NonUniqueFumiCheck_c());
35
36 mAccelY = -0.1875f;
37 mSpeedMax.set(0.0f, -4.0f, 0.0f);
38 mAirAccelY = -0.1875f;
39 mAirSpeedMaxY = -4.0f;
40 mAirMaxFallSpeed = -4.0f;
41
44
45 mFlags = 0;
46
47 for (int i = 0; i < PLAYER_COUNT; i++) {
48 mNoHitPlayer.mTimer[i] = 0;
49 }
50}
51
53
55 boyonInit();
56 if (dBc_c::checkWater(mPos.x, mPos.y, mLayer, nullptr)) {
57 mInLiquid = true;
58 }
59
61}
62
65 return NOT_READY;
66 }
67
68 if (!mNoRespawn && !isState(StateID_Ice) && isQuakeDamage()) {
69 if (dQuake_c::m_instance->mFlags & dQuake_c::FLAG_1) {
70 if (checkDispIn()) {
71 setDeathInfo_Quake(0);
72 }
73 } else if (dQuake_c::m_instance->mFlags & dQuake_c::FLAG_2) {
74 if (checkDispIn()) {
75 setDeathInfo_Quake(1);
76 }
77 } else if (dQuake_c::m_instance->mFlags & dQuake_c::FLAG_0) {
79 }
80 }
81
82 if (mDeathInfo.mIsDead) {
83 if (!mNoRespawn) {
84 mNoRespawn = true;
85 setNicePoint_Death();
86 changeState(*mDeathInfo.mDeathState);
87 }
88 mDeathInfo.mIsDead = false;
89 } else {
90 if (mTimer3 != 0) {
91 mTimer3--;
92 }
93 if (mTimer1 != 0) {
94 mTimer1--;
95 }
96 if (mTimer2 != 0) {
97 mTimer2--;
98 }
99 for (u32 i = 0; i < PLAYER_COUNT; i++) {
100 mNoHitPlayer.update(i);
101 }
102 }
103
104 calcBoyonScale();
106}
107
109 if (status == SUCCESS && !(dActor_c::mExecStop & BIT_FLAG(ACTOR_MAP_ENEMY))) {
110 mBgCollFlags = 0;
111 }
112 dActor_c::postExecute(status);
113}
114
116 if (dActor_c::preDraw() == NOT_READY) {
117 return NOT_READY;
118 }
119 return SUCCEEDED;
120}
121
122void dEn_c::hitdamageEffect(const mVec3_c &pos) {
123 mVec3_c efPos = pos;
124 efPos.z = 5500.0f;
125 mEf::createEffect("Wm_en_hit", 0, &efPos, nullptr, nullptr);
126}
127
128void dEn_c::fumidamageEffect(const mVec3_c &pos) {
129 hitdamageEffect(pos);
130}
131
132void dEn_c::hipatkEffect(const mVec3_c &pos) {
133 if (mFlags & FLAG_1) {
134 dEf::createEffect_change("Wm_mr_hardhit", 0, &pos, nullptr, nullptr);
135 } else {
136 dEf::createEffect_change("Wm_mr_softhit", 0, &pos, nullptr, nullptr);
137 }
138}
139
140void dEn_c::fumidamageSE(const mVec3_c &, int) {
141 dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0);
142}
143
145 mSpeed.y += 2.0f;
146}
147
148void dEn_c::posMove() {
149 u16 ang = mBc.getSakaMoveAngle(mSpeed.x < 0.0f);
150 mVec3_c move;
151 if (mFootAttr3) {
152 move.set(0.0f, 0.0f, 0.0f);
153 } else {
154 float speedX = std::fabs(mSpeed.x);
155 float cos = mAng(ang).cos();
156 float sin = mAng(ang).sin();
157 move.x = speedX * cos;
158 move.y = mSpeed.y + speedX * sin;
159 move.z = mSpeed.z;
160
161 if (mInLiquid) {
162 mFootPush2.set(0.0f, 0.0f, 0.0f);
163 move.x /= 2;
164 } else {
165 bool ok = mDeathInfo.mIsDead || mNoRespawn;
166 if (!ok && mSpeed.y <= 0.0f) {
167 move.x += mFootPush2.x;
168 }
169 }
170 }
171 move += mFootPush;
172 mPos += move;
173}
174
175void dEn_c::Bound(float epsY, float scaleX, float scaleY) {
176 if (!mBc.isFoot()) {
177 return;
178 }
179
180 if (scaleX < 1.0f) {
181 mSpeed.x *= scaleX;
182 if (std::fabs(mSpeed.x) < 1.0f / 16.0f) {
183 mSpeed.x = 0.0f;
184 }
185 }
186
187 if (mSpeed.y < 0.0f) {
188 mSpeed.y = -mSpeed.y;
189 mSpeed.y *= scaleY;
190 if (mSpeed.y < epsY) {
191 mSpeed.y = 0.0f;
192 }
193 }
194}
195
196bool dEn_c::checkDispIn() {
197 float x = getCenterPos().x;
198 float y = getCenterPos().y;
199
200 dBgParameter_c *bgParam = dBgParameter_c::ms_Instance_p;
201 float xStart = bgParam->xStart();
202 float xEnd = bgParam->xEnd();
203 float yStart = bgParam->yStart();
204 float yEnd = bgParam->yEnd();
205
206 if (x < xStart) {
207 return false;
208 }
209 if (x > xEnd) {
210 return false;
211 }
212 if (y > yStart) {
213 return false;
214 }
215 if (y < yEnd) {
216 return false;
217 }
218 return true;
219}
220
221void dEn_c::normal_collcheck(dCc_c *cc1, dCc_c *cc2) {
222 dEn_c *actor1 = (dEn_c *) cc1->mpOwner;
223 dActor_c *actor2 = (dActor_c *) cc2->mpOwner;
224
225 if (actor1->mDeathInfo.mIsDead) {
226 cc1->mFlag |= dCc_c::CC_DISABLE;
227 return;
228 }
229
230 u32 kind = actor2->mKind;
231 if (kind == STAGE_ACTOR_ENEMY) {
232 if (actor1->EnDamageCheck(cc1, cc2)) {
233 cc1->mFlag |= dCc_c::CC_DISABLE;
234 } else {
235 actor1->Normal_VsEnHitCheck(cc1, cc2);
236 }
237 } else if (kind == STAGE_ACTOR_PLAYER) {
238 if (actor1->mFlags & FLAG_24 || !CeilCheck(actor1->mPos.y, cc1)) {
239 if (actor1->PlDamageCheck(cc1, cc2)) {
240 actor1->mCcValue = cc1->unk3;
241 cc1->mFlag |= dCc_c::CC_DISABLE;
242 } else if (cc2->mCcData.mCategory != dCc_c::CAT_PLAYER_ATTACK) {
243 s8 *plrNo = actor2->getPlrNo();
244 if (*plrNo >= 0 && *plrNo < PLAYER_COUNT) {
245 if (actor1->mNoHitPlayer.mTimer[*plrNo] == 0) {
246 actor1->mNoHitPlayer.mTimer[*plrNo] = smc_NO_HIT_PLAYER_TIMER_DEFAULT;
247 actor1->Normal_VsPlHitCheck(cc1, cc2);
248 }
249 }
250 }
251 }
252 } else if (kind == STAGE_ACTOR_YOSHI) {
253 s8 *plrNo = actor2->getPlrNo();
254 if (*plrNo >= 0 && *plrNo < PLAYER_COUNT) {
255 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_YOSHI_EAT) {
256 actor1->hitYoshiEat(cc1, cc2);
257 } else {
258 if (!CeilCheck(actor1->mPos.y, cc1)) {
259 if (actor1->YoshiDamageCheck(cc1, cc2)) {
260 actor1->mCcValue = cc1->unk3;
261 cc1->mFlag |= dCc_c::CC_DISABLE;
262 } else if (actor1->mNoHitPlayer.mTimer[*plrNo] == 0) {
263 actor1->mNoHitPlayer.mTimer[*plrNo] = smc_NO_HIT_PLAYER_TIMER_DEFAULT;
264 actor1->Normal_VsYoshiHitCheck(cc1, cc2);
265 }
266 }
267 }
268 }
269 } else {
270 if (actor1->EtcDamageCheck(cc1, cc2)) {
271 actor1->mCcValue = cc1->unk3;
272 cc1->mFlag |= dCc_c::CC_DISABLE;
273 }
274 }
275}
276
277void dEn_c::Normal_VsEnHitCheck(dCc_c *cc1, dCc_c *cc2) {}
278
279void dEn_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) {
280 dActor_c *owner = (dActor_c *) cc2->mpOwner;
281 if (!LineBoundaryCheck(owner)){
282 setDamage(owner);
283 }
284}
285
286void dEn_c::Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2) {
287 dActor_c *owner = (dActor_c *) cc2->mpOwner;
288 if (!LineBoundaryCheck(owner)){
289 setDamage(owner);
290 }
291}
292
293bool dEn_c::EnDamageCheck(dCc_c *cc1, dCc_c *cc2) {
294 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_SHELL) {
295 if (hitCallback_Shell(cc1, cc2)) {
296 return true;
297 }
298 }
299 return false;
300}
301
302bool dEn_c::PlDamageCheck(dCc_c *cc1, dCc_c *cc2) {
303 daPlBase_c *owner = (daPlBase_c *) cc2->mpOwner;
304 if (owner->mKind != STAGE_ACTOR_PLAYER) {
305 return false;
306 }
307
308 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_STAR && hitCallback_Star(cc1, cc2)) {
309 return true;
310 }
311 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_HIP_ATTK) {
312 if (owner->isMameAction()) {
313 return false;
314 }
315 if (hitCallback_HipAttk(cc1, cc2)) {
316 return true;
317 }
318 }
319 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_SLIP) {
320 if (cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_SLIP) && hitCallback_Slip(cc1, cc2)) {
321 return true;
322 }
323 }
324 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_PENGUIN_SLIDE) {
325 if (mActorProperties & 0x200) {
326 return false;
327 }
328 if (hitCallback_PenguinSlide(cc1, cc2)) {
329 return true;
330 }
331 }
332 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_SPIN_FALL && hitCallback_Spin(cc1, cc2)) {
333 return true;
334 }
335 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_CANNON && hitCallback_Cannon(cc1, cc2)) {
336 return true;
337 }
338 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_WIRE_NET && hitCallback_WireNet(cc1, cc2)) {
339 return true;
340 }
341 return false;
342}
343
344bool dEn_c::YoshiDamageCheck(dCc_c *cc1, dCc_c *cc2) {
345 daPlBase_c *owner = (daPlBase_c *) cc2->mpOwner;
346 if (owner->mKind != STAGE_ACTOR_YOSHI) {
347 return false;
348 }
349
350 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_STAR && hitCallback_Star(cc1, cc2)) {
351 return true;
352 }
353 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_HIP_ATTK && hitCallback_YoshiHipAttk(cc1, cc2)) {
354 return true;
355 }
356 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_SLIP) {
357 if (cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_SLIP) && hitCallback_Slip(cc1, cc2)) {
358 return true;
359 }
360 }
361 return false;
362}
363
364bool dEn_c::EtcDamageCheck(dCc_c *cc1, dCc_c *cc2) {
365 dEn_c *owner = (dEn_c *) cc1->mpOwner;
366 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_SHELL && owner->hitCallback_Shell(cc1, cc2)) {
367 return true;
368 }
369 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_FIRE) {
370 if (cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_FIRE) && owner->hitCallback_Fire(cc1, cc2)) {
371 return true;
372 }
373 }
374 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_YOSHI_FIRE) {
375 if (cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_YOSHI_FIRE) && owner->hitCallback_YoshiFire(cc1, cc2)) {
376 return true;
377 }
378 }
379 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_FIRE_2 && owner->hitCallback_Fire(cc1, cc2)) {
380 return true;
381 }
382 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_ICE && cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_ICE) ||
383 cc2->mCcData.mAttackCategory == dCc_c::ATTACK_ICE_2 && cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_ICE_2)) {
384 if (owner->hitCallback_Ice(cc1, cc2)) {
385 return true;
386 }
387 }
388 if (cc2->mCcData.mAttackCategory == dCc_c::ATTACK_YOSHI_BULLET) {
389 if (cc1->mCcData.mAttackCategoryInteract & (1 << dCc_c::ATTACK_YOSHI_BULLET) && owner->hitCallback_YoshiBullet(cc1, cc2)) {
390 return true;
391 }
392 }
393 return false;
394}
395
396void dEn_c::hitYoshiEat(dCc_c *cc1, dCc_c *cc2) {}
397
398bool dEn_c::getPl_LRflag(const mVec3_c &pos) {
399 mVec2_c playerPos;
400 mVec2_c pos2D(pos.x, pos.y);
401 if (searchNearPlayer_Main(playerPos, pos2D) == nullptr) {
402 return false;
403 }
404 return playerPos.x < 0;
405}
406
407bool dEn_c::getPl_UDflag(const mVec3_c &pos) {
408 mVec2_c playerPos;
409 mVec2_c pos2D(pos.x, pos.y);
410 if (searchNearPlayer_Main(playerPos, pos2D) == nullptr) {
411 return false;
412 }
413 return playerPos.y < 0;
414}
415
416bool dEn_c::CeilCheck(float y, dCc_c *cc) {
417 return dBgParameter_c::getInstance()->check(y + cc->mCcData.mOffsetY, cc->mCcData.mHeight);
418}
419
420bool dEn_c::carry_check(dActor_c *actor) {
421 dAcPy_c *pl = (dAcPy_c *) actor;
422 if (pl->FUN_8012e540(this, true)) {
423 mPlayerNo = *actor->getPlrNo();
424 return true;
425 }
426 return false;
427}
428
430 float dir = l_EnMuki[mDirection];
431 mBc.checkWall(&dir);
432 mVec3_c truePos = mPos;
433 truePos += mCenterOffs;
434 return mBc.checkBg(truePos.x, truePos.y, mLayer, l_Ami_Line[mAmiLayer], 0x819);
435}
436
437int dEn_c::Enfumi_check(dCc_c *cc1, dCc_c *cc2, int step) {
438 dActor_c *owner;
439 FumiCcInfo_c fumiInfo(cc1, cc2);
440 int fumiRes = mFumiProc.operate(fumiInfo, 1);
441 owner = (dActor_c *) cc2->getOwner();
442 switch (fumiRes) {
443 case 1:
444 if ((int) owner->mKind == STAGE_ACTOR_PLAYER) {
445 if (step == 0) {
446 fumiSE(owner);
447 fumiEffect(owner);
448 } else if (step == 1) {
449 fumistepSE(owner);
450 }
451 FumiJumpSet(owner);
452 FumiScoreSet(owner);
453 } else {
454 if (step == 0) {
455 yoshifumiSE(owner);
456 yoshifumiEffect(owner);
457 } else if (step == 1) {
458 yoshifumistepSE(owner);
459 }
460 YoshiFumiJumpSet(owner);
461 YoshiFumiScoreSet(owner);
462 }
463 break;
464 case 2:
465 MameFumiJumpSet(owner);
466 mamefumiSE(owner);
467 mamefumiEffect(owner);
468 break;
469 case 3:
470 if (step == 0) {
471 spinfumiSE(owner);
472 spinfumiEffect(owner);
473 } else if (step == 1) {
474 fumistepSE(owner);
475 }
476 SpinFumiJumpSet(owner);
477 SpinFumiScoreSet(owner);
478 break;
479 }
480 return fumiRes;
481}
482
483void dEn_c::FumiScoreSet(dActor_c *actor) {
484 setFumiComboScore(actor);
485}
486
487void dEn_c::FumiJumpSet(dActor_c *actor) {
488 PlayerFumiJump(actor, dAcPy_c::msc_JUMP_SPEED + 0.2815f);
489}
490
491void dEn_c::MameFumiJumpSet(dActor_c *actor) {
492 float jumpSpeed = (dAcPy_c::msc_JUMP_SPEED + 0.2815f);
493 jumpSpeed *= 0.8125f;
494 if (mSpeed.y > 0.0f) {
495 jumpSpeed += mSpeed.y * 0.2f;
496 }
497 PlayerFumiJump(actor, jumpSpeed);
498}
499
500void dEn_c::YoshiFumiJumpSet(dActor_c *actor) {
501 PlayerFumiJump(actor, dAcPy_c::msc_JUMP_SPEED + 0.2815f);
502}
503
504void dEn_c::YoshiFumiScoreSet(dActor_c *actor) {
505 FumiScoreSet(actor);
506}
507
508void dEn_c::SpinFumiJumpSet(dActor_c *actor) {
509 FumiJumpSet(actor);
510}
511
512void dEn_c::SpinFumiScoreSet(dActor_c *actor) {
513 FumiScoreSet(actor);
514}
515
516void dEn_c::PlayerFumiJump(dActor_c *actor, float param_2) {
517 ((daPlBase_c *) actor)->vf3fc(param_2, actor->mSpeedF, 1, 0, 2);
518 dEnemyMng_c::m_instance->m_138 = 1;
519}
520
521void dEn_c::setFumiComboScore(dActor_c *actor) {
522 int treadCount = dEnCombo_c::calcPlFumiCnt(actor);
523 if (treadCount >= 0) {
524 mVec3_c pos = getCenterPos();
525 float scY = dScoreMng_c::smc_SCORE_Y;
526 pos.y = mPos.y + scY;
527 switch (mCombo.mType) {
528 case dEnCombo_c::COMBO_REGULAR: {
529 dScoreMng_c *instance = dScoreMng_c::getInstance();
530 instance->ScoreSet(pos, treadCount, *actor->getPlrNo(), 1);
531 break;
532 }
533 case dEnCombo_c::COMBO_SHORT: {
534 dScoreMng_c *instance = dScoreMng_c::getInstance();
535 instance->ScoreSet2(pos, treadCount, *actor->getPlrNo());
536 break;
537 }
538 default:
539 break;
540 }
541 }
542}
543
545 /// @unofficial
546 static const int claps[] = { 7, 7, 4 };
547 return num >= claps[mCombo.mType];
548}
549
550void dEn_c::fumiSE(dActor_c *actor) {
551 const static dAudio::SoundEffectID_t cs_combo_se[] = {
552 SE_EMY_FUMU_1,
553 SE_EMY_FUMU_2,
554 SE_EMY_FUMU_3,
555 SE_EMY_FUMU_4,
556 SE_EMY_FUMU_5,
557 SE_EMY_FUMU_6,
558 SE_EMY_FUMU_7,
559 SE_EMY_FUMU_7,
560 SE_EMY_FUMU_7
561 };
562
563 int count = ((daPlBase_c *) actor)->getTreadCount();
564 if (count >= ARRAY_SIZE(cs_combo_se)) {
565 count = ARRAY_SIZE(cs_combo_se) - 1;
566 };
567 if (checkComboClap(count)) {
569 }
570
571 cs_combo_se[count].playEmySound(getCenterPos(), 0);
572}
573
574void dEn_c::spinfumiSE(dActor_c *actor) {
575 const static dAudio::SoundEffectID_t cs_combo_se[] = {
576 SE_EMY_DOWN_SPIN_1,
577 SE_EMY_DOWN_SPIN_2,
578 SE_EMY_DOWN_SPIN_3,
579 SE_EMY_DOWN_SPIN_4,
580 SE_EMY_DOWN_SPIN_5,
581 SE_EMY_DOWN_SPIN_6,
582 SE_EMY_DOWN_SPIN_7,
583 SE_EMY_DOWN_SPIN_7,
584 SE_EMY_DOWN_SPIN_7
585 };
586
587 int count = ((daPlBase_c *) actor)->getTreadCount();
588 if (count >= ARRAY_SIZE(cs_combo_se)) {
589 count = ARRAY_SIZE(cs_combo_se) - 1;
590 };
591 if (checkComboClap(count)) {
593 }
594
595 cs_combo_se[count].playEmySound(getCenterPos(), 0);
596}
597
598void dEn_c::yoshifumiSE(dActor_c *actor) {
599 const static dAudio::SoundEffectID_t cs_combo_se[] = {
600 SE_EMY_YOSHI_FUMU_1,
601 SE_EMY_YOSHI_FUMU_2,
602 SE_EMY_YOSHI_FUMU_3,
603 SE_EMY_YOSHI_FUMU_4,
604 SE_EMY_YOSHI_FUMU_5,
605 SE_EMY_YOSHI_FUMU_6,
606 SE_EMY_YOSHI_FUMU_7,
607 SE_EMY_YOSHI_FUMU_7,
608 SE_EMY_YOSHI_FUMU_7
609 };
610
611 int count = ((daPlBase_c *) actor)->getTreadCount();
612 if (count >= ARRAY_SIZE(cs_combo_se)) {
613 count = ARRAY_SIZE(cs_combo_se) - 1;
614 };
615 if (checkComboClap(count)) {
617 }
618
619 cs_combo_se[count].playEmySound(getCenterPos(), 0);
620}
621
622void dEn_c::mamefumiSE(dActor_c *actor) {
623 dAudio::SoundEffectID_t(SE_EMY_MAME_STEP).playEmySound(getCenterPos(), 0);
624}
625
626void dEn_c::fumistepSE(dActor_c *actor) {
627 dAudio::SoundEffectID_t(SE_EMY_CMN_STEP).playEmySound(getCenterPos(), 0);
628}
629
630void dEn_c::yoshifumistepSE(dActor_c *actor) {
631 dAudio::SoundEffectID_t(SE_EMY_YOSHI_STEP).playEmySound(getCenterPos(), 0);
632}
633
634void dEn_c::fumiEffect(dActor_c *actor) {
635 if (actor->mKind != STAGE_ACTOR_PLAYER && actor->mKind != STAGE_ACTOR_YOSHI) {
636 return;
637 }
638
639 daPlBase_c *pl = (daPlBase_c *) actor;
640 mVec3_c efPos;
641 efPos.x = pl->getAnkleCenterX();
642 efPos.y = pl->getAnkleCenterY();
643 efPos.z = 5500.0f;
644 mEf::createEffect("Wm_en_hit", 0, &efPos, nullptr, nullptr);
645}
646
647void dEn_c::spinfumiEffect(dActor_c *actor) {
648 mVec3_c efPos;
649 efPos.x = actor->mPos.x;
650 efPos.y = actor->mPos.y;
651 efPos.z = 5500.0f;
652 mEf::createEffect("Wm_en_hit", 0, &efPos, nullptr, nullptr);
653}
654
655void dEn_c::yoshifumiEffect(dActor_c *actor) {}
656
657void dEn_c::mamefumiEffect(dActor_c *actor) {}
658
659u32 dEn_c::EnBgCheck() {
660 u32 flags = 0;
661 u32 footCheckRes = EnBgCheckFoot();
662 if (footCheckRes) {
663 flags |= 1;
664 mSpeed.y = 0.0f;
665 }
666 u32 checkHeadRes = mBc.checkHead(footCheckRes);
667 if (checkHeadRes) {
668 flags |= 2;
669 }
670 u32 bgCheckWallRes = EnBgCheckWall();
671 if (bgCheckWallRes) {
672 flags |= 4;
673 }
674 u32 arg = checkHeadRes | bgCheckWallRes;
675 u32 actArg = arg | footCheckRes;
676 if (mBc.mFlags & 0x8000 && mBc.mFlags & 3 && mBc.mpRc != nullptr) {
677 int v = 0;
678 if (mSpeed.y > 0.0f) {
679 v |= 1;
680 }
681 if (!mBc.mpRc->check2(actArg & 0x1f6000, v, 0)) {
682 mBc.mFlags &= 0xffff7fff;
683 }
684 }
685 return flags;
686}
687
688bool dEn_c::EnBgCheckFoot() {
689 if (!mBc.hasSensorFoot()) {
690 mFootPush2.set(0.0f, 0.0f, 0.0f);
691 return false;
692 }
693 bool res = mBc.checkFootEnm();
694 mFootAttr3 = false;
695 mFootAttr1 = false;
696 if (mBc.isFoot()) {
697 u32 footAttr = mBc.getFootAttr();
698 if ((u16) footAttr == 3) {
699 mFootAttr3 = true;
700 }
701 if ((u16) footAttr == 1) {
702 mFootAttr1 = true;
703 }
704 mFootPush = mBc.mPushForce;
705 mFootPush2.set(0.0f, 0.0f, 0.0f);
706 } else {
707 mFootPush.set(0.0f, 0.0f, 0.0f);
708 }
709 return res;
710}
711
712u32 dEn_c::EnBgCheckWall() {
713 if (!mBc.hasSensorWall()) {
714 return 0;
715 }
716 float tmpX = mBc.m_4c;
717 u8 dir = mPos.x - tmpX < 0.0f;
718 float dirVal = l_EnMuki[dir];
719 u32 flags = mBc.checkWallEnm(&dirVal);
720 dirVal = l_EnMuki[dir ^ 1];
721 u32 wallFlags = mBc.checkWallEnm(&dirVal);
722 if (mBgCollFlags & 3) {
723 wallFlags |= mBc.checkWallEnm(&dirVal);
724 }
725 mBc.mFlags |= flags | wallFlags;
726 return flags;
727}
728
729void dEn_c::WaterCheck(mVec3_c &pos, float h) {
730 if (mKilledByLiquid) {
731 return;
732 }
733 int waterLineRes = WaterLineProc(pos, h);
734 if (waterLineRes == dBc_c::WATER_CHECK_YOGAN) {
735 setDeathInfo_Smoke(nullptr);
736 mKilledByLiquid = true;
737 } else if (waterLineRes != dBc_c::WATER_CHECK_NONE && mNoRespawn) {
738 mKilledByLiquid = true;
739 }
740}
741
742bool dEn_c::LineBoundaryCheck(dActor_c *actor) {
743 daPlBase_c *pl = (daPlBase_c *) actor;
744 if ((pl->mPos.z > 0.0f && mAmiLayer == 1) || (pl->mPos.z < 0.0f && mAmiLayer == 0)) {
745 if (pl->mFlags & 0x80000 || pl->mFlags & 0x100000) {
746 return true;
747 }
748 }
749 return false;
750}
751
752dBc_c::WATER_TYPE_e dEn_c::WaterLineProc(const mVec3_c &pos, float h) {
753 float height = 0.0f;
754 dBc_c::WATER_TYPE_e res = dBc_c::checkWater(pos.x, pos.y, mLayer, &height);
755 mVec3_c waterPos(mPos.x, height, 6500.0f);
756 switch (res) {
757 case dBc_c::WATER_CHECK_WATER:
758 case dBc_c::WATER_CHECK_WATER_BUBBLE:
759 if (!mInLiquid) {
760 mInLiquid = true;
764 setWaterSpeed();
765 waterSplashEffect(waterPos, h);
766 }
767 break;
768 case dBc_c::WATER_CHECK_YOGAN:
769 if (!mInLiquid) {
770 mInLiquid = true;
771 yoganSplashEffect(waterPos, h);
772 }
773 break;
774 case dBc_c::WATER_CHECK_POISON:
775 if (!mInLiquid) {
776 mInLiquid = true;
777 poisonSplashEffect(waterPos, h);
778 }
779 break;
780 default:
781 if (mInLiquid) {
785 }
786 mInLiquid = false;
787 break;
788 }
789 return res;
790}
791
792void dEn_c::yoganSplashEffect(const mVec3_c &pos, float scale) {
793 mVec3_c efPos(pos, 6500.0f);
794 mVec3_c efScale(scale, scale, scale);
795 u32 flags = mLayer << 16 | 5;
796 dEffActorMng_c::m_instance->createWaterSplashEff(efPos, flags, -1, efScale);
797
798 dAudio::SoundEffectID_t(SE_OBJ_CMN_SPLASH_LAVA).playMapSound(efPos, 0);
799
800 if (scale < 1.0f) {
801 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 16);
802 } else {
803 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 14);
804 }
805}
806
807void dEn_c::poisonSplashEffect(const mVec3_c &pos, float scale) {
808 mVec3_c efPos(pos, 6500.0f);
809 mVec3_c efScale(scale, scale, scale);
810 u32 flags = mLayer << 16 | 7;
811 dEffActorMng_c::m_instance->createWaterSplashEff(efPos, flags, -1, efScale);
812
813 dAudio::SoundEffectID_t(SE_OBJ_CMN_SPLASH_POISON).playMapSound(pos, 0);
814
815 if (scale < 1.0f) {
816 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 23);
817 } else {
818 dBg_c::m_bg_p->setWaterInWave(pos.x, pos.y, 21);
819 }
820}
821
822bool dEn_c::EnLavaCheck(const mVec3_c &pos) {
823 float height = 0.0f;
824 dBc_c::WATER_TYPE_e res = dBc_c::checkWater(pos.x, pos.y, mLayer, &height);
825 if (res == dBc_c::WATER_CHECK_YOGAN) {
826 if (height < 0.0f && mLastPos.y > height && mPos.y <= height) {
827 yoganSplashEffect(mVec3_c(pos.x, height, 6000.0f), 1.0f);
828 }
829 return true;
830 }
831 return false;
832}
833
834bool dEn_c::EnWaterCheck(const mVec3_c &pos) {
835 if (EnWaterFlagCheck(pos) != dBc_c::WATER_CHECK_NONE) {
836 return true;
837 }
838 mSpeedMax.y = -4.0f;
839 mMaxFallSpeed = -4.0f;
840 return false;
841}
842
843bool dEn_c::EnWaterFlagCheck(const mVec3_c &pos) {
844 switch (dBc_c::checkWater(pos.x, pos.y, mLayer, nullptr)) {
845 case dBc_c::WATER_CHECK_WATER:
846 case dBc_c::WATER_CHECK_WATER_BUBBLE:
847 setWaterSpeed();
848 return true;
849 default:
850 return false;
851 }
852}
853
854void dEn_c::setWaterSpeed() {
855 mAccelY = smc_WATER_GRAVITY;
856
857 if (mSpeedMax.y < -smc_WATER_YMAXSPD) {
858 mSpeedMax.y = -smc_WATER_YMAXSPD;
859 } else if (mSpeedMax.y > smc_WATER_YMAXSPD) {
860 mSpeedMax.y = smc_WATER_YMAXSPD;
861 }
862
863 if (mMaxFallSpeed < smc_WATER_FALLMAXSPD) {
864 mMaxFallSpeed = smc_WATER_FALLMAXSPD;
865 } else if (mMaxFallSpeed > -smc_WATER_FALLMAXSPD) {
866 mMaxFallSpeed = -smc_WATER_FALLMAXSPD;
867 }
868
869 if (mSpeed.y < -smc_WATER_YMAXSPD) {
870 mSpeed.y = -smc_WATER_YMAXSPD;
871 } else if (mSpeed.y > smc_WATER_YMAXSPD) {
872 mSpeed.y = smc_WATER_YMAXSPD;
873 }
874}
875
876bool dEn_c::Area_X_check(float x) {
877 for (int i = 0; i < PLAYER_COUNT; i++) {
878 dAcPy_c *player = daPyMng_c::getPlayer(i);
879 if (player != nullptr && daPyMng_c::checkPlayer(i)) {
880 mVec3_c playerPos = player->mPos;
881 float diff = std::fabs(playerPos.x - mPos.x);
882 if (diff < x) {
883 return true;
884 }
885 }
886 }
887 return false;
888}
889
890bool dEn_c::Area_XY_check(float x, float y) {
891 for (int i = 0; i < PLAYER_COUNT; i++) {
892 dAcPy_c *player = daPyMng_c::getPlayer(i);
893 if (player != nullptr && daPyMng_c::checkPlayer(i)) {
894 mVec3_c playerPos = player->mPos;
895 if (std::fabs(playerPos.x - mPos.x) < x && std::fabs(playerPos.y - mPos.y) < y) {
896 return true;
897 }
898 }
899 }
900 return false;
901}
902
903bool dEn_c::PlayerCarryCheck(dActor_c *actor) {
904 for (int i = 0; i < PLAYER_COUNT; i++) {
905 dAcPy_c *player = daPyMng_c::getPlayer(i);
906 if (player != nullptr && fManager_c::searchBaseByID(player->mCarryActorID) == this) {
907 return true;
908 }
909 }
910 return false;
911}
912
913mVec3_c dEn_c::calcCarryPos(const mVec3_c &pos) {
914 dAcPy_c *player = daPyMng_c::getPlayer(mPlayerNo);
915 if (player->isStatus(4)) {
916 return mPos;
917 }
918 mMtx_c mtx = player->getCarryMtx();
919 mMtx_c transposeMtx = mMtx_c::createTrans(pos);
920 mVec3_c res;
921 mtx.concat(transposeMtx).multVecZero(res);
922 return res;
923}
924
925bool dEn_c::turnangle_calc(const short *target, const short *delta) {
926 mAngle.y += delta[mDirection];
927 if (target[0] <= mAngle.y || mAngle.y <= target[1]) {
928 mAngle.y = target[mDirection];
929 return true;
930 }
931 return false;
932}
933
934void dEn_c::slipBound(dActor_c *actor) {
935 static const float cs_jump_xspeed[] = { 1.5f, -1.5f };
936 daPlBase_c *pl = (daPlBase_c *) actor;
937
938 u8 idx = !(pl->mPos.x >= mPos.x);
939 pl->vf3fc(3.0f, cs_jump_xspeed[idx], 1, 0, 0);
940
941 int plrNo = *pl->getPlrNo();
942 mNoHitPlayer.mTimer[plrNo] = 3;
943}
944
946 removeCc();
948 changeState(StateID_EatIn);
949}
950
952 reviveCc();
954 changeState(*mStateMgr.getOldStateID());
955}
956
958 calcSpitOutPos(actor);
959 int plrNo = *actor->getPlrNo();
961 mDirection = actor->mDirection;
962 reviveCc();
964 changeState(StateID_EatOut);
965 return true;
966}
967
970 mBoyoMng.mCounter = 0;
971}
972
973void dEn_c::setNicePoint_Death() {
974 int killedBy = mDeathInfo.mKilledBy;
975 if (mDeathInfo.mKilledBy >= 0 && mDeathInfo.mKilledBy < PLAYER_COUNT) {
976 dMultiMng_c::mspInstance->incEnemyDown(killedBy);
977 }
978}
979
980void dEn_c::fireballInvalid(dCc_c *cc1, dCc_c *cc2) {
981 dAudio::g_pSndObjMap->startSound(SE_OBJ_FIREBALL_DISAPP, cc2->mpOwner->mPos, 0);
982}
983
984void dEn_c::iceballInvalid(dCc_c *cc1, dCc_c *cc2) {
985 dBaseActor_c *owner = cc2->mpOwner;
986 dAudio::g_pSndObjMap->startSound(SE_OBJ_PNGN_ICEBALL_DISAPP, owner->mPos, 0);
987
988 mVec3_c efPos(owner->mPos.x, owner->mPos.y, 5500.0f);
989 EffectManager_c::SetIceBallMissshitEffect(&efPos);
990}
991
992void dEn_c::setDamage(dActor_c *actor) {
993 daPlBase_c *pl = (daPlBase_c *) actor;
994 pl->setDamage(this, daPlBase_c::DAMAGE_NONE);
995}
996
997void dEn_c::boyonInit() {
998 mBoyoMng.mScale = mBoyoMng.mpOwner->mScale;
999}
1000
1001void dEn_c::boyonBegin() {
1002 mBoyoMng.begin(dEnBoyoMng_c::smc_BOYON_TIME, dEnBoyoMng_c::smc_DELTA_SCALE);
1003}
1004
1006 u8 dir = mDeathFallDirection;
1007 s8 plrNo = *getPlrNo();
1008
1009 mVec3_c efPos(mVec2_c(mPos.x, mPos.y), 5500.0f);
1010
1011 hitdamageEffect(efPos);
1012 dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0);
1013
1015 l_base_fall_speed_x[dir],
1016 3.0f,
1017 -4.0f,
1018 -0.1875f,
1019 &StateID_DieFall,
1020 -1,
1021 -1,
1022 dir,
1023 (u8) plrNo
1024 };
1025}
bool FUN_8012e540(dActor_c *, bool)
bool isState(const sStateIDIf_c &other) const
Checks if the actor is currently in the given state.
sFStateStateMgr_c< dActorMultiState_c, sStateMethodUsr_FI_c, sStateMethodUsr_FI_c > mStateMgr
The state manager.
The minimum required implementation for a stage actor.
Definition d_actor.hpp:17
static u8 mExecStop
The actors for which the execute operation is currently disabled.
Definition d_actor.hpp:402
u8 mExecStopMask
The mask required to disable the execute operation for the actor.
Definition d_actor.hpp:378
virtual void postCreate(fBase_c::MAIN_STATE_e status)
post method for the create operation.
Definition d_actor.cpp:88
mVec3_c mPreEatScale
The actor's scale before being eaten.
Definition d_actor.hpp:369
bool mNoRespawn
Whether the actor should not respawn after being deleted.
Definition d_actor.hpp:380
virtual void reviveCc()
Enables the actor's collision.
Definition d_actor.cpp:804
dBc_c mBc
The actor-to-tile collision sensor.
Definition d_actor.hpp:344
u8 mKind
The actor's kind. Value is a STAGE_ACTOR_KIND_e.
Definition d_actor.hpp:376
u8 mAmiLayer
The actor's layer for chainlink fences.
Definition d_actor.hpp:381
u8 mDirection
The actor's facing direction.
Definition d_actor.hpp:353
virtual void removeCc()
Disables the actor's collision.
Definition d_actor.cpp:800
static dAcPy_c * searchNearPlayer_Main(mVec2_c &delta, const mVec2_c &pos)
See searchNearPlayerFunc.
Definition d_actor.cpp:195
virtual void postExecute(fBase_c::MAIN_STATE_e status)
post method for the execute operation.
Definition d_actor.cpp:122
void setKind(u8 kind)
Sets the actor's kind. See STAGE_ACTOR_KIND_e.
Definition d_actor.cpp:176
virtual int preExecute()
pre method for the execute operation.
Definition d_actor.cpp:104
s8 mPlayerNo
The player associated with the actor, -1 if not associated to any player.
Definition d_actor.hpp:377
virtual void waterSplashEffect(const mVec3_c &pos, float size)
Generates a water splash effect.
Definition d_actor.cpp:731
dActor_c()
Constructs a new actor.
Definition d_actor.cpp:46
virtual void calcEatInScale(dActor_c *eatingActor)
Adjusts the actor's scale while being eaten.
Definition d_actor.cpp:674
virtual int preDraw()
pre method for the draw operation.
Definition d_actor.cpp:140
virtual s8 * getPlrNo()
Gets the player number associated with the actor. See mPlayerNo.
Definition d_actor.hpp:107
virtual void setAfterEatScale()
Restores the actor's scale once spat out.
Definition d_actor.cpp:647
@ STAGE_ACTOR_ENEMY
An enemy actor.
Definition d_actor.hpp:51
@ STAGE_ACTOR_YOSHI
The Yoshi actor.
Definition d_actor.hpp:50
@ STAGE_ACTOR_PLAYER
The player actor.
Definition d_actor.hpp:49
virtual void calcSpitOutPos(dActor_c *eatingActor)
Calculates the position where the actor will be spat out.
Definition d_actor.cpp:651
u8 mLayer
The actor's layer.
Definition d_actor.hpp:379
u8 mBgCollFlags
The collision directions that the actor can respond to.
Definition d_actor.hpp:355
mVec3_c mScale
The actor's scale (defaults to 1).
mVec3_c mSpeed
The actor's speed.
mVec3_c mPos
The actor's position.
mVec3_c mSpeedMax
The actor's maximum speed.
mVec3_c mCenterOffs
The offset from the position to the center of the actor (defaults to 0).
float mSpeedF
The actor's horizontal speed.
float mMaxFallSpeed
The actor's maximum fall speed.
mVec3_c getCenterPos() const
Gets the actor's centered position.
mAng3_c mAngle
The actor's rotation (for 2D actors).
u32 mActorProperties
The actor's properties. See fProfile::fActorProfile_c::mActorProperties.
float mAccelY
The actor's vertical acceleration.
@ ACTOR_MAP_ENEMY
A map enemy (dWmEnemy_c).
dBaseActor_c()
Constructs a new actor.
Collider ("Collision Check") class - handles collisions between actors.
Definition d_cc.hpp:12
@ CAT_PLAYER_ATTACK
Definition d_cc.hpp:41
dBaseActor_c * getOwner() const
Gets the owner actor of this collider.
Definition d_cc.hpp:172
CcData_s mCcData
The collision data of this collider.
Definition d_cc.hpp:276
dBaseActor_c * mpOwner
The actor this collider belongs to.
Definition d_cc.hpp:266
@ CC_DISABLE
Disables all collisions with this collider.
Definition d_cc.hpp:32
static const u16 smc_NO_HIT_PLAYER_TIMER_DEFAULT
Definition d_enemy.hpp:300
float mAirMaxFallSpeed
The maximum fall speed before entering a liquid.
Definition d_enemy.hpp:281
virtual ~dEn_c()
Destroys the actor.
Definition d_enemy.cpp:52
u16 mTimer2
[Used in EN_HATENA_BALLON, for example]
Definition d_enemy.hpp:284
bool getPl_LRflag(const mVec3_c &pos)
Checks whether the nearest player is to the left of pos.
Definition d_enemy.cpp:398
u8 mDeathFallDirection
The X direction to move towards on death.
Definition d_enemy.hpp:268
u16 m_24
Definition d_enemy.hpp:264
void WaterCheck(mVec3_c &pos, float h)
Definition d_enemy.cpp:729
virtual bool setEatSpitOut(dActor_c *)
Callback for when the actor is about to be spat out.
Definition d_enemy.cpp:957
float mAirAccelY
The Y acceleration before entering a liquid.
Definition d_enemy.hpp:279
dDeathInfo_c mDeathInfo
The parameters for the death animation.
Definition d_enemy.hpp:262
virtual void postCreate(fBase_c::MAIN_STATE_e status)
post method for the create operation.
Definition d_enemy.cpp:54
dIceMng_c mIceMng
The ice manager for this enemy.
Definition d_enemy.hpp:278
dEnCombo_c mCombo
The enemy combo manager.
Definition d_enemy.hpp:292
u16 mTimer1
[Used in EN_HATENA_BALLON, for example]
Definition d_enemy.hpp:283
dEn_c()
Constructs a new enemy actor.
Definition d_enemy.cpp:28
static const u16 smc_NO_HIT_PLAYER_TIMER_SPIT_OUT
Definition d_enemy.hpp:301
bool mKilledByLiquid
Whether the enemy was killed by falling in a liquid.
Definition d_enemy.hpp:270
virtual void quakeAction()
Definition d_enemy.cpp:144
virtual void setEatTongueOff(dActor_c *)
Callback for when the eating action is canceled.
Definition d_enemy.cpp:951
virtual int preExecute()
pre method for the execute operation.
Definition d_enemy.cpp:63
virtual void block_hit_init()
Callback for when a block directly beneath the actor is hit.
Definition d_enemy.cpp:1005
float mAirSpeedMaxY
The maximum Y speed before entering a liquid.
Definition d_enemy.hpp:280
dPlayerDownTimer_c mNoHitPlayer
Hit cooldown timers for each player. This is used to prevent, for example, a thrown shell from hittin...
Definition d_enemy.hpp:289
virtual void postExecute(fBase_c::MAIN_STATE_e status)
post method for the execute operation.
Definition d_enemy.cpp:108
bool checkWallAndBg()
Definition d_enemy.cpp:429
virtual void calcEatInScale(dActor_c *)
Adjusts the actor's scale while being eaten.
Definition d_enemy.cpp:968
virtual void poisonSplashEffect(const mVec3_c &, float)
Generates a poison water splash effect.
Definition d_enemy.cpp:807
virtual void setEatTongue(dActor_c *)
Callback for when the actor is targeted by Yoshi's tongue.
Definition d_enemy.cpp:945
virtual void yoganSplashEffect(const mVec3_c &, float)
Generates a lava splash effect.
Definition d_enemy.cpp:792
virtual int preDraw()
pre method for the draw operation.
Definition d_enemy.cpp:115
u32 mFlags
Flags for this actor. See FLAGS_e.
Definition d_enemy.hpp:282
bool getPl_UDflag(const mVec3_c &pos)
Checks whether the nearest player is below pos.
Definition d_enemy.cpp:407
bool mInLiquid
Whether the enemy is in a liquid.
Definition d_enemy.hpp:273
virtual void changeState(const sStateIDIf_c &newState)
Changes the actor's state to the given state.
virtual bool checkComboClap(int max)
Definition d_enemy.cpp:544
static dMultiMng_c * mspInstance
The instance of this class.
void setClapSE()
Plays the clap sound effect.
static float smc_SCORE_Y
The score's vertical offset from the actor position.
virtual u32 vf3fc(float, float, int, int, int)
MAIN_STATE_e
The possible operation results.
Definition f_base.hpp:33
@ SUCCESS
The operation was completed successfully.
Definition f_base.hpp:36
bool mDeleteRequested
If deletion of the base was requested, but the delete operation has not been scheduled yet.
Definition f_base.hpp:67
@ NOT_READY
The step could not completed at this time.
Definition f_base.hpp:42
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:43
static fBase_c * searchBaseByID(fBaseID_e id)
Searches for a base with the given ID.
Definition f_manager.cpp:18
void multVecZero(nw4r::math::VEC3 &out) const
Extracts the translation vector from the matrix.
Definition m_mtx.cpp:135
A two-dimensional floating point vector.
Definition m_vec.hpp:9
A three-dimensional floating point vector.
Definition m_vec.hpp:100
const u8 l_Ami_Line[]
The sub-layer for each side of chainlink fences.
Definition d_actor.cpp:38
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 mOffsetY
The Y offset of the collider.
Definition d_cc.hpp:82