diff options
| author | lepelog <25211966+lepelog@users.noreply.github.com> | 2026-05-01 10:56:52 +0200 |
|---|---|---|
| committer | lepelog <25211966+lepelog@users.noreply.github.com> | 2026-06-28 13:10:36 +0200 |
| commit | 040df8c5c0df189d113cdc1dab2ffa24921028e8 (patch) | |
| tree | 43f512e909fe27f49fa3efcaece80ce2705f7701 | |
| parent | e6c69576b45e355c3218cd8c183bf14392c7b591 (diff) | |
wip
| -rw-r--r-- | include/d/a/d_a_base.h | 2 | ||||
| -rw-r--r-- | include/d/a/npc/d_a_npc_bee.h | 68 | ||||
| -rw-r--r-- | include/toBeSorted/d_unk_mdl_stuff_2.h | 5 | ||||
| -rw-r--r-- | src/REL/d/a/npc/d_a_npc_bee.cpp | 136 |
4 files changed, 209 insertions, 2 deletions
diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index f063e4e2..b405f69d 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -72,7 +72,7 @@ public: enum AcProperties_e { AC_PROP_0x1 = (1 << 0), AC_PROP_0x2 = (1 << 1), - AC_PROP_0x4 = (1 << 2), + AC_PROP_0x4 = (1 << 2), // when set, also update in event AC_PROP_0x100 = (1 << 8), AC_PROP_0x400 = (1 << 10), AC_PROP_0x800 = (1 << 11), diff --git a/include/d/a/npc/d_a_npc_bee.h b/include/d/a/npc/d_a_npc_bee.h index 855e6c25..6d161ac1 100644 --- a/include/d/a/npc/d_a_npc_bee.h +++ b/include/d/a/npc/d_a_npc_bee.h @@ -1,14 +1,80 @@ #ifndef D_A_NPC_BEE_H #define D_A_NPC_BEE_H +#include "common.h" +#include "d/a/d_a_base.h" #include "d/a/e/d_a_en_base.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_cc.h" +#include "m/m3d/m_proc.h" +#include "m/m_angle.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" + +class dAcNpcBeeSingleBee { +public: + enum State { + BEE_STATE_DEAD = 0, + BEE_STATE_CHASE = 1, + BEE_STATE_FLY_UP = 2, + BEE_STATE_FLY_UP2 = 3, + BEE_STATE_UNK4 = 4, + BEE_STATE_RISE = 5, + BEE_STATE_CRAWL = 0xA, + }; + /* 0x000 */ u8 mIndex; + /* 0x001 */ u8 mBeeState; // see State enum + /* 0x002 */ u8 field_0x002; + /* 0x003 */ u8 field_0x003; + /* 0x004 */ u8 field_0x004; + /* 0x005 */ u8 field_0x005; + /* 0x006 */ u8 field_0x006; + /* 0x007 */ u8 field_0x007; + /* 0x008 */ u8 field_0x008; + /* 0x009 */ u8 field_0x009[0xc-9]; + /* 0x00C */ s16 mRotY; + /* 0x00E */ s16 field_0x00E; + /* 0x010 */ u8 field_0x010[0x18-0x10]; + /* 0x018 */ mVec3_c mPos; + /* 0x024 */ u8 field_0x024[0x3C-0x24]; + /* 0x03C */ mVec3_c field_0x03C; + /* 0x048 */ mVec3_c field_0x048; + /* 0x054 */ mVec3_c field_0x054; + /* 0x060 */ mAng3_c field_0x060; + /* 0x066 */ u8 field_0x066[0x6C-0x66]; + /* 0x06C */ dCcD_Linked_Sph mCollider; +}; + class dAcNpcBee_c : public dAcEnBase_c { public: - dAcNpcBee_c() {} + dAcNpcBee_c(): mRes(nullptr) {} virtual ~dAcNpcBee_c() {} + virtual bool createHeap() override; + virtual int create() override; + virtual int execute() override; + void updateSwarmBeeColliders(); + void actuallyUpdateSwarmBees(); + void fn_14_1F40(dAcNpcBeeSingleBee* bee); + u32 fn_14_2690(dAcNpcBeeSingleBee* bee); private: + /* 0x0378 */ u8 mSwarmBeeCount; + /* 0x0379 */ u8 field_0x0379; // rumble timer + /* 0x037A */ u8 mSceneflag; + /* 0x037B */ u8 field_0x037B; + /* 0x037C */ s16 field_0x037C; + /* 0x037E */ u8 field_0x037E[0x388-0x37E]; + /* 0x0388 */ nw4r::g3d::ResFile mRes; + /* 0x038C */ dShpProc1_c mBeeModels[4]; + /* 0x045C */ dAcNpcBeeSingleBee mBees[100]; + /* 0xB80C */ dAcRef_c<dAcObjBase_c> mHiveRef; + /* 0xB818 */ dAcRef_c<dAcObjBase_c> mAttackRef; + /* 0xB824 */ dColliderLinkedList mColliderList; + /* 0xB830 */ mVec3_c field_0xB830; + /* 0xB834 */ dAcObjBase_c* mAttackActor; + /* 0xB838 */ u8 field_0xB838[0xB844-0xB838]; }; #endif diff --git a/include/toBeSorted/d_unk_mdl_stuff_2.h b/include/toBeSorted/d_unk_mdl_stuff_2.h index c46ab28e..0820b17e 100644 --- a/include/toBeSorted/d_unk_mdl_stuff_2.h +++ b/include/toBeSorted/d_unk_mdl_stuff_2.h @@ -6,7 +6,9 @@ #include "m/m_allocator.h" #include "m/m_mtx.h" #include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" #include "nw4r/g3d/res/g3d_resshp.h" /** a process for drawing shapes directly */ @@ -59,6 +61,9 @@ public: } bool create(nw4r::g3d::ResMat mat, nw4r::g3d::ResShp shp, s32 count, mHeapAllocator_c *alloc, bool xlu, u32 *pSize); + bool create(s32 count, nw4r::g3d::ResMdl mdl, mHeapAllocator_c *alloc, bool xlu, u32 *pSize) { + return create(mdl.GetResMat(0), mdl.GetResShp(0), count, alloc, xlu, pSize); + } void draw(); void setTransform(s32 idx, const mMtx_c &transform) { diff --git a/src/REL/d/a/npc/d_a_npc_bee.cpp b/src/REL/d/a/npc/d_a_npc_bee.cpp index 3b859974..d80c8603 100644 --- a/src/REL/d/a/npc/d_a_npc_bee.cpp +++ b/src/REL/d/a/npc/d_a_npc_bee.cpp @@ -1,3 +1,139 @@ #include "d/a/npc/d_a_npc_bee.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/bg/d_bg_s_gnd_chk.h" +#include "d/col/cc/d_cc_d.h" +#include "d/d_rumble.h" +#include "d/flag/sceneflag_manager.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "s/s_Math.h" SPECIAL_ACTOR_PROFILE(NPC_BEE, dAcNpcBee_c, fProfile::NPC_BEE, 0x123, 0, 0); + +bool dAcNpcBee_c::createHeap() { + mRes = nw4r::g3d::ResFile(getOarcResFile("Bee")); + static const char* sModelNames[4] = { + "fly_A", + "fly_B", + "walk_A", + "walk_B", + }; + mSwarmBeeCount = 0x14; + for (int i = 0; i < (int)ARRAY_LENGTH(sModelNames); i++) { + // instruction reordering + TRY_CREATE(mBeeModels[i].create(mSwarmBeeCount, mRes.GetResMdl(sModelNames[i]), &mAllocator, true, nullptr)); + } + return SUCCEEDED; +} + +static dCcD_SrcSph sph; + +int dAcNpcBee_c::create() { + mSceneflag = getFromParams(0x10, 0xFF); + // mRoom regalloc + if (mSceneflag != 0xFF && SceneflagManager::sInstance && SceneflagManager::sInstance->checkFlag(mRoomID, mSceneflag)) { + return FAILED; + } + CREATE_ALLOCATOR(dAcNpcBee_c); + dAcNpcBeeSingleBee* bee = &mBees[0]; + for (int i = 0; i < mSwarmBeeCount; i++, bee++) { + bee->mIndex = i; + bee->mBeeState = dAcNpcBeeSingleBee::BEE_STATE_CRAWL; + bee->mPos = mPosition; + bee->mRotY = cM::rndF(65536); + mColliderList.addCc(bee->mCollider, sph); + bee->mCollider.mTg.OffSPrm(0x100); + bee->mCollider.mAt.OnSPrm(0x100); + if (i < mSwarmBeeCount / 2) { + bee->field_0x008 = 1; + } + } + // probably inline here + mStts.SetRank(3); + mInteractionFlags |= 0x80; + mColliderList.SetStts(mStts); + field_0x037C = cM::rndF(65536); + dAcObjBase_c* honeycomb = dAcObjBase_c::create(fProfile::NPC_HONEYCOMB, -1, mParams, &mPosition, nullptr, nullptr, -1); + if (honeycomb == nullptr) { + return FAILED; + } else { + mHiveRef.link(honeycomb); + mAttackRef.link(dAcPy_c::GetLinkM()); + } + return SUCCEEDED; +} + +int dAcNpcBee_c::execute() { + field_0x037C++; + updateSwarmBeeColliders(); + actuallyUpdateSwarmBees(); + if (field_0x0379) { + field_0x0379--; + if (field_0x0379 == 7) { + dRumble_c::start(dRumble_c::sRumblePreset1, 1); + } else if (field_0x0379 == 5) { + dRumble_c::stop(-1); + } + } + return SUCCEEDED; +} + +void dAcNpcBee_c::fn_14_1F40(dAcNpcBeeSingleBee* bee) { + bee->field_0x003 = 1; + switch (bee->field_0x005) { + case 0: { + bee->field_0x054 = mStartingPos + (bee->mPos - mStartingPos) * (cM::rndF(0.5f) + 1.5f); + bee->field_0x002 = 0x14; + bee->field_0x005 = 1; + // fallthrough + } + case 1: { + cLib::addCalcPos2(&bee->mPos, bee->field_0x054, 0.2f, 15.0f); + sLib::addCalcAngle(bee->field_0x060.y.ref(), cLib::targetAngleY(bee->mPos, mAttackActor->mPositionCopy2), 2, 0x800); + sLib::addCalcAngle(bee->field_0x060.x.ref(), 0, 2, 0x800); + sLib::addCalcAngle(bee->field_0x060.z.ref(), 0, 2, 0x800); + if (bee->field_0x002 == 0) { + bee->mBeeState = dAcNpcBeeSingleBee::BEE_STATE_CHASE; + bee->field_0x005 = 0; + bee->field_0x00E = cM::rndF(155.f) + 300.f; + } + } + } +} + +u32 fn_14_2690(dAcNpcBeeSingleBee* bee) { + dBgS_ObjGndChk gndChk; + dBgS_ObjLinChk linChk; + u32 ret = 0; + mVec3_c local_148_2 = bee->mPos - bee->field_0x03C; + mVec3_c local_148 = local_148_2; + local_148.y = 0.f; + local_148.normalize(); + mVec3_c scaled = local_148 * 50.f; + mVec3_c another = bee->mPos + scaled; + linChk.Set(&bee->mPos, &another, nullptr); + if (dBgS::GetInstance()->LineCross(&linChk)) { + ret = 2; + bee->mPos.x = linChk.GetLinEnd().x - scaled.x; + bee->mPos.z = linChk.GetLinEnd().z - scaled.z; + } + mVec3_c local_149 = bee->mPos; + local_149.z += 100.f; + gndChk.SetPos(&local_149); + if (bee->mPos.y <= dBgS::GetInstance()->GroundCross(&gndChk) + 15.f) { + // imagine using temp variables... + bee->mPos.y = dBgS::GetInstance()->GroundCross(&gndChk) + 15.f; + ret |= 1; + } + return ret; +} |
