summaryrefslogtreecommitdiff
path: root/src/Game/Actor/Damage/dmgDamageManagerBase.cpp
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/Game/Actor/Damage/dmgDamageManagerBase.cpp
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/Game/Actor/Damage/dmgDamageManagerBase.cpp')
-rw-r--r--src/Game/Actor/Damage/dmgDamageManagerBase.cpp279
1 files changed, 0 insertions, 279 deletions
diff --git a/src/Game/Actor/Damage/dmgDamageManagerBase.cpp b/src/Game/Actor/Damage/dmgDamageManagerBase.cpp
deleted file mode 100644
index 26e8876b..00000000
--- a/src/Game/Actor/Damage/dmgDamageManagerBase.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-#include "Game/Actor/Damage/dmgDamageManagerBase.h"
-#include "Game/AOC/aocHardModeManager.h"
-#include "Game/Actor/Damage/dmgDamageCallback.h"
-#include "KingSystem/ActorSystem/actActor.h"
-#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
-#include "KingSystem/ActorSystem/actActorParam.h"
-#include "KingSystem/ActorSystem/actActorUtil.h"
-#include "KingSystem/ActorSystem/actLifeRecoveryInfo.h"
-#include "KingSystem/Resource/Actor/resResourceGParamList.h"
-#include "KingSystem/Resource/GeneralParamList/resGParamListObjectGeneral.h"
-
-namespace uking::dmg {
-
-DamageManagerBase_UnknownBase1::DamageManagerBase_UnknownBase1(ksys::act::Actor* actor)
- : mActor(actor) {}
-
-// Compiler seems to combine zero(0) writes to (0x0 ,0x8) and (0x10, 0x18)
-// when writing the vtable and Actor.
-// The original Compiler writes (0x8, 0x10) in one 'stp', and writes 0x0 and 0x18 individually with
-// 'str'. The rest seems to fall out of sync due to that, but it's otherwise functionally the same.
-// NON_MATCHING: Incorrect order.
-DamageManagerBase::DamageManagerBase(ksys::act::Actor* actor)
- : DamageManagerBase_UnknownBase1(actor) {}
-
-u32 DamageManagerBase::getDamage() {
- u32 result;
- if (canTakeDamage())
- result = mDamage;
- else
- result = 0LL;
-
- return result;
-}
-
-void DamageManagerBase::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 DamageManagerBase::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;
-}
-
-bool DamageManagerBase::applyDamage(s32& life) {
- auto* param_list = mActor->getParam()->getRes().mGParamList;
-
- const ksys::res::GParamListObjectGeneral& params = *param_list->getGeneral();
- if (params.mIsLifeInfinite.ref()) {
- // Since life is infinite, we don't need to modify the damage or life.
- // But we still call the "callback" as if damage was done.
- onApplyDamage();
- return false;
- }
-
- s32 damage = getDamage();
- if (damage >= 1) {
- if (ksys::act::isPlayerProfile(mActor)) {
- if (getAttacker()->hasProc()) {
- tryBuffDamage(damage);
- }
- }
- }
-
- tryApplyDamageRecovery(damage);
-
- // Actually deal damage
- onApplyDamage();
- f32 old_life = life;
- life = std::max(0, life - damage);
- bool did_damage = old_life != life;
-
- return did_damage;
-}
-
-void DamageManagerBase::tryBuffDamage(s32& damage) {
- if (!aoc::HardModeManager::instance()) {
- return;
- }
-
- if (!aoc::HardModeManager::instance()->checkFlag(aoc::HardModeManager::Flag::EnableHardMode)) {
- return;
- }
-
- if (!aoc::HardModeManager::instance()->isHardModeChangeOn(
- aoc::HardModeManager::HardModeChange::ApplyDamageMultiplier)) {
- return;
- }
-
- ksys::act::ActorLinkConstDataAccess acc;
- ksys::act::acquireActor(getAttacker(), &acc);
- if (aoc::HardModeManager::shouldApplyMasterModeDamageMultiplier(acc)) {
- aoc::HardModeManager::buffDamage(damage);
- }
-}
-
-void DamageManagerBase::tryApplyDamageRecovery(s32& damage) {
- if (!aoc::HardModeManager::instance()) {
- return;
- }
-
- if (!aoc::HardModeManager::instance()->checkFlag(aoc::HardModeManager::Flag::EnableHardMode)) {
- return;
- }
-
- if (!aoc::HardModeManager::instance()->isHardModeChangeOn(
- uking::aoc::HardModeManager::HardModeChange::EnableLifeRegen)) {
- return;
- }
-
- if (!mActor->getLifeRecoverInfo()) {
- return;
- }
-
- // Take damage from extra HP1, and modify damage.
- // Returns true if damage remains? No more regen?
- ksys::act::LifeRecoverInfo* life_recovery_info = mActor->getLifeRecoverInfo();
- if (life_recovery_info->onApplyDamage(damage)) {
- // Update flags and counter.
- life_recovery_info->onApplyDamage_0();
- }
-}
-
-s32 DamageManagerBase::getNumCallbacks() {
- // More like number of supported event types, than number of callbacks.
- // These seem to return a fixed number for each different DamageManager class.
- return 0;
-}
-
-bool DamageManagerBase::initCallbacks(sead::Heap*) {
- // Does nothing in the Base class, and doesn't seem like any of the known classes actually
- // override this yet.
- return true;
-}
-
-bool DamageManagerBase::allocStruct20(sead::Heap* heap) {
- mStruct20_a = new (heap) Struct20;
- if (!mStruct20_a) {
- return false;
- }
-
- mStruct20_b = new (heap) Struct20;
- return mStruct20_b != nullptr;
-}
-
-void DamageManagerBase::preDelete1() {
- if (mStruct20_a) {
- delete mStruct20_a;
- mStruct20_a = nullptr;
- }
- if (mStruct20_b) {
- delete mStruct20_b;
- mStruct20_b = nullptr;
- }
-}
-
-bool DamageManagerBase::canTakeDamage() {
- u32 damageTypeMaybe = m49(getField50());
- if (!DamageInfoMgr::instance()) {
- return false;
- }
-
- s32 idx = mDamageReactionTableStuff;
- if (idx < 0) {
- return false;
- }
-
- if (!DamageInfoMgr::instance()->getDamagesArray().isBufferReady()) {
- return false;
- }
-
- DamageInfoMgr::DamageItem& item = DamageInfoMgr::instance()->getDamagesArray()[idx];
- return item.mCanTakeDamageFromType[damageTypeMaybe] & 0x1;
-}
-
-void DamageManagerBase::handleDamageForPlayer(u32* a2, u32* a3, u32* a4, u32* a5, u32* a6) {
- Struct20* currentStruct = sead::DynamicCast<Struct20>(mStruct20_b);
- if (!currentStruct) {
- return;
- }
-
- *a2 = currentStruct->mField_8;
- *a3 = currentStruct->mField_C;
- *a5 = currentStruct->mField_14;
- *a6 = currentStruct->mField_18;
- *a4 = currentStruct->mField_10;
-}
-
-bool DamageManagerBase::addDamage(s64, s32 damage, s32 df48, s32 minDmg, s32 f50, s32 f54,
- s32 f40) {
- mDamage += damage;
- mField_48 += df48;
- mMinDmg += minDmg;
-
- if (mField_54 >= f54) {
- return false;
- }
-
- mField_50 = f50;
- mField_54 = f54;
- mField_40 = f40;
-
- return true;
-}
-
-s32 DamageManagerBase::m49(s32 damageTypeMaybe) {
- if (damageTypeMaybe == 3) {
- return 2;
- }
-
- return 0;
-}
-
-} // namespace uking::dmg