d_a_npc_honeycomb 98%

This commit is contained in:
lepelog
2026-07-01 23:17:50 +02:00
parent 3a93d428e8
commit 7793e2adfa
4 changed files with 390 additions and 31 deletions
@@ -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<Uc>__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
+49 -7
View File
@@ -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
+10 -6
View File
@@ -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);
+283
View File
@@ -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;
}