summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2024-11-10 21:20:43 +0100
committerrobojumper <robojumper@gmail.com>2024-11-13 19:08:38 +0100
commit3a45e6536a1deec0cd5a4c108dfeb4c374ca34d9 (patch)
tree018d678c476252f260ed68fb1c22ad991f4154f5
parentfefe3af58f305a5543e2fe2c20f2415040dc4dd4 (diff)
Try to figure out how this virtual state thing works
-rw-r--r--config/SOUE01/splits.txt8
-rw-r--r--configure.py2
-rw-r--r--include/d/a/npc/d_a_npc.h65
-rw-r--r--include/d/a/npc/d_a_ordinary_npc.h11
-rw-r--r--src/d/a/npc/d_a_npc.cpp26
-rw-r--r--src/d/a/npc/d_a_ordinary_npc.cpp5
6 files changed, 116 insertions, 1 deletions
diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt
index 0a66776a..d06d4ab2 100644
--- a/config/SOUE01/splits.txt
+++ b/config/SOUE01/splits.txt
@@ -45,6 +45,14 @@ d/a/e/d_a_e_base.cpp:
.text start:0x8002F300 end:0x80030CB0
.ctors start:0x804DB664 end:0x804DB668
+d/a/npc/d_a_npc.cpp:
+ .text start:0x80030CB0 end:0x8003F718
+ .ctors start:0x804DB668 end:0x804DB66C
+
+d/a/npc/d_a_ordinary_npc.cpp:
+ .text start:0x800462D0 end:0x8004D810
+ .ctors start:0x804DB66C end:0x804DB670
+
d/d_ac_npc_kyui.cpp:
.text start:0x8004D810 end:0x80050800
.ctors start:0x804DB670 end:0x804DB674
diff --git a/configure.py b/configure.py
index 519a6d24..12e19429 100644
--- a/configure.py
+++ b/configure.py
@@ -338,6 +338,8 @@ config.libs = [
Object(NonMatching, "d/a/d_a_base.cpp"),
Object(NonMatching, "d/a/d_a_item.cpp"),
Object(NonMatching, "d/a/obj/d_a_obj_base.cpp"),
+ Object(NonMatching, "d/a/npc/d_a_npc.cpp"),
+ Object(NonMatching, "d/a/npc/d_a_ordinary_npc.cpp"),
Object(NonMatching, "d/a/obj/d_a_obj_bomb.cpp"),
Object(NonMatching, "d/a/obj/d_a_obj_arrow.cpp"),
Object(NonMatching, "d/a/obj/d_a_obj_boomerang.cpp"),
diff --git a/include/d/a/npc/d_a_npc.h b/include/d/a/npc/d_a_npc.h
index 0e360ad5..ad95da03 100644
--- a/include/d/a/npc/d_a_npc.h
+++ b/include/d/a/npc/d_a_npc.h
@@ -2,12 +2,75 @@
#define D_A_NPC_H
#include "d/a/obj/d_a_obj_base.h"
+#include "s/s_FStateID.hpp"
+#include "s/s_FStateMgr.hpp"
+#include "s/s_StateID.hpp"
+#include "s/s_StateMethodUsr_FI.hpp"
+
+// Virtual states!
+template <typename T>
+class sVFStateID_c : public sFStateID_c<T> {
+public:
+ typedef void (T::*stateFunc)();
+ sVFStateID_c(sStateID_c *superState, const char *name, stateFunc initialize, stateFunc execute, stateFunc finalize)
+ : sFStateID_c<T>(name, initialize, execute, finalize), mpSuperState(superState) {}
+
+ virtual unsigned int number() const {
+ return getRootState()->numberBase();
+ }
+
+ const sVFStateID_c<T> *getRootState() const {
+ if (!mpSuperState->isNull()) {
+ return static_cast<const sVFStateID_c<T> *>(mpSuperState)->getRootState();
+ }
+ return this;
+ }
+
+ unsigned int numberBase() const {
+ return sStateID_c::number();
+ }
+
+
+private:
+ sStateID_c *mpSuperState;
+};
+
+#define STATE_VIRTUAL_FUNC_DECLARE(class, name) \
+ virtual void initializeState_##name(); \
+ virtual void executeState_##name(); \
+ virtual void finalizeState_##name(); \
+ static sVFStateID_c<class> StateID_##name
+
+#define STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(class, super_class, name) \
+ virtual void initializeState_##name() override; \
+ virtual void executeState_##name() override; \
+ virtual void finalizeState_##name() override; \
+ static sVFStateID_c<class> StateID_##name; \
+
+#define STATE_VIRTUAL_DEFINE(class, name) \
+ sStateID_c *getDefaultSuperState_##class##name() { \
+ return &sStateID::null; \
+ } \
+ sVFStateID_c<class> class ::StateID_##name( \
+ getDefaultSuperState_##class##name(), #class "::StateID_" #name, &class ::initializeState_##name, \
+ &class ::executeState_##name, &class ::finalizeState_##name \
+ )
+
+#define STATE_VIRTUAL_MGR_DECLARE(class_name) sFStateMgr_c<class_name, sStateMethodUsr_FI_c> mStateMgr;
// This is the NPC base. Most npcs actually use dAcOrdinaryNpc, but this just is a simpler one?
// Ghidra: ActorNpcBase
// size: 0x6e4
// official name
-class dAcNpc_c : public dAcObjBase_c {};
+class dAcNpc_c : public dAcObjBase_c {
+public:
+ dAcNpc_c();
+
+ STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Wait);
+ STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Demo);
+
+ STATE_VIRTUAL_MGR_DECLARE(dAcNpc_c);
+};
#endif
diff --git a/include/d/a/npc/d_a_ordinary_npc.h b/include/d/a/npc/d_a_ordinary_npc.h
new file mode 100644
index 00000000..c826f478
--- /dev/null
+++ b/include/d/a/npc/d_a_ordinary_npc.h
@@ -0,0 +1,11 @@
+#ifndef D_A_ORDINARY_NPC_H
+#define D_A_ORDINARY_NPC_H
+
+#include "d/a/npc/d_a_npc.h"
+
+class dAcOrdinaryNpc_c : public dAcNpc_c {
+public:
+ STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Pain);
+};
+
+#endif
diff --git a/src/d/a/npc/d_a_npc.cpp b/src/d/a/npc/d_a_npc.cpp
new file mode 100644
index 00000000..33bab964
--- /dev/null
+++ b/src/d/a/npc/d_a_npc.cpp
@@ -0,0 +1,26 @@
+#include "d/a/npc/d_a_npc.h"
+#include "s/s_StateID.hpp"
+
+fLiMgBa_c NPC_ACTOR_LIST;
+
+STATE_VIRTUAL_DEFINE(dAcNpc_c, Wait);
+STATE_VIRTUAL_DEFINE(dAcNpc_c, Demo);
+
+extern nw4r::ut::Color sColors[] = {
+ nw4r::ut::Color(0xEF, 0x30, 0x27, 0xFF),
+ nw4r::ut::Color(0, 0, 0, 0xFF),
+ nw4r::ut::Color(0xEF, 0x30, 0x27, 0),
+ nw4r::ut::Color(0xFF, 0xFF, 0xFF, 0),
+ nw4r::ut::Color(0xFE, 0xF8, 0x9D, 0xFF),
+ nw4r::ut::Color(0x88, 0x63, 0x36, 0x80),
+ nw4r::ut::Color(0x4F, 0x46, 0x33, 0xFF),
+ nw4r::ut::Color(0xD8, 0xC5, 0x8D, 0xFF),
+ nw4r::ut::Color(0x95, 0x69, 0x3B, 0xFF),
+ nw4r::ut::Color(0x50, 0x46, 0x32, 0),
+ nw4r::ut::Color(0xD8, 0xC5, 0x8D, 0),
+ nw4r::ut::Color(0x96, 0x69, 0x3C, 0),
+ nw4r::ut::Color(0, 0, 0, 0),
+};
+
+
+dAcNpc_c::dAcNpc_c() : mStateMgr(*this, sStateID::null) {}
diff --git a/src/d/a/npc/d_a_ordinary_npc.cpp b/src/d/a/npc/d_a_ordinary_npc.cpp
new file mode 100644
index 00000000..767a9c7e
--- /dev/null
+++ b/src/d/a/npc/d_a_ordinary_npc.cpp
@@ -0,0 +1,5 @@
+#include "d/a/npc/d_a_ordinary_npc.h"
+#include "d/a/npc/d_a_npc.h"
+#include "s/s_StateID.hpp"
+
+STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Pain);