summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlepelog <25211966+lepelog@users.noreply.github.com>2025-12-04 13:42:58 +0100
committerlepelog <25211966+lepelog@users.noreply.github.com>2025-12-04 13:50:58 +0100
commit413cfaa41f0811e209d16dea6a9aa79df757679d (patch)
tree1fa2369fc0cb166a8b87c3173be7012257e19b07
parent08844fb5da445344613971b66e7fdc9ff55290ac (diff)
insect tag progress
-rw-r--r--config/SOUE01/rels/d_t_insectNP/symbols.txt22
-rw-r--r--config/SOUE01/symbols.txt2
-rw-r--r--configure.py2
-rw-r--r--include/d/a/d_a_base.h8
-rw-r--r--include/d/a/d_a_insect_butterfly.h11
-rw-r--r--include/d/a/obj/d_a_obj_soil.h7
-rw-r--r--include/d/a/obj/d_a_obj_warp.h48
-rw-r--r--include/d/flag/storyflag_map.h8
-rw-r--r--include/d/t/d_t_insect.h95
-rw-r--r--include/nw4r/math/math_geometry.h1
-rw-r--r--src/REL/d/t/d_t_insect.cpp424
11 files changed, 517 insertions, 111 deletions
diff --git a/config/SOUE01/rels/d_t_insectNP/symbols.txt b/config/SOUE01/rels/d_t_insectNP/symbols.txt
index b6342198..3cde2287 100644
--- a/config/SOUE01/rels/d_t_insectNP/symbols.txt
+++ b/config/SOUE01/rels/d_t_insectNP/symbols.txt
@@ -4,15 +4,15 @@ _unresolved = .text:0x00000060; // type:function size:0x4 scope:global
__register_global_object = .text:0x00000070; // type:function size:0x1C scope:global
__destroy_global_chain = .text:0x00000090; // type:function size:0x54 scope:global
dTgInsect_c_classInit__Fv = .text:0x000000F0; // type:function size:0xE0
-__dt__11dTgInsect_cFv = .text:0x000001D0; // type:function size:0x58
+__dt__20dTgInsectSupertype_cFv = .text:0x000001D0; // type:function size:0x58
__dt__24sFState_c<11dTgInsect_c>Fv = .text:0x00000230; // type:function size:0x58
__dt__27sFStateFct_c<11dTgInsect_c>Fv = .text:0x00000290; // type:function size:0x6C
__dt__80sStateMgr_c<11dTgInsect_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000300; // type:function size:0xA0
__dt__50sFStateMgr_c<11dTgInsect_c,20sStateMethodUsr_FI_c>Fv = .text:0x000003A0; // type:function size:0xA4
-fn_450_450 = .text:0x00000450; // type:function size:0x14
-fn_450_470 = .text:0x00000470; // type:function size:0x58
-fn_450_4D0 = .text:0x000004D0; // type:function size:0x140
-TgInsect__init2 = .text:0x00000610; // type:function size:0x5B8
+__ct__20dAcRef_c<9dAcBase_c>Fv = .text:0x00000450; // type:function size:0x14
+__dt__20dAcRef_c<9dAcBase_c>Fv = .text:0x00000470; // type:function size:0x58
+actorCreate__11dTgInsect_cFv = .text:0x000004D0; // type:function size:0x140
+actorPostCreate__11dTgInsect_cFv = .text:0x00000610; // type:function size:0x5B8
changeState__80sStateMgr_c<11dTgInsect_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000BD0; // type:function size:0x10
fn_450_BE0 = .text:0x00000BE0; // type:function size:0x8
fn_450_BF0 = .text:0x00000BF0; // type:function size:0x30
@@ -30,11 +30,11 @@ finalizeState_WaitForceEscape__11dTgInsect_cFv = .text:0x000012A0; // type:funct
initializeState_End__11dTgInsect_cFv = .text:0x000012B0; // type:function size:0x4
executeState_End__11dTgInsect_cFv = .text:0x000012C0; // type:function size:0x4
finalizeState_End__11dTgInsect_cFv = .text:0x000012D0; // type:function size:0x4
-fn_450_12E0 = .text:0x000012E0; // type:function size:0x64
-fn_450_1350 = .text:0x00001350; // type:function size:0x530
-fn_450_1880 = .text:0x00001880; // type:function size:0x140
-fn_450_19C0 = .text:0x000019C0; // type:function size:0x1E0
-fn_450_1BA0 = .text:0x00001BA0; // type:function size:0xF0
+spawnAll__11dTgInsect_cFv = .text:0x000012E0; // type:function size:0x64
+spawnInsect__11dTgInsect_cFl = .text:0x00001350; // type:function size:0x530
+shouldSpawn__11dTgInsect_cFv = .text:0x00001880; // type:function size:0x140
+someGroundCheck__11dTgInsect_cFRC7mVec3_cl = .text:0x000019C0; // type:function size:0x1E0
+__dt__11dTgInsect_cFv = .text:0x00001BA0; // type:function size:0xF0
getStateID__80sStateMgr_c<11dTgInsect_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00001C90; // type:function size:0x10
build__27sFStateFct_c<11dTgInsect_c>FRC12sStateIDIf_c = .text:0x00001CA0; // type:function size:0x60
dispose__27sFStateFct_c<11dTgInsect_c>FRP10sStateIf_c = .text:0x00001D00; // type:function size:0xC
@@ -68,7 +68,7 @@ lbl_450_rodata_70 = .rodata:0x00000070; // type:object size:0x8 align:4 data:flo
g_profile_TAG_INSECT = .data:0x00000000; // type:object size:0x10 data:4byte
jumptable_450_data_10 = .data:0x00000010; // type:object size:0x2C scope:local
jumptable_450_data_3C = .data:0x0000003C; // type:object size:0x2C scope:local
-lbl_450_data_68 = .data:0x00000068; // type:object size:0x78
+__vt__11dTgInsect_c = .data:0x00000068; // type:object size:0x78
lbl_450_data_E0 = .data:0x000000E0; // type:object size:0x30
lbl_450_data_110 = .data:0x00000110; // type:object size:0x30
lbl_450_data_140 = .data:0x00000140; // type:object size:0x18
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index 808d7997..2ad47c47 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -17270,7 +17270,7 @@ cLib__chasePos = .text:0x802E03D0; // type:function size:0x174
chasePosXZ__4cLibFR7mVec3_cR7mVec3_cf = .text:0x802E0550; // type:function size:0x124
targetAngleY__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E0680; // type:function size:0x1C
targetAngleX__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E06A0; // type:function size:0x68
-cLib__offsetPos = .text:0x802E0710; // type:function size:0xD8
+offsetPos__4cLibFR7mVec3_cRC7mVec3_csRC7mVec3_c = .text:0x802E0710; // type:function size:0xD8
easeIn__4cLibFff = .text:0x802E07F0; // type:function size:0x24
easeOut__4cLibFff = .text:0x802E0820; // type:function size:0x34
easeInOut__4cLibFff = .text:0x802E0860; // type:function size:0x60
diff --git a/configure.py b/configure.py
index 0833cb75..cca0a7dc 100644
--- a/configure.py
+++ b/configure.py
@@ -2903,7 +2903,7 @@ config.libs = [
Rel(NonMatching, "d_t_harp", "REL/d/t/d_t_harp.cpp"),
Rel(Matching, "d_t_heat_resist", "REL/d/t/d_t_heat_resist.cpp"),
Rel(Matching, "d_t_holy_water", "REL/d/t/d_t_holy_water.cpp"),
- Rel(NonMatching, "d_t_insect", "REL/d/t/d_t_insect.cpp"),
+ Rel(NonMatching, "d_t_insect", "REL/d/t/d_t_insect.cpp", extra_cflags=["-opt nostrength"]),
Rel(NonMatching, "d_t_ks", "REL/d/t/d_t_ks.cpp"),
Rel(NonMatching, "d_t_kytag", "REL/d/t/d_t_kytag.cpp"),
Rel(NonMatching, "d_t_lb_thunder", "REL/d/t/d_t_lb_thunder.cpp"),
diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h
index c24f8ed7..6df2237e 100644
--- a/include/d/a/d_a_base.h
+++ b/include/d/a/d_a_base.h
@@ -4,6 +4,7 @@
#include "common.h"
#include "d/d_base.h"
#include "d/snd/d_snd_source_if.h"
+#include "f/f_profile_name.h"
#include "m/m_allocator.h"
#include "m/m_angle.h"
#include "m/m_vec.h"
@@ -180,6 +181,9 @@ public:
bool checkBeyondRadius(const mVec3_c &point, f32 radius) {
return getSquareDistanceTo(point) > radius;
}
+ bool checkInRadius(const mVec3_c &point, f32 radius) {
+ return getSquareDistanceTo(point) < radius;
+ }
u32 getRoomId() {
return mRoomID;
@@ -195,6 +199,10 @@ public:
return mActorProperties & property;
}
+ dAcBase_c* searchNextActor(dAcBase_c* parent) {
+ return static_cast<dAcBase_c*>(fManager_c::searchBaseByGroupType(dAcBase_c::ACTOR, parent));
+ }
+
public:
static void setTempCreateParams(
mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, s32 roomId, u32 params2, dAcBase_c *parent, u8 subtype, u16 unkFlag,
diff --git a/include/d/a/d_a_insect_butterfly.h b/include/d/a/d_a_insect_butterfly.h
index 84c32694..91688269 100644
--- a/include/d/a/d_a_insect_butterfly.h
+++ b/include/d/a/d_a_insect_butterfly.h
@@ -4,8 +4,9 @@
#include "d/a/obj/d_a_obj_base.h"
#include "s/s_State.hpp"
#include "s/s_StateMgr.hpp"
+#include "d/a/d_a_insect.h"
-class dAcInsectButterfly_c : public dAcObjBase_c {
+class dAcInsectButterfly_c : public dAcOInsect_c {
public:
dAcInsectButterfly_c() : mStateMgr(*this, sStateID::null) {}
virtual ~dAcInsectButterfly_c() {}
@@ -16,8 +17,14 @@ public:
STATE_FUNC_DECLARE(dAcInsectButterfly_c, Finalize);
STATE_FUNC_DECLARE(dAcInsectButterfly_c, Dead);
+ void setKillSignal() {
+ killSignal = 1;
+ }
private:
- /* 0x??? */ STATE_MGR_DECLARE(dAcInsectButterfly_c);
+ /* 0x468 */ u8 field_0x468[0xA34-0x468];
+ /* 0xA34 */ STATE_MGR_DECLARE(dAcInsectButterfly_c);
+ /* 0xA70 */ u8 field_0xA70[0xAC6-0xA70];
+ /* 0xAC6 */ u8 killSignal;
};
#endif
diff --git a/include/d/a/obj/d_a_obj_soil.h b/include/d/a/obj/d_a_obj_soil.h
index c4e24b31..64f1f0f9 100644
--- a/include/d/a/obj/d_a_obj_soil.h
+++ b/include/d/a/obj/d_a_obj_soil.h
@@ -14,8 +14,13 @@ public:
STATE_FUNC_DECLARE(dAcOsoil_c, Hole);
STATE_FUNC_DECLARE(dAcOsoil_c, Ready);
+ bool isStateHole() {
+ return mStateMgr.isState(StateID_Hole);
+ }
+
private:
- /* 0x??? */ STATE_MGR_DECLARE(dAcOsoil_c);
+ /* 0x330 */ u8 field_0x330[0x6CC-0x330];
+ /* 0x6CC */ STATE_MGR_DECLARE(dAcOsoil_c);
};
#endif
diff --git a/include/d/a/obj/d_a_obj_warp.h b/include/d/a/obj/d_a_obj_warp.h
index 1c64e61c..0b2f4874 100644
--- a/include/d/a/obj/d_a_obj_warp.h
+++ b/include/d/a/obj/d_a_obj_warp.h
@@ -2,6 +2,7 @@
#define D_A_OBJ_WARP_H
#include "d/a/obj/d_a_obj_base.h"
+#include "d/flag/storyflag_manager.h"
#include "s/s_State.hpp"
#include "s/s_StateMgr.hpp"
@@ -18,7 +19,54 @@ public:
STATE_FUNC_DECLARE(dAcOWarp_c, GateIn);
STATE_FUNC_DECLARE(dAcOWarp_c, GateClear);
+ virtual void fn_0x80();
+ virtual void fn_0x84();
+ virtual void fn_0x88();
+ virtual s32 checkStateGateOpen();
+ virtual s32 fn_0x90();
+ virtual s32 checkThisHasSongItem();
+
+ bool isFaronTrial() const {
+ return mTrialIndexBitmask & 0x10;
+ }
+
+ bool isEldinTrial() const {
+ return mTrialIndexBitmask & 0x40;
+ }
+
+ bool isLanayruTrial() const {
+ return mTrialIndexBitmask & 0x20;
+ }
+
+ bool isHyliaTrial() const {
+ return mTrialIndexBitmask & 0x80;
+ }
+
+ bool isFaronTrialAndCompleted() const {
+ return isFaronTrial() && StoryflagManager::sInstance->getFlag(STORYFLAG_FARON_TRIAL_COMPLETE);
+ }
+
+ bool isEdlinTrialAndCompleted() const {
+ return isEldinTrial() && StoryflagManager::sInstance->getFlag(STORYFLAG_ELDIN_TRIAL_COMPLETE);
+ }
+
+ bool isLanayruTrialAndCompleted() const {
+ return isLanayruTrial() && StoryflagManager::sInstance->getFlag(STORYFLAG_LANAYRU_TRIAL_COMPLETE);
+ }
+
+ bool isHyliaTrialAndCompleted() const {
+ return isHyliaTrial() && StoryflagManager::sInstance->getFlag(STORYFLAG_HYLIA_TRIAL_COMPLETE);
+ }
+
+ bool isTrialComplete() const {
+ return isFaronTrialAndCompleted()
+ || isEdlinTrialAndCompleted()
+ || isLanayruTrialAndCompleted()
+ || isHyliaTrialAndCompleted();
+ }
private:
+ /* 0x330 */ u8 field_0x330[0xC66-0x330];
+ /* 0xC66 */ u8 mTrialIndexBitmask;
/* 0x??? */ STATE_MGR_DECLARE(dAcOWarp_c);
};
diff --git a/include/d/flag/storyflag_map.h b/include/d/flag/storyflag_map.h
index 86271424..940380fd 100644
--- a/include/d/flag/storyflag_map.h
+++ b/include/d/flag/storyflag_map.h
@@ -1050,22 +1050,22 @@ enum StoryFlags_e {
* layer 3 / Skyview Boss Room layer 3 / Lake Floria layer 1 / Water Dragon's Lair layer 1)] Story Flag #206
* (0x00CE) - JP 805ACD70 0x04 / US 805A9AF0 0x04
*/
- STORYFLAG_206,
+ STORYFLAG_FARON_TRIAL_COMPLETE,
/** [Eldin Trial Completed (removes fi trigger in front of Volcano Summit)]
* Story Flag #207 (0x00CF) - JP 805ACD70 0x08 / US 805A9AF0 0x08
*/
- STORYFLAG_207,
+ STORYFLAG_ELDIN_TRIAL_COMPLETE,
/** [Lanayru Trial Completed (Lanayru Caves layer 1)]
* Story Flag #208 (0x00D0) - JP 805ACD70 0x10 / US 805A9AF0 0x10
*/
- STORYFLAG_208,
+ STORYFLAG_LANAYRU_TRIAL_COMPLETE,
/** [Hylia's Trial Completed (Triggers Fi Text after Skyloft Trial)]
* Story Flag #209 (0x00D1) - JP 805ACD70 0x20 / US 805A9AF0 0x20
*/
- STORYFLAG_209,
+ STORYFLAG_HYLIA_TRIAL_COMPLETE,
/** [Obtain Stone of Trials]
* Story Flag #210 (0x00D2) - JP 805ACD70 0x40 / US 805A9AF0 0x40
diff --git a/include/d/t/d_t_insect.h b/include/d/t/d_t_insect.h
index cd3b4e0b..ef17d2e6 100644
--- a/include/d/t/d_t_insect.h
+++ b/include/d/t/d_t_insect.h
@@ -6,9 +6,34 @@
#include "s/s_State.hpp"
#include "s/s_StateMgr.hpp"
-class dTgInsect_c : public dAcBase_c {
+class dTgInsectSupertype_c : public dAcBase_c {};
+
+extern "C" bool fn_801BB750(nw4r::math::AABB *aabb, f32 f);
+
+class dTgInsect_c : public dTgInsectSupertype_c {
public:
- dTgInsect_c() : mStateMgr(*this, sStateID::null), unk26C(0), unk270(0), unk274(0) {}
+ enum Subtype {
+ SUBTYPE_VOLCANIC_LADYBUG = 3,
+ SUBTYPE_GERUDO_DRAGONFLY,
+ SUBTYPE_WOODLAND_RHINO_BEETLE,
+ SUBTYPE_SAND_CICADA,
+ SUBTYPE_FARON_GRASSHOPPER,
+ SUBTYPE_LANAYRU_ANT,
+ SUBTYPE_SKY_STAG_BEETLE,
+ SUBTYPE_BUTTERFLY,
+ SUBTYPE_SKYLOFT_MANTIS,
+ SUBTYPE_EDLIN_ROLLER,
+ SUBTYPE_STARRY_FIREFLY,
+ };
+ enum SpawnSubtype {
+ SPAWN_SKYLOFT_BUGKID_TREE = 1,
+ SPAWN_BUG_MINIGAME,
+ SPAWN_TRIAL_GATE,
+ SPAWN_GOSSIP_STONE,
+ SPAWN_GODDESS_WALL, // doesn't seem to be used?
+ SPAWN_DEFAULT = 0xF,
+ };
+ dTgInsect_c() : mStateMgr(*this, sStateID::null) {}
virtual ~dTgInsect_c() {}
STATE_FUNC_DECLARE(dTgInsect_c, Wait);
@@ -19,7 +44,7 @@ public:
private:
/* 0x0FC */ STATE_MGR_DECLARE(dTgInsect_c);
/* 0x138 */ dAcRef_c<dAcBase_c> mLinks[16];
- /* 0x1F8 */ u8 unk1F8[0x208-0x1F8];
+ /* 0x1F8 */ u8 unk1F8[0x208 - 0x1F8];
/* 0x208 */ s32 unk208[16];
/* 0x248 */ s32 mInsectCount;
/* 0x24C */ u8 unk24C;
@@ -27,20 +52,74 @@ private:
/* 0x24E */ u8 unk24E;
/* 0x24F */ u8 unk24F;
/* 0x250 */ u8 unk250[16];
- /* 0x260 */ u8 unk260[0x26C-0x260];
- /* 0x26C */ s32 unk26C;
- /* 0x270 */ s32 unk270;
- /* 0x274 */ s32 unk274;
+ /* 0x260 */ mVec3_c unk260;
+ /* 0x26C */ dAcRef_c<dAcBase_c> unk26C;
s32 getSpawnSubtype() const {
return (mParams >> 8 & 0xF);
}
+ bool isSpawnSubtype(s32 spanwSubtype) const {
+ return getSpawnSubtype() == spanwSubtype;
+ }
s32 getSubtype() const {
return (mParams >> 4 & 0xF);
}
+ bool isSubtype(u8 subtype) const {
+ return getSubtype() == subtype;
+ }
+ s32 getInsectCount() const {
+ return (mParams & 0xF);
+ }
void spawnInsect(s32 index);
bool shouldSpawn();
- bool someGroundCheck(const mVec3_c &pos,s32 param_3);
+ void spawnAll();
+ bool someGroundCheck(const mVec3_c &pos, s32 param_3);
+ void handleForceEscape(s32 i) {
+ if (mLinks[i].isLinked()) {
+ mLinks[i].get()->mActorProperties |= AC_PROP_0x4;
+ }
+ }
+ bool isButterfly() const {
+ return isSubtype(10);
+ }
+ bool isTrialGateType() const {
+ if (getSubtype() != SUBTYPE_BUTTERFLY) {
+ return false;
+ }
+ if (getSpawnSubtype() != SPAWN_TRIAL_GATE) {
+ return false;
+ }
+ return true;
+ }
+ bool isGossipStoneType() const {
+ if (!isButterfly()) {
+ return false;
+ }
+ if (!isSpawnSubtype(SPAWN_GOSSIP_STONE)) {
+ return false;
+ }
+ return true;
+ }
+ bool isGoddessWallType() const {
+ if (!isButterfly()) {
+ return false;
+ }
+ if (!isSpawnSubtype(SPAWN_GODDESS_WALL)) {
+ return false;
+ }
+ return true;
+ }
+ f32 getOriginalScaleX() const {
+ return 100 * mScale.x;
+ }
+ f32 getOriginalScaleY() const {
+ return 100 * mScale.y;
+ }
+ inline s32 getTries() {
+ return 5;
+ }
+ int actorCreate();
+ int actorPostCreate();
};
#endif
diff --git a/include/nw4r/math/math_geometry.h b/include/nw4r/math/math_geometry.h
index 922942e8..657c95b3 100644
--- a/include/nw4r/math/math_geometry.h
+++ b/include/nw4r/math/math_geometry.h
@@ -36,6 +36,7 @@ struct AABB {
AABB() {}
AABB(const VEC3 &min, const VEC3 &max) : min(min), max(max) {}
+ AABB(f32 minX, f32 minY, f32 minZ, f32 maxX, f32 maxY, f32 maxZ) : min(minX, minY, minZ), max(maxX, maxY, maxZ) {}
void Set(const VEC3 *points, unsigned int num);
void Set(const AABB *box, const MTX34 *mtx);
diff --git a/src/REL/d/t/d_t_insect.cpp b/src/REL/d/t/d_t_insect.cpp
index 718ff57b..827af1e9 100644
--- a/src/REL/d/t/d_t_insect.cpp
+++ b/src/REL/d/t/d_t_insect.cpp
@@ -1,17 +1,30 @@
#include "d/t/d_t_insect.h"
+
#include "c/c_lib.h"
#include "c/c_math.h"
#include "common.h"
#include "d/a/d_a_base.h"
+#include "d/a/d_a_insect_butterfly.h"
#include "d/a/d_a_item.h"
#include "d/a/d_a_itembase.h"
#include "d/a/obj/d_a_obj_base.h"
+#include "d/a/obj/d_a_obj_soil.h"
+#include "d/a/obj/d_a_obj_warp.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/flag/itemflag_manager.h"
#include "d/flag/sceneflag_manager.h"
+#include "d/flag/storyflag_manager.h"
+#include "f/f_base.h"
+#include "f/f_manager.h"
#include "f/f_profile.h"
#include "f/f_profile_name.h"
+#include "m/m_angle.h"
#include "m/m_vec.h"
+#include "nw4r/math/math_geometry.h"
+#include "nw4r/math/math_types.h"
+#include "rvl/MTX/mtx.h"
SPECIAL_ACTOR_PROFILE(TAG_INSECT, dTgInsect_c, fProfile::TAG_INSECT, 0x167, 0, 0);
@@ -20,86 +33,309 @@ STATE_DEFINE(dTgInsect_c, WaitCreate);
STATE_DEFINE(dTgInsect_c, WaitForceEscape);
STATE_DEFINE(dTgInsect_c, End);
+static const s32 unused[] = {
+ 0x001E0100, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const f32 different100[] = {100};
+
+static const f32 WHATEVER[] = {100, 150, 0.5f};
+
+const s32 *useUnused() {
+ return unused;
+}
+
+// non matching
+int dTgInsect_c::actorCreate() {
+ if (getSubtype() == 0) {
+ return FAILED;
+ }
+ if (getSubtype() == 1) {
+ return FAILED;
+ }
+ if (getSubtype() == 2) {
+ return FAILED;
+ }
+ mInsectCount = getInsectCount();
+ if (mInsectCount > 0xF) {
+ mInsectCount = 0xF;
+ } else {
+ if (mInsectCount == 0xF) {
+ mInsectCount = 1;
+ }
+ }
+ mScale *= 0.01f;
+ unk24C = 0;
+ unk260 = mPosition;
+ // non matching: load of 0 in r0
+ // that is already 0
+ if (isTrialGateType() || isGossipStoneType() || isGoddessWallType() || isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
+ unk24E = 1;
+ }
+ return SUCCEEDED;
+}
+
+inline bool checkProfile(u16 prof, u32 target) {
+ return prof == target;
+}
+
+// non matching: the inline vecs from the distance checks
+// are in the wrong order on the stack
+int dTgInsect_c::actorPostCreate() {
+ s32 subtype = (mParams >> 4 & 0xF);
+ // ??? doesn't match without the double comparison
+ if (subtype == 5 || subtype == 5 || subtype == 6 || subtype == 3 || subtype == 9) {
+ if (!someGroundCheck(mPosition, 1)) {
+ return FAILED;
+ }
+ }
+ dAcBase_c *obj = nullptr;
+ do {
+ obj = searchNextActor(obj);
+ if (obj == nullptr) {
+ break;
+ }
+ u16 prof = obj->mProfileName;
+ if ((
+ checkProfile(prof, fProfile::OBJ_TUBO) || checkProfile(prof, fProfile::OBJ_CARRY_STONE) ||
+ checkProfile(prof, fProfile::OBJ_OCT_GRASS_LEAF) || checkProfile(prof, fProfile::OBJ_FRUIT) ||
+ checkProfile(prof, fProfile::OBJ_BARREL) || checkProfile(prof, fProfile::OBJ_VSD) ||
+ checkProfile(prof, fProfile::OBJ_SOIL)
+ // inline vec 1
+ ) &&
+ getSquareDistanceTo(obj->mPosition) < 25) {
+ if (subtype == 7 || subtype == 0xB || subtype == 8 || subtype == 0xC) {
+ if (prof == fProfile::OBJ_SOIL && static_cast<dAcOsoil_c *>(obj)->isStateHole()) {
+ return FAILED;
+ }
+ setActorRef(obj);
+ }
+ break;
+ }
+ } while (true);
+ if (mActorNode.isLinked()) {
+ mStateMgr.changeState(StateID_WaitCreate);
+ } else {
+ if (isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
+ for (s32 i = 0; i < 16; i++) {
+ unk1F8[i] = 0;
+ }
+ mStateMgr.changeState(StateID_Wait);
+ } else if (isTrialGateType()) {
+ dAcOWarp_c *warp = static_cast<dAcOWarp_c *>(fManager_c::searchBaseByProfName(fProfile::OBJ_WARP));
+ if (warp == nullptr) {
+ return FAILED;
+ }
+ if (!warp->checkThisHasSongItem() || warp->isTrialComplete()) {
+ return FAILED;
+ }
+ // inline vec 2
+ if ((warp->checkInRadius(mPosition, 1000000))) {
+ unk26C.link(warp);
+ } else {
+ return FAILED;
+ }
+ mStateMgr.changeState(StateID_WaitForceEscape);
+ } else if (isGossipStoneType()) {
+ if (!ItemflagManager::sInstance->getFlagDirect(ITEM_BALLAD_OF_THE_GODDESS)) {
+ return FAILED;
+ }
+ if (!StoryflagManager::sInstance->getFlag(STORYFLAG_IMPRISONED_1_DEFEATED)) {
+ return FAILED;
+ }
+ bool flag = SceneflagManager::sInstance->checkFlag(mRoomID, mParams >> 0xC & 0xFF);
+ if (flag) {
+ return FAILED;
+ }
+ } else if (isGoddessWallType()) {
+ if (!ItemflagManager::sInstance->getFlagDirect(ITEM_BALLAD_OF_THE_GODDESS)) {
+ return FAILED;
+ }
+ if (!StoryflagManager::sInstance->getFlag(STORYFLAG_FARON_TRIAL_COMPLETE)) {
+ return FAILED;
+ }
+ mStateMgr.changeState(StateID_WaitForceEscape);
+ } else {
+ mStateMgr.changeState(StateID_End);
+ }
+ spawnAll();
+ }
+ return SUCCEEDED;
+}
+
void dTgInsect_c::initializeState_Wait() {}
-void dTgInsect_c::executeState_Wait() {}
+
+void dTgInsect_c::executeState_Wait() {
+ if (isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
+ s32 i = 0;
+ for (; i < mInsectCount; i++) {
+ if (!mLinks[i].isLinked()) {
+ if (unk208[i] > 0) {
+ unk208[i]--;
+ } else if (unk208[i] == 0) {
+ nw4r::math::MTX34 mtx;
+ PSMTXTrans(mtx, mPosition.x, mPosition.y, mPosition.z);
+ nw4r::math::MTX34 scale;
+ PSMTXScale(scale, mScale.x, mScale.y, mScale.x);
+ PSMTXConcat(mtx, scale, mtx);
+ nw4r::math::AABB aabb(-100, 0, -100, 100, 100, 100);
+ aabb.Set(&aabb, &mtx);
+ if (fn_801BB750(&aabb, 10000)) {
+ spawnInsect(i);
+ }
+ } else {
+ unk208[i] = 900;
+ }
+ }
+ }
+ }
+}
void dTgInsect_c::finalizeState_Wait() {}
void dTgInsect_c::initializeState_WaitCreate() {
- if (getSpawnSubtype() != 2) {
+ if (!isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
unk24F = 1;
for (s32 i = 0; i < mInsectCount; i++) {
unk250[i] = shouldSpawn();
}
}
}
-void dTgInsect_c::executeState_WaitCreate() {}
+#pragma opt_strength_reduction on
+void dTgInsect_c::executeState_WaitCreate() {
+ if (mActorNode.isLinked()) {
+ if (mActorNode.get()->mProfileName == fProfile::OBJ_VSD ||
+ mActorNode.get()->mProfileName == fProfile::OBJ_SOIL) {
+ if (unk24C == 0) {
+ return;
+ }
+ } else {
+ if (mPosition.squareDistanceToXZ(mActorNode.get()->mPosition) < 25) {
+ return;
+ }
+ }
+ }
+ mActorNode.unlink();
+ for (s32 i = 0; i < mInsectCount; i++) {
+ if (!isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
+ if (unk250[i] != 0) {
+ unk250[i] = 0;
+ } else {
+ continue;
+ }
+ }
+ dAcBase_c *insect = nullptr;
+ mVec3_c tmp1 = mPosition;
+ if (unk24C) {
+ tmp1 = unk260;
+ }
+ mAng3_c rot(0, cM::rndFX(65536), 0);
+ switch (getSubtype()) {
+ case SUBTYPE_LANAYRU_ANT:
+ insect = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_ANT, 1, &tmp1, &rot, nullptr, 0, 0x3f);
+ break;
+ case SUBTYPE_FARON_GRASSHOPPER:
+ insect = dAcObjBase_c::createInsectActor(
+ this, fProfile::INSECT_GRASSHOPPER, 1, &tmp1, &rot, nullptr, 0, 0x3f
+ );
+ break;
+ case SUBTYPE_SKYLOFT_MANTIS:
+ insect = dAcObjBase_c::createInsectActor(
+ this, fProfile::INSECT_GRASSHOPPER, 0x10000001, &tmp1, &rot, nullptr, 0, 0x3f
+ );
+ break;
+ case SUBTYPE_EDLIN_ROLLER:
+ insect =
+ dAcObjBase_c::createInsectActor(this, fProfile::INSECT_SCARAB, 1, &tmp1, &rot, nullptr, 0, 0x3f);
+ break;
+ }
+ if (insect != nullptr) {
+ mLinks[i].link(insect);
+ unk208[i] = -1;
+ }
+ }
+ if (isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
+ mStateMgr.changeState(StateID_Wait);
+ } else {
+ mStateMgr.changeState(StateID_End);
+ }
+}
void dTgInsect_c::finalizeState_WaitCreate() {}
-void dTgInsect_c::initializeState_WaitForceEscape() {}
-void dTgInsect_c::executeState_WaitForceEscape() {}
+
+// non matching: regswap
+void dTgInsect_c::initializeState_WaitForceEscape() {
+ for (s32 i = 0; i < mInsectCount; i++) {
+ if (mLinks[i].isLinked()) {
+ mLinks[i].get()->mActorProperties |= AC_PROP_0x4;
+ }
+ }
+}
+
+void dTgInsect_c::executeState_WaitForceEscape() {
+ if (isTrialGateType()) {
+ if (unk26C.isLinked()) {
+ dAcOWarp_c *warp = static_cast<dAcOWarp_c *>(unk26C.get());
+ if (warp->fn_0x90()) {
+ for (s32 i = 0; i < mInsectCount; i++) {
+ if (mLinks[i].isLinked()) {
+ static_cast<dAcInsectButterfly_c *>(mLinks[i].get())->setKillSignal();
+ mStateMgr.changeState(StateID_End);
+ }
+ }
+ }
+ }
+ } else if (isGoddessWallType() && unk24D) {
+ for (s32 i = 0; i < mInsectCount; i++) {
+ if (mLinks[i].isLinked()) {
+ static_cast<dAcInsectButterfly_c *>(mLinks[i].get())->setKillSignal();
+ mStateMgr.changeState(StateID_End);
+ }
+ }
+ }
+}
void dTgInsect_c::finalizeState_WaitForceEscape() {}
void dTgInsect_c::initializeState_End() {}
void dTgInsect_c::executeState_End() {}
void dTgInsect_c::finalizeState_End() {}
-inline bool isButterfly3(int subtype, int spawnSubtype) {
- if (subtype != 10) return false;
- if (spawnSubtype != 3) return false;
- return true;
-}
-inline bool isButterfly4(int subtype, int spawnSubtype) {
- if (subtype != 10) return false;
- if (spawnSubtype != 4) return false;
- return true;
-}
-inline bool isButterfly5(int subtype, int spawnSubtype) {
- if (subtype != 10) return false;
- if (spawnSubtype != 5) return false;
- return true;
-}
-
static const f32 FLOAT_ARRAY[] = {
- 0.1f,
- -0.4f,
- 0.3f,
- 0.7f,
- -0.7f,
-};
-
-static const f32 WHATEVER[] = {
- 100,
- 150,
- 0.5f
+ 0.1f, -0.4f, 0.3f, 0.7f, -0.7f,
};
-static const f32 different100[] = { 100 };
-
-
+void dTgInsect_c::spawnAll() {
+ for (s32 i = 0; i < mInsectCount; i++) {
+ if (shouldSpawn()) {
+ spawnInsect(i);
+ }
+ }
+}
-// regalloc (probably)
+// non matching: rodata is weird, using multiple different 100.0f instead of just one
+// also the registers are wrong
void dTgInsect_c::spawnInsect(s32 index) {
+ s32 tries;
f32 scaledScale = 100 * mScale.y;
f32 scaled2 = mScale.x * WHATEVER[0] * 0.85f;
- mAng3_c rot(0,0,0);
+ bool spawnFound;
mVec3_c pos;
- bool spawnFound = false;
- s32 tries = 5;
+ mVec3_c tmp;
+ mAng3_c rot(0, 0, 0);
+ spawnFound = false;
+ tries = 5;
do {
f32 scale = cM::rndF(scaled2);
s16 angle1 = cM::rndFX(65536.0f);
- s16 angle2 = cM::rndFX(65536.0f);
- rot.y = angle2;
+ rot.y = cM::rndFX(65536.0f);
mVec3_c v2 = mVec3_c::Ez * scale;
cLib::offsetPos(pos, mPosition, angle1, v2);
- s32 subtype = mParams >> 4 & 0xF;
- switch (subtype) {
- case 3:
- case 5:
- case 6:
- case 9:
+ switch (getSubtype()) {
+ case SUBTYPE_VOLCANIC_LADYBUG:
+ case SUBTYPE_WOODLAND_RHINO_BEETLE:
+ case SUBTYPE_SAND_CICADA:
+ case SUBTYPE_SKY_STAG_BEETLE:
pos = mPosition;
- if (subtype == 6) {
- mVec3_c tmp = mVec3_c::Ez;
+ if (getSubtype() == SUBTYPE_SAND_CICADA) {
+ tmp = mVec3_c::Ez;
tmp.rotY(mAng(mRotation.y + 0x4000));
- f32 arrayResult = FLOAT_ARRAY[index % 5];
+ f32 arrayResult = FLOAT_ARRAY[index % (s32)ARRAY_LENGTH(FLOAT_ARRAY)];
f32 scaledX = WHATEVER[0] * mScale.x;
tmp.multScalar(arrayResult * scaledX);
pos = mPosition + tmp;
@@ -114,59 +350,59 @@ void dTgInsect_c::spawnInsect(s32 index) {
}
spawnFound = true;
break;
- case 7:
- case 8:
- case 0xB:
- case 0xC:
+ case SUBTYPE_FARON_GRASSHOPPER:
+ case SUBTYPE_LANAYRU_ANT:
+ case SUBTYPE_SKYLOFT_MANTIS:
+ case SUBTYPE_EDLIN_ROLLER:
pos.y = different100[0] + mPosition.y;
if (dBgS_ObjGndChk::CheckPos(pos)) {
spawnFound = true;
}
break;
- case 4:
- case 0xA:
- case 0xD:
+ case SUBTYPE_GERUDO_DRAGONFLY:
+ case SUBTYPE_BUTTERFLY:
+ case SUBTYPE_STARRY_FIREFLY:
spawnFound = true;
break;
}
} while (!spawnFound && --tries);
- s32 subtype = mParams >> 4 & 0xF;
- dAcBase_c* ref = nullptr;
- if (subtype == 3) {
-
- }
- switch (subtype) {
- case 3:
+ dAcBase_c *ref = nullptr;
+ switch (getSubtype()) {
+ case SUBTYPE_VOLCANIC_LADYBUG:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_LADYBUG, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 4:
+ case SUBTYPE_GERUDO_DRAGONFLY:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_DRAGONFLY, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 5:
+ case SUBTYPE_WOODLAND_RHINO_BEETLE:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_BEETLE, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 6:
+ case SUBTYPE_FARON_GRASSHOPPER:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_GRASSHOPPER, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 7:
+ case SUBTYPE_SAND_CICADA:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_CICADA, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 8:
+ case SUBTYPE_LANAYRU_ANT:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_ANT, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 9:
+ case SUBTYPE_SKY_STAG_BEETLE:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_BEETLE, 0x10000000, &pos, &rot, NULL, 0, 0x3f);
break;
- case 0xA:
- ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_BUTTERFLY, mViewClipIdx, &pos, &rot, NULL, 0, 0x3f);
+ case SUBTYPE_BUTTERFLY:
+ ref = dAcObjBase_c::createInsectActor(
+ this, fProfile::INSECT_BUTTERFLY, mViewClipIdx, &pos, &rot, NULL, 0, 0x3f
+ );
break;
- case 0xB:
- ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_GRASSHOPPER, 0x10000000, &pos, &rot, NULL, 0, 0x3f);
+ case SUBTYPE_SKYLOFT_MANTIS:
+ ref = dAcObjBase_c::createInsectActor(
+ this, fProfile::INSECT_GRASSHOPPER, 0x10000000, &pos, &rot, NULL, 0, 0x3f
+ );
break;
- case 0xC:
+ case SUBTYPE_EDLIN_ROLLER:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_SCARAB, 0, &pos, &rot, NULL, 0, 0x3f);
break;
- case 0xD:
+ case SUBTYPE_STARRY_FIREFLY:
ref = dAcObjBase_c::createInsectActor(this, fProfile::INSECT_FIREFLY, 0, &pos, &rot, NULL, 0, 0x3f);
break;
}
@@ -178,19 +414,17 @@ void dTgInsect_c::spawnInsect(s32 index) {
}
bool dTgInsect_c::shouldSpawn() {
- int spawnSubtype = mParams >> 8 & 0xF;
- if (spawnSubtype == 2) {
+ if (isSpawnSubtype(SPAWN_BUG_MINIGAME)) {
return true;
- } else if (spawnSubtype == 1) {
+ } else if (isSpawnSubtype(SPAWN_SKYLOFT_BUGKID_TREE)) {
bool tmp = SceneflagManager::sInstance->checkFlag(mRoomID, 0x3a);
return !tmp;
} else {
- int subtype = mParams >> 4 & 0xF;
- if (isButterfly3(subtype, spawnSubtype)) {
+ if (isTrialGateType()) {
return true;
- } else if (isButterfly4(subtype, spawnSubtype) || isButterfly5(subtype, spawnSubtype)) {
+ } else if (isGossipStoneType() || isGoddessWallType()) {
return true;
- } else if((subtype == 0xD) && !dAcItem_c::checkFlag(ITEM_STARRY_FIREFLY)) {
+ } else if ((isSubtype(SUBTYPE_STARRY_FIREFLY)) && !dAcItem_c::checkFlag(ITEM_STARRY_FIREFLY)) {
return true;
} else {
if (cM::rndF(1.0f) >= 0.5f) {
@@ -201,3 +435,27 @@ bool dTgInsect_c::shouldSpawn() {
}
}
}
+
+bool dTgInsect_c::someGroundCheck(const mVec3_c &pos, s32 updateRotation) {
+ mVec3_c tmp = mVec3_c::Ez * (mScale.x * 100);
+ tmp.rotY(mRotation.y);
+ tmp += pos;
+ dBgS_LinChk linChk;
+ linChk.mBackFlag = true;
+ linChk.mFrontFlag = false;
+ linChk.Set(&pos, &tmp, nullptr);
+ if (!dBgS::GetInstance()->LineCross(&linChk)) {
+ mAng yRot = mRotation.y + 0x7FFF;
+ if (updateRotation != 0) {
+ mRotation.y = yRot;
+ }
+ tmp = mVec3_c::Ez * (mScale.x * 100);
+ tmp.rotY(yRot);
+ tmp += pos;
+ linChk.Set(&pos, &tmp, nullptr);
+ if (!dBgS::GetInstance()->LineCross(&linChk)) {
+ return false;
+ }
+ }
+ return true;
+}