From 4391c61d3d28bd16ab77dfcb972103a5ab56eeef Mon Sep 17 00:00:00 2001 From: user Date: Wed, 6 May 2026 00:09:46 +0200 Subject: [PATCH 1/9] First stab at d_a_en_noko (Koopa Troopa) Still far from complete, but at least it's a start... --- include/game/bases/d_a_en_noko.hpp | 130 ++++ include/game/bases/d_a_en_shell.hpp | 4 +- include/game/bases/d_actor_manager.hpp | 4 + include/game/mLib/m_3d/mdl.hpp | 2 +- slices/d_enemiesNP.json | 10 +- source/d_enemiesNP/bases/d_a_en_noko.cpp | 736 +++++++++++++++++++++++ 6 files changed, 882 insertions(+), 4 deletions(-) create mode 100644 include/game/bases/d_a_en_noko.hpp create mode 100644 source/d_enemiesNP/bases/d_a_en_noko.cpp diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp new file mode 100644 index 00000000..41666f87 --- /dev/null +++ b/include/game/bases/d_a_en_noko.hpp @@ -0,0 +1,130 @@ + +#include + +namespace nw4r { + namespace ef { + struct EmitterInheritSetting { + u16 mSpeed; + u8 mScale; + u8 mAlpha; + u8 mColor; + u8 mWeight; + u8 mType; + u8 mFlag; + u8 mAlphaFuncPri; + u8 mAlphaFuncSec; + u8 mPad[2]; + }; + }; +}; + +namespace mEf { + class levelOneEffect_c : public levelEffect_c { + public: + float mEmissionRateMaybe; + nw4r::ef::EmitterInheritSetting setting; + }; +}; + +class daTagWind_c : public dActor_c { +public: + float m_394; + u8 mPad[32]; +}; + +/** + * @brief Koopa Troopa + * @statetable + * @paramtable + */ +class daEnNoko_c : public daEnShell_c { +public: + daEnNoko_c(); + ~daEnNoko_c(); + + virtual int create() override; + virtual int doDelete() override; + virtual int execute() override; + virtual int preExecute() override; + virtual int draw() override; + virtual void finalUpdate() override; + // virtual bool isSpinLiftUpEnable() override; + // virtual void boyonBegin() override; + virtual bool createIceActor() override; + virtual void beginFunsui() override; + virtual void endFunsui() override; + virtual bool isFunsui() const override; + virtual void YoshiFumiScoreSet(dActor_c *) override; + virtual void initializeState_Wakeup() override; + virtual void executeState_Wakeup() override; + virtual void finalizeState_Wakeup() override; + virtual void initializeState_WakeupTurn() override; + virtual void executeState_WakeupTurn() override; + virtual void finalizeState_WakeupTurn() override; + virtual bool setPlayerDamage(dActor_c *actor) override; + virtual bool checkSleep() override; + virtual void calcShellEffectPos() override; + // virtual bool isFumiInvalid() override; + // virtual void kickEffect() override; + // virtual bool isDieShell() override; + // virtual bool isBlockHitDeath() override; + + virtual void vf300(); + virtual void vf304(u32 * pDir, mAng * pAng); + virtual bool isWalking(); + virtual void vf30C(); + virtual void vf310(); + virtual bool canDance(); + virtual void danceWithMove(int move); + virtual void dance(); + virtual void changeStateAccordingToSettings(); + virtual void vf324(); + virtual void vf328(); + virtual void deleteRest(); + virtual mVec3_c getPos(); + + STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); + STATE_FUNC_DECLARE(daEnNoko_c, Walk); + STATE_FUNC_DECLARE(daEnNoko_c, Turn); + STATE_FUNC_DECLARE(daEnNoko_c, WindTurn); + STATE_FUNC_DECLARE(daEnNoko_c, SpitOut_Ready); + STATE_FUNC_DECLARE(daEnNoko_c, BgmDance); + STATE_FUNC_DECLARE(daEnNoko_c, BgmDanceEd); + + void loadRes(); + void updateAmiLine(); + void setZPos(); + bool isInQuicksand(); + void spawnQuicksandEffects(); + bool sub_80A73330(dActor_c *); + void setBc(); + bool turnProc(); + float getWindMultiplier(); + void setMoveAnimation(char * name, m3d::playMode_e mode, float frame); + void setBaseAnimation(char * name, m3d::playMode_e mode, float frame); + bool sub_80A73BC0(); + void sub_80A73CB0(); + + u8 mPad0[4]; + dHeapAllocator_c mNokoAllocator; + nw4r::g3d::ResFile mNokoResFile; + m3d::mdl_c mNokoModel; + m3d::anmChr_c mMoveAnim; + nw4r::g3d::ResAnmTexPat mNokoResAnmTexPat; + m3d::anmTexPat_c mNokoAnimTex; + u32 mIsFrozen; + s16 m_8a8; + bool mWalksOffLedges; + u8 mPad2[1]; + mVec3_c m_8ac; + float mXSpeedBeforeFrozen; + u8 mPad3[8]; + float m_8c4; + u32 m_8c8; + int mDancesRemaining; + mAng mYRotIncrease; + u8 mPad4[2]; + u32 mDanceMove; + mEf::levelOneEffect_c mQuickSandEffect; + m3d::mdl_c::callback_c mMdlCallback; +}; diff --git a/include/game/bases/d_a_en_shell.hpp b/include/game/bases/d_a_en_shell.hpp index 3c698293..f739217e 100644 --- a/include/game/bases/d_a_en_shell.hpp +++ b/include/game/bases/d_a_en_shell.hpp @@ -98,7 +98,7 @@ class daEnShell_c : public daEnCarry_c { m3d::anmChr_c mAnim; nw4r::g3d::ResAnmTexPat mResAnmTexPat; m3d::anmTexPat_c mAnimTex; - u8 mPad1[0x24]; + sCcDatNewF mCcData; sBcSensorPoint mSensorHead; sBcSensorLine mSensorFootNormal; sBcSensorLine mSensorWall; @@ -106,7 +106,7 @@ class daEnShell_c : public daEnCarry_c { mEf::levelEffect_c mEffect; int mYoshiKickable; ///< Whether the shell can be kicked in any state by Yoshi. int mUseBaseIceBehaviour; - u8 mPad2[0xc]; + mVec3_c m_71c; mVec3_c mCarryPos; int mIsCarryFall; int mSlideAirAfterThrow; diff --git a/include/game/bases/d_actor_manager.hpp b/include/game/bases/d_actor_manager.hpp index b214ee4e..5ae8104b 100644 --- a/include/game/bases/d_actor_manager.hpp +++ b/include/game/bases/d_actor_manager.hpp @@ -4,6 +4,10 @@ class dActorMng_c { public: + u8 mPad1[0x28]; + int mGoombaZOrderThing; + u8 mPad2[0x218]; + void createUpCoin(const mVec3_c &pos, u8 dir, u8 count, u8 layer); static dActorMng_c *m_instance; diff --git a/include/game/mLib/m_3d/mdl.hpp b/include/game/mLib/m_3d/mdl.hpp index fde75b21..b8b2b86b 100644 --- a/include/game/mLib/m_3d/mdl.hpp +++ b/include/game/mLib/m_3d/mdl.hpp @@ -5,7 +5,7 @@ namespace m3d { class mdl_c : public smdl_c { - + public: class callback_c { public: virtual ~callback_c(); diff --git a/slices/d_enemiesNP.json b/slices/d_enemiesNP.json index 195d39c6..b551c46d 100644 --- a/slices/d_enemiesNP.json +++ b/slices/d_enemiesNP.json @@ -2,7 +2,7 @@ "meta": { "fileName": "d_enemiesNP.rel", "type": "REL", - "defaultCompilerFlags": "-sdata 0 -sdata2 0 -proc gekko -fp hard -O4,p -char signed -rtti off -enum int -Cpp_exceptions off -ipa file -enc SJIS", + "defaultCompilerFlags": "-sdata 0 -sdata2 0 -proc gekko -fp hard -O4,p -inline noauto -char signed -rtti off -enum int -Cpp_exceptions off -ipa file -enc SJIS", "moduleNum": 3, "baseAddr": "809A2D90", "sections": { @@ -34,6 +34,14 @@ "memoryRanges": { ".text": "0x0-0x70" } + }, + { + "source": "d_enemiesNP/bases/d_a_en_noko.cpp", + "memoryRanges": { + ".text": "0xc6230-0xd2570", + ".data": "0x28250-0x289d0", + ".bss": "0x7e60-0x80a0" + } } ] } diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp new file mode 100644 index 00000000..eb2cc389 --- /dev/null +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -0,0 +1,736 @@ +#include +#include +#include +#include +#include +#include + +const float buf_80ad34b0[2] = {0.5f, -0.5f}; +const mAng buf_80ad34b8[2] = {0x800, 0xF800}; +const mAng buf_80ad34bc[2] = {0x4000, 0xC000}; +const s16 buf_80ad34f0[2] = {0xEAAB, 0x1555}; +const int buf_80ad34f8[2] = {0, 1}; +const float buf_80ad3500[2] = {-2.0f, -4.0f}; +const float buf_80ad3518[2] = {2.5f, -2.5f}; +const char *buf_80afdd98[3] = { + "BGM_anim_walkA_1", + "BGM_anim_walkA_1", + "BGM_anim_walkA_3", +}; + +STATE_DEFINE(daEnNoko_c, BlockAppear); +STATE_DEFINE(daEnNoko_c, Walk); +STATE_DEFINE(daEnNoko_c, Turn); +STATE_DEFINE(daEnNoko_c, WindTurn); +STATE_DEFINE(daEnNoko_c, SpitOut_Ready); +STATE_DEFINE(daEnNoko_c, BgmDance); +STATE_DEFINE(daEnNoko_c, BgmDanceEd); + +int daEnNoko_c::create() { + mWalksOffLedges = mParam & 1; + loadRes(); + createShell("nokonokoA", "g3d/nokonokoA.brres", "nokonoko_shell", "Tnokonoko_shell", mWalksOffLedges); + mScale.set(1.0f, 1.0f, 1.0f); + mCenterOffs.set(0.0f, 8.0f, 0.0); + mVisibleAreaOffset.set(0.0f, 16.0f); + mVisibleAreaSize.set(28.0f, 32.0f); + mNokoModel.setCallback(&mMdlCallback); + clrComboCnt(); + + u8 dir = getPl_LRflag(mPos); + mDirection = dir; + mAngle.y = buf_80ad34bc[dir]; + mAmiLayer = (mParam >> 16) & 1; + m_8ac = mPos; + mFlags |= dEn_c::EN_FLAG_16; + mPos.z = l_Ami_Zpos[(mParam >> 16) & 1]; + + mNokoAnimTex.setPlayMode(m3d::FORWARD_ONCE, 0); + mNokoModel.setAnm(mNokoAnimTex, 0.0f); + mNokoAnimTex.setFrame(mWalksOffLedges, 0); + mNokoAnimTex.setRate(0.0f, 0); + + mSensorHead.mX = 0; + mSensorHead.mY = 0xC000; + mSensorWall.mLineA = 0x6000; + mSensorWall.mLineA = 0x9000; + mSensorWall.mDistanceFromCenter = 0x6000; + mSensorFootNormal.mLineA = -0x4000; + mSensorFootNormal.mLineB = 0x4000; + mSensorFootNormal.mDistanceFromCenter = 0; + + mCcData.mBase.mOffset.set(0.0f, 8.0f); + mCcData.mBase.mSize.set(9.0f, 8.0f); + mCcData.mKind = CC_KIND_ENEMY; + mCcData.mAttack = CC_ATTACK_NONE; + mCcData.mVsKind = ((1 << CC_KIND_YOSHI) | (1 << CC_KIND_ENEMY) | (1 << CC_KIND_TAMA)); + mCcData.mVsDamage = ~((1 << CC_ATTACK_NONE) | (1 << CC_ATTACK_YOSHI_MOUTH) | (1 << CC_ATTACK_SPIN_LIFT_UP) | (1 << CC_ATTACK_SAND_PILLAR)); + mCcData.mStatus = CC_STATUS_NONE; + mCcData.mCallback = dEn_c::normal_collcheck; + mCc.set(this, &mCcData, l_Ami_Line[mAmiLayer]); + mCc.entry(); + + m_8c4 = dActorMng_c::m_instance->mGoombaZOrderThing * 16.0f; + dActorMng_c::m_instance->mGoombaZOrderThing = (dActorMng_c::m_instance->mGoombaZOrderThing + 1) & 0xF; + + changeStateAccordingToSettings(); + + mBc.set(this, (const sBcSensorBase *) &mSensorFootNormal, (const sBcSensorBase *) &mSensorHead, (const sBcSensorBase *) &mSensorWall); + mBc.m_4c = mPos.x; + + return 1; +} + +void daEnNoko_c::loadRes() { + mNokoAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], nullptr, 0x20); + + mNokoResFile = dResMng_c::m_instance->getRes("nokonokoA", "g3d/nokonokoA.brres"); + nw4r::g3d::ResMdl mdl = mNokoResFile.GetResMdl("nokonokoA"); + mNokoModel.create(mdl, &mNokoAllocator, nw4r::g3d::ScnMdl::BUFFER_RESMATMISC | nw4r::g3d::ScnMdl::BUFFER_RESTEXOBJ | nw4r::g3d::ScnMdl::BUFFER_RESTLUTOBJ, 1, nullptr); + dActor_c::setSoftLight_Enemy(mNokoModel); + nw4r::g3d::ResAnmChr anm = mNokoResFile.GetResAnmChr("walkA"); + mMoveAnim.create(mdl, anm, &mNokoAllocator, nullptr); + mNokoResAnmTexPat = mNokoResFile.GetResAnmTexPat("nokonokoA"); + mNokoAnimTex.create(mdl, mNokoResAnmTexPat, &mNokoAllocator, nullptr, 1); + + vf324(); + mNokoAllocator.adjustFrmHeap(); + + mNokoAnimTex.setAnm(mNokoModel, mNokoResAnmTexPat, 0, m3d::FORWARD_ONCE); +} + +void daEnNoko_c::vf324() { } + +void daEnNoko_c::changeStateAccordingToSettings() { + mDirection = getPl_LRflag(mPos); + if (((mParam >> 4) & 1) == 1) { + mSpeed.y = 0.0f; + changeState(daEnShell_c::StateID_Sleep); + } else if ((mParam >> 0x1C) & 1) { + changeState(daEnNoko_c::StateID_BlockAppear); + } else if ((mParam >> 0x1D) & 1) { + changeState(daEnNoko_c::StateID_SpitOut_Ready); + } else { + changeState(daEnNoko_c::StateID_Walk); + } +} + +int daEnNoko_c::preExecute() { + int res = dEn_c::preExecute(); + if (res == 0) { + return 0; + } + + if (canDance()) { + if (dAudio::isBgmAccentSign(2)) { + danceWithMove(0); + } else if (dAudio::isBgmAccentSign(2)) { + danceWithMove(1); + } else if (dAudio::isBgmAccentSign(8)) { + danceWithMove(2); + } + } + + return 1; +} + +int daEnNoko_c::execute() { + mStateMgr.executeState(); + + if (cullCheck()) { + return 1; + } + + if (isState(StateID_BgmDance)) { + m_8a8 = 0; + } else { + dance(); + } + + if (!mNoRespawn && !isState(StateID_Ice)) { + updateAmiLine(); + setZPos(); + if (isInQuicksand()) { + spawnQuicksandEffects(); + } + } + + return 1; +} + +int daEnNoko_c::draw() { + if (!mUseBaseIceBehaviour) { + return daEnShell_c::drawShell(); + } + + if (isState(StateID_Wakeup)) { + daEnShell_c::drawShell(); + } + + mNokoModel.entry(); + return 1; +} + +int daEnNoko_c::doDelete() { + if (mNokoAllocator.mpHeap != mAllocatorDummyHeap_c::getInstance()) { + mMoveAnim.remove(); + mNokoModel.remove(); + mNokoAnimTex.remove(); + deleteRest(); + } + + return 1; +} + +void daEnNoko_c::deleteRest() { } + +bool daEnNoko_c::isInQuicksand() { + if (mBc.isFoot()) { + mVec3_c pos = getCenterPos(); + u32 type = dBc_c::getUnitType(pos.x, pos.y, mLayer); + u8 subkind = dBc_c::getUnitKind(pos.x, pos.y, mLayer) >> 16; + + if ((type & 0x8000) && (subkind == 3)) { + return true; + } + } + + return false; +} + +void daEnNoko_c::spawnQuicksandEffects() { + mVec3_c pos = getCenterPos(); + mQuickSandEffect.createEffect("Wm_en_quicksand", 0, &pos, nullptr, nullptr); +} + +bool daEnNoko_c::canDance() { + if (isState(StateID_Walk) || isState(StateID_Turn) || isState(StateID_WindTurn) || isState(StateID_BgmDance) || isState(StateID_BgmDanceEd)) { + return true; + } + + return false; +} + +void daEnNoko_c::danceWithMove(int move) { + mDanceMove = move; + changeState(StateID_BgmDance); +} + +void daEnNoko_c::vf310() { + calcShellMdl(); + mVec3_c pos = getPos(); + mAng3_c angle = mAngle; + dActor_c::changePosAngle(&pos, &angle, 1); + PSMTXTrans(mMatrix, pos.x, pos.y, pos.z); + mMatrix.ZXYrotM(angle.x, angle.y, angle.z); + mNokoModel.setLocalMtx(&mMatrix); + mVec3_c boyo_scale = mBoyoMng.mScale; + mNokoModel.setScale(boyo_scale); + mNokoModel.calc(false); +} + +mVec3_c daEnNoko_c::getPos() { + return mPos; +} + +void daEnNoko_c::calcShellEffectPos() { + m3d::mdl_c * model = &mModel; + nw4r::g3d::ResMdl resMdl = model->getResMdl(); + nw4r::g3d::ResNode resNode = resMdl.GetResNode("nokonoko_shell_model"); + + ulong idx = 0; + if (resNode.IsValid()) { + idx = resNode.GetID(); + } + mMtx_c matrix; + + model->getNodeWorldMtx(idx, &matrix); + matrix.multVecZero(m_71c); + if (mIsFlipped) { + m_71c.y -= 16.0f; + } +} + +bool daEnNoko_c::setPlayerDamage(dActor_c *ac_player) { + daPlBase_c * player = (daPlBase_c *)ac_player; + bool ok = player->setDamage(this, daPlBase_c::DAMAGE_DEFAULT); + + if (ok && isWalking()) { + sub_80A73330(ac_player); + return true; + } + + return false; +} + +bool daEnNoko_c::isWalking() { + return true; +} + +bool daEnNoko_c::sub_80A73330(dActor_c *actor) { + bool x = dActor_c::getTrgToSrcDir_Main(actor->mPos.x + actor->mCenterOffs.x, mPos.x + mCenterOffs.x); + + if ((mDirection == x) || ((mUseBaseIceBehaviour & 0xFF) == 0)) { + return false; + } + + mDirection = x; + mAngle.y = buf_80ad34bc[x]; + m_8a8 = -m_8a8; + vf30C(); + + return true; +} + +void daEnNoko_c::setBc() { + mSensorHead.mBase.mFlags = SENSOR_IS_POINT; + mSensorHead.mX = 0; + mSensorHead.mY = 0xc000; + mSensorWall.mBase.mFlags = SENSOR_IS_LINE; + mSensorWall.mLineA = 0x6000; + mSensorWall.mLineB = 0x9000; + mSensorWall.mDistanceFromCenter = 0x6000; + mSensorFootNormal.mBase.mFlags = SENSOR_IS_LINE; + mSensorFootNormal.mLineA = -0x4000; + mSensorFootNormal.mLineB = 0x4000; + mSensorFootNormal.mDistanceFromCenter = 0; + mBc.set(this, (const sBcSensorBase *) &mSensorFootNormal, (const sBcSensorBase *) &mSensorHead, (const sBcSensorBase *) &mSensorWall); +} + +void daEnNoko_c::vf30C() { + if (isState(StateID_Turn)) { + changeState(StateID_Walk); + } else { + mSpeed.x = -mSpeed.x; + } +} + +bool daEnNoko_c::turnProc() { + mAng turnAng; + u32 turnDir; + + vf304(&turnDir, &turnAng); + mAngle.y += turnAng; + + int z = ((mAng *)buf_80ad34bc)[turnDir]; + int x = abs(z); + int y = abs(mAngle.y); + + if (y >= x) { + mAngle.y = z; + return true; + } + + return false; +} + +void daEnNoko_c::vf304(u32 * pDir, mAng * pAng) { + u32 x = mDirection; + *pDir = x; + *pAng = buf_80ad34b8[x]; +} + +void daEnNoko_c::setZPos() { + if (mLayer == 0) { + mPos.z = m_8c4 + l_Ami_Zpos[mAmiLayer]; + } else { + mPos.z = -2500.0f; + } +} + +void daEnNoko_c::updateAmiLine() { + float f1 = mCc.mCcData.mBase.mSize.x; + float f2 = mCc.mCcData.mBase.mOffset.x; + float f3 = mPos.x; + float f4 = f3 + f2; + + float f5 = mCc.mCcData.mBase.mOffset.y; + float f6 = mPos.y; + float f7 = f6 + f5; + + u32 u1 = dBc_c::getUnitType(f4 + f1, f7, mLayer); + u32 u2 = dBc_c::getUnitKind(f4 + f1, f7, mLayer) & 0xFF; + u32 u3 = dBc_c::getUnitType(f4 - f1, f7, mLayer); + u32 u4 = dBc_c::getUnitKind(f4 - f1, f7, mLayer) & 0xFF; + + if ((((u1 & 1024) == 0) || (u2 < 2)) && (((u3 & 1024) == 0) || (u4 < 2))) { + goto e8; + } else if (!mAmiLayer) { + mCc.mAmiLine = 1; + goto ret; + } else { + mCc.mAmiLine = 2; + goto ret; + } + { + e8: + mCc.mAmiLine = 3; + } +ret: + return; +} + +void daEnNoko_c::dance() { + sLib::chaseAngle(&m_8a8, buf_80ad34f0[mDirection], 0x400); +} + +bool daEnNoko_c::createIceActor() { + float f_60; + mVec3_c f_5c; + int ice_mode; + + if (*mStateMgr.getMainStateID() == StateID_BgmDance) { + f_5c.set(mPos.x, mPos.y - 4.0f, mPos.z + 2.0f); + f_60 = 1.75f; + ice_mode = 1; + } else { + int x = mUseBaseIceBehaviour; + f_5c.set(mPos.x, mPos.y + buf_80ad3500[x], mPos.z); + f_60 = 1.05f; + ice_mode = buf_80ad34f8[x]; + } + + dIceInfo iceInfo[] = { + { + ice_mode, + f_5c, + mVec3_c(1.0f, 1.0f, f_60) + } + }; + + return mIceMng.createIce(iceInfo, ARRAY_SIZE(iceInfo)); +} + +bool daEnNoko_c::checkSleep() { + if (((mParam >> 4) & 1) == 1) { + return false; + } + + return daEnShell_c::checkSleep(); +} + +void daEnNoko_c::beginFunsui() { + if (isState(StateID_Carry) || isState(StateID_Ice)) { + return; + } + + mIsFrozen = 1; + mXSpeedBeforeFrozen = mSpeed.x; + mSpeed.set(0.0f, 0.0f, 0.0f); + + if (mUseBaseIceBehaviour == 0) { + changeState(StateID_Sleep); + } else { + mMoveAnim.setRate(2.0f); + } +} + +void daEnNoko_c::endFunsui() { + + mIsFrozen = 0; + + if (mUseBaseIceBehaviour != 0) { + mMoveAnim.setRate(1.0f); + mSpeed.x = mXSpeedBeforeFrozen; + } +} + +float daEnNoko_c::getWindMultiplier() { + daTagWind_c *ac_wind = (daTagWind_c *)fManager_c::searchBaseByProfName(fProfile::TAG_WIND, nullptr); + + if (ac_wind == nullptr) { + return 0.0f; + } + + return ac_wind->m_394; +} + +void daEnNoko_c::setMoveAnimation(char * name, m3d::playMode_e mode, float frame) { + mMoveAnim.setAnm(mNokoModel, mNokoResFile.GetResAnmChr(name), mode); + mNokoModel.setAnm(mMoveAnim, frame); +} + +void daEnNoko_c::setBaseAnimation(char * name, m3d::playMode_e mode, float frame) { + mAnim.setAnm(mModel, mResFile.GetResAnmChr(name), mode); + mModel.setAnm(mAnim, frame); +} + +bool daEnNoko_c::sub_80A73BC0() { + float fVar1 = mPos.y; + mVec3_c local_14 = mVec3_c(mPos.x + buf_80ad3518[mDirection], fVar1 + 4.0f, mPos.z); + u32 uVar2 = dBc_c::getUnitKind(local_14.x, fVar1 - 2.0f, mLayer); + + if (((uVar2 >> 0x10) & 0xff) == 8) { + return false; + } + + float local_18 = 0.0f; + u32 temp = dBc_c::checkGround(&local_14, &local_18, mLayer, 1, -1); + if ((temp == 0) || !(local_14.y < local_18) || (local_18 > mPos.y - 5.0f)) { + return true; + } + + return false; +} + +void daEnNoko_c::sub_80A73CB0() { + mVec3_c pos = mVec3_c(mPos.x, mPos.y, 5500.0f); + + if (mBc.getFootAttr() == 12) { + mEf::createEffect("Wm_en_sndlandsmk_s", 0, &pos, nullptr, nullptr); + } else { + mEf::createEffect("Wm_en_landsmoke_s", 0, &pos, nullptr, nullptr); + } +} + +void daEnNoko_c::initializeState_Walk() { + if ((*mStateMgr.getOldStateID() != StateID_Turn) && (*mStateMgr.getOldStateID() != StateID_Walk) && (*mStateMgr.getOldStateID() != StateID_WindTurn) && (*mStateMgr.getOldStateID() != StateID_WakeupTurn)) { + setMoveAnimation("walkA", m3d::FORWARD_LOOP, 1.0f); + } + + float f = buf_80ad34b0[mDirection]; + mUseBaseIceBehaviour = 1; + mAccelY = -0.1875f; + mAccelF = 0.05f; + mSpeedMax.x = f; + mSpeedMax.y = -4.0f; + mSpeedMax.z = 0.0f; + mSensorFootNormal.mBase.mFlags = SENSOR_IS_LINE; + mSensorFootNormal.mLineA = -0x4000; + mSensorFootNormal.mLineB = 0x4000; + mSensorFootNormal.mDistanceFromCenter = 0; + mSpeed.x = f; + m_8c8 = 0; +} + +void daEnNoko_c::finalizeState_Walk() {} + +void daEnNoko_c::executeState_Walk() { + mNokoModel.play(); + float wind = getWindMultiplier(); + + if (std::fabs(wind) > 0.475f) { + if (((float)(int)buf_80ad34b0[mDirection]) * wind >= 0.0f) { + changeState(StateID_WindTurn); + return; + } else { + mSpeedMax.x = 0.0f; + } + } else { + mSpeedMax.x = buf_80ad34b0[mDirection]; + } + + calcSpeedX(); + calcSpeedY(); + posMove(); + u32 foot = mBc.isFoot(); + EnBgCheck(); + if (mBc.isFoot()) { + mSpeed.y = 0.0f; + if ((mWalksOffLedges == true) && (!sub_80A73BC0())) { + changeState(StateID_Turn); + } + } else if (foot && !mInLiquid && (mSpeed.y <= 0.0f)) { + mFootPush2.x += m_1eb.x; + } + + if (mBc.mFlags & (0x15 << mDirection)) { + changeState(StateID_Turn); + } +} + +void daEnNoko_c::initializeState_Wakeup() { + setMoveAnimation("revival", m3d::FORWARD_ONCE, 0.0f); + setBaseAnimation("revival_shell", m3d::FORWARD_ONCE, 0.0f); + mUseBaseIceBehaviour = 1; + + daEnShell_c::initializeState_Wakeup(); +} + +void daEnNoko_c::finalizeState_Wakeup() { + mAnim.setFrame(0.0f); + mCc.mCcData.mBase.mOffset.x = 0.0f; + mCc.mCcData.mBase.mSize.x = 8.0f; +} + +void daEnNoko_c::executeState_Wakeup() { + mNokoModel.play(); + mModel.play(); + calcSpeedY(); + posMove(); + + u32 x = EnBgCheck(); + if (x & 1) { + mSpeed.y = 0.0f; + } + if (x & 4) { + mSpeed.x = 0.0f; + } + + if (mMoveAnim.isStop()) { + changeState(StateID_WakeupTurn); + } +} + +void daEnNoko_c::initializeState_WakeupTurn() { + setMoveAnimation("walkA", m3d::FORWARD_LOOP, 1.0f); + daEnShell_c::initializeState_WakeupTurn(); +} + +void daEnNoko_c::finalizeState_WakeupTurn() { + daEnShell_c::finalizeState_WakeupTurn(); +} + +void daEnNoko_c::executeState_WakeupTurn() { + mNokoModel.play(); + daEnShell_c::executeState_WakeupTurn(); +} + +void daEnNoko_c::initializeState_Turn() { + mDirection ^= 1; + mSpeed.x = 0.0f; + mSpeedMax.set(0.0f, -4.0f, 0.0f); +} + +void daEnNoko_c::finalizeState_Turn() {} + +void daEnNoko_c::executeState_Turn() { + mNokoModel.play(); + calcSpeedY(); + posMove(); + u32 x = EnBgCheck(); + if (x & 1) { + mSpeed.y = 0.0f; + } + + WaterCheck(mPos, 1.0f); + + if (turnProc()) { + changeState(StateID_Walk); + } +} + +void daEnNoko_c::initializeState_WindTurn() { + mDirection ^= 1; + mSpeed.x = 0.0f; + mSpeedMax.set(0.0f, -4.0f, 0.0f); +} + +void daEnNoko_c::finalizeState_WindTurn() {} + +void daEnNoko_c::executeState_WindTurn() { + mNokoModel.play(); + calcSpeedY(); + posMove(); + u32 x = EnBgCheck(); + if (x & 1) { + mSpeed.y = 0.0f; + } + + turnProc(); + + if (std::fabs(getWindMultiplier()) < 0.25f) { + changeState(StateID_Turn); + } +} + +void daEnNoko_c::initializeState_BlockAppear() { + setMoveAnimation("walkA", m3d::FORWARD_LOOP, 1.0f); + mTimer1 = 40; + mCc.release(); +} + +void daEnNoko_c::finalizeState_BlockAppear() { + mCc.entry(); +} + +void daEnNoko_c::executeState_BlockAppear() { + if (mTimer1 == 0) { + changeState(StateID_Walk); + } +} + +void daEnNoko_c::initializeState_SpitOut_Ready() { + mNoHitPlayer.mTimer[(mParam >> 24) & 3] = 16; +} + +void daEnNoko_c::finalizeState_SpitOut_Ready() { } + +void daEnNoko_c::executeState_SpitOut_Ready() { + if (mEatenByID == BASE_ID_NULL) { + return; + } + + dActor_c *player = (dActor_c *)fManager_c::searchBaseByID(mEatenByID); + if (player == nullptr) { + deleteRequest(); + } else { + setSlideThrowSpeed(player); + mPlayerNo = getPlrNo(); + changeState(StateID_Slide); + } +} + +void daEnNoko_c::initializeState_BgmDance() { + setMoveAnimation((char *)buf_80afdd98[mDanceMove], m3d::FORWARD_ONCE, 3.0f); + mSpeed.x = 0.0; + mDancesRemaining = 3; + mYRotIncrease = (u16)(abs((int)mAngle.y) / (int)mDancesRemaining); +} + +void daEnNoko_c::finalizeState_BgmDance() {} + +void daEnNoko_c::executeState_BgmDance() { + mNokoModel.play(); + calcSpeedY(); + posMove(); + + u32 x = EnBgCheck(); + if (x & 1) { + mSpeed.y = 0.0f; + } + + if (mDancesRemaining > 0) { + mDancesRemaining--; + sLib::chaseAngle((s16*)&mAngle.y, 0, mYRotIncrease); + } else { + mAngle.y = 0; + } + + if (mMoveAnim.isStop()) { + changeState(StateID_BgmDance); + } +} + +void daEnNoko_c::initializeState_BgmDanceEd() { + setMoveAnimation("walkA", m3d::FORWARD_ONCE, 4.0f); + mAng x = buf_80ad34bc[mDirection]; + mSpeed.x = 0.0f; + mDancesRemaining = 4; + mYRotIncrease = abs(x) / mDancesRemaining; +} + +void daEnNoko_c::finalizeState_BgmDanceEd() {} + +void daEnNoko_c::executeState_BgmDanceEd() { + mNokoModel.play(); + calcSpeedY(); + posMove(); + u32 x = EnBgCheck(); + if (x & 1) { + mSpeed.y = 0.0; + } + + if (mDancesRemaining > 0) { + mAng y = buf_80ad34bc[mDirection]; + mDancesRemaining--; + sLib::chaseAngle((s16*)&mAngle.y, y, mYRotIncrease); + + if (mDancesRemaining > 0) { + return; + } + + mAngle.y = buf_80ad34bc[mDirection]; + changeState(StateID_Walk); + } +} From 4192df8bb6f9123518e289e7030723e6d2338928 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 08:25:16 +0200 Subject: [PATCH 2/9] Mostly down to regswaps and function / data order --- include/game/bases/d_a_en_noko.hpp | 73 +++++++----- include/game/bases/d_bc.hpp | 24 ++-- include/game/bases/d_enemy.hpp | 2 +- include/game/mLib/m_3d/mdl.hpp | 8 +- include/lib/nw4r/g3d/g3d_calcworld.h | 7 ++ include/lib/nw4r/g3d/res/g3d_resnode.h | 10 ++ slices/d_enemiesNP.json | 3 +- source/d_enemiesNP/bases/d_a_en_noko.cpp | 138 ++++++++++++----------- source/dol/bases/d_a_en_shell.cpp | 30 ++--- syms.txt | 2 +- 10 files changed, 171 insertions(+), 126 deletions(-) diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp index 41666f87..ac9cb0e4 100644 --- a/include/game/bases/d_a_en_noko.hpp +++ b/include/game/bases/d_a_en_noko.hpp @@ -1,5 +1,5 @@ - #include +#include namespace nw4r { namespace ef { @@ -21,6 +21,8 @@ namespace nw4r { namespace mEf { class levelOneEffect_c : public levelEffect_c { public: + levelOneEffect_c() { reset(); } + float mEmissionRateMaybe; nw4r::ef::EmitterInheritSetting setting; }; @@ -39,37 +41,59 @@ class daTagWind_c : public dActor_c { */ class daEnNoko_c : public daEnShell_c { public: - daEnNoko_c(); - ~daEnNoko_c(); + class nodeCallback_c : public m3d::mdl_c::callback_c { + public: + virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl) { + mMtx_c mtx; + if (strcmp(resMdl.GetResNode(nodeId).GetName(), "head") == 0) { + manip->GetMatrix(&mtx); + mtx.XrotM(mpOwner->m_8a8); + manip->SetMatrix(mtx); + } + } + + daEnNoko_c *mpOwner; + }; + + daEnNoko_c() { mMdlCallback.mpOwner = this; } + ~daEnNoko_c() {} virtual int create() override; virtual int doDelete() override; virtual int execute() override; virtual int preExecute() override; virtual int draw() override; - virtual void finalUpdate() override; - // virtual bool isSpinLiftUpEnable() override; - // virtual void boyonBegin() override; + virtual void finalUpdate() override { vf310(); } virtual bool createIceActor() override; virtual void beginFunsui() override; virtual void endFunsui() override; - virtual bool isFunsui() const override; + virtual BOOL isFunsui() const override { return mIsFrozen; } virtual void YoshiFumiScoreSet(dActor_c *) override; - virtual void initializeState_Wakeup() override; - virtual void executeState_Wakeup() override; - virtual void finalizeState_Wakeup() override; - virtual void initializeState_WakeupTurn() override; - virtual void executeState_WakeupTurn() override; - virtual void finalizeState_WakeupTurn() override; + + STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); + STATE_FUNC_DECLARE(daEnNoko_c, Walk); + STATE_FUNC_DECLARE(daEnNoko_c, Turn); + STATE_FUNC_DECLARE(daEnNoko_c, WindTurn); + STATE_FUNC_DECLARE(daEnNoko_c, SpitOut_Ready); + STATE_FUNC_DECLARE(daEnNoko_c, BgmDance); + STATE_FUNC_DECLARE(daEnNoko_c, BgmDanceEd); + STATE_VIRTUAL_FUNC_DECLARE(daEnNoko_c, Wakeup); + STATE_VIRTUAL_FUNC_DECLARE(daEnNoko_c, WakeupTurn); + virtual bool setPlayerDamage(dActor_c *actor) override; virtual bool checkSleep() override; virtual void calcShellEffectPos() override; - // virtual bool isFumiInvalid() override; - // virtual void kickEffect() override; - // virtual bool isDieShell() override; - // virtual bool isBlockHitDeath() override; + virtual void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } + virtual void setAfterSleepState() override { changeState(StateID_Walk); } + virtual void slideEffect() override { + if (!mWalksOffLedges) { + mEffect.createEffect("Wm_en_shellgreentail", 0, &m_71c, nullptr, nullptr); + } else { + mEffect.createEffect("Wm_en_shellredtail", 0, &m_71c, nullptr, nullptr); + } + } - virtual void vf300(); + virtual void vf300() { WaterCheck(mPos, 1.0f); } virtual void vf304(u32 * pDir, mAng * pAng); virtual bool isWalking(); virtual void vf30C(); @@ -79,18 +103,10 @@ class daEnNoko_c : public daEnShell_c { virtual void dance(); virtual void changeStateAccordingToSettings(); virtual void vf324(); - virtual void vf328(); + virtual void vf328() {} virtual void deleteRest(); virtual mVec3_c getPos(); - STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); - STATE_FUNC_DECLARE(daEnNoko_c, Walk); - STATE_FUNC_DECLARE(daEnNoko_c, Turn); - STATE_FUNC_DECLARE(daEnNoko_c, WindTurn); - STATE_FUNC_DECLARE(daEnNoko_c, SpitOut_Ready); - STATE_FUNC_DECLARE(daEnNoko_c, BgmDance); - STATE_FUNC_DECLARE(daEnNoko_c, BgmDanceEd); - void loadRes(); void updateAmiLine(); void setZPos(); @@ -115,7 +131,6 @@ class daEnNoko_c : public daEnShell_c { u32 mIsFrozen; s16 m_8a8; bool mWalksOffLedges; - u8 mPad2[1]; mVec3_c m_8ac; float mXSpeedBeforeFrozen; u8 mPad3[8]; @@ -126,5 +141,5 @@ class daEnNoko_c : public daEnShell_c { u8 mPad4[2]; u32 mDanceMove; mEf::levelOneEffect_c mQuickSandEffect; - m3d::mdl_c::callback_c mMdlCallback; + nodeCallback_c mMdlCallback; }; diff --git a/include/game/bases/d_bc.hpp b/include/game/bases/d_bc.hpp index 23ee65bc..95c655ea 100644 --- a/include/game/bases/d_bc.hpp +++ b/include/game/bases/d_bc.hpp @@ -7,23 +7,21 @@ enum SensorFlags { SENSOR_IS_LINE = 1 }; -struct sBcSensorBase { - u32 mFlags; -}; +class sBcSensorIf_c {}; /// @unofficial struct sBcSensorPoint { - operator const sBcSensorBase *() const { return &mBase; } + operator const sBcSensorIf_c *() const { return (const sBcSensorIf_c *) this; } - sBcSensorBase mBase; + u32 mFlags; int mX, mY; }; /// @unofficial struct sBcSensorLine { - operator const sBcSensorBase *() const { return &mBase; } + operator const sBcSensorIf_c *() const { return (const sBcSensorIf_c *) this; } - sBcSensorBase mBase; + u32 mFlags; int mLineA, mLineB; int mDistanceFromCenter; }; @@ -31,7 +29,7 @@ struct sBcSensorLine { /// @unofficial class sBcPointData { public: - operator const sBcSensorBase *() const { return (sBcSensorBase *) &mFlags; } + operator const sBcSensorIf_c *() const { return (sBcSensorIf_c *) &mFlags; } u32 mFlags; long mInfMargin; @@ -127,7 +125,7 @@ class dBc_c { virtual ~dBc_c(); void init(); - void set(dActor_c *, const sBcSensorBase *, const sBcSensorBase *, const sBcSensorBase *); ///< @unofficial + void set(dActor_c *, const sBcSensorIf_c *, const sBcSensorIf_c *, const sBcSensorIf_c *); ///< @unofficial void checkLink(); bool checkRide(); @@ -168,14 +166,16 @@ class dBc_c { u32 isWallR() { return mFlags & FLAG_WALL_R; } 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; } u32 isHead() { return mFlags & FLAG_HEAD; } u32 isCollision() { return mFlags & (FLAG_WALL_L | FLAG_WALL_R | FLAG_FOOT | FLAG_HEAD); } dActor_c *mpOwner; - sBcSensorBase *mpSensorFoot; - sBcSensorBase *mpSensorHead; - sBcSensorBase *mpSensorWall; + sBcSensorIf_c *mpSensorFoot; + sBcSensorIf_c *mpSensorHead; + sBcSensorIf_c *mpSensorWall; mVec3_c *mpOwnerPos; mVec3_c *mpOwnerLastPos; mVec3_c *mpOwnerSpeed; diff --git a/include/game/bases/d_enemy.hpp b/include/game/bases/d_enemy.hpp index 5ec20278..fdb30668 100644 --- a/include/game/bases/d_enemy.hpp +++ b/include/game/bases/d_enemy.hpp @@ -199,7 +199,7 @@ class dEn_c : public dActorMultiState_c { virtual void beginFunsui(); virtual void endFunsui(); - virtual bool isFunsui() const; + virtual BOOL isFunsui() const; virtual bool checkComboClap(int max); diff --git a/include/game/mLib/m_3d/mdl.hpp b/include/game/mLib/m_3d/mdl.hpp index b8b2b86b..4500fab0 100644 --- a/include/game/mLib/m_3d/mdl.hpp +++ b/include/game/mLib/m_3d/mdl.hpp @@ -8,10 +8,10 @@ namespace m3d { public: class callback_c { public: - virtual ~callback_c(); - virtual void timingA(ulong nodeId, nw4r::g3d::ChrAnmResult *anmRes, nw4r::g3d::ResMdl resMdl); - virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl); - virtual void timingC(nw4r::math::MTX34 *mtx, nw4r::g3d::ResMdl resMdl); + virtual ~callback_c() {} + virtual void timingA(ulong nodeId, nw4r::g3d::ChrAnmResult *anmRes, nw4r::g3d::ResMdl resMdl) {} + virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl) {} + virtual void timingC(nw4r::math::MTX34 *mtx, nw4r::g3d::ResMdl resMdl) {} }; class mdlCallback_c { diff --git a/include/lib/nw4r/g3d/g3d_calcworld.h b/include/lib/nw4r/g3d/g3d_calcworld.h index 9e8bbbd7..9616683f 100644 --- a/include/lib/nw4r/g3d/g3d_calcworld.h +++ b/include/lib/nw4r/g3d/g3d_calcworld.h @@ -61,6 +61,13 @@ class WorldMtxManip { WorldMtxManip(math::MTX34* pM, math::VEC3* pS, ulong* pWMAttr) : mpM(pM), mpS(pS), mpWMAttr(pWMAttr) {} + void GetMatrix(math::MTX34 *dst) const { + if (dst) { + PSMTXCopy(*mpM, *dst); + } + } + void SetMatrix(const math::MTX34 &mtx) { PSMTXCopy(mtx, *mpM); } + private: math::MTX34* mpM; // at 0x0 math::VEC3* mpS; // at 0x4 diff --git a/include/lib/nw4r/g3d/res/g3d_resnode.h b/include/lib/nw4r/g3d/res/g3d_resnode.h index 0827c6e7..027af7d1 100644 --- a/include/lib/nw4r/g3d/res/g3d_resnode.h +++ b/include/lib/nw4r/g3d/res/g3d_resnode.h @@ -95,6 +95,16 @@ class ResNode : public ResCommon, public ResNodeDataTypedef { return ResName(NULL); } + const char *GetName() const { + const ResNodeData& r = ref(); + + if (r.name != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.name).GetName(); + } + + return nullptr; + } + ulong GetID() const { if (IsValid()) { return ptr()->id; diff --git a/slices/d_enemiesNP.json b/slices/d_enemiesNP.json index b551c46d..369923bf 100644 --- a/slices/d_enemiesNP.json +++ b/slices/d_enemiesNP.json @@ -37,8 +37,9 @@ }, { "source": "d_enemiesNP/bases/d_a_en_noko.cpp", + "nonMatching": true, "memoryRanges": { - ".text": "0xc6230-0xd2570", + ".text": "0xcf710-0xd2930", ".data": "0x28250-0x289d0", ".bss": "0x7e60-0x80a0" } diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp index eb2cc389..927fa454 100644 --- a/source/d_enemiesNP/bases/d_a_en_noko.cpp +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -6,16 +6,26 @@ #include const float buf_80ad34b0[2] = {0.5f, -0.5f}; -const mAng buf_80ad34b8[2] = {0x800, 0xF800}; -const mAng buf_80ad34bc[2] = {0x4000, 0xC000}; -const s16 buf_80ad34f0[2] = {0xEAAB, 0x1555}; +const s16 buf_80ad34b8[2] = {0x800, -0x800}; +const s16 buf_80ad34bc[2] = {0x4000, -0x4000}; +const s16 buf_80ad34f0[2] = {-0x1555, 0x1555}; const int buf_80ad34f8[2] = {0, 1}; const float buf_80ad3500[2] = {-2.0f, -4.0f}; const float buf_80ad3518[2] = {2.5f, -2.5f}; -const char *buf_80afdd98[3] = { - "BGM_anim_walkA_1", - "BGM_anim_walkA_1", - "BGM_anim_walkA_3", + +const sBcSensorPoint smc_noko_head = { SENSOR_IS_POINT, 0, 0xc000 }; +const sBcSensorLine smc_noko_foot = { SENSOR_IS_LINE, -0x4000, 0x4000, 0x0 }; +const sBcSensorLine smc_noko_wall = { SENSOR_IS_LINE, 0x6000, 0x9000, 0x6000 }; +const sCcDatNewF ccData = { + 0.0f, 8.0f, + 9.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_ENEMY) | BIT_FLAG(CC_KIND_TAMA), + (u32) ~BIT_FLAG(CC_ATTACK_NONE) & ~BIT_FLAG(CC_ATTACK_YOSHI_MOUTH) & ~BIT_FLAG(CC_ATTACK_SPIN_LIFT_UP) & ~BIT_FLAG(CC_ATTACK_SAND_PILLAR), + CC_STATUS_NONE, + dEn_c::normal_collcheck }; STATE_DEFINE(daEnNoko_c, BlockAppear); @@ -25,6 +35,10 @@ STATE_DEFINE(daEnNoko_c, WindTurn); STATE_DEFINE(daEnNoko_c, SpitOut_Ready); STATE_DEFINE(daEnNoko_c, BgmDance); STATE_DEFINE(daEnNoko_c, BgmDanceEd); +STATE_VIRTUAL_DEFINE(daEnNoko_c, Wakeup); +STATE_VIRTUAL_DEFINE(daEnNoko_c, WakeupTurn); + +ACTOR_PROFILE(EN_NOKONOKO, daEnNoko_c, 0x0); int daEnNoko_c::create() { mWalksOffLedges = mParam & 1; @@ -39,8 +53,8 @@ int daEnNoko_c::create() { u8 dir = getPl_LRflag(mPos); mDirection = dir; - mAngle.y = buf_80ad34bc[dir]; mAmiLayer = (mParam >> 16) & 1; + mAngle.y = buf_80ad34bc[dir]; m_8ac = mPos; mFlags |= dEn_c::EN_FLAG_16; mPos.z = l_Ami_Zpos[(mParam >> 16) & 1]; @@ -50,23 +64,18 @@ int daEnNoko_c::create() { mNokoAnimTex.setFrame(mWalksOffLedges, 0); mNokoAnimTex.setRate(0.0f, 0); - mSensorHead.mX = 0; - mSensorHead.mY = 0xC000; - mSensorWall.mLineA = 0x6000; - mSensorWall.mLineA = 0x9000; - mSensorWall.mDistanceFromCenter = 0x6000; - mSensorFootNormal.mLineA = -0x4000; - mSensorFootNormal.mLineB = 0x4000; - mSensorFootNormal.mDistanceFromCenter = 0; - - mCcData.mBase.mOffset.set(0.0f, 8.0f); - mCcData.mBase.mSize.set(9.0f, 8.0f); - mCcData.mKind = CC_KIND_ENEMY; - mCcData.mAttack = CC_ATTACK_NONE; - mCcData.mVsKind = ((1 << CC_KIND_YOSHI) | (1 << CC_KIND_ENEMY) | (1 << CC_KIND_TAMA)); - mCcData.mVsDamage = ~((1 << CC_ATTACK_NONE) | (1 << CC_ATTACK_YOSHI_MOUTH) | (1 << CC_ATTACK_SPIN_LIFT_UP) | (1 << CC_ATTACK_SAND_PILLAR)); - mCcData.mStatus = CC_STATUS_NONE; - mCcData.mCallback = dEn_c::normal_collcheck; + mSensorHead = smc_noko_head; + mSensorWall = smc_noko_wall; + mSensorFootNormal = smc_noko_foot; + + mCcData.mBase.mOffset = ccData.mBase.mOffset; + mCcData.mBase.mSize = ccData.mBase.mSize; + mCcData.mKind = ccData.mKind; + mCcData.mAttack = ccData.mAttack; + mCcData.mVsKind = ccData.mVsKind; + mCcData.mVsDamage = ccData.mVsDamage; + mCcData.mStatus = ccData.mStatus; + mCcData.mCallback = ccData.mCallback; mCc.set(this, &mCcData, l_Ami_Line[mAmiLayer]); mCc.entry(); @@ -75,7 +84,7 @@ int daEnNoko_c::create() { changeStateAccordingToSettings(); - mBc.set(this, (const sBcSensorBase *) &mSensorFootNormal, (const sBcSensorBase *) &mSensorHead, (const sBcSensorBase *) &mSensorWall); + mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); mBc.m_4c = mPos.x; return 1; @@ -85,9 +94,11 @@ void daEnNoko_c::loadRes() { mNokoAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], nullptr, 0x20); mNokoResFile = dResMng_c::m_instance->getRes("nokonokoA", "g3d/nokonokoA.brres"); + nw4r::g3d::ResMdl mdl = mNokoResFile.GetResMdl("nokonokoA"); mNokoModel.create(mdl, &mNokoAllocator, nw4r::g3d::ScnMdl::BUFFER_RESMATMISC | nw4r::g3d::ScnMdl::BUFFER_RESTEXOBJ | nw4r::g3d::ScnMdl::BUFFER_RESTLUTOBJ, 1, nullptr); dActor_c::setSoftLight_Enemy(mNokoModel); + nw4r::g3d::ResAnmChr anm = mNokoResFile.GetResAnmChr("walkA"); mMoveAnim.create(mdl, anm, &mNokoAllocator, nullptr); mNokoResAnmTexPat = mNokoResFile.GetResAnmTexPat("nokonokoA"); @@ -124,7 +135,7 @@ int daEnNoko_c::preExecute() { if (canDance()) { if (dAudio::isBgmAccentSign(2)) { danceWithMove(0); - } else if (dAudio::isBgmAccentSign(2)) { + } else if (dAudio::isBgmAccentSign(4)) { danceWithMove(1); } else if (dAudio::isBgmAccentSign(8)) { danceWithMove(2); @@ -199,8 +210,9 @@ bool daEnNoko_c::isInQuicksand() { } void daEnNoko_c::spawnQuicksandEffects() { - mVec3_c pos = getCenterPos(); - mQuickSandEffect.createEffect("Wm_en_quicksand", 0, &pos, nullptr, nullptr); + mVec3_c center = getCenterPos(); + mVec3_c efPos(center.x, center.y, 5500.0f); + mQuickSandEffect.createEffect("Wm_en_quicksand", 0, &efPos, nullptr, nullptr); } bool daEnNoko_c::canDance() { @@ -238,10 +250,7 @@ void daEnNoko_c::calcShellEffectPos() { nw4r::g3d::ResMdl resMdl = model->getResMdl(); nw4r::g3d::ResNode resNode = resMdl.GetResNode("nokonoko_shell_model"); - ulong idx = 0; - if (resNode.IsValid()) { - idx = resNode.GetID(); - } + ulong idx = resNode.GetID(); mMtx_c matrix; model->getNodeWorldMtx(idx, &matrix); @@ -268,33 +277,26 @@ bool daEnNoko_c::isWalking() { } bool daEnNoko_c::sub_80A73330(dActor_c *actor) { - bool x = dActor_c::getTrgToSrcDir_Main(actor->mPos.x + actor->mCenterOffs.x, mPos.x + mCenterOffs.x); + u8 x = dActor_c::getTrgToSrcDir_Main(actor->getCenterX(), getCenterX()); - if ((mDirection == x) || ((mUseBaseIceBehaviour & 0xFF) == 0)) { + u8 mShellKind = mUseBaseIceBehaviour; + if (mDirection == x || mShellKind == 0) { return false; } mDirection = x; mAngle.y = buf_80ad34bc[x]; - m_8a8 = -m_8a8; + m_8a8 *= -1; vf30C(); return true; } void daEnNoko_c::setBc() { - mSensorHead.mBase.mFlags = SENSOR_IS_POINT; - mSensorHead.mX = 0; - mSensorHead.mY = 0xc000; - mSensorWall.mBase.mFlags = SENSOR_IS_LINE; - mSensorWall.mLineA = 0x6000; - mSensorWall.mLineB = 0x9000; - mSensorWall.mDistanceFromCenter = 0x6000; - mSensorFootNormal.mBase.mFlags = SENSOR_IS_LINE; - mSensorFootNormal.mLineA = -0x4000; - mSensorFootNormal.mLineB = 0x4000; - mSensorFootNormal.mDistanceFromCenter = 0; - mBc.set(this, (const sBcSensorBase *) &mSensorFootNormal, (const sBcSensorBase *) &mSensorHead, (const sBcSensorBase *) &mSensorWall); + mSensorHead = smc_noko_head; + mSensorWall = smc_noko_wall; + mSensorFootNormal = smc_noko_foot; + mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); } void daEnNoko_c::vf30C() { @@ -379,22 +381,24 @@ bool daEnNoko_c::createIceActor() { mVec3_c f_5c; int ice_mode; + mVec3_c scale; + if (*mStateMgr.getMainStateID() == StateID_BgmDance) { f_5c.set(mPos.x, mPos.y - 4.0f, mPos.z + 2.0f); - f_60 = 1.75f; ice_mode = 1; + scale.set(1.0f, 1.05f, 1.75f); } else { int x = mUseBaseIceBehaviour; f_5c.set(mPos.x, mPos.y + buf_80ad3500[x], mPos.z); - f_60 = 1.05f; ice_mode = buf_80ad34f8[x]; + scale.set(1.0f, 1.05f, 1.05f); } dIceInfo iceInfo[] = { { ice_mode, f_5c, - mVec3_c(1.0f, 1.0f, f_60) + scale } }; @@ -484,7 +488,12 @@ void daEnNoko_c::sub_80A73CB0() { } void daEnNoko_c::initializeState_Walk() { - if ((*mStateMgr.getOldStateID() != StateID_Turn) && (*mStateMgr.getOldStateID() != StateID_Walk) && (*mStateMgr.getOldStateID() != StateID_WindTurn) && (*mStateMgr.getOldStateID() != StateID_WakeupTurn)) { + if ( + *mStateMgr.getOldStateID() != StateID_Turn && + *mStateMgr.getOldStateID() != StateID_Walk && + *mStateMgr.getOldStateID() != StateID_WindTurn && + *mStateMgr.getOldStateID() != daEnShell_c::StateID_WakeupTurn + ) { setMoveAnimation("walkA", m3d::FORWARD_LOOP, 1.0f); } @@ -495,10 +504,7 @@ void daEnNoko_c::initializeState_Walk() { mSpeedMax.x = f; mSpeedMax.y = -4.0f; mSpeedMax.z = 0.0f; - mSensorFootNormal.mBase.mFlags = SENSOR_IS_LINE; - mSensorFootNormal.mLineA = -0x4000; - mSensorFootNormal.mLineB = 0x4000; - mSensorFootNormal.mDistanceFromCenter = 0; + mSensorFootNormal = smc_noko_foot; mSpeed.x = f; m_8c8 = 0; } @@ -510,7 +516,7 @@ void daEnNoko_c::executeState_Walk() { float wind = getWindMultiplier(); if (std::fabs(wind) > 0.475f) { - if (((float)(int)buf_80ad34b0[mDirection]) * wind >= 0.0f) { + if (l_EnMuki[mDirection] * wind >= 0.0f) { changeState(StateID_WindTurn); return; } else { @@ -547,11 +553,11 @@ void daEnNoko_c::initializeState_Wakeup() { daEnShell_c::initializeState_Wakeup(); } -void daEnNoko_c::finalizeState_Wakeup() { - mAnim.setFrame(0.0f); - mCc.mCcData.mBase.mOffset.x = 0.0f; - mCc.mCcData.mBase.mSize.x = 8.0f; -} +// void daEnNoko_c::finalizeState_Wakeup() { +// mAnim.setFrame(0.0f); +// mCc.mCcData.mBase.mOffset.x = 0.0f; +// mCc.mCcData.mBase.mSize.x = 8.0f; +// } void daEnNoko_c::executeState_Wakeup() { mNokoModel.play(); @@ -666,12 +672,18 @@ void daEnNoko_c::executeState_SpitOut_Ready() { deleteRequest(); } else { setSlideThrowSpeed(player); - mPlayerNo = getPlrNo(); + mPlayerNo = player->getPlrNo(); changeState(StateID_Slide); } } void daEnNoko_c::initializeState_BgmDance() { + static const char *buf_80afdd98[3] = { + "BGM_anim_walkA_1", + "BGM_anim_walkA_1", + "BGM_anim_walkA_3", + }; + setMoveAnimation((char *)buf_80afdd98[mDanceMove], m3d::FORWARD_ONCE, 3.0f); mSpeed.x = 0.0; mDancesRemaining = 3; diff --git a/source/dol/bases/d_a_en_shell.cpp b/source/dol/bases/d_a_en_shell.cpp index 8bbf5921..b81a283c 100644 --- a/source/dol/bases/d_a_en_shell.cpp +++ b/source/dol/bases/d_a_en_shell.cpp @@ -1026,7 +1026,7 @@ void daEnShell_c::executeState_Carry() { } void daEnShell_c::initializeState_Slide() { - mSensorFootSlide.mBase.mFlags = 1; + mSensorFootSlide.mFlags = 1; mSensorFootSlide.mLineA = -0x3000; mSensorFootSlide.mLineB = 0x2000; mSensorFootSlide.mDistanceFromCenter = 0; @@ -1053,10 +1053,10 @@ void daEnShell_c::initializeState_Slide() { mNoHitPlayer.mTimer[mPlayerNo] = 10; } - mSensorHead.mBase.mFlags |= 0xc0000; - mSensorFootNormal.mBase.mFlags |= 0xc0000; - mSensorWall.mBase.mFlags |= 0xc0000; - mSensorFootSlide.mBase.mFlags |= 0xc0000; + mSensorHead.mFlags |= 0xc0000; + mSensorFootNormal.mFlags |= 0xc0000; + mSensorWall.mFlags |= 0xc0000; + mSensorFootSlide.mFlags |= 0xc0000; } mSlideAirAfterThrow = 0; @@ -1072,11 +1072,11 @@ void daEnShell_c::initializeState_Slide() { mAccelY = -0.1875f; mSpeedMax.set(mSpeed.x, -4.0f, 0.0f); - mSensorHead.mBase.mFlags |= 0x900000; - mSensorWall.mBase.mFlags |= 0x900000; + mSensorHead.mFlags |= 0x900000; + mSensorWall.mFlags |= 0x900000; if (mJumpPlayerCarryActorID) { - mSensorHead.mBase.mFlags |= 0x400; - mSensorWall.mBase.mFlags |= 0x400; + mSensorHead.mFlags |= 0x400; + mSensorWall.mFlags |= 0x400; } mBc.set(this, mSensorFootSlide, mSensorHead, mSensorWall); @@ -1105,10 +1105,10 @@ void daEnShell_c::finalizeState_Slide() { mCc.mCcData.mAttack = CC_ATTACK_NONE; mAccelF = 0.0f; mSpeedMax.set(0.0f, -4.0f, 0.0f); - mSensorHead.mBase.mFlags &= ~0x49c0400; - mSensorFootNormal.mBase.mFlags &= ~0xc0000; - mSensorWall.mBase.mFlags &= ~0x9c0400; - mSensorFootSlide.mBase.mFlags &= ~0xc0000; + mSensorHead.mFlags &= ~0x49c0400; + mSensorFootNormal.mFlags &= ~0xc0000; + mSensorWall.mFlags &= ~0x9c0400; + mSensorFootSlide.mFlags &= ~0xc0000; mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); mBc.mOwningPlrNo = -1; mPlayerNo = -1; @@ -1122,8 +1122,8 @@ void daEnShell_c::executeState_Slide() { slideSpin(); slideEffect(); if (mJumpPlayerNoCarryHitTimer == 0) { - mSensorHead.mBase.mFlags &= ~0x400; - mSensorWall.mBase.mFlags &= ~0x400; + mSensorHead.mFlags &= ~0x400; + mSensorWall.mFlags &= ~0x400; } EnBgCheckWall(); EnBgCheckFoot(); diff --git a/syms.txt b/syms.txt index 9df20aba..cad5f0ae 100644 --- a/syms.txt +++ b/syms.txt @@ -107,7 +107,7 @@ isChange__7dAcPy_cFv=0x8006C400 __ct__5dBc_cFv=0x8006CF40 __dt__5dBc_cFv=0x8006CFA0 init__5dBc_cFv=0x8006CFE0 -set__5dBc_cFP8dActor_cPC13sBcSensorBasePC13sBcSensorBasePC13sBcSensorBase=0x8006D090 +set__5dBc_cFP8dActor_cPC13sBcSensorIf_cPC13sBcSensorIf_cPC13sBcSensorIf_c=0x8006D090 checkFoot__5dBc_cFv=0x8006DB30 checkHead__5dBc_cFUl=0x8006EF40 checkWall__5dBc_cFPf=0x8006FA40 From 5eed71966043ed91e0b991218fd548620a7b8a5d Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 10:41:24 +0200 Subject: [PATCH 3/9] Support keepWeak in RELs --- configure.py | 6 +++--- slices/wiimj2d.json | 3 +-- tools/gen_lcf.py | 49 +++++++++++++++++++++++++++------------------ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/configure.py b/configure.py index d4c8c91d..e7fb5a68 100644 --- a/configure.py +++ b/configure.py @@ -166,11 +166,11 @@ def gen_rel_build_statements(writer: NinjaWriter, slices: list[SliceFile]): # RELs need to come together to create the common linker script for the final stripped modules # Pick the slice with the largest number of sections as the base - rel_slices = [x for x in slices if x.meta.type == SliceType.REL] - best_slice = max(rel_slices, key=lambda x: len(x.meta.sections)) + rel_slices = [x.path for x in slices if x.meta.type == SliceType.REL] writer.build('gen_linkerscript', common_lcf, - [best_slice.path, *files_with_suffix(rel_files, '.preplf')]) + rel_slices, + implicit_inputs=files_with_suffix(rel_files, '.preplf')) ###################### # Build Script Setup # diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 78922119..cb4307a4 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -63,8 +63,7 @@ "GetRuntimeTypeInfo__Q34nw4r3lyt4PaneCFv", "setPosParam__Q23EGG14CoreControllerFff", "getFileSize__Q23EGG7DvdFileCFv", - "isItemKinopio__7dAcPy_cFv", - "dummy__10daPlBase_cFv" + "isItemKinopio__7dAcPy_cFv" ], "slices": [ { diff --git a/tools/gen_lcf.py b/tools/gen_lcf.py index 92da6c45..6a59a3e3 100644 --- a/tools/gen_lcf.py +++ b/tools/gen_lcf.py @@ -37,17 +37,24 @@ def make_elf_force_directives(slice_file: SliceFile) -> set[str]: return force_actives -def make_plf_force_directives(preplfs: list[Path]) -> set[str]: +def make_plf_force_directives(slice_file: SliceFile) -> set[str]: force_actives = set() + rel_file_name = (BUILDDIR / slice_file.meta.fileName).with_suffix('.preplf') + + if not rel_file_name.exists(): + return force_actives + # We need the unresolved symbols from all RELs so that the linker does not deadstrip them. # We do this by checking the symbols in the .preplf with an undefined section index. - for preplf in preplfs: - preplf_file: ElfFile = ElfFile.read(preplf.read_bytes()) - symtab = cast(ElfSymtab, preplf_file.get_section('.symtab')) - for sym in symtab.syms: - if sym.st_shndx == 0 and not REL_SYM.match(sym.name): - force_actives.add(sym.name) + preplf_file: ElfFile = ElfFile.read(rel_file_name.read_bytes()) + symtab = cast(ElfSymtab, preplf_file.get_section('.symtab')) + for sym in symtab.syms: + if sym.st_shndx == 0 and not REL_SYM.match(sym.name): + force_actives.add(sym.name) + elif sym.name in slice_file.keepWeak: + # Some symbols might not be referenced yet, but we still want to keep them + force_actives.add(sym.name) force_actives.add('_prolog') force_actives.add('_epilog') @@ -55,10 +62,9 @@ def make_plf_force_directives(preplfs: list[Path]) -> set[str]: return force_actives -def gen_lcf(slice_file_path: Path, preplfs: list[Path], out_path: Path) -> None: - assert slice_file_path.is_file() - - slice_file: SliceFile = load_slice_file(slice_file_path) +def gen_lcf(slice_file_paths: list[Path], out_path: Path) -> None: + slice_files = [load_slice_file(path) for path in slice_file_paths] + most_sections_slice = max(slice_files, key=lambda x: len(x.meta.sections)) lcf_file = StringIO() # MEMORY section: include base address (hardcoded for now) @@ -69,21 +75,25 @@ def gen_lcf(slice_file_path: Path, preplfs: list[Path], out_path: Path) -> None: # SECTIONS section lcf_file.write('SECTIONS {\n') lcf_file.write('\tGROUP: {\n') - for name, section in slice_file.meta.sections.items(): + + for name, section in most_sections_slice.meta.sections.items(): if '$' in name or section.size == 0: continue align = section.align if section.secAlign == -1 else section.secAlign - if slice_file.meta.type == SliceType.DOL: + if most_sections_slice.meta.type == SliceType.DOL: align = 0x20 lcf_file.write(f'\t\t{name} ALIGN(0x{align:0x}) : {{}}\n') + lcf_file.write('\t} > text\n') lcf_file.write('}\n\n') # FORCEACTIVE section - if slice_file.meta.type == SliceType.DOL: - force_active = make_elf_force_directives(slice_file) - else: - force_active = make_plf_force_directives(preplfs) + force_active = set() + for slice_file in slice_files: + if slice_file.meta.type == SliceType.DOL: + force_active |= make_elf_force_directives(slice_file) + else: + force_active |= make_plf_force_directives(slice_file) lcf_file.write('FORCEACTIVE {\n') for force_sym in sorted(force_active): @@ -96,8 +106,7 @@ def gen_lcf(slice_file_path: Path, preplfs: list[Path], out_path: Path) -> None: if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description='Generates a linker script from a slice file.') - parser.add_argument('slice_file', type=Path, help='Slice file to generate the linker script from.') - parser.add_argument('preplf', nargs='*', type=Path, help='PREPLF files to generate the FORCEACTIVE section from.') + parser.add_argument('slice_files', nargs='*', type=Path, help='Slice files to generate the linker script from.') parser.add_argument('-o', '--output', type=Path, required=True, help='Path the linker script will be stored to.') args = parser.parse_args() - gen_lcf(args.slice_file, args.preplf, args.output) + gen_lcf(args.slice_files, args.output) From 314c75c960aaefe4363b491dcdcb1066ef3a7a54 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 10:41:49 +0200 Subject: [PATCH 4/9] Sort alias_db.txt, add some symbols for d_enemiesNP --- alias_db.txt | 1357 +++++++++++++++++++++++++------------------------- 1 file changed, 692 insertions(+), 665 deletions(-) diff --git a/alias_db.txt b/alias_db.txt index 2f805731..e17d62a6 100644 --- a/alias_db.txt +++ b/alias_db.txt @@ -1,10 +1,6 @@ -R_2_1_F0 = finalizeProlog__Fv -R_2_1_100 = finalizeEpilog__Fv -R_3_1_F0 = finalizeProlog__Fv -R_3_1_100 = finalizeEpilog__Fv -R_4_1_F0 = finalizeProlog__Fv -R_4_1_100 = finalizeEpilog__Fv R_2_1_70 = __register_global_object +R_2_1_f0 = finalizeProlog__Fv +R_2_1_100 = finalizeEpilog__Fv R_2_1_1be0 = __dt__7mVec3_cFv R_2_1_88b0 = __dt__Q26dWmLib19ForceInCourseList_tFv R_2_1_49500 = finalUpdate__12dBaseActor_cFv @@ -29,63 +25,107 @@ R_2_1_15ab90 = vf78__13dWmObjActor_cFv R_2_1_15aba0 = vf74__13dWmObjActor_cFv R_2_1_15abb0 = GetActorType__13dWmObjActor_cFv R_2_1_1a7e90 = FUN_80915600__11dCsSeqMng_cFv -R_2_5_4fa70 = g_profile_WORLD_MAP -R_2_5_4da38 = g_profile_WORLD_9_DEMO -R_2_5_4f238 = g_profile_STAGE -R_2_5_4f150 = g_profile_RESTART_CRSIN -R_2_5_4dff8 = g_profile_CRSIN -R_2_5_4ea98 = g_profile_MOVIE -R_2_5_4e710 = g_profile_GAMEOVER -R_2_5_4ce50 = g_profile_GAME_SETUP -R_2_5_4d3e0 = g_profile_MULTI_PLAY_COURSE_SELECT -R_2_5_51c20 = g_profile_WM_TEST -R_2_5_51c2c = g_profile_WM_TEST2 -R_2_5_4c668 = g_profile_CAMERA -R_2_5_4bfb0 = g_profile_YOSHI_FIRE -R_2_5_3da40 = g_profile_SLOW_QUICK_TAG -R_2_5_3f880 = g_profile_TORIDE_KOKOOPA_DEMO +R_2_5_0 = g_profile_CHARACTER_CHANGE_INDICATOR +R_2_5_1c8 = g_profile_CHARACTER_CHANGE_SELECT_ARROW +R_2_5_668 = g_profile_CHARACTER_CHANGE_SELECT_BASE +R_2_5_1130 = g_profile_CHARACTER_CHANGE_SELECT_CONTENTS +R_2_5_1590 = g_profile_COLLECTION_COIN +R_2_5_1ba8 = g_profile_COLLECTION_COIN_BASE +R_2_5_1d68 = g_profile_COLLECTION_COIN_DATE +R_2_5_2108 = g_profile_CONTINUE +R_2_5_29c0 = g_profile_COURSE_CLEAR +R_2_5_3040 = g_profile_COURSE_SELECT_MENU +R_2_5_36e0 = g_profile_COURSE_TIME_UP +R_2_5_3a98 = g_profile_DATE_FILE +R_2_5_4180 = g_profile_DEMO_MESSAGE +R_2_5_4530 = g_profile_DRAW_GAME +R_2_5_48b8 = g_profile_EASY_PAIRING +R_2_5_4ee0 = g_profile_EVENT_OPENING_TITLE +R_2_5_5390 = g_profile_FILE_SELECT +R_2_5_6bf0 = g_profile_GAME_OVER +R_2_5_7198 = g_profile_INFO_WINDOW +R_2_5_72e0 = g_profile_LETTER_WINDOW +R_2_5_77a0 = g_profile_MESSAGE_WINDOW +R_2_5_7b78 = g_profile_MINI_GAME_CANNON +R_2_5_84a8 = g_profile_MINI_GAME_WIRE +R_2_5_93b0 = g_profile_MODE_SELECT +R_2_5_98e0 = g_profile_MODEL_PLAY_ARROW +R_2_5_9db0 = g_profile_MODEL_PLAY_BASE +R_2_5_a3c0 = g_profile_MODEL_PLAY_DATE +R_2_5_a890 = g_profile_MODEL_PLAY_GUIDE +R_2_5_a978 = g_profile_MODEL_PLAY_MANAGER +R_2_5_b1d0 = g_profile_MULTI_COURSE_SELECT +R_2_5_c0f8 = g_profile_MULTI_COURSE_SELECT_CONTENTS +R_2_5_ce60 = g_profile_NUMBER_OF_PEOPLE_CHANGE +R_2_5_d97c = g_profile_OTEHON_CLEAR +R_2_5_ddd0 = g_profile_POINT_RESULT_DATE_FILE +R_2_5_ef68 = g_profile_POINT_RESULT_DATE_FILE_FREE +R_2_5_f658 = g_profile_POINT_RESULT_MULTI +R_2_5_10198 = g_profile_SELECT_PLAYER +R_2_5_109c0 = g_profile_SEQUENCE_BG +R_2_5_10e58 = g_profile_STAFF_CREDIT_SCORE +R_2_5_11508 = g_profile_STOCK_ITEM +R_2_5_11f30 = g_profile_STOCK_ITEM_SHADOW +R_2_5_121a8 = g_profile_THE_END +R_2_5_124e8 = g_profile_TIME_UP +R_2_5_12880 = g_profile_AC_BG_WATER +R_2_5_1288c = g_profile_AC_BG_LAVA +R_2_5_12898 = g_profile_AC_BG_POISON +R_2_5_128a4 = g_profile_AC_BG_SAND +R_2_5_128b0 = g_profile_AC_BG_CLOUD +R_2_5_128bc = g_profile_AC_BG_MOYA +R_2_5_12d70 = g_profile_AC_AUTOSCROOL_SWICH +R_2_5_132b0 = g_profile_BARNAR_MGR +R_2_5_13390 = g_profile_AC_BATTLE_GAME +R_2_5_135f8 = g_profile_AC_BATTLE_KINOPIO +R_2_5_13758 = g_profile_AC_BATTLE_ITEM +R_2_5_13a98 = g_profile_BELT_NEEDLE +R_2_5_13c30 = g_profile_BG_CENTER +R_2_5_13d10 = g_profile_BGM_INTERLOCKING_DUMMY_BLOCK +R_2_5_142d0 = g_profile_BGM_INTERLOCKING_DUMMY_BLOCK_MGR +R_2_5_14548 = g_profile_AC_BIGSHELL +R_2_5_14718 = g_profile_BIGHANA_MGR +R_2_5_14918 = g_profile_AC_COPYRIGHT +R_2_5_14ab0 = g_profile_AC_BLOCK_COIN +R_2_5_14b90 = g_profile_AC_BLOCK_GROUP +R_2_5_14c70 = g_profile_BLOCK_LIGHT +R_2_5_14e70 = g_profile_AC_BLOCK_ONEUP +R_2_5_14f50 = g_profile_BLOCK_TARU +R_2_5_15280 = g_profile_AC_BLOCK_WIND_TAG +R_2_5_15480 = g_profile_BOMB_JR_C +R_2_5_15a60 = g_profile_BOOMERANG R_2_5_15d90 = g_profile_BOSS_KAMECK_DEMO +R_2_5_16008 = g_profile_AC_BOSS_KOOPA_BG_EFFECT R_2_5_16228 = g_profile_BOSS_KOOPA_DEMO -R_2_5_18bcc = g_profile_CASTLE_KOKOOPA_DEMO_1ST -R_2_5_18fb0 = g_profile_CASTLE_KOKOOPA_DEMO_2ND R_2_5_16cdc = g_profile_BOSS_KOOPA_JR_DEMO -R_2_5_26860 = g_profile_KOOPA_SHIP_FOR_CASTLE_DEMO -R_2_5_25da8 = g_profile_KOOPA_JR_FOR_CASTLE_DEMO -R_2_5_39ab8 = g_profile_PEACH_FOR_CASTLE_DEMO -R_2_5_23338 = g_profile_KAMECK_FOR_CASTLE_DEMO -R_2_5_27db0 = g_profile_LEMMY_FOOTHOLD -R_2_5_27dbc = g_profile_LEMMY_FOOTHOLD_MAIN +R_2_5_170d0 = g_profile_AC_BOSS_KOOPA_RUBBLE +R_2_5_17440 = g_profile_AC_BOSS_KOOPA_SCAFFOLD +R_2_5_176f8 = g_profile_BRANCH +R_2_5_177d8 = g_profile_BROS_ICEBALL +R_2_5_179d0 = g_profile_AC_WATER_BUBBLE +R_2_5_17ac0 = g_profile_CAGE_BLOCK +R_2_5_17c68 = g_profile_CANNON_PIPE R_2_5_181e8 = g_profile_CASTLE_BOSS_DOOR R_2_5_18658 = g_profile_CASTLE_BOSS_KEY -R_2_5_13390 = g_profile_AC_BATTLE_GAME -R_2_5_135f8 = g_profile_AC_BATTLE_KINOPIO -R_2_5_13758 = g_profile_AC_BATTLE_ITEM -R_2_5_4c0e0 = g_profile_AC_ENDING_MAIN -R_2_5_15280 = g_profile_AC_BLOCK_WIND_TAG -R_2_5_1ea58 = g_profile_AC_GROUPID -R_2_5_24078 = g_profile_KAWANAGARE -R_2_5_3b3c8 = g_profile_RIVER_PAIPO -R_2_5_3b0f8 = g_profile_RIVER_ITEM -R_2_5_3b008 = g_profile_RIVER_COIN -R_2_5_3b698 = g_profile_RIVER_STARCOIN -R_2_5_3b1e8 = g_profile_RIVER_LIFT -R_2_5_3af18 = g_profile_RIVER_BARREL -R_2_5_3b5a8 = g_profile_RIVER_PUKU -R_2_5_3b4b8 = g_profile_RIVER_PAKKUN -R_2_5_3b2d8 = g_profile_RIVER_MGR -R_3_5_22370 = g_profile_EN_KURIBO -R_3_5_2c8b8 = g_profile_EN_PATA_KURIBO -R_3_5_24f68 = g_profile_EN_MAME_KURIBO -R_3_5_28250 = g_profile_EN_NOKONOKO -R_3_5_2d098 = g_profile_EN_PATAPATA -R_3_5_264a0 = g_profile_EN_MET -R_3_5_366f0 = g_profile_EN_TOGEZO -R_3_5_31a28 = g_profile_EN_SAKASA_TOGEZO -R_3_5_5568 = g_profile_EN_BLOCK -R_3_5_1b3a8 = g_profile_EN_ITEM -R_3_5_33b90 = g_profile_EN_STAR_COIN -R_3_5_33b9c = g_profile_EN_STAR_COIN_LINE -R_3_5_33ba8 = g_profile_EN_STAR_COIN_VOLT +R_2_5_18bcc = g_profile_CASTLE_KOKOOPA_DEMO_1ST +R_2_5_18fb0 = g_profile_CASTLE_KOKOOPA_DEMO_2ND +R_2_5_191c0 = g_profile_CASTLE_LEMMY_BALL +R_2_5_19a00 = g_profile_CASTLE_LEMMY_THROW_BALL +R_2_5_19e08 = g_profile_AC_CHENGE_BLOCK +R_2_5_19ef8 = g_profile_CHOROPOO_SHADOW +R_2_5_1a238 = g_profile_CHUKAN_POINT +R_2_5_1a4e8 = g_profile_CIRCLE_RIGHT +R_2_5_1a5e8 = g_profile_AC_DOKAN_CANNON +R_2_5_1a7f8 = g_profile_DUMMY_ACTOR +R_2_5_1a8d8 = g_profile_DUMMY_DOOR +R_2_5_1aa08 = g_profile_DUMMY_DOOR_CHILD +R_2_5_1aae8 = g_profile_DUMMY_DOOR_PARENT +R_2_5_1abc8 = g_profile_ELASTIC_KINOKO +R_2_5_1afc8 = g_profile_ELASTIC_KINOKO_PARENT +R_2_5_1b188 = g_profile_FALL_FIRE +R_2_5_1b520 = g_profile_FIRE_BLITZ +R_2_5_1b790 = g_profile_BROS_FIREBALL +R_2_5_1b9b0 = g_profile_PAKKUN_FIREBALL R_2_5_1bbd8 = g_profile_AC_FLAGON R_2_5_1bbe4 = g_profile_AC_4SWICHAND R_2_5_1bbf0 = g_profile_AC_4SWICHOR @@ -93,657 +133,644 @@ R_2_5_1bbfc = g_profile_AC_RANDSWICH R_2_5_1bc08 = g_profile_AC_CHNGESWICH R_2_5_1bc14 = g_profile_AC_IFSWICH R_2_5_1bc20 = g_profile_AC_RNSWICH -R_3_5_9230 = g_profile_EN_BKBLOCK -R_3_5_190c8 = g_profile_EN_HNSWICH -R_3_5_190d4 = g_profile_EN_PSWICH -R_3_5_190e0 = g_profile_EN_QSWICH -R_3_5_190f8 = g_profile_EN_BOSS_KOOPA_SWITCH -R_3_5_19104 = g_profile_EN_BOSS_KOOPA_BIG_SWITCH -R_3_5_6fa8 = g_profile_EN_BLSWICH -R_3_5_6fb4 = g_profile_EN_BLPSWICH -R_3_5_6fc0 = g_profile_EN_BLQSWICH -R_3_5_9528 = g_profile_EN_BUBBLE -R_3_5_126f8 = g_profile_EN_DOSUN -R_3_5_12704 = g_profile_EN_BIGDOSUN -R_3_5_1db10 = g_profile_EN_JUGEM -R_3_5_1db1c = g_profile_EN_JUGEM_COIN -R_3_5_12d30 = g_profile_EN_EATJUGEM -R_3_5_1dfd8 = g_profile_EN_JUGEM_BODY -R_3_5_35df0 = g_profile_EN_TOGEMET -R_3_5_13678 = g_profile_EN_FIREBAR -R_3_5_362c8 = g_profile_EN_TOGETEKKYU -R_3_5_3210 = g_profile_EN_BIG_TOGETEKKYU -R_3_5_12020 = g_profile_EN_UP_DOKAN_PAKKUN -R_3_5_11498 = g_profile_EN_DOWN_DOKAN_PAKKUN -R_3_5_11c48 = g_profile_EN_RIGHT_DOKAN_PAKKUN -R_3_5_11870 = g_profile_EN_LEFT_DOKAN_PAKKUN -R_3_5_110e8 = g_profile_EN_UP_DOKAN_FPAKKUN -R_3_5_105c0 = g_profile_EN_DOWN_DOKAN_FPAKKUN -R_3_5_10d30 = g_profile_EN_RIGHT_DOKAN_FPAKKUN -R_3_5_10978 = g_profile_EN_LEFT_DOKAN_FPAKKUN -R_3_5_1d720 = g_profile_EN_JIMEN_PAKKUN -R_3_5_1d020 = g_profile_EN_JIMEN_BIG_PAKKUN -R_3_5_1d2f0 = g_profile_EN_JIMEN_FPAKKUN -R_3_5_1cd48 = g_profile_EN_JIMEN_BIG_FPAKKUN -R_3_5_37ff8 = g_profile_EN_WALK_PAKKUN -R_2_5_1b9b0 = g_profile_PAKKUN_FIREBALL -R_2_5_1b790 = g_profile_BROS_FIREBALL -R_2_5_15a60 = g_profile_BOOMERANG -R_3_5_18718 = g_profile_EN_HELPOS -R_3_5_13348 = g_profile_EN_FIREBROS -R_3_5_8838 = g_profile_EN_BOOMERANGBROS -R_3_5_17dc0 = g_profile_EN_HAMMERBROS -R_3_5_19f90 = g_profile_EN_ICEBROS -R_3_5_23698 = g_profile_EN_LIFT_HAMMERBROS +R_2_5_1bf38 = g_profile_AC_FLOOR_DOKAN_EIGHT +R_2_5_1c238 = g_profile_AC_FLOOR_GYRATION +R_2_5_1c528 = g_profile_AC_FLOOR_HOLE_DOKAN +R_2_5_1c780 = g_profile_FLOOR_JR_A +R_2_5_1cc30 = g_profile_FLOOR_JR_B +R_2_5_1cec8 = g_profile_FLOOR_JR_C +R_2_5_1d258 = g_profile_FLOOR_JR_C_MGR +R_2_5_1d5d8 = g_profile_FLYDOKAN_DOWN +R_2_5_1d6c8 = g_profile_FLYDOKAN_LEFT +R_2_5_1d7b8 = g_profile_FLYDOKAN_RIGHT +R_2_5_1d8a8 = g_profile_FLYDOKAN_UP +R_2_5_1d998 = g_profile_FOO_BALL +R_2_5_1de78 = g_profile_FREEFALL +R_2_5_1e048 = g_profile_AC_FREEZER +R_2_5_1e3e0 = g_profile_GABON_ROCK +R_2_5_1e800 = g_profile_AC_GEAR_GYRATION +R_2_5_1ea58 = g_profile_AC_GROUPID R_2_5_1eb38 = g_profile_HAMMER -R_3_5_189a8 = g_profile_EN_HIMANBROS -R_2_5_30688 = g_profile_MEGA_HAMMER -R_2_5_177d8 = g_profile_BROS_ICEBALL -R_3_5_8fa0 = g_profile_EN_BOYON -R_3_5_303b0 = g_profile_EN_REMOCON_TORIMOCHI -R_2_5_3ec68 = g_profile_TAG_WIND -R_2_5_3eaa8 = g_profile_TAG_THUNDER -R_2_5_3eb88 = g_profile_TAG_WATER -R_3_5_618 = g_profile_EN_AUTOSCR -R_2_5_343e0 = g_profile_OBJ_GRASS -R_3_5_130a8 = g_profile_EN_ENV -R_3_5_20b70 = g_profile_EN_KILLER -R_3_5_20b7c = g_profile_EN_SEARCH_KILLER -R_3_5_20b88 = g_profile_EN_MAGNUM_KILLER -R_3_5_20b94 = g_profile_EN_SEARCH_MAGNUM_KILLER -R_3_5_1a98 = g_profile_EN_BASABASA -R_2_5_40ab0 = g_profile_WAKI_PARABOM -R_3_5_80c0 = g_profile_EN_BOMHEI -R_3_5_2bfe0 = g_profile_EN_PARA_BOMHEI -R_3_5_25e90 = g_profile_EN_MECHA_KOOPA -R_3_5_27528 = g_profile_EN_MOUSE -R_3_5_16340 = g_profile_EN_GHOST_JUGEM -R_3_5_37870 = g_profile_DOKAN_WAKIDASHI -R_3_5_fa38 = g_profile_EN_CRASHER -R_2_5_2bdb0 = g_profile_AC_WAKILIFT -R_3_5_4b18 = g_profile_EN_BIRIKYU -R_3_5_249a0 = g_profile_EN_LINE_BIRIKYU -R_3_5_4f38 = g_profile_EN_BIRIKYU_MAKER -R_3_5_aba8 = g_profile_EN_CHOROBON -R_3_5_31ec0 = g_profile_EN_SANBO -R_3_5_32890 = g_profile_EN_SANBO_PARTS -R_3_5_322f8 = g_profile_EN_SANBO_EL -R_3_5_17a80 = g_profile_EN_GURUGURU -R_3_5_15520 = g_profile_EN_GESSO -R_3_5_d48 = g_profile_EN_BARAMAKI_GESSO -R_3_5_165d0 = g_profile_EN_GOALPOLE -R_3_5_15e88 = g_profile_EN_GESSO_CHILD -R_2_5_132b0 = g_profile_BARNAR_MGR -R_3_5_34aa0 = g_profile_EN_SYNCRO_BARNAR -R_3_5_10d8 = g_profile_EN_BARNAR -R_3_5_22cb8 = g_profile_EN_LARGE_BARNAR -R_3_5_2e310 = g_profile_EN_PUKUPUKU_PARENT -R_2_5_3f1d0 = g_profile_AC_TEAM_PUKUPUKU -R_3_5_2dba0 = g_profile_EN_PUKUPUKU -R_3_5_2dbc4 = g_profile_EN_TOGEPUKU -R_3_5_2dbac = g_profile_EN_MIDDLE_PUKU -R_3_5_2dbb8 = g_profile_EN_PUKUCOIN -R_3_5_1fa40 = g_profile_EN_KARON -R_3_5_1fa4c = g_profile_EN_BIGKARON -R_3_5_200d8 = g_profile_EN_KARON_HEAD -R_3_5_30640 = g_profile_EN_REVERSE -R_3_5_37ce8 = g_profile_EN_WAKI_JUGEM -R_3_5_3a8e0 = g_profile_EN_WIRE_TURN -R_3_5_3a8ec = g_profile_EN_BIG_WIRE_TURN -R_3_5_27a30 = g_profile_EN_NET_NOKONOKO_LR -R_3_5_27dd0 = g_profile_EN_NET_NOKONOKO_UD -R_2_5_14718 = g_profile_BIGHANA_MGR R_2_5_1ed98 = g_profile_HANA_MOUNTAIN -R_3_5_18230 = g_profile_EN_HANACHAN -R_3_5_2460 = g_profile_EN_BIG_HANACHAN -R_3_5_35170 = g_profile_EN_TERESA -R_3_5_3517c = g_profile_EN_BIG_TERESA -R_3_5_10010 = g_profile_EN_CROW -R_3_5_4088 = g_profile_EN_BIGPILE_UNDER -R_3_5_4338 = g_profile_EN_BIGPILE_UPPER -R_3_5_3dd8 = g_profile_EN_BIGPILE_RIGHT -R_3_5_3b28 = g_profile_EN_BIGPILE_LEFT -R_3_5_343e0 = g_profile_EN_SUPER_BIGPILE_RIGHT -R_3_5_33fe8 = g_profile_EN_SUPER_BIGPILE_LEFT -R_3_5_16a88 = g_profile_EN_GOKUBUTO_BIGPILE_UNDER -R_3_5_16eb8 = g_profile_EN_GOKUBUTO_BIGPILE_UPPER -R_3_5_45e8 = g_profile_EN_MORTON_BIGPILE -R_3_5_3b140 = g_profile_EN_YAJIRUSHI -R_3_5_387d0 = g_profile_EN_WANWAN -R_3_5_38e50 = g_profile_EN_WANWAN_PILE -R_3_5_1e918 = g_profile_EN_JUMPPUKU -R_3_5_1aef0 = g_profile_EN_IGAPUKU -R_3_5_37950 = g_profile_EN_WAKI_IGAPUKU -R_3_5_13a18 = g_profile_EN_FIRESNAKE -R_4_5_6ae8 = g_profile_EN_BOSS_KAMECK -R_3_5_32bd0 = g_profile_EN_SLIP_PENGUIN -R_2_5_40fd0 = g_profile_WAKI_SLIP_PENGUIN2 -R_3_5_32e60 = g_profile_EN_SLIP_PENGUIN2 -R_2_5_3d850 = g_profile_SLIP_PENGUIN2_GLASSES -R_3_5_1a970 = g_profile_EN_IGA_KURIBO -R_3_5_3a160 = g_profile_EN_WATERSTREAM -R_2_5_1aae8 = g_profile_DUMMY_DOOR_PARENT -R_2_5_1aa08 = g_profile_DUMMY_DOOR_CHILD -R_2_5_1a8d8 = g_profile_DUMMY_DOOR -R_2_5_33930 = g_profile_NOBORIBOU_OBAKE -R_2_5_3feb8 = g_profile_UNTEI_ROPE -R_2_5_3a748 = g_profile_REMO_DOOR -R_2_5_3ac10 = g_profile_REMO_SLIDE_DOOR -R_2_5_176f8 = g_profile_BRANCH -R_2_5_13c30 = g_profile_BG_CENTER -R_2_5_23980 = g_profile_KAMECK_MAGIC -R_2_5_3d258 = g_profile_SINKDOKAN_UP -R_2_5_3cf40 = g_profile_SINKDOKAN_DOWN -R_2_5_3d048 = g_profile_SINKDOKAN_LEFT -R_2_5_3d150 = g_profile_SINKDOKAN_RIGHT -R_2_5_1d8a8 = g_profile_FLYDOKAN_UP -R_2_5_1d5d8 = g_profile_FLYDOKAN_DOWN -R_2_5_1d6c8 = g_profile_FLYDOKAN_LEFT -R_2_5_1d7b8 = g_profile_FLYDOKAN_RIGHT -R_3_5_2b038 = g_profile_EN_ONEWAY_GATE -R_3_5_2c408 = g_profile_EN_PATABLOCK -R_3_5_20560 = g_profile_EN_KERONPA -R_2_5_24680 = g_profile_KERONPA_FIRE -R_2_5_332f8 = g_profile_AC_NEXTGOTO_BLOCK -R_3_5_8a8 = g_profile_EN_BAKUBAKU -R_3_5_123f0 = g_profile_EN_DOOR -R_3_5_347e0 = g_profile_EN_SWITCHDOOR -R_3_5_289d0 = g_profile_EN_OBAKEDOOR -R_3_5_36ab0 = g_profile_EN_TORIDEDOOR -R_3_5_a088 = g_profile_EN_CASTLEDOOR -R_3_5_21ac8 = g_profile_EN_KOOPADOOR -R_2_5_3ae38 = g_profile_AC_REVERSEBLOCK -R_2_5_1a238 = g_profile_CHUKAN_POINT -R_3_5_25be0 = g_profile_EN_MAX_UE_LEFT -R_3_5_25bec = g_profile_EN_MAX_UE_RIGHT -R_3_5_25bf8 = g_profile_EN_MAX_UE2_LEFT -R_3_5_25c04 = g_profile_EN_MAX_UE2_RIGHT -R_3_5_3b3e8 = g_profile_EN_ZOOM -R_4_5_bcd8 = g_profile_EN_BOSS_LARRY -R_4_5_11378 = g_profile_EN_BOSS_WENDY -R_4_5_5a40 = g_profile_EN_BOSS_IGGY -R_4_5_cb98 = g_profile_EN_BOSS_LEMMY -R_4_5_f168 = g_profile_EN_BOSS_MORTON -R_4_5_10180 = g_profile_EN_BOSS_ROY -R_4_5_de30 = g_profile_EN_BOSS_LUDWIG -R_4_5_eb0 = g_profile_EN_BOSS_CASTLE_LARRY -R_4_5_3eb8 = g_profile_EN_BOSS_CASTLE_ROY -R_4_5_4e90 = g_profile_EN_BOSS_CASTLE_WENDY -R_4_5_0 = g_profile_EN_BOSS_CASTLE_IGGY -R_2_5_191c0 = g_profile_CASTLE_LEMMY_BALL -R_4_5_1958 = g_profile_EN_BOSS_CASTLE_LEMMY -R_4_5_3220 = g_profile_EN_BOSS_CASTLE_MORTON -R_2_5_36578 = g_profile_OBJ_LUDWIG -R_4_5_24a0 = g_profile_EN_BOSS_CASTLE_LUDWIG -R_4_5_7d60 = g_profile_EN_BOSS_KOOPA -R_4_5_9988 = g_profile_EN_BOSS_KOOPA_DEMO_KAMECK -R_4_5_a058 = g_profile_EN_BOSS_KOOPA_DEMO_PEACH -R_2_5_408b8 = g_profile_AC_WAKI_KOOPA_FIRE -R_2_5_259a0 = g_profile_KOOPA_FIRE -R_2_5_26e90 = g_profile_LARRY_FIRE -R_2_5_25188 = g_profile_KOKOOPA_RING -R_2_5_24c18 = g_profile_KOKOOPA_BALL -R_2_5_25830 = g_profile_KOKOOPA_THREEWAY_BLITZ -R_2_5_274b8 = g_profile_LEMMY_BALL -R_2_5_19a00 = g_profile_CASTLE_LEMMY_THROW_BALL -R_2_5_345a0 = g_profile_OBJ_IGGY_SLED -R_2_5_34a50 = g_profile_OBJ_IGGY_WANWAN -R_2_5_369e0 = g_profile_OBJ_MORTON -R_2_5_37748 = g_profile_OBJ_ROY -R_2_5_36070 = g_profile_OBJ_LARRY -R_2_5_38938 = g_profile_OBJ_WENDY -R_2_5_17440 = g_profile_AC_BOSS_KOOPA_SCAFFOLD -R_2_5_170d0 = g_profile_AC_BOSS_KOOPA_RUBBLE -R_2_5_16008 = g_profile_AC_BOSS_KOOPA_BG_EFFECT -R_2_5_2dbc8 = g_profile_CASTLE_LUDWIG_BLITZ -R_2_5_2dbd4 = g_profile_CASTLE_LUDWIG_BLITZ_MGR -R_2_5_40728 = g_profile_WAKI_KOKOOPA_FIRE -R_2_5_1b188 = g_profile_FALL_FIRE -R_2_5_401b8 = g_profile_WAKI_FIRE -R_2_5_1b520 = g_profile_FIRE_BLITZ -R_2_5_25520 = g_profile_KOKOOPA_SEARCH_FIRE -R_3_5_37058 = g_profile_EN_UNIZOO -R_3_5_37064 = g_profile_EN_UNIRA -R_3_5_1f1e8 = g_profile_EN_KANIBO -R_3_5_1f750 = g_profile_EN_KANITAMA -R_3_5_21dd0 = g_profile_EN_KOPONE -R_3_5_0 = g_profile_EN_AKOYA -R_3_5_26a88 = g_profile_EN_MIDDLE_KURIBO -R_3_5_23090 = g_profile_EN_LARGE_KURIBO -R_3_5_1ff0 = g_profile_EN_BEANS_KURIBO -R_2_5_3e1f8 = g_profile_AC_STRONGBOX -R_3_5_2fda8 = g_profile_EN_REMOCON_CANNON -R_2_5_41238 = g_profile_WAKI_TOGETEKKYU +R_2_5_1ee78 = g_profile_HAND_RIGHT +R_2_5_1f0f0 = g_profile_ICE_ASHIBA +R_2_5_1f1e8 = g_profile_ICE_ASHIBA_RAIL +R_2_5_1f2e0 = g_profile_ICE_ASHIBA_WATER +R_2_5_1f5a8 = g_profile_ICECUBE +R_2_5_1f940 = g_profile_ICELUMP +R_2_5_1fb40 = g_profile_INTERMITTENT +R_2_5_1fe88 = g_profile_AC_ITEM_KEY +R_2_5_200e0 = g_profile_IWAO_ROCK R_2_5_201d0 = g_profile_JR_CLOWN_A R_2_5_20734 = g_profile_JR_CLOWN_B R_2_5_20e98 = g_profile_JR_CLOWN_C +R_2_5_216a4 = g_profile_JR_CLOWN_FOR_JR_C_DEMO R_2_5_21b50 = g_profile_JR_CLOWN_FOR_PLAYER -R_2_5_1c780 = g_profile_FLOOR_JR_A -R_2_5_1cc30 = g_profile_FLOOR_JR_B -R_2_5_1cec8 = g_profile_FLOOR_JR_C -R_2_5_1d258 = g_profile_FLOOR_JR_C_MGR -R_2_5_15480 = g_profile_BOMB_JR_C -R_4_5_a680 = g_profile_EN_BOSS_KOOPA_JR_A -R_4_5_ad90 = g_profile_EN_BOSS_KOOPA_JR_B -R_4_5_b5d0 = g_profile_EN_BOSS_KOOPA_JR_C R_2_5_222e8 = g_profile_JR_FIRE -R_2_5_22624 = g_profile_JR_FLOOR_FIRE R_2_5_22618 = g_profile_JR_FLOOR_FIRE_MGR -R_2_5_216a4 = g_profile_JR_CLOWN_FOR_JR_C_DEMO +R_2_5_22624 = g_profile_JR_FLOOR_FIRE R_2_5_22cb8 = g_profile_KAMECK_FOR_AIRSHIP_DEMO -R_2_5_395f8 = g_profile_PEACH_FOR_AIRSHIP_DEMO +R_2_5_23338 = g_profile_KAMECK_FOR_CASTLE_DEMO +R_2_5_23980 = g_profile_KAMECK_MAGIC +R_2_5_23cc0 = g_profile_AC_KANBAN_ARROW +R_2_5_23e70 = g_profile_KATAMUKIYUKA +R_2_5_24078 = g_profile_KAWANAGARE +R_2_5_24158 = g_profile_KAZAN_MGR +R_2_5_24458 = g_profile_KAZAN_ROCK +R_2_5_24680 = g_profile_KERONPA_FIRE +R_2_5_248a0 = g_profile_KINOKO_LIFT +R_2_5_24b38 = g_profile_KINOKO_LIFT_PARENT +R_2_5_24c18 = g_profile_KOKOOPA_BALL +R_2_5_25188 = g_profile_KOKOOPA_RING +R_2_5_25520 = g_profile_KOKOOPA_SEARCH_FIRE +R_2_5_25830 = g_profile_KOKOOPA_THREEWAY_BLITZ +R_2_5_259a0 = g_profile_KOOPA_FIRE +R_2_5_25da8 = g_profile_KOOPA_JR_FOR_CASTLE_DEMO R_2_5_264e8 = g_profile_KOOPA_SHIP_FOR_AIRSHIP_DEMO -R_2_5_405c0 = g_profile_AC_WAKI_KILLER -R_2_5_404e0 = g_profile_WAKI_KERONPA -R_2_5_40ca0 = g_profile_AC_WAKI_PUKUPUKU -R_2_5_13a98 = g_profile_BELT_NEEDLE -R_2_5_1fb40 = g_profile_INTERMITTENT +R_2_5_26860 = g_profile_KOOPA_SHIP_FOR_CASTLE_DEMO +R_2_5_26cb0 = g_profile_LADDER +R_2_5_26e90 = g_profile_LARRY_FIRE +R_2_5_27460 = g_profile_LASTACTOR_STAGE +R_2_5_274b8 = g_profile_LEMMY_BALL +R_2_5_27db0 = g_profile_LEMMY_FOOTHOLD +R_2_5_27dbc = g_profile_LEMMY_FOOTHOLD_MAIN +R_2_5_28558 = g_profile_AC_LIFT_BALANCE +R_2_5_28768 = g_profile_LIFT_DOKAN +R_2_5_28a78 = g_profile_LIFT_DOWN_ON +R_2_5_28c28 = g_profile_LIFT_DOWN_ON_NORMAL +R_2_5_28d60 = g_profile_AC_LIFT_FALL +R_2_5_28f60 = g_profile_LIFT_HURIKO +R_2_5_291b0 = g_profile_LIFT_HURIKO_CENTER +R_2_5_292c8 = g_profile_AC_LIFT_ICE_SPRING +R_2_5_293a8 = g_profile_AC_LINE_LIFT +R_2_5_29590 = g_profile_AC_LIFT_OBJBG_HMOVE +R_2_5_2959c = g_profile_AC_LIFT_OBJBG_HMOVE_BIG +R_2_5_297b8 = g_profile_AC_LIFT_OBJBG_VMOVE +R_2_5_299d0 = g_profile_AC_LIFT_REMOCON_BALANCE +R_2_5_29cc0 = g_profile_AC_LIFT_REMOCON_BALANCE_CLINCH +R_2_5_29db0 = g_profile_AC_LIFT_REMOCON_SEESAW +R_2_5_29dbc = g_profile_AC_LIFT_BOSS_REMOCON_SEESAW +R_2_5_29fc0 = g_profile_AC_LIFT_REMOCON_XLINE +R_2_5_2a278 = g_profile_AC_LIFT_RIDE_HMOVE +R_2_5_2a480 = g_profile_LIFT_RIDE_OFF +R_2_5_2a710 = g_profile_AC_LIFT_RIDE_VMOVE +R_2_5_2a918 = g_profile_AC_LIFT_RIDEMOVE +R_2_5_2ab28 = g_profile_AC_LIFT_SCALES +R_2_5_2ae70 = g_profile_AC_LIFT_SCALES_STEP +R_2_5_2b1b8 = g_profile_AC_LIFT_SEESAW +R_2_5_2b3a0 = g_profile_AC_LIFT_SLIDE_KINOKO +R_2_5_2b7a8 = g_profile_AC_LIFT_SPINROTATION +R_2_5_2ba78 = g_profile_AC_LIFT_SPINROTATION_SYNC +R_2_5_2bbf8 = g_profile_LIFT_TORIDE_ROLL +R_2_5_2bdb0 = g_profile_AC_WAKILIFT +R_2_5_2beb8 = g_profile_AC_WAKILIFT_STEP +R_2_5_2bfa8 = g_profile_AC_LIFT_WATERWHEEL +R_2_5_2c1c0 = g_profile_EN_LIFT_WHEEL +R_2_5_2c350 = g_profile_LIFT_ZEN_HAMMER +R_2_5_2c490 = g_profile_LIFT_ZEN_KAITEN_KANAAMI +R_2_5_2c5e0 = g_profile_LIFT_ZEN_KAIHEI +R_2_5_2c8d0 = g_profile_LIFT_ZEN_SHIRO +R_2_5_2cb88 = g_profile_LIFT_ZEN_SHIRO_YOGAN +R_2_5_2ce90 = g_profile_LIFT_ZEN_SUISYA +R_2_5_2cfd0 = g_profile_AC_LIGHT_BLOCK +R_2_5_2d478 = g_profile_LINE_KINOKO_BLOCK +R_2_5_2d6a8 = g_profile_LINE_SPIN_LIFT +R_2_5_2d8b0 = g_profile_LINE_TRAIN +R_2_5_2dbc8 = g_profile_CASTLE_LUDWIG_BLITZ +R_2_5_2dbd4 = g_profile_CASTLE_LUDWIG_BLITZ_MGR +R_2_5_2ded0 = g_profile_MANHOLE +R_2_5_2e138 = g_profile_MANTA +R_2_5_2e4c0 = g_profile_MANTA_MGR +R_2_5_2e5a0 = g_profile_MANTA_MGR2 +R_2_5_2e748 = g_profile_MD_ACTOR +R_2_5_30688 = g_profile_MEGA_HAMMER +R_2_5_308f8 = g_profile_MIDDLE_BG_FOR_CASTLE_LUDWIG +R_2_5_30904 = g_profile_BOTTOM_BG_FOR_CASTLE_LUDWIG +R_2_5_30fa0 = g_profile_MINI_GAME_BALLOON +R_2_5_31410 = g_profile_MINI_GAME_BALLOON_STICK +R_2_5_31918 = g_profile_MINI_GAME_GUN_BATTERY_MGR +R_2_5_31928 = g_profile_MINI_GAME_GUN_BATTERY_MGR_OBJ +R_2_5_31ccc = g_profile_MINI_GAME_KINOPIO +R_2_5_320e8 = g_profile_MINI_GAME_WIRE_MESH +R_2_5_326d0 = g_profile_MINI_GAME_WIRE_MESH_MGR +R_2_5_326e0 = g_profile_MINI_GAME_WIRE_MESH_MGR_OBJ R_2_5_32b38 = g_profile_MIST_INTERMITTENT -R_2_5_4b680 = g_profile_YOGAN_INTERMITTENT -R_3_5_19870 = g_profile_EN_IBARAMUSHI -R_2_5_3ffd0 = g_profile_WAKI_ANKOH -R_3_5_a740 = g_profile_EN_CHOCHIN_ANKOH -R_3_5_26eb0 = g_profile_EN_MISTMAN -R_3_5_35630 = g_profile_EN_TESTMAN -R_3_5_b9f8 = g_profile_EN_CLOUD -R_2_5_1fe88 = g_profile_AC_ITEM_KEY -R_2_5_4ba88 = g_profile_AC_YOSHI_EGG -R_3_5_398c0 = g_profile_EN_WATERPAIPO -R_3_5_39c28 = g_profile_EN_WATERPAKKUN -R_2_5_1d998 = g_profile_FOO_BALL +R_2_5_32c18 = g_profile_MOUSE_HOLE R_2_5_32d20 = g_profile_MT_HANACHAN -R_3_5_30900 = g_profile_EN_LR_STOP_UP -R_3_5_3090c = g_profile_EN_LR_STOP_DW -R_3_5_30f08 = g_profile_EN_ROT_PAKKUN -R_3_5_2d5f0 = g_profile_EN_POLTER -R_3_5_1a378 = g_profile_EN_ICICLE -R_2_5_414b0 = g_profile_WALLINSECT_MGR -R_3_5_38540 = g_profile_EN_WALLINSECT -R_3_5_228b8 = g_profile_EN_LANDBARREL -R_3_5_1c520 = g_profile_EN_IWAO -R_2_5_200e0 = g_profile_IWAO_ROCK -R_2_5_24158 = g_profile_KAZAN_MGR -R_2_5_24458 = g_profile_KAZAN_ROCK -R_3_5_9d58 = g_profile_EN_CANNON_BULLET -R_3_5_afa8 = g_profile_EN_CHOROPU -R_3_5_25268 = g_profile_EN_MANHOLE_CHOROPU -R_2_5_19ef8 = g_profile_CHOROPOO_SHADOW -R_2_5_30fa0 = g_profile_MINI_GAME_BALLOON -R_2_5_31410 = g_profile_MINI_GAME_BALLOON_STICK -R_3_5_1c7b0 = g_profile_EN_JELLY_FISH -R_2_5_320e8 = g_profile_MINI_GAME_WIRE_MESH -R_2_5_31918 = g_profile_MINI_GAME_GUN_BATTERY_MGR -R_2_5_31928 = g_profile_MINI_GAME_GUN_BATTERY_MGR_OBJ -R_2_5_326d0 = g_profile_MINI_GAME_WIRE_MESH_MGR -R_2_5_326e0 = g_profile_MINI_GAME_WIRE_MESH_MGR_OBJ +R_2_5_32e10 = g_profile_NEEDLE_FOR_KOOPA_JR_B +R_2_5_332f8 = g_profile_AC_NEXTGOTO_BLOCK +R_2_5_33468 = g_profile_NICE_BOAT +R_2_5_33778 = g_profile_AC_NICE_COIN +R_2_5_33784 = g_profile_AC_NICE_COIN_REGULAR +R_2_5_33930 = g_profile_NOBORIBOU_OBAKE +R_2_5_33a58 = g_profile_NUT +R_2_5_33c10 = g_profile_OBJ_CENTER +R_2_5_33cf0 = g_profile_OBJ_CENTER2 +R_2_5_33ee8 = g_profile_AC_OBJ_CLEAR_BLOCK +R_2_5_343e0 = g_profile_OBJ_GRASS +R_2_5_345a0 = g_profile_OBJ_IGGY_SLED +R_2_5_34a50 = g_profile_OBJ_IGGY_WANWAN +R_2_5_35138 = g_profile_OBJ_KAMECK +R_2_5_35ee8 = g_profile_OBJ_KINOKO +R_2_5_36070 = g_profile_OBJ_LARRY +R_2_5_36578 = g_profile_OBJ_LUDWIG +R_2_5_369e0 = g_profile_OBJ_MORTON +R_2_5_371b0 = g_profile_OBJ_MOVE_ON_GHOST +R_2_5_372e8 = g_profile_OBJ_PIPE_DOWN +R_2_5_373c8 = g_profile_OBJ_PIPE_LEFT +R_2_5_374a8 = g_profile_OBJ_PIPE_RIGHT +R_2_5_37588 = g_profile_OBJ_PIPE_UP +R_2_5_37668 = g_profile_OBJ_PIPE_UP_NG +R_2_5_37748 = g_profile_OBJ_ROY +R_2_5_37c70 = g_profile_OBJ_SEAWEED +R_2_5_37f48 = g_profile_OBJ_SNOW +R_2_5_382b8 = g_profile_OBJ_SPARKS +R_2_5_385e0 = g_profile_OBJ_SPIN_ASHIBA +R_2_5_38748 = g_profile_OBJ_SPIN_CHILD +R_2_5_38840 = g_profile_OBJ_SPIN_PARENT +R_2_5_38938 = g_profile_OBJ_WENDY +R_2_5_38d88 = g_profile_PALM_TREE +R_2_5_38ef0 = g_profile_PEACH_CASTLE_BLOCK R_2_5_39320 = g_profile_PEACH_CASTLE_SEQUENCE_MGR R_2_5_39330 = g_profile_PEACH_CASTLE_SEQUENCE_MGR_OBJ -R_2_5_38ef0 = g_profile_PEACH_CASTLE_BLOCK -R_2_5_31ccc = g_profile_MINI_GAME_KINOPIO -R_2_5_23cc0 = g_profile_AC_KANBAN_ARROW -R_2_5_179d0 = g_profile_AC_WATER_BUBBLE -R_3_5_99c8 = g_profile_EN_BUBBLE_CONTROL -R_2_5_41318 = g_profile_AC_WAKI_WOODBOX -R_2_5_12d70 = g_profile_AC_AUTOSCROOL_SWICH +R_2_5_395f8 = g_profile_PEACH_FOR_AIRSHIP_DEMO +R_2_5_39ab8 = g_profile_PEACH_FOR_CASTLE_DEMO +R_2_5_39fa8 = g_profile_POW_BLOCK +R_2_5_3a2f0 = g_profile_AC_PROP_BLOCK +R_2_5_3a748 = g_profile_REMO_DOOR +R_2_5_3a960 = g_profile_REMO_LINE_LIFT +R_2_5_3ac10 = g_profile_REMO_SLIDE_DOOR +R_2_5_3ae38 = g_profile_AC_REVERSEBLOCK +R_2_5_3af18 = g_profile_RIVER_BARREL +R_2_5_3b008 = g_profile_RIVER_COIN +R_2_5_3b0f8 = g_profile_RIVER_ITEM +R_2_5_3b1e8 = g_profile_RIVER_LIFT +R_2_5_3b2d8 = g_profile_RIVER_MGR +R_2_5_3b3c8 = g_profile_RIVER_PAIPO +R_2_5_3b4b8 = g_profile_RIVER_PAKKUN +R_2_5_3b5a8 = g_profile_RIVER_PUKU +R_2_5_3b698 = g_profile_RIVER_STARCOIN +R_2_5_3b788 = g_profile_ROT_BARNAR +R_2_5_3b9f8 = g_profile_LIFT_ROTATION_FULL_CHIKA +R_2_5_3bb88 = g_profile_LIFT_ROTATION_FULL_COLOR +R_2_5_3bc98 = g_profile_LIFT_ROTATION_FULL_KINOKO +R_2_5_3bdf0 = g_profile_AC_HOUSE_LIGHT +R_2_5_3bf70 = g_profile_AC_ROT_CANNON +R_2_5_3c218 = g_profile_ROT_DOKAN +R_2_5_3c438 = g_profile_AC_ROT_DOKAN_CANNON R_2_5_3c730 = g_profile_AC_ROTATION_GHOST_PARENT -R_3_5_31198 = g_profile_EN_ROTATION_GHOST +R_2_5_3c9b8 = g_profile_AC_SHIP_CANNON +R_2_5_3cc98 = g_profile_AC_SHIP_GEAR R_2_5_3ce50 = g_profile_SHIP_WINDOW -R_3_5_24cd8 = g_profile_EN_MADOPU +R_2_5_3cf40 = g_profile_SINKDOKAN_DOWN +R_2_5_3d048 = g_profile_SINKDOKAN_LEFT +R_2_5_3d150 = g_profile_SINKDOKAN_RIGHT +R_2_5_3d258 = g_profile_SINKDOKAN_UP +R_2_5_3d360 = g_profile_SLIDE_BLOCK +R_2_5_3d850 = g_profile_SLIP_PENGUIN2_GLASSES +R_2_5_3da40 = g_profile_SLOW_QUICK_TAG +R_2_5_3db20 = g_profile_AC_LIGHT_WATER R_2_5_3dcc8 = g_profile_SPANA -R_3_5_14a70 = g_profile_EN_GABON -R_2_5_1e3e0 = g_profile_GABON_ROCK -R_2_5_2ded0 = g_profile_MANHOLE -R_2_5_13d10 = g_profile_BGM_INTERLOCKING_DUMMY_BLOCK -R_2_5_142d0 = g_profile_BGM_INTERLOCKING_DUMMY_BLOCK_MGR -R_3_5_216e8 = g_profile_EN_KING_KILLER -R_3_5_39578 = g_profile_EN_WATER_BUBBLE_BULLET -R_3_5_14658 = g_profile_EN_FRUIT -R_2_5_382b8 = g_profile_OBJ_SPARKS -R_2_5_37f48 = g_profile_OBJ_SNOW +R_2_5_3df28 = g_profile_SPIN_WIRE +R_2_5_3e060 = g_profile_AC_STAND +R_2_5_3e1f8 = g_profile_AC_STRONGBOX +R_2_5_3e738 = g_profile_TAG_ENVSOUND R_2_5_3e9c8 = g_profile_TAG_SCROLL -R_2_5_14b90 = g_profile_AC_BLOCK_GROUP -R_2_5_14e70 = g_profile_AC_BLOCK_ONEUP -R_2_5_14ab0 = g_profile_AC_BLOCK_COIN -R_2_5_40e60 = g_profile_AC_WAKI_SEARCH_MAGKILLER -R_3_5_359e0 = g_profile_EN_TOBIPUKU -R_2_5_410c8 = g_profile_AC_WAKI_TOBIPUKU -R_2_5_32e10 = g_profile_NEEDLE_FOR_KOOPA_JR_B +R_2_5_3eaa8 = g_profile_TAG_THUNDER +R_2_5_3eb88 = g_profile_TAG_WATER +R_2_5_3ec68 = g_profile_TAG_WIND +R_2_5_3ed48 = g_profile_TARZAN_ROPE +R_2_5_3ee28 = g_profile_TARZAN_TSUTA +R_2_5_3efc8 = g_profile_TARZAN_IVY +R_2_5_3f1d0 = g_profile_AC_TEAM_PUKUPUKU R_2_5_3f340 = g_profile_TOP_BG_FOR_CASTLE_LUDWIG -R_2_5_308f8 = g_profile_MIDDLE_BG_FOR_CASTLE_LUDWIG -R_2_5_30904 = g_profile_BOTTOM_BG_FOR_CASTLE_LUDWIG -R_2_5_2e748 = g_profile_MD_ACTOR -R_2_5_4c7a0 = g_profile_MD_CAMERA -R_3_5_bd98 = g_profile_EN_CLOUDLT -R_2_5_3fbb8 = g_profile_UNIT_RAIL +R_2_5_3f6d0 = g_profile_TORCHILIGHT +R_2_5_3f880 = g_profile_TORIDE_KOKOOPA_DEMO R_2_5_3faf8 = g_profile_UNIT_CHIKUWA -R_2_5_37c70 = g_profile_OBJ_SEAWEED -R_2_5_3e738 = g_profile_TAG_ENVSOUND -R_3_5_c0c8 = g_profile_EN_COIN -R_3_5_d930 = g_profile_EN_COIN_JUGEM -R_3_5_e000 = g_profile_EN_COIN_JUMP -R_3_5_d268 = g_profile_EN_COIN_FLOOR -R_3_5_e678 = g_profile_EN_COIN_VOLT -R_3_5_f370 = g_profile_EN_COIN_WIND -R_3_5_7740 = g_profile_EN_BLUE_COIN -R_3_5_ecf8 = g_profile_EN_COIN_WATER -R_3_5_2f978 = g_profile_EN_REDCOIN -R_3_5_172e8 = g_profile_EN_GREENCOIN -R_2_5_2cfd0 = g_profile_AC_LIGHT_BLOCK -R_2_5_3a2f0 = g_profile_AC_PROP_BLOCK -R_2_5_3d360 = g_profile_SLIDE_BLOCK -R_2_5_39fa8 = g_profile_POW_BLOCK -R_2_5_14f50 = g_profile_BLOCK_TARU -R_2_5_33c10 = g_profile_OBJ_CENTER -R_2_5_33cf0 = g_profile_OBJ_CENTER2 -R_3_5_30b98 = g_profile_EN_LIFT_ROTATION_FULL -R_2_5_3b9f8 = g_profile_LIFT_ROTATION_FULL_CHIKA -R_2_5_3bc98 = g_profile_LIFT_ROTATION_FULL_KINOKO -R_2_5_3bb88 = g_profile_LIFT_ROTATION_FULL_COLOR -R_2_5_17ac0 = g_profile_CAGE_BLOCK -R_2_5_2c350 = g_profile_LIFT_ZEN_HAMMER -R_2_5_2ce90 = g_profile_LIFT_ZEN_SUISYA -R_2_5_2c490 = g_profile_LIFT_ZEN_KAITEN_KANAAMI -R_2_5_32c18 = g_profile_MOUSE_HOLE -R_2_5_23e70 = g_profile_KATAMUKIYUKA -R_2_5_2bbf8 = g_profile_LIFT_TORIDE_ROLL -R_2_5_2a278 = g_profile_AC_LIFT_RIDE_HMOVE -R_2_5_297b8 = g_profile_AC_LIFT_OBJBG_VMOVE -R_2_5_29590 = g_profile_AC_LIFT_OBJBG_HMOVE -R_2_5_2959c = g_profile_AC_LIFT_OBJBG_HMOVE_BIG -R_3_5_29460 = g_profile_EN_OBJ_POL -R_3_5_2a980 = g_profile_EN_OBJ_POL_TORIDE -R_3_5_29930 = g_profile_EN_OBJ_POL_NEEDLE_L -R_3_5_2993c = g_profile_EN_OBJ_POL_NEEDLE_R -R_3_5_29948 = g_profile_EN_OBJ_POL_NEEDLE_LR -R_3_5_29954 = g_profile_EN_OBJ_POL_NEEDLE_U -R_3_5_29960 = g_profile_EN_OBJ_POL_NEEDLE_D -R_3_5_2996c = g_profile_EN_OBJ_POL_NEEDLE_UD -R_3_5_241a0 = g_profile_LIFT_ZEN_TOGE -R_2_5_2cb88 = g_profile_LIFT_ZEN_SHIRO_YOGAN -R_2_5_2c5e0 = g_profile_LIFT_ZEN_KAIHEI -R_2_5_28768 = g_profile_LIFT_DOKAN -R_3_5_2bad8 = g_profile_EN_PAIR_OBJ_PARENT -R_3_5_2b450 = g_profile_EN_PAIR_OBJ_CHILD -R_2_5_2c8d0 = g_profile_LIFT_ZEN_SHIRO -R_3_5_2b830 = g_profile_EN_PAIR_OBJ_CHILD_TORIDE +R_2_5_3fbb8 = g_profile_UNIT_RAIL +R_2_5_3feb8 = g_profile_UNTEI_ROPE +R_2_5_3ffd0 = g_profile_WAKI_ANKOH +R_2_5_401b8 = g_profile_WAKI_FIRE R_2_5_40320 = g_profile_WAKI_ICE_ASHIBA R_2_5_40400 = g_profile_WAKI_ICE_ASHIBA_WATER -R_2_5_1f0f0 = g_profile_ICE_ASHIBA -R_2_5_1f2e0 = g_profile_ICE_ASHIBA_WATER -R_2_5_1f1e8 = g_profile_ICE_ASHIBA_RAIL -R_2_5_2a710 = g_profile_AC_LIFT_RIDE_VMOVE -R_2_5_2b1b8 = g_profile_AC_LIFT_SEESAW -R_2_5_28d60 = g_profile_AC_LIFT_FALL -R_2_5_29db0 = g_profile_AC_LIFT_REMOCON_SEESAW -R_2_5_2c1c0 = g_profile_EN_LIFT_WHEEL -R_2_5_28558 = g_profile_AC_LIFT_BALANCE -R_2_5_29cc0 = g_profile_AC_LIFT_REMOCON_BALANCE_CLINCH -R_2_5_299d0 = g_profile_AC_LIFT_REMOCON_BALANCE -R_2_5_29fc0 = g_profile_AC_LIFT_REMOCON_XLINE -R_3_5_23b48 = g_profile_EN_LIFT_REMOCON_TRPLN -R_3_5_36da8 = g_profile_EN_TRPLN_WALL -R_3_5_a380 = g_profile_EN_CHIKUWA_BLOCK -R_3_5_b628 = g_profile_EN_CLIFF_CHIKUWA_BLOCK -R_3_5_2127c = g_profile_EN_KILLER_HOUDAI -R_3_5_21270 = g_profile_EN_MAGNUM_KILLER_HOUDAI -R_2_5_2beb8 = g_profile_AC_WAKILIFT_STEP -R_2_5_293a8 = g_profile_AC_LINE_LIFT -R_2_5_2d6a8 = g_profile_LINE_SPIN_LIFT -R_2_5_38d88 = g_profile_PALM_TREE -R_2_5_33468 = g_profile_NICE_BOAT -R_2_5_2d478 = g_profile_LINE_KINOKO_BLOCK -R_2_5_26cb0 = g_profile_LADDER -R_2_5_3ee28 = g_profile_TARZAN_TSUTA -R_2_5_3efc8 = g_profile_TARZAN_IVY -R_3_5_23c98 = g_profile_EN_LIFT_ROTATION_HALF -R_2_5_291b0 = g_profile_LIFT_HURIKO_CENTER -R_2_5_28f60 = g_profile_LIFT_HURIKO -R_2_5_2a918 = g_profile_AC_LIFT_RIDEMOVE -R_3_5_233e0 = g_profile_EN_LIFT_BURANKO -R_2_5_2bfa8 = g_profile_AC_LIFT_WATERWHEEL -R_3_5_2f030 = g_profile_EN_RAIL_POLYGON -R_3_5_2e990 = g_profile_EN_RAIL_POLY_ICE -R_3_5_2edd8 = g_profile_EN_RAIL_POLY_PARENT -R_3_5_2e480 = g_profile_EN_RAIL_POLY_CHILD -R_2_5_1de78 = g_profile_FREEFALL -R_3_5_176a8 = g_profile_EN_GURA_ROCK -R_3_5_178d0 = g_profile_EN_GURA_YUKA -R_3_5_1ee90 = g_profile_EN_KAITEN_HOUDAI -R_3_5_2f580 = g_profile_EN_REDRING -R_3_5_1530 = g_profile_EN_BARREL -R_3_5_1e470 = g_profile_EN_JUMPDAI -R_3_5_190ec = g_profile_EN_BIG_HNSWICH -R_3_5_3600 = g_profile_EN_BIGBLOCK -R_3_5_33680 = g_profile_EN_SNAKEBLOCK -R_3_5_25930 = g_profile_EN_MARUTA -R_2_5_35138 = g_profile_OBJ_KAMECK -R_2_5_2b7a8 = g_profile_AC_LIFT_SPINROTATION -R_2_5_2ba78 = g_profile_AC_LIFT_SPINROTATION_SYNC -R_3_5_315d0 = g_profile_EN_RULETBLOCK -R_2_5_2ab28 = g_profile_AC_LIFT_SCALES -R_2_5_2ae70 = g_profile_AC_LIFT_SCALES_STEP -R_3_5_34ee0 = g_profile_EN_TARZANROPE -R_2_5_29dbc = g_profile_AC_LIFT_BOSS_REMOCON_SEESAW -R_2_5_19e08 = g_profile_AC_CHENGE_BLOCK -R_3_5_142e0 = g_profile_EN_FIXATION_ICICLE -R_3_5_28ce8 = g_profile_EN_OBJ_HATENA_BLOCK -R_3_5_28cf4 = g_profile_EN_OBJ_HATENAB_BLOCK -R_3_5_28d00 = g_profile_EN_OBJ_RENGA_BLOCK -R_3_5_28d0c = g_profile_EN_OBJ_CLEAR_BLOCK -R_2_5_33ee8 = g_profile_AC_OBJ_CLEAR_BLOCK -R_3_5_28d18 = g_profile_EN_HATENA_BLOCK_LINE -R_3_5_28d24 = g_profile_EN_RENGA_BLOCK_LINE -R_3_5_7388 = g_profile_EN_BLOCK_HATENA_WATER -R_3_5_6650 = g_profile_EN_BLOCK_SOROBAN -R_3_5_6a40 = g_profile_EN_BLOCK_STAFFROLL -R_2_5_1afc8 = g_profile_ELASTIC_KINOKO_PARENT -R_2_5_1abc8 = g_profile_ELASTIC_KINOKO -R_3_5_3a400 = g_profile_EN_WHITE_BLOCK -R_2_5_2e4c0 = g_profile_MANTA_MGR -R_2_5_2e5a0 = g_profile_MANTA_MGR2 -R_2_5_2e138 = g_profile_MANTA -R_2_5_2b3a0 = g_profile_AC_LIFT_SLIDE_KINOKO -R_3_5_2ac20 = g_profile_EN_ROTATION_BLOCK -R_3_5_cba0 = g_profile_EN_COIN_ANGLE -R_2_5_3c218 = g_profile_ROT_DOKAN -R_3_5_59e0 = g_profile_EN_BLOCK_HATENA_ANGLE -R_3_5_59ec = g_profile_EN_BLOCK_RENGA_ANGLE -R_2_5_428b8 = g_profile_AC_WIRE_CIRCLE -R_2_5_42db8 = g_profile_AC_WIRE_REMOCON -R_2_5_292c8 = g_profile_AC_LIFT_ICE_SPRING -R_2_5_1f940 = g_profile_ICELUMP -R_2_5_1f5a8 = g_profile_ICECUBE -R_3_5_3ac78 = g_profile_EN_WOODBOX -R_3_5_2ccd0 = g_profile_EN_PATAMET -R_3_5_2ccdc = g_profile_EN_BIG_PATAMET -R_2_5_33a58 = g_profile_NUT -R_3_5_2e98 = g_profile_EN_BIG_MET -R_3_5_14f98 = g_profile_EN_GAKE_NOKO -R_2_5_1a5e8 = g_profile_AC_DOKAN_CANNON -R_2_5_3c9b8 = g_profile_AC_SHIP_CANNON -R_2_5_3bf70 = g_profile_AC_ROT_CANNON -R_2_5_3c438 = g_profile_AC_ROT_DOKAN_CANNON -R_2_5_3b788 = g_profile_ROT_BARNAR -R_2_5_1a4e8 = g_profile_CIRCLE_RIGHT -R_2_5_14c70 = g_profile_BLOCK_LIGHT -R_2_5_1ee78 = g_profile_HAND_RIGHT -R_3_5_2850 = g_profile_EN_BIG_ICICLE -R_2_5_41e10 = g_profile_AC_WATER_BUBBLE_PARENT -R_2_5_41c00 = g_profile_AC_WATER_BUBBLE_CANNON -R_3_5_21288 = g_profile_EN_KILLER_HOUDAI_SLIDE -R_3_5_51c8 = g_profile_EN_BLACK_PAKKUN -R_2_5_3f6d0 = g_profile_TORCHILIGHT -R_3_5_5e38 = g_profile_EN_BLOCK_CLOUD -R_2_5_42b58 = g_profile_AC_WIRE_MOVE -R_3_5_8b68 = g_profile_EN_BOUNCE_BALL -R_3_5_627c = g_profile_EN_BLOCK_HATENA_PLAYER -R_3_5_6288 = g_profile_EN_BLOCK_RENGA_PLAYER -R_2_5_1e048 = g_profile_AC_FREEZER -R_2_5_42a48 = g_profile_AC_WIRE_FOOTHOLD -R_3_5_1c108 = g_profile_EN_ITEM_IVY -R_2_5_3ed48 = g_profile_TARZAN_ROPE -R_2_5_17c68 = g_profile_CANNON_PIPE -R_2_5_24b38 = g_profile_KINOKO_LIFT_PARENT -R_2_5_248a0 = g_profile_KINOKO_LIFT -R_2_5_38840 = g_profile_OBJ_SPIN_PARENT -R_2_5_38748 = g_profile_OBJ_SPIN_CHILD -R_2_5_385e0 = g_profile_OBJ_SPIN_ASHIBA -R_2_5_3df28 = g_profile_SPIN_WIRE +R_2_5_404e0 = g_profile_WAKI_KERONPA +R_2_5_405c0 = g_profile_AC_WAKI_KILLER +R_2_5_40728 = g_profile_WAKI_KOKOOPA_FIRE +R_2_5_408b8 = g_profile_AC_WAKI_KOOPA_FIRE +R_2_5_40ab0 = g_profile_WAKI_PARABOM +R_2_5_40ca0 = g_profile_AC_WAKI_PUKUPUKU +R_2_5_40e60 = g_profile_AC_WAKI_SEARCH_MAGKILLER +R_2_5_40fd0 = g_profile_WAKI_SLIP_PENGUIN2 +R_2_5_410c8 = g_profile_AC_WAKI_TOBIPUKU +R_2_5_41238 = g_profile_WAKI_TOGETEKKYU +R_2_5_41318 = g_profile_AC_WAKI_WOODBOX +R_2_5_414b0 = g_profile_WALLINSECT_MGR R_2_5_41740 = g_profile_WARP_CANNON -R_2_5_35ee8 = g_profile_OBJ_KINOKO -R_2_5_4c4a8 = g_profile_ZOOM_PIPE -R_2_5_4c588 = g_profile_ZOOM_PIPE_DOWN -R_2_5_37588 = g_profile_OBJ_PIPE_UP -R_2_5_37668 = g_profile_OBJ_PIPE_UP_NG -R_2_5_372e8 = g_profile_OBJ_PIPE_DOWN -R_2_5_374a8 = g_profile_OBJ_PIPE_RIGHT -R_2_5_373c8 = g_profile_OBJ_PIPE_LEFT -R_2_5_28a78 = g_profile_LIFT_DOWN_ON -R_2_5_371b0 = g_profile_OBJ_MOVE_ON_GHOST -R_2_5_28c28 = g_profile_LIFT_DOWN_ON_NORMAL -R_2_5_2a480 = g_profile_LIFT_RIDE_OFF -R_2_5_2d8b0 = g_profile_LINE_TRAIN -R_2_5_3a960 = g_profile_REMO_LINE_LIFT +R_2_5_41c00 = g_profile_AC_WATER_BUBBLE_CANNON +R_2_5_41e10 = g_profile_AC_WATER_BUBBLE_PARENT R_2_5_41f80 = g_profile_WATER_LIFT -R_2_5_33778 = g_profile_AC_NICE_COIN -R_2_5_33784 = g_profile_AC_NICE_COIN_REGULAR -R_3_5_391d0 = g_profile_EN_BLOCK_HELP -R_2_5_12880 = g_profile_AC_BG_WATER -R_2_5_1288c = g_profile_AC_BG_LAVA -R_2_5_12898 = g_profile_AC_BG_POISON -R_2_5_128a4 = g_profile_AC_BG_SAND -R_2_5_128b0 = g_profile_AC_BG_CLOUD -R_2_5_128bc = g_profile_AC_BG_MOYA -R_2_5_42630 = g_profile_AC_WATERALL_RAIL -R_3_5_7e30 = g_profile_EN_BLUR -R_2_5_51b28 = g_profile_DTEST R_2_5_42128 = g_profile_AC_WATER_MOVE R_2_5_42134 = g_profile_AC_WATER_MOVE_REGULAR R_2_5_423a0 = g_profile_AC_WATER_XINFINITE_MOVE -R_2_5_1c238 = g_profile_AC_FLOOR_GYRATION -R_2_5_1c528 = g_profile_AC_FLOOR_HOLE_DOKAN -R_2_5_1bf38 = g_profile_AC_FLOOR_DOKAN_EIGHT -R_2_5_1e800 = g_profile_AC_GEAR_GYRATION -R_2_5_3cc98 = g_profile_AC_SHIP_GEAR -R_2_5_14548 = g_profile_AC_BIGSHELL -R_4_5_9500 = g_profile_EN_BOSS_KOOPA_DEMO_CAGE -R_2_5_3e060 = g_profile_AC_STAND -R_2_5_3bdf0 = g_profile_AC_HOUSE_LIGHT -R_2_5_3db20 = g_profile_AC_LIGHT_WATER -R_2_5_14918 = g_profile_AC_COPYRIGHT -R_2_5_4c70c = g_profile_WM_CS_SEQ_MNG -R_2_5_50c48 = g_profile_WORLD_CAMERA -R_2_5_46490 = g_profile_WM_MAP -R_2_5_49cdc = g_profile_WM_IBARA +R_2_5_42630 = g_profile_AC_WATERALL_RAIL +R_2_5_428b8 = g_profile_AC_WIRE_CIRCLE +R_2_5_42a48 = g_profile_AC_WIRE_FOOTHOLD +R_2_5_42b58 = g_profile_AC_WIRE_MOVE +R_2_5_42db8 = g_profile_AC_WIRE_REMOCON +R_2_5_43010 = g_profile_WM_2D_PLAYER +R_2_5_436e0 = g_profile_WM_ANCHOR +R_2_5_437bc = g_profile_WM_ANTLION R_2_5_43954 = g_profile_WM_ANTLION_MNG +R_2_5_43a20 = g_profile_WM_BOARD +R_2_5_43b8c = g_profile_WM_BUBBLE R_2_5_44004 = g_profile_WM_CASTLE -R_2_5_480b4 = g_profile_WM_TOWER -R_2_5_46974 = g_profile_WM_PEACH_CASTLE +R_2_5_442b0 = g_profile_WM_CLOUD +R_2_5_44434 = g_profile_WM_COURSE +R_2_5_445c4 = g_profile_WM_DANCE_PAKKUN +R_2_5_44a9c = g_profile_WM_GHOST +R_2_5_44cb4 = g_profile_WM_GRID +R_2_5_44d54 = g_profile_WM_HANACHAN +R_2_5_44f10 = g_profile_WM_ISLAND +R_2_5_45030 = g_profile_WM_ITEM R_2_5_45270 = g_profile_WM_KILLER R_2_5_4541c = g_profile_WM_KILLERBULLET -R_2_5_471b4 = g_profile_WM_SINKSHIP -R_2_5_47a0c = g_profile_WM_SWITCH -R_2_5_47484 = g_profile_WM_START +R_2_5_45664 = g_profile_WM_KINOBALLOON +R_2_5_457ec = g_profile_WM_KINOKO_1UP R_2_5_458e4 = g_profile_WM_KINOKO_BASE R_2_5_45ab4 = g_profile_WM_KINOKO_RED -R_2_5_457ec = g_profile_WM_KINOKO_1UP R_2_5_45bbc = g_profile_WM_KINOKO_STAR -R_2_5_44434 = g_profile_WM_COURSE +R_2_5_45cc0 = g_profile_WM_KINOPIO +R_2_5_45e0c = g_profile_WM_KOOPAJR +R_2_5_45fd8 = g_profile_WM_KOOPASHIP +R_2_5_46378 = g_profile_WM_MANTA +R_2_5_46490 = g_profile_WM_MAP +R_2_5_467a4 = g_profile_WM_NOTE +R_2_5_46890 = g_profile_WM_PEACH +R_2_5_46974 = g_profile_WM_PEACH_CASTLE +R_2_5_46c14 = g_profile_WM_SANDPILLAR +R_2_5_471b4 = g_profile_WM_SINKSHIP +R_2_5_4728c = g_profile_WM_SMALLCLOUD +R_2_5_47484 = g_profile_WM_START R_2_5_47530 = g_profile_WM_STOP +R_2_5_475ec = g_profile_WM_SUBPLAYER +R_2_5_47a0c = g_profile_WM_SWITCH +R_2_5_47b9c = g_profile_WM_TERESA +R_2_5_47df4 = g_profile_WM_TOGEZO R_2_5_47ec4 = g_profile_WM_TORIDE -R_2_5_44a9c = g_profile_WM_GHOST -R_2_5_45fd8 = g_profile_WM_KOOPASHIP +R_2_5_480b4 = g_profile_WM_TOWER +R_2_5_4818c = g_profile_WM_TREASURESHIP +R_2_5_4825c = g_profile_WM_YOGANPILLAR R_2_5_485fc = g_profile_WM_BOSS_BASE -R_2_5_48cd8 = g_profile_WM_BOSS_LARRY -R_2_5_492c4 = g_profile_WM_BOSS_ROY -R_2_5_49440 = g_profile_WM_BOSS_WENDY R_2_5_488c8 = g_profile_WM_BOSS_IGGY +R_2_5_48ae4 = g_profile_WM_BOSS_KAMECK +R_2_5_48cd8 = g_profile_WM_BOSS_LARRY R_2_5_48e58 = g_profile_WM_BOSS_LEMMY -R_2_5_49150 = g_profile_WM_BOSS_MORTON R_2_5_48fd8 = g_profile_WM_BOSS_LUDWIG -R_2_5_48ae4 = g_profile_WM_BOSS_KAMECK -R_2_5_437bc = g_profile_WM_ANTLION -R_2_5_4a4ac = g_profile_WM_KURIBO -R_2_5_4b234 = g_profile_WM_PUKU -R_2_5_4a6b4 = g_profile_WM_PAKKUN +R_2_5_49150 = g_profile_WM_BOSS_MORTON +R_2_5_492c4 = g_profile_WM_BOSS_ROY +R_2_5_49440 = g_profile_WM_BOSS_WENDY R_2_5_49640 = g_profile_WM_BROS -R_2_5_4a134 = g_profile_WM_JUGEM -R_2_5_4ab5c = g_profile_WM_PLAYER -R_2_5_475ec = g_profile_WM_SUBPLAYER -R_2_5_467a4 = g_profile_WM_NOTE -R_2_5_4818c = g_profile_WM_TREASURESHIP -R_2_5_49958 = g_profile_WM_DIRECTOR -R_2_5_44cb4 = g_profile_WM_GRID -R_2_5_44f10 = g_profile_WM_ISLAND -R_2_5_45030 = g_profile_WM_ITEM R_2_5_497e4 = g_profile_WM_CS_W3_PALM -R_2_5_4b514 = g_profile_WM_SURRENDER +R_2_5_49958 = g_profile_WM_DIRECTOR +R_2_5_49cdc = g_profile_WM_IBARA +R_2_5_4a134 = g_profile_WM_JUGEM R_2_5_4a2f4 = g_profile_WM_KOOPA_CASTLE -R_2_5_436e0 = g_profile_WM_ANCHOR +R_2_5_4a4ac = g_profile_WM_KURIBO +R_2_5_4a6b4 = g_profile_WM_PAKKUN R_2_5_4a8e0 = g_profile_WM_PAKKUNHEAD -R_2_5_442b0 = g_profile_WM_CLOUD -R_2_5_4728c = g_profile_WM_SMALLCLOUD -R_2_5_45e0c = g_profile_WM_KOOPAJR -R_2_5_46890 = g_profile_WM_PEACH -R_2_5_43a20 = g_profile_WM_BOARD -R_2_5_43b8c = g_profile_WM_BUBBLE -R_2_5_45664 = g_profile_WM_KINOBALLOON -R_2_5_46c14 = g_profile_WM_SANDPILLAR -R_2_5_4825c = g_profile_WM_YOGANPILLAR -R_2_5_45cc0 = g_profile_WM_KINOPIO -R_2_5_445c4 = g_profile_WM_DANCE_PAKKUN -R_2_5_44d54 = g_profile_WM_HANACHAN -R_2_5_47df4 = g_profile_WM_TOGEZO -R_2_5_46378 = g_profile_WM_MANTA -R_2_5_47b9c = g_profile_WM_TERESA +R_2_5_4ab5c = g_profile_WM_PLAYER +R_2_5_4b234 = g_profile_WM_PUKU +R_2_5_4b514 = g_profile_WM_SURRENDER +R_2_5_4b680 = g_profile_YOGAN_INTERMITTENT +R_2_5_4ba88 = g_profile_AC_YOSHI_EGG +R_2_5_4bfb0 = g_profile_YOSHI_FIRE +R_2_5_4c0e0 = g_profile_AC_ENDING_MAIN +R_2_5_4c4a8 = g_profile_ZOOM_PIPE +R_2_5_4c588 = g_profile_ZOOM_PIPE_DOWN +R_2_5_4c668 = g_profile_CAMERA +R_2_5_4c70c = g_profile_WM_CS_SEQ_MNG +R_2_5_4c7a0 = g_profile_MD_CAMERA +R_2_5_4c808 = g_profile_OTASUKE_INFO +R_2_5_4ce50 = g_profile_GAME_SETUP +R_2_5_4d3e0 = g_profile_MULTI_PLAY_COURSE_SELECT +R_2_5_4d778 = g_profile_RESULT +R_2_5_4da38 = g_profile_WORLD_9_DEMO +R_2_5_4dff8 = g_profile_CRSIN +R_2_5_4e710 = g_profile_GAMEOVER +R_2_5_4ea98 = g_profile_MOVIE +R_2_5_4f150 = g_profile_RESTART_CRSIN +R_2_5_4f238 = g_profile_STAGE +R_2_5_4fa70 = g_profile_WORLD_MAP R_2_5_4fff8 = g_profile_WORLD_SELECT R_2_5_506c8 = g_profile_WORLD_SELECT_GUIDE -R_2_5_1ba8 = g_profile_COLLECTION_COIN_BASE -R_2_5_1590 = g_profile_COLLECTION_COIN -R_2_5_3040 = g_profile_COURSE_SELECT_MENU -R_2_5_ce60 = g_profile_NUMBER_OF_PEOPLE_CHANGE -R_2_5_11508 = g_profile_STOCK_ITEM -R_2_5_11f30 = g_profile_STOCK_ITEM_SHADOW -R_2_5_48b8 = g_profile_EASY_PAIRING -R_2_5_43010 = g_profile_WM_2D_PLAYER -R_2_5_4ee0 = g_profile_EVENT_OPENING_TITLE -R_2_5_10198 = g_profile_SELECT_PLAYER -R_2_5_b1d0 = g_profile_MULTI_COURSE_SELECT -R_2_5_124e8 = g_profile_TIME_UP -R_2_5_36e0 = g_profile_COURSE_TIME_UP +R_2_5_50c48 = g_profile_WORLD_CAMERA R_2_5_50d5c = g_profile_COURSE_SELECT_MANAGER -R_2_5_4c808 = g_profile_OTASUKE_INFO -R_2_5_4d778 = g_profile_RESULT -R_2_5_f658 = g_profile_POINT_RESULT_MULTI -R_2_5_ddd0 = g_profile_POINT_RESULT_DATE_FILE -R_2_5_ef68 = g_profile_POINT_RESULT_DATE_FILE_FREE -R_2_5_29c0 = g_profile_COURSE_CLEAR -R_2_5_d97c = g_profile_OTEHON_CLEAR -R_2_5_7198 = g_profile_INFO_WINDOW -R_2_5_109c0 = g_profile_SEQUENCE_BG -R_2_5_6bf0 = g_profile_GAME_OVER -R_2_5_93b0 = g_profile_MODE_SELECT -R_2_5_3a98 = g_profile_DATE_FILE -R_2_5_5390 = g_profile_FILE_SELECT -R_2_5_2108 = g_profile_CONTINUE -R_2_5_7b78 = g_profile_MINI_GAME_CANNON -R_2_5_84a8 = g_profile_MINI_GAME_WIRE -R_2_5_a978 = g_profile_MODEL_PLAY_MANAGER -R_2_5_9db0 = g_profile_MODEL_PLAY_BASE -R_2_5_a3c0 = g_profile_MODEL_PLAY_DATE -R_2_5_98e0 = g_profile_MODEL_PLAY_ARROW -R_2_5_a890 = g_profile_MODEL_PLAY_GUIDE -R_2_5_77a0 = g_profile_MESSAGE_WINDOW -R_2_5_668 = g_profile_CHARACTER_CHANGE_SELECT_BASE -R_2_5_1130 = g_profile_CHARACTER_CHANGE_SELECT_CONTENTS -R_2_5_1c8 = g_profile_CHARACTER_CHANGE_SELECT_ARROW -R_2_5_0 = g_profile_CHARACTER_CHANGE_INDICATOR -R_2_5_c0f8 = g_profile_MULTI_COURSE_SELECT_CONTENTS -R_2_5_1d68 = g_profile_COLLECTION_COIN_DATE -R_2_5_4530 = g_profile_DRAW_GAME -R_2_5_10e58 = g_profile_STAFF_CREDIT_SCORE -R_2_5_121a8 = g_profile_THE_END -R_2_5_4180 = g_profile_DEMO_MESSAGE -R_2_5_72e0 = g_profile_LETTER_WINDOW -R_2_5_1a7f8 = g_profile_DUMMY_ACTOR -R_2_5_27460 = g_profile_LASTACTOR_STAGE +R_2_5_51b28 = g_profile_DTEST +R_2_5_51c20 = g_profile_WM_TEST +R_2_5_51c2c = g_profile_WM_TEST2 +R_3_1_f0 = finalizeProlog__Fv +R_3_1_100 = finalizeEpilog__Fv +R_3_1_780 = getPlrNo__8dActor_cFv +R_3_1_2710 = GetActorType__12dBaseActor_cFv +R_3_1_2720 = funsuiMoveX__8dActor_cFv +R_3_1_2730 = setCarryFall__8dActor_cFP8dActor_ci +R_3_1_2750 = vf68__8dActor_cFP9dBg_ctr_c +R_3_1_2760 = isFunsui__5dEn_cCFv +R_3_1_2770 = endFunsui__5dEn_cFv +R_3_1_2780 = beginFunsui__5dEn_cFv +R_3_1_2790 = calcBoyonScale__5dEn_cFv +R_3_1_2870 = getType__Q23m3d8anmChr_cCFv +R_3_1_33e0 = isQuakeDamage__5dEn_cFv +R_3_1_b4b0 = __dt__8dIceInfoFv +R_3_1_f360 = __dt__Q23m3d8anmChr_cFv +R_3_1_10ea0 = timingC__Q33m3d5mdl_c10callback_cFPQ34nw4r4math5MTX34Q34nw4r3g3d6ResMdl +R_3_1_10eb0 = timingB__Q33m3d5mdl_c10callback_cFUlPQ34nw4r3g3d13WorldMtxManipQ34nw4r3g3d6ResMdl +R_3_1_10ec0 = timingA__Q33m3d5mdl_c10callback_cFUlPQ34nw4r3g3d12ChrAnmResultQ34nw4r3g3d6ResMdl +R_3_1_c6240 = isBlockHitDeath__11daEnShell_cCFv +R_3_1_c6270 = isDieShell__11daEnShell_cFv +R_3_1_c6280 = kickEffect__11daEnShell_cF7mVec3_c +R_3_1_c62a0 = isFumiInvalid__11daEnShell_cCFv +R_3_1_c62b0 = specialFumiProc_Yoshi__11daEnShell_cFP8dActor_c +R_3_1_c62c0 = specialFumiProc__11daEnShell_cFP8dActor_c +R_3_1_c6230 = YoshiFumiScoreSet__11daEnShell_cFP8dActor_c +R_3_1_c62d0 = isSpinLiftUpEnable__11daEnShell_cFv +R_3_1_c6330 = boyonBegin__11daEnShell_cFv +R_3_5_0 = g_profile_EN_AKOYA +R_3_5_320 = __vt__Q23m3d8anmChr_c +R_3_5_618 = g_profile_EN_AUTOSCR +R_3_5_8a8 = g_profile_EN_BAKUBAKU +R_3_5_d48 = g_profile_EN_BARAMAKI_GESSO +R_3_5_10d8 = g_profile_EN_BARNAR +R_3_5_1530 = g_profile_EN_BARREL +R_3_5_1a98 = g_profile_EN_BASABASA +R_3_5_1ff0 = g_profile_EN_BEANS_KURIBO +R_3_5_2460 = g_profile_EN_BIG_HANACHAN +R_3_5_2730 = __vt__Q33m3d5mdl_c10callback_c +R_3_5_2850 = g_profile_EN_BIG_ICICLE +R_3_5_2e98 = g_profile_EN_BIG_MET +R_3_5_3210 = g_profile_EN_BIG_TOGETEKKYU +R_3_5_3600 = g_profile_EN_BIGBLOCK +R_3_5_3b28 = g_profile_EN_BIGPILE_LEFT +R_3_5_3dd8 = g_profile_EN_BIGPILE_RIGHT +R_3_5_4088 = g_profile_EN_BIGPILE_UNDER +R_3_5_4338 = g_profile_EN_BIGPILE_UPPER +R_3_5_45e8 = g_profile_EN_MORTON_BIGPILE +R_3_5_4b18 = g_profile_EN_BIRIKYU +R_3_5_4f38 = g_profile_EN_BIRIKYU_MAKER +R_3_5_51c8 = g_profile_EN_BLACK_PAKKUN +R_3_5_5568 = g_profile_EN_BLOCK +R_3_5_59e0 = g_profile_EN_BLOCK_HATENA_ANGLE +R_3_5_59ec = g_profile_EN_BLOCK_RENGA_ANGLE +R_3_5_5e38 = g_profile_EN_BLOCK_CLOUD +R_3_5_627c = g_profile_EN_BLOCK_HATENA_PLAYER +R_3_5_6288 = g_profile_EN_BLOCK_RENGA_PLAYER +R_3_5_6650 = g_profile_EN_BLOCK_SOROBAN +R_3_5_6a40 = g_profile_EN_BLOCK_STAFFROLL +R_3_5_6fa8 = g_profile_EN_BLSWICH +R_3_5_6fb4 = g_profile_EN_BLPSWICH +R_3_5_6fc0 = g_profile_EN_BLQSWICH +R_3_5_7388 = g_profile_EN_BLOCK_HATENA_WATER +R_3_5_7740 = g_profile_EN_BLUE_COIN +R_3_5_7e30 = g_profile_EN_BLUR +R_3_5_80c0 = g_profile_EN_BOMHEI +R_3_5_8838 = g_profile_EN_BOOMERANGBROS +R_3_5_8b68 = g_profile_EN_BOUNCE_BALL +R_3_5_8fa0 = g_profile_EN_BOYON +R_3_5_9230 = g_profile_EN_BKBLOCK +R_3_5_9528 = g_profile_EN_BUBBLE +R_3_5_99c8 = g_profile_EN_BUBBLE_CONTROL +R_3_5_9d58 = g_profile_EN_CANNON_BULLET +R_3_5_a088 = g_profile_EN_CASTLEDOOR +R_3_5_a380 = g_profile_EN_CHIKUWA_BLOCK +R_3_5_a740 = g_profile_EN_CHOCHIN_ANKOH +R_3_5_aba8 = g_profile_EN_CHOROBON +R_3_5_afa8 = g_profile_EN_CHOROPU +R_3_5_b628 = g_profile_EN_CLIFF_CHIKUWA_BLOCK +R_3_5_b9f8 = g_profile_EN_CLOUD +R_3_5_bd98 = g_profile_EN_CLOUDLT +R_3_5_c0c8 = g_profile_EN_COIN +R_3_5_cba0 = g_profile_EN_COIN_ANGLE +R_3_5_d268 = g_profile_EN_COIN_FLOOR +R_3_5_d930 = g_profile_EN_COIN_JUGEM +R_3_5_e000 = g_profile_EN_COIN_JUMP +R_3_5_e678 = g_profile_EN_COIN_VOLT +R_3_5_ecf8 = g_profile_EN_COIN_WATER +R_3_5_f370 = g_profile_EN_COIN_WIND +R_3_5_fa38 = g_profile_EN_CRASHER +R_3_5_10010 = g_profile_EN_CROW +R_3_5_105c0 = g_profile_EN_DOWN_DOKAN_FPAKKUN +R_3_5_10978 = g_profile_EN_LEFT_DOKAN_FPAKKUN +R_3_5_10d30 = g_profile_EN_RIGHT_DOKAN_FPAKKUN +R_3_5_110e8 = g_profile_EN_UP_DOKAN_FPAKKUN +R_3_5_11498 = g_profile_EN_DOWN_DOKAN_PAKKUN +R_3_5_11870 = g_profile_EN_LEFT_DOKAN_PAKKUN +R_3_5_11c48 = g_profile_EN_RIGHT_DOKAN_PAKKUN +R_3_5_12020 = g_profile_EN_UP_DOKAN_PAKKUN +R_3_5_123f0 = g_profile_EN_DOOR +R_3_5_126f8 = g_profile_EN_DOSUN +R_3_5_12704 = g_profile_EN_BIGDOSUN +R_3_5_12d30 = g_profile_EN_EATJUGEM +R_3_5_130a8 = g_profile_EN_ENV +R_3_5_13348 = g_profile_EN_FIREBROS +R_3_5_13678 = g_profile_EN_FIREBAR +R_3_5_13a18 = g_profile_EN_FIRESNAKE +R_3_5_142e0 = g_profile_EN_FIXATION_ICICLE +R_3_5_14658 = g_profile_EN_FRUIT +R_3_5_14a70 = g_profile_EN_GABON +R_3_5_14f98 = g_profile_EN_GAKE_NOKO +R_3_5_15520 = g_profile_EN_GESSO +R_3_5_15e88 = g_profile_EN_GESSO_CHILD +R_3_5_16340 = g_profile_EN_GHOST_JUGEM +R_3_5_165d0 = g_profile_EN_GOALPOLE +R_3_5_16a88 = g_profile_EN_GOKUBUTO_BIGPILE_UNDER +R_3_5_16eb8 = g_profile_EN_GOKUBUTO_BIGPILE_UPPER +R_3_5_172e8 = g_profile_EN_GREENCOIN +R_3_5_176a8 = g_profile_EN_GURA_ROCK +R_3_5_178d0 = g_profile_EN_GURA_YUKA +R_3_5_17a80 = g_profile_EN_GURUGURU +R_3_5_17dc0 = g_profile_EN_HAMMERBROS +R_3_5_18230 = g_profile_EN_HANACHAN +R_3_5_18718 = g_profile_EN_HELPOS +R_3_5_189a8 = g_profile_EN_HIMANBROS +R_3_5_190c8 = g_profile_EN_HNSWICH +R_3_5_190d4 = g_profile_EN_PSWICH +R_3_5_190e0 = g_profile_EN_QSWICH +R_3_5_190ec = g_profile_EN_BIG_HNSWICH +R_3_5_190f8 = g_profile_EN_BOSS_KOOPA_SWITCH +R_3_5_19104 = g_profile_EN_BOSS_KOOPA_BIG_SWITCH +R_3_5_19870 = g_profile_EN_IBARAMUSHI +R_3_5_19f90 = g_profile_EN_ICEBROS +R_3_5_1a378 = g_profile_EN_ICICLE +R_3_5_1a970 = g_profile_EN_IGA_KURIBO +R_3_5_1aef0 = g_profile_EN_IGAPUKU +R_3_5_1b3a8 = g_profile_EN_ITEM +R_3_5_1c108 = g_profile_EN_ITEM_IVY +R_3_5_1c520 = g_profile_EN_IWAO +R_3_5_1c7b0 = g_profile_EN_JELLY_FISH +R_3_5_1cd48 = g_profile_EN_JIMEN_BIG_FPAKKUN +R_3_5_1d020 = g_profile_EN_JIMEN_BIG_PAKKUN +R_3_5_1d2f0 = g_profile_EN_JIMEN_FPAKKUN +R_3_5_1d720 = g_profile_EN_JIMEN_PAKKUN +R_3_5_1db10 = g_profile_EN_JUGEM +R_3_5_1db1c = g_profile_EN_JUGEM_COIN +R_3_5_1dfd8 = g_profile_EN_JUGEM_BODY +R_3_5_1e470 = g_profile_EN_JUMPDAI +R_3_5_1e918 = g_profile_EN_JUMPPUKU +R_3_5_1ee90 = g_profile_EN_KAITEN_HOUDAI +R_3_5_1f1e8 = g_profile_EN_KANIBO +R_3_5_1f750 = g_profile_EN_KANITAMA +R_3_5_1fa40 = g_profile_EN_KARON +R_3_5_1fa4c = g_profile_EN_BIGKARON +R_3_5_200d8 = g_profile_EN_KARON_HEAD +R_3_5_20560 = g_profile_EN_KERONPA +R_3_5_20b70 = g_profile_EN_KILLER +R_3_5_20b7c = g_profile_EN_SEARCH_KILLER +R_3_5_20b88 = g_profile_EN_MAGNUM_KILLER +R_3_5_20b94 = g_profile_EN_SEARCH_MAGNUM_KILLER +R_3_5_21270 = g_profile_EN_MAGNUM_KILLER_HOUDAI +R_3_5_2127c = g_profile_EN_KILLER_HOUDAI +R_3_5_21288 = g_profile_EN_KILLER_HOUDAI_SLIDE +R_3_5_216e8 = g_profile_EN_KING_KILLER +R_3_5_21ac8 = g_profile_EN_KOOPADOOR +R_3_5_21dd0 = g_profile_EN_KOPONE +R_3_5_22370 = g_profile_EN_KURIBO +R_3_5_228b8 = g_profile_EN_LANDBARREL +R_3_5_22cb8 = g_profile_EN_LARGE_BARNAR +R_3_5_23090 = g_profile_EN_LARGE_KURIBO +R_3_5_233e0 = g_profile_EN_LIFT_BURANKO +R_3_5_23698 = g_profile_EN_LIFT_HAMMERBROS +R_3_5_23b48 = g_profile_EN_LIFT_REMOCON_TRPLN +R_3_5_23c98 = g_profile_EN_LIFT_ROTATION_HALF +R_3_5_241a0 = g_profile_LIFT_ZEN_TOGE +R_3_5_249a0 = g_profile_EN_LINE_BIRIKYU +R_3_5_24cd8 = g_profile_EN_MADOPU +R_3_5_24f68 = g_profile_EN_MAME_KURIBO +R_3_5_25268 = g_profile_EN_MANHOLE_CHOROPU +R_3_5_25930 = g_profile_EN_MARUTA +R_3_5_25be0 = g_profile_EN_MAX_UE_LEFT +R_3_5_25bec = g_profile_EN_MAX_UE_RIGHT +R_3_5_25bf8 = g_profile_EN_MAX_UE2_LEFT +R_3_5_25c04 = g_profile_EN_MAX_UE2_RIGHT +R_3_5_25e90 = g_profile_EN_MECHA_KOOPA +R_3_5_264a0 = g_profile_EN_MET +R_3_5_26a88 = g_profile_EN_MIDDLE_KURIBO +R_3_5_26eb0 = g_profile_EN_MISTMAN +R_3_5_27528 = g_profile_EN_MOUSE +R_3_5_27a30 = g_profile_EN_NET_NOKONOKO_LR +R_3_5_27dd0 = g_profile_EN_NET_NOKONOKO_UD +R_3_5_28250 = g_profile_EN_NOKONOKO +R_3_5_289d0 = g_profile_EN_OBAKEDOOR +R_3_5_28ce8 = g_profile_EN_OBJ_HATENA_BLOCK +R_3_5_28cf4 = g_profile_EN_OBJ_HATENAB_BLOCK +R_3_5_28d00 = g_profile_EN_OBJ_RENGA_BLOCK +R_3_5_28d0c = g_profile_EN_OBJ_CLEAR_BLOCK +R_3_5_28d18 = g_profile_EN_HATENA_BLOCK_LINE +R_3_5_28d24 = g_profile_EN_RENGA_BLOCK_LINE +R_3_5_29460 = g_profile_EN_OBJ_POL +R_3_5_29930 = g_profile_EN_OBJ_POL_NEEDLE_L +R_3_5_2993c = g_profile_EN_OBJ_POL_NEEDLE_R +R_3_5_29948 = g_profile_EN_OBJ_POL_NEEDLE_LR +R_3_5_29954 = g_profile_EN_OBJ_POL_NEEDLE_U +R_3_5_29960 = g_profile_EN_OBJ_POL_NEEDLE_D +R_3_5_2996c = g_profile_EN_OBJ_POL_NEEDLE_UD +R_3_5_2a980 = g_profile_EN_OBJ_POL_TORIDE +R_3_5_2ac20 = g_profile_EN_ROTATION_BLOCK +R_3_5_2b038 = g_profile_EN_ONEWAY_GATE +R_3_5_2b450 = g_profile_EN_PAIR_OBJ_CHILD +R_3_5_2b830 = g_profile_EN_PAIR_OBJ_CHILD_TORIDE +R_3_5_2bad8 = g_profile_EN_PAIR_OBJ_PARENT +R_3_5_2bfe0 = g_profile_EN_PARA_BOMHEI +R_3_5_2c408 = g_profile_EN_PATABLOCK +R_3_5_2c8b8 = g_profile_EN_PATA_KURIBO +R_3_5_2ccd0 = g_profile_EN_PATAMET +R_3_5_2ccdc = g_profile_EN_BIG_PATAMET +R_3_5_2d098 = g_profile_EN_PATAPATA +R_3_5_2d5f0 = g_profile_EN_POLTER +R_3_5_2dba0 = g_profile_EN_PUKUPUKU +R_3_5_2dbac = g_profile_EN_MIDDLE_PUKU +R_3_5_2dbb8 = g_profile_EN_PUKUCOIN +R_3_5_2dbc4 = g_profile_EN_TOGEPUKU +R_3_5_2e310 = g_profile_EN_PUKUPUKU_PARENT +R_3_5_2e480 = g_profile_EN_RAIL_POLY_CHILD +R_3_5_2e990 = g_profile_EN_RAIL_POLY_ICE +R_3_5_2edd8 = g_profile_EN_RAIL_POLY_PARENT +R_3_5_2f030 = g_profile_EN_RAIL_POLYGON +R_3_5_2f580 = g_profile_EN_REDRING +R_3_5_2f978 = g_profile_EN_REDCOIN +R_3_5_2fda8 = g_profile_EN_REMOCON_CANNON +R_3_5_303b0 = g_profile_EN_REMOCON_TORIMOCHI +R_3_5_30640 = g_profile_EN_REVERSE +R_3_5_30900 = g_profile_EN_LR_STOP_UP +R_3_5_3090c = g_profile_EN_LR_STOP_DW +R_3_5_30b98 = g_profile_EN_LIFT_ROTATION_FULL +R_3_5_30f08 = g_profile_EN_ROT_PAKKUN +R_3_5_31198 = g_profile_EN_ROTATION_GHOST +R_3_5_315d0 = g_profile_EN_RULETBLOCK +R_3_5_31a28 = g_profile_EN_SAKASA_TOGEZO +R_3_5_31ec0 = g_profile_EN_SANBO +R_3_5_322f8 = g_profile_EN_SANBO_EL +R_3_5_32890 = g_profile_EN_SANBO_PARTS +R_3_5_32bd0 = g_profile_EN_SLIP_PENGUIN +R_3_5_32e60 = g_profile_EN_SLIP_PENGUIN2 +R_3_5_33680 = g_profile_EN_SNAKEBLOCK +R_3_5_33b90 = g_profile_EN_STAR_COIN +R_3_5_33b9c = g_profile_EN_STAR_COIN_LINE +R_3_5_33ba8 = g_profile_EN_STAR_COIN_VOLT +R_3_5_33fe8 = g_profile_EN_SUPER_BIGPILE_LEFT +R_3_5_343e0 = g_profile_EN_SUPER_BIGPILE_RIGHT +R_3_5_347e0 = g_profile_EN_SWITCHDOOR +R_3_5_34aa0 = g_profile_EN_SYNCRO_BARNAR +R_3_5_34ee0 = g_profile_EN_TARZANROPE +R_3_5_35170 = g_profile_EN_TERESA +R_3_5_3517c = g_profile_EN_BIG_TERESA +R_3_5_35630 = g_profile_EN_TESTMAN +R_3_5_359e0 = g_profile_EN_TOBIPUKU +R_3_5_35df0 = g_profile_EN_TOGEMET +R_3_5_362c8 = g_profile_EN_TOGETEKKYU +R_3_5_366f0 = g_profile_EN_TOGEZO +R_3_5_36ab0 = g_profile_EN_TORIDEDOOR +R_3_5_36da8 = g_profile_EN_TRPLN_WALL +R_3_5_37058 = g_profile_EN_UNIZOO +R_3_5_37064 = g_profile_EN_UNIRA +R_3_5_37870 = g_profile_DOKAN_WAKIDASHI +R_3_5_37950 = g_profile_EN_WAKI_IGAPUKU +R_3_5_37ce8 = g_profile_EN_WAKI_JUGEM +R_3_5_37ff8 = g_profile_EN_WALK_PAKKUN +R_3_5_38540 = g_profile_EN_WALLINSECT +R_3_5_387d0 = g_profile_EN_WANWAN +R_3_5_38e50 = g_profile_EN_WANWAN_PILE +R_3_5_391d0 = g_profile_EN_BLOCK_HELP +R_3_5_39578 = g_profile_EN_WATER_BUBBLE_BULLET +R_3_5_398c0 = g_profile_EN_WATERPAIPO +R_3_5_39c28 = g_profile_EN_WATERPAKKUN +R_3_5_3a160 = g_profile_EN_WATERSTREAM +R_3_5_3a400 = g_profile_EN_WHITE_BLOCK +R_3_5_3a8e0 = g_profile_EN_WIRE_TURN +R_3_5_3a8ec = g_profile_EN_BIG_WIRE_TURN +R_3_5_3ac78 = g_profile_EN_WOODBOX +R_3_5_3b140 = g_profile_EN_YAJIRUSHI +R_3_5_3b3e8 = g_profile_EN_ZOOM +R_4_1_f0 = finalizeProlog__Fv +R_4_1_100 = finalizeEpilog__Fv +R_4_5_0 = g_profile_EN_BOSS_CASTLE_IGGY +R_4_5_eb0 = g_profile_EN_BOSS_CASTLE_LARRY +R_4_5_1958 = g_profile_EN_BOSS_CASTLE_LEMMY +R_4_5_24a0 = g_profile_EN_BOSS_CASTLE_LUDWIG +R_4_5_3220 = g_profile_EN_BOSS_CASTLE_MORTON +R_4_5_3eb8 = g_profile_EN_BOSS_CASTLE_ROY +R_4_5_4e90 = g_profile_EN_BOSS_CASTLE_WENDY +R_4_5_5a40 = g_profile_EN_BOSS_IGGY +R_4_5_6ae8 = g_profile_EN_BOSS_KAMECK +R_4_5_7d60 = g_profile_EN_BOSS_KOOPA +R_4_5_9500 = g_profile_EN_BOSS_KOOPA_DEMO_CAGE +R_4_5_9988 = g_profile_EN_BOSS_KOOPA_DEMO_KAMECK +R_4_5_a058 = g_profile_EN_BOSS_KOOPA_DEMO_PEACH +R_4_5_a680 = g_profile_EN_BOSS_KOOPA_JR_A +R_4_5_ad90 = g_profile_EN_BOSS_KOOPA_JR_B +R_4_5_b5d0 = g_profile_EN_BOSS_KOOPA_JR_C +R_4_5_bcd8 = g_profile_EN_BOSS_LARRY +R_4_5_cb98 = g_profile_EN_BOSS_LEMMY +R_4_5_de30 = g_profile_EN_BOSS_LUDWIG +R_4_5_f168 = g_profile_EN_BOSS_MORTON +R_4_5_10180 = g_profile_EN_BOSS_ROY +R_4_5_11378 = g_profile_EN_BOSS_WENDY From fba98292753ee7812f5cfdcd1d35377b54ef1ef5 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 10:42:32 +0200 Subject: [PATCH 5/9] `daEnNoko_c` matched and linked --- include/game/bases/d_a_en_noko.hpp | 31 ++--- slices/d_enemiesNP.json | 16 ++- source/d_enemiesNP/bases/d_a_en_noko.cpp | 142 +++++++++++------------ syms.txt | 2 + 4 files changed, 104 insertions(+), 87 deletions(-) diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp index ac9cb0e4..744c0151 100644 --- a/include/game/bases/d_a_en_noko.hpp +++ b/include/game/bases/d_a_en_noko.hpp @@ -22,6 +22,12 @@ namespace mEf { class levelOneEffect_c : public levelEffect_c { public: levelOneEffect_c() { reset(); } + ~levelOneEffect_c() {} + + virtual void reset(); + virtual void createEffect(const char *, int); + virtual void createEffect(const char *, ulong, const mVec3_c *, const mAng3_c *, const mVec3_c *); + virtual void createEffect(const char *, ulong, const mMtx_c *); float mEmissionRateMaybe; nw4r::ef::EmitterInheritSetting setting; @@ -43,14 +49,7 @@ class daEnNoko_c : public daEnShell_c { public: class nodeCallback_c : public m3d::mdl_c::callback_c { public: - virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl) { - mMtx_c mtx; - if (strcmp(resMdl.GetResNode(nodeId).GetName(), "head") == 0) { - manip->GetMatrix(&mtx); - mtx.XrotM(mpOwner->m_8a8); - manip->SetMatrix(mtx); - } - } + virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl); daEnNoko_c *mpOwner; }; @@ -67,8 +66,6 @@ class daEnNoko_c : public daEnShell_c { virtual bool createIceActor() override; virtual void beginFunsui() override; virtual void endFunsui() override; - virtual BOOL isFunsui() const override { return mIsFrozen; } - virtual void YoshiFumiScoreSet(dActor_c *) override; STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); STATE_FUNC_DECLARE(daEnNoko_c, Walk); @@ -84,6 +81,9 @@ class daEnNoko_c : public daEnShell_c { virtual bool checkSleep() override; virtual void calcShellEffectPos() override; virtual void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } + + virtual void vf300() { WaterCheck(mPos, 1.0f); } + virtual void setAfterSleepState() override { changeState(StateID_Walk); } virtual void slideEffect() override { if (!mWalksOffLedges) { @@ -93,7 +93,6 @@ class daEnNoko_c : public daEnShell_c { } } - virtual void vf300() { WaterCheck(mPos, 1.0f); } virtual void vf304(u32 * pDir, mAng * pAng); virtual bool isWalking(); virtual void vf30C(); @@ -105,7 +104,9 @@ class daEnNoko_c : public daEnShell_c { virtual void vf324(); virtual void vf328() {} virtual void deleteRest(); - virtual mVec3_c getPos(); + virtual mVec3_c getPos() { return mVec3_c(mPos.x, mPos.y, mPos.z); } + + virtual BOOL isFunsui() const override { return mIsFrozen; } void loadRes(); void updateAmiLine(); @@ -113,11 +114,11 @@ class daEnNoko_c : public daEnShell_c { bool isInQuicksand(); void spawnQuicksandEffects(); bool sub_80A73330(dActor_c *); - void setBc(); + void setNokoBc(); bool turnProc(); float getWindMultiplier(); - void setMoveAnimation(char * name, m3d::playMode_e mode, float frame); - void setBaseAnimation(char * name, m3d::playMode_e mode, float frame); + void setMoveAnimation(const char *name, m3d::playMode_e mode, float frame); + void setBaseAnimation(const char *name, m3d::playMode_e mode, float frame); bool sub_80A73BC0(); void sub_80A73CB0(); diff --git a/slices/d_enemiesNP.json b/slices/d_enemiesNP.json index 369923bf..9cc405b6 100644 --- a/slices/d_enemiesNP.json +++ b/slices/d_enemiesNP.json @@ -27,6 +27,10 @@ ".PPC.EMB.apuinfo": { "index": 18, "align": 16, "size": "0x0" } } }, + "keepWeak": [ + "setNokoBc__10daEnNoko_cFv", + "sub_80A73CB0__10daEnNoko_cFv" + ], "slices": [ { "source": "runtime/rel_init.cpp", @@ -35,11 +39,21 @@ ".text": "0x0-0x70" } }, + { + "source": "runtime/global_destructor_chain.c", + "compilerFlags": "-c -Cpp_exceptions off -O4 -fp hard -sdata 0 -sdata2 0", + "memoryRanges": { + ".text": "0x70-0xf0", + ".dtors": "0x0-0x4", + ".bss": "0x0-0x8" + } + }, { "source": "d_enemiesNP/bases/d_a_en_noko.cpp", - "nonMatching": true, "memoryRanges": { ".text": "0xcf710-0xd2930", + ".ctors": "0x1b4-0x1b8", + ".rodata": "0x6008-0x60f0", ".data": "0x28250-0x289d0", ".bss": "0x7e60-0x80a0" } diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp index 927fa454..7ab0a4e5 100644 --- a/source/d_enemiesNP/bases/d_a_en_noko.cpp +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -5,14 +5,6 @@ #include #include -const float buf_80ad34b0[2] = {0.5f, -0.5f}; -const s16 buf_80ad34b8[2] = {0x800, -0x800}; -const s16 buf_80ad34bc[2] = {0x4000, -0x4000}; -const s16 buf_80ad34f0[2] = {-0x1555, 0x1555}; -const int buf_80ad34f8[2] = {0, 1}; -const float buf_80ad3500[2] = {-2.0f, -4.0f}; -const float buf_80ad3518[2] = {2.5f, -2.5f}; - const sBcSensorPoint smc_noko_head = { SENSOR_IS_POINT, 0, 0xc000 }; const sBcSensorLine smc_noko_foot = { SENSOR_IS_LINE, -0x4000, 0x4000, 0x0 }; const sBcSensorLine smc_noko_wall = { SENSOR_IS_LINE, 0x6000, 0x9000, 0x6000 }; @@ -28,6 +20,10 @@ const sCcDatNewF ccData = { dEn_c::normal_collcheck }; +const float buf_80ad34b0[2] = {0.5f, -0.5f}; +const s16 buf_80ad34b8[2] = {0x800, -0x800}; +const s16 buf_80ad34bc[2] = {0x4000, -0x4000}; + STATE_DEFINE(daEnNoko_c, BlockAppear); STATE_DEFINE(daEnNoko_c, Walk); STATE_DEFINE(daEnNoko_c, Turn); @@ -38,7 +34,7 @@ STATE_DEFINE(daEnNoko_c, BgmDanceEd); STATE_VIRTUAL_DEFINE(daEnNoko_c, Wakeup); STATE_VIRTUAL_DEFINE(daEnNoko_c, WakeupTurn); -ACTOR_PROFILE(EN_NOKONOKO, daEnNoko_c, 0x0); +ACTOR_PROFILE(EN_NOKONOKO, daEnNoko_c, 0x12); int daEnNoko_c::create() { mWalksOffLedges = mParam & 1; @@ -174,7 +170,7 @@ int daEnNoko_c::draw() { return daEnShell_c::drawShell(); } - if (isState(StateID_Wakeup)) { + if (isState(daEnShell_c::StateID_Wakeup)) { daEnShell_c::drawShell(); } @@ -233,16 +229,14 @@ void daEnNoko_c::vf310() { mVec3_c pos = getPos(); mAng3_c angle = mAngle; dActor_c::changePosAngle(&pos, &angle, 1); - PSMTXTrans(mMatrix, pos.x, pos.y, pos.z); - mMatrix.ZXYrotM(angle.x, angle.y, angle.z); + + mMatrix.trans(pos); + mMatrix.ZXYrotM(angle); + mNokoModel.setLocalMtx(&mMatrix); - mVec3_c boyo_scale = mBoyoMng.mScale; - mNokoModel.setScale(boyo_scale); - mNokoModel.calc(false); -} -mVec3_c daEnNoko_c::getPos() { - return mPos; + mNokoModel.setScale(mBoyoMng.getScale()); + mNokoModel.calc(false); } void daEnNoko_c::calcShellEffectPos() { @@ -292,7 +286,7 @@ bool daEnNoko_c::sub_80A73330(dActor_c *actor) { return true; } -void daEnNoko_c::setBc() { +void daEnNoko_c::setNokoBc() { mSensorHead = smc_noko_head; mSensorWall = smc_noko_wall; mSensorFootNormal = smc_noko_foot; @@ -341,42 +335,41 @@ void daEnNoko_c::setZPos() { } void daEnNoko_c::updateAmiLine() { - float f1 = mCc.mCcData.mBase.mSize.x; - float f2 = mCc.mCcData.mBase.mOffset.x; - float f3 = mPos.x; - float f4 = f3 + f2; - - float f5 = mCc.mCcData.mBase.mOffset.y; - float f6 = mPos.y; - float f7 = f6 + f5; - - u32 u1 = dBc_c::getUnitType(f4 + f1, f7, mLayer); - u32 u2 = dBc_c::getUnitKind(f4 + f1, f7, mLayer) & 0xFF; - u32 u3 = dBc_c::getUnitType(f4 - f1, f7, mLayer); - u32 u4 = dBc_c::getUnitKind(f4 - f1, f7, mLayer) & 0xFF; - - if ((((u1 & 1024) == 0) || (u2 < 2)) && (((u3 & 1024) == 0) || (u4 < 2))) { - goto e8; - } else if (!mAmiLayer) { - mCc.mAmiLine = 1; - goto ret; + float width = mCc.mCcData.mBase.mSize.x; + float offX = mCc.mCcData.mBase.mOffset.x; + float offY = mCc.mCcData.mBase.mOffset.y; + + float x = mPos.x + offX; + float y = mPos.y + offY; + + u32 u1 = dBc_c::getUnitType(x + width, y, mLayer); + u8 u2 = dBc_c::getUnitKind(x + width, y, mLayer) & 0xFF; + u32 u3 = dBc_c::getUnitType(x - width, y, mLayer); + u8 u4 = dBc_c::getUnitKind(x - width, y, mLayer) & 0xFF; + + if ( + u1 & BIT_FLAG(10) && u2 >= 2 || + u3 & BIT_FLAG(10) && u4 >= 2 + ) { + if (!mAmiLayer) { + mCc.mAmiLine = 1; + } else { + mCc.mAmiLine = 2; + } } else { - mCc.mAmiLine = 2; - goto ret; - } - { - e8: mCc.mAmiLine = 3; } -ret: - return; } void daEnNoko_c::dance() { + static const s16 buf_80ad34f0[2] = {-0x1555, 0x1555}; sLib::chaseAngle(&m_8a8, buf_80ad34f0[mDirection], 0x400); } bool daEnNoko_c::createIceActor() { + static const int buf_80ad34f8[2] = {0, 1}; + static const float buf_80ad3500[2] = {-2.0f, -4.0f}; + float f_60; mVec3_c f_5c; int ice_mode; @@ -386,12 +379,11 @@ bool daEnNoko_c::createIceActor() { if (*mStateMgr.getMainStateID() == StateID_BgmDance) { f_5c.set(mPos.x, mPos.y - 4.0f, mPos.z + 2.0f); ice_mode = 1; - scale.set(1.0f, 1.05f, 1.75f); + scale.set(1.05f, 1.0f, 1.75f); } else { - int x = mUseBaseIceBehaviour; - f_5c.set(mPos.x, mPos.y + buf_80ad3500[x], mPos.z); - ice_mode = buf_80ad34f8[x]; - scale.set(1.0f, 1.05f, 1.05f); + ice_mode = buf_80ad34f8[mUseBaseIceBehaviour]; + f_5c.set(mPos.x, mPos.y + buf_80ad3500[mUseBaseIceBehaviour], mPos.z); + scale.set(1.05f, 1.0f, 1.05f); } dIceInfo iceInfo[] = { @@ -449,28 +441,28 @@ float daEnNoko_c::getWindMultiplier() { return ac_wind->m_394; } -void daEnNoko_c::setMoveAnimation(char * name, m3d::playMode_e mode, float frame) { +void daEnNoko_c::setMoveAnimation(const char *name, m3d::playMode_e mode, float frame) { mMoveAnim.setAnm(mNokoModel, mNokoResFile.GetResAnmChr(name), mode); mNokoModel.setAnm(mMoveAnim, frame); } -void daEnNoko_c::setBaseAnimation(char * name, m3d::playMode_e mode, float frame) { +void daEnNoko_c::setBaseAnimation(const char *name, m3d::playMode_e mode, float frame) { mAnim.setAnm(mModel, mResFile.GetResAnmChr(name), mode); mModel.setAnm(mAnim, frame); } bool daEnNoko_c::sub_80A73BC0() { - float fVar1 = mPos.y; - mVec3_c local_14 = mVec3_c(mPos.x + buf_80ad3518[mDirection], fVar1 + 4.0f, mPos.z); - u32 uVar2 = dBc_c::getUnitKind(local_14.x, fVar1 - 2.0f, mLayer); + static const float buf_80ad3518[2] = {2.5f, -2.5f}; + + mVec3_c pos(mPos.x + buf_80ad3518[mDirection], mPos.y + 4.0f, mPos.z); + u8 kind = dBc_c::getUnitKind(pos.x, mPos.y - 2.0f, mLayer) >> 16; - if (((uVar2 >> 0x10) & 0xff) == 8) { + if (kind == 8) { return false; } - float local_18 = 0.0f; - u32 temp = dBc_c::checkGround(&local_14, &local_18, mLayer, 1, -1); - if ((temp == 0) || !(local_14.y < local_18) || (local_18 > mPos.y - 5.0f)) { + float height = 0.0f; + if (dBc_c::checkGround(&pos, &height, mLayer, 1, -1) && height < pos.y && height > mPos.y - 5.0f) { return true; } @@ -535,6 +527,7 @@ void daEnNoko_c::executeState_Walk() { mSpeed.y = 0.0f; if ((mWalksOffLedges == true) && (!sub_80A73BC0())) { changeState(StateID_Turn); + return; } } else if (foot && !mInLiquid && (mSpeed.y <= 0.0f)) { mFootPush2.x += m_1eb.x; @@ -553,11 +546,11 @@ void daEnNoko_c::initializeState_Wakeup() { daEnShell_c::initializeState_Wakeup(); } -// void daEnNoko_c::finalizeState_Wakeup() { -// mAnim.setFrame(0.0f); -// mCc.mCcData.mBase.mOffset.x = 0.0f; -// mCc.mCcData.mBase.mSize.x = 8.0f; -// } +void daEnNoko_c::finalizeState_Wakeup() { + mAnim.setFrame(0.0f); + mCc.mCcData.mBase.mOffset.x = 0.0f; + mCc.mCcData.mBase.mSize.x = 8.0f; +} void daEnNoko_c::executeState_Wakeup() { mNokoModel.play(); @@ -574,7 +567,7 @@ void daEnNoko_c::executeState_Wakeup() { } if (mMoveAnim.isStop()) { - changeState(StateID_WakeupTurn); + changeState(daEnShell_c::StateID_WakeupTurn); } } @@ -684,7 +677,7 @@ void daEnNoko_c::initializeState_BgmDance() { "BGM_anim_walkA_3", }; - setMoveAnimation((char *)buf_80afdd98[mDanceMove], m3d::FORWARD_ONCE, 3.0f); + setMoveAnimation(buf_80afdd98[mDanceMove], m3d::FORWARD_ONCE, 3.0f); mSpeed.x = 0.0; mDancesRemaining = 3; mYRotIncrease = (u16)(abs((int)mAngle.y) / (int)mDancesRemaining); @@ -710,16 +703,15 @@ void daEnNoko_c::executeState_BgmDance() { } if (mMoveAnim.isStop()) { - changeState(StateID_BgmDance); + changeState(StateID_BgmDanceEd); } } void daEnNoko_c::initializeState_BgmDanceEd() { setMoveAnimation("walkA", m3d::FORWARD_ONCE, 4.0f); - mAng x = buf_80ad34bc[mDirection]; mSpeed.x = 0.0f; mDancesRemaining = 4; - mYRotIncrease = abs(x) / mDancesRemaining; + mYRotIncrease = abs(buf_80ad34bc[mDirection]) / mDancesRemaining; } void daEnNoko_c::finalizeState_BgmDanceEd() {} @@ -734,9 +726,8 @@ void daEnNoko_c::executeState_BgmDanceEd() { } if (mDancesRemaining > 0) { - mAng y = buf_80ad34bc[mDirection]; mDancesRemaining--; - sLib::chaseAngle((s16*)&mAngle.y, y, mYRotIncrease); + sLib::chaseAngle((s16*)&mAngle.y, buf_80ad34bc[mDirection], mYRotIncrease); if (mDancesRemaining > 0) { return; @@ -746,3 +737,12 @@ void daEnNoko_c::executeState_BgmDanceEd() { changeState(StateID_Walk); } } + +void daEnNoko_c::nodeCallback_c::timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl) { + mMtx_c mtx; + if (strcmp(resMdl.GetResNode(nodeId).GetName(), "head") == 0) { + manip->GetMatrix(&mtx); + mtx.XrotM(mpOwner->m_8a8); + manip->SetMatrix(mtx); + } +} \ No newline at end of file diff --git a/syms.txt b/syms.txt index cad5f0ae..62c168ef 100644 --- a/syms.txt +++ b/syms.txt @@ -568,6 +568,7 @@ Init__Q34nw4r3g3d7ResFileFv=0x8023A6D0 CheckRevision__Q34nw4r3g3d7ResFileCFv=0x8023A9A0 GetResNode__Q34nw4r3g3d6ResMdlCFPCc=0x8023B340 GetResNode__Q34nw4r3g3d6ResMdlCFi=0x8023B3E0 +GetResNode__Q34nw4r3g3d6ResMdlCFUl=0x8023B440 GetResNodeNumEntries__Q34nw4r3g3d6ResMdlCFv=0x8023B4A0 GetResMat__Q34nw4r3g3d6ResMdlCFUl=0x8023B9A0 GetResMatNumEntries__Q34nw4r3g3d6ResMdlCFv=0x8023BA00 @@ -885,6 +886,7 @@ g_profile_PLAYER_ICE=0x80326960 g_profile_YOSHI=0x80326A50 g_profile_FUKIDASHI_MANAGER=0x803275E0 g_profile_GAMEDISPLAY=0x80327668 +__vt__Q23mEf16levelOneEffect_c=0x80329BE4 __vt__Q23mEf13levelEffect_c=0x80329CA0 __vt__Q23mEf8effect_c=0x80329D68 sTVModeInfo__Q23EGG6Screen=0x80350820 From 3fde868de7e5d023ffd73251a4ef1c5d0311c084 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 10:55:58 +0200 Subject: [PATCH 6/9] Fix `prepare_objdiff.py` --- prepare_objdiff.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prepare_objdiff.py b/prepare_objdiff.py index a1d14713..ae8e9b90 100644 --- a/prepare_objdiff.py +++ b/prepare_objdiff.py @@ -272,7 +272,8 @@ def get_dtk(tag: str) -> str: del sym_dict[(sec, addr + sym.st_size - 4)] attributes['size'] = str(sym.st_size) - sym_dict[(sec, addr)] = (name, attributes) + if len(attributes) > 0: + sym_dict[(sec, addr)] = (name, attributes) # Write back updated symbols symbols_path.write_text(syms_to_text(new_syms)) From 12513b9dd216aec39fced20b577e6134c99fb900 Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 12:03:05 +0200 Subject: [PATCH 7/9] Cleanup --- alias_db.txt | 1 - include/game/bases/d_a_en_noko.hpp | 95 ++---- include/game/bases/d_a_en_shell.hpp | 9 +- include/game/bases/d_a_tag_wind.hpp | 9 + include/game/mLib/m_angle.hpp | 10 +- include/game/mLib/m_effect.hpp | 15 + .../drawstrategy/ef_drawbillboardstrategy.h | 6 +- .../drawstrategy/ef_drawdirectionalstrategy.h | 6 +- .../ef/drawstrategy/ef_drawstripestrategy.h | 6 +- include/lib/nw4r/ef/ef_emitter.h | 2 + include/types.h | 2 + slices/d_enemiesNP.json | 2 +- source/d_enemiesNP/bases/d_a_en_noko.cpp | 317 +++++++++--------- source/dol/bases/d_a_en_shell.cpp | 20 +- 14 files changed, 247 insertions(+), 253 deletions(-) create mode 100644 include/game/bases/d_a_tag_wind.hpp diff --git a/alias_db.txt b/alias_db.txt index e17d62a6..a5bd20da 100644 --- a/alias_db.txt +++ b/alias_db.txt @@ -658,7 +658,6 @@ R_3_5_26eb0 = g_profile_EN_MISTMAN R_3_5_27528 = g_profile_EN_MOUSE R_3_5_27a30 = g_profile_EN_NET_NOKONOKO_LR R_3_5_27dd0 = g_profile_EN_NET_NOKONOKO_UD -R_3_5_28250 = g_profile_EN_NOKONOKO R_3_5_289d0 = g_profile_EN_OBAKEDOOR R_3_5_28ce8 = g_profile_EN_OBJ_HATENA_BLOCK R_3_5_28cf4 = g_profile_EN_OBJ_HATENAB_BLOCK diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp index 744c0151..b93896e9 100644 --- a/include/game/bases/d_a_en_noko.hpp +++ b/include/game/bases/d_a_en_noko.hpp @@ -1,45 +1,7 @@ #include +#include #include -namespace nw4r { - namespace ef { - struct EmitterInheritSetting { - u16 mSpeed; - u8 mScale; - u8 mAlpha; - u8 mColor; - u8 mWeight; - u8 mType; - u8 mFlag; - u8 mAlphaFuncPri; - u8 mAlphaFuncSec; - u8 mPad[2]; - }; - }; -}; - -namespace mEf { - class levelOneEffect_c : public levelEffect_c { - public: - levelOneEffect_c() { reset(); } - ~levelOneEffect_c() {} - - virtual void reset(); - virtual void createEffect(const char *, int); - virtual void createEffect(const char *, ulong, const mVec3_c *, const mAng3_c *, const mVec3_c *); - virtual void createEffect(const char *, ulong, const mMtx_c *); - - float mEmissionRateMaybe; - nw4r::ef::EmitterInheritSetting setting; - }; -}; - -class daTagWind_c : public dActor_c { -public: - float m_394; - u8 mPad[32]; -}; - /** * @brief Koopa Troopa * @statetable @@ -54,6 +16,11 @@ class daEnNoko_c : public daEnShell_c { daEnNoko_c *mpOwner; }; + enum NokoType_e { + NOKO_GREEN, ///< Green Koopas don't turn around on ledges. + NOKO_RED ///< Red Koopas turn around on ledges. + }; + daEnNoko_c() { mMdlCallback.mpOwner = this; } ~daEnNoko_c() {} @@ -62,7 +29,7 @@ class daEnNoko_c : public daEnShell_c { virtual int execute() override; virtual int preExecute() override; virtual int draw() override; - virtual void finalUpdate() override { vf310(); } + virtual void finalUpdate() override { calcMdl(); } virtual bool createIceActor() override; virtual void beginFunsui() override; virtual void endFunsui() override; @@ -79,31 +46,32 @@ class daEnNoko_c : public daEnShell_c { virtual bool setPlayerDamage(dActor_c *actor) override; virtual bool checkSleep() override; + virtual bool turnProc() override; virtual void calcShellEffectPos() override; virtual void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } - virtual void vf300() { WaterCheck(mPos, 1.0f); } + virtual void checkWaterEntry() { WaterCheck(mPos, 1.0f); } virtual void setAfterSleepState() override { changeState(StateID_Walk); } virtual void slideEffect() override { - if (!mWalksOffLedges) { + if (!mNokoType) { mEffect.createEffect("Wm_en_shellgreentail", 0, &m_71c, nullptr, nullptr); } else { mEffect.createEffect("Wm_en_shellredtail", 0, &m_71c, nullptr, nullptr); } } - virtual void vf304(u32 * pDir, mAng * pAng); - virtual bool isWalking(); - virtual void vf30C(); - virtual void vf310(); + virtual void doTurn(int *dir, s16 *turnSpeed); + virtual bool isWalking() { return true; } + virtual void turnAround(); + virtual void calcMdl(); virtual bool canDance(); virtual void danceWithMove(int move); virtual void dance(); - virtual void changeStateAccordingToSettings(); - virtual void vf324(); + virtual void setInitialState(); + virtual void vf324() {} virtual void vf328() {} - virtual void deleteRest(); + virtual void deleteResExtra() {} virtual mVec3_c getPos() { return mVec3_c(mPos.x, mPos.y, mPos.z); } virtual BOOL isFunsui() const override { return mIsFrozen; } @@ -113,34 +81,41 @@ class daEnNoko_c : public daEnShell_c { void setZPos(); bool isInQuicksand(); void spawnQuicksandEffects(); - bool sub_80A73330(dActor_c *); + bool playerDamageTurn(dActor_c *); void setNokoBc(); - bool turnProc(); float getWindMultiplier(); void setMoveAnimation(const char *name, m3d::playMode_e mode, float frame); void setBaseAnimation(const char *name, m3d::playMode_e mode, float frame); - bool sub_80A73BC0(); - void sub_80A73CB0(); + bool checkLedge(); + void landEffect(); u8 mPad0[4]; + dHeapAllocator_c mNokoAllocator; nw4r::g3d::ResFile mNokoResFile; m3d::mdl_c mNokoModel; m3d::anmChr_c mMoveAnim; nw4r::g3d::ResAnmTexPat mNokoResAnmTexPat; m3d::anmTexPat_c mNokoAnimTex; + u32 mIsFrozen; - s16 m_8a8; - bool mWalksOffLedges; - mVec3_c m_8ac; + s16 mBgmDanceAngle; + u8 mNokoType; ///< Is a NokoType_e. + mVec3_c mCreatePos; float mXSpeedBeforeFrozen; - u8 mPad3[8]; - float m_8c4; + u8 mPad1[8]; + float mBaseZPos; u32 m_8c8; int mDancesRemaining; - mAng mYRotIncrease; - u8 mPad4[2]; + mAng mBgmDanceRotSpeed; u32 mDanceMove; mEf::levelOneEffect_c mQuickSandEffect; nodeCallback_c mMdlCallback; + + ACTOR_PARAM_CONFIG(NokoType, 0, 1); + ACTOR_PARAM_CONFIG(SpawnMode, 4, 1); ///< 1 = Spawn as sleeping shell + ACTOR_PARAM_CONFIG(Layer, 16, 1); + ACTOR_PARAM_CONFIG(BlockHitPlayer, 24, 2); + ACTOR_PARAM_CONFIG(BlockAppear, 28, 1); + ACTOR_PARAM_CONFIG(SpitOut, 29, 1); }; diff --git a/include/game/bases/d_a_en_shell.hpp b/include/game/bases/d_a_en_shell.hpp index f739217e..e63442d6 100644 --- a/include/game/bases/d_a_en_shell.hpp +++ b/include/game/bases/d_a_en_shell.hpp @@ -12,6 +12,13 @@ */ class daEnShell_c : public daEnCarry_c { public: + /// Other actors can extend this enum to add new modes. + /// @unofficial + enum ShellMode_e { + SHELL_MODE_BASE, + SHELL_MODE_NOKO_WALK + }; + struct GlobalData_t { s16 mSpinSpeed; s16 mUnkSpeed; @@ -105,7 +112,7 @@ class daEnShell_c : public daEnCarry_c { sBcSensorLine mSensorFootSlide; mEf::levelEffect_c mEffect; int mYoshiKickable; ///< Whether the shell can be kicked in any state by Yoshi. - int mUseBaseIceBehaviour; + ShellMode_e mShellMode; mVec3_c m_71c; mVec3_c mCarryPos; int mIsCarryFall; diff --git a/include/game/bases/d_a_tag_wind.hpp b/include/game/bases/d_a_tag_wind.hpp new file mode 100644 index 00000000..4a9367ac --- /dev/null +++ b/include/game/bases/d_a_tag_wind.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +class daTagWind_c : public dActor_c { +public: + float m_394; + u8 mPad[32]; +}; diff --git a/include/game/mLib/m_angle.hpp b/include/game/mLib/m_angle.hpp index cf88fc3f..339cdc6e 100644 --- a/include/game/mLib/m_angle.hpp +++ b/include/game/mLib/m_angle.hpp @@ -2,10 +2,10 @@ #include #include #include +#include -extern "C" { - int abs(int); -} +#define DEG_TO_ANGLE(x) (0x10000 * x / 360) +#define ANGLE_360_DIV(x) (0x10000 / x) /// @brief A one-dimensional short angle vector. /// @ingroup mlib @@ -29,8 +29,8 @@ struct mAng { return sLib::chase(&mAngle, target, step); } - mAng abs() const { - return mAng(::abs(mAngle)); + int abs() const { + return ::abs(mAngle); } /// @brief Augmented addition operator. diff --git a/include/game/mLib/m_effect.hpp b/include/game/mLib/m_effect.hpp index bafd04ad..608fd824 100644 --- a/include/game/mLib/m_effect.hpp +++ b/include/game/mLib/m_effect.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -45,6 +46,20 @@ class levelEffect_c : public effect_c { u32 m_120, m_124; }; +class levelOneEffect_c : public levelEffect_c { +public: + levelOneEffect_c() { reset(); } + ~levelOneEffect_c() {} + + virtual void reset(); + virtual void createEffect(const char *, int); + virtual void createEffect(const char *, ulong, const mVec3_c *, const mAng3_c *, const mVec3_c *); + virtual void createEffect(const char *, ulong, const mMtx_c *); + + float mEmissionRateMaybe; + nw4r::ef::EmitterInheritSetting mSetting; +}; + void createEffect(const char *, unsigned long, const mVec3_c *, const mAng3_c *, const mVec3_c *); }; // namespace mEf diff --git a/include/lib/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h b/include/lib/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h index 735df919..d8fe411d 100644 --- a/include/lib/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h +++ b/include/lib/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h @@ -1,7 +1,7 @@ #ifndef NW4R_EF_DRAW_BILLBOARD_STRATEGY_H #define NW4R_EF_DRAW_BILLBOARD_STRATEGY_H -#include "types_nw4r.h" -#include "ef_drawstrategyimpl.h" +#include +#include namespace nw4r { @@ -12,7 +12,7 @@ namespace nw4r public: DrawBillboardStrategy(); virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 - + virtual void Draw(const DrawInfo &, ParticleManager *); }; } diff --git a/include/lib/nw4r/ef/drawstrategy/ef_drawdirectionalstrategy.h b/include/lib/nw4r/ef/drawstrategy/ef_drawdirectionalstrategy.h index 6d1dba68..9f2b43a9 100644 --- a/include/lib/nw4r/ef/drawstrategy/ef_drawdirectionalstrategy.h +++ b/include/lib/nw4r/ef/drawstrategy/ef_drawdirectionalstrategy.h @@ -1,7 +1,7 @@ #ifndef NW4R_EF_DRAW_DIRECTIONAL_STRATEGY_H #define NW4R_EF_DRAW_DIRECTIONAL_STRATEGY_H -#include "types_nw4r.h" -#include "ef_drawstrategyimpl.h" +#include +#include namespace nw4r { @@ -12,7 +12,7 @@ namespace nw4r public: DrawDirectionalStrategy(); virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 - + virtual void Draw(const DrawInfo &, ParticleManager *); }; } diff --git a/include/lib/nw4r/ef/drawstrategy/ef_drawstripestrategy.h b/include/lib/nw4r/ef/drawstrategy/ef_drawstripestrategy.h index cb7a0932..d4799573 100644 --- a/include/lib/nw4r/ef/drawstrategy/ef_drawstripestrategy.h +++ b/include/lib/nw4r/ef/drawstrategy/ef_drawstripestrategy.h @@ -1,7 +1,7 @@ #ifndef NW4R_EF_DRAW_STRIPE_STRATEGY_H #define NW4R_EF_DRAW_STRIPE_STRATEGY_H -#include "types_nw4r.h" -#include "ef_drawstrategyimpl.h" +#include +#include namespace nw4r { @@ -12,7 +12,7 @@ namespace nw4r public: DrawStripeStrategy(); virtual UNKTYPE GetCalcAheadFunc(ParticleManager *); // at 0x18 - + virtual UNKTYPE Draw(const DrawInfo &, ParticleManager *); }; } diff --git a/include/lib/nw4r/ef/ef_emitter.h b/include/lib/nw4r/ef/ef_emitter.h index 11a75fb2..f43dbed8 100644 --- a/include/lib/nw4r/ef/ef_emitter.h +++ b/include/lib/nw4r/ef/ef_emitter.h @@ -36,6 +36,8 @@ struct EmitterInheritSetting { u8 weight; // at 0x5 u8 type; // at 0x6 u8 flag; // at 0x7 + u8 alphaFuncPri; + u8 alphaFuncSec; }; class EmitterParameter { diff --git a/include/types.h b/include/types.h index ece753da..f681ca36 100644 --- a/include/types.h +++ b/include/types.h @@ -54,6 +54,8 @@ typedef int BOOL; #define BIT_FLAG(bit) ((bit) < 0 ? 0 : 1 << (bit)) #define ROUND_UP(x, align) (((x) + (align) - 1) & (-(align))) #define ROUND_UP_PTR(x, align) ((void*)((((u32)(x)) + (align) - 1) & (~((align) - 1)))) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) // No-op on release #define EGG_ASSERT(...) diff --git a/slices/d_enemiesNP.json b/slices/d_enemiesNP.json index 9cc405b6..eb3c3c8f 100644 --- a/slices/d_enemiesNP.json +++ b/slices/d_enemiesNP.json @@ -29,7 +29,7 @@ }, "keepWeak": [ "setNokoBc__10daEnNoko_cFv", - "sub_80A73CB0__10daEnNoko_cFv" + "landEffect__10daEnNoko_cFv" ], "slices": [ { diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp index 7ab0a4e5..02f70df5 100644 --- a/source/d_enemiesNP/bases/d_a_en_noko.cpp +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -1,14 +1,15 @@ #include #include +#include #include #include #include #include -const sBcSensorPoint smc_noko_head = { SENSOR_IS_POINT, 0, 0xc000 }; -const sBcSensorLine smc_noko_foot = { SENSOR_IS_LINE, -0x4000, 0x4000, 0x0 }; -const sBcSensorLine smc_noko_wall = { SENSOR_IS_LINE, 0x6000, 0x9000, 0x6000 }; -const sCcDatNewF ccData = { +const sBcSensorPoint l_noko_head = { SENSOR_IS_POINT, 0, 0xc000 }; +const sBcSensorLine l_noko_foot = { SENSOR_IS_LINE, -0x4000, 0x4000, 0x0 }; +const sBcSensorLine l_noko_wall = { SENSOR_IS_LINE, 0x6000, 0x9000, 0x6000 }; +const sCcDatNewF l_noko_cc = { 0.0f, 8.0f, 9.0f, 8.0f, CC_KIND_ENEMY, @@ -20,9 +21,9 @@ const sCcDatNewF ccData = { dEn_c::normal_collcheck }; -const float buf_80ad34b0[2] = {0.5f, -0.5f}; -const s16 buf_80ad34b8[2] = {0x800, -0x800}; -const s16 buf_80ad34bc[2] = {0x4000, -0x4000}; +const float l_walk_speed[2] = {0.5f, -0.5f}; +const s16 l_turn_speed[2] = {ANGLE_360_DIV(32), -ANGLE_360_DIV(32)}; +const s16 l_turn_target_angle[2] = {DEG_TO_ANGLE(90), -DEG_TO_ANGLE(90)}; STATE_DEFINE(daEnNoko_c, BlockAppear); STATE_DEFINE(daEnNoko_c, Walk); @@ -37,9 +38,10 @@ STATE_VIRTUAL_DEFINE(daEnNoko_c, WakeupTurn); ACTOR_PROFILE(EN_NOKONOKO, daEnNoko_c, 0x12); int daEnNoko_c::create() { - mWalksOffLedges = mParam & 1; + mNokoType = ACTOR_PARAM(NokoType); + loadRes(); - createShell("nokonokoA", "g3d/nokonokoA.brres", "nokonoko_shell", "Tnokonoko_shell", mWalksOffLedges); + createShell("nokonokoA", "g3d/nokonokoA.brres", "nokonoko_shell", "Tnokonoko_shell", mNokoType); mScale.set(1.0f, 1.0f, 1.0f); mCenterOffs.set(0.0f, 8.0f, 0.0); mVisibleAreaOffset.set(0.0f, 16.0f); @@ -49,36 +51,36 @@ int daEnNoko_c::create() { u8 dir = getPl_LRflag(mPos); mDirection = dir; - mAmiLayer = (mParam >> 16) & 1; - mAngle.y = buf_80ad34bc[dir]; - m_8ac = mPos; + mAmiLayer = ACTOR_PARAM(Layer); + mAngle.y = l_turn_target_angle[dir]; + mCreatePos = mPos; mFlags |= dEn_c::EN_FLAG_16; - mPos.z = l_Ami_Zpos[(mParam >> 16) & 1]; + mPos.z = l_Ami_Zpos[ACTOR_PARAM(Layer)]; mNokoAnimTex.setPlayMode(m3d::FORWARD_ONCE, 0); mNokoModel.setAnm(mNokoAnimTex, 0.0f); - mNokoAnimTex.setFrame(mWalksOffLedges, 0); + mNokoAnimTex.setFrame(mNokoType, 0); mNokoAnimTex.setRate(0.0f, 0); - mSensorHead = smc_noko_head; - mSensorWall = smc_noko_wall; - mSensorFootNormal = smc_noko_foot; - - mCcData.mBase.mOffset = ccData.mBase.mOffset; - mCcData.mBase.mSize = ccData.mBase.mSize; - mCcData.mKind = ccData.mKind; - mCcData.mAttack = ccData.mAttack; - mCcData.mVsKind = ccData.mVsKind; - mCcData.mVsDamage = ccData.mVsDamage; - mCcData.mStatus = ccData.mStatus; - mCcData.mCallback = ccData.mCallback; + mSensorHead = l_noko_head; + mSensorWall = l_noko_wall; + mSensorFootNormal = l_noko_foot; + + mCcData.mBase.mOffset = l_noko_cc.mBase.mOffset; + mCcData.mBase.mSize = l_noko_cc.mBase.mSize; + mCcData.mKind = l_noko_cc.mKind; + mCcData.mAttack = l_noko_cc.mAttack; + mCcData.mVsKind = l_noko_cc.mVsKind; + mCcData.mVsDamage = l_noko_cc.mVsDamage; + mCcData.mStatus = l_noko_cc.mStatus; + mCcData.mCallback = l_noko_cc.mCallback; mCc.set(this, &mCcData, l_Ami_Line[mAmiLayer]); mCc.entry(); - m_8c4 = dActorMng_c::m_instance->mGoombaZOrderThing * 16.0f; + mBaseZPos = dActorMng_c::m_instance->mGoombaZOrderThing * 16.0f; dActorMng_c::m_instance->mGoombaZOrderThing = (dActorMng_c::m_instance->mGoombaZOrderThing + 1) & 0xF; - changeStateAccordingToSettings(); + setInitialState(); mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); mBc.m_4c = mPos.x; @@ -106,16 +108,14 @@ void daEnNoko_c::loadRes() { mNokoAnimTex.setAnm(mNokoModel, mNokoResAnmTexPat, 0, m3d::FORWARD_ONCE); } -void daEnNoko_c::vf324() { } - -void daEnNoko_c::changeStateAccordingToSettings() { +void daEnNoko_c::setInitialState() { mDirection = getPl_LRflag(mPos); - if (((mParam >> 4) & 1) == 1) { + if (ACTOR_PARAM(SpawnMode) == 1) { mSpeed.y = 0.0f; changeState(daEnShell_c::StateID_Sleep); - } else if ((mParam >> 0x1C) & 1) { + } else if (ACTOR_PARAM(BlockAppear)) { changeState(daEnNoko_c::StateID_BlockAppear); - } else if ((mParam >> 0x1D) & 1) { + } else if (ACTOR_PARAM(SpitOut)) { changeState(daEnNoko_c::StateID_SpitOut_Ready); } else { changeState(daEnNoko_c::StateID_Walk); @@ -123,9 +123,8 @@ void daEnNoko_c::changeStateAccordingToSettings() { } int daEnNoko_c::preExecute() { - int res = dEn_c::preExecute(); - if (res == 0) { - return 0; + if (dEn_c::preExecute() == NOT_READY) { + return NOT_READY; } if (canDance()) { @@ -138,18 +137,18 @@ int daEnNoko_c::preExecute() { } } - return 1; + return SUCCEEDED; } int daEnNoko_c::execute() { mStateMgr.executeState(); if (cullCheck()) { - return 1; + return SUCCEEDED; } if (isState(StateID_BgmDance)) { - m_8a8 = 0; + mBgmDanceAngle = 0; } else { dance(); } @@ -162,20 +161,20 @@ int daEnNoko_c::execute() { } } - return 1; + return SUCCEEDED; } int daEnNoko_c::draw() { - if (!mUseBaseIceBehaviour) { - return daEnShell_c::drawShell(); + if (mShellMode == SHELL_MODE_BASE) { + return drawShell(); } if (isState(daEnShell_c::StateID_Wakeup)) { - daEnShell_c::drawShell(); + drawShell(); } mNokoModel.entry(); - return 1; + return SUCCEEDED; } int daEnNoko_c::doDelete() { @@ -183,21 +182,19 @@ int daEnNoko_c::doDelete() { mMoveAnim.remove(); mNokoModel.remove(); mNokoAnimTex.remove(); - deleteRest(); + deleteResExtra(); } - return 1; + return SUCCEEDED; } -void daEnNoko_c::deleteRest() { } - bool daEnNoko_c::isInQuicksand() { if (mBc.isFoot()) { mVec3_c pos = getCenterPos(); u32 type = dBc_c::getUnitType(pos.x, pos.y, mLayer); u8 subkind = dBc_c::getUnitKind(pos.x, pos.y, mLayer) >> 16; - if ((type & 0x8000) && (subkind == 3)) { + if (type & BIT_FLAG(15) && subkind == 3) { return true; } } @@ -212,7 +209,13 @@ void daEnNoko_c::spawnQuicksandEffects() { } bool daEnNoko_c::canDance() { - if (isState(StateID_Walk) || isState(StateID_Turn) || isState(StateID_WindTurn) || isState(StateID_BgmDance) || isState(StateID_BgmDanceEd)) { + if ( + isState(StateID_Walk) || + isState(StateID_Turn) || + isState(StateID_WindTurn) || + isState(StateID_BgmDance) || + isState(StateID_BgmDanceEd) + ) { return true; } @@ -224,7 +227,7 @@ void daEnNoko_c::danceWithMove(int move) { changeState(StateID_BgmDance); } -void daEnNoko_c::vf310() { +void daEnNoko_c::calcMdl() { calcShellMdl(); mVec3_c pos = getPos(); mAng3_c angle = mAngle; @@ -240,60 +243,54 @@ void daEnNoko_c::vf310() { } void daEnNoko_c::calcShellEffectPos() { - m3d::mdl_c * model = &mModel; - nw4r::g3d::ResMdl resMdl = model->getResMdl(); + m3d::mdl_c &model = mModel; + nw4r::g3d::ResMdl resMdl = model.getResMdl(); nw4r::g3d::ResNode resNode = resMdl.GetResNode("nokonoko_shell_model"); - ulong idx = resNode.GetID(); mMtx_c matrix; - model->getNodeWorldMtx(idx, &matrix); + model.getNodeWorldMtx(resNode.GetID(), &matrix); matrix.multVecZero(m_71c); if (mIsFlipped) { m_71c.y -= 16.0f; } } -bool daEnNoko_c::setPlayerDamage(dActor_c *ac_player) { - daPlBase_c * player = (daPlBase_c *)ac_player; - bool ok = player->setDamage(this, daPlBase_c::DAMAGE_DEFAULT); +bool daEnNoko_c::setPlayerDamage(dActor_c *actor) { + daPlBase_c *player = (daPlBase_c *)actor; - if (ok && isWalking()) { - sub_80A73330(ac_player); + if (player->setDamage(this, daPlBase_c::DAMAGE_DEFAULT) && isWalking()) { + playerDamageTurn(actor); return true; } return false; } -bool daEnNoko_c::isWalking() { - return true; -} - -bool daEnNoko_c::sub_80A73330(dActor_c *actor) { - u8 x = dActor_c::getTrgToSrcDir_Main(actor->getCenterX(), getCenterX()); +bool daEnNoko_c::playerDamageTurn(dActor_c *actor) { + u8 dir = dActor_c::getTrgToSrcDir_Main(actor->getCenterX(), getCenterX()); - u8 mShellKind = mUseBaseIceBehaviour; - if (mDirection == x || mShellKind == 0) { + u8 mode = mShellMode; + if (mDirection == dir || mode == SHELL_MODE_BASE) { return false; } - mDirection = x; - mAngle.y = buf_80ad34bc[x]; - m_8a8 *= -1; - vf30C(); + mDirection = dir; + mAngle.y = l_turn_target_angle[dir]; + mBgmDanceAngle *= -1; + turnAround(); return true; } void daEnNoko_c::setNokoBc() { - mSensorHead = smc_noko_head; - mSensorWall = smc_noko_wall; - mSensorFootNormal = smc_noko_foot; + mSensorHead = l_noko_head; + mSensorWall = l_noko_wall; + mSensorFootNormal = l_noko_foot; mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); } -void daEnNoko_c::vf30C() { +void daEnNoko_c::turnAround() { if (isState(StateID_Turn)) { changeState(StateID_Walk); } else { @@ -302,33 +299,28 @@ void daEnNoko_c::vf30C() { } bool daEnNoko_c::turnProc() { - mAng turnAng; - u32 turnDir; - - vf304(&turnDir, &turnAng); - mAngle.y += turnAng; - - int z = ((mAng *)buf_80ad34bc)[turnDir]; - int x = abs(z); - int y = abs(mAngle.y); - - if (y >= x) { - mAngle.y = z; + int turnDir; + s16 turnSpeed; + doTurn(&turnDir, &turnSpeed); + mAngle.y += turnSpeed; + + mAng target = l_turn_target_angle[turnDir]; + if (mAngle.y.abs() >= target.abs()) { + mAngle.y = target; return true; } return false; } -void daEnNoko_c::vf304(u32 * pDir, mAng * pAng) { - u32 x = mDirection; - *pDir = x; - *pAng = buf_80ad34b8[x]; +void daEnNoko_c::doTurn(int *dir, s16 *turnSpeed) { + *dir = mDirection; + *turnSpeed = l_turn_speed[*dir]; } void daEnNoko_c::setZPos() { if (mLayer == 0) { - mPos.z = m_8c4 + l_Ami_Zpos[mAmiLayer]; + mPos.z = mBaseZPos + l_Ami_Zpos[mAmiLayer]; } else { mPos.z = -2500.0f; } @@ -342,14 +334,14 @@ void daEnNoko_c::updateAmiLine() { float x = mPos.x + offX; float y = mPos.y + offY; - u32 u1 = dBc_c::getUnitType(x + width, y, mLayer); - u8 u2 = dBc_c::getUnitKind(x + width, y, mLayer) & 0xFF; - u32 u3 = dBc_c::getUnitType(x - width, y, mLayer); - u8 u4 = dBc_c::getUnitKind(x - width, y, mLayer) & 0xFF; + u32 typeRight = dBc_c::getUnitType(x + width, y, mLayer); + u8 kindRight = dBc_c::getUnitKind(x + width, y, mLayer) & 0xFF; + u32 typeLeft = dBc_c::getUnitType(x - width, y, mLayer); + u8 kindLeft = dBc_c::getUnitKind(x - width, y, mLayer) & 0xFF; if ( - u1 & BIT_FLAG(10) && u2 >= 2 || - u3 & BIT_FLAG(10) && u4 >= 2 + typeRight & BIT_FLAG(10) && kindRight >= 2 || + typeLeft & BIT_FLAG(10) && kindLeft >= 2 ) { if (!mAmiLayer) { mCc.mAmiLine = 1; @@ -362,35 +354,32 @@ void daEnNoko_c::updateAmiLine() { } void daEnNoko_c::dance() { - static const s16 buf_80ad34f0[2] = {-0x1555, 0x1555}; - sLib::chaseAngle(&m_8a8, buf_80ad34f0[mDirection], 0x400); + static const s16 sc_danceAngle[2] = {-DEG_TO_ANGLE(30), DEG_TO_ANGLE(30)}; + sLib::chaseAngle(&mBgmDanceAngle, sc_danceAngle[mDirection], 0x400); } bool daEnNoko_c::createIceActor() { - static const int buf_80ad34f8[2] = {0, 1}; - static const float buf_80ad3500[2] = {-2.0f, -4.0f}; - - float f_60; - mVec3_c f_5c; - int ice_mode; - - mVec3_c scale; + static const int sc_iceMode[2] = {0, 1}; + static const float cs_iceOffsetY[2] = {-2.0f, -4.0f}; + int iceMode; + mVec3_c icePos; + mVec3_c iceSize; if (*mStateMgr.getMainStateID() == StateID_BgmDance) { - f_5c.set(mPos.x, mPos.y - 4.0f, mPos.z + 2.0f); - ice_mode = 1; - scale.set(1.05f, 1.0f, 1.75f); + icePos.set(mPos.x, mPos.y - 4.0f, mPos.z + 2.0f); + iceMode = 1; + iceSize.set(1.05f, 1.0f, 1.75f); } else { - ice_mode = buf_80ad34f8[mUseBaseIceBehaviour]; - f_5c.set(mPos.x, mPos.y + buf_80ad3500[mUseBaseIceBehaviour], mPos.z); - scale.set(1.05f, 1.0f, 1.05f); + iceMode = sc_iceMode[mShellMode]; + icePos.set(mPos.x, mPos.y + cs_iceOffsetY[mShellMode], mPos.z); + iceSize.set(1.05f, 1.0f, 1.05f); } dIceInfo iceInfo[] = { { - ice_mode, - f_5c, - scale + iceMode, + icePos, + iceSize } }; @@ -398,7 +387,7 @@ bool daEnNoko_c::createIceActor() { } bool daEnNoko_c::checkSleep() { - if (((mParam >> 4) & 1) == 1) { + if (ACTOR_PARAM(SpawnMode) == 1) { return false; } @@ -414,7 +403,7 @@ void daEnNoko_c::beginFunsui() { mXSpeedBeforeFrozen = mSpeed.x; mSpeed.set(0.0f, 0.0f, 0.0f); - if (mUseBaseIceBehaviour == 0) { + if (mShellMode == SHELL_MODE_BASE) { changeState(StateID_Sleep); } else { mMoveAnim.setRate(2.0f); @@ -422,23 +411,22 @@ void daEnNoko_c::beginFunsui() { } void daEnNoko_c::endFunsui() { - mIsFrozen = 0; - if (mUseBaseIceBehaviour != 0) { + if (mShellMode != SHELL_MODE_BASE) { mMoveAnim.setRate(1.0f); mSpeed.x = mXSpeedBeforeFrozen; } } float daEnNoko_c::getWindMultiplier() { - daTagWind_c *ac_wind = (daTagWind_c *)fManager_c::searchBaseByProfName(fProfile::TAG_WIND, nullptr); + daTagWind_c *tagWind = (daTagWind_c *) fManager_c::searchBaseByProfName(fProfile::TAG_WIND, nullptr); - if (ac_wind == nullptr) { + if (tagWind == nullptr) { return 0.0f; } - return ac_wind->m_394; + return tagWind->m_394; } void daEnNoko_c::setMoveAnimation(const char *name, m3d::playMode_e mode, float frame) { @@ -451,10 +439,10 @@ void daEnNoko_c::setBaseAnimation(const char *name, m3d::playMode_e mode, float mModel.setAnm(mAnim, frame); } -bool daEnNoko_c::sub_80A73BC0() { - static const float buf_80ad3518[2] = {2.5f, -2.5f}; +bool daEnNoko_c::checkLedge() { + static const float sc_offsetX[2] = {2.5f, -2.5f}; - mVec3_c pos(mPos.x + buf_80ad3518[mDirection], mPos.y + 4.0f, mPos.z); + mVec3_c pos(mPos.x + sc_offsetX[mDirection], mPos.y + 4.0f, mPos.z); u8 kind = dBc_c::getUnitKind(pos.x, mPos.y - 2.0f, mLayer) >> 16; if (kind == 8) { @@ -469,7 +457,7 @@ bool daEnNoko_c::sub_80A73BC0() { return false; } -void daEnNoko_c::sub_80A73CB0() { +void daEnNoko_c::landEffect() { mVec3_c pos = mVec3_c(mPos.x, mPos.y, 5500.0f); if (mBc.getFootAttr() == 12) { @@ -489,15 +477,12 @@ void daEnNoko_c::initializeState_Walk() { setMoveAnimation("walkA", m3d::FORWARD_LOOP, 1.0f); } - float f = buf_80ad34b0[mDirection]; - mUseBaseIceBehaviour = 1; + mShellMode = SHELL_MODE_NOKO_WALK; mAccelY = -0.1875f; mAccelF = 0.05f; - mSpeedMax.x = f; - mSpeedMax.y = -4.0f; - mSpeedMax.z = 0.0f; - mSensorFootNormal = smc_noko_foot; - mSpeed.x = f; + mSpeedMax.set(l_walk_speed[mDirection], -4.0f, 0.0f); + mSensorFootNormal = l_noko_foot; + mSpeed.x = l_walk_speed[mDirection]; m_8c8 = 0; } @@ -505,8 +490,8 @@ void daEnNoko_c::finalizeState_Walk() {} void daEnNoko_c::executeState_Walk() { mNokoModel.play(); - float wind = getWindMultiplier(); + float wind = getWindMultiplier(); if (std::fabs(wind) > 0.475f) { if (l_EnMuki[mDirection] * wind >= 0.0f) { changeState(StateID_WindTurn); @@ -515,25 +500,26 @@ void daEnNoko_c::executeState_Walk() { mSpeedMax.x = 0.0f; } } else { - mSpeedMax.x = buf_80ad34b0[mDirection]; + mSpeedMax.x = l_walk_speed[mDirection]; } calcSpeedX(); calcSpeedY(); posMove(); - u32 foot = mBc.isFoot(); + + u32 prevFoot = mBc.isFoot(); EnBgCheck(); if (mBc.isFoot()) { mSpeed.y = 0.0f; - if ((mWalksOffLedges == true) && (!sub_80A73BC0())) { + if (mNokoType == NOKO_RED && !checkLedge()) { changeState(StateID_Turn); return; } - } else if (foot && !mInLiquid && (mSpeed.y <= 0.0f)) { + } else if (prevFoot && !mInLiquid && (mSpeed.y <= 0.0f)) { mFootPush2.x += m_1eb.x; } - if (mBc.mFlags & (0x15 << mDirection)) { + if (mBc.isWall(mDirection)) { changeState(StateID_Turn); } } @@ -541,7 +527,7 @@ void daEnNoko_c::executeState_Walk() { void daEnNoko_c::initializeState_Wakeup() { setMoveAnimation("revival", m3d::FORWARD_ONCE, 0.0f); setBaseAnimation("revival_shell", m3d::FORWARD_ONCE, 0.0f); - mUseBaseIceBehaviour = 1; + mShellMode = SHELL_MODE_NOKO_WALK; daEnShell_c::initializeState_Wakeup(); } @@ -558,11 +544,11 @@ void daEnNoko_c::executeState_Wakeup() { calcSpeedY(); posMove(); - u32 x = EnBgCheck(); - if (x & 1) { + u32 bgCheck = EnBgCheck(); + if (bgCheck & 1) { mSpeed.y = 0.0f; } - if (x & 4) { + if (bgCheck & 4) { mSpeed.x = 0.0f; } @@ -597,8 +583,8 @@ void daEnNoko_c::executeState_Turn() { mNokoModel.play(); calcSpeedY(); posMove(); - u32 x = EnBgCheck(); - if (x & 1) { + + if (EnBgCheck() & 1) { mSpeed.y = 0.0f; } @@ -621,8 +607,8 @@ void daEnNoko_c::executeState_WindTurn() { mNokoModel.play(); calcSpeedY(); posMove(); - u32 x = EnBgCheck(); - if (x & 1) { + + if (EnBgCheck() & 1) { mSpeed.y = 0.0f; } @@ -650,7 +636,7 @@ void daEnNoko_c::executeState_BlockAppear() { } void daEnNoko_c::initializeState_SpitOut_Ready() { - mNoHitPlayer.mTimer[(mParam >> 24) & 3] = 16; + mNoHitPlayer.mTimer[ACTOR_PARAM(BlockHitPlayer)] = 16; } void daEnNoko_c::finalizeState_SpitOut_Ready() { } @@ -660,7 +646,7 @@ void daEnNoko_c::executeState_SpitOut_Ready() { return; } - dActor_c *player = (dActor_c *)fManager_c::searchBaseByID(mEatenByID); + dActor_c *player = (dActor_c *) fManager_c::searchBaseByID(mEatenByID); if (player == nullptr) { deleteRequest(); } else { @@ -671,16 +657,16 @@ void daEnNoko_c::executeState_SpitOut_Ready() { } void daEnNoko_c::initializeState_BgmDance() { - static const char *buf_80afdd98[3] = { + static const char *sc_bgmDanceAnim[3] = { "BGM_anim_walkA_1", "BGM_anim_walkA_1", "BGM_anim_walkA_3", }; - setMoveAnimation(buf_80afdd98[mDanceMove], m3d::FORWARD_ONCE, 3.0f); + setMoveAnimation(sc_bgmDanceAnim[mDanceMove], m3d::FORWARD_ONCE, 3.0f); mSpeed.x = 0.0; mDancesRemaining = 3; - mYRotIncrease = (u16)(abs((int)mAngle.y) / (int)mDancesRemaining); + mBgmDanceRotSpeed = mAngle.y.abs() / mDancesRemaining; } void daEnNoko_c::finalizeState_BgmDance() {} @@ -690,14 +676,13 @@ void daEnNoko_c::executeState_BgmDance() { calcSpeedY(); posMove(); - u32 x = EnBgCheck(); - if (x & 1) { + if (EnBgCheck() & 1) { mSpeed.y = 0.0f; } if (mDancesRemaining > 0) { mDancesRemaining--; - sLib::chaseAngle((s16*)&mAngle.y, 0, mYRotIncrease); + sLib::chaseAngle(&mAngle.y.mAngle, 0, mBgmDanceRotSpeed); } else { mAngle.y = 0; } @@ -711,7 +696,7 @@ void daEnNoko_c::initializeState_BgmDanceEd() { setMoveAnimation("walkA", m3d::FORWARD_ONCE, 4.0f); mSpeed.x = 0.0f; mDancesRemaining = 4; - mYRotIncrease = abs(buf_80ad34bc[mDirection]) / mDancesRemaining; + mBgmDanceRotSpeed = abs(l_turn_target_angle[mDirection]) / mDancesRemaining; } void daEnNoko_c::finalizeState_BgmDanceEd() {} @@ -720,20 +705,20 @@ void daEnNoko_c::executeState_BgmDanceEd() { mNokoModel.play(); calcSpeedY(); posMove(); - u32 x = EnBgCheck(); - if (x & 1) { + + if (EnBgCheck() & 1) { mSpeed.y = 0.0; } if (mDancesRemaining > 0) { mDancesRemaining--; - sLib::chaseAngle((s16*)&mAngle.y, buf_80ad34bc[mDirection], mYRotIncrease); + sLib::chaseAngle(&mAngle.y.mAngle, l_turn_target_angle[mDirection], mBgmDanceRotSpeed); if (mDancesRemaining > 0) { return; } - mAngle.y = buf_80ad34bc[mDirection]; + mAngle.y = l_turn_target_angle[mDirection]; changeState(StateID_Walk); } } @@ -742,7 +727,7 @@ void daEnNoko_c::nodeCallback_c::timingB(ulong nodeId, nw4r::g3d::WorldMtxManip mMtx_c mtx; if (strcmp(resMdl.GetResNode(nodeId).GetName(), "head") == 0) { manip->GetMatrix(&mtx); - mtx.XrotM(mpOwner->m_8a8); + mtx.XrotM(mpOwner->mBgmDanceAngle); manip->SetMatrix(mtx); } -} \ No newline at end of file +} diff --git a/source/dol/bases/d_a_en_shell.cpp b/source/dol/bases/d_a_en_shell.cpp index b81a283c..b3619f47 100644 --- a/source/dol/bases/d_a_en_shell.cpp +++ b/source/dol/bases/d_a_en_shell.cpp @@ -128,7 +128,7 @@ void daEnShell_c::postExecute(fBase_c::MAIN_STATE_e status) { setDeathInfo_Hasami(); } mVec3_c pos = mPos; - if (!mUseBaseIceBehaviour) { + if (mShellMode == SHELL_MODE_BASE) { pos = getCenterPos(); } WaterCheck(pos, 1.0f); @@ -168,7 +168,7 @@ void daEnShell_c::Normal_VsEnHitCheck(dCc_c *self, dCc_c *other) { dActor_c *otherActor = other->getOwner(); if ( isState(daEnCarry_c::StateID_Carry) && - other->mCcData.mVsDamage & (1 << CC_ATTACK_SHELL) && + other->mCcData.mVsDamage & BIT_FLAG(CC_ATTACK_SHELL) && otherActor->mProfName != fProfile::EN_HATENA_BALLOON && hitCallback_Shell(self, other) ) { @@ -177,8 +177,8 @@ void daEnShell_c::Normal_VsEnHitCheck(dCc_c *self, dCc_c *other) { } if ( isState(StateID_Slide) && - (other->mCcData.mStatus & CC_STATUS_8 && - hitCallback_Shell(self, other)) + other->mCcData.mStatus & CC_STATUS_8 && + hitCallback_Shell(self, other) ) { self->mInfo |= CC_NO_HIT; return; @@ -768,7 +768,7 @@ bool daEnShell_c::hitCallback_Ice(dCc_c *self, dCc_c *other) { break; } } - if (!mUseBaseIceBehaviour) { + if (mShellMode == SHELL_MODE_BASE) { changeState(StateID_Ice); mPlayerNo = -1; } else { @@ -778,7 +778,7 @@ bool daEnShell_c::hitCallback_Ice(dCc_c *self, dCc_c *other) { } void daEnShell_c::returnState_Ice() { - if (!mUseBaseIceBehaviour) { + if (mShellMode == SHELL_MODE_BASE) { mPlayerNo = -1; mSpeed.set(0.0f, 0.0f, 0.0f); changeState(StateID_Sleep); @@ -887,7 +887,7 @@ void daEnShell_c::initializeState_Sleep() { mSpeedMax.y = -4.0f; mAccelY = -0.1875f; clrComboCnt(); - mUseBaseIceBehaviour = 0; + mShellMode = SHELL_MODE_BASE; mCc.mCcData.mVsDamage |= (1 << CC_ATTACK_SPIN_LIFT_UP); mWakeupShakeAngle = 0; mWakeupShakeAngle3D.x = 0; @@ -966,7 +966,7 @@ void daEnShell_c::initializeState_Carry() { if (mSleepTimer > smc_SLEEP_TIMER_SHAKE) { mCarryTimer = mSleepTimer; } - mUseBaseIceBehaviour = 0; + mShellMode = SHELL_MODE_BASE; mWakeupShakeAngle = 0; mWakeupShakeAngle3D.x = 0; mWakeupShakeAngle3D.y = 0; @@ -1067,7 +1067,7 @@ void daEnShell_c::initializeState_Slide() { mCc.mCcData.mVsKind |= (1 << CC_KIND_BALLOON) | (1 << CC_KIND_ITEM) | (1 << CC_KIND_KILLER); mCc.mCcData.mAttack = CC_ATTACK_SHELL; - mUseBaseIceBehaviour = 0; + mShellMode = SHELL_MODE_BASE; mAccelF = 1 / 1024.0f; mAccelY = -0.1875f; mSpeedMax.set(mSpeed.x, -4.0f, 0.0f); @@ -1250,7 +1250,7 @@ void daEnShell_c::executeState_WakeupReverse() { void daEnShell_c::initializeState_DieFall() { if (isDieShell()) { - mUseBaseIceBehaviour = 0; + mShellMode = SHELL_MODE_BASE; } mFootAttr3 = false; dEn_c::initializeState_DieFall(); From 1b7b40636d095da0ecd955d359c7ca732ecfcd7f Mon Sep 17 00:00:00 2001 From: RootCubed Date: Wed, 6 May 2026 16:10:56 +0200 Subject: [PATCH 8/9] Further cleanup --- include/game/bases/d_a_en_noko.hpp | 122 +++++++++++---------- include/game/bases/d_a_en_shell.hpp | 2 +- include/game/bases/d_a_tag_wind.hpp | 2 +- source/d_enemiesNP/bases/d_a_en_noko.cpp | 133 +++++++++++------------ 4 files changed, 132 insertions(+), 127 deletions(-) diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp index b93896e9..d16cfbec 100644 --- a/include/game/bases/d_a_en_noko.hpp +++ b/include/game/bases/d_a_en_noko.hpp @@ -22,42 +22,41 @@ class daEnNoko_c : public daEnShell_c { }; daEnNoko_c() { mMdlCallback.mpOwner = this; } - ~daEnNoko_c() {} - - virtual int create() override; - virtual int doDelete() override; - virtual int execute() override; - virtual int preExecute() override; - virtual int draw() override; - virtual void finalUpdate() override { calcMdl(); } - virtual bool createIceActor() override; - virtual void beginFunsui() override; - virtual void endFunsui() override; - - STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); - STATE_FUNC_DECLARE(daEnNoko_c, Walk); - STATE_FUNC_DECLARE(daEnNoko_c, Turn); - STATE_FUNC_DECLARE(daEnNoko_c, WindTurn); - STATE_FUNC_DECLARE(daEnNoko_c, SpitOut_Ready); - STATE_FUNC_DECLARE(daEnNoko_c, BgmDance); - STATE_FUNC_DECLARE(daEnNoko_c, BgmDanceEd); + + int create() override; + int doDelete() override; + int execute() override; + int preExecute() override; + int draw() override; + void finalUpdate() override { calcMdl(); } + bool createIceActor() override; + void beginFunsui() override; + void endFunsui() override; + + STATE_FUNC_DECLARE(daEnNoko_c, BlockAppear); ///< Spawning from a block. + STATE_FUNC_DECLARE(daEnNoko_c, Walk); ///< Walking on the ground. + STATE_FUNC_DECLARE(daEnNoko_c, Turn); ///< Turning around while walking. + STATE_FUNC_DECLARE(daEnNoko_c, WindTurn); ///< Being turned around by the wind. + STATE_FUNC_DECLARE(daEnNoko_c, SpitOut_Ready); ///< About to be spit out by Yoshi. + STATE_FUNC_DECLARE(daEnNoko_c, BgmDance); ///< Doing a dance move to the background music. + STATE_FUNC_DECLARE(daEnNoko_c, BgmDanceEd); ///< Returning from a dance move to walking. STATE_VIRTUAL_FUNC_DECLARE(daEnNoko_c, Wakeup); STATE_VIRTUAL_FUNC_DECLARE(daEnNoko_c, WakeupTurn); - virtual bool setPlayerDamage(dActor_c *actor) override; - virtual bool checkSleep() override; - virtual bool turnProc() override; - virtual void calcShellEffectPos() override; - virtual void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } + bool setPlayerDamage(dActor_c *actor) override; + bool checkSleep() override; + bool turnProc() override; + void calcShellEffectPos() override; + void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } virtual void checkWaterEntry() { WaterCheck(mPos, 1.0f); } - virtual void setAfterSleepState() override { changeState(StateID_Walk); } - virtual void slideEffect() override { + void setAfterSleepState() override { changeState(StateID_Walk); } + void slideEffect() override { if (!mNokoType) { - mEffect.createEffect("Wm_en_shellgreentail", 0, &m_71c, nullptr, nullptr); + mEffect.createEffect("Wm_en_shellgreentail", 0, &mSlideEffectPos, nullptr, nullptr); } else { - mEffect.createEffect("Wm_en_shellredtail", 0, &m_71c, nullptr, nullptr); + mEffect.createEffect("Wm_en_shellredtail", 0, &mSlideEffectPos, nullptr, nullptr); } } @@ -67,55 +66,62 @@ class daEnNoko_c : public daEnShell_c { virtual void calcMdl(); virtual bool canDance(); virtual void danceWithMove(int move); - virtual void dance(); + virtual void walkTurn(); + + /// @brief Initializes the state of the Koopa after creation. virtual void setInitialState(); - virtual void vf324() {} + + /// @brief Subclasses can override this function to create additional models. + virtual void createModelExtra() {} virtual void vf328() {} + + /// @brief Subclasses can override this function to delete additional resources. virtual void deleteResExtra() {} + virtual mVec3_c getPos() { return mVec3_c(mPos.x, mPos.y, mPos.z); } - virtual BOOL isFunsui() const override { return mIsFrozen; } + BOOL isFunsui() const override { return mIsFunsui; } - void loadRes(); + void createModel(); void updateAmiLine(); void setZPos(); - bool isInQuicksand(); - void spawnQuicksandEffects(); - bool playerDamageTurn(dActor_c *); - void setNokoBc(); - float getWindMultiplier(); + bool checkRyusa(); ///< Checks if the actor is inside quicksand. + void ryusaEffect(); ///< Creates the quicksand effect. + bool playerDamageTurn(dActor_c *); ///< Returns whether the Koopa should turn around after damaging the player. + void setNokoBc(); ///< Reverts the collision to a regular Koopa. + float getWindStrength(); void setMoveAnimation(const char *name, m3d::playMode_e mode, float frame); void setBaseAnimation(const char *name, m3d::playMode_e mode, float frame); - bool checkLedge(); + bool checkLedge(); ///< Checks if there is a ledge in front of the Koopa. void landEffect(); u8 mPad0[4]; - dHeapAllocator_c mNokoAllocator; - nw4r::g3d::ResFile mNokoResFile; - m3d::mdl_c mNokoModel; - m3d::anmChr_c mMoveAnim; - nw4r::g3d::ResAnmTexPat mNokoResAnmTexPat; - m3d::anmTexPat_c mNokoAnimTex; + dHeapAllocator_c mNokoAllocator; ///< The allocator used for the resources of this actor. + nw4r::g3d::ResFile mNokoResFile; ///< The resource file containing the resources of this actor. + m3d::mdl_c mNokoModel; ///< The model of the Koopa. + m3d::anmChr_c mWalkAnim; ///< The walk animation of the Koopa. + nw4r::g3d::ResAnmTexPat mNokoResAnmTex; ///< The animated texture resource of the Koopa. + m3d::anmTexPat_c mNokoAnimTex; ///< The animated texture of the Koopa. - u32 mIsFrozen; - s16 mBgmDanceAngle; + BOOL mIsFunsui; ///< Whether the Koopa is being blown upwards by a fountain. + s16 mHeadAngle; u8 mNokoType; ///< Is a NokoType_e. - mVec3_c mCreatePos; - float mXSpeedBeforeFrozen; + mVec3_c mCreatePos; ///< The position where the Koopa was spawned. + float mXSpeedBeforeFunsui; ///< The horizontal speed of the Koopa before being blown by a fountain. u8 mPad1[8]; float mBaseZPos; u32 m_8c8; - int mDancesRemaining; - mAng mBgmDanceRotSpeed; - u32 mDanceMove; - mEf::levelOneEffect_c mQuickSandEffect; + int mDanceTimer; ///< Timer for starting and ending the dance. + mAng mBgmDanceRotSpeed; ///< The rotation speed for turning toward the target rotation for a dance. + u32 mDanceMove; ///< Which dance move to perform. + mEf::levelOneEffect_c mQuicksandEffect; nodeCallback_c mMdlCallback; - ACTOR_PARAM_CONFIG(NokoType, 0, 1); - ACTOR_PARAM_CONFIG(SpawnMode, 4, 1); ///< 1 = Spawn as sleeping shell - ACTOR_PARAM_CONFIG(Layer, 16, 1); - ACTOR_PARAM_CONFIG(BlockHitPlayer, 24, 2); - ACTOR_PARAM_CONFIG(BlockAppear, 28, 1); - ACTOR_PARAM_CONFIG(SpitOut, 29, 1); + ACTOR_PARAM_CONFIG(NokoType, 0, 1); ///< See NokoType_e. + ACTOR_PARAM_CONFIG(SpawnMode, 4, 1); ///< Set to 1 to spawn as a sleeping shell. + ACTOR_PARAM_CONFIG(Layer, 16, 1); ///< The layer to spawn on. + ACTOR_PARAM_CONFIG(BlockHitPlayer, 24, 2); ///< The player number that hit the block from which this Koopa spawned. + ACTOR_PARAM_CONFIG(BlockAppear, 28, 1); ///< Whether the Koopa should spawn from a block. + ACTOR_PARAM_CONFIG(SpitOut, 29, 1); ///< Whether this Koopa was spat out by Yoshi. }; diff --git a/include/game/bases/d_a_en_shell.hpp b/include/game/bases/d_a_en_shell.hpp index e63442d6..71ecb506 100644 --- a/include/game/bases/d_a_en_shell.hpp +++ b/include/game/bases/d_a_en_shell.hpp @@ -113,7 +113,7 @@ class daEnShell_c : public daEnCarry_c { mEf::levelEffect_c mEffect; int mYoshiKickable; ///< Whether the shell can be kicked in any state by Yoshi. ShellMode_e mShellMode; - mVec3_c m_71c; + mVec3_c mSlideEffectPos; mVec3_c mCarryPos; int mIsCarryFall; int mSlideAirAfterThrow; diff --git a/include/game/bases/d_a_tag_wind.hpp b/include/game/bases/d_a_tag_wind.hpp index 4a9367ac..0a34eba0 100644 --- a/include/game/bases/d_a_tag_wind.hpp +++ b/include/game/bases/d_a_tag_wind.hpp @@ -4,6 +4,6 @@ class daTagWind_c : public dActor_c { public: - float m_394; + float mStrength; u8 mPad[32]; }; diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp index 02f70df5..c15ab2ed 100644 --- a/source/d_enemiesNP/bases/d_a_en_noko.cpp +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -21,9 +21,9 @@ const sCcDatNewF l_noko_cc = { dEn_c::normal_collcheck }; -const float l_walk_speed[2] = {0.5f, -0.5f}; -const s16 l_turn_speed[2] = {ANGLE_360_DIV(32), -ANGLE_360_DIV(32)}; -const s16 l_turn_target_angle[2] = {DEG_TO_ANGLE(90), -DEG_TO_ANGLE(90)}; +const float l_walk_speed[2] = { 0.5f, -0.5f }; +const s16 l_turn_speed[2] = { ANGLE_360_DIV(32), -ANGLE_360_DIV(32) }; +const s16 l_turn_target_angle[2] = { DEG_TO_ANGLE(90), -DEG_TO_ANGLE(90) }; STATE_DEFINE(daEnNoko_c, BlockAppear); STATE_DEFINE(daEnNoko_c, Walk); @@ -40,7 +40,7 @@ ACTOR_PROFILE(EN_NOKONOKO, daEnNoko_c, 0x12); int daEnNoko_c::create() { mNokoType = ACTOR_PARAM(NokoType); - loadRes(); + createModel(); createShell("nokonokoA", "g3d/nokonokoA.brres", "nokonoko_shell", "Tnokonoko_shell", mNokoType); mScale.set(1.0f, 1.0f, 1.0f); mCenterOffs.set(0.0f, 8.0f, 0.0); @@ -85,10 +85,10 @@ int daEnNoko_c::create() { mBc.set(this, mSensorFootNormal, mSensorHead, mSensorWall); mBc.m_4c = mPos.x; - return 1; + return SUCCEEDED; } -void daEnNoko_c::loadRes() { +void daEnNoko_c::createModel() { mNokoAllocator.createFrmHeap(-1, mHeap::g_gameHeaps[mHeap::GAME_HEAP_DEFAULT], nullptr, 0x20); mNokoResFile = dResMng_c::m_instance->getRes("nokonokoA", "g3d/nokonokoA.brres"); @@ -98,14 +98,15 @@ void daEnNoko_c::loadRes() { dActor_c::setSoftLight_Enemy(mNokoModel); nw4r::g3d::ResAnmChr anm = mNokoResFile.GetResAnmChr("walkA"); - mMoveAnim.create(mdl, anm, &mNokoAllocator, nullptr); - mNokoResAnmTexPat = mNokoResFile.GetResAnmTexPat("nokonokoA"); - mNokoAnimTex.create(mdl, mNokoResAnmTexPat, &mNokoAllocator, nullptr, 1); + mWalkAnim.create(mdl, anm, &mNokoAllocator, nullptr); + mNokoResAnmTex = mNokoResFile.GetResAnmTexPat("nokonokoA"); + mNokoAnimTex.create(mdl, mNokoResAnmTex, &mNokoAllocator, nullptr, 1); + + createModelExtra(); - vf324(); mNokoAllocator.adjustFrmHeap(); - mNokoAnimTex.setAnm(mNokoModel, mNokoResAnmTexPat, 0, m3d::FORWARD_ONCE); + mNokoAnimTex.setAnm(mNokoModel, mNokoResAnmTex, 0, m3d::FORWARD_ONCE); } void daEnNoko_c::setInitialState() { @@ -128,11 +129,11 @@ int daEnNoko_c::preExecute() { } if (canDance()) { - if (dAudio::isBgmAccentSign(2)) { + if (dAudio::isBgmAccentSign(BIT_FLAG(1))) { danceWithMove(0); - } else if (dAudio::isBgmAccentSign(4)) { + } else if (dAudio::isBgmAccentSign(BIT_FLAG(2))) { danceWithMove(1); - } else if (dAudio::isBgmAccentSign(8)) { + } else if (dAudio::isBgmAccentSign(BIT_FLAG(3))) { danceWithMove(2); } } @@ -148,16 +149,16 @@ int daEnNoko_c::execute() { } if (isState(StateID_BgmDance)) { - mBgmDanceAngle = 0; + mHeadAngle = 0; } else { - dance(); + walkTurn(); } if (!mNoRespawn && !isState(StateID_Ice)) { updateAmiLine(); setZPos(); - if (isInQuicksand()) { - spawnQuicksandEffects(); + if (checkRyusa()) { + ryusaEffect(); } } @@ -179,7 +180,7 @@ int daEnNoko_c::draw() { int daEnNoko_c::doDelete() { if (mNokoAllocator.mpHeap != mAllocatorDummyHeap_c::getInstance()) { - mMoveAnim.remove(); + mWalkAnim.remove(); mNokoModel.remove(); mNokoAnimTex.remove(); deleteResExtra(); @@ -188,13 +189,13 @@ int daEnNoko_c::doDelete() { return SUCCEEDED; } -bool daEnNoko_c::isInQuicksand() { +bool daEnNoko_c::checkRyusa() { if (mBc.isFoot()) { mVec3_c pos = getCenterPos(); u32 type = dBc_c::getUnitType(pos.x, pos.y, mLayer); - u8 subkind = dBc_c::getUnitKind(pos.x, pos.y, mLayer) >> 16; + u8 kind = dBc_c::getUnitKind(pos.x, pos.y, mLayer) >> 16; - if (type & BIT_FLAG(15) && subkind == 3) { + if (type & BIT_FLAG(15) && kind == 3) { return true; } } @@ -202,10 +203,10 @@ bool daEnNoko_c::isInQuicksand() { return false; } -void daEnNoko_c::spawnQuicksandEffects() { +void daEnNoko_c::ryusaEffect() { mVec3_c center = getCenterPos(); mVec3_c efPos(center.x, center.y, 5500.0f); - mQuickSandEffect.createEffect("Wm_en_quicksand", 0, &efPos, nullptr, nullptr); + mQuicksandEffect.createEffect("Wm_en_quicksand", 0, &efPos, nullptr, nullptr); } bool daEnNoko_c::canDance() { @@ -250,14 +251,14 @@ void daEnNoko_c::calcShellEffectPos() { mMtx_c matrix; model.getNodeWorldMtx(resNode.GetID(), &matrix); - matrix.multVecZero(m_71c); + matrix.multVecZero(mSlideEffectPos); if (mIsFlipped) { - m_71c.y -= 16.0f; + mSlideEffectPos.y -= 16.0f; } } bool daEnNoko_c::setPlayerDamage(dActor_c *actor) { - daPlBase_c *player = (daPlBase_c *)actor; + daPlBase_c *player = (daPlBase_c *) actor; if (player->setDamage(this, daPlBase_c::DAMAGE_DEFAULT) && isWalking()) { playerDamageTurn(actor); @@ -277,7 +278,7 @@ bool daEnNoko_c::playerDamageTurn(dActor_c *actor) { mDirection = dir; mAngle.y = l_turn_target_angle[dir]; - mBgmDanceAngle *= -1; + mHeadAngle *= -1; turnAround(); return true; @@ -343,7 +344,7 @@ void daEnNoko_c::updateAmiLine() { typeRight & BIT_FLAG(10) && kindRight >= 2 || typeLeft & BIT_FLAG(10) && kindLeft >= 2 ) { - if (!mAmiLayer) { + if (mAmiLayer == 0) { mCc.mAmiLine = 1; } else { mCc.mAmiLine = 2; @@ -353,14 +354,14 @@ void daEnNoko_c::updateAmiLine() { } } -void daEnNoko_c::dance() { - static const s16 sc_danceAngle[2] = {-DEG_TO_ANGLE(30), DEG_TO_ANGLE(30)}; - sLib::chaseAngle(&mBgmDanceAngle, sc_danceAngle[mDirection], 0x400); +void daEnNoko_c::walkTurn() { + static const s16 sc_walkAngle[2] = { -DEG_TO_ANGLE(30), DEG_TO_ANGLE(30) }; + sLib::chaseAngle(&mHeadAngle, sc_walkAngle[mDirection], ANGLE_360_DIV(64)); } bool daEnNoko_c::createIceActor() { - static const int sc_iceMode[2] = {0, 1}; - static const float cs_iceOffsetY[2] = {-2.0f, -4.0f}; + static const int sc_iceMode[2] = { 0, 1 }; + static const float cs_iceOffsetY[2] = { -2.0f, -4.0f }; int iceMode; mVec3_c icePos; @@ -399,39 +400,39 @@ void daEnNoko_c::beginFunsui() { return; } - mIsFrozen = 1; - mXSpeedBeforeFrozen = mSpeed.x; + mIsFunsui = true; + mXSpeedBeforeFunsui = mSpeed.x; mSpeed.set(0.0f, 0.0f, 0.0f); if (mShellMode == SHELL_MODE_BASE) { changeState(StateID_Sleep); } else { - mMoveAnim.setRate(2.0f); + mWalkAnim.setRate(2.0f); } } void daEnNoko_c::endFunsui() { - mIsFrozen = 0; + mIsFunsui = false; if (mShellMode != SHELL_MODE_BASE) { - mMoveAnim.setRate(1.0f); - mSpeed.x = mXSpeedBeforeFrozen; + mWalkAnim.setRate(1.0f); + mSpeed.x = mXSpeedBeforeFunsui; } } -float daEnNoko_c::getWindMultiplier() { +float daEnNoko_c::getWindStrength() { daTagWind_c *tagWind = (daTagWind_c *) fManager_c::searchBaseByProfName(fProfile::TAG_WIND, nullptr); if (tagWind == nullptr) { return 0.0f; } - return tagWind->m_394; + return tagWind->mStrength; } void daEnNoko_c::setMoveAnimation(const char *name, m3d::playMode_e mode, float frame) { - mMoveAnim.setAnm(mNokoModel, mNokoResFile.GetResAnmChr(name), mode); - mNokoModel.setAnm(mMoveAnim, frame); + mWalkAnim.setAnm(mNokoModel, mNokoResFile.GetResAnmChr(name), mode); + mNokoModel.setAnm(mWalkAnim, frame); } void daEnNoko_c::setBaseAnimation(const char *name, m3d::playMode_e mode, float frame) { @@ -440,7 +441,7 @@ void daEnNoko_c::setBaseAnimation(const char *name, m3d::playMode_e mode, float } bool daEnNoko_c::checkLedge() { - static const float sc_offsetX[2] = {2.5f, -2.5f}; + static const float sc_offsetX[2] = { 2.5f, -2.5f }; mVec3_c pos(mPos.x + sc_offsetX[mDirection], mPos.y + 4.0f, mPos.z); u8 kind = dBc_c::getUnitKind(pos.x, mPos.y - 2.0f, mLayer) >> 16; @@ -491,7 +492,7 @@ void daEnNoko_c::finalizeState_Walk() {} void daEnNoko_c::executeState_Walk() { mNokoModel.play(); - float wind = getWindMultiplier(); + float wind = getWindStrength(); if (std::fabs(wind) > 0.475f) { if (l_EnMuki[mDirection] * wind >= 0.0f) { changeState(StateID_WindTurn); @@ -552,7 +553,7 @@ void daEnNoko_c::executeState_Wakeup() { mSpeed.x = 0.0f; } - if (mMoveAnim.isStop()) { + if (mWalkAnim.isStop()) { changeState(daEnShell_c::StateID_WakeupTurn); } } @@ -614,7 +615,7 @@ void daEnNoko_c::executeState_WindTurn() { turnProc(); - if (std::fabs(getWindMultiplier()) < 0.25f) { + if (std::fabs(getWindStrength()) < 0.25f) { changeState(StateID_Turn); } } @@ -646,12 +647,12 @@ void daEnNoko_c::executeState_SpitOut_Ready() { return; } - dActor_c *player = (dActor_c *) fManager_c::searchBaseByID(mEatenByID); - if (player == nullptr) { + dActor_c *eatActor = (dActor_c *) fManager_c::searchBaseByID(mEatenByID); + if (eatActor == nullptr) { deleteRequest(); } else { - setSlideThrowSpeed(player); - mPlayerNo = player->getPlrNo(); + setSlideThrowSpeed(eatActor); + mPlayerNo = eatActor->getPlrNo(); changeState(StateID_Slide); } } @@ -665,8 +666,8 @@ void daEnNoko_c::initializeState_BgmDance() { setMoveAnimation(sc_bgmDanceAnim[mDanceMove], m3d::FORWARD_ONCE, 3.0f); mSpeed.x = 0.0; - mDancesRemaining = 3; - mBgmDanceRotSpeed = mAngle.y.abs() / mDancesRemaining; + mDanceTimer = 3; + mBgmDanceRotSpeed = mAngle.y.abs() / mDanceTimer; } void daEnNoko_c::finalizeState_BgmDance() {} @@ -680,14 +681,14 @@ void daEnNoko_c::executeState_BgmDance() { mSpeed.y = 0.0f; } - if (mDancesRemaining > 0) { - mDancesRemaining--; + if (mDanceTimer > 0) { + mDanceTimer--; sLib::chaseAngle(&mAngle.y.mAngle, 0, mBgmDanceRotSpeed); } else { mAngle.y = 0; } - if (mMoveAnim.isStop()) { + if (mWalkAnim.isStop()) { changeState(StateID_BgmDanceEd); } } @@ -695,8 +696,8 @@ void daEnNoko_c::executeState_BgmDance() { void daEnNoko_c::initializeState_BgmDanceEd() { setMoveAnimation("walkA", m3d::FORWARD_ONCE, 4.0f); mSpeed.x = 0.0f; - mDancesRemaining = 4; - mBgmDanceRotSpeed = abs(l_turn_target_angle[mDirection]) / mDancesRemaining; + mDanceTimer = 4; + mBgmDanceRotSpeed = abs(l_turn_target_angle[mDirection]) / mDanceTimer; } void daEnNoko_c::finalizeState_BgmDanceEd() {} @@ -710,16 +711,14 @@ void daEnNoko_c::executeState_BgmDanceEd() { mSpeed.y = 0.0; } - if (mDancesRemaining > 0) { - mDancesRemaining--; + if (mDanceTimer > 0) { + mDanceTimer--; sLib::chaseAngle(&mAngle.y.mAngle, l_turn_target_angle[mDirection], mBgmDanceRotSpeed); - if (mDancesRemaining > 0) { - return; + if (mDanceTimer <= 0) { + mAngle.y = l_turn_target_angle[mDirection]; + changeState(StateID_Walk); } - - mAngle.y = l_turn_target_angle[mDirection]; - changeState(StateID_Walk); } } @@ -727,7 +726,7 @@ void daEnNoko_c::nodeCallback_c::timingB(ulong nodeId, nw4r::g3d::WorldMtxManip mMtx_c mtx; if (strcmp(resMdl.GetResNode(nodeId).GetName(), "head") == 0) { manip->GetMatrix(&mtx); - mtx.XrotM(mpOwner->mBgmDanceAngle); + mtx.XrotM(mpOwner->mHeadAngle); manip->SetMatrix(mtx); } } From f2ab328c752cbe3e26b4b31524ccca01a4aeef2a Mon Sep 17 00:00:00 2001 From: CLF78 <29682335+CLF78@users.noreply.github.com> Date: Sun, 10 May 2026 22:48:34 +0200 Subject: [PATCH 9/9] Apply code review --- include/game/bases/d_a_en_noko.hpp | 33 +++++++++++++++++++----- include/game/bases/d_cc.hpp | 15 +++++++++++ source/d_enemiesNP/bases/d_a_en_noko.cpp | 33 +++++++++--------------- source/dol/bases/d_cc.cpp | 9 +------ 4 files changed, 54 insertions(+), 36 deletions(-) diff --git a/include/game/bases/d_a_en_noko.hpp b/include/game/bases/d_a_en_noko.hpp index d16cfbec..a7579d66 100644 --- a/include/game/bases/d_a_en_noko.hpp +++ b/include/game/bases/d_a_en_noko.hpp @@ -11,6 +11,7 @@ class daEnNoko_c : public daEnShell_c { public: class nodeCallback_c : public m3d::mdl_c::callback_c { public: + nodeCallback_c(daEnNoko_c *owner) : mpOwner(owner) {} virtual void timingB(ulong nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl); daEnNoko_c *mpOwner; @@ -21,7 +22,19 @@ class daEnNoko_c : public daEnShell_c { NOKO_RED ///< Red Koopas turn around on ledges. }; - daEnNoko_c() { mMdlCallback.mpOwner = this; } + enum SPAWN_MODE_e { + SPAWN_MODE_WALK, + SPAWN_MODE_SLEEP, + }; + + enum DANCE_MOVE_e { + BGM_anim_walkA_1, + BGM_anim_walkA_2, ///< Actually uses the same animation as BGM_anim_walkA_1. + BGM_anim_walkA_3, + DANCE_MOVE_COUNT, + }; + + daEnNoko_c() : mMdlCallback(this) {} int create() override; int doDelete() override; @@ -47,11 +60,17 @@ class daEnNoko_c : public daEnShell_c { bool checkSleep() override; bool turnProc() override; void calcShellEffectPos() override; - void setEnemyTurn() override { if (isState(StateID_Walk)) { changeState(StateID_Turn); } } + + void setEnemyTurn() override { + if (isState(StateID_Walk)) { + changeState(StateID_Turn); + } + } virtual void checkWaterEntry() { WaterCheck(mPos, 1.0f); } void setAfterSleepState() override { changeState(StateID_Walk); } + void slideEffect() override { if (!mNokoType) { mEffect.createEffect("Wm_en_shellgreentail", 0, &mSlideEffectPos, nullptr, nullptr); @@ -106,7 +125,7 @@ class daEnNoko_c : public daEnShell_c { BOOL mIsFunsui; ///< Whether the Koopa is being blown upwards by a fountain. s16 mHeadAngle; - u8 mNokoType; ///< Is a NokoType_e. + u8 mNokoType; ///< Is a NOKO_TYPE_e. mVec3_c mCreatePos; ///< The position where the Koopa was spawned. float mXSpeedBeforeFunsui; ///< The horizontal speed of the Koopa before being blown by a fountain. u8 mPad1[8]; @@ -114,13 +133,13 @@ class daEnNoko_c : public daEnShell_c { u32 m_8c8; int mDanceTimer; ///< Timer for starting and ending the dance. mAng mBgmDanceRotSpeed; ///< The rotation speed for turning toward the target rotation for a dance. - u32 mDanceMove; ///< Which dance move to perform. + u32 mDanceMove; ///< The dance move to perform. mEf::levelOneEffect_c mQuicksandEffect; nodeCallback_c mMdlCallback; - ACTOR_PARAM_CONFIG(NokoType, 0, 1); ///< See NokoType_e. - ACTOR_PARAM_CONFIG(SpawnMode, 4, 1); ///< Set to 1 to spawn as a sleeping shell. - ACTOR_PARAM_CONFIG(Layer, 16, 1); ///< The layer to spawn on. + ACTOR_PARAM_CONFIG(NokoType, 0, 1); ///< See NOKO_TYPE_e. + ACTOR_PARAM_CONFIG(SpawnMode, 4, 1); ///< See SPAWN_MODE_e. + ACTOR_PARAM_CONFIG(SubLayer, 16, 1); ///< The sublayer to spawn on. ACTOR_PARAM_CONFIG(BlockHitPlayer, 24, 2); ///< The player number that hit the block from which this Koopa spawned. ACTOR_PARAM_CONFIG(BlockAppear, 28, 1); ///< Whether the Koopa should spawn from a block. ACTOR_PARAM_CONFIG(SpitOut, 29, 1); ///< Whether this Koopa was spat out by Yoshi. diff --git a/include/game/bases/d_cc.hpp b/include/game/bases/d_cc.hpp index 849d30d4..002e9ef7 100644 --- a/include/game/bases/d_cc.hpp +++ b/include/game/bases/d_cc.hpp @@ -84,6 +84,11 @@ struct sCcDatNew { ///< @brief The size of the collider. ///< Note: This is the distance from the center to the edge, so half the actual size. mVec2_POD_c mSize; + + void set(const sCcDatNew &other) { + mOffset = other.mOffset; + mSize = other.mSize; + } }; /** @@ -107,6 +112,16 @@ struct sCcDatNewF { u16 mStatus; ///< Status flags for this collider. See CC_STATUS_FLAG_e. void (*mCallback)(dCc_c *self, dCc_c *target); ///< The callback to execute when a collision occurs. + + void set(const sCcDatNewF &other) { + mBase.set(other.mBase); + mKind = other.mKind; + mAttack = other.mAttack; + mVsKind = other.mVsKind; + mVsDamage = other.mVsDamage; + mStatus = other.mStatus; + mCallback = other.mCallback; + } }; /** diff --git a/source/d_enemiesNP/bases/d_a_en_noko.cpp b/source/d_enemiesNP/bases/d_a_en_noko.cpp index c15ab2ed..c0c45ae8 100644 --- a/source/d_enemiesNP/bases/d_a_en_noko.cpp +++ b/source/d_enemiesNP/bases/d_a_en_noko.cpp @@ -51,11 +51,11 @@ int daEnNoko_c::create() { u8 dir = getPl_LRflag(mPos); mDirection = dir; - mAmiLayer = ACTOR_PARAM(Layer); + mAmiLayer = ACTOR_PARAM(SubLayer); mAngle.y = l_turn_target_angle[dir]; mCreatePos = mPos; mFlags |= dEn_c::EN_FLAG_16; - mPos.z = l_Ami_Zpos[ACTOR_PARAM(Layer)]; + mPos.z = l_Ami_Zpos[ACTOR_PARAM(SubLayer)]; mNokoAnimTex.setPlayMode(m3d::FORWARD_ONCE, 0); mNokoModel.setAnm(mNokoAnimTex, 0.0f); @@ -66,14 +66,7 @@ int daEnNoko_c::create() { mSensorWall = l_noko_wall; mSensorFootNormal = l_noko_foot; - mCcData.mBase.mOffset = l_noko_cc.mBase.mOffset; - mCcData.mBase.mSize = l_noko_cc.mBase.mSize; - mCcData.mKind = l_noko_cc.mKind; - mCcData.mAttack = l_noko_cc.mAttack; - mCcData.mVsKind = l_noko_cc.mVsKind; - mCcData.mVsDamage = l_noko_cc.mVsDamage; - mCcData.mStatus = l_noko_cc.mStatus; - mCcData.mCallback = l_noko_cc.mCallback; + mCcData.set(l_noko_cc); mCc.set(this, &mCcData, l_Ami_Line[mAmiLayer]); mCc.entry(); @@ -111,7 +104,7 @@ void daEnNoko_c::createModel() { void daEnNoko_c::setInitialState() { mDirection = getPl_LRflag(mPos); - if (ACTOR_PARAM(SpawnMode) == 1) { + if (ACTOR_PARAM(SpawnMode) == SPAWN_MODE_SLEEP) { mSpeed.y = 0.0f; changeState(daEnShell_c::StateID_Sleep); } else if (ACTOR_PARAM(BlockAppear)) { @@ -130,11 +123,11 @@ int daEnNoko_c::preExecute() { if (canDance()) { if (dAudio::isBgmAccentSign(BIT_FLAG(1))) { - danceWithMove(0); + danceWithMove(BGM_anim_walkA_1); } else if (dAudio::isBgmAccentSign(BIT_FLAG(2))) { - danceWithMove(1); + danceWithMove(BGM_anim_walkA_2); } else if (dAudio::isBgmAccentSign(BIT_FLAG(3))) { - danceWithMove(2); + danceWithMove(BGM_anim_walkA_3); } } @@ -232,7 +225,7 @@ void daEnNoko_c::calcMdl() { calcShellMdl(); mVec3_c pos = getPos(); mAng3_c angle = mAngle; - dActor_c::changePosAngle(&pos, &angle, 1); + changePosAngle(&pos, &angle, 1); mMatrix.trans(pos); mMatrix.ZXYrotM(angle); @@ -249,7 +242,6 @@ void daEnNoko_c::calcShellEffectPos() { nw4r::g3d::ResNode resNode = resMdl.GetResNode("nokonoko_shell_model"); mMtx_c matrix; - model.getNodeWorldMtx(resNode.GetID(), &matrix); matrix.multVecZero(mSlideEffectPos); if (mIsFlipped) { @@ -270,8 +262,8 @@ bool daEnNoko_c::setPlayerDamage(dActor_c *actor) { bool daEnNoko_c::playerDamageTurn(dActor_c *actor) { u8 dir = dActor_c::getTrgToSrcDir_Main(actor->getCenterX(), getCenterX()); - u8 mode = mShellMode; + if (mDirection == dir || mode == SHELL_MODE_BASE) { return false; } @@ -320,7 +312,7 @@ void daEnNoko_c::doTurn(int *dir, s16 *turnSpeed) { } void daEnNoko_c::setZPos() { - if (mLayer == 0) { + if (mLayer == LAYER_1) { mPos.z = mBaseZPos + l_Ami_Zpos[mAmiLayer]; } else { mPos.z = -2500.0f; @@ -388,7 +380,7 @@ bool daEnNoko_c::createIceActor() { } bool daEnNoko_c::checkSleep() { - if (ACTOR_PARAM(SpawnMode) == 1) { + if (ACTOR_PARAM(SpawnMode) == SPAWN_MODE_SLEEP) { return false; } @@ -590,7 +582,6 @@ void daEnNoko_c::executeState_Turn() { } WaterCheck(mPos, 1.0f); - if (turnProc()) { changeState(StateID_Walk); } @@ -658,7 +649,7 @@ void daEnNoko_c::executeState_SpitOut_Ready() { } void daEnNoko_c::initializeState_BgmDance() { - static const char *sc_bgmDanceAnim[3] = { + static const char *sc_bgmDanceAnim[DANCE_MOVE_COUNT] = { "BGM_anim_walkA_1", "BGM_anim_walkA_1", "BGM_anim_walkA_3", diff --git a/source/dol/bases/d_cc.cpp b/source/dol/bases/d_cc.cpp index ad6f777e..16a334f1 100644 --- a/source/dol/bases/d_cc.cpp +++ b/source/dol/bases/d_cc.cpp @@ -90,14 +90,7 @@ void dCc_c::release() { void dCc_c::set(dActor_c *actor, sCcDatNewF *collInfo) { mpOwner = actor; - mCcData.mBase.mOffset = collInfo->mBase.mOffset; - mCcData.mBase.mSize = collInfo->mBase.mSize; - mCcData.mKind = collInfo->mKind; - mCcData.mAttack = collInfo->mAttack; - mCcData.mVsKind = collInfo->mVsKind; - mCcData.mVsDamage = collInfo->mVsDamage; - mCcData.mStatus = collInfo->mStatus; - mCcData.mCallback = collInfo->mCallback; + mCcData.set(*collInfo); mInfo = 0; }