1#include <game/bases/d_enemy.hpp>
3#include <game/bases/d_a_player_base.hpp>
4#include <game/bases/d_a_player_manager.hpp>
5#include <game/bases/d_actor_manager.hpp>
6#include <game/bases/d_effectmanager.hpp>
7#include <game/bases/d_enemy_manager.hpp>
8#include <game/bases/d_game_com.hpp>
9#include <game/bases/d_multi_manager.hpp>
10#include <game/bases/d_score_manager.hpp>
11#include <game/mLib/m_effect.hpp>
23const float dEn_c::smc_DEADFALL_GRAVITY = -0.25f + 0.00625001f;
24const float dEn_c::smc_DEADFALL_YSPEED = 3.9f;
25const float dEn_c::smc_DEADFALL_YSPEED_MAX = -4.0f;
26const s16 dEn_c::smc_DEADFALL_SPINSPEED = 0xc00;
28bool dEn_c::hitCallback_Star(
dCc_c *self,
dCc_c *other) {
29 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
34 hitdamageEffect(mVec3_c(collPos, 5500.0f));
37 if (
mCombo.mType == dEnCombo_c::COMBO_SHORT) {
40 player->
slideComboSE(player->getStarCount(), shortCombo);
42 int score =
mCombo.getComboScore(dEnCombo_c::calcPlStarCnt(player));
45 l_base_fall_speed_x[dir],
47 smc_DEADFALL_YSPEED_MAX,
59bool dEn_c::hitCallback_Cannon(
dCc_c *self,
dCc_c *other) {
60 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
65 hitdamageEffect(mVec3_c(collPos, 5500.0f));
68 if (
mCombo.mType == dEnCombo_c::COMBO_SHORT) {
73 int score =
mCombo.getComboScore(dEnCombo_c::calcPlComboCnt(player));
76 l_base_fall_speed_x[dir],
78 smc_DEADFALL_YSPEED_MAX,
90bool dEn_c::hitCallback_Slip(
dCc_c *self,
dCc_c *other) {
91 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
96 hitdamageEffect(mVec3_c(collPos, 5500.0f));
98 setDeathSound_Slip(player);
100 int score =
mCombo.getComboScore(dEnCombo_c::calcPlComboCnt(player));
103 l_base_fall_speed_x[dir],
105 smc_DEADFALL_YSPEED_MAX,
106 smc_DEADFALL_GRAVITY,
117bool dEn_c::hitCallback_PenguinSlide(
dCc_c *self,
dCc_c *other) {
118 return hitCallback_Slip(self, other);
121bool dEn_c::hitCallback_Screw(
dCc_c *self,
dCc_c *other) {
125bool dEn_c::hitCallback_WireNet(
dCc_c *self,
dCc_c *other) {
126 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
130 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN,
mPos, 0);
133 0.75f * l_base_fall_speed_x[dir],
135 smc_DEADFALL_YSPEED_MAX,
136 smc_DEADFALL_GRAVITY,
147bool dEn_c::hitCallback_Large(
dCc_c *self,
dCc_c *other) {
148 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
152 float xSpeed = l_EnMuki[dir];
156 }
else if (xSpeed < -6.0f) {
163 smc_DEADFALL_YSPEED_MAX,
164 smc_DEADFALL_GRAVITY,
175bool dEn_c::hitCallback_Rolling(
dCc_c *self,
dCc_c *other) {
179bool dEn_c::hitCallback_Spin(
dCc_c *self,
dCc_c *other) {
180 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
184 setDeathSound_Spin();
187 playerPos.x = player->
mPos.x;
188 playerPos.y = player->
mPos.y;
189 hipatkEffect(mVec3_c(playerPos, 5500.0f));
191 int score =
mCombo.getComboScore(dEnCombo_c::calcPlFumiCnt(player));
194 l_base_fall_speed_x[dir],
196 smc_DEADFALL_YSPEED_MAX,
197 smc_DEADFALL_GRAVITY,
208bool dEn_c::hitCallback_HipAttk(
dCc_c *self,
dCc_c *other) {
209 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
213 setDeathSound_HipAttk();
216 playerPos.x = player->
mPos.x;
217 playerPos.y = player->
mPos.y;
218 hipatkEffect(mVec3_c(playerPos, 5500.0f));
220 int score =
mCombo.getComboScore(dEnCombo_c::calcPlFumiCnt(player));
223 l_base_fall_speed_x[dir],
225 smc_DEADFALL_YSPEED_MAX,
226 smc_DEADFALL_GRAVITY,
237bool dEn_c::hitCallback_YoshiHipAttk(
dCc_c *self,
dCc_c *other) {
238 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
242 int comboScore =
mCombo.getComboScore(dEnCombo_c::calcPlFumiCnt(player));
243 if (comboScore >= 0 && plrNo < PLAYER_COUNT) {
244 dScoreMng_c::m_instance->ScoreSet(
this, comboScore, plrNo, dScoreMng_c::smc_SCORE_X, dScoreMng_c::smc_SCORE_Y);
247 dAudio::g_pSndObjEmy->startSound(SE_EMY_YOSHI_HPDP,
mPos, 0);
249 setDeathInfo_YoshiFumi(player);
254bool dEn_c::hitCallback_YoshiBullet(
dCc_c *self,
dCc_c *other) {
255 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
259 setDeathSound_Fire();
261 hitdamageEffect(mVec3_c(self->getCollPosX(), self->getCollPosY(), 5500.0f));
263 dActorMng_c::m_instance->createUpCoin(
getCenterPos(), dir, 1, 0);
266 l_base_fall_speed_x[dir],
268 smc_DEADFALL_YSPEED_MAX,
269 smc_DEADFALL_GRAVITY,
280bool dEn_c::hitCallback_YoshiFire(
dCc_c *self,
dCc_c *other) {
281 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
282 u8 dir = !(player->
mSpeed.x >= 0.0f);
284 dActorMng_c::m_instance->createUpCoin(centerPos, dir, 1, 0);
288 hitdamageEffect(mVec3_c(collPos, 5500.0f));
291 if (
mCombo.mType == dEnCombo_c::COMBO_SHORT) {
302 l_base_fall_speed_x[dir],
304 smc_DEADFALL_YSPEED_MAX,
305 smc_DEADFALL_GRAVITY,
316bool dEn_c::hitCallback_Shell(
dCc_c *self,
dCc_c *other) {
317 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
322 hitdamageEffect(mVec3_c(collPos, 5500.0f));
325 if (plrNo >= 0 && plrNo < PLAYER_COUNT) {
327 if (
mCombo.mType == dEnCombo_c::COMBO_SHORT) {
337 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN,
mPos, 0);
341 l_base_fall_speed_x[dir],
343 smc_DEADFALL_YSPEED_MAX,
344 smc_DEADFALL_GRAVITY,
355bool dEn_c::hitCallback_Fire(
dCc_c *self,
dCc_c *other) {
356 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
357 u8 dir = !(player->
mSpeed.x >= 0.0f);
360 setDeathSound_Fire();
362 dActorMng_c::m_instance->createUpCoin(
getCenterPos(), dir, 1, 0);
365 l_base_fall_speed_x[dir],
367 smc_DEADFALL_YSPEED_MAX,
368 smc_DEADFALL_GRAVITY,
379bool dEn_c::hitCallback_Ice(
dCc_c *self,
dCc_c *other) {
381 daPlBase_c *player = (daPlBase_c *) other->
getOwner();
383 if (player->
mSpeed.x >= 0.0f) {
384 mBoyoMng.mDirection = 0;
386 mBoyoMng.mDirection = 1;
389 for (
int i = 0; i < PLAYER_COUNT; i++) {
390 dAcPy_c *pl = daPyMng_c::getPlayer(i);
392 pl->cancelCarry(
this);
403void dEn_c::setDeadMode(
dActor_c *actor,
int i) {
417 setDeathInfo_Smoke(actor);
419 setDeathInfo_SpinFumi(actor, 0);
421 static const float cs_effect_offset_x[] = { -6.0f, 6.0f };
423 center.x += cs_effect_offset_x[
mDeathInfo.mDirection];
424 hitdamageEffect(center);
426 dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(
mPos, 0);
430void dEn_c::setDeathInfo_Quake(
int i) {
431 mVec3_c center(getCenterX(), getCenterY(), 5500.0f);
442 dEnemyMng_c::m_instance->breakdownSE(dEnemyMng_c::m_instance->m_154,
mPos);
444 dEnemyMng_c::m_instance->incQuakeComboCount(0);
446 int comboScore =
mCombo.getQuakeScore(dEnemyMng_c::m_instance->m_154);
451 smc_DEADFALL_YSPEED_MAX,
452 smc_DEADFALL_GRAVITY,
461void dEn_c::setDeathInfo_Smoke(
dActor_c *actor) {
463 if (actor !=
nullptr) {
487 smc_DEADFALL_YSPEED_MAX,
488 smc_DEADFALL_GRAVITY,
497void dEn_c::setDeathInfo_YoshiFumi(
dActor_c *killedBy) {
506 &StateID_DieYoshiFumi,
514void dEn_c::setDeathInfo_Other(
dActor_c *killedBy) {
516 if (killedBy !=
nullptr) {
533void dEn_c::setDeathInfo_SpinFumi(
dActor_c *killedBy,
int) {
538 l_base_fall_speed_x[dir],
540 smc_DEADFALL_YSPEED_MAX,
541 smc_DEADFALL_GRAVITY,
550void dEn_c::setDeathInfo_IceBreak() {
557 l_base_fall_speed_x[dir],
559 smc_DEADFALL_YSPEED_MAX,
560 smc_DEADFALL_GRAVITY,
569void dEn_c::setDeathInfo_IceVanish() {
572 int coinDir = dGameCom::rndInt(2);
573 dActorMng_c::m_instance->createUpCoin(
getCenterPos(), coinDir, 1, 0);
583 &StateID_DieIceVanish,
591void dEn_c::initializeState_DieFumi() {
592 for (
int i = 0; i < PLAYER_COUNT; i++) {
593 dAcPy_c *pl = daPyMng_c::getPlayer(i);
595 pl->cancelCarry(
this);
619 if (plrNo >= 0 && plrNo < PLAYER_COUNT) {
620 dScoreMng_c::m_instance->ScoreSet(
this, score, plrNo, dScoreMng_c::smc_SCORE_X, dScoreMng_c::smc_SCORE_Y);
622 dScoreMng_c::m_instance->UnKnownScoreSet(
this, score, 0.0f, 24.0f);
633void dEn_c::finalizeState_DieFumi() {}
635void dEn_c::executeState_DieFumi() {
636 s16 angDelta = smc_DEADFALL_SPINSPEED / 4;
638 angDelta *= smc_WATER_ROLL_DEC_RATE;
646void dEn_c::initializeState_DieFall() {
647 for (
int i = 0; i < PLAYER_COUNT; i++) {
648 dAcPy_c *pl = daPyMng_c::getPlayer(i);
650 pl->cancelCarry(
this);
674 if (plrNo >= 0 && plrNo < PLAYER_COUNT) {
675 dScoreMng_c::m_instance->ScoreSet(
this, score, plrNo, dScoreMng_c::smc_SCORE_X, dScoreMng_c::smc_SCORE_Y);
677 dScoreMng_c::m_instance->UnKnownScoreSet(
this, score, 0.0f, 24.0f);
688void dEn_c::finalizeState_DieFall() {}
690void dEn_c::executeState_DieFall() {
691 const static s16 cs_spin_speed[] = { 0x100, -0x100 };
696 angDeltaX = smc_DEADFALL_SPINSPEED;
699 angDeltaX = -smc_DEADFALL_SPINSPEED;
703 angDeltaX *= smc_WATER_ROLL_DEC_RATE;
713void dEn_c::initializeState_DieBigFall() {
714 initializeState_DieFall();
717void dEn_c::finalizeState_DieBigFall() {
718 finalizeState_DieFall();
721void dEn_c::executeState_DieBigFall() {
722 mAngle.x += smc_DEADFALL_SPINSPEED;
728void dEn_c::initializeState_DieSmoke() {
730 mEf::createEffect(
"Wm_en_burst_m", 0, &pos,
nullptr,
nullptr);
734void dEn_c::finalizeState_DieSmoke() {}
736void dEn_c::executeState_DieSmoke() {
740void dEn_c::initializeState_DieIceVanish() {
746 if (plrNo >= 0 && plrNo < PLAYER_COUNT) {
747 dScoreMng_c::m_instance->ScoreSet(
this, score, plrNo, dScoreMng_c::smc_SCORE_X, dScoreMng_c::smc_SCORE_Y);
749 dScoreMng_c::m_instance->UnKnownScoreSet(
this, score, 0.0f, 24.0f);
754void dEn_c::finalizeState_DieIceVanish() {}
756void dEn_c::executeState_DieIceVanish() {
760void dEn_c::initializeState_DieYoshiFumi() {
762 mEf::createEffect(
"Wm_mr_yoshistep", 0, &pos,
nullptr,
nullptr);
766void dEn_c::finalizeState_DieYoshiFumi() {}
768void dEn_c::executeState_DieYoshiFumi() {
772void dEn_c::initializeState_DieGoal() {}
774void dEn_c::finalizeState_DieGoal() {}
776void dEn_c::executeState_DieGoal() {}
778void dEn_c::initializeState_DieOther() {
782void dEn_c::finalizeState_DieOther() {}
784void dEn_c::executeState_DieOther() {}
786void dEn_c::setDeathSound_Fire() {
787 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN,
mPos, 0);
790void dEn_c::setDeathSound_HipAttk() {
791 if (
mFlags & EN_IS_HARD) {
792 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN_HPDP_H,
mPos, 0);
794 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN_HPDP_S,
mPos, 0);
798void dEn_c::setDeathSound_Slip(
dActor_c *killedBy) {
799 const static dAudio::SoundEffectID_t cs_combo_se[] = {
811 int count = ((daPlBase_c *) killedBy)->m_cee;
812 if (count >= ARRAY_SIZE(cs_combo_se)) {
813 count = ARRAY_SIZE(cs_combo_se) - 1;
822void dEn_c::setDeathSound_Spin() {
823 if (
mFlags & EN_IS_HARD) {
824 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN_HPDP_H,
mPos, 0);
826 dAudio::g_pSndObjEmy->startSound(SE_EMY_DOWN_HPDP_S,
mPos, 0);
830void dEn_c::setDeathSound_Rolling() {}
static void SetVsHitEffect(mVec3_c *)
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.
void deleteActor(u8 deleteForever)
Deletes the actor and optionally disables respawn.
void slideComboSE(int multiplier, bool shortCombo)
Plays the combo kill sound effect.
bool mNoRespawn
Whether the actor should not respawn after being deleted.
dBc_c mBc
The actor-to-tile collision sensor.
static bool getTrgToSrcDir_Main(float trgX, float srcX)
See getTrgToSrcDirFunc.
u8 mAmiLayer
The actor's layer for chainlink fences.
u8 mDirection
The actor's facing direction.
virtual void removeCc()
Disables the actor's collision.
int mComboMultiplier
The current combo multiplier obtained by the actor by colliding with other actors.
s8 mPlayerNo
The player associated with the actor, -1 if not associated to any player.
virtual s8 * getPlrNo()
Gets the player number associated with the actor. See mPlayerNo.
float mAccelF
The actor's horizontal acceleration.
mVec3_c mSpeed
The actor's speed.
mVec3_c mPos
The actor's position.
mVec3_c mSpeedMax
The actor's maximum speed.
void posMove()
Moves the actor by its speed.
mVec3_c getCenterPos() const
Gets the actor's centered position.
mAng3_c mAngle
The actor's rotation (for 2D actors).
float mAccelY
The actor's vertical acceleration.
void calcSpeedY()
Updates the actor's Y speed. See here for details.
Collider ("Collision Check") class - handles collisions between actors.
mVec2_c mCollPos
The position where the last collision occurred.
dActor_c * getOwner() const
Gets the owner actor of this collider.
static const u8 smc_UNKNOWN_HIT
An enemy actor. Note that the definition of "enemy" in this context is actually any interactible stag...
u8 mIceDeathDirection
The X direction to move towards on ice death.
void WaterCheck(mVec3_c &pos, float h)
dDeathInfo_c mDeathInfo
The parameters for the death animation.
dIceMng_c mIceMng
The ice manager for this enemy.
dEnCombo_c mCombo
The enemy combo manager.
u32 mFlags
Flags for this actor. See FLAGS_e.
bool mInLiquid
Whether the enemy is in a liquid.
virtual bool checkComboClap(int max)
void setClapSE()
Plays the clap sound effect.
static dMultiMng_c * mspInstance
The instance of this class.
static fBase_c * searchBaseByID(fBaseID_e id)
Searches for a base with the given ID.
A two-dimensional floating point vector.
The interface for state IDs.
#define STATE_VIRTUAL_DEFINE(class, name)
Defines a virtual state.