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 +class sVFStateID_c : public sFStateID_c { +public: + typedef void (T::*stateFunc)(); + sVFStateID_c(sStateID_c *superState, const char *name, stateFunc initialize, stateFunc execute, stateFunc finalize) + : sFStateID_c(name, initialize, execute, finalize), mpSuperState(superState) {} + + virtual unsigned int number() const { + return getRootState()->numberBase(); + } + + const sVFStateID_c *getRootState() const { + if (!mpSuperState->isNull()) { + return static_cast *>(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 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 StateID_##name; \ + +#define STATE_VIRTUAL_DEFINE(class, name) \ + sStateID_c *getDefaultSuperState_##class##name() { \ + return &sStateID::null; \ + } \ + sVFStateID_c 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 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);