diff --git a/include/game/bases/d_a_player_demo_manager.hpp b/include/game/bases/d_a_player_demo_manager.hpp index 39d1a6cb..6fca6364 100644 --- a/include/game/bases/d_a_player_demo_manager.hpp +++ b/include/game/bases/d_a_player_demo_manager.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include class daPyDemoMng_c { public: @@ -21,6 +22,18 @@ class daPyDemoMng_c { int getControlDemoPlayerNum() const; int getNextDemoNo(); + void setBossDownPlayerNo(int plNo); + void setBossDown(daPlBase_c *player) { + setBossDownPlayerNo(player->getPlrNo()); + } + + int getPlrNo() const { return mPlayerNo; } + void setPlrNo(int playerNo) { mPlayerNo = playerNo; } + int get_88() const { return m_88; } + void inc_88() { m_88++; } + + static daPyDemoMng_c *getInstance() { return mspInstance; } + char mPad1[0x10]; u32 mFlags; u32 mGoalType; @@ -41,10 +54,5 @@ class daPyDemoMng_c { u8 mPad8[0x8]; int m_94; - int getPlrNo() const { return mPlayerNo; } - void setPlrNo(int playerNo) { mPlayerNo = playerNo; } - int get_88() const { return m_88; } - void inc_88() { m_88++; } - static daPyDemoMng_c *mspInstance; }; diff --git a/include/game/bases/d_actor_manager.hpp b/include/game/bases/d_actor_manager.hpp index 5ae8104b..711813ad 100644 --- a/include/game/bases/d_actor_manager.hpp +++ b/include/game/bases/d_actor_manager.hpp @@ -9,6 +9,7 @@ class dActorMng_c { u8 mPad2[0x218]; void createUpCoin(const mVec3_c &pos, u8 dir, u8 count, u8 layer); + void allEnemyDeath(int); static dActorMng_c *m_instance; }; diff --git a/include/game/bases/d_bc.hpp b/include/game/bases/d_bc.hpp index 95c655ea..4e8f2dd8 100644 --- a/include/game/bases/d_bc.hpp +++ b/include/game/bases/d_bc.hpp @@ -168,7 +168,7 @@ class dBc_c { u32 isWallL() { return mFlags & FLAG_WALL_L; } u32 isWall() { return mFlags & (FLAG_WALL_R | FLAG_WALL_L); } u32 isWall(u8 dir) { return mFlags & (FLAG_WALL_R << dir); } - u32 isFoot(); // { return mFlags & FLAG_FOOT; } + bool isFoot(); // { return mFlags & FLAG_FOOT; } u32 isHead() { return mFlags & FLAG_HEAD; } u32 isCollision() { return mFlags & (FLAG_WALL_L | FLAG_WALL_R | FLAG_FOOT | FLAG_HEAD); } diff --git a/include/game/bases/d_boss_life.hpp b/include/game/bases/d_boss_life.hpp new file mode 100644 index 00000000..0e63ff39 --- /dev/null +++ b/include/game/bases/d_boss_life.hpp @@ -0,0 +1,75 @@ +#pragma once + +/// @brief Interface for tracking the life of a boss enemy. +class dBossLifeInf_c { +public: + dBossLifeInf_c(int life) : mLife(life) {} + + virtual ~dBossLifeInf_c() {} + virtual bool isNonDamage() const = 0; + virtual bool isOneDamage() const = 0; + virtual bool isTwoDamage() const = 0; + virtual bool isDmgSection() const { return false; } + virtual int getDamage_Fire() const = 0; + virtual int getDamage_Fumi() const = 0; + virtual int getDamage_HipAtk() const = 0; + virtual int getDamage_Star() const = 0; + virtual int getDamage_PenguinSlide() const = 0; + virtual int getDamage_BlockHit() const = 0; + virtual int getDamage_Shell() const = 0; + virtual int getDamage_Quake() const = 0; + virtual void damageRev(int) {} + + int updateCommon(int dmg) { + mLife -= dmg; + if (mLife > 0) { + damageRev(dmg); + } + return mLife; + } + + int updateFire() { return updateCommon(getDamage_Fire()); } + int updateFumi() { return updateCommon(getDamage_Fumi()); } + int updateHipAtk() { return updateCommon(getDamage_HipAtk()); } + int updateStar() { return updateCommon(getDamage_Star()); } + int updatePenguinSlide() { return updateCommon(getDamage_PenguinSlide()); } + int updateBlockHit() { return updateCommon(getDamage_BlockHit()); } + int updateShell() { return updateCommon(getDamage_Shell()); } + int updateQuake() { return updateCommon(getDamage_Quake()); } + + int mLife; +}; + +/// @brief A base implementation of dBossLifeInf_c. +/// @details The boss's life is divided into sections of 6 HP each. +class dBossLife_Common_c : public dBossLifeInf_c { +public: + dBossLife_Common_c(int num) : dBossLifeInf_c(num) {} + virtual ~dBossLife_Common_c() {} + + int getSection() const { return (mLife - 1) / 6; } + + virtual bool isNonDamage() const override { + return getSection() > 1; + } + virtual bool isOneDamage() const override { + return getSection() > 0 && getSection() < 2; + } + virtual bool isTwoDamage() const override { + return getSection() <= 0; + } + + virtual bool isDmgSection() const override { return mLife % 6 == 0; } + virtual void damageRev(int dmg) override { + int sections = mLife / 6; + if (mLife - sections * 6 != 0 && dmg >= 6) { mLife = (sections + 1) * 6; }; + } + virtual int getDamage_Fire() const override { return 1; } + virtual int getDamage_Fumi() const override { return 6; } + virtual int getDamage_HipAtk() const override { return 6; } + virtual int getDamage_Star() const override { return 6; } + virtual int getDamage_PenguinSlide() const override { return 6; } + virtual int getDamage_BlockHit() const override { return 6; } + virtual int getDamage_Shell() const override { return 6; } + virtual int getDamage_Quake() const override { return 6; } +}; diff --git a/include/game/bases/d_enemy.hpp b/include/game/bases/d_enemy.hpp index fdb30668..ebfc8ede 100644 --- a/include/game/bases/d_enemy.hpp +++ b/include/game/bases/d_enemy.hpp @@ -91,6 +91,7 @@ class dEn_c : public dActorMultiState_c { enum FLAGS_e { EN_IS_SHELL = BIT_FLAG(0), EN_IS_HARD = BIT_FLAG(1), + EN_FLAG_4 = BIT_FLAG(4), EN_FLAG_16 = BIT_FLAG(16), EN_FLAG_24 = BIT_FLAG(24) }; diff --git a/include/game/bases/d_enemy_boss.hpp b/include/game/bases/d_enemy_boss.hpp new file mode 100644 index 00000000..377bd11c --- /dev/null +++ b/include/game/bases/d_enemy_boss.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include +#include +#include +#include +#include + +/// @brief The base class for boss enemies. +class dEnBoss_c : public dEn_c { +public: + struct GlobalData_t { + bool mInstantKill; + }; + + dEnBoss_c(); + virtual ~dEnBoss_c(); + + // fBase_c overrides + + virtual int create(); + virtual int preExecute(); + virtual void postExecute(MAIN_STATE_e state); + + // dEn_c overrides + + virtual void FumiScoreSet(dActor_c *actor) {} + virtual void Normal_VsPlHitCheck(dCc_c *self, dCc_c *other); + virtual void Normal_VsYoshiHitCheck(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Fire(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Shell(dCc_c *self, dCc_c *other); + virtual bool hitCallback_HipAttk(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Spin(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Star(dCc_c *self, dCc_c *other); + virtual bool hitCallback_Ice(dCc_c *self, dCc_c *other) { iceballInvalid(self, other); return false; } + virtual bool hitCallback_Slip(dCc_c *self, dCc_c *other) { return false; } + virtual bool hitCallback_WireNet(dCc_c *self, dCc_c *other) { return false; } + virtual bool hitCallback_PenguinSlide(dCc_c *self, dCc_c *other); + virtual void setDeathInfo_Quake(int); + virtual bool isQuakeDamage(); + + // New virtual functions + + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DemoWait); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieFumi); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieFire); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieSlide); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieShell); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieStar); + STATE_VIRTUAL_FUNC_DECLARE(dEnBoss_c, DieQuake); + + virtual void setBattleReady() {} + virtual void createModel() {} + virtual void createBossLife(); + virtual int createInit(); + virtual void tenmetsuReady() {} ///< Prepares the flashing effect after the boss takes damage. + virtual void tenmetsuProc() {} ///< Handles the flashing effect after the boss takes damage. + virtual void tenmetsuFin() {} ///< Ends the flashing effect after the boss takes damage. + virtual int getTenmetsuTime_Fire() { return 40; } + virtual int getTenmetsuTime_Shell() { return 40; } + virtual int getTenmetsuTime_Press() { return 40; } + virtual void deadAllKill(); + virtual void setFumiDamage(dActor_c *) {} + virtual void setFumiDead(dActor_c *) {} + virtual void setFireDamage(dActor_c *) {} + virtual void setFireDead(dActor_c *) {} + virtual void setHipatkDamage(dActor_c *actor) { setFumiDamage(actor); } + virtual void setHipatkDead(dActor_c *actor) { setFumiDead(actor); } + virtual void setSlideDamage(dActor_c *) {} + virtual void setSlideDead(dActor_c *) {} + virtual void setStarDamage(dActor_c *) {} + virtual void setStarDead(dActor_c *) {} + virtual void setQuakeDamage() {} + virtual void setQuakeDead() {} + virtual void setShellDamage(dActor_c *) {} + virtual void setShellDead(dActor_c *) {} + virtual void damageProc() {} + virtual void deadProc() {} + virtual bool isFumiInvalid() const { return false; } + virtual bool isFumiDmgInvalid() const { return false; } + virtual bool isFireInvalid() const { return false; } + virtual bool isSlideInvalid() const { return true; } + virtual bool isShellInvalid() const { return false; } + virtual bool isStarInvalid() const { return false; } + virtual void fumideadEffect() {} + virtual void fumidmgEffect() {} + virtual void hitFireEffect() {} + virtual void hitShellEffect() {} + virtual void fumidmgSE() { playSE(SE_BOSS_CMN_STOMPED); } + virtual void fumideadSE() { playSE(SE_BOSS_CMN_STOMPED_LAST1); } + virtual void stardmgSE() { playSE(SE_BOSS_CMN_DAMAGE_STAR_DEF); } + virtual void stardeadSE() { playSE(SE_BOSS_CMN_DAMAGE_STAR_LAST); } + virtual void shelldmgSE() { playSE(SE_BOSS_CMN_DAMAGE_DEF);} + virtual void shelldeadSE() { playSE(SE_BOSS_CMN_DAMAGE_LAST);} + virtual void firedmgSE() { mpBossLife->isDmgSection() ? playSE(SE_BOSS_CMN_DAMAGE_FIRE_DEF) : playSE(SE_BOSS_CMN_DAMAGE_FIRE); } + virtual void firedeadSE() { playSE(SE_BOSS_CMN_DAMAGE_FIRE_LAST); } + virtual void quakedmgSE() { playSE(SE_BOSS_CMN_DAMAGE_STAR_DEF); } + virtual void quakedeadSE() { playSE(SE_BOSS_CMN_DAMAGE_STAR_LAST);} + virtual void fumiDeadVo() {} + virtual void damageSVo() {} + virtual void damageLVo() {} + + void getTenmetsuTimePress(bool a) { + /// [Get weak function placement to work out] + if (a) { + tenmetsuReady(); + } + mTenmetsuTime = getTenmetsuTime_Press(); + tenmetsuReady(); + } + + void playSE(ulong soundID) { mSndObject.startSound(soundID, m_d0, 0); } + int getLife() const { return mpBossLife->mLife; } + bool isDead() const { return mpBossLife->mLife <= 0; } + + void allocate(); + void fumiProc(dActor_c *actor); + + dHeapAllocator_c mAllocator; + int mTenmetsuTime; ///< Timer for the flashing effect when the boss takes damage. + dAudio::SndObjctEmy_c mSndObject; + u16 m_d0; + u32 mQuakeDamage; + dBossLifeInf_c *mpBossLife; +}; diff --git a/include/game/sLib/s_State.hpp b/include/game/sLib/s_State.hpp index 6d230a55..f570b264 100644 --- a/include/game/sLib/s_State.hpp +++ b/include/game/sLib/s_State.hpp @@ -59,3 +59,24 @@ &class::executeState_##name, \ &class::finalizeState_##name \ ); + +/// @brief Defines a virtual state. +/// @param class The class name. +/// @param name The state name. +/// @hideinitializer +#define STATE_VIRTUAL_DEFINE_INH(class, name, inherit) \ + template \ + static const sStateIDIf_c &baseID_##name() { \ + return T::StateID_##name; \ + } \ + template <> \ + const sStateIDIf_c &baseID_##name() { \ + return sStateID::null; \ + } \ + sFStateVirtualID_c class::StateID_##name( \ + baseID_##name(), \ + #class "::StateID_" #name, \ + &class::initializeState_##name, \ + &class::executeState_##name, \ + &class::finalizeState_##name \ + ); diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 39962977..ad6b1827 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -63,7 +63,8 @@ "GetRuntimeTypeInfo__Q34nw4r3lyt4PaneCFv", "setPosParam__Q23EGG14CoreControllerFff", "getFileSize__Q23EGG7DvdFileCFv", - "isItemKinopio__7dAcPy_cFv" + "isItemKinopio__7dAcPy_cFv", + "__dt__11SndObjctEmyFv" ], "slices": [ { @@ -306,6 +307,17 @@ ".sdata2": "0x1120-0x11a8" } }, + { + "source": "dol/bases/d_enemy_boss.cpp", + "memoryRanges": { + ".text": "0x91bd0-0x94520", + ".ctors": "0xd8-0xdc", + ".data": "0x13be8-0x142a0", + ".bss": "0x6028-0x61e8", + ".sdata2": "0x11a8-0x11b0", + ".sbss2": "0x8-0x10" + } + }, { "source": "dol/bases/d_enemy_carry.cpp", "memoryRanges": { diff --git a/source/dol/bases/d_enemy_boss.cpp b/source/dol/bases/d_enemy_boss.cpp new file mode 100644 index 00000000..c5fc8fb2 --- /dev/null +++ b/source/dol/bases/d_enemy_boss.cpp @@ -0,0 +1,400 @@ +#include +#include +#include +#include +#include +#include + +template<> +const dEnBoss_c::GlobalData_t sGlobalData_c::mData = { + false +}; + +STATE_VIRTUAL_DEFINE(dEnBoss_c, DemoWait); +STATE_VIRTUAL_DEFINE_INH(dEnBoss_c, DieFumi, sStateID_c); // [Why is this not properly inherited?] +STATE_VIRTUAL_DEFINE(dEnBoss_c, DieFire); +STATE_VIRTUAL_DEFINE(dEnBoss_c, DieSlide); +STATE_VIRTUAL_DEFINE(dEnBoss_c, DieShell); +STATE_VIRTUAL_DEFINE(dEnBoss_c, DieStar); +STATE_VIRTUAL_DEFINE(dEnBoss_c, DieQuake); + +dEnBoss_c::dEnBoss_c() : mTenmetsuTime(0) { + m_d0 = 0; + mQuakeDamage = 0; + mpBossLife = nullptr; +} + +dEnBoss_c::~dEnBoss_c() {} + +int dEnBoss_c::create() { + allocate(); + mFlags = EN_FLAG_4; + createInit(); + mActorProperties |= 0x200; + changeState(StateID_DemoWait); + mStateMgr.refreshState(); + return SUCCEEDED; +} + +int dEnBoss_c::createInit() { + return 1; +} + +void dEnBoss_c::allocate() { + mAllocator.createFrmHeapToCurrent(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], nullptr, 0x20, mHeap::OPT_NONE); + createModel(); + createBossLife(); + mAllocator.adjustFrmHeapRestoreCurrent(); +} + +void dEnBoss_c::createBossLife() { + if (mpBossLife == nullptr) { + mpBossLife = new dBossLife_Common_c(18); + } +} + +int dEnBoss_c::preExecute() { + if (dEn_c::preExecute() == NOT_READY) { + return NOT_READY; + } + + if (mTenmetsuTime > 0) { + mTenmetsuTime--; + if (mTenmetsuTime > 0) { + tenmetsuProc(); + } else { + tenmetsuFin(); + } + } + + if (mQuakeDamage && !(dQuake_c::m_instance->mFlags & dQuake_c::FLAG_1)) { + mQuakeDamage = 0; + } + + return SUCCEEDED; +} + +void dEnBoss_c::postExecute(MAIN_STATE_e state) { + if (state == SUCCESS) { + mSndObject.mPos = dAudio::cvtSndObjctPos(mPos); + mSndObject.calc(); + } + dEn_c::postExecute(state); +} + +bool dEnBoss_c::isQuakeDamage() { + if (mQuakeDamage) { + return false; + } + if (isState(StateID_DemoWait)) { + return false; + } + return mBc.isFoot(); +} + +void dEnBoss_c::Normal_VsPlHitCheck(dCc_c *self, dCc_c *other) { + if (isFumiInvalid()) { + dEn_c::Normal_VsPlHitCheck(self, other); + return; + } + + daPlBase_c *player = (daPlBase_c *) other->getOwner(); + + switch (Enfumi_check(self, other, 2)) { + case 1: + case 3: + if (!isFumiDmgInvalid()) { + fumiProc(other->getOwner()); + } + break; + case 0: + dEn_c::Normal_VsPlHitCheck(self, other); + if (player->isStatus(0x3F)) { + int plrNo = player->getPlrNo(); + if (plrNo >= 0 && plrNo < PLAYER_COUNT) { + mNoHitPlayer.mTimer[plrNo] = 16; + } + } + break; + } +} + +void dEnBoss_c::Normal_VsYoshiHitCheck(dCc_c *self, dCc_c *other) { + if (isFumiInvalid()) { + dEn_c::Normal_VsYoshiHitCheck(self, other); + return; + } + + switch (Enfumi_check(self, other, 0)) { + case 1: + if (!isFumiDmgInvalid()) { + fumiProc(other->getOwner()); + } + break; + case 0: + dEn_c::Normal_VsPlHitCheck(self, other); + break; + } +} + +void dEnBoss_c::deadAllKill() { + dActorMng_c::m_instance->allEnemyDeath(0); +} + +void dEnBoss_c::fumiProc(dActor_c *actor) { + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } else { + mpBossLife->updateFumi(); + } + + getTenmetsuTimePress(false); + if (mpBossLife->mLife <= 0) { + fumideadEffect(); + fumideadSE(); + fumiDeadVo(); + mpBossLife->mLife = 0; + deadAllKill(); + daPyDemoMng_c::mspInstance->setBossDown((daPlBase_c *) actor); + setFumiDead(actor); + deadProc(); + } else { + fumidmgEffect(); + fumidmgSE(); + setFumiDamage(actor); + damageProc(); + } +} + +bool dEnBoss_c::hitCallback_Fire(dCc_c *self, dCc_c *other) { + if (isFireInvalid()) { + fireballInvalid(self, other); + return true; + } + + dActor_c *player = other->getOwner(); + int prev2 = getLife(); + int prev = mpBossLife->updateFire(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (prev >= prev2) { + fireballInvalid(self, other); + } else { + if (isDead()) { + mpBossLife->mLife = 0; + mTenmetsuTime = getTenmetsuTime_Fire(); + tenmetsuReady(); + hitFireEffect(); + firedeadSE(); + deadAllKill(); + daPyDemoMng_c::getInstance()->setBossDown((daPlBase_c *) player); + setFireDead(player); + deadProc(); + } else { + mTenmetsuTime = getTenmetsuTime_Fire(); + tenmetsuReady(); + hitFireEffect(); + firedmgSE(); + setFireDamage(player); + damageProc(); + } + } + + return true; +} + +bool dEnBoss_c::hitCallback_Shell(dCc_c *self, dCc_c *other) { + if (isShellInvalid()) { + return false; + } + + dActor_c *player = other->getOwner(); + int prev2 = getLife(); + int prev = mpBossLife->updateShell(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (prev < prev2) { + if (isDead()) { + mpBossLife->mLife = 0; + mTenmetsuTime = getTenmetsuTime_Shell(); + tenmetsuReady(); + hitShellEffect(); + shelldeadSE(); + deadAllKill(); + daPyDemoMng_c::mspInstance->setBossDown((daPlBase_c *) player); + setShellDead(player); + deadProc(); + } else { + mTenmetsuTime = getTenmetsuTime_Shell(); + tenmetsuReady(); + hitShellEffect(); + shelldmgSE(); + setShellDamage(player); + damageProc(); + } + } + + return true; +} + +bool dEnBoss_c::hitCallback_HipAttk(dCc_c *self, dCc_c *other) { + if (isFumiInvalid()) { + return false; + } + + dActor_c *player = other->getOwner(); + FumiJumpSet(player); + mTenmetsuTime = getTenmetsuTime_Press(); + tenmetsuReady(); + mpBossLife->updateHipAtk(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (mpBossLife->mLife <= 0) { + fumideadEffect(); + fumideadSE(); + fumiDeadVo(); + mpBossLife->mLife = 0; + deadAllKill(); + daPyDemoMng_c::mspInstance->setBossDown((daPlBase_c *) player); + setHipatkDead(player); + deadProc(); + } else { + fumidmgEffect(); + fumidmgSE(); + setHipatkDamage(player); + damageProc(); + } + + return true; +} + +bool dEnBoss_c::hitCallback_Spin(dCc_c *self, dCc_c *other) { + if (isFumiInvalid()) { + return false; + } + + dActor_c *player = other->getOwner(); + FumiJumpSet(player); + mTenmetsuTime = getTenmetsuTime_Press(); + tenmetsuReady(); + mpBossLife->updateFumi(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (mpBossLife->mLife <= 0) { + fumideadEffect(); + fumideadSE(); + fumiDeadVo(); + mpBossLife->mLife = 0; + deadAllKill(); + daPyDemoMng_c::getInstance()->setBossDown((daPlBase_c *) player); + setHipatkDead(player); + deadProc(); + } else { + fumidmgEffect(); + fumidmgSE(); + setHipatkDamage(player); + damageProc(); + } + + return true; +} + +bool dEnBoss_c::hitCallback_Star(dCc_c *self, dCc_c *other) { + daPlBase_c *player = (daPlBase_c *) other->getOwner(); + + if (isStarInvalid()) { + player->setForcedDamage(this, daPlBase_c::DAMAGE_HIP_ATTACK); + return true; + } + + mTenmetsuTime = getTenmetsuTime_Press(); + tenmetsuReady(); + mpBossLife->updateStar(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (isDead()) { + mpBossLife->mLife = 0; + deadAllKill(); + daPyDemoMng_c::mspInstance->setBossDown(player); + stardeadSE(); + setStarDead(player); + deadProc(); + } else { + stardmgSE(); + setStarDamage(player); + damageProc(); + } + + return true; +} + +void dEnBoss_c::setDeathInfo_Quake(int) { + mQuakeDamage = 1; + mTenmetsuTime = getTenmetsuTime_Press(); + tenmetsuReady(); + mpBossLife->updateQuake(); + + if (sGlobalData_c::mData.mInstantKill) { + mpBossLife->mLife = 0; + } + + if (isDead()) { + mpBossLife->mLife = 0; + daPyDemoMng_c::mspInstance->setBossDownPlayerNo(-1); + quakedeadSE(); + deadAllKill(); + setQuakeDead(); + deadProc(); + } else { + quakedmgSE(); + setQuakeDamage(); + damageProc(); + } +} + +bool dEnBoss_c::hitCallback_PenguinSlide(dCc_c *self, dCc_c *other) { + return false; +} + +void dEnBoss_c::initializeState_DemoWait() {} +void dEnBoss_c::finalizeState_DemoWait() {} +void dEnBoss_c::executeState_DemoWait() {} + +void dEnBoss_c::initializeState_DieFumi() {} +void dEnBoss_c::finalizeState_DieFumi() {} +void dEnBoss_c::executeState_DieFumi() {} + +void dEnBoss_c::initializeState_DieFire() { initializeState_DieFumi(); } +void dEnBoss_c::finalizeState_DieFire() { finalizeState_DieFumi(); } +void dEnBoss_c::executeState_DieFire() { executeState_DieFumi(); } + +void dEnBoss_c::initializeState_DieSlide() { initializeState_DieFumi(); } +void dEnBoss_c::finalizeState_DieSlide() { finalizeState_DieFumi(); } +void dEnBoss_c::executeState_DieSlide() { executeState_DieFumi(); } + +void dEnBoss_c::initializeState_DieShell() { initializeState_DieFumi(); } +void dEnBoss_c::finalizeState_DieShell() { finalizeState_DieFumi(); } +void dEnBoss_c::executeState_DieShell() { executeState_DieFumi(); } + +void dEnBoss_c::initializeState_DieStar() { initializeState_DieFumi(); } +void dEnBoss_c::finalizeState_DieStar() { finalizeState_DieFumi(); } +void dEnBoss_c::executeState_DieStar() { executeState_DieFumi(); } + +void dEnBoss_c::initializeState_DieQuake() { initializeState_DieFumi(); } +void dEnBoss_c::finalizeState_DieQuake() { finalizeState_DieFumi(); } +void dEnBoss_c::executeState_DieQuake() { executeState_DieFumi(); } diff --git a/syms.txt b/syms.txt index 62c168ef..9ca2f9af 100644 --- a/syms.txt +++ b/syms.txt @@ -5,6 +5,7 @@ __ct__7mVec3_cFv=0x80015E30 changeState__82sStateMgr_c<13dActorState_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c=0x8001CC90 refreshState__82sStateMgr_c<13dActorState_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv=0x8001CCA0 executeState__82sStateMgr_c<13dActorState_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv=0x8001CCE0 +setBattleReady__9dEnBoss_cFv=0x8001D0F0 finalUpdate__12dBaseActor_cFv=0x8001D1B0 GetActorType__12dBaseActor_cFv=0x8001D1C0 funsuiMoveX__8dActor_cFv=0x8001D1D0 @@ -38,6 +39,7 @@ setGoalDemoList__13daPyDemoMng_cFi=0x8005B780 stopBgmGoalDemo__13daPyDemoMng_cFv=0x8005B810 getPoleBelowPlayer__13daPyDemoMng_cFi=0x8005B840 getControlDemoPlayerNum__13daPyDemoMng_cCFv=0x8005CAD0 +setBossDownPlayerNo__13daPyDemoMng_cFi=0x8005CB60 setCourseOutList__13daPyDemoMng_cFSc=0x8005D050 checkDemoNo__13daPyDemoMng_cFSc=0x8005D090 getNextDemoNo__13daPyDemoMng_cFv=0x8005D0C0 @@ -76,6 +78,7 @@ setHipAttackQuake__9daPyMng_cFiUc=0x80060C10 isCreateBalloon__9daPyMng_cFi=0x80061110 process__18dActorGroupIdMng_cFP13sMapActorDataiUci=0x800661C0 createUpCoin__11dActorMng_cFRC7mVec3_cUcUcUc=0x80066630 +allEnemyDeath__11dActorMng_cFi=0x80066A40 __ct__16dHeapAllocator_cFv=0x80069020 __dt__16dHeapAllocator_cFv=0x80069060 createFrmHeap__16dHeapAllocator_cFUlPQ23EGG4HeapPCcUl=0x800690C0 @@ -447,6 +450,12 @@ __ct__15NMSndObjectBaseFQ215NMSndObjectBase8OBJ_TYPERQ34nw4r3snd18SoundArchivePl __dt__15NMSndObjectBaseFv=0x801974C0 sendRemote__15NMSndObjectBaseFPQ34nw4r3snd11SoundHandleUlUl=0x80197540 vf1C__15NMSndObjectBaseFUli=0x801976B0 +startSound__11SndObjctEmyFUlUl=0x80197790 +holdSound__11SndObjctEmyFUlUl=0x801978E0 +startSound__11SndObjctEmyFUlsUl=0x80197A30 +holdSound__11SndObjctEmyFUlsUl=0x80197BB0 +startSound__11SndObjctEmyFUlRCQ34nw4r4math4VEC2Ul=0x80197D30 +holdSound__11SndObjctEmyFUlRCQ34nw4r4math4VEC2Ul=0x80197E20 startSound__14SndObjctCmnEmyFUlRCQ34nw4r4math4VEC2Ul=0x80198040 startSound__14SndObjctCmnMapFUlRCQ34nw4r4math4VEC2Ul=0x80198D70 startSound__11SndObjctPlyFUlUl=0x8019A0F0