summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2026-09-28 03:39:31 +0200
committerLéo Lam <leo@leolam.fr>2026-10-11 04:53:08 +0200
commit419f8f46bb40763d9602e4f975a033194281c5f5 (patch)
treebdd44d13360e6d6c5422c1f269aa7af84d7075a2 /src/KingSystem/ActorSystem
parentbdf141cf2d4919bb08de69d8a0c6cb4b6dd3e4ef (diff)
ksys/act: split IDamageManager out of DamageManagerBase
DamageManagerBase's root base class (previously DamageManagerBase_UnknownBase1) holds the damage callback list, and its code is linked among the ActorSystem objects rather than with the Game/Actor/Damage files. It appears to be an engine-side abstract base, so let's move it to KingSystem/ActorSystem as ksys::act::IDamageManager (unofficial name, following the ksys IManager/Manager pattern and Actor::getDamageMgr), together with DamageCallback and Struct20Base, and have Actor::getDamageMgr return it. DamageManagerBase now overrides its getters and inherits addDamageCallback/removeDamageCallback from it. The rest of the damage code stays in Game/Actor/Damage but is regrouped to match link order: Struct20::combineMaybe moves into actDamageManagerBase.cpp, Struct20::reset becomes inline and dmgStruct20.cpp becomes actDamageMgr.cpp. The uking::dmg namespace is merged into uking::act, so the files there take the act prefix too, and dmgInfoManager becomes actDamageInfoMgr after the class it holds. (AI assisted using Claude Fable 5.1 and Claude Opus 5.5)
Diffstat (limited to 'src/KingSystem/ActorSystem')
-rw-r--r--src/KingSystem/ActorSystem/CMakeLists.txt2
-rw-r--r--src/KingSystem/ActorSystem/actActor.h7
-rw-r--r--src/KingSystem/ActorSystem/actIDamageManager.cpp81
-rw-r--r--src/KingSystem/ActorSystem/actIDamageManager.h64
4 files changed, 149 insertions, 5 deletions
diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt
index b3f0e0da..c83f97de 100644
--- a/src/KingSystem/ActorSystem/CMakeLists.txt
+++ b/src/KingSystem/ActorSystem/CMakeLists.txt
@@ -101,6 +101,8 @@ target_sources(uking PRIVATE
actDebug.h
actGlobalParameter.cpp
actGlobalParameter.h
+ actIDamageManager.cpp
+ actIDamageManager.h
actInfoCommon.cpp
actInfoCommon.h
actInfoData.cpp
diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h
index d9b2952b..2749d091 100644
--- a/src/KingSystem/ActorSystem/actActor.h
+++ b/src/KingSystem/ActorSystem/actActor.h
@@ -23,10 +23,6 @@ namespace gsys {
class Model;
} // namespace gsys
-namespace uking::dmg {
-class DamageManagerBase;
-} // namespace uking::dmg
-
namespace ksys {
namespace as {
@@ -74,6 +70,7 @@ class BaseProcLink;
class BoneControl;
class Chemical;
class ImpulseBaseProcLink;
+class IDamageManager;
class ModelBindInfo;
class Schedule;
@@ -270,7 +267,7 @@ public:
virtual void onPlacementObjReset();
virtual void getAtk();
virtual void m126();
- virtual uking::dmg::DamageManagerBase* getDamageMgr();
+ virtual IDamageManager* getDamageMgr();
virtual void m128();
virtual void m129();
virtual void getPlayerRideInfo();
diff --git a/src/KingSystem/ActorSystem/actIDamageManager.cpp b/src/KingSystem/ActorSystem/actIDamageManager.cpp
new file mode 100644
index 00000000..fd4f09a6
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actIDamageManager.cpp
@@ -0,0 +1,81 @@
+#include "KingSystem/ActorSystem/actIDamageManager.h"
+#include "KingSystem/ActorSystem/actActor.h"
+
+namespace ksys::act {
+
+void IDamageManager::addDamageCallback(s32 eventId, DamageCallback* callback) {
+ if (mCallbacks.isBufferReady() && !callback->mDamageManager) {
+ DamageCallback* next = mCallbacks[eventId];
+ if (next) {
+ DamageCallback* prev;
+ while (next) {
+ prev = next;
+ next = next->mNext;
+ }
+
+ prev->mNext = callback;
+ callback->mPrev = prev;
+ } else {
+ mCallbacks[eventId] = callback;
+ }
+
+ callback->mDamageManager = this;
+ callback->mEventId = eventId;
+ }
+}
+
+void IDamageManager::removeDamageCallback(DamageCallback* callback) {
+ if (!mCallbacks.isBufferReady() || callback->mDamageManager != this) {
+ return;
+ }
+
+ u32 event_id = callback->mEventId;
+ DamageCallback* current_callback = mCallbacks[event_id];
+ if (!current_callback) {
+ if (mActor) {
+ // Logging about trying to remove missing callback?
+ mActor->nullsub_4649();
+ }
+
+ callback->mDamageManager = nullptr;
+ callback->mEventId = -1;
+#ifdef MATCHING_HACK_NX_CLANG
+ asm(""); // Stop optimizing with the other clear below
+#endif
+ return;
+ }
+
+ if (current_callback == callback) {
+ mCallbacks[event_id] = callback->mNext;
+ current_callback = mCallbacks[event_id];
+ if (current_callback) {
+ current_callback->mPrev = nullptr;
+ }
+#ifdef MATCHING_HACK_NX_CLANG
+ asm(""); // Stop re-using variables, generating an extra register
+#endif
+ } else {
+ do {
+ if (current_callback == callback) {
+ DamageCallback* prev = callback->mPrev;
+ if (prev) {
+ prev->mNext = callback->mNext;
+ }
+ DamageCallback* next = callback->mNext;
+ if (next) {
+ next->mPrev = callback->mPrev;
+ }
+ }
+ current_callback = current_callback->mNext;
+ } while (current_callback);
+ }
+ callback->mNext = nullptr;
+#ifdef MATCHING_HACK_NX_CLANG
+ asm(""); // Stop combining the mNext and mDamageManager
+#endif
+ callback->mDamageManager = nullptr;
+ callback->mEventId = -1;
+ callback->mPrev = nullptr;
+}
+
+} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actIDamageManager.h b/src/KingSystem/ActorSystem/actIDamageManager.h
new file mode 100644
index 00000000..4a5b77fa
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actIDamageManager.h
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <basis/seadTypes.h>
+#include <container/seadBuffer.h>
+#include <prim/seadRuntimeTypeInfo.h>
+
+namespace ksys::act {
+
+class Actor;
+class IDamageManager;
+
+class DamageCallback {
+public:
+ virtual ~DamageCallback() {}
+ virtual void call(u32* a1, s32* a2, u32* a3, u32* a4, u32* a5, u64 a6);
+
+ DamageCallback* mPrev;
+ DamageCallback* mNext;
+ IDamageManager* mDamageManager;
+ u32 mEventId;
+};
+
+class Struct20Base {
+ SEAD_RTTI_BASE(Struct20Base)
+
+public:
+ virtual ~Struct20Base() = default;
+
+ virtual void reset();
+ virtual void combineMaybe(Struct20Base* other);
+};
+
+class IDamageManager {
+public:
+ explicit IDamageManager(Actor* actor) : mActor(actor) {}
+
+ SEAD_RTTI_BASE(IDamageManager)
+
+ virtual ~IDamageManager() = default;
+
+ virtual u32 getDamage() = 0;
+ virtual s32 getField48() = 0;
+ virtual s32 getMinDmg() = 0;
+ virtual s32 getField50() = 0;
+ virtual s32 getField54() = 0;
+ virtual bool checkDamageFlags() = 0;
+ virtual s32 getFlags2() = 0;
+ virtual void addDamageCallback(s32 eventId, DamageCallback* callback);
+ virtual void removeDamageCallback(DamageCallback* callback);
+
+ // Sturct20 for Damage receive/send?
+ Struct20Base* mStruct20_a = nullptr;
+ Struct20Base* mStruct20_b = nullptr;
+
+ Actor* mActor = nullptr;
+
+ sead::Buffer<DamageCallback*> mCallbacks{};
+
+ // Callback status flags?
+ s32 mField_30 = 0;
+ s8 mField_34 = 0;
+};
+
+} // namespace ksys::act