diff options
| author | Léo Lam <leo@leolam.fr> | 2026-09-28 03:39:31 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2026-10-11 04:53:08 +0200 |
| commit | 419f8f46bb40763d9602e4f975a033194281c5f5 (patch) | |
| tree | bdd44d13360e6d6c5422c1f269aa7af84d7075a2 /src/KingSystem/ActorSystem | |
| parent | bdf141cf2d4919bb08de69d8a0c6cb4b6dd3e4ef (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.txt | 2 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actActor.h | 7 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actIDamageManager.cpp | 81 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actIDamageManager.h | 64 |
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 |
