From 23c3d82ff726c8fc5d7595e164f1e89b525c729a Mon Sep 17 00:00:00 2001 From: RootCubed Date: Sun, 9 Nov 2025 14:19:06 +0100 Subject: [PATCH 1/2] Match and link `daEnBomhei_c` --- include/game/bases/d_a_en_bomhei.hpp | 117 ++ include/game/bases/d_a_fireball_base.hpp | 9 + include/game/bases/d_audio.hpp | 91 +- include/game/bases/d_bc.hpp | 1 + include/game/bases/d_bg.hpp | 19 +- include/game/bases/d_enemy_manager.hpp | 6 +- include/game/bases/d_ice_manager.hpp | 2 +- include/game/mLib/m_3d/anm_mat_clr.hpp | 2 + include/game/mLib/m_angle.hpp | 4 + include/game/mLib/m_effect.hpp | 2 +- .../egg/util/{eggEffect.hpp => eggEffect.h} | 0 ...ggEffectManager.hpp => eggEffectManager.h} | 0 slices/d_enemiesNP.json | 10 + source/d_enemiesNP/bases/d_a_en_bomhei.cpp | 1257 +++++++++++++++++ source/dol/bases/d_last_actor.cpp | 2 +- syms.txt | 15 + 16 files changed, 1503 insertions(+), 34 deletions(-) create mode 100644 include/game/bases/d_a_en_bomhei.hpp create mode 100644 include/game/bases/d_a_fireball_base.hpp rename include/lib/egg/util/{eggEffect.hpp => eggEffect.h} (100%) rename include/lib/egg/util/{eggEffectManager.hpp => eggEffectManager.h} (100%) create mode 100644 source/d_enemiesNP/bases/d_a_en_bomhei.cpp diff --git a/include/game/bases/d_a_en_bomhei.hpp b/include/game/bases/d_a_en_bomhei.hpp new file mode 100644 index 00000000..4f53eb8e --- /dev/null +++ b/include/game/bases/d_a_en_bomhei.hpp @@ -0,0 +1,117 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +class daEnBomhei_c : public daEnCarry_c { +public: + enum SpawnMode_e { + SPAWN_MODE_NORMAL, + SPAWN_MODE_WAKIDASHI, + SPAWN_MODE_ICE_LUMP, + SPAWN_MODE_CANNON, + }; + + daEnBomhei_c() : mTimer(-1), m_5f0(-1), m_620(3) {} + virtual ~daEnBomhei_c() {} + + virtual int create(); + virtual int execute(); + virtual int preDraw(); + virtual int draw(); + virtual int doDelete(); + virtual void deleteReady(); + virtual void finalUpdate(); + virtual bool ActorDrawCullCheck(); + virtual void setSpinLiftUpActor(dActor_c *carryingActor); + virtual void Normal_VsEnHitCheck(dCc_c *cc1, dCc_c *cc2); + virtual void Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2); + virtual void Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2); + virtual void block_hit_init(); + virtual bool hitCallback_Shell(dCc_c *cc1, dCc_c *cc2); + virtual bool hitCallback_Fire(dCc_c *cc1, dCc_c *cc2); + virtual bool hitCallback_Ice(dCc_c *cc1, dCc_c *cc2); + virtual void returnState_Ice(); + virtual bool hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2); + virtual bool hitCallback_YoshiHipAttk(dCc_c *cc1, dCc_c *cc2); + virtual bool hitCallback_Spin(dCc_c *cc1, dCc_c *cc2) { return hitCallback_HipAttk(cc1, cc2); } + virtual bool createIceActor(); + virtual bool EtcDamageCheck(dCc_c *cc1, dCc_c *cc2); + + virtual void boyonBegin() {} + virtual bool isSpinLiftUpEnable() { return isState(StateID_Sleep); } + + STATE_FUNC_DECLARE(daEnBomhei_c, Walk); + STATE_FUNC_DECLARE(daEnBomhei_c, Sleep); + STATE_VIRTUAL_FUNC_DECLARE(daEnBomhei_c, Carry); + STATE_FUNC_DECLARE(daEnBomhei_c, Slide); + STATE_FUNC_DECLARE(daEnBomhei_c, Kick); + STATE_FUNC_DECLARE(daEnBomhei_c, KickBom); + STATE_FUNC_DECLARE(daEnBomhei_c, Wakidashi); + STATE_FUNC_DECLARE(daEnBomhei_c, Explode); + STATE_FUNC_DECLARE(daEnBomhei_c, Turn); + STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Upper); + STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Under); + STATE_FUNC_DECLARE(daEnBomhei_c, AfterIce); + STATE_FUNC_DECLARE(daEnBomhei_c, InIceLump); + STATE_VIRTUAL_FUNC_DECLARE(daEnBomhei_c, EatOut); + + virtual void vf28c(); + virtual void vf290(); + virtual void vf294(); + virtual void vf298(); + virtual void vf29c() {} + + void mdlSetup(); + + void bcSet1(); + void bcSet2(); + void setDeathInfo_Carry(dActor_c *killedBy); + void checkBombBreak(); + void someBgCheck(); + mVec2_c getSomePos(); + void calcIgnitionPos(); + void updateCarryCc(); + + void breakEffect() { mEf::createEffect("Wm_en_bombheibreak", 0, &mIgnitionPos, nullptr, nullptr); } + void explosionEffect() { mEf::createEffect("Wm_en_explosion", 0, &mIgnitionPos, nullptr, nullptr); } + + ACTOR_PARAM_CONFIG(wakidashiConfig, 0, 2); + ACTOR_PARAM_CONFIG(unk2, 4, 2); + ACTOR_PARAM_CONFIG(CannonHopDir, 6, 1); + ACTOR_PARAM_CONFIG(zLayer, 24, 4); + ACTOR_PARAM_CONFIG(spawnMode, 28, 2); + + dHeapAllocator_c mAllocator; + nw4r::g3d::ResFile mFile; + m3d::mdl_c mModel; + m3d::anmChr_c mAnm; + m3d::anmMatClr_c mAnmMat; + int mTimer; + int m_5f0; + int m_5f4; + int m_5f8; + int m_5fc; + u8 mPad[4]; + mVec3_c m_604; + float mCcOffsetX; + float mCcOffsetY; + float mCcWidth; + float mCcHeight; + int m_620; + int m_624; + int m_628; + mVec3_c mIgnitionPos; + mEf::levelEffect_c mEffect; + + static const float smc_WALK_SPEED; + static const float smc_SLIDE_SPEED_X; + static const float smc_KICK_SPEED_X; + static const float smc_KICK_SPEED_Y; + static const int smc_5EC_VALUE; + static const int smc_SOUND_EFFECTS[]; +}; diff --git a/include/game/bases/d_a_fireball_base.hpp b/include/game/bases/d_a_fireball_base.hpp new file mode 100644 index 00000000..518835a1 --- /dev/null +++ b/include/game/bases/d_a_fireball_base.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +class daFireBall_Base_c : public dActorState_c { +public: + void kill(); +}; diff --git a/include/game/bases/d_audio.hpp b/include/game/bases/d_audio.hpp index 60507d70..7135601c 100644 --- a/include/game/bases/d_audio.hpp +++ b/include/game/bases/d_audio.hpp @@ -231,6 +231,39 @@ class NMSndObject : public NMSndObjectBase { nw4r::math::VEC2 mPos; }; +template +class NMSndObjectCmn : public NMSndObjectBase { +public: + class SoundHandlePrm : public nw4r::snd::SoundHandle { + public: + SoundHandlePrm() : m_04(1.0f) {} + + float m_04; + }; + + NMSndObjectCmn() : + NMSndObjectBase(NMSndObjectBase::OBJ_TYPE_0, SndAudioMgr::sInstance->mArcPlayer), + m_64(1.0f), m_68(0), m_6c(1.0f), m_70(0.0f) + { + SetPlayableSoundCount(0, T); + mTotalCount = T + 2; + m_58 = 1; + } + + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, short p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, short p4, unsigned long p5); + + float m_64; + int m_68; + float m_6c; + float m_70; + SoundHandlePrm mParams[T + 2]; + nw4r::math::VEC2 mPos; +}; + class SndObjctPly : public NMSndObject<4> { public: void calculate(const nw4r::math::VEC2 &pos) { @@ -260,24 +293,22 @@ class SndObjctEmy : public NMSndObject<4> { virtual SoundHandlePrm *holdSound(ulong p1, const nw4r::math::VEC2 &p2, ulong p3); }; -class SndObjctCmnEmy : public NMSndObject<4> { +class SndObjctCmnEmy : public NMSndObjectCmn<12> { public: - virtual SoundHandlePrm *startSound(ulong p1, ulong p2); - virtual SoundHandlePrm *holdSound(ulong p1, ulong p2); - virtual SoundHandlePrm *startSound(ulong p1, short p2, ulong p3); - virtual SoundHandlePrm *holdSound(ulong p1, short p2, ulong p3); - virtual SoundHandlePrm *startSound(ulong p1, const nw4r::math::VEC2 &p2, ulong p3); - virtual SoundHandlePrm *holdSound(ulong p1, const nw4r::math::VEC2 &p2, ulong p3); + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, short p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, short p4, unsigned long p5); }; -class SndObjctCmnMap : public NMSndObject<4> { +class SndObjctCmnMap : public NMSndObjectCmn<12> { public: - virtual SoundHandlePrm *startSound(ulong p1, ulong p2); - virtual SoundHandlePrm *holdSound(ulong p1, ulong p2); - virtual SoundHandlePrm *startSound(ulong p1, short p2, ulong p3); - virtual SoundHandlePrm *holdSound(ulong p1, short p2, ulong p3); - virtual SoundHandlePrm *startSound(ulong p1, const nw4r::math::VEC2 &p2, ulong p3); - virtual SoundHandlePrm *holdSound(ulong p1, const nw4r::math::VEC2 &p2, ulong p3); + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *startSound(unsigned long p1, const nw4r::math::VEC2 &p2, short p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, const nw4r::math::VEC2 &p2, unsigned long p3); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, unsigned long p4); + virtual SoundHandlePrm *holdSound(unsigned long p1, int p2, const nw4r::math::VEC2 &p3, short p4, unsigned long p5); }; namespace dAudio { @@ -340,6 +371,12 @@ namespace dAudio { SoundHandlePrm *startSound(unsigned long soundID, const mVec3_c &pos, int remPlayer) { return SndObjctCmnEmy::startSound(soundID, dAudio::cvtSndObjctPos(pos), remPlayer); } + SoundHandlePrm *holdSound(unsigned long soundID, int i, const nw4r::math::VEC2 &pos, int remPlayer) { + return SndObjctCmnEmy::holdSound(soundID, i, pos, remPlayer); + } + SoundHandlePrm *holdSound(unsigned long soundID, int i, const mVec3_c &pos, int remPlayer) { + return SndObjctCmnEmy::holdSound(soundID, i, dAudio::cvtSndObjctPos(pos), remPlayer); + } }; class SndObjctEmy_c : public SndObjctEmy { @@ -390,20 +427,34 @@ namespace dAudio { obj->startSound(id, dAudio::cvtSndObjctPos(pos), playerNo); } - void playEmySound(const mVec2_c &pos, int playerNo) const { - playObjSound(dAudio::g_pSndObjEmy, pos, playerNo); + template + void holdObjSound(T *obj, int i, const mVec2_c &pos, int playerNo) const { + obj->holdSound(id, i, dAudio::cvtSndObjctPos(pos), playerNo); } - void playEmySound(const mVec3_c &pos, int playerNo) const { + template + void holdObjSound(T *obj, int i, const mVec3_c &pos, int playerNo) const { + obj->holdSound(id, i, dAudio::cvtSndObjctPos(pos), playerNo); + } + + template + void playEmySound(const T &pos, int playerNo) const { playObjSound(dAudio::g_pSndObjEmy, pos, playerNo); } - void playMapSound(const mVec2_c &pos, int playerNo) const { + template + void playMapSound(const T &pos, int playerNo) const { playObjSound(dAudio::g_pSndObjMap, pos, playerNo); } - void playMapSound(const mVec3_c &pos, int playerNo) const { - playObjSound(dAudio::g_pSndObjMap, pos, playerNo); + template + void holdEmySound(int i, const T &pos, int playerNo) const { + holdObjSound(dAudio::g_pSndObjEmy, i, pos, playerNo); + } + + template + void holdMapSound(int i, const T &pos, int playerNo) const { + holdObjSound(dAudio::g_pSndObjMap, i, pos, playerNo); } private: diff --git a/include/game/bases/d_bc.hpp b/include/game/bases/d_bc.hpp index 95c655ea..50bcc5c1 100644 --- a/include/game/bases/d_bc.hpp +++ b/include/game/bases/d_bc.hpp @@ -157,6 +157,7 @@ class dBc_c { u16 getHeadAttr(); short getHeadSakaMoveAngle(u8 direction); void clearBgcSaveAll(); + void checkBombBreak(mVec2_c, mVec2_c); bool getSakaUpDown(u8 direction); short getSakaAngleBySpeed(float); diff --git a/include/game/bases/d_bg.hpp b/include/game/bases/d_bg.hpp index 526d4dff..2f36c7fa 100644 --- a/include/game/bases/d_bg.hpp +++ b/include/game/bases/d_bg.hpp @@ -17,6 +17,16 @@ class dBg_c { }; public: + float getLiquidHeight() const { return mLiquidHeight; } + + float getDispScale() { return mDispScale; } + float getPrevDispScale() { return mPrevDispScale; } + + void setWaterInWave(float x, float y, u8 type); + float getLeftLimit(); + float getRightLimit(); + void BgUnitChange(u16, u16, int, u16); + u8 mPad1[0x8fe70]; float m_8fe00; u8 mPad2[0x2c]; @@ -34,14 +44,5 @@ class dBg_c { u8 mPad7[0x1a]; u8 m_9008e; - float getLiquidHeight() const { return mLiquidHeight; } - - void setWaterInWave(float x, float y, u8 type); - float getLeftLimit(); - float getRightLimit(); - - float getDispScale() { return mDispScale; } - float getPrevDispScale() { return mPrevDispScale; } - static dBg_c *m_bg_p; }; diff --git a/include/game/bases/d_enemy_manager.hpp b/include/game/bases/d_enemy_manager.hpp index 2573dfa3..6a23ac6c 100644 --- a/include/game/bases/d_enemy_manager.hpp +++ b/include/game/bases/d_enemy_manager.hpp @@ -12,9 +12,11 @@ class dEnemyMng_c { u8 mPad1[0x138]; int m_138; - u8 mPad2[0x18]; - int m_154; + u8 mPad2[0x10]; + int m_14c; u8 mPad3[0x4]; + int m_154; + u8 mPad4[0x4]; int m_15c; static dEnemyMng_c *m_instance; diff --git a/include/game/bases/d_ice_manager.hpp b/include/game/bases/d_ice_manager.hpp index d0f2cc7c..cd4bf2a7 100644 --- a/include/game/bases/d_ice_manager.hpp +++ b/include/game/bases/d_ice_manager.hpp @@ -20,7 +20,7 @@ class dIceEfScale_c { class dIceInfo { public: - ~dIceInfo(); + ~dIceInfo() {} int mMode; mVec3_c mPos; diff --git a/include/game/mLib/m_3d/anm_mat_clr.hpp b/include/game/mLib/m_3d/anm_mat_clr.hpp index d5aec51e..6bbdbb57 100644 --- a/include/game/mLib/m_3d/anm_mat_clr.hpp +++ b/include/game/mLib/m_3d/anm_mat_clr.hpp @@ -6,6 +6,8 @@ namespace m3d { class anmMatClr_c : public banm_c { public: + anmMatClr_c() : children(nullptr) {} + virtual ~anmMatClr_c(); virtual void remove(); virtual void play(); diff --git a/include/game/mLib/m_angle.hpp b/include/game/mLib/m_angle.hpp index 339cdc6e..9504b1cf 100644 --- a/include/game/mLib/m_angle.hpp +++ b/include/game/mLib/m_angle.hpp @@ -29,6 +29,10 @@ struct mAng { return sLib::chase(&mAngle, target, step); } + BOOL chaseAngle(short target, short step) { + return sLib::chaseAngle(&mAngle, target, step); + } + int abs() const { return ::abs(mAngle); } diff --git a/include/game/mLib/m_effect.hpp b/include/game/mLib/m_effect.hpp index 608fd824..9b5dfcc6 100644 --- a/include/game/mLib/m_effect.hpp +++ b/include/game/mLib/m_effect.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/include/lib/egg/util/eggEffect.hpp b/include/lib/egg/util/eggEffect.h similarity index 100% rename from include/lib/egg/util/eggEffect.hpp rename to include/lib/egg/util/eggEffect.h diff --git a/include/lib/egg/util/eggEffectManager.hpp b/include/lib/egg/util/eggEffectManager.h similarity index 100% rename from include/lib/egg/util/eggEffectManager.hpp rename to include/lib/egg/util/eggEffectManager.h diff --git a/slices/d_enemiesNP.json b/slices/d_enemiesNP.json index eb3c3c8f..2e69129f 100644 --- a/slices/d_enemiesNP.json +++ b/slices/d_enemiesNP.json @@ -48,6 +48,16 @@ ".bss": "0x0-0x8" } }, + { + "source": "d_enemiesNP/bases/d_a_en_bomhei.cpp", + "memoryRanges": { + ".text": "0x25fa0-0x2b0e0", + ".ctors": "0x60-0x64", + ".data": "0x80c0-0x8838", + ".rodata": "0x10b8-0x1330", + ".bss": "0x1618-0x1998" + } + }, { "source": "d_enemiesNP/bases/d_a_en_noko.cpp", "memoryRanges": { diff --git a/source/d_enemiesNP/bases/d_a_en_bomhei.cpp b/source/d_enemiesNP/bases/d_a_en_bomhei.cpp new file mode 100644 index 00000000..124a31ea --- /dev/null +++ b/source/d_enemiesNP/bases/d_a_en_bomhei.cpp @@ -0,0 +1,1257 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ACTOR_PROFILE(EN_BOMHEI, daEnBomhei_c, 0x12); + +STATE_DEFINE(daEnBomhei_c, Walk); +STATE_DEFINE(daEnBomhei_c, Sleep); +STATE_VIRTUAL_DEFINE(daEnBomhei_c, Carry); +STATE_DEFINE(daEnBomhei_c, Slide); +STATE_DEFINE(daEnBomhei_c, Kick); +STATE_DEFINE(daEnBomhei_c, KickBom); +STATE_DEFINE(daEnBomhei_c, Wakidashi); +STATE_DEFINE(daEnBomhei_c, Explode); +STATE_DEFINE(daEnBomhei_c, Turn); +STATE_DEFINE(daEnBomhei_c, CannonHop_Upper); +STATE_DEFINE(daEnBomhei_c, CannonHop_Under); +STATE_DEFINE(daEnBomhei_c, AfterIce); +STATE_DEFINE(daEnBomhei_c, InIceLump); +STATE_VIRTUAL_DEFINE(daEnBomhei_c, EatOut); + +const float daEnBomhei_c::smc_WALK_SPEED = 0.5f; +const float daEnBomhei_c::smc_SLIDE_SPEED_X = 4.0f; +const float daEnBomhei_c::smc_KICK_SPEED_X = 2.5f; +const float daEnBomhei_c::smc_KICK_SPEED_Y = 2.0f; +const int daEnBomhei_c::smc_5EC_VALUE = 240; + +const sBcSensorPoint l_bomhei_head = { SENSOR_IS_POINT, 0x0, 0x10000 }; +const sBcSensorLine l_bomhei_foot = { SENSOR_IS_LINE, -0x3000, 0x3000, 0 }; +const sBcSensorPoint l_bomhei_wall = { SENSOR_IS_POINT, 0x6000, 0x6000 }; +const sBcSensorPoint l_bomhei_4 = { 0x40000, 0, 0x10000 }; +const sBcSensorPoint l_bomhei_5 = { 0x40000, 0, 0 }; +const sBcSensorPoint l_bomhei_6 = { 0x40000, 0x6000, 0x6000 }; +const sBcSensorLine l_bomhei_7 = { 0x82000001, -0x6000, 0x6000, 0x10000 }; +const u32 l_unused1[] = { 0, 0 }; +const sBcSensorLine l_bomhei_8 = { 0x82000001, -0x6000, 0x6000, 0 }; +const u32 l_unused2[] = { 0, 0 }; +const sBcSensorLine l_bomhei_9 = { 0x82000001, 0xE000, 0x3000, 0x8000 }; +const u32 l_unused3[] = { 0, 0 }; + +int unused() { + return l_unused1[0] + l_unused2[0] + l_unused3[0]; +} + +const sCcDatNewF l_bomhei_cc = { + 0.0f, 8.0f, + 8.0f, 8.0f, + CC_KIND_ENEMY, + CC_ATTACK_NONE, + BIT_FLAG(CC_KIND_PLAYER) | BIT_FLAG(CC_KIND_PLAYER_ATTACK) | BIT_FLAG(CC_KIND_YOSHI) | + BIT_FLAG(CC_KIND_ITEM) | BIT_FLAG(CC_KIND_ENEMY) | BIT_FLAG(CC_KIND_TAMA), + (u32) ~BIT_FLAG(CC_ATTACK_NONE) & ~BIT_FLAG(CC_ATTACK_YOSHI_MOUTH) & ~BIT_FLAG(CC_ATTACK_SAND_PILLAR), + CC_STATUS_NONE, + dEn_c::normal_collcheck, +}; + +const short l_turn_angleY_add[] = { 0x400, -0x400 }; + +int daEnBomhei_c::create() { + mdlSetup(); + mScale.set(1.0f, 1.0f, 1.0f); + mSpeedMax.set(0.0f, -4.0f, 0.0f); + mVisibleAreaOffset.set(0.0f, 8.0f); + mVisibleAreaSize.set(16.0f, 16.0f); + mCenterOffs.set(0.0f, 8.0f, 0.0f); + + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); + mBc.m_4c = mPos.x; + mCc.set(this, (sCcDatNewF *) &l_bomhei_cc); + mCc.entry(); + + mEatBehavior = EAT_TYPE_DRINK; + mFlags = EN_IS_HARD; + + if (ACTOR_PARAM(spawnMode) != SPAWN_MODE_ICE_LUMP) { + dEnemyMng_c::m_instance->m_14c++; + } + vf298(); + + return SUCCEEDED; +} + +void daEnBomhei_c::vf298() { + if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_WAKIDASHI) { + changeState(StateID_Wakidashi); + } else if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_ICE_LUMP) { + changeState(StateID_InIceLump); + } else if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_CANNON) { + int unk2 = ACTOR_PARAM(unk2); + m_5f8 = unk2; + mDirection = unk2 & 1; + mAngle.y = l_base_angleY[mDirection]; + if (unk2 == 0 || unk2 == 1) { + changeState(StateID_CannonHop_Upper); + } else { + changeState(StateID_CannonHop_Under); + } + } else { + mDirection = getPl_LRflag(mPos); + mAngle.y = l_base_angleY[mDirection]; + changeState(StateID_Walk); + } +} + +void daEnBomhei_c::mdlSetup() { + mAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[0], nullptr, 0x20); + + mFile = dResMng_c::m_instance->getRes("bombhei", "g3d/bombhei.brres"); + nw4r::g3d::ResMdl resMdl = mFile.GetResMdl("bombhei"); + mModel.create(resMdl, &mAllocator, 0x128, 1, nullptr); + + setSoftLight_Enemy(mModel); + nw4r::g3d::ResAnmChr anmChr = mFile.GetResAnmChr("walk"); + mAnm.create(resMdl, anmChr, &mAllocator, nullptr); + + nw4r::g3d::ResAnmClr anmClr = mFile.GetResAnmClr("bombhei"); + mAnmMat.create(resMdl, anmClr, &mAllocator, nullptr, 1); + + mModel.setAnm(mAnmMat); + mAnmMat.setPlayMode(m3d::FORWARD_ONCE, 0); + mAnmMat.setFrame(0.0f, 0); + + vf294(); + mAllocator.adjustFrmHeap(); +} + +void daEnBomhei_c::vf294() {} + +int daEnBomhei_c::execute() { + mStateMgr.executeState(); + if (!isState(StateID_InIceLump)) { + if (!isState(StateID_Ice)) { + if (mTimer > 0) { + mAnmMat.play(); + dAudio::SoundEffectID_t(SE_EMY_BH_HIBANA).holdEmySound(mUniqueID, mPos, 0); + } + if (m_628 > 0) { + m_628--; + } + if (HasamareBgCheck() || EnLavaCheck(mPos)) { + changeState(StateID_Explode); + } + } + ActorScrOutCheck(0); + } + return SUCCEEDED; +} + +int daEnBomhei_c::preDraw() { + if (dEn_c::preDraw() == NOT_READY) { + return NOT_READY; + } + if (isState(StateID_Explode)) { + return NOT_READY; + } + return SUCCEEDED; +} + +int daEnBomhei_c::draw() { + mModel.entry(); + return SUCCEEDED; +} + +void daEnBomhei_c::vf290() { + mVec3_c pos = mPos; + mAng3_c angle = mAngle; + if (isState(StateID_Carry)) { + pos = calcCarryPos(m_604); + mPos.x = pos.x; + mPos.y = pos.y; + } + changePosAngle(&pos, &angle, 1); + mMatrix.trans(pos.x, pos.y, pos.z); + mMatrix.YrotM(angle.y); + + mMatrix.concat(mMtx_c::createTrans(0.0f, 8.0f, 0.0f)); + mMatrix.XrotM(angle.x); + mMatrix.concat(mMtx_c::createTrans(0.0f, -8.0f, 0.0f)); + + mMatrix.concat(mMtx_c::createTrans(0.0f, 16.0f, 0.0f)); + mMatrix.ZrotM(angle.z); + mMatrix.concat(mMtx_c::createTrans(0.0f, -16.0f, 0.0f)); + + mModel.setLocalMtx(&mMatrix); + mModel.setScale(mScale); + mModel.calc(false); + + calcIgnitionPos(); +} + +void daEnBomhei_c::deleteReady() {} + +int daEnBomhei_c::doDelete() { + for (int i = 0; i < PLAYER_COUNT; i++) { + dAcPy_c *player = daPyMng_c::getPlayer(i); + if (player != nullptr && fManager_c::searchBaseByID(player->mCarryActorID) == this) { + player->cancelCarry(this); + } + } + if (ACTOR_PARAM(spawnMode) != SPAWN_MODE_ICE_LUMP) { + dEnemyMng_c::m_instance->m_14c--; + if (dEnemyMng_c::m_instance->m_14c < 0) { + dEnemyMng_c::m_instance->m_14c = 0; + } + } + return SUCCEEDED; +} + +void daEnBomhei_c::finalUpdate() { + vf290(); +} + +bool daEnBomhei_c::ActorDrawCullCheck() { + if (isState(StateID_Carry)) { + return false; + } + return dActor_c::ActorDrawCullCheck(); +} + +void daEnBomhei_c::calcIgnitionPos() { + nw4r::g3d::ResNode resNode = mModel.getResMdl().GetResNode("skl_root"); + mMtx_c mtx; + mModel.getNodeWorldMtx(resNode.GetID(), &mtx); + mtx.multVecZero(mIgnitionPos); +} + +void daEnBomhei_c::updateCarryCc() { + bool dir = mAngle.y < 0 ? 1 : 0; + + static const float fs[] = { -8.0f, 8.0f }; + + mVec3_c v1( + getCenterPos().x + fs[dir], + getCenterPos().y, + getCenterPos().z + ); + + mVec3_c v2( + v1.x + l_EnMuki[dir] * 16.0f, + v1.y, + v1.z + ); + + mCc.mCcData.mBase.mOffset.set(mCcOffsetX, mCcOffsetY); + mCc.mCcData.mBase.mSize.set(mCcWidth, mCcHeight); + float f = 0.0f; + if (dBc_c::checkWall(&v1, &v2, &f, mLayer, 1, nullptr)) { + float f1 = (v1.x + f) * 0.5f; + float f2 = (v1.x - f) * 0.5f; + mCc.mCcData.mBase.mOffset.set(f1 - mPos.x, 8.0f); + mCc.mCcData.mBase.mSize.set(std::fabs(f2), 8.0f); + } +} + +void daEnBomhei_c::setSpinLiftUpActor(dActor_c *carryingActor) { + int plrNo = carryingActor->getPlrNo(); + mPlayerNo = plrNo; + m_624 = plrNo; + m_604.set(0.0f, 0.0f, 0.0f); + changeState(StateID_Carry); +} + +void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) { + dAcPy_c *other = (dAcPy_c *) cc2->mpOwner; + if (fManager_c::searchBaseByID(other->mCarryActorID) == this) { + return; + } + u8 newDir = cc1->mCollOffsetX[0] >= 0.0f ? 0 : 1; + u8 plrNo = other->getPlrNo(); + if (isState(StateID_Sleep)) { + if (carry_check(other)) { + m_624 = plrNo; + m_604.set(0.0f, -5.0f, 6.0f); + changeState(StateID_Carry); + } else { + mDirection = newDir; + mNoHitPlayer.mTimer[plrNo] = 32; + dAudio::SoundEffectID_t(SE_EMY_KAME_KERU).playEmySound(getCenterPos(), dAudio::getRemotePlayer(plrNo)); + mPlayerNo = plrNo; + mBc.mOwningPlrNo = plrNo; + changeState(StateID_Kick); + } + } else if (isState(StateID_Slide) || isState(StateID_Kick)) { + mDirection = newDir; + mNoHitPlayer.mTimer[plrNo] = 32; + dAudio::SoundEffectID_t(SE_EMY_KAME_KERU).playEmySound(getCenterPos(), dAudio::getRemotePlayer(plrNo)); + mPlayerNo = plrNo; + mBc.mOwningPlrNo = plrNo; + changeState(StateID_Kick); + } else { + int checkRes = Enfumi_check(cc1, cc2, 0); + if (checkRes == 0) { + if (!isState(StateID_Wakidashi) && !isState(StateID_Carry)) { + dEn_c::Normal_VsPlHitCheck(cc1, cc2); + } + } else if (checkRes == 1) { + mPlayerNo = plrNo; + mBc.mOwningPlrNo = plrNo; + if (isState(StateID_Carry)) { + changeState(StateID_Kick); + } else { + vf28c(); + } + } else if (checkRes == 3) { + mDirection = newDir; + mPlayerNo = plrNo; + mBc.mOwningPlrNo = plrNo; + if (mTimer < 0) { + mTimer = smc_5EC_VALUE; + mAnmMat.setFrame(0.0f, 0); + } + vf29c(); + changeState(StateID_Slide); + } + } +} + +void daEnBomhei_c::Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2) { + daYoshi_c *other = (daYoshi_c *) cc2->mpOwner; + u8 newDir = cc1->mCollOffsetX[2] >= 0.0f ? 0 : 1; + u8 plrNo = other->getPlrNo(); + if (Enfumi_check(cc1, cc2, 0) == 0) { + if (isState(StateID_Sleep) || isState(StateID_Slide) || isState(StateID_Kick)) { + if (plrNo < PLAYER_COUNT) { + mDirection = newDir; + mPlayerNo = plrNo; + mNoHitPlayer.mTimer[plrNo] = 32; + mBc.mOwningPlrNo = plrNo; + dAudio::SoundEffectID_t(SE_EMY_KAME_KERU).playEmySound(getCenterPos(), dAudio::getRemotePlayer(plrNo)); + changeState(StateID_Kick); + } + } else { + dEn_c::Normal_VsYoshiHitCheck(cc1, cc2); + } + } else if (!isState(StateID_Explode)) { + setDeathInfo_YoshiFumi(other); + } +} + +void daEnBomhei_c::Normal_VsEnHitCheck(dCc_c *cc1, dCc_c *cc2) { + u16 flag = cc2->mCcData.mStatus; + dActor_c *other = cc2->getOwner(); + + if (flag & 0x200) { + cc1->mInfo |= CC_NO_HIT; + if (!isState(StateID_Explode)) { + changeState(StateID_Explode); + } + } else if (cc1->mCcData.mAttack == CC_ATTACK_SHELL && (flag & 0x100) && hitCallback_Shell(cc1, cc2)) { + cc2->mInfo |= CC_NO_HIT; + cc1->mInfo |= CC_NO_HIT; + } else if ( + isState(StateID_Carry) && (cc2->mCcData.mVsDamage & BIT_FLAG(CC_ATTACK_SHELL)) && + other->mProfName != fProfile::EN_HATENA_BALLOON && hitCallback_Shell(cc1, cc2) + ) { + cc2->mInfo |= CC_NO_HIT; + } else if (isState(StateID_Walk)) { + float offsetX = cc1->mCollOffsetX[3]; + + if ((mDirection == 1 && offsetX > 0.0f) || (mDirection == 0 && offsetX < 0.0f)) { + changeState(StateID_Turn); + } + } else { + dEn_c::Normal_VsEnHitCheck(cc1, cc2); + } +} + +void daEnBomhei_c::vf28c() { + if (isState(StateID_Wakidashi)) { + float f = l_EnMuki[mDirection ^ 1]; + mBc.checkWall(&f); + } + mSpeed.set(0.0f, 0.0f, 0.0f); + vf29c(); + if (mTimer < 0) { + mTimer = smc_5EC_VALUE; + mAnmMat.setFrame(0.0f, 0); + changeState(StateID_Sleep); + } +} + +void daEnBomhei_c::block_hit_init() { + mVec3_c shiftedPos(mVec2_c(mPos.x, mPos.y), 5500.0f); + + hitdamageEffect(shiftedPos); + dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); + + mDirection = mDeathFallDirection; + mSpeed.set(l_base_fall_speed_x[mDirection], 3.0f, 0.0f); + vf29c(); + if (mTimer < 0) { + mTimer = smc_5EC_VALUE; + mAnmMat.setFrame(0.0f, 0); + changeState(StateID_Sleep); + } +} + +bool daEnBomhei_c::hitCallback_Shell(dCc_c *cc1, dCc_c *cc2) { + dActor_c *other = cc2->getOwner(); + u8 dir = getTrgToSrcDir_Main( + getCenterX(), + other->getCenterX() + ); + int plrNo = acmShellPlayerNo(other); + shellDamageEffect(cc1, other); + int comboScore = -1; + if ((u32) plrNo < PLAYER_COUNT) { + int shortCombo = 0; + if (mCombo.mType == 2) { + shortCombo = 1; + } + other->slideComboSE(other->mComboMultiplier, shortCombo); + other->mComboMultiplier++; + if (other->mComboMultiplier >= 8) { + other->mComboMultiplier = 8; + } + comboScore = mCombo.getComboScore(other->mComboMultiplier); + } else { + dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); + } + + mDeathInfo = (sDeathInfoData) { + l_base_fall_speed_x[dir], + smc_DEADFALL_YSPEED, + smc_DEADFALL_YSPEED_MAX, + smc_DEADFALL_GRAVITY, + &StateID_DieFall, + comboScore, + -1, + dir, + (u8) plrNo + }; + + return true; +} + +bool daEnBomhei_c::hitCallback_Fire(dCc_c *cc1, dCc_c *cc2) { + dActor_c *other = cc2->getOwner(); + u8 dir = !(other->mSpeed.x >= 0.0f); + mDirection = dir; + mAngle.y = l_base_angleY[dir]; + mSpeed.x = l_EnMuki[dir] * smc_WALK_SPEED; + mSpeed.y = 1.5f; + mSpeedMax.x = 0.0f; + dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); + if (--m_620 >= 0) { + dActorMng_c::m_instance->createUpCoin(getCenterPos(), dir, 1, 0); + } + vf29c(); + if (mTimer < 0) { + mTimer = smc_5EC_VALUE; + mAnmMat.setFrame(0.0f, 0); + changeState(StateID_Sleep); + } + + return true; +} + +bool daEnBomhei_c::hitCallback_Ice(dCc_c *cc1, dCc_c *cc2) { + if (mIceMng.mActive) { + return true; + } + + dActor_c *player = (dActor_c *) cc2->getOwner(); + if (player->mSpeed.x >= 0.0f) { + mBoyoMng.mDirection = 0; + } else { + mBoyoMng.mDirection = 1; + } + + mAnmMat.setFrame(0.0f, 0); + + for (int i = 0; i < PLAYER_COUNT; i++) { + dAcPy_c *pl = daPyMng_c::getPlayer(i); + if (pl != nullptr && fManager_c::searchBaseByID(pl->mCarryActorID) == this) { + pl->cancelCarry(this); + } + } + mIceMng.mPlrNo = player->getPlrNo(); + changeState(StateID_Ice); + + mTimer = -1; + mPlayerNo = -1; + + return true; +} + +void daEnBomhei_c::returnState_Ice() { + mPlayerNo = -1; + changeState(StateID_AfterIce); +} + +bool daEnBomhei_c::hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2) { + dActor_c *other = cc2->getOwner(); + u8 plrNo = other->getPlrNo(); + + if (plrNo >= PLAYER_COUNT) { + return true; + } + if (mNoHitPlayer.mTimer[plrNo] != 0) { + return true; + } + + if (mPos.x >= other->mPos.x) { + mDirection = 0; + } else { + mDirection = 1; + } + mPlayerNo = plrNo; + dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); + hipatkEffect(other->mPos); + mNoHitPlayer.mTimer[mPlayerNo] = 16; + if (mTimer < 0) { + mTimer = smc_5EC_VALUE; + mAnmMat.setFrame(0.0f, 0); + } + vf29c(); + changeState(StateID_Slide); + + return true; +} + +bool daEnBomhei_c::hitCallback_YoshiHipAttk(dCc_c *cc1, dCc_c *cc2) { + if (!isState(StateID_Explode)) { + dAudio::SoundEffectID_t(SE_EMY_YOSHI_HPDP).playEmySound(mPos, 0); + setDeathInfo_YoshiFumi(cc2->getOwner()); + + return true; + } + + return false; +} + +bool daEnBomhei_c::createIceActor() { + mVec3_c pos, size; + if (isState(StateID_Walk) || isState(StateID_Turn)) { + pos.set(mPos.x, mPos.y - 2.0f, mPos.z); + size.set(1.25f, 1.25f, 1.25f); + } else { + pos.set(mPos.x, mPos.y - 2.0f, 2.0f + mPos.z); + size.set(1.25f, 1.25f, 1.5f); + } + + dIceInfo iceInfo[] = { + { + 0, + pos, + size + } + }; + return mIceMng.createIce(iceInfo, ARRAY_SIZE(iceInfo)); +} + +bool daEnBomhei_c::EtcDamageCheck(dCc_c *cc1, dCc_c *cc2) { + if (dEn_c::EtcDamageCheck(cc1, cc2)) { + return true; + } + + dActor_c *other = cc2->getOwner(); + daEnBomhei_c *self = (daEnBomhei_c *) cc1->getOwner(); + if (cc2->mCcData.mStatus & 0x200) { + cc1->mInfo |= CC_NO_HIT; + if (!self->isState(StateID_Explode)) { + self->changeState(StateID_Explode); + } + return true; + } else if (other->mProfName == fProfile::PAKKUN_FIREBALL || other->mProfName == fProfile::BROS_FIREBALL) { + if (self->mTimer < 0) { + self->mTimer = smc_5EC_VALUE; + self->mAnmMat.setFrame(0.0f, 0); + self->changeState(StateID_Sleep); + } + daFireBall_Base_c *fireball = (daFireBall_Base_c *) other; + fireball->kill(); + return true; + } + + return false; +} + +void daEnBomhei_c::bcSet1() { + mBc.set(this, l_bomhei_5, l_bomhei_4, l_bomhei_6); + mBc.mOwningPlrNo = mPlayerNo; +} + +void daEnBomhei_c::bcSet2() { + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); +} + +void daEnBomhei_c::setDeathInfo_Carry(dActor_c *killedBy) { + mDeathInfo = (sDeathInfoData) { + 0.0f, + 3.0f, + -4.0f, + -0.1875f, + &StateID_DieFall, + -1, + -1, + mDirection, + (u8) killedBy->getPlrNo() + }; +} + +void daEnBomhei_c::checkBombBreak() { + mVec2_c v1, v2; + + static const float offsets[2][2] = { + { 40.0f, -24.0f }, + { 24.0f, -40.0f } + }; + + v1.x = mPos.x + offsets[mDirection][1]; + v1.y = mPos.y + 15.0f; + v2.x = mPos.x + offsets[mDirection][0]; + v2.y = mPos.y + 1.0f; + mBc.checkBombBreak(v1, v2); + + v1.x = mPos.x - 8.0f; + v1.y = mPos.y + 31.0f; + v2.x = mPos.x + 8.0f; + v2.y = mPos.y - 15.0f; + mBc.checkBombBreak(v1, v2); +} + +void daEnBomhei_c::someBgCheck() { + mVec2_c pos = getSomePos(); + for (int i = 0; i < 2; i++) { + int unitType = dBc_c::getUnitType(pos.x, pos.y, mLayer); + if (unitType & 0x1c) { + short x, y; + y = -pos.y; + x = pos.x; + dBg_c::m_bg_p->BgUnitChange(x, y, 0, 0); + } + pos.x += l_EnMuki[mDirection] * 16.0f; + } +} + +mVec2_c daEnBomhei_c::getSomePos() { + if (m_5f0 >= 9) { + return mVec2_c(0.0f, 0.0f); + } + static const float xOffsets[] = { + -16.0f, 0.0f, 16.0f, + -16.0f, 0.0f, 16.0f, + -16.0f, 0.0f, 16.0f + }; + static const float yOffsets[] = { + 16.0f, 16.0f, 16.0f, + 0.0f, 0.0f, 0.0f, + -16.0f, -16.0f, -16.0f + }; + int roundedX = mPos.x / 16; + int roundedY = mPos.y / 16; + float x = roundedX * 16.0f; + float y = roundedY * 16.0f; + x += xOffsets[m_5f0]; + y += yOffsets[m_5f0]; + return mVec2_c(x, y); +} + +void explosionCallback(dCc_c *cc1, dCc_c *cc2) { + dActor_c *self = cc1->getOwner(); + dActor_c *other = cc2->getOwner(); + if (other->mKind == dActor_c::STAGE_ACTOR_PLAYER || other->mKind == dActor_c::STAGE_ACTOR_YOSHI) { + daPlBase_c *player = (daPlBase_c *) other; + player->setDamage(self, daPlBase_c::DAMAGE_DEFAULT); + } +} + +void daEnBomhei_c::initializeState_Walk() { + if ( + *mStateMgr.getOldStateID() != StateID_AfterIce && + *mStateMgr.getOldStateID() != StateID_CannonHop_Upper && + *mStateMgr.getOldStateID() != StateID_CannonHop_Under + ) { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("walk"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 2.0f); + mAnm.setRate(1.0f); + } + + static const float dirSpeed[] = { smc_WALK_SPEED, -smc_WALK_SPEED }; + + mFlags &= ~0x10000; + mSpeed.x = dirSpeed[mDirection]; + mPos.z = 1500.0f + ACTOR_PARAM(zLayer) * 16.0f; + mPlayerNo = -1; + mBc.mOwningPlrNo = -1; +} + +void daEnBomhei_c::finalizeState_Walk() {} + +void daEnBomhei_c::executeState_Walk() { + mModel.play(); + calcSpeedY(); + posMove(); + EnBgCheckFoot(); + if (mBc.isFoot()) { + mSpeed.y = 0.0f; + } + mBc.checkHead(mBc.mFlags); + EnBgCheckWall(); + WaterCheck(mPos, 1.0f); + if (mBc.mFlags & 0x15 << mDirection) { + changeState(StateID_Turn); + } +} + +void daEnBomhei_c::initializeState_Turn() { + mSpeed.x = 0.0f; + mDirection ^= 1; +} + +void daEnBomhei_c::finalizeState_Turn() {} + +void daEnBomhei_c::executeState_Turn() { + mModel.play(); + calcSpeedY(); + posMove(); + EnBgCheckFoot(); + if (mBc.isFoot()) { + mAnm.setRate(1.0f); + mSpeed.y = 0.0f; + } + mBc.checkHead(mBc.mFlags); + EnBgCheckWall(); + WaterCheck(mPos, 1.0f); + + mAngle.y += l_turn_angleY_add[mDirection]; + int angleY = l_base_angleY[mDirection]; + + int abs1 = abs(angleY); + int abs2 = abs(mAngle.y); + if (abs2 >= abs1) { + mAngle.y = angleY; + changeState(StateID_Walk); + } +} + +void daEnBomhei_c::initializeState_Sleep() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("stop"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 2.0f); + mAnm.setRate(1.0f); + mFlags &= ~0x10000; + mAngle.y = l_base_angleY[mDirection]; +} + +void daEnBomhei_c::finalizeState_Sleep() {} + +void daEnBomhei_c::executeState_Sleep() { + mModel.play(); + calcSpeedY(); + posMove(); + EnBgCheckFoot(); + if (mBc.isFoot()) { + Bound(0.1875f, 0.5f, 0.5f); + } + mBc.checkHead(0); + EnBgCheckWall(); + if (mBc.mFlags & 0x3c000000) { + if (mSpeed.y > 0.0f) { + mSpeed.y = -0.85f * mSpeed.y; + } + } + if (mBc.mFlags & 0x3f) { + mSpeed.x = 0.0f; + } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + mTimer--; + if (mTimer <= 0) { + changeState(StateID_Explode); + } +} + +void daEnBomhei_c::initializeState_Carry() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("carry"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 2.0f); + mAnm.setRate(1.0f); + mPlayerNo = m_624; + dAcPy_c *player = daPyMng_c::getPlayer(m_624); + if (player->mAmiLayer == 1) { + mAmiLayer = 0; + } else { + mAmiLayer = 1; + } + + float x, y, width, height; + x = mCc.mCcData.mBase.mOffset.x; + y = mCc.mCcData.mBase.mOffset.y; + width = mCc.mCcData.mBase.mSize.x; + height = mCc.mCcData.mBase.mSize.y; + mCcOffsetX = x; + mCcOffsetY = y; + mCcWidth = width; + mCcHeight = height; + mCc.mAmiLine = l_Ami_Line[mAmiLayer]; + mBc.mAmiLine = l_Ami_Line[mAmiLayer]; + mCc.mCcData.mVsKind |= BIT_FLAG(CC_KIND_KILLER) | BIT_FLAG(CC_KIND_BALLOON); + mCc.mCcData.mAttack = CC_ATTACK_SHELL; + mRc.setRide(nullptr); + mActorProperties &= ~0x2; +} + +void daEnBomhei_c::finalizeState_Carry() { + dAcPy_c *player = daPyMng_c::getPlayer(m_624); + player->cancelCarry(this); + mCc.mCcData.mVsKind &= ~BIT_FLAG(CC_KIND_KILLER); + mCc.mCcData.mAttack = CC_ATTACK_NONE; + mCc.mCcData.mBase.mOffset.set(mCcOffsetX, mCcOffsetY); + mCc.mCcData.mBase.mSize.set(mCcWidth, mCcHeight); + mRc.setRide(nullptr); + mBc.mFlags = 0; + mCarryingFlags &= ~(CARRY_RELEASE | CARRY_THROW); + mActorProperties |= 0x2; + mAngle.y = l_base_angleY[mDirection]; +} + +void daEnBomhei_c::executeState_Carry() { + dAcPy_c *player = daPyMng_c::getPlayer(m_624); + mModel.play(); + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + mTimer--; + if (mTimer <= 0) { + mDirection = player->mDirection; + if (checkWallAndBg()) { + setDeathInfo_Carry(player); + } else { + changeState(StateID_Explode); + } + } else if (mCarryingFlags & CARRY_RELEASE) { + mDirection = mThrowDirection; + mAngle.y = l_base_angleY[mDirection]; + if (checkWallAndBg()) { + setDeathInfo_Carry(player); + return; + } + if ((mBc.mFlags & 0x15 << mDirection) == 0) { + mPos.x += l_EnMuki[mDirection] * 6.0f; + } + if (mCarryingFlags & CARRY_THROW) { + changeState(StateID_Slide); + } else { + changeState(StateID_Sleep); + } + } else { + mAngle.y = player->mAngle.y; + WaterCheck(mPos, 1.0f); + } + updateCarryCc(); +} + +void daEnBomhei_c::initializeState_Slide() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("stop"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 2.0f); + mAnm.setRate(1.0f); + + static const float dirSpeed[] = { smc_SLIDE_SPEED_X, -smc_SLIDE_SPEED_X }; + clrComboCnt(); + mAccelF = 0.0625f; + mSpeed.x = dirSpeed[mDirection]; + mSpeedMax.x = 0.0f; + mAngle.y = l_base_angleY[mDirection]; + mNoHitPlayer.mTimer[mPlayerNo] = 10; + mCc.mCcData.mAttack = CC_ATTACK_SHELL; + bcSet1(); +} + +void daEnBomhei_c::finalizeState_Slide() { + clrComboCnt(); + mAccelF = 0.0f; + mSpeedMax.x = 0.0f; + bcSet2(); + mCc.mCcData.mAttack = CC_ATTACK_NONE; +} + +void daEnBomhei_c::executeState_Slide() { + mModel.play(); + calcSpeedX(); + calcSpeedY(); + posMove(); + u32 bcFlags = EnBgCheckFoot(); + if (mBc.isFoot()) { + Bound(0.1875f, 1.0f, 0.5f); + if (std::fabs(mSpeed.x) > 0.2f) { + mVec3_c efPos(mPos.x, mPos.y, 5500.0f); + mEf::createEffect("Wm_en_landsmoke_s", 0, &efPos, nullptr, nullptr); + } + } + mBc.checkHead(bcFlags); + EnBgCheckWall(); + if (mBc.mFlags & 0x15 << mDirection) { + mDirection ^= 1; + mAngle.y = l_base_angleY[mDirection]; + mSpeed.x = -mSpeed.x * smc_WALK_SPEED; + } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + WaterCheck(mPos, 1.0f); + mTimer--; + if (mTimer <= 0) { + changeState(StateID_Explode); + } else if (mSpeed.x == 0.0f) { + changeState(StateID_Sleep); + } +} + +void daEnBomhei_c::initializeState_Kick() { + static const float dirSpeed[] = { smc_KICK_SPEED_X, -smc_KICK_SPEED_X }; + + mSpeed.set(dirSpeed[mDirection], smc_KICK_SPEED_Y, 0.0f); + mAngle.y = l_base_angleY[mDirection]; + clrComboCnt(); + mAccelY = -0.1875f; + mCc.mCcData.mAttack = CC_ATTACK_SHELL; +} + +void daEnBomhei_c::finalizeState_Kick() { + clrComboCnt(); + mCc.mCcData.mAttack = CC_ATTACK_NONE; +} + +void daEnBomhei_c::executeState_Kick() { + calcSpeedY(); + posMove(); + u32 bcFlags = EnBgCheckFoot(); + if (mBc.isFoot()) { + Bound(0.1875f, 0.5f, 0.5f); + } + mBc.checkHead(bcFlags); + EnBgCheckWall(); + if (bcFlags != 0) { + if (std::fabs(mSpeed.x) > 0.2f) { + mVec3_c efPos(mPos.x, mPos.y, 5500.0f); + mEf::createEffect("Wm_en_landsmoke_s", 0, &efPos, nullptr, nullptr); + } + } + if (mBc.mFlags & 0x3c000000) { + if (mSpeed.y > 0.0f) { + mSpeed.y = -0.85f * mSpeed.y; + } + } + if (mBc.mFlags & 0x15 << mDirection) { + mDirection = mDirection ^ 1; + mAngle.y = l_base_angleY[mDirection]; + mSpeed.x = -mSpeed.x; + } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + WaterCheck(mPos, 1.0f); + mTimer--; + if (mTimer <= 0) { + changeState(StateID_Explode); + } else if (mSpeed.x == 0.0f) { + changeState(StateID_Sleep); + } +} + +void daEnBomhei_c::initializeState_KickBom() { + static const float dirSpeed[] = { smc_KICK_SPEED_X, -smc_KICK_SPEED_X }; + + mSpeed.set(dirSpeed[mDirection], 2.0f, 0.0f); + mAngle.y = l_base_angleY[mDirection]; + clrComboCnt(); + mAccelY = -0.1875f; + mCc.mCcData.mAttack = CC_ATTACK_SHELL; + m_23b = 1; +} + +void daEnBomhei_c::finalizeState_KickBom() { + clrComboCnt(); + mCc.mCcData.mAttack = CC_ATTACK_NONE; +} + +void daEnBomhei_c::executeState_KickBom() { + calcSpeedY(); + posMove(); + u32 bcFlags = EnBgCheckFoot(); + mBc.checkHead(bcFlags); + EnBgCheckWall(); + if (mBc.mFlags & 0x15 << mDirection) { + mDirection = mDirection ^ 1; + mAngle.y = l_base_angleY[mDirection]; + mSpeed.x = -mSpeed.x; + } + WaterCheck(mPos, 1.0f); + switch (m_23b) { + case 1: + if (bcFlags != 0) { + mSpeed.y = 1.0f; + m_23b = 2; + } + break; + case 2: + if (bcFlags != 0) { + changeState(StateID_Explode); + } + break; + } +} + +void daEnBomhei_c::initializeState_Wakidashi() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("walk"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 2.0f); + mAnm.setRate(2.0f); + + u8 wakidashiSetting = ACTOR_PARAM(wakidashiConfig); + if (wakidashiSetting & 2) { + mDirection = (wakidashiSetting & 1) ^ 1; + } else { + mDirection = getPl_LRflag(mPos); + } + + static const float speedX[] = { 0.0f, 0.0f, -smc_WALK_SPEED, smc_WALK_SPEED }; + static const float speedY[] = { smc_WALK_SPEED, -smc_WALK_SPEED, 0.0f, 0.0f }; + + mAngle.y = l_base_angleY[mDirection]; + mSpeed.set(speedX[wakidashiSetting], speedY[wakidashiSetting], 0.0f); + mFlags |= 0x10000; + m_5f4 = 0x20; + mCc.mCcData.mVsKind &= ~BIT_FLAG(CC_KIND_ENEMY); + mCc.mCcData.mVsDamage &= ~BIT_FLAG(CC_ATTACK_FIREBALL); +} + +void daEnBomhei_c::finalizeState_Wakidashi() { + mCc.mCcData.mVsKind |= BIT_FLAG(CC_KIND_ENEMY); + mPos.z = 1500.0f; + mCc.mCcData.mVsDamage |= BIT_FLAG(CC_ATTACK_FIREBALL); +} + +void daEnBomhei_c::executeState_Wakidashi() { + mModel.play(); + dBaseActor_c::posMove(); + m_5f4--; + if (m_5f4 == 0) { + changeState(StateID_Walk); + } +} + +void daEnBomhei_c::initializeState_CannonHop_Upper() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("walk"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 0.0f); + mAnm.setRate(2.0f); + + static const float speedX[2][2] = { + {1.5f, -1.5f}, + {1.3f, -1.3f} + }; + static const float speedY[] = { 2.25f, 4.5f }; + + mAccelY = -0.1875f; + mSpeed.set( + speedX[ACTOR_PARAM(CannonHopDir)][mDirection], + speedY[ACTOR_PARAM(CannonHopDir)], + 0.0f + ); + mBc.set(this, l_bomhei_8, l_bomhei_7, l_bomhei_9); + m_5fc = 8; + m_23b = 1; +} + +void daEnBomhei_c::finalizeState_CannonHop_Upper() { + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); +} + +void daEnBomhei_c::executeState_CannonHop_Upper() { + mModel.play(); + calcSpeedY(); + posMove(); + switch (m_23b) { + case 1: + mBc.checkWall(nullptr); + mBc.checkHead(0); + m_5fc--; + if (m_5fc <= 0) { + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); + m_23b = 2; + } + break; + case 2: + if (mBc.checkFootEnm()) { + mAnm.setRate(1.0f); + changeState(StateID_Walk); + } else if (mBc.checkWall(nullptr)) { + mSpeed.x = -mSpeed.x; + changeState(StateID_Turn); + } + break; + } +} + +void daEnBomhei_c::initializeState_CannonHop_Under() { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("walk"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 0.0f); + mAnm.setRate(1.0f); + mAnm.setRate(2.0f); + + static const float speedX[] = { 1.25f, -1.25f }; + + mAccelY = -0.1875f; + mSpeed.set(speedX[mDirection], -0.75f, 0.0f); + m_5fc = 8; + mBc.set(this, l_bomhei_8, l_bomhei_7, l_bomhei_9); + m_23b = 1; +} + +void daEnBomhei_c::finalizeState_CannonHop_Under() { + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); +} + +void daEnBomhei_c::executeState_CannonHop_Under() { + mModel.play(); + calcSpeedY(); + posMove(); + switch (m_23b) { + case 1: + mBc.checkWall(nullptr); + mBc.checkHead(0); + m_5fc--; + if (m_5fc <= 0) { + mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); + m_23b = 2; + } + break; + case 2: + if (mBc.checkFootEnm()) { + mAnm.setRate(1.0f); + changeState(StateID_Walk); + } else if (mBc.checkWall(nullptr)) { + mSpeed.x = -mSpeed.x; + changeState(StateID_Turn); + } + break; + } +} + +void daEnBomhei_c::initializeState_AfterIce() { + mAnmMat.setFrame(0.0f, 0); + m_23b = 1; +} + +void daEnBomhei_c::finalizeState_AfterIce() {} + +void daEnBomhei_c::executeState_AfterIce() { + calcSpeedY(); + posMove(); + if (mBc.checkWall(nullptr)) { + mSpeed.x = -mSpeed.x; + } + switch (m_23b) { + case 1: + if (mBc.checkFootEnm()) { + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("walk"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 5.0f); + mAnm.setRate(1.0f); + mSpeed.set(0.0f, 0.0f, 0.0f); + mDirection = getPl_LRflag(mPos); + m_23b = 2; + } + break; + case 2: + mModel.play(); + if (mBc.checkFootEnm()) { + mSpeed.y = 0.0f; + } + if (mAngle.y.chaseAngle(l_base_angleY[mDirection], 0x400)) { + changeState(StateID_Walk); + } + break; + } +} + +void daEnBomhei_c::initializeState_EatOut() { + dEn_c::initializeState_EatOut(); + nw4r::g3d::ResAnmChr anm = mFile.GetResAnmChr("stop"); + mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); + mModel.setAnm(mAnm, 0.0f); + mAnm.setRate(1.0f); +} + +void daEnBomhei_c::finalizeState_EatOut() { + dEn_c::finalizeState_EatOut(); +} + +void daEnBomhei_c::executeState_EatOut() { + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + mTimer--; + if (mTimer <= 0) { + changeState(StateID_Explode); + } else { + dEn_c::executeState_EatOut(); + } +} + +void daEnBomhei_c::initializeState_Explode() { + explosionEffect(); + breakEffect(); + dAudio::SoundEffectID_t(SE_EMY_BH_BOMB).playEmySound(mPos, 0); + mCc.mCcData.mBase.mOffset.x = 0.0f; + mCc.mCcData.mBase.mOffset.y = 0.0f; + mCc.mCcData.mBase.mSize.x = 18.0f; + mCc.mCcData.mBase.mSize.y = 18.0f; + mCc.mCcData.mAttack = CC_ATTACK_SHELL; + mCc.mCcData.mVsKind |= BIT_FLAG(CC_KIND_PLAYER) | BIT_FLAG(CC_KIND_PLAYER_ATTACK) | BIT_FLAG(CC_KIND_YOSHI) | + BIT_FLAG(CC_KIND_ENEMY) | BIT_FLAG(CC_KIND_TAMA) | BIT_FLAG(CC_KIND_KILLER); + mCc.mCcData.mVsDamage = 0; + mCc.mCcData.mStatus |= CC_STATUS_NO_REVISION; + mCc.mCcData.mCallback = explosionCallback; + mTimer = 0; + mAngle.y = l_base_angleY[mDirection]; + mPos.y += 8.0f; + checkBombBreak(); +} + +void daEnBomhei_c::finalizeState_Explode() {} + +void daEnBomhei_c::executeState_Explode() { + m_5f0++; + if (m_5f0 < 9) { + someBgCheck(); + } else if (m_5f0 == 16) { + deleteActor(true); + } +} + +void daEnBomhei_c::initializeState_InIceLump() { + mAngle.x = dGameCom::rndInt(9) * 0x1000 - 0x4000; + mAngle.y = dGameCom::rndInt(9) * 0x1000 - 0x4000; + mAngle.z = dGameCom::rndInt(9) * 0x1000 - 0x4000; + mCc.release(); +} + +void daEnBomhei_c::finalizeState_InIceLump() {} + +void daEnBomhei_c::executeState_InIceLump() {} + +const int daEnBomhei_c::smc_SOUND_EFFECTS[] = { + SE_EMY_YOSHI_HPDP, + SE_EMY_DOWN, + SE_EMY_KAME_KERU, + SE_EMY_BH_HIBANA, + SE_EMY_BH_BOMB +}; diff --git a/source/dol/bases/d_last_actor.cpp b/source/dol/bases/d_last_actor.cpp index aef85198..647a2ce9 100644 --- a/source/dol/bases/d_last_actor.cpp +++ b/source/dol/bases/d_last_actor.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include BASE_PROFILE(LASTACTOR, dLastActor_c); diff --git a/syms.txt b/syms.txt index 62c168ef..a7d64331 100644 --- a/syms.txt +++ b/syms.txt @@ -32,6 +32,7 @@ getType__Q23m3d8anmChr_cCFv=0x8002A210 getStarCount__10daPlBase_cCFv=0x8002D970 refreshState__99sStateStateMgr_c<18dActorMultiState_c,12sFStateMgr_c,20sStateMethodUsr_FI_c,20sStateMethodUsr_FI_c>Fv=0x80034700 getStateID__82sStateMgr_c<13dActorState_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv=0x80040BC0 +kill__17daFireBall_Base_cFv=0x80040EC0 __dt__18dCircleLightMask_cFv=0x800414A0 setDemoMode__13daPyDemoMng_cFQ213daPyDemoMng_c6Mode_ei=0x8005B5C0 setGoalDemoList__13daPyDemoMng_cFi=0x8005B780 @@ -150,6 +151,8 @@ checkTenjou__5dBc_cFPC7mVec3_cPfUcUc=0x80075CA0 checkWall__5dBc_cFPC7mVec3_cPC7mVec3_cPfUcUcPP8dActor_c=0x80075FD0 checkWaterDepth__5dBc_cFffUcUcPf=0x80076530 checkWireNet__5dBc_cFffUc=0x800767F0 +checkBombBreak__5dBc_cF7mVec2_c7mVec2_c=0x800768D0 +BgUnitChange__5dBg_cFUsUsiUs=0x80077860 setWaterInWave__5dBg_cFffUc=0x80078410 getLeftLimit__5dBg_cFv=0x80078A70 getRightLimit__5dBg_cFv=0x80078C10 @@ -435,6 +438,16 @@ fade__Q23mEf13levelEffect_cFv=0x8016D6B0 kill__Q23mEf13levelEffect_cFv=0x8016D6C0 follow__Q23mEf13levelEffect_cFPC7mVec3_cPC7mAng3_cPC7mVec3_c=0x8016D6D0 follow__Q23mEf13levelEffect_cFPC6mMtx_c=0x8016D720 +setCurrentHeap__5mHeapFPQ23EGG4Heap=0x8016E630 +createExpHeap__5mHeapFUlPQ23EGG4HeapPCcUlQ25mHeap13AllocOptBit_t=0x8016E640 +createFrmHeap__5mHeapFUlPQ23EGG4HeapPCcUlQ25mHeap13AllocOptBit_t=0x8016E770 +destroyFrmHeap__5mHeapFPQ23EGG7FrmHeap=0x8016E880 +adjustFrmHeap__5mHeapFPQ23EGG7FrmHeap=0x8016E8A0 +frmHeapCost__5mHeapFUlUl=0x8016E910 +saveCurrentHeap__4mHeapFv=0x8016EAB0 +saveCurrentHeap__5mHeapFv=0x8016EAB0 +restoreCurrentHeap__5mHeapFv=0x8016EAC0 +createFrmHeapToCurrent__5mHeapFUlPQ23EGG4HeapPCcUlQ25mHeap13AllocOptBit_t=0x8016EAF0 create__4mPadFv=0x8016F330 beginPad__4mPadFv=0x8016F360 endPad__4mPadFv=0x8016F550 @@ -448,6 +461,7 @@ __dt__15NMSndObjectBaseFv=0x801974C0 sendRemote__15NMSndObjectBaseFPQ34nw4r3snd11SoundHandleUlUl=0x80197540 vf1C__15NMSndObjectBaseFUli=0x801976B0 startSound__14SndObjctCmnEmyFUlRCQ34nw4r4math4VEC2Ul=0x80198040 +holdSound__14SndObjctCmnEmyFUliRCQ34nw4r4math4VEC2Ul=0x801987A0 startSound__14SndObjctCmnMapFUlRCQ34nw4r4math4VEC2Ul=0x80198D70 startSound__11SndObjctPlyFUlUl=0x8019A0F0 holdSound__11SndObjctPlyFUlUl=0x8019A1E0 @@ -561,6 +575,7 @@ SinFIdx__Q24nw4r4mathFf=0x80237D10 CosFIdx__Q24nw4r4mathFf=0x80237D80 GetResMdl__Q34nw4r3g3d7ResFileCFPCc=0x80239F70 GetResAnmChr__Q34nw4r3g3d7ResFileCFPCc=0x8023A1F0 +GetResAnmClr__Q34nw4r3g3d7ResFileCFPCc=0x8023A2D0 GetResAnmTexPat__Q34nw4r3g3d7ResFileCFPCc=0x8023A340 GetResAnmTexSrt__Q34nw4r3g3d7ResFileCFPCc=0x8023A3B0 Bind__Q34nw4r3g3d7ResFileFQ34nw4r3g3d7ResFile=0x8023A490 From 68d933bd7558e92e8265036c53a5ba5d2bbb7ce7 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Fri, 28 Nov 2025 13:35:38 +0100 Subject: [PATCH 2/2] Cleanup `daEnBomhei_c` --- include/game/bases/d_a_en_bomhei.hpp | 111 +++--- include/game/bases/d_cc.hpp | 5 +- include/game/bases/d_en_boyo_manager.hpp | 1 - include/game/bases/d_enemy.hpp | 1 + include/game/bases/d_enemy_manager.hpp | 2 +- source/d_enemiesNP/bases/d_a_en_bomhei.cpp | 433 ++++++++++++--------- source/dol/bases/d_a_en_shell.cpp | 4 +- source/dol/bases/d_enemy_death.cpp | 4 +- 8 files changed, 309 insertions(+), 252 deletions(-) diff --git a/include/game/bases/d_a_en_bomhei.hpp b/include/game/bases/d_a_en_bomhei.hpp index 4f53eb8e..a26ad367 100644 --- a/include/game/bases/d_a_en_bomhei.hpp +++ b/include/game/bases/d_a_en_bomhei.hpp @@ -7,16 +7,21 @@ #include #include +/// @brief A bob-omb enemy. +/// @statetable +/// @paramtable +/// @ingroup bases class daEnBomhei_c : public daEnCarry_c { public: + /// @brief The different modes for spawning a bob-omb. enum SpawnMode_e { - SPAWN_MODE_NORMAL, - SPAWN_MODE_WAKIDASHI, - SPAWN_MODE_ICE_LUMP, - SPAWN_MODE_CANNON, + SPAWN_MODE_NORMAL, ///< Start walking immediately. + SPAWN_MODE_WAKIDASHI, ///< Walk out of a pipe. + SPAWN_MODE_ICE_LUMP, ///< Stuck in a large ice block. + SPAWN_MODE_CANNON_HOP ///< Shoot out of a cannon. }; - daEnBomhei_c() : mTimer(-1), m_5f0(-1), m_620(3) {} + daEnBomhei_c() : mExplodeWaitTimer(-1), mExplodeTimer(-1), mFireCoinCount(smc_FireCountCount) {} virtual ~daEnBomhei_c() {} virtual int create(); @@ -28,42 +33,42 @@ class daEnBomhei_c : public daEnCarry_c { virtual void finalUpdate(); virtual bool ActorDrawCullCheck(); virtual void setSpinLiftUpActor(dActor_c *carryingActor); - virtual void Normal_VsEnHitCheck(dCc_c *cc1, dCc_c *cc2); - virtual void Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2); - virtual void Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2); + virtual void Normal_VsEnHitCheck(dCc_c *self, dCc_c *other); + virtual void Normal_VsPlHitCheck(dCc_c *self, dCc_c *other); + virtual void Normal_VsYoshiHitCheck(dCc_c *self, dCc_c *other); virtual void block_hit_init(); - virtual bool hitCallback_Shell(dCc_c *cc1, dCc_c *cc2); - virtual bool hitCallback_Fire(dCc_c *cc1, dCc_c *cc2); - virtual bool hitCallback_Ice(dCc_c *cc1, dCc_c *cc2); + virtual bool hitCallback_Shell(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Fire(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Ice(dCc_c *self, dCc_c *other); virtual void returnState_Ice(); - virtual bool hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2); - virtual bool hitCallback_YoshiHipAttk(dCc_c *cc1, dCc_c *cc2); - virtual bool hitCallback_Spin(dCc_c *cc1, dCc_c *cc2) { return hitCallback_HipAttk(cc1, cc2); } + virtual bool hitCallback_HipAttk(dCc_c *self, dCc_c *other); + virtual bool hitCallback_YoshiHipAttk(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Spin(dCc_c *self, dCc_c *other) { return hitCallback_HipAttk(self, other); } virtual bool createIceActor(); - virtual bool EtcDamageCheck(dCc_c *cc1, dCc_c *cc2); + virtual bool EtcDamageCheck(dCc_c *self, dCc_c *other); virtual void boyonBegin() {} virtual bool isSpinLiftUpEnable() { return isState(StateID_Sleep); } - STATE_FUNC_DECLARE(daEnBomhei_c, Walk); - STATE_FUNC_DECLARE(daEnBomhei_c, Sleep); - STATE_VIRTUAL_FUNC_DECLARE(daEnBomhei_c, Carry); - STATE_FUNC_DECLARE(daEnBomhei_c, Slide); - STATE_FUNC_DECLARE(daEnBomhei_c, Kick); + STATE_FUNC_DECLARE(daEnBomhei_c, Walk); ///< Walking on the ground. + STATE_FUNC_DECLARE(daEnBomhei_c, Sleep); ///< Sleeping, waiting to explode. + STATE_VIRTUAL_FUNC_DECLARE(daEnBomhei_c, Carry); ///< Being carried by a player. + STATE_FUNC_DECLARE(daEnBomhei_c, Slide); ///< Sliding along the ground after a ground pound. + STATE_FUNC_DECLARE(daEnBomhei_c, Kick); ///< Being kicked by the player. STATE_FUNC_DECLARE(daEnBomhei_c, KickBom); - STATE_FUNC_DECLARE(daEnBomhei_c, Wakidashi); - STATE_FUNC_DECLARE(daEnBomhei_c, Explode); - STATE_FUNC_DECLARE(daEnBomhei_c, Turn); - STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Upper); - STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Under); + STATE_FUNC_DECLARE(daEnBomhei_c, Wakidashi); ///< Moving out of a pipe. + STATE_FUNC_DECLARE(daEnBomhei_c, Explode); ///< Exploding after the timer runs out. + STATE_FUNC_DECLARE(daEnBomhei_c, Turn); ///< Turning around + STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Upper); ///< Being shot upwards out of a cannon. + STATE_FUNC_DECLARE(daEnBomhei_c, CannonHop_Under); ///< Being shot downwards out of a cannon. STATE_FUNC_DECLARE(daEnBomhei_c, AfterIce); - STATE_FUNC_DECLARE(daEnBomhei_c, InIceLump); + STATE_FUNC_DECLARE(daEnBomhei_c, InIceLump); ///< Stuck in a large ice block. STATE_VIRTUAL_FUNC_DECLARE(daEnBomhei_c, EatOut); virtual void vf28c(); - virtual void vf290(); - virtual void vf294(); - virtual void vf298(); + virtual void modelUpdate(); + virtual void postMdlSetup(); + virtual void initialStateSet(); virtual void vf29c() {} void mdlSetup(); @@ -72,46 +77,48 @@ class daEnBomhei_c : public daEnCarry_c { void bcSet2(); void setDeathInfo_Carry(dActor_c *killedBy); void checkBombBreak(); - void someBgCheck(); - mVec2_c getSomePos(); + void explodeBgUnit(); + mVec2_c getExplodeTilePos(); void calcIgnitionPos(); void updateCarryCc(); void breakEffect() { mEf::createEffect("Wm_en_bombheibreak", 0, &mIgnitionPos, nullptr, nullptr); } void explosionEffect() { mEf::createEffect("Wm_en_explosion", 0, &mIgnitionPos, nullptr, nullptr); } - ACTOR_PARAM_CONFIG(wakidashiConfig, 0, 2); - ACTOR_PARAM_CONFIG(unk2, 4, 2); - ACTOR_PARAM_CONFIG(CannonHopDir, 6, 1); - ACTOR_PARAM_CONFIG(zLayer, 24, 4); - ACTOR_PARAM_CONFIG(spawnMode, 28, 2); - dHeapAllocator_c mAllocator; nw4r::g3d::ResFile mFile; m3d::mdl_c mModel; m3d::anmChr_c mAnm; m3d::anmMatClr_c mAnmMat; - int mTimer; - int m_5f0; - int m_5f4; - int m_5f8; - int m_5fc; + int mExplodeWaitTimer; ///< Timer counting down until the bob-omb explodes. + int mExplodeTimer; ///< Timer counting up while exploding. + int mWakidashiTimer; ///< Timer counting down until the bob-omb will beging walking normally. + int mCannonHopDir; + int mCannonHopTimer; u8 mPad[4]; - mVec3_c m_604; + mVec3_c mLiftPos; float mCcOffsetX; float mCcOffsetY; float mCcWidth; float mCcHeight; - int m_620; - int m_624; - int m_628; + int mFireCoinCount; ///< How many more coins can be spawned by hitting the bob-omb with a fireball. + int mCarryingPlayer; + int mUnkTimer; mVec3_c mIgnitionPos; mEf::levelEffect_c mEffect; - static const float smc_WALK_SPEED; - static const float smc_SLIDE_SPEED_X; - static const float smc_KICK_SPEED_X; - static const float smc_KICK_SPEED_Y; - static const int smc_5EC_VALUE; - static const int smc_SOUND_EFFECTS[]; + ACTOR_PARAM_CONFIG(WakidashiSpawnDir, 0, 2); ///< The direction to move out of the pipe. + ACTOR_PARAM_CONFIG(CannonHopSpawnDir, 4, 2); ///< The direction to shoot out of the cannon. + ACTOR_PARAM_CONFIG(CannonHopType, 6, 1); ///< The trajectory to shoot out of the cannon. 0 is a flat arc, 1 is a high arc. + ACTOR_PARAM_CONFIG(ZLayer, 24, 4); ///< The Z layer to place the bob-omb on. + ACTOR_PARAM_CONFIG(SpawnMode, 28, 2); ///< See SpawnMode_e. + + static const float smc_WalkSpeed; + static const float smc_SlideSpeedX; + static const float smc_KickSpeedX; + static const float smc_KickSpeedY; + static const int smc_ExplodeWaitFrames; + static const int smc_SoundEffectIDs[]; + + static const int smc_FireCountCount = 3; }; diff --git a/include/game/bases/d_cc.hpp b/include/game/bases/d_cc.hpp index 002e9ef7..82dc4f76 100644 --- a/include/game/bases/d_cc.hpp +++ b/include/game/bases/d_cc.hpp @@ -23,6 +23,7 @@ enum CC_STATUS_FLAG_e { */ CC_STATUS_NO_PASS_INFO = BIT_FLAG(2), CC_STATUS_8 = BIT_FLAG(8), + CC_STATUS_9 = BIT_FLAG(9), }; ///< @unofficial @@ -44,8 +45,8 @@ enum CC_KIND_e { CC_KIND_ITEM, CC_KIND_TAMA, CC_KIND_KILLER, - CC_KIND_GOAL_POLE, - CC_KIND_COUNT = CC_KIND_GOAL_POLE // Goal pole is special and doesn't count + CC_KIND_COUNT, + CC_KIND_GOAL_POLE = CC_KIND_COUNT ///< [Unsure why this goes above the count] }; ///< @unofficial diff --git a/include/game/bases/d_en_boyo_manager.hpp b/include/game/bases/d_en_boyo_manager.hpp index 83ab1695..20f48aa6 100644 --- a/include/game/bases/d_en_boyo_manager.hpp +++ b/include/game/bases/d_en_boyo_manager.hpp @@ -21,7 +21,6 @@ class dEnBoyoMng_c { float mFactorDelta; int mCounter; dActor_c *mpOwner; - u8 mDirection; static float smc_DELTA_SCALE; static int smc_BOYON_TIME; diff --git a/include/game/bases/d_enemy.hpp b/include/game/bases/d_enemy.hpp index fdb30668..bc63b10c 100644 --- a/include/game/bases/d_enemy.hpp +++ b/include/game/bases/d_enemy.hpp @@ -282,6 +282,7 @@ class dEn_c : public dActorMultiState_c { bool mFootAttr1; u8 mPad3[5]; dEnBoyoMng_c mBoyoMng; + u8 mIceDirection; dIceMng_c mIceMng; ///< The ice manager for this enemy. float mAirAccelY; ///< The Y acceleration before entering a liquid. float mAirSpeedMaxY; ///< The maximum Y speed before entering a liquid. diff --git a/include/game/bases/d_enemy_manager.hpp b/include/game/bases/d_enemy_manager.hpp index 6a23ac6c..9da5587a 100644 --- a/include/game/bases/d_enemy_manager.hpp +++ b/include/game/bases/d_enemy_manager.hpp @@ -13,7 +13,7 @@ class dEnemyMng_c { u8 mPad1[0x138]; int m_138; u8 mPad2[0x10]; - int m_14c; + int mBomheiCount; u8 mPad3[0x4]; int m_154; u8 mPad4[0x4]; diff --git a/source/d_enemiesNP/bases/d_a_en_bomhei.cpp b/source/d_enemiesNP/bases/d_a_en_bomhei.cpp index 124a31ea..bc0e523e 100644 --- a/source/d_enemiesNP/bases/d_a_en_bomhei.cpp +++ b/source/d_enemiesNP/bases/d_a_en_bomhei.cpp @@ -28,11 +28,11 @@ STATE_DEFINE(daEnBomhei_c, AfterIce); STATE_DEFINE(daEnBomhei_c, InIceLump); STATE_VIRTUAL_DEFINE(daEnBomhei_c, EatOut); -const float daEnBomhei_c::smc_WALK_SPEED = 0.5f; -const float daEnBomhei_c::smc_SLIDE_SPEED_X = 4.0f; -const float daEnBomhei_c::smc_KICK_SPEED_X = 2.5f; -const float daEnBomhei_c::smc_KICK_SPEED_Y = 2.0f; -const int daEnBomhei_c::smc_5EC_VALUE = 240; +const float daEnBomhei_c::smc_WalkSpeed = 0.5f; +const float daEnBomhei_c::smc_SlideSpeedX = 4.0f; +const float daEnBomhei_c::smc_KickSpeedX = 2.5f; +const float daEnBomhei_c::smc_KickSpeedY = 2.0f; +const int daEnBomhei_c::smc_ExplodeWaitFrames = 240; const sBcSensorPoint l_bomhei_head = { SENSOR_IS_POINT, 0x0, 0x10000 }; const sBcSensorLine l_bomhei_foot = { SENSOR_IS_LINE, -0x3000, 0x3000, 0 }; @@ -57,7 +57,7 @@ const sCcDatNewF l_bomhei_cc = { CC_KIND_ENEMY, CC_ATTACK_NONE, BIT_FLAG(CC_KIND_PLAYER) | BIT_FLAG(CC_KIND_PLAYER_ATTACK) | BIT_FLAG(CC_KIND_YOSHI) | - BIT_FLAG(CC_KIND_ITEM) | BIT_FLAG(CC_KIND_ENEMY) | BIT_FLAG(CC_KIND_TAMA), + BIT_FLAG(CC_KIND_ENEMY) | BIT_FLAG(CC_KIND_ITEM) | BIT_FLAG(CC_KIND_TAMA), (u32) ~BIT_FLAG(CC_ATTACK_NONE) & ~BIT_FLAG(CC_ATTACK_YOSHI_MOUTH) & ~BIT_FLAG(CC_ATTACK_SAND_PILLAR), CC_STATUS_NONE, dEn_c::normal_collcheck, @@ -81,27 +81,29 @@ int daEnBomhei_c::create() { mEatBehavior = EAT_TYPE_DRINK; mFlags = EN_IS_HARD; - if (ACTOR_PARAM(spawnMode) != SPAWN_MODE_ICE_LUMP) { - dEnemyMng_c::m_instance->m_14c++; + if (ACTOR_PARAM(SpawnMode) != SPAWN_MODE_ICE_LUMP) { + dEnemyMng_c::m_instance->mBomheiCount++; } - vf298(); + initialStateSet(); return SUCCEEDED; } -void daEnBomhei_c::vf298() { - if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_WAKIDASHI) { +void daEnBomhei_c::initialStateSet() { + if (ACTOR_PARAM(SpawnMode) == SPAWN_MODE_WAKIDASHI) { changeState(StateID_Wakidashi); - } else if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_ICE_LUMP) { + } else if (ACTOR_PARAM(SpawnMode) == SPAWN_MODE_ICE_LUMP) { changeState(StateID_InIceLump); - } else if (ACTOR_PARAM(spawnMode) == SPAWN_MODE_CANNON) { - int unk2 = ACTOR_PARAM(unk2); - m_5f8 = unk2; - mDirection = unk2 & 1; + } else if (ACTOR_PARAM(SpawnMode) == SPAWN_MODE_CANNON_HOP) { + int spawnDir = ACTOR_PARAM(CannonHopSpawnDir); + mCannonHopDir = spawnDir; + mDirection = spawnDir & 1; mAngle.y = l_base_angleY[mDirection]; - if (unk2 == 0 || unk2 == 1) { + if (spawnDir == 0 || spawnDir == 1) { + // up-right or up-left changeState(StateID_CannonHop_Upper); } else { + // down-right or down-left changeState(StateID_CannonHop_Under); } } else { @@ -129,22 +131,22 @@ void daEnBomhei_c::mdlSetup() { mAnmMat.setPlayMode(m3d::FORWARD_ONCE, 0); mAnmMat.setFrame(0.0f, 0); - vf294(); + postMdlSetup(); mAllocator.adjustFrmHeap(); } -void daEnBomhei_c::vf294() {} +void daEnBomhei_c::postMdlSetup() {} int daEnBomhei_c::execute() { mStateMgr.executeState(); if (!isState(StateID_InIceLump)) { if (!isState(StateID_Ice)) { - if (mTimer > 0) { + if (mExplodeWaitTimer > 0) { mAnmMat.play(); dAudio::SoundEffectID_t(SE_EMY_BH_HIBANA).holdEmySound(mUniqueID, mPos, 0); } - if (m_628 > 0) { - m_628--; + if (mUnkTimer > 0) { + mUnkTimer--; } if (HasamareBgCheck() || EnLavaCheck(mPos)) { changeState(StateID_Explode); @@ -159,9 +161,11 @@ int daEnBomhei_c::preDraw() { if (dEn_c::preDraw() == NOT_READY) { return NOT_READY; } + if (isState(StateID_Explode)) { return NOT_READY; } + return SUCCEEDED; } @@ -170,14 +174,15 @@ int daEnBomhei_c::draw() { return SUCCEEDED; } -void daEnBomhei_c::vf290() { +void daEnBomhei_c::modelUpdate() { mVec3_c pos = mPos; mAng3_c angle = mAngle; if (isState(StateID_Carry)) { - pos = calcCarryPos(m_604); + pos = calcCarryPos(mLiftPos); mPos.x = pos.x; mPos.y = pos.y; } + changePosAngle(&pos, &angle, 1); mMatrix.trans(pos.x, pos.y, pos.z); mMatrix.YrotM(angle.y); @@ -206,17 +211,19 @@ int daEnBomhei_c::doDelete() { player->cancelCarry(this); } } - if (ACTOR_PARAM(spawnMode) != SPAWN_MODE_ICE_LUMP) { - dEnemyMng_c::m_instance->m_14c--; - if (dEnemyMng_c::m_instance->m_14c < 0) { - dEnemyMng_c::m_instance->m_14c = 0; + + if (ACTOR_PARAM(SpawnMode) != SPAWN_MODE_ICE_LUMP) { + dEnemyMng_c::m_instance->mBomheiCount--; + if (dEnemyMng_c::m_instance->mBomheiCount < 0) { + dEnemyMng_c::m_instance->mBomheiCount = 0; } } + return SUCCEEDED; } void daEnBomhei_c::finalUpdate() { - vf290(); + modelUpdate(); } bool daEnBomhei_c::ActorDrawCullCheck() { @@ -236,26 +243,26 @@ void daEnBomhei_c::calcIgnitionPos() { void daEnBomhei_c::updateCarryCc() { bool dir = mAngle.y < 0 ? 1 : 0; - static const float fs[] = { -8.0f, 8.0f }; + static const float sc_carryOffsetX[] = { -8.0f, 8.0f }; - mVec3_c v1( - getCenterPos().x + fs[dir], + mVec3_c centerPos( + getCenterPos().x + sc_carryOffsetX[dir], getCenterPos().y, getCenterPos().z ); mVec3_c v2( - v1.x + l_EnMuki[dir] * 16.0f, - v1.y, - v1.z + centerPos.x + l_EnMuki[dir] * 16.0f, + centerPos.y, + centerPos.z ); mCc.mCcData.mBase.mOffset.set(mCcOffsetX, mCcOffsetY); mCc.mCcData.mBase.mSize.set(mCcWidth, mCcHeight); float f = 0.0f; - if (dBc_c::checkWall(&v1, &v2, &f, mLayer, 1, nullptr)) { - float f1 = (v1.x + f) * 0.5f; - float f2 = (v1.x - f) * 0.5f; + if (dBc_c::checkWall(¢erPos, &v2, &f, mLayer, 1, nullptr)) { + float f1 = (centerPos.x + f) * 0.5f; + float f2 = (centerPos.x - f) * 0.5f; mCc.mCcData.mBase.mOffset.set(f1 - mPos.x, 8.0f); mCc.mCcData.mBase.mSize.set(std::fabs(f2), 8.0f); } @@ -264,22 +271,23 @@ void daEnBomhei_c::updateCarryCc() { void daEnBomhei_c::setSpinLiftUpActor(dActor_c *carryingActor) { int plrNo = carryingActor->getPlrNo(); mPlayerNo = plrNo; - m_624 = plrNo; - m_604.set(0.0f, 0.0f, 0.0f); + mCarryingPlayer = plrNo; + mLiftPos.set(0.0f, 0.0f, 0.0f); changeState(StateID_Carry); } -void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) { - dAcPy_c *other = (dAcPy_c *) cc2->mpOwner; - if (fManager_c::searchBaseByID(other->mCarryActorID) == this) { +void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *self, dCc_c *other) { + dAcPy_c *player = (dAcPy_c *) other->mpOwner; + if (fManager_c::searchBaseByID(player->mCarryActorID) == this) { return; } - u8 newDir = cc1->mCollOffsetX[0] >= 0.0f ? 0 : 1; - u8 plrNo = other->getPlrNo(); + + u8 newDir = self->mCollOffsetX[CC_KIND_PLAYER] >= 0.0f ? 0 : 1; + u8 plrNo = player->getPlrNo(); if (isState(StateID_Sleep)) { - if (carry_check(other)) { - m_624 = plrNo; - m_604.set(0.0f, -5.0f, 6.0f); + if (carry_check(player)) { + mCarryingPlayer = plrNo; + mLiftPos.set(0.0f, -5.0f, 6.0f); changeState(StateID_Carry); } else { mDirection = newDir; @@ -297,10 +305,10 @@ void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) { mBc.mOwningPlrNo = plrNo; changeState(StateID_Kick); } else { - int checkRes = Enfumi_check(cc1, cc2, 0); + int checkRes = Enfumi_check(self, other, 0); if (checkRes == 0) { if (!isState(StateID_Wakidashi) && !isState(StateID_Carry)) { - dEn_c::Normal_VsPlHitCheck(cc1, cc2); + dEn_c::Normal_VsPlHitCheck(self, other); } } else if (checkRes == 1) { mPlayerNo = plrNo; @@ -314,8 +322,8 @@ void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) { mDirection = newDir; mPlayerNo = plrNo; mBc.mOwningPlrNo = plrNo; - if (mTimer < 0) { - mTimer = smc_5EC_VALUE; + if (mExplodeWaitTimer < 0) { + mExplodeWaitTimer = smc_ExplodeWaitFrames; mAnmMat.setFrame(0.0f, 0); } vf29c(); @@ -324,11 +332,12 @@ void daEnBomhei_c::Normal_VsPlHitCheck(dCc_c *cc1, dCc_c *cc2) { } } -void daEnBomhei_c::Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2) { - daYoshi_c *other = (daYoshi_c *) cc2->mpOwner; - u8 newDir = cc1->mCollOffsetX[2] >= 0.0f ? 0 : 1; - u8 plrNo = other->getPlrNo(); - if (Enfumi_check(cc1, cc2, 0) == 0) { +void daEnBomhei_c::Normal_VsYoshiHitCheck(dCc_c *self, dCc_c *other) { + daYoshi_c *yoshi = (daYoshi_c *) other->mpOwner; + u8 newDir = self->mCollOffsetX[CC_KIND_YOSHI] >= 0.0f ? 0 : 1; + u8 plrNo = yoshi->getPlrNo(); + + if (Enfumi_check(self, other, 0) == 0) { if (isState(StateID_Sleep) || isState(StateID_Slide) || isState(StateID_Kick)) { if (plrNo < PLAYER_COUNT) { mDirection = newDir; @@ -339,38 +348,38 @@ void daEnBomhei_c::Normal_VsYoshiHitCheck(dCc_c *cc1, dCc_c *cc2) { changeState(StateID_Kick); } } else { - dEn_c::Normal_VsYoshiHitCheck(cc1, cc2); + dEn_c::Normal_VsYoshiHitCheck(self, other); } } else if (!isState(StateID_Explode)) { - setDeathInfo_YoshiFumi(other); + setDeathInfo_YoshiFumi(yoshi); } } -void daEnBomhei_c::Normal_VsEnHitCheck(dCc_c *cc1, dCc_c *cc2) { - u16 flag = cc2->mCcData.mStatus; - dActor_c *other = cc2->getOwner(); +void daEnBomhei_c::Normal_VsEnHitCheck(dCc_c *self, dCc_c *other) { + u16 flag = other->mCcData.mStatus; + dActor_c *enemy = other->getOwner(); - if (flag & 0x200) { - cc1->mInfo |= CC_NO_HIT; + if (flag & CC_STATUS_9) { + self->mInfo |= CC_NO_HIT; if (!isState(StateID_Explode)) { changeState(StateID_Explode); } - } else if (cc1->mCcData.mAttack == CC_ATTACK_SHELL && (flag & 0x100) && hitCallback_Shell(cc1, cc2)) { - cc2->mInfo |= CC_NO_HIT; - cc1->mInfo |= CC_NO_HIT; + } else if (self->mCcData.mAttack == CC_ATTACK_SHELL && (flag & CC_STATUS_8) && hitCallback_Shell(self, other)) { + other->mInfo |= CC_NO_HIT; + self->mInfo |= CC_NO_HIT; } else if ( - isState(StateID_Carry) && (cc2->mCcData.mVsDamage & BIT_FLAG(CC_ATTACK_SHELL)) && - other->mProfName != fProfile::EN_HATENA_BALLOON && hitCallback_Shell(cc1, cc2) + isState(StateID_Carry) && (other->mCcData.mVsDamage & BIT_FLAG(CC_ATTACK_SHELL)) && + enemy->mProfName != fProfile::EN_HATENA_BALLOON && hitCallback_Shell(self, other) ) { - cc2->mInfo |= CC_NO_HIT; + other->mInfo |= CC_NO_HIT; } else if (isState(StateID_Walk)) { - float offsetX = cc1->mCollOffsetX[3]; + float offsetX = self->mCollOffsetX[CC_KIND_ENEMY]; - if ((mDirection == 1 && offsetX > 0.0f) || (mDirection == 0 && offsetX < 0.0f)) { + if ((mDirection == DIR_LR_L && offsetX > 0.0f) || (mDirection == DIR_LR_R && offsetX < 0.0f)) { changeState(StateID_Turn); } } else { - dEn_c::Normal_VsEnHitCheck(cc1, cc2); + dEn_c::Normal_VsEnHitCheck(self, other); } } @@ -379,51 +388,55 @@ void daEnBomhei_c::vf28c() { float f = l_EnMuki[mDirection ^ 1]; mBc.checkWall(&f); } + mSpeed.set(0.0f, 0.0f, 0.0f); vf29c(); - if (mTimer < 0) { - mTimer = smc_5EC_VALUE; + + if (mExplodeWaitTimer < 0) { + mExplodeWaitTimer = smc_ExplodeWaitFrames; mAnmMat.setFrame(0.0f, 0); changeState(StateID_Sleep); } } void daEnBomhei_c::block_hit_init() { - mVec3_c shiftedPos(mVec2_c(mPos.x, mPos.y), 5500.0f); + mVec3_c efPos(mVec2_c(mPos.x, mPos.y), 5500.0f); - hitdamageEffect(shiftedPos); + hitdamageEffect(efPos); dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); mDirection = mDeathFallDirection; mSpeed.set(l_base_fall_speed_x[mDirection], 3.0f, 0.0f); vf29c(); - if (mTimer < 0) { - mTimer = smc_5EC_VALUE; + + if (mExplodeWaitTimer < 0) { + mExplodeWaitTimer = smc_ExplodeWaitFrames; mAnmMat.setFrame(0.0f, 0); changeState(StateID_Sleep); } } -bool daEnBomhei_c::hitCallback_Shell(dCc_c *cc1, dCc_c *cc2) { - dActor_c *other = cc2->getOwner(); +bool daEnBomhei_c::hitCallback_Shell(dCc_c *self, dCc_c *other) { + dActor_c *shell = other->getOwner(); u8 dir = getTrgToSrcDir_Main( getCenterX(), - other->getCenterX() + shell->getCenterX() ); - int plrNo = acmShellPlayerNo(other); - shellDamageEffect(cc1, other); + int plrNo = acmShellPlayerNo(shell); + shellDamageEffect(self, shell); int comboScore = -1; + if ((u32) plrNo < PLAYER_COUNT) { int shortCombo = 0; if (mCombo.mType == 2) { shortCombo = 1; } - other->slideComboSE(other->mComboMultiplier, shortCombo); - other->mComboMultiplier++; - if (other->mComboMultiplier >= 8) { - other->mComboMultiplier = 8; + shell->slideComboSE(shell->mComboMultiplier, shortCombo); + shell->mComboMultiplier++; + if (shell->mComboMultiplier >= 8) { + shell->mComboMultiplier = 8; } - comboScore = mCombo.getComboScore(other->mComboMultiplier); + comboScore = mCombo.getComboScore(shell->mComboMultiplier); } else { dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); } @@ -443,21 +456,23 @@ bool daEnBomhei_c::hitCallback_Shell(dCc_c *cc1, dCc_c *cc2) { return true; } -bool daEnBomhei_c::hitCallback_Fire(dCc_c *cc1, dCc_c *cc2) { - dActor_c *other = cc2->getOwner(); - u8 dir = !(other->mSpeed.x >= 0.0f); +bool daEnBomhei_c::hitCallback_Fire(dCc_c *self, dCc_c *other) { + dActor_c *fire = other->getOwner(); + u8 dir = !(fire->mSpeed.x >= 0.0f); mDirection = dir; mAngle.y = l_base_angleY[dir]; - mSpeed.x = l_EnMuki[dir] * smc_WALK_SPEED; + mSpeed.x = l_EnMuki[dir] * smc_WalkSpeed; mSpeed.y = 1.5f; mSpeedMax.x = 0.0f; dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); - if (--m_620 >= 0) { + + if (--mFireCoinCount >= 0) { dActorMng_c::m_instance->createUpCoin(getCenterPos(), dir, 1, 0); } vf29c(); - if (mTimer < 0) { - mTimer = smc_5EC_VALUE; + + if (mExplodeWaitTimer < 0) { + mExplodeWaitTimer = smc_ExplodeWaitFrames; mAnmMat.setFrame(0.0f, 0); changeState(StateID_Sleep); } @@ -465,16 +480,16 @@ bool daEnBomhei_c::hitCallback_Fire(dCc_c *cc1, dCc_c *cc2) { return true; } -bool daEnBomhei_c::hitCallback_Ice(dCc_c *cc1, dCc_c *cc2) { +bool daEnBomhei_c::hitCallback_Ice(dCc_c *self, dCc_c *other) { if (mIceMng.mActive) { return true; } - dActor_c *player = (dActor_c *) cc2->getOwner(); + dActor_c *player = (dActor_c *) other->getOwner(); if (player->mSpeed.x >= 0.0f) { - mBoyoMng.mDirection = 0; + mIceDirection = DIR_LR_R; } else { - mBoyoMng.mDirection = 1; + mIceDirection = DIR_LR_L; } mAnmMat.setFrame(0.0f, 0); @@ -488,7 +503,7 @@ bool daEnBomhei_c::hitCallback_Ice(dCc_c *cc1, dCc_c *cc2) { mIceMng.mPlrNo = player->getPlrNo(); changeState(StateID_Ice); - mTimer = -1; + mExplodeWaitTimer = -1; mPlayerNo = -1; return true; @@ -499,9 +514,9 @@ void daEnBomhei_c::returnState_Ice() { changeState(StateID_AfterIce); } -bool daEnBomhei_c::hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2) { - dActor_c *other = cc2->getOwner(); - u8 plrNo = other->getPlrNo(); +bool daEnBomhei_c::hitCallback_HipAttk(dCc_c *self, dCc_c *other) { + dActor_c *otherActor = other->getOwner(); + u8 plrNo = otherActor->getPlrNo(); if (plrNo >= PLAYER_COUNT) { return true; @@ -510,17 +525,18 @@ bool daEnBomhei_c::hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2) { return true; } - if (mPos.x >= other->mPos.x) { - mDirection = 0; + if (mPos.x >= otherActor->mPos.x) { + mDirection = DIR_LR_R; } else { - mDirection = 1; + mDirection = DIR_LR_L; } + mPlayerNo = plrNo; dAudio::SoundEffectID_t(SE_EMY_DOWN).playEmySound(mPos, 0); - hipatkEffect(other->mPos); + hipatkEffect(otherActor->mPos); mNoHitPlayer.mTimer[mPlayerNo] = 16; - if (mTimer < 0) { - mTimer = smc_5EC_VALUE; + if (mExplodeWaitTimer < 0) { + mExplodeWaitTimer = smc_ExplodeWaitFrames; mAnmMat.setFrame(0.0f, 0); } vf29c(); @@ -529,11 +545,10 @@ bool daEnBomhei_c::hitCallback_HipAttk(dCc_c *cc1, dCc_c *cc2) { return true; } -bool daEnBomhei_c::hitCallback_YoshiHipAttk(dCc_c *cc1, dCc_c *cc2) { +bool daEnBomhei_c::hitCallback_YoshiHipAttk(dCc_c *self, dCc_c *other) { if (!isState(StateID_Explode)) { dAudio::SoundEffectID_t(SE_EMY_YOSHI_HPDP).playEmySound(mPos, 0); - setDeathInfo_YoshiFumi(cc2->getOwner()); - + setDeathInfo_YoshiFumi(other->getOwner()); return true; } @@ -560,26 +575,26 @@ bool daEnBomhei_c::createIceActor() { return mIceMng.createIce(iceInfo, ARRAY_SIZE(iceInfo)); } -bool daEnBomhei_c::EtcDamageCheck(dCc_c *cc1, dCc_c *cc2) { - if (dEn_c::EtcDamageCheck(cc1, cc2)) { +bool daEnBomhei_c::EtcDamageCheck(dCc_c *self, dCc_c *other) { + if (dEn_c::EtcDamageCheck(self, other)) { return true; } - dActor_c *other = cc2->getOwner(); - daEnBomhei_c *self = (daEnBomhei_c *) cc1->getOwner(); - if (cc2->mCcData.mStatus & 0x200) { - cc1->mInfo |= CC_NO_HIT; - if (!self->isState(StateID_Explode)) { - self->changeState(StateID_Explode); + dActor_c *otherActor = other->getOwner(); + daEnBomhei_c *selfActor = (daEnBomhei_c *) self->getOwner(); + if (other->mCcData.mStatus & CC_STATUS_9) { + self->mInfo |= CC_NO_HIT; + if (!selfActor->isState(StateID_Explode)) { + selfActor->changeState(StateID_Explode); } return true; - } else if (other->mProfName == fProfile::PAKKUN_FIREBALL || other->mProfName == fProfile::BROS_FIREBALL) { - if (self->mTimer < 0) { - self->mTimer = smc_5EC_VALUE; - self->mAnmMat.setFrame(0.0f, 0); - self->changeState(StateID_Sleep); + } else if (otherActor->mProfName == fProfile::PAKKUN_FIREBALL || otherActor->mProfName == fProfile::BROS_FIREBALL) { + if (selfActor->mExplodeWaitTimer < 0) { + selfActor->mExplodeWaitTimer = smc_ExplodeWaitFrames; + selfActor->mAnmMat.setFrame(0.0f, 0); + selfActor->changeState(StateID_Sleep); } - daFireBall_Base_c *fireball = (daFireBall_Base_c *) other; + daFireBall_Base_c *fireball = (daFireBall_Base_c *) otherActor; fireball->kill(); return true; } @@ -631,8 +646,8 @@ void daEnBomhei_c::checkBombBreak() { mBc.checkBombBreak(v1, v2); } -void daEnBomhei_c::someBgCheck() { - mVec2_c pos = getSomePos(); +void daEnBomhei_c::explodeBgUnit() { + mVec2_c pos = getExplodeTilePos(); for (int i = 0; i < 2; i++) { int unitType = dBc_c::getUnitType(pos.x, pos.y, mLayer); if (unitType & 0x1c) { @@ -645,10 +660,11 @@ void daEnBomhei_c::someBgCheck() { } } -mVec2_c daEnBomhei_c::getSomePos() { - if (m_5f0 >= 9) { +mVec2_c daEnBomhei_c::getExplodeTilePos() { + if (mExplodeTimer >= 9) { return mVec2_c(0.0f, 0.0f); } + static const float xOffsets[] = { -16.0f, 0.0f, 16.0f, -16.0f, 0.0f, 16.0f, @@ -659,21 +675,22 @@ mVec2_c daEnBomhei_c::getSomePos() { 0.0f, 0.0f, 0.0f, -16.0f, -16.0f, -16.0f }; - int roundedX = mPos.x / 16; - int roundedY = mPos.y / 16; - float x = roundedX * 16.0f; - float y = roundedY * 16.0f; - x += xOffsets[m_5f0]; - y += yOffsets[m_5f0]; + + int tileX = mPos.x / 16; + int tileY = mPos.y / 16; + float x = tileX * 16.0f; + float y = tileY * 16.0f; + x += xOffsets[mExplodeTimer]; + y += yOffsets[mExplodeTimer]; return mVec2_c(x, y); } -void explosionCallback(dCc_c *cc1, dCc_c *cc2) { - dActor_c *self = cc1->getOwner(); - dActor_c *other = cc2->getOwner(); - if (other->mKind == dActor_c::STAGE_ACTOR_PLAYER || other->mKind == dActor_c::STAGE_ACTOR_YOSHI) { - daPlBase_c *player = (daPlBase_c *) other; - player->setDamage(self, daPlBase_c::DAMAGE_DEFAULT); +void explosionCallback(dCc_c *self, dCc_c *other) { + dActor_c *selfActor = self->getOwner(); + dActor_c *otherActor = other->getOwner(); + if (otherActor->mKind == dActor_c::STAGE_ACTOR_PLAYER || otherActor->mKind == dActor_c::STAGE_ACTOR_YOSHI) { + daPlBase_c *player = (daPlBase_c *) otherActor; + player->setDamage(selfActor, daPlBase_c::DAMAGE_DEFAULT); } } @@ -689,11 +706,11 @@ void daEnBomhei_c::initializeState_Walk() { mAnm.setRate(1.0f); } - static const float dirSpeed[] = { smc_WALK_SPEED, -smc_WALK_SPEED }; + static const float dirSpeed[] = { smc_WalkSpeed, -smc_WalkSpeed }; mFlags &= ~0x10000; mSpeed.x = dirSpeed[mDirection]; - mPos.z = 1500.0f + ACTOR_PARAM(zLayer) * 16.0f; + mPos.z = 1500.0f + ACTOR_PARAM(ZLayer) * 16.0f; mPlayerNo = -1; mBc.mOwningPlrNo = -1; } @@ -704,12 +721,16 @@ void daEnBomhei_c::executeState_Walk() { mModel.play(); calcSpeedY(); posMove(); + EnBgCheckFoot(); if (mBc.isFoot()) { mSpeed.y = 0.0f; } + mBc.checkHead(mBc.mFlags); + EnBgCheckWall(); + WaterCheck(mPos, 1.0f); if (mBc.mFlags & 0x15 << mDirection) { changeState(StateID_Turn); @@ -727,13 +748,17 @@ void daEnBomhei_c::executeState_Turn() { mModel.play(); calcSpeedY(); posMove(); + EnBgCheckFoot(); if (mBc.isFoot()) { mAnm.setRate(1.0f); mSpeed.y = 0.0f; } + mBc.checkHead(mBc.mFlags); + EnBgCheckWall(); + WaterCheck(mPos, 1.0f); mAngle.y += l_turn_angleY_add[mDirection]; @@ -762,11 +787,14 @@ void daEnBomhei_c::executeState_Sleep() { mModel.play(); calcSpeedY(); posMove(); + EnBgCheckFoot(); if (mBc.isFoot()) { Bound(0.1875f, 0.5f, 0.5f); } + mBc.checkHead(0); + EnBgCheckWall(); if (mBc.mFlags & 0x3c000000) { if (mSpeed.y > 0.0f) { @@ -776,9 +804,10 @@ void daEnBomhei_c::executeState_Sleep() { if (mBc.mFlags & 0x3f) { mSpeed.x = 0.0f; } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); - mTimer--; - if (mTimer <= 0) { + mExplodeWaitTimer--; + if (mExplodeWaitTimer <= 0) { changeState(StateID_Explode); } } @@ -788,19 +817,19 @@ void daEnBomhei_c::initializeState_Carry() { mAnm.setAnm(mModel, anm, m3d::FORWARD_LOOP); mModel.setAnm(mAnm, 2.0f); mAnm.setRate(1.0f); - mPlayerNo = m_624; - dAcPy_c *player = daPyMng_c::getPlayer(m_624); + + mPlayerNo = mCarryingPlayer; + dAcPy_c *player = daPyMng_c::getPlayer(mCarryingPlayer); if (player->mAmiLayer == 1) { mAmiLayer = 0; } else { mAmiLayer = 1; } - float x, y, width, height; - x = mCc.mCcData.mBase.mOffset.x; - y = mCc.mCcData.mBase.mOffset.y; - width = mCc.mCcData.mBase.mSize.x; - height = mCc.mCcData.mBase.mSize.y; + float x = mCc.mCcData.mBase.mOffset.x; + float y = mCc.mCcData.mBase.mOffset.y; + float width = mCc.mCcData.mBase.mSize.x; + float height = mCc.mCcData.mBase.mSize.y; mCcOffsetX = x; mCcOffsetY = y; mCcWidth = width; @@ -814,7 +843,7 @@ void daEnBomhei_c::initializeState_Carry() { } void daEnBomhei_c::finalizeState_Carry() { - dAcPy_c *player = daPyMng_c::getPlayer(m_624); + dAcPy_c *player = daPyMng_c::getPlayer(mCarryingPlayer); player->cancelCarry(this); mCc.mCcData.mVsKind &= ~BIT_FLAG(CC_KIND_KILLER); mCc.mCcData.mAttack = CC_ATTACK_NONE; @@ -828,11 +857,12 @@ void daEnBomhei_c::finalizeState_Carry() { } void daEnBomhei_c::executeState_Carry() { - dAcPy_c *player = daPyMng_c::getPlayer(m_624); + dAcPy_c *player = daPyMng_c::getPlayer(mCarryingPlayer); mModel.play(); mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); - mTimer--; - if (mTimer <= 0) { + + mExplodeWaitTimer--; + if (mExplodeWaitTimer <= 0) { mDirection = player->mDirection; if (checkWallAndBg()) { setDeathInfo_Carry(player); @@ -867,7 +897,7 @@ void daEnBomhei_c::initializeState_Slide() { mModel.setAnm(mAnm, 2.0f); mAnm.setRate(1.0f); - static const float dirSpeed[] = { smc_SLIDE_SPEED_X, -smc_SLIDE_SPEED_X }; + static const float dirSpeed[] = { smc_SlideSpeedX, -smc_SlideSpeedX }; clrComboCnt(); mAccelF = 0.0625f; mSpeed.x = dirSpeed[mDirection]; @@ -891,6 +921,7 @@ void daEnBomhei_c::executeState_Slide() { calcSpeedX(); calcSpeedY(); posMove(); + u32 bcFlags = EnBgCheckFoot(); if (mBc.isFoot()) { Bound(0.1875f, 1.0f, 0.5f); @@ -899,17 +930,22 @@ void daEnBomhei_c::executeState_Slide() { mEf::createEffect("Wm_en_landsmoke_s", 0, &efPos, nullptr, nullptr); } } + mBc.checkHead(bcFlags); + EnBgCheckWall(); if (mBc.mFlags & 0x15 << mDirection) { mDirection ^= 1; mAngle.y = l_base_angleY[mDirection]; - mSpeed.x = -mSpeed.x * smc_WALK_SPEED; + mSpeed.x = -mSpeed.x * smc_WalkSpeed; } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + WaterCheck(mPos, 1.0f); - mTimer--; - if (mTimer <= 0) { + + mExplodeWaitTimer--; + if (mExplodeWaitTimer <= 0) { changeState(StateID_Explode); } else if (mSpeed.x == 0.0f) { changeState(StateID_Sleep); @@ -917,9 +953,9 @@ void daEnBomhei_c::executeState_Slide() { } void daEnBomhei_c::initializeState_Kick() { - static const float dirSpeed[] = { smc_KICK_SPEED_X, -smc_KICK_SPEED_X }; + static const float dirSpeed[] = { smc_KickSpeedX, -smc_KickSpeedX }; - mSpeed.set(dirSpeed[mDirection], smc_KICK_SPEED_Y, 0.0f); + mSpeed.set(dirSpeed[mDirection], smc_KickSpeedY, 0.0f); mAngle.y = l_base_angleY[mDirection]; clrComboCnt(); mAccelY = -0.1875f; @@ -934,11 +970,14 @@ void daEnBomhei_c::finalizeState_Kick() { void daEnBomhei_c::executeState_Kick() { calcSpeedY(); posMove(); + u32 bcFlags = EnBgCheckFoot(); if (mBc.isFoot()) { Bound(0.1875f, 0.5f, 0.5f); } + mBc.checkHead(bcFlags); + EnBgCheckWall(); if (bcFlags != 0) { if (std::fabs(mSpeed.x) > 0.2f) { @@ -956,10 +995,13 @@ void daEnBomhei_c::executeState_Kick() { mAngle.y = l_base_angleY[mDirection]; mSpeed.x = -mSpeed.x; } + mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); + WaterCheck(mPos, 1.0f); - mTimer--; - if (mTimer <= 0) { + + mExplodeWaitTimer--; + if (mExplodeWaitTimer <= 0) { changeState(StateID_Explode); } else if (mSpeed.x == 0.0f) { changeState(StateID_Sleep); @@ -967,7 +1009,7 @@ void daEnBomhei_c::executeState_Kick() { } void daEnBomhei_c::initializeState_KickBom() { - static const float dirSpeed[] = { smc_KICK_SPEED_X, -smc_KICK_SPEED_X }; + static const float dirSpeed[] = { smc_KickSpeedX, -smc_KickSpeedX }; mSpeed.set(dirSpeed[mDirection], 2.0f, 0.0f); mAngle.y = l_base_angleY[mDirection]; @@ -985,6 +1027,7 @@ void daEnBomhei_c::finalizeState_KickBom() { void daEnBomhei_c::executeState_KickBom() { calcSpeedY(); posMove(); + u32 bcFlags = EnBgCheckFoot(); mBc.checkHead(bcFlags); EnBgCheckWall(); @@ -993,7 +1036,9 @@ void daEnBomhei_c::executeState_KickBom() { mAngle.y = l_base_angleY[mDirection]; mSpeed.x = -mSpeed.x; } + WaterCheck(mPos, 1.0f); + switch (m_23b) { case 1: if (bcFlags != 0) { @@ -1015,20 +1060,20 @@ void daEnBomhei_c::initializeState_Wakidashi() { mModel.setAnm(mAnm, 2.0f); mAnm.setRate(2.0f); - u8 wakidashiSetting = ACTOR_PARAM(wakidashiConfig); - if (wakidashiSetting & 2) { - mDirection = (wakidashiSetting & 1) ^ 1; + u8 wakidashiDir = ACTOR_PARAM(WakidashiSpawnDir); + if (wakidashiDir & 2) { + mDirection = (wakidashiDir & 1) ^ 1; } else { mDirection = getPl_LRflag(mPos); } - static const float speedX[] = { 0.0f, 0.0f, -smc_WALK_SPEED, smc_WALK_SPEED }; - static const float speedY[] = { smc_WALK_SPEED, -smc_WALK_SPEED, 0.0f, 0.0f }; + static const float speedX[] = { 0.0f, 0.0f, -smc_WalkSpeed, smc_WalkSpeed }; + static const float speedY[] = { smc_WalkSpeed, -smc_WalkSpeed, 0.0f, 0.0f }; mAngle.y = l_base_angleY[mDirection]; - mSpeed.set(speedX[wakidashiSetting], speedY[wakidashiSetting], 0.0f); + mSpeed.set(speedX[wakidashiDir], speedY[wakidashiDir], 0.0f); mFlags |= 0x10000; - m_5f4 = 0x20; + mWakidashiTimer = 32; mCc.mCcData.mVsKind &= ~BIT_FLAG(CC_KIND_ENEMY); mCc.mCcData.mVsDamage &= ~BIT_FLAG(CC_ATTACK_FIREBALL); } @@ -1042,8 +1087,8 @@ void daEnBomhei_c::finalizeState_Wakidashi() { void daEnBomhei_c::executeState_Wakidashi() { mModel.play(); dBaseActor_c::posMove(); - m_5f4--; - if (m_5f4 == 0) { + mWakidashiTimer--; + if (mWakidashiTimer == 0) { changeState(StateID_Walk); } } @@ -1062,12 +1107,12 @@ void daEnBomhei_c::initializeState_CannonHop_Upper() { mAccelY = -0.1875f; mSpeed.set( - speedX[ACTOR_PARAM(CannonHopDir)][mDirection], - speedY[ACTOR_PARAM(CannonHopDir)], + speedX[ACTOR_PARAM(CannonHopType)][mDirection], + speedY[ACTOR_PARAM(CannonHopType)], 0.0f ); mBc.set(this, l_bomhei_8, l_bomhei_7, l_bomhei_9); - m_5fc = 8; + mCannonHopTimer = 8; m_23b = 1; } @@ -1079,12 +1124,13 @@ void daEnBomhei_c::executeState_CannonHop_Upper() { mModel.play(); calcSpeedY(); posMove(); + switch (m_23b) { case 1: mBc.checkWall(nullptr); mBc.checkHead(0); - m_5fc--; - if (m_5fc <= 0) { + mCannonHopTimer--; + if (mCannonHopTimer <= 0) { mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); m_23b = 2; } @@ -1112,7 +1158,7 @@ void daEnBomhei_c::initializeState_CannonHop_Under() { mAccelY = -0.1875f; mSpeed.set(speedX[mDirection], -0.75f, 0.0f); - m_5fc = 8; + mCannonHopTimer = 8; mBc.set(this, l_bomhei_8, l_bomhei_7, l_bomhei_9); m_23b = 1; } @@ -1125,12 +1171,13 @@ void daEnBomhei_c::executeState_CannonHop_Under() { mModel.play(); calcSpeedY(); posMove(); + switch (m_23b) { case 1: mBc.checkWall(nullptr); mBc.checkHead(0); - m_5fc--; - if (m_5fc <= 0) { + mCannonHopTimer--; + if (mCannonHopTimer <= 0) { mBc.set(this, l_bomhei_foot, l_bomhei_head, l_bomhei_wall); m_23b = 2; } @@ -1160,6 +1207,7 @@ void daEnBomhei_c::executeState_AfterIce() { if (mBc.checkWall(nullptr)) { mSpeed.x = -mSpeed.x; } + switch (m_23b) { case 1: if (mBc.checkFootEnm()) { @@ -1198,8 +1246,8 @@ void daEnBomhei_c::finalizeState_EatOut() { void daEnBomhei_c::executeState_EatOut() { mEffect.createEffect("Wm_en_bombignition", 0, &mIgnitionPos, nullptr, nullptr); - mTimer--; - if (mTimer <= 0) { + mExplodeWaitTimer--; + if (mExplodeWaitTimer <= 0) { changeState(StateID_Explode); } else { dEn_c::executeState_EatOut(); @@ -1220,7 +1268,8 @@ void daEnBomhei_c::initializeState_Explode() { mCc.mCcData.mVsDamage = 0; mCc.mCcData.mStatus |= CC_STATUS_NO_REVISION; mCc.mCcData.mCallback = explosionCallback; - mTimer = 0; + + mExplodeWaitTimer = 0; mAngle.y = l_base_angleY[mDirection]; mPos.y += 8.0f; checkBombBreak(); @@ -1229,10 +1278,10 @@ void daEnBomhei_c::initializeState_Explode() { void daEnBomhei_c::finalizeState_Explode() {} void daEnBomhei_c::executeState_Explode() { - m_5f0++; - if (m_5f0 < 9) { - someBgCheck(); - } else if (m_5f0 == 16) { + mExplodeTimer++; + if (mExplodeTimer < 9) { + explodeBgUnit(); + } else if (mExplodeTimer == 16) { deleteActor(true); } } @@ -1248,7 +1297,7 @@ void daEnBomhei_c::finalizeState_InIceLump() {} void daEnBomhei_c::executeState_InIceLump() {} -const int daEnBomhei_c::smc_SOUND_EFFECTS[] = { +const int daEnBomhei_c::smc_SoundEffectIDs[] = { SE_EMY_YOSHI_HPDP, SE_EMY_DOWN, SE_EMY_KAME_KERU, diff --git a/source/dol/bases/d_a_en_shell.cpp b/source/dol/bases/d_a_en_shell.cpp index b3619f47..8d0a00a8 100644 --- a/source/dol/bases/d_a_en_shell.cpp +++ b/source/dol/bases/d_a_en_shell.cpp @@ -757,9 +757,9 @@ bool daEnShell_c::hitCallback_Ice(dCc_c *self, dCc_c *other) { } if (other->mpOwner->mSpeed.x >= 0.0f) { - mBoyoMng.mDirection = DIR_LR_R; + mIceDirection = DIR_LR_R; } else { - mBoyoMng.mDirection = DIR_LR_L; + mIceDirection = DIR_LR_L; } for (int i = 0; i < PLAYER_COUNT; i++) { dAcPy_c *player = daPyMng_c::getPlayer(i); diff --git a/source/dol/bases/d_enemy_death.cpp b/source/dol/bases/d_enemy_death.cpp index 75491736..8eea1c62 100644 --- a/source/dol/bases/d_enemy_death.cpp +++ b/source/dol/bases/d_enemy_death.cpp @@ -381,9 +381,9 @@ bool dEn_c::hitCallback_Ice(dCc_c *self, dCc_c *other) { daPlBase_c *player = (daPlBase_c *) other->getOwner(); if (player->mSpeed.x >= 0.0f) { - mBoyoMng.mDirection = 0; + mIceDirection = 0; } else { - mBoyoMng.mDirection = 1; + mIceDirection = 1; } for (int i = 0; i < PLAYER_COUNT; i++) {