diff --git a/config/SOUE01/rels/d_a_npc_honeycombNP/symbols.txt b/config/SOUE01/rels/d_a_npc_honeycombNP/symbols.txt index ff5cd0e0..1e64667e 100644 --- a/config/SOUE01/rels/d_a_npc_honeycombNP/symbols.txt +++ b/config/SOUE01/rels/d_a_npc_honeycombNP/symbols.txt @@ -2,31 +2,61 @@ _prolog = .text:0x00000000; // type:function size:0x2C scope:global _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global dAcNpcHc_c_classInit__Fv = .text:0x00000070; // type:function size:0xC0 -fn_15_130 = .text:0x00000130; // type:function size:0x90 -fn_15_1C0 = .text:0x000001C0; // type:function size:0x68 -AcNpcHc__init = .text:0x00000230; // type:function size:0x15C -fn_15_390 = .text:0x00000390; // type:function size:0x8 -AcNpcHc__handleCollider = .text:0x000003A0; // type:function size:0x21C -fn_15_5C0 = .text:0x000005C0; // type:function size:0x4C -fn_15_610 = .text:0x00000610; // type:function size:0x1C -AcNpcHc__update = .text:0x00000630; // type:function size:0x838 -AcNpcHc__draw = .text:0x00000E70; // type:function size:0x34 -fn_15_EB0 = .text:0x00000EB0; // type:function size:0x8 -fn_15_EC0 = .text:0x00000EC0; // type:function size:0x4 -fn_15_ED0 = .text:0x00000ED0; // type:function size:0x4 -fn_15_EE0 = .text:0x00000EE0; // type:function size:0x8 +__dt__15dCcD_Linked_SphFv = .text:0x00000130; // type:function size:0x90 +createHeap__10dAcNpcHc_cFv = .text:0x000001C0; // type:function size:0x68 +create__10dAcNpcHc_cFv = .text:0x00000230; // type:function size:0x15C +doDelete__10dAcNpcHc_cFv = .text:0x00000390; // type:function size:0x8 +handleCollider__10dAcNpcHc_cFv = .text:0x000003A0; // type:function size:0x21C +ChkTgHit__8cCcD_ObjFv = .text:0x000005C0; // type:function size:0x4C +calcTimer__4sLibFPUc_Uc = .text:0x00000610; // type:function size:0x1C +actorExecute__10dAcNpcHc_cFv = .text:0x00000630; // type:function size:0x838 +draw__10dAcNpcHc_cFv = .text:0x00000E70; // type:function size:0x34 +vt_0x88__11dAcEnBase_cFi = .text:0x00000EB0; // type:function size:0x8 +vt_0x84__11dAcEnBase_cFv = .text:0x00000EC0; // type:function size:0x4 +vt_0x80__11dAcEnBase_cFv = .text:0x00000ED0; // type:function size:0x4 +getObjectListEntry__11dAcEnBase_cFv = .text:0x00000EE0; // type:function size:0x8 __dt__10dAcNpcHc_cFv = .text:0x00000EF0; // type:function size:0xD8 -fn_15_FD0 = .text:0x00000FD0; // type:function size:0x8 +@272@__dt__15dCcD_Linked_SphFv = .text:0x00000FD0; // type:function size:0x8 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global -lbl_15_rodata_0 = .rodata:0x00000000; // type:object size:0x7C data:float +lbl_15_rodata_0 = .rodata:0x00000000; // type:object size:0x4 data:float +lbl_15_rodata_4 = .rodata:0x00000004; // type:object size:0x4 data:float +lbl_15_rodata_8 = .rodata:0x00000008; // type:object size:0x4 data:float +lbl_15_rodata_c = .rodata:0x0000000C; // type:object size:0x4 data:float +lbl_15_rodata_10 = .rodata:0x00000010; // type:object size:0x4 data:float +lbl_15_rodata_14 = .rodata:0x00000014; // type:object size:0x4 data:float +lbl_15_rodata_18 = .rodata:0x00000018; // type:object size:0x4 data:float +lbl_15_rodata_1c = .rodata:0x0000001C; // type:object size:0x4 data:float +lbl_15_rodata_20 = .rodata:0x00000020; // type:object size:0x4 data:float +lbl_15_rodata_24 = .rodata:0x00000024; // type:object size:0x4 data:float +lbl_15_rodata_28 = .rodata:0x00000028; // type:object size:0x4 data:float +lbl_15_rodata_2c = .rodata:0x0000002C; // type:object size:0x4 data:float +lbl_15_rodata_30 = .rodata:0x00000030; // type:object size:0x4 data:float +lbl_15_rodata_34 = .rodata:0x00000034; // type:object size:0x4 data:float +lbl_15_rodata_38 = .rodata:0x00000038; // type:object size:0x4 data:float +lbl_15_rodata_3c = .rodata:0x0000003C; // type:object size:0x4 data:float +lbl_15_rodata_40 = .rodata:0x00000040; // type:object size:0x4 data:float +lbl_15_rodata_44 = .rodata:0x00000044; // type:object size:0x4 data:float +lbl_15_rodata_48 = .rodata:0x00000048; // type:object size:0x4 data:float +lbl_15_rodata_4c = .rodata:0x0000004C; // type:object size:0x4 data:float +lbl_15_rodata_50 = .rodata:0x00000050; // type:object size:0x4 data:float +lbl_15_rodata_54 = .rodata:0x00000054; // type:object size:0x4 data:float +lbl_15_rodata_58 = .rodata:0x00000058; // type:object size:0x4 data:float +lbl_15_rodata_5c = .rodata:0x0000005C; // type:object size:0x4 data:float +lbl_15_rodata_60 = .rodata:0x00000060; // type:object size:0x4 data:float +lbl_15_rodata_64 = .rodata:0x00000064; // type:object size:0x4 data:float +lbl_15_rodata_68 = .rodata:0x00000068; // type:object size:0x4 data:float +lbl_15_rodata_6c = .rodata:0x0000006C; // type:object size:0x4 data:float +lbl_15_rodata_70 = .rodata:0x00000070; // type:object size:0x4 data:float +lbl_15_rodata_74 = .rodata:0x00000074; // type:object size:0x4 data:float +lbl_15_rodata_78 = .rodata:0x00000078; // type:object size:0x4 data:float g_profile_NPC_HONEYCOMB = .data:0x00000000; // type:object size:0x10 -lbl_15_data_10 = .data:0x00000010; // type:object size:0x2C +srcSph = .data:0x00000010; // type:object size:0x2C lbl_15_data_3C = .data:0x0000003C; // type:object size:0x4 data:string lbl_15_data_40 = .data:0x00000040; // type:object size:0x5 data:string lbl_15_data_48 = .data:0x00000048; // type:object size:0x18 data:string lbl_15_data_60 = .data:0x00000060; // type:object size:0xC data:4byte -AcNpcHc__vtable = .data:0x0000006C; // type:object size:0x8C -lbl_15_data_F8 = .data:0x000000F8; // type:object size:0x70 +__vt__10dAcNpcHc_c = .data:0x0000006C; // type:object size:0x8C +__vt__15dCcD_Linked_Sph = .data:0x000000F8; // type:object size:0x70 lbl_15_bss_8 = .bss:0x00000008; // type:object size:0x1 data:byte lbl_15_bss_C = .bss:0x0000000C; // type:object size:0xC align:4 data:float diff --git a/include/d/a/npc/d_a_npc_honeycomb.h b/include/d/a/npc/d_a_npc_honeycomb.h index f04640a2..507d6936 100644 --- a/include/d/a/npc/d_a_npc_honeycomb.h +++ b/include/d/a/npc/d_a_npc_honeycomb.h @@ -1,20 +1,62 @@ #ifndef D_A_NPC_HONEYCOMB_H #define D_A_NPC_HONEYCOMB_H +#include "common.h" #include "d/a/e/d_a_en_base.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/d_cc.h" +#include "m/m3d/m_smdl.h" #include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" class dAcNpcHc_c : public dAcEnBase_c { public: - dAcNpcHc_c() {} + dAcNpcHc_c() : mRes(nullptr) {} virtual ~dAcNpcHc_c() {} + virtual bool createHeap() override; + virtual int create() override; + virtual int actorExecute() override; + virtual int draw() override; + virtual int doDelete() override; - // private: - /* 0x378 */ u8 field_0x378[0x915 - 0x378]; - /* 0x915 */ u8 field_0x915; - /* 0x916 */ u8 field_0x916; - /* 0x917 */ u8 field_0x917[0x928 - 0x917]; - /* 0x928 */ mVec3_c field_0x928; + u8 getBeeAngerTimer() const { + return mBeeAngerTimer; + } + + bool isPlayerObstructed() const { + return mPlayerObstructed; + } + + const mVec3_c &getActualPosition() const { + return mActualPosition; + } + +private: + /* 0x374 */ nw4r::g3d::ResFile mRes; + /* 0x378 */ m3d::smdl_c mModel; + /* 0x398 */ dBgS_AcchCir mAcchCir; + /* 0x3F4 */ dBgS_ObjAcch mObjAcch; + /* 0x7A4 */ dCcD_Linked_Sph mSph; + /* 0x904 */ dColliderLinkedList mCollider; + /* 0x910 */ u8 mNoCollisionTimer; + /* 0x911 */ bool mIsBlown; + /* 0x912 */ u8 mFallDownTimer; + /* 0x913 */ u8 mDeathTimer; + /* 0x914 */ u8 mGustBellowsTimer; + /* 0x915 */ u8 mBeeAngerTimer; + /* 0x916 */ bool mPlayerObstructed; + /* 0x917 */ u8 mSceneflag; + /* 0x918 */ s8 field_0x918; + /* 0x919 */ // padding + /* 0x91A */ s16 mUnusedTimer1; + /* 0x91C */ s16 mUnusedTimer2; + /* 0x91E */ s16 mRandomnessTimer; + /* 0x920 */ f32 field_0x920; + /* 0x924 */ f32 field_0x924; + /* 0x928 */ mVec3_c mActualPosition; + /* 0x934 */ mVec3_c field_0x934; + + void handleCollider(); }; #endif 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 23a93b27..8cdf38d2 100644 --- a/src/REL/d/a/npc/d_a_npc_bee.cpp +++ b/src/REL/d/a/npc/d_a_npc_bee.cpp @@ -108,7 +108,7 @@ int dAcNpcBee_c::doDelete() { // non matching void dAcNpcBee_c::actuallyUpdateSwarmBees() { if (mHiveRef.isLinked()) { - setStartingPosition(mHiveRef.get()->field_0x928); + setStartingPosition(mHiveRef.get()->getActualPosition()); } dAcPy_c *player = dAcPy_c::GetLinkM(); if ((mFrameCounter & 0xF) == 0) { @@ -276,11 +276,11 @@ void dAcNpcBee_c::handleBeeCrawlingOnHive(dAcNpcBeeSingleBee *bee) { (mAttackActor->getPosition().y - getPosition().y) < 0.f && bee->mSubState != CRAWLING_SUBSTATE_PRE_RISE) { // using getSpeed inline breaks the match f32 aggroDistance = mAttackActor->mSpeed * 20.f + 350.f; - if (hive->field_0x915 >= 5 || hive->mHealth == 1 || - (hive->field_0x916 == 0 && mAttackActorDistFromHome < aggroDistance)) { + if (hive->getBeeAngerTimer() >= 5 || hive->mHealth == 1 || + (!hive->isPlayerObstructed() && mAttackActorDistFromHome < aggroDistance)) { bee->mSubState = CRAWLING_SUBSTATE_PRE_RISE; bee->mActionTimer = cM::rndF(15.f); - } else if (bee->mSubState != CRAWLING_SUBSTATE_FLY && hive->field_0x915 != 0) { + } else if (bee->mSubState != CRAWLING_SUBSTATE_FLY && hive->getBeeAngerTimer() != 0) { bee->mActionTimer = cM::rndF(70.f) + 30.f; bee->mSubState = CRAWLING_SUBSTATE_FLY; } @@ -530,8 +530,12 @@ void dAcNpcBee_c::handleBeeFlyingStates(dAcNpcBeeSingleBee *bee) { } else { s32 fVar17 = nw4r::math::SinIdx(bee->mTimer * 3500) * 1500.f; s32 fVar16 = nw4r::math::SinIdx(bee->mTimer * 3000) * 1500.f; - sLib::addCalcAngle(bee->mCrawlingRotation.y.ref(), fVar17 + cM::atan2s(offsetToTarget.x, offsetToTarget.z), 1, 0x1000); - sLib::addCalcAngle(bee->mCrawlingRotation.x.ref(), fVar16 - cM::atan2s(offsetToTarget.y, offsetToTarget.absXZ()), 1, 0x1000); + sLib::addCalcAngle( + bee->mCrawlingRotation.y.ref(), fVar17 + cM::atan2s(offsetToTarget.x, offsetToTarget.z), 1, 0x1000 + ); + sLib::addCalcAngle( + bee->mCrawlingRotation.x.ref(), fVar16 - cM::atan2s(offsetToTarget.y, offsetToTarget.absXZ()), 1, 0x1000 + ); } } mtx.YrotS(bee->mCrawlingRotation.y); diff --git a/src/REL/d/a/npc/d_a_npc_honeycomb.cpp b/src/REL/d/a/npc/d_a_npc_honeycomb.cpp index 2ac3be3f..10531b8b 100644 --- a/src/REL/d/a/npc/d_a_npc_honeycomb.cpp +++ b/src/REL/d/a/npc/d_a_npc_honeycomb.cpp @@ -1,3 +1,286 @@ #include "d/a/npc/d_a_npc_honeycomb.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_itembase.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_boomerang.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/c/c_cc_d.h" +#include "d/d_light_env.h" +#include "d/d_linkage.h" +#include "d/flag/sceneflag_manager.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "m/m_allocator.h" +#include "m/m_angle.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/math/math_triangular.h" +#include "s/s_Math.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/d_emitter.h" + SPECIAL_ACTOR_PROFILE(NPC_HONEYCOMB, dAcNpcHc_c, fProfile::NPC_HONEYCOMB, 0x124, 0, 2); + +static dCcD_SrcSph srcSph = { + /* mObjInf */ + {/* mObjAt */ {}, + /* mObjTg */ + {~(AT_TYPE_BUGNET | AT_TYPE_0x2000000 | AT_TYPE_0x8000 | AT_TYPE_WIND | AT_TYPE_BEETLE | + AT_TYPE_GLITTERING_SPORES), + 0x103, + {0, 0, 0x40F}, + 0, + 0}, + /* mObjCo */ {0x89}}, + /* mSphInf */ + {40.0f} +}; + +bool dAcNpcHc_c::createHeap() { + mRes = nw4r::g3d::ResFile(getOarcResFile("Bee")); + return mModel.create(mRes.GetResMdl("home"), &mAllocator, 0x20, 1, nullptr); +} + +int dAcNpcHc_c::create() { + mSceneflag = getFromParams(0x10, 0xFF); + CREATE_ALLOCATOR(dAcNpcHc_c); + mObjAcch.Set(this, 1, &mAcchCir); + mAcchCir.SetWall(35.f, 35.f); + mCollider.addCc(mSph, srcSph); + mStts.SetRank(8); + mCollider.SetStts(mStts); + mAcceleration = -5.f; + mMaxSpeed = -50.f; + mBoundingBox.Set(mVec3_c(-200.f, -200.f, -200.f), mVec3_c(200.f, 200.f, 200.f)); + mRandomnessTimer = cM::rndF(65536.f); + field_0x934 = mPosition; + mHealth = 10000; + field_0x918 = 1; + mLinkage.set(0x80, 0.0f, 30.f, 70.f, nullptr); + return SUCCEEDED; +} + +int dAcNpcHc_c::doDelete() { + return SUCCEEDED; +} + +void dAcNpcHc_c::handleCollider() { + if (sLib::calcTimer(&mNoCollisionTimer) == 0 && someEnemyDamageCollisionStuffMaybe(mCollider, nullptr)) { + mNoCollisionTimer = 5; + cCcD_Obj *found = mCollider.find(&cCcD_Obj::ChkTgHit); + if (found != nullptr) { + mVec3_c local_58; + if (found->ChkTgAtHitType(AT_TYPE_0x40) && dAcPy_c::hasBeetleVariantOrBetter(dAcBoomerang_c::HOOK_BEETLE)) { + return; + } + if (found->ChkTgAtHitType(AT_TYPE_BUBBLE)) { + field_0x918 = 1; + } else if (found->ChkTgSkywardStrike()) { + mDeathTimer = 10; + mHealth = 0; + return; + } + if (found->ChkTgAtHitType(AT_TYPE_BELLOWS)) { + mIsBlown = true; + local_58.x = 0.f; + local_58.y = 0.f; + local_58.z = -5.f; + mBeeAngerTimer = 10; + mNoCollisionTimer = 0; + mGustBellowsTimer += 2; + if (mGustBellowsTimer >= 60) { + mFallDownTimer = 1; + mNoCollisionTimer = 200; + } + } else { + mBeeAngerTimer = 10; + mIsBlown = false; + local_58.x = 0.f; + local_58.y = 0.f; + local_58.z = -100.f; + field_0x918--; + // since the field is only ever set to 1, this will always succeed + if (field_0x918 <= 0) { + mFallDownTimer = 0xf; + mNoCollisionTimer = 200; + } + } + mMtx_c mtx; + mtx.YrotS(found->GetTgAtHitDir().atan2sX_Z()); + mtx.multVec(local_58, local_58); + field_0x920 += local_58.x; + field_0x924 += local_58.z; + } + } +} + +extern "C" bool fn_80030390(f32, dAcObjBase_c *); +extern "C" void spawnDrop(u16, s32, void *, void *); + +// non matching +int dAcNpcHc_c::actorExecute() { + if (mDeathTimer != 0) { + if (--mDeathTimer == 0) { + killWithFlag(); + if (mSceneflag != 0xFF && SceneflagManager::sInstance) { + SceneflagManager::sInstance->setFlag(getRoomId(), mSceneflag); + } + } + return SUCCEEDED; + } + mRandomnessTimer++; + dAcPy_c *player = dAcPy_c::GetLinkM(); + if (mUnusedTimer1 != 0) { + mUnusedTimer1--; + } + if (mUnusedTimer2 != 0) { + mUnusedTimer2--; + } + if (mGustBellowsTimer != 0) { + mGustBellowsTimer--; + } + if (player->checkFlags0x350(0x2000) && getSquareDistanceTo(player->mPosition) < 160000.f && + getHeightDifference(*player) < 800.f) { + mBeeAngerTimer = 10; + mIsBlown = false; + mVec3_c local_11c(0.f, 0.f, -100.f); + mFallDownTimer = 0xf; + mNoCollisionTimer = 200; + mMtx_c mtx; + mtx.YrotS(player->mRotation.y); + mtx.multVec(local_11c, local_11c); + field_0x920 += local_11c.x; + field_0x924 += local_11c.z; + } else if (dLightEnv_c::GetPInstance()->check_BPM8(&mPosition, nullptr)) { + mBeeAngerTimer = 5; + } else if ((mRandomnessTimer & 0xF) == 0) { + // check if there is something in the way between the hive and the player + mPlayerObstructed = fn_80030390(0.f, this); + } + if (mBeeAngerTimer != 0) { + mBeeAngerTimer--; + } + if (mLinkage.checkConnection(dLinkage_c::CONNECTION_5)) { + setStartingPosition(mPosition); + field_0x934 = mPosition; + mFallDownTimer = 1; + dAcObjBase_c *beetle = player->getBeetleInFlight(); + if (beetle != nullptr) { + mRotation.y = beetle->mRotation.y; + f32 fVar11 = nw4r::math::SinIdx((s16)(mRandomnessTimer * 2048)); + s32 speed = beetle->mSpeed; + s32 temp = fVar11 * 1000.f; + // regalloc + s16 temp2 = speed * 0x96 + temp; + sLib::addCalcAngle(mRotation.x.ref(), temp2 + beetle->mRotation.x, 8, 0x400); + sLib::addCalcAngle(mRotation.z.ref(), (beetle->mRotation.z * 2) / 3, 8, 0x400); + } + mWorldMtx.transS(mPosition); + mWorldMtx.YrotM(mRotation.y); + mWorldMtx.XrotM(mRotation.x); + mWorldMtx.ZrotM(mRotation.z); + mWorldMtx.transM(0.f, -80.f, 0.f); + mMtx_c mtx; + mtx.YrotS(mRotation.y); + mtx.multVec(mVec3_c(0.f, -0.5f, 30.f), mVelocity); + mPosition.y -= 130.f; + mObjAcch.CrrPos(*dBgS::GetInstance()); + mPosition.y += 130.f; + if (mObjAcch.ChkGndHit()) { + mDeathTimer = 10; + mHealth = 1; + } + } else { + if (mFallDownTimer != 0) { + if (mFallDownTimer >= 2) { + mFallDownTimer--; + } else { + mPosition += mVelocity; + mVelocity.y -= 5.f; + mPosition.y -= 130.f; + mObjAcch.CrrPos(*dBgS::GetInstance()); + mPosition.y += 130.f; + if (mObjAcch.ChkGndHit()) { + mDeathTimer = 10; + mHealth = 1; + } + } + } else { + handleCollider(); + } + sLib::addCalcAngle(mRotation.x.ref(), mAngle.x, 0x20, 0x80); + sLib::addCalcAngle(mAngle.x.ref(), 0, 0x2, 0x800); + f32 fVar11 = field_0x934.x - mStartingPos.x; + f32 fVar1 = field_0x934.z - mStartingPos.z; + f32 twoHundred = 200.f; + if (mIsBlown == true) { + field_0x920 = (field_0x920 - fVar11 * 0.02f) * 0.9f; + field_0x924 = (field_0x924 - fVar1 * 0.02f) * 0.9f; + } else { + field_0x920 = (field_0x920 - fVar11 * 0.1f) * 0.9f; + field_0x924 = (field_0x924 - fVar1 * 0.1f) * 0.9f; + } + field_0x934.x += field_0x920; + field_0x934.z += field_0x924; + s16 sVar8 = -cM::atan2s(twoHundred, fVar1); + // f32 fVar12; + // // f32 fVar2 = twoHundred * twoHundred + fVar1 * fVar1; + // if (twoHundred * twoHundred + fVar1 * fVar1 <= 0.f) { + // fVar12 = (twoHundred * twoHundred + fVar1 * fVar1); + // } else { + // fVar12 = (twoHundred * twoHundred + fVar1 * fVar1) * nw4r::math::FrSqrt(twoHundred * twoHundred + fVar1 * + // fVar1); + // } + // wtf + s16 sVar9 = cM::atan2s( + fVar11, (twoHundred * twoHundred + fVar1 * fVar1 <= 0.f ? + twoHundred * twoHundred + fVar1 * fVar1 : + (twoHundred * twoHundred + fVar1 * fVar1) * + nw4r::math::FrSqrt(twoHundred * twoHundred + fVar1 * fVar1)) + ); + mWorldMtx.transS(mPosition); + mWorldMtx.XrotM(sVar8); + mWorldMtx.YrotM(sVar9); + mWorldMtx.XrotM(0x4000); + mWorldMtx.transM(0.f, -90.f, 0.f); + } + mModel.setLocalMtx(mWorldMtx); + mWorldMtx.multVec(mVec3_c(0.f, 1.f, 0.f), mActualPosition); + mSph.SetC(mActualPosition); + mSph.SetR(50.f); + if (mLinkage.checkConnection(dLinkage_c::CONNECTION_5)) { + mNoCollisionTimer = 5; + } else { + mCollider.registerColliders(); + } + mPositionCopy3 = mActualPosition; + mPositionCopy2 = mActualPosition; + AttentionManager::sInstance->addUnk3Target(*this, 1, 500.f, -400.f, 400.f); + if (mDeathTimer != 0) { + startSound(SE_HnComb_BREAK); + static mVec3_c temp(1.f, 1.f, 1.f); + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_249_, mActualPosition, nullptr, &temp, nullptr, nullptr, nullptr, nullptr + ); + dEmitterBase_c *eff = dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_477_, mActualPosition, nullptr, &temp, nullptr, nullptr, nullptr, nullptr + ); + if (eff != nullptr) { + eff->bindShpEmitter(6, true); + } + mAng3_c ang(0.f, 0.f, 0.f); + spawnDrop(ITEM_HORNET_LARVAE, -1, &mActualPosition, &ang); + } + return SUCCEEDED; +} + +int dAcNpcHc_c::draw() { + if (mDeathTimer == 0) { + drawModelType1(&mModel); + } + return SUCCEEDED; +}