summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/REL/d/a/npc/d_a_npc_bee.cpp317
1 files changed, 305 insertions, 12 deletions
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 d80c8603..b1b657f6 100644
--- a/src/REL/d/a/npc/d_a_npc_bee.cpp
+++ b/src/REL/d/a/npc/d_a_npc_bee.cpp
@@ -3,20 +3,33 @@
#include "c/c_math.h"
#include "common.h"
#include "d/a/d_a_player.h"
+#include "d/a/e/d_a_e_bc.h"
+#include "d/a/npc/d_a_npc_honeycomb.h"
#include "d/a/obj/d_a_obj_base.h"
+#include "d/a/obj/d_a_obj_spore.h"
#include "d/col/bg/d_bg_s.h"
#include "d/col/bg/d_bg_s_gnd_chk.h"
+#include "d/col/bg/d_bg_s_lin_chk.h"
#include "d/col/cc/d_cc_d.h"
+#include "d/d_camera.h"
+#include "d/d_player_act.h"
#include "d/d_rumble.h"
+#include "d/d_sc_game.h"
#include "d/flag/sceneflag_manager.h"
+#include "d/snd/d_snd_wzsound.h"
#include "f/f_base.h"
+#include "f/f_manager.h"
#include "f/f_profile_name.h"
+#include "m/m_angle.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"
+#include "nw4r/math/math_triangular.h"
#include "s/s_Math.h"
+#include <cmath>
SPECIAL_ACTOR_PROFILE(NPC_BEE, dAcNpcBee_c, fProfile::NPC_BEE, 0x123, 0, 0);
@@ -67,25 +80,259 @@ int dAcNpcBee_c::create() {
if (honeycomb == nullptr) {
return FAILED;
} else {
- mHiveRef.link(honeycomb);
+ mHiveRef.link(static_cast<dAcNpcHc_c*>(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);
+void dAcNpcBee_c::actuallyUpdateSwarmBees() {
+ if (mHiveRef.isLinked()) {
+ setStartingPosition(mHiveRef.get()->field_0x928);
+ }
+ dAcPy_c *player = dAcPy_c::GetLink2();
+ if ((field_0x037C & 0xF) == 0) {
+ mAttackRef.link(player);
+ bool bVar3 = true;
+ fLiNdBa_c *current = dAcOSpore_c::getListHead();
+ if (current != nullptr) {
+ for (;current != nullptr;current = current->getNext()) {
+ dAcOSpore_c* spore = static_cast<dAcOSpore_c*>(current->p_owner);
+ if (spore != nullptr && (s32)(spore->mParams & 0xF) == 1) {
+ mVec3_c& sporePos = spore->mPosition;
+ if (spore->mPosition.squareDistanceToXZ(field_0xB830) < 1000000.f &&
+ std::fabsf(spore->mPosition.y - field_0xB830.y) < 500.f) {
+ if (!dBgS_ObjLinChk::LineCross(&field_0xB830, &sporePos, this)) {
+ mAttackRef.link(spore);
+ bVar3 = false;
+ field_0xB840 = spore;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bVar3) {
+ dAcEbc_c *boko = nullptr;
+ while((boko = static_cast<dAcEbc_c*>(fManager_c::searchBaseByProfName(fProfile::E_BC, boko)))) {
+ if (boko->getField_0x130D()) continue;
+ f32 distToPlayer = field_0xB830.distance(dAcPy_c::GetLink()->mPositionCopy2);
+ f32 distToBoko = field_0xB830.distance(boko->mPositionCopy2);
+ if (distToBoko < distToPlayer) {
+ mAttackRef.link(boko);
+ break;
+ }
+ }
}
}
- return SUCCEEDED;
+ mAttackActor = mAttackRef.get();
+ if (mAttackActor == nullptr) {
+ mAttackActor = player;
+ }
+ dAcNpcBeeSingleBee* bee = &mBees[0];
+ u8 beesAlive = 0;
+ int uVar13 = 0;
+ static mVec3_c someVec(10000.f, -20000.f, 50000.f);
+ dCamera_c* camera = dScGame_c::getCamera();
+ bool bVar3 = true;
+ int iVar12 = 0;
+ int iVar17 = 0;
+ field_0x0380 = mStartingPos.distance(mAttackActor->mPositionCopy2);
+ mPosition = mStartingPos;
+ for (int i = 0; i < mSwarmBeeCount; i++, bee++) {
+ bool bVar9 = true;
+ mMtx_c mtx;
+ if (bee->mBeeState != dAcNpcBeeSingleBee::BEE_STATE_DEAD) {
+ beesAlive++;
+ bee->field_0x03C = bee->mPos;
+ if (bee->field_0x002) {
+ bee->field_0x002--;
+ }
+ if(bee->field_0x006) {
+ bee->field_0x006--;
+ }
+ if (bee->mBeeState == dAcNpcBeeSingleBee::BEE_STATE_CRAWL) {
+ handleBeeCrawlingOnHive(bee);
+ bee->field_0x006 = 5;
+ } else {
+ bee->mRotY++;
+ if (bee->mBeeState <= dAcNpcBeeSingleBee::BEE_STATE_FLY_UP2) {
+ fn_14_1350(bee);
+ iVar12++;
+ if (bVar3) {
+ bVar3 = false;
+ mPosition = bee->mPos;
+ }
+ } else if (bee->mBeeState == dAcNpcBeeSingleBee::BEE_STATE_UNK4) {
+ fn_14_20F0(bee);
+ } else if (bee->mBeeState == dAcNpcBeeSingleBee::BEE_STATE_RISE) {
+ fn_14_1F40(bee);
+ }
+ }
+ if (bee->field_0x008 == 0) {
+ mVec3_c localA4 = bee->mPos - camera->getPosition();
+ if (localA4.absXZ() < 3000.f) {
+ localA4.normalize();
+ mVec3_c localB0 = camera->getTarget() - camera->getPosition();
+ localB0.normalize();
+ if (localB0.dot(localA4) > 0.5f) {
+ if (bee->field_0x003) {
+ if (bee->mRotY & 1) {
+ uVar13 = 0;
+ } else {
+ uVar13 = 1;
+ }
+ } else {
+ s32 tmp = -(bee->mRotY >> 2 & 1);
+ tmp += 3;
+ uVar13 = tmp;
+ }
+ if (bee->mBeeState == dAcNpcBeeSingleBee::BEE_STATE_CRAWL) {
+ mtx.transS(bee->mPos);
+ mtx.ZrotM(bee->field_0x060.x);
+ mtx.XrotM(bee->field_0x060.z);
+ mtx.YrotM(bee->field_0x060.y);
+ mtx.XrotM(0x8000);
+ } else {
+ mtx.transS(bee->mPos);
+ mtx.YrotM(bee->field_0x066.y);
+ mtx.XrotM(bee->field_0x066.x);
+ mtx.ZrotM(bee->field_0x066.z);
+ }
+ bVar9 = false;
+ }
+ }
+ }
+ field_0xB830 = bee->mPos;
+ }
+
+ for (u32 uVar8 = 0, iVar18 = 4; iVar18 != 0; uVar8++, iVar18--) {
+ if (!bVar9 && (uVar8 & 0xFF) == (uVar13 & 0xFF)) {
+ mBeeModels[uVar8 & 0xFF].setDrawDisabled(i, false);
+ mBeeModels[uVar8 & 0xFF].setTransform(i, mtx);
+ } else {
+ mBeeModels[uVar8 & 0xFF].setDrawDisabled(i, true);
+ }
+ }
+ if (!bVar9 && bee->field_0x006 == 0) {
+ bee->mCollider.SetC(bee->mPos);
+ } else {
+ bee->mCollider.SetC(someVec);
+ }
+ }
+ if (iVar12 != 0) {
+ holdSoundWithIntParam(SE_Bee_FLY_LV, iVar12);
+ }
+ mColliderList.registerColliders();
+ if (!beesAlive) {
+ deleteRequest();
+ }
+}
+
+void dAcNpcBee_c::handleBeeCrawlingOnHive(dAcNpcBeeSingleBee* bee) {
+ f32 fVar7 = 0.0f;
+ dAcNpcHc_c* hive = mHiveRef.get();
+ if (hive == nullptr || hive->mHealth == 0) {
+ bee->mBeeState = dAcNpcBeeSingleBee::BEE_STATE_DEAD;
+ } else {
+ if (bee->field_0x008) {
+ if (hive->mHealth == 1) {
+ bee->field_0x008 = 0;
+ bee->field_0x024.x = cM::rndFX(300.f);
+ bee->field_0x024.z = cM::rndFX(300.f);
+ } else {
+ bee->mPos = mStartingPos;
+ return;
+ }
+ }
+ if (dAcPy_c::GetLink()->getRidingActorType() != daPlayerActBase_c::RIDING_LOFTWING && (mAttackActor->getPosition().y - getPosition().y) < 0.f && bee->field_0x005 != 4) {
+ f32 compSpeed = mAttackActor->getSpeed() * 20.f + 350.f;
+ if (hive->field_0x915 >= 5 || hive->mHealth == 1 || (hive->field_0x916 == 0 && field_0x0380 < compSpeed)) {
+ bee->field_0x005 = 4;
+ bee->field_0x002 = cM::rndF(15.f);
+ } else if (bee->field_0x005 != 2 && hive->field_0x915 != 0) {
+ bee->field_0x002 = cM::rndF(70.f) + 30.f;
+ bee->field_0x005 = 2;
+ }
+ }
+ mVec3_c local_74;
+ mVec3_c local_80 = bee->field_0x054 - bee->field_0x024;
+ bee->field_0x003 = 0;
+ local_74 = local_80;
+ if (bee->field_0x005 == 0) {
+ bee->field_0x010 = 0.f;
+ if (bee->field_0x002 == 0) {
+ if (cM::rnd() < 0.02f) {
+ bee->field_0x002 = cM::rndF(70.f) + 30.f;
+ bee->field_0x005 = 2;
+ } else {
+ bee->field_0x002 = cM::rndF(30.f) + 5.f;
+ bee->field_0x054.x = cM::rndFX(300.f);
+ bee->field_0x054.z = cM::rndFX(300.f);
+ bee->field_0x005 = 1;
+ }
+ }
+ } else if (bee->field_0x005 == 1) {
+ bee->mRotY++;
+ sLib::addCalcAngle(bee->field_0x060.y.ref(), local_74.atan2sX_Z(), 2, 0x400);
+ if (bee->field_0x002 == 0 || local_74.absXZ() < 10.f) {
+ bee->field_0x005 = 0;
+ bee->field_0x002 = cM::rndF(15.f) + 2.f;
+ }
+ fVar7 = 2.f;
+ } else if (bee->field_0x005 == 2) {
+ bee->field_0x003 = 1;
+ sLib::addCalcScaledDiff(&bee->field_0x010, 50.f, 0.1f, 5.f);
+ sLib::addCalcAngle(bee->field_0x060.y.ref(), local_74.atan2sX_Z(), 2, 0x800);
+ if ((bee->field_0x002 & 0x7) == 0) {
+ bee->field_0x054.x = cM::rndFX(300.f);
+ bee->field_0x054.z = cM::rndFX(300.f);
+ }
+ if (bee->field_0x002 == 0) {
+ bee->field_0x005 = 3;
+ }
+ fVar7 = 5.f;
+ } else if (bee->field_0x005 == 3) {
+ bee->field_0x003 = 1;
+ sLib::addCalcScaled(&bee->field_0x010, 1.f, 5.f);
+ if (bee->field_0x010 <= 0.1f) {
+ bee->field_0x005 = 0;
+ }
+ } else if (bee->field_0x005 == 4 && bee->field_0x002 == 0) {
+ bee->mBeeState = dAcNpcBeeSingleBee::BEE_STATE_RISE;
+ bee->field_0x005 = 0;
+ }
+ sLib::addCalcScaledDiff(&bee->field_0x014, fVar7, 0.5f, 0.5f);
+ mMtx_c mtx;
+ mtx.YrotS(bee->field_0x060.y);
+ local_74.set(0.f, 0.f, bee->field_0x014);
+ mtx.multVec(local_74, bee->field_0x048);
+ bee->field_0x024 += bee->field_0x048;
+ s16 xRot = -bee->field_0x024.x * 32768.f / 200.f;
+ s16 zRot = bee->field_0x024.z * 32768.f / 200.f;
+ local_74.y = bee->field_0x010;
+ local_74.x = 0.f;
+ local_74.z = 0.f;
+ local_74.y = -68.f - local_74.y;
+ mtx.scaleS(1.f, 1.15f, 1.f);
+ mtx.YrotM(hive->mRotation.y);
+ mtx.ZrotM(xRot);
+ mtx.XrotM(zRot);
+ mtx.multVec(local_74, bee->mPos);
+ bee->mPos += mStartingPos;
+ if (bee->field_0x003 == 0) {
+ sLib::addCalcAngle(bee->field_0x060.x.ref(), xRot, 2, 0x800);
+ sLib::addCalcAngle(bee->field_0x060.z.ref(), zRot, 2, 0x800);
+ } else {
+ bee->mRotY++;
+ sLib::addCalcAngle(bee->field_0x060.x.ref(), 0, 1, 0x1000);
+ sLib::addCalcAngle(bee->field_0x060.z.ref(), -0x8000, 1, 0x1000);
+ }
+ }
+}
+
+void dAcNpcBee_c::fn_14_1350(dAcNpcBeeSingleBee* bee) {
+
}
void dAcNpcBee_c::fn_14_1F40(dAcNpcBeeSingleBee* bee) {
@@ -111,6 +358,52 @@ void dAcNpcBee_c::fn_14_1F40(dAcNpcBeeSingleBee* bee) {
}
}
+void dAcNpcBee_c::fn_14_20F0(dAcNpcBeeSingleBee* bee) {
+ bee->mPos += bee->field_0x048;
+ bee->mPos.x += nw4r::math::SinIdx(bee->mRotY * 0x900) * 10.f;
+ bee->mPos.y += nw4r::math::SinIdx(bee->mRotY * 0xa00) * 10.f;
+ bee->mPos.z += nw4r::math::SinIdx(bee->mRotY * 0xb00) * 10.f;
+ if ((bee->mIndex & 1) != 0) {
+ bee->field_0x066.y += 0xD00;
+ } else {
+ bee->field_0x066.y -= 0xD00;
+ }
+ bee->field_0x066.x += 0xA00;
+ if (bee->field_0x002 == 0) {
+ bee->mBeeState = dAcNpcBeeSingleBee::BEE_STATE_CHASE;
+ bee->field_0x005 = 0;
+ bee->field_0x00E = cM::rndF(155.f) + 300.f;
+ }
+ fn_14_2690(bee);
+}
+
+int dAcNpcBee_c::actorExecute() {
+ 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::updateSwarmBeeColliders() {
+
+}
+
+int dAcNpcBee_c::draw() {
+ dShpProc1_c* model = &mBeeModels[0];
+ for (int i = 0; i < 4; i++, model++) {
+ model->entry();
+ }
+ return 1;
+}
+
u32 fn_14_2690(dAcNpcBeeSingleBee* bee) {
dBgS_ObjGndChk gndChk;
dBgS_ObjLinChk linChk;