From 05a69f745b8e47b5b4a0c63ca48a73686559da69 Mon Sep 17 00:00:00 2001 From: Wildex999 Date: Sun, 18 Oct 2020 17:12:23 +0200 Subject: [PATCH] ksys/dmg: Implementing some of DamageManagerBase. Added some temporary classes/variables used by DamageManagerBase. --- data/uking_functions.csv | 114 ++++---- src/Game/DLC/aoc2.cpp | 10 + src/Game/DLC/aoc2.h | 13 + src/KingSystem/ActorSystem/CMakeLists.txt | 1 + src/KingSystem/ActorSystem/actActor.h | 12 + src/KingSystem/ActorSystem/actActorParamMgr.h | 23 ++ .../ActorSystem/actLifeRecoveryInfo.h | 37 +++ src/KingSystem/CMakeLists.txt | 1 + src/KingSystem/Damage/CMakeLists.txt | 8 + src/KingSystem/Damage/dmgDamageCallback.h | 23 ++ src/KingSystem/Damage/dmgDamageInfoManager.h | 31 ++ .../Damage/dmgDamageManagerBase.cpp | 273 ++++++++++++++++++ src/KingSystem/Damage/dmgDamageManagerBase.h | 145 ++++++++++ src/KingSystem/Damage/dmgStruct20.cpp | 53 ++++ src/KingSystem/Damage/dmgStruct20.h | 64 ++++ 15 files changed, 751 insertions(+), 57 deletions(-) create mode 100644 src/KingSystem/ActorSystem/actLifeRecoveryInfo.h create mode 100644 src/KingSystem/Damage/CMakeLists.txt create mode 100644 src/KingSystem/Damage/dmgDamageCallback.h create mode 100644 src/KingSystem/Damage/dmgDamageInfoManager.h create mode 100644 src/KingSystem/Damage/dmgDamageManagerBase.cpp create mode 100644 src/KingSystem/Damage/dmgDamageManagerBase.h create mode 100644 src/KingSystem/Damage/dmgStruct20.cpp create mode 100644 src/KingSystem/Damage/dmgStruct20.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index d372b65c..13ddb0f5 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -204,33 +204,33 @@ 0x0000007100003f48,DamageMgrBow::m54,164, 0x0000007100003fec,DamageMgrBow::m0,132, 0x0000007100004070,DamageMgrBow::m1,92, -0x00000071000040cc,DamageMgrBase::m2_null,4, +0x00000071000040cc,DamageMgrBase::m2_null,4,_ZN4ksys3dmg17DamageManagerBaseD2Ev 0x00000071000040d0,j__ZdlPv_0,4, -0x00000071000040d4,DamageMgrBase::m5,8, -0x00000071000040dc,DamageMgrBase::getMinDmg,8, -0x00000071000040e4,DamageMgrBase::m7,8, -0x00000071000040ec,DamageMgrBase::m9,8, -0x00000071000040f4,DamageMgrBase::m10,8, -0x00000071000040fc,DamageMgrBase::m13,8, -0x0000007100004104,DamageMgrBase::m14,8, -0x000000710000410c,DamageMgrBase::m16,8, -0x0000007100004114,DamageMgrBase::m17_null,4, +0x00000071000040d4,DamageMgrBase::m5,8,_ZN4ksys3dmg17DamageManagerBase10getField48Ev +0x00000071000040dc,DamageMgrBase::getMinDmg,8,_ZN4ksys3dmg17DamageManagerBase9getMinDmgEv +0x00000071000040e4,DamageMgrBase::m7,8,_ZN4ksys3dmg17DamageManagerBase10getField50Ev +0x00000071000040ec,DamageMgrBase::m9,8,_ZN4ksys3dmg17DamageManagerBase16checkDamageFlagsEv +0x00000071000040f4,DamageMgrBase::m10,8,_ZN4ksys3dmg17DamageManagerBase9getFlags2Ev +0x00000071000040fc,DamageMgrBase::m13,8,_ZN4ksys3dmg17DamageManagerBase3m13Ev +0x0000007100004104,DamageMgrBase::m14,8,_ZN4ksys3dmg17DamageManagerBase3m14Ev +0x000000710000410c,DamageMgrBase::m16,8,_ZN4ksys3dmg17DamageManagerBase3m16Ev +0x0000007100004114,DamageMgrBase::m17_null,4,_ZN4ksys3dmg17DamageManagerBase3m17Ev 0x0000007100004118,DamageMgrBow::m18,8, -0x0000007100004120,DamageMgrBase::initCallbacks,8, -0x0000007100004128,DamageMgrBase::m21_null,4, -0x000000710000412c,DamageMgrBase::m25,8, -0x0000007100004134,DamageMgrBase::m26,8, -0x000000710000413c,DamageMgrBase::m31,8, -0x0000007100004144,DamageMgrBase::m32,8, -0x000000710000414c,DamageMgrBase::m34,8, -0x0000007100004154,DamageMgrBase::m35,8, -0x000000710000415c,DamageMgrBase::m38,8, -0x0000007100004164,DamageMgrBase::m40,8, -0x000000710000416c,DamageMgrBase::m41,8, -0x0000007100004174,DamageMgrBase::m42,8, -0x000000710000417c,DamageMgrBase::m43_null,4, +0x0000007100004120,DamageMgrBase::initCallbacks,8,_ZN4ksys3dmg17DamageManagerBase13initCallbacksEPN4sead4HeapE +0x0000007100004128,DamageMgrBase::m21_null,4,_ZN4ksys3dmg17DamageManagerBase10preDelete2Ev +0x000000710000412c,DamageMgrBase::m25,8,_ZN4ksys3dmg17DamageManagerBase3m25Ev +0x0000007100004134,DamageMgrBase::m26,8,_ZN4ksys3dmg17DamageManagerBase3m26Ev +0x000000710000413c,DamageMgrBase::m31,8,_ZN4ksys3dmg17DamageManagerBase3m31Ev +0x0000007100004144,DamageMgrBase::m32,8,_ZN4ksys3dmg17DamageManagerBase3m32Ev +0x000000710000414c,DamageMgrBase::m34,8,_ZN4ksys3dmg17DamageManagerBase26tgSensorMaterialOnHitMaybeEv +0x0000007100004154,DamageMgrBase::m35,8,_ZN4ksys3dmg17DamageManagerBase3m35Ev +0x000000710000415c,DamageMgrBase::m38,8,_ZN4ksys3dmg17DamageManagerBase3m38Ev +0x0000007100004164,DamageMgrBase::m40,8,_ZN4ksys3dmg17DamageManagerBase3m40Ev +0x000000710000416c,DamageMgrBase::m41,8,_ZN4ksys3dmg17DamageManagerBase3m41Ev +0x0000007100004174,DamageMgrBase::m42,8,_ZN4ksys3dmg17DamageManagerBase3m42Ev +0x000000710000417c,DamageMgrBase::m43_null,4,_ZN4ksys3dmg17DamageManagerBase3m43Ev 0x0000007100004180,DamageMgr::m44,8, -0x0000007100004188,DamageMgrBase::onApplyDamage,4, +0x0000007100004188,DamageMgrBase::onApplyDamage,4,_ZN4ksys3dmg17DamageManagerBase13onApplyDamageEv 0x000000710000418c,DamageMgrBow::m51,8, 0x0000007100004194,DamageMgrBow::m52,8, 0x000000710000419c,DamageMgrBow::m53,8, @@ -620,11 +620,11 @@ 0x000000710001bd9c,DamageMgrWeapon::rtti1,288, 0x000000710001bebc,sub_710001BEBC,92, 0x000000710001bf18,j__ZdlPv_12,4, -0x000000710001bf1c,DamageMgrBase::m18,8, -0x000000710001bf24,DamageMgrBase::m22_null,4, -0x000000710001bf28,DamageMgrBase::m27,8, -0x000000710001bf30,DamageMgrBase::m28,8, -0x000000710001bf38,DamageMgrBase::m33,8, +0x000000710001bf1c,DamageMgrBase::m18,8,_ZN4ksys3dmg17DamageManagerBase15getNumCallbacksEv +0x000000710001bf24,DamageMgrBase::m22_null,4,_ZN4ksys3dmg17DamageManagerBase3m22Ev +0x000000710001bf28,DamageMgrBase::m27,8,_ZN4ksys3dmg17DamageManagerBase11getPositionEv +0x000000710001bf30,DamageMgrBase::m28,8,_ZN4ksys3dmg17DamageManagerBase3m28Ev +0x000000710001bf38,DamageMgrBase::m33,8,_ZN4ksys3dmg17DamageManagerBase3m33Ev 0x000000710001bf40,nullsub_55,4, 0x000000710001bf44,sub_710001BF44,8, 0x000000710001bf4c,DamageMgrWeapon::m52,8, @@ -44061,7 +44061,7 @@ 0x00000071006d8be4,DamageMgr::m55,516, 0x00000071006d8de8,sub_71006D8DE8,148, 0x00000071006d8e7c,sub_71006D8E7C,68, -0x00000071006d8ec0,sub_71006D8EC0,244, +0x00000071006d8ec0,sub_71006D8EC0,244,_ZN4ksys3dmg10Struct20_212combineMaybeEPNS0_12Struct20BaseE 0x00000071006d8fb4,DamageMgr::rtti0,288, 0x00000071006d90d4,DamageMgr::rtti2,92, 0x00000071006d9130,DamageMgr::m2,212, @@ -44073,10 +44073,10 @@ 0x00000071006d9310,DamageMgr::m53,8, 0x00000071006d9318,sub_71006D9318,212, 0x00000071006d93ec,sub_71006D93EC,224, -0x00000071006d94cc,sub_71006D94CC,288, -0x00000071006d95ec,sub_71006D95EC,92, -0x00000071006d9648,j__ZdlPv_292,4, -0x00000071006d964c,sub_71006D964C,24, +0x00000071006d94cc,sub_71006D94CC,288,_ZNK4ksys3dmg10Struct20_227checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x00000071006d95ec,sub_71006D95EC,92,_ZNK4ksys3dmg10Struct20_218getRuntimeTypeInfoEv +0x00000071006d9648,j__ZdlPv_292,4,_ZN4ksys3dmg10Struct20_2D0Ev +0x00000071006d964c,sub_71006D964C,24,_ZN4ksys3dmg10Struct20_25resetEv 0x00000071006d9664,j__ZdlPv_293,4, 0x00000071006d9668,sub_71006D9668,8, 0x00000071006d9670,j__ZdlPv_294,4, @@ -44085,7 +44085,7 @@ 0x00000071006d9748,sub_71006D9748,92, 0x00000071006d97a4,sub_71006D97A4,112, 0x00000071006d9814,sub_71006D9814,92, -0x00000071006d9870,Struct20::m2,20, +0x00000071006d9870,Struct20::m2,20,_ZN4ksys3dmg8Struct20D2Ev 0x00000071006d9884,j__ZdlPv_295,4, 0x00000071006d9888,nullsub_2287,4, 0x00000071006d988c,nullsub_2288,4, @@ -44224,21 +44224,21 @@ 0x00000071006dfcb0,nullsub_2297,4, 0x00000071006dfcb4,nullsub_2298,4, 0x00000071006dfcb8,nullsub_2299,4, -0x00000071006dfcbc,DamageMgrBase::allocStruct20,132, -0x00000071006dfd40,DamageMgrBase::m24,76, -0x00000071006dfd8c,DamageMgrBase::ctor,76, +0x00000071006dfcbc,DamageMgrBase::allocStruct20,132,_ZN4ksys3dmg17DamageManagerBase13allocStruct20EPN4sead4HeapE +0x00000071006dfd40,DamageMgrBase::m24,76,_ZN4ksys3dmg17DamageManagerBase10preDelete1Ev +0x00000071006dfd8c,DamageMgrBase::ctor,76,_ZN4ksys3dmg17DamageManagerBaseC1EPNS_3act5ActorE? 0x00000071006dfdd8,DamageMgrBase::m20,96, 0x00000071006dfe38,DamageMgrBase::resetStuff,20, -0x00000071006dfe4c,DamageMgrBase::applyDamage,500, -0x00000071006e0040,DamageMgrBase::m46,204, -0x00000071006e010c,DamageMgrBase::addDamage,72, +0x00000071006dfe4c,DamageMgrBase::applyDamage,500,_ZN4ksys3dmg17DamageManagerBase11applyDamageERi? +0x00000071006e0040,DamageMgrBase::m46,204,_ZN4ksys3dmg17DamageManagerBase21handleDamageForPlayerEPjS2_S2_S2_S2_ +0x00000071006e010c,DamageMgrBase::addDamage,72,_ZN4ksys3dmg17DamageManagerBase9addDamageEliiiiii 0x00000071006e0154,DamageMgrBase::isSlowTime,4, 0x00000071006e0158,DamageMgrBase::m29,324, 0x00000071006e029c,DamageMgrBase::m30,2296, -0x00000071006e0b94,DamageMgrBase::getDamage,56, -0x00000071006e0bcc,DamageMgrBase::m8,8, +0x00000071006e0b94,DamageMgrBase::getDamage,56,_ZN4ksys3dmg17DamageManagerBase9getDamageEv +0x00000071006e0bcc,DamageMgrBase::m8,8,_ZN4ksys3dmg17DamageManagerBase10getField54Ev 0x00000071006e0bd4,sub_71006E0BD4,100, -0x00000071006e0c38,DamageMgrBase::canTakeDamage,136, +0x00000071006e0c38,DamageMgrBase::canTakeDamage,136,_ZN4ksys3dmg17DamageManagerBase13canTakeDamageEv 0x00000071006e0cc0,sub_71006E0CC0,100, 0x00000071006e0d24,sub_71006E0D24,196, 0x00000071006e0de8,sub_71006E0DE8,144, @@ -44246,21 +44246,21 @@ 0x00000071006e0f24,sub_71006E0F24,144, 0x00000071006e0fb4,sub_71006E0FB4,156, 0x00000071006e10d0,sub_71006E10D0,292, -0x00000071006e1274,DamageMgrBase::m45_null,4, -0x00000071006e1278,DamageMgrBase::m49,16, +0x00000071006e1274,DamageMgrBase::m45_null,4,_ZN4ksys3dmg17DamageManagerBase3m45Ev +0x00000071006e1278,DamageMgrBase::m49,16,_ZN4ksys3dmg17DamageManagerBase3m49Ei 0x00000071006e1288,DamageMgr::getActorDamageParam,28, -0x00000071006e12a4,Struct20::m5,208, +0x00000071006e12a4,Struct20::m5,208,_ZN4ksys3dmg8Struct2012combineMaybeEPNS0_12Struct20BaseE 0x00000071006e1374,DamageMgrBase::m36,20, 0x00000071006e1388,DamageMgrBase::m37,20, 0x00000071006e139c,DamageMgrBase::rtti1,204, 0x00000071006e1468,DamageMgrBase::rtti2,92, -0x00000071006e14c4,DamageMgrBase::m3,4, -0x00000071006e14c8,nullsub_2301,4, -0x00000071006e14cc,sub_71006E14CC,8, -0x00000071006e14d4,Struct20::rtti1,204, -0x00000071006e15a0,Struct20::rtti2,92, -0x00000071006e15fc,j__ZdlPv_299,4, -0x00000071006e1600,Struct20::m4,20, +0x00000071006e14c4,DamageMgrBase::m3,4,_ZN4ksys3dmg17DamageManagerBaseD0Ev +0x00000071006e14c8,nullsub_2301,4,_ZThn56_N4ksys3dmg17DamageManagerBaseD1Ev +0x00000071006e14cc,sub_71006E14CC,8,_ZThn56_N4ksys3dmg17DamageManagerBaseD0Ev +0x00000071006e14d4,Struct20::rtti1,204,_ZNK4ksys3dmg8Struct2027checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x00000071006e15a0,Struct20::rtti2,92,_ZNK4ksys3dmg8Struct2018getRuntimeTypeInfoEv +0x00000071006e15fc,j__ZdlPv_299,4,_ZN4ksys3dmg8Struct20D0Ev +0x00000071006e1600,Struct20::m4,20,_ZN4ksys3dmg8Struct205resetEv 0x00000071006e1614,sub_71006E1614,112, 0x00000071006e1684,sub_71006E1684,120, 0x00000071006e16fc,sub_71006E16FC,84, @@ -71591,8 +71591,8 @@ 0x0000007100d2d370,DamageMgrBase::calcMaybe,180, 0x0000007100d2d424,sub_7100D2D424,160, 0x0000007100d2d4c4,DamageMgrBase::callDamageCallbacks,152, -0x0000007100d2d55c,DamageMgrBase::addDamageCallback,80, -0x0000007100d2d5ac,DamageMgrBase::removeDamageCallback,220, +0x0000007100d2d55c,DamageMgrBase::addDamageCallback,80,_ZN4ksys3dmg17DamageManagerBase17addDamageCallbackEiPNS0_14DamageCallbackE +0x0000007100d2d5ac,DamageMgrBase::removeDamageCallback,220,_ZN4ksys3dmg17DamageManagerBase20removeDamageCallbackEPNS0_14DamageCallbackE 0x0000007100d2d688,sub_7100D2D688,20, 0x0000007100d2d69c,act::getSystemIsGetItemSelf,20, 0x0000007100d2d6b0,ActorInfoData::getGeneralLife,20, @@ -72748,7 +72748,7 @@ 0x0000007100d6d3d4,aoc2::modifyEnemyNoticeDuration,60, 0x0000007100d6d410,sub_7100D6D410,304, 0x0000007100d6d540,aoc2::shouldApplyMasterModeDamageMultiplier,6164,_ZN5uking4aoc237shouldApplyMasterModeDamageMultiplierERKN4ksys3act20ActorConstDataAccessE -0x0000007100d6ed54,aoc2::buffDamage,40, +0x0000007100d6ed54,aoc2::buffDamage,40,_ZN5uking4aoc210buffDamageERi 0x0000007100d6ed7c,aoc2::initHardModeFlag,172, 0x0000007100d6ee28,aoc2::setAocFlag2,172, 0x0000007100d6eed4,aoc2::setIsLastPlayHardMode,60, diff --git a/src/Game/DLC/aoc2.cpp b/src/Game/DLC/aoc2.cpp index 254ce9ea..ad45b388 100644 --- a/src/Game/DLC/aoc2.cpp +++ b/src/Game/DLC/aoc2.cpp @@ -2,6 +2,9 @@ namespace uking { +SEAD_ENUM_IMPL(aoc2::Flags1) +SEAD_ENUM_IMPL(aoc2::Flags2) + bool aoc2::shouldApplyMasterModeDamageMultiplier(const ksys::act::ActorConstDataAccess& accessor) { if (!accessor.hasProc()) return false; @@ -180,4 +183,11 @@ bool aoc2::rankUpEnemy(const sead::SafeString& actor_name, const ksys::map::Obje return true; } +void aoc2::buffDamage(s32& damage) { + damage = damage * 1.5f; + if (damage == 1) { + damage = 2; + } +} + } // namespace uking diff --git a/src/Game/DLC/aoc2.h b/src/Game/DLC/aoc2.h index 4e806b0c..99fb6865 100644 --- a/src/Game/DLC/aoc2.h +++ b/src/Game/DLC/aoc2.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #include "KingSystem/ActorSystem/actActorConstDataAccess.h" #include "KingSystem/Map/mapObject.h" @@ -15,15 +17,26 @@ class aoc2 { virtual ~aoc2(); public: + SEAD_ENUM(Flags1, F0, F1, F2, F3, F4, EnableLifeRegen, F7, ApplyDamageMultiplier); + SEAD_ENUM(Flags2, EnableHardMode); + void init(sead::Heap* heap); static bool shouldApplyMasterModeDamageMultiplier(const ksys::act::ActorConstDataAccess& accessor); + static void buffDamage(s32& damage); bool isTestOfStrengthShrine() const; bool rankUpEnemy(const sead::SafeString& actor_name, const ksys::map::Object& obj, const char** new_name); + + bool checkFlag1(Flags1 flag) const { return mFlags1.isOnBit(flag); } + bool checkFlag2(Flags2 flag) const { return mFlags2.isOnBit(flag); } + + u8 TEMP[0x28]; // Temp to get flag offsets correct + sead::BitFlag32 mFlags1; + sead::BitFlag32 mFlags2; }; } // namespace uking diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt index 4e59d0cc..a72504fa 100644 --- a/src/KingSystem/ActorSystem/CMakeLists.txt +++ b/src/KingSystem/ActorSystem/CMakeLists.txt @@ -31,6 +31,7 @@ target_sources(uking PRIVATE actBaseProcMgr.h actBaseProcUnit.cpp actBaseProcUnit.h + actLifeRecoveryInfo.h actInstParamPack.cpp actInstParamPack.h actTag.h diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h index 39f41064..cb33476c 100644 --- a/src/KingSystem/ActorSystem/actActor.h +++ b/src/KingSystem/ActorSystem/actActor.h @@ -6,6 +6,9 @@ namespace ksys { namespace act { +class LifeRecoverInfo; +class ActorParam; + class Actor : public BaseProc { public: Actor(); // FIXME @@ -13,9 +16,18 @@ public: SEAD_RTTI_OVERRIDE(Actor, BaseProc) + virtual LifeRecoverInfo* getLifeRecoverInfo(); + void emitBasicSigOn(); void emitBasicSigOff(); + + void nullsub_4649(); // Some kind of logging which has been excluded from the build? + + u8 TEMP1[0x3F4]; // FIXME + ActorParam* mActorParam; + u8 TEMP2[0x2C0]; // FIXME }; +KSYS_CHECK_SIZE_NX150(Actor, 0x838); } // namespace act diff --git a/src/KingSystem/ActorSystem/actActorParamMgr.h b/src/KingSystem/ActorSystem/actActorParamMgr.h index 0ae5a850..faae022a 100644 --- a/src/KingSystem/ActorSystem/actActorParamMgr.h +++ b/src/KingSystem/ActorSystem/actActorParamMgr.h @@ -10,6 +10,29 @@ class GParamList; namespace act { +// FIXME: incomplete +class ActorParam { +public: + // FIXME: incomplete + struct Data { + public: + u8 TEMP1[0xA0]; + + res::GParamList* mGParamList; + u8 TEMP2[0x18]; + void* mDamageParam; + u8 TEMP3[0x128]; + }; + KSYS_CHECK_SIZE_NX150(ActorParam::Data, 0x1F0); + + // vtable is still unknown + virtual void TEMP_VTABLE(); + + u64 TEMP; // Unknown number of fields(2+) + Data mData; +}; +KSYS_CHECK_SIZE_NX150(ActorParam, 0x200); + // FIXME: incomplete class ActorParamMgr { SEAD_SINGLETON_DISPOSER(ActorParamMgr) diff --git a/src/KingSystem/ActorSystem/actLifeRecoveryInfo.h b/src/KingSystem/ActorSystem/actLifeRecoveryInfo.h new file mode 100644 index 00000000..f382d1b9 --- /dev/null +++ b/src/KingSystem/ActorSystem/actLifeRecoveryInfo.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +#include "KingSystem/Utils/Types.h" + +namespace ksys::act { + +// FIXME: incomplete +class LifeRecoverInfo { +public: + void init(void* params); + + // Modifies extra Hp1 and Damage. (Regen?) + bool onApplyDamage(s32& damage); + + // Update flags and counter + void onApplyDamage_0(); + + void printLifeRecoverInfo(u32 life, sead::FormatFixedSafeString<128>** Output); + + f32 mCounter; + f32 mField_4; + u8 gap_8[16]; // Is this really a gap? + u32 mExtraHp1; + u32 mExtraHp2; + u32 mMaxLife; + f32 mRecoverFactor; + s32 mField_28; + f32 mField_2C; + u8 mFlags; + u8 mUnknown[7]; // Flags might just be two u32 +}; +KSYS_CHECK_SIZE_NX150(LifeRecoverInfo, 0x38); + +} // namespace ksys::act diff --git a/src/KingSystem/CMakeLists.txt b/src/KingSystem/CMakeLists.txt index 47e4a296..85f528ed 100644 --- a/src/KingSystem/CMakeLists.txt +++ b/src/KingSystem/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(ActorSystem) add_subdirectory(Ecosystem) +add_subdirectory(Damage) add_subdirectory(Framework) add_subdirectory(GameData) add_subdirectory(Map) diff --git a/src/KingSystem/Damage/CMakeLists.txt b/src/KingSystem/Damage/CMakeLists.txt new file mode 100644 index 00000000..93df54bb --- /dev/null +++ b/src/KingSystem/Damage/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(uking PRIVATE + dmgDamageCallback.h + dmgDamageInfoManager.h + dmgDamageManagerBase.h + dmgDamageManagerBase.cpp + dmgStruct20.h + dmgStruct20.cpp +) diff --git a/src/KingSystem/Damage/dmgDamageCallback.h b/src/KingSystem/Damage/dmgDamageCallback.h new file mode 100644 index 00000000..8dddac3f --- /dev/null +++ b/src/KingSystem/Damage/dmgDamageCallback.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "KingSystem/Damage/dmgDamageManagerBase.h" + +namespace ksys::dmg { + +class DamageManagerBase; + +// FIXME: incomplete +class DamageCallback { +public: + virtual ~DamageCallback() {} + virtual void call(u32* a1, s32* a2, u32* a3, u32* a4, u32* a5, u64 a6); + + DamageCallback* mPrev; + DamageCallback* mNext; + DamageManagerBase* mDamageManager; // Might be a different base class(Interface?) + u32 mEventId; +}; + +} // namespace ksys::dmg diff --git a/src/KingSystem/Damage/dmgDamageInfoManager.h b/src/KingSystem/Damage/dmgDamageInfoManager.h new file mode 100644 index 00000000..e9c0a052 --- /dev/null +++ b/src/KingSystem/Damage/dmgDamageInfoManager.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include + +#include "KingSystem/Resource/resHandle.h" + +namespace ksys::dmg { + +// FIXME: incomplete +class DamageInfoMgr { +public: + SEAD_SINGLETON_DISPOSER(DamageInfoMgr); + +public: + // FIXME: incomplete + class DamageItem { + public: + s32 mField_0; // unknown + sead::SafeArray mCanTakeDamageFromType; + }; + + u8 TEMP1[0x5F8]; // Fields + res::Handle* mReactionTable; // 0x5D0 + sead::Buffer mDamagesArray; // 0x620 +}; +// KSYS_CHECK_SIZE_NX150(DamageInfoMgr, 0x12F0); + +} // namespace ksys::dmg diff --git a/src/KingSystem/Damage/dmgDamageManagerBase.cpp b/src/KingSystem/Damage/dmgDamageManagerBase.cpp new file mode 100644 index 00000000..874770b9 --- /dev/null +++ b/src/KingSystem/Damage/dmgDamageManagerBase.cpp @@ -0,0 +1,273 @@ +#include "KingSystem/Damage/dmgDamageManagerBase.h" +#include "Game/DLC/aoc2.h" +#include "KingSystem/ActorSystem/actActor.h" +#include "KingSystem/ActorSystem/actActorConstDataAccess.h" +#include "KingSystem/ActorSystem/actActorParamMgr.h" +#include "KingSystem/ActorSystem/actLifeRecoveryInfo.h" +#include "KingSystem/Resource/GeneralParamList/resGParamListObjectGeneral.h" +#include "KingSystem/Resource/resResourceGParamList.h" + +namespace ksys::dmg { + +DamageManagerBase_UnknownBase1::DamageManagerBase_UnknownBase1(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(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->mActorParam->mData.mGParamList; + + const 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 (isPlayerClass(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 (!uking::aoc2::instance()) { + return; + } + + if (!uking::aoc2::instance()->checkFlag2(uking::aoc2::Flags2::EnableHardMode)) { + return; + } + + if (!uking::aoc2::instance()->checkFlag1(uking::aoc2::Flags1::ApplyDamageMultiplier)) { + return; + } + + act::ActorConstDataAccess acc; + act::acquireActor(getAttacker(), &acc); + if (uking::aoc2::shouldApplyMasterModeDamageMultiplier(acc)) { + uking::aoc2::buffDamage(damage); + } +} + +void DamageManagerBase::tryApplyDamageRecovery(s32& damage) { + if (!uking::aoc2::instance()) { + return; + } + + if (!uking::aoc2::instance()->checkFlag2(uking::aoc2::Flags2::EnableHardMode)) { + return; + } + + if (!uking::aoc2::instance()->checkFlag1(uking::aoc2::Flags1::EnableLifeRegen)) { + return; + } + + if (!mActor->getLifeRecoverInfo()) { + return; + } + + // Take damage from extra HP1, and modify damage. + // Returns true if damage remains? No more regen? + 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()->mDamagesArray.isBufferReady()) { + return false; + } + + DamageInfoMgr::DamageItem& item = DamageInfoMgr::instance()->mDamagesArray[idx]; + return item.mCanTakeDamageFromType[damageTypeMaybe] & 0x1; +} + +void DamageManagerBase::handleDamageForPlayer(u32* a2, u32* a3, u32* a4, u32* a5, u32* a6) { + Struct20* currentStruct = sead::DynamicCast(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 ksys::dmg diff --git a/src/KingSystem/Damage/dmgDamageManagerBase.h b/src/KingSystem/Damage/dmgDamageManagerBase.h new file mode 100644 index 00000000..faa5f473 --- /dev/null +++ b/src/KingSystem/Damage/dmgDamageManagerBase.h @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include +#include + +#include "KingSystem/ActorSystem/actBaseProcLink.h" +#include "KingSystem/Damage/dmgDamageCallback.h" +#include "KingSystem/Damage/dmgDamageInfoManager.h" +#include "KingSystem/Damage/dmgStruct20.h" + +namespace ksys::act { +class Actor; +class ActorParam; +} // namespace ksys::act + +namespace ksys::dmg { + +// FIXME: Unknown base. This base seems to handle callbacks and messaging, so maybe a shared base? +class DamageManagerBase_UnknownBase1 { +public: + DamageManagerBase_UnknownBase1(act::Actor* WeaponActor); + virtual ~DamageManagerBase_UnknownBase1() {} + + // Sturct20 for Damage receive/send? + Struct20Base* mStruct20_a = nullptr; + Struct20Base* mStruct20_b = nullptr; + + ksys::act::Actor* mActor = nullptr; + + sead::Buffer mCallbacks{}; + + // Callback status flags? + s32 mField_30 = 0; + s8 mField_34 = 0; +}; + +// FIXME: Unknown base 2. Helper functions maybe? Might also contain some of the fields from +// DamageManagerBase. +class DamageManagerBase_UnknownBase2 { +public: + virtual ~DamageManagerBase_UnknownBase2() = default; +}; + +class DamageManagerBase : public DamageManagerBase_UnknownBase1, + public DamageManagerBase_UnknownBase2 { +public: + DamageManagerBase(act::Actor* actor); + virtual ~DamageManagerBase() = default; + + SEAD_RTTI_BASE(DamageManagerBase) + + virtual u32 getDamage(); + virtual s32 getField48() { return mField_48; } + virtual s32 getMinDmg() { return mMinDmg; } + virtual s32 getField50() { return mField_50; } + virtual s32 getField54() { return mField_54; } + virtual bool checkDamageFlags() { return false; } + virtual s32 getFlags2() { return mFlags2; } + virtual void addDamageCallback(s32 eventId, DamageCallback* callback); + virtual void removeDamageCallback(DamageCallback* callback); + virtual f32 m13() { return 0.0f; } + virtual bool m14() { return false; } + virtual bool applyDamage(s32& life); + virtual bool m16() { return false; } + virtual void m17() {} + virtual s32 getNumCallbacks(); + virtual bool initCallbacks(sead::Heap* heap); + + // m20 (FIXME: incomplete) + virtual void resetDamage(); + + virtual void preDelete2() {} + virtual void m22() {} + virtual bool allocStruct20(sead::Heap* heap); + virtual void preDelete1(); + virtual s64 m25() { return 0; } + virtual s64 m26() { return 0; } + virtual s32 getPosition() { return 0; } + virtual s32 m28() { return 0; } + + //(FIXME: incomplete) + virtual s64 m29(s64 a2); + + // qword pointer? (FIXME: incomplete) + virtual s64 m30(u64 a2); + + virtual s32 m31() { return 0; } + virtual s32 m32() { return 0; } + virtual s64 m33() { return 0; } + virtual s64 tgSensorMaterialOnHitMaybe() { return 0; } + virtual s32 m35() { return 0; } + + // FIXME: incomplete. Return dummy Base Proc Link + virtual ksys::act::BaseProcLink* getAttacker(); + + // FIXME: incomplete. Same as getAttacker, but return different Actor ProcLink I assume. + virtual s64 m37(); + + virtual s32 m38() { return 0; } + + // FIXME: Incomplete. Call isSlowTimeMaybe + virtual bool isSlowTime(); + + virtual s32 m40() { return 0; } + virtual s32 m41() { return 0; } + virtual s32 m42() { return 0; } + virtual void m43() {} + virtual bool canTakeDamage(); + virtual void m45() {} + virtual void handleDamageForPlayer(u32* a2, u32* a3, u32* a4, u32* a5, u32* a6); + virtual bool addDamage(s64 a2, s32 damage, s32 df48, s32 minDmg, s32 f50, s32 f54, s32 f40); + virtual void onApplyDamage() {} + + // Something depending on damage type? + virtual s32 m49(s32 damageTypeMaybe); + + void clearCallbacks(); + void resetStuff(); + void callDamageCallbacks(u32 a2, u32* a3, s32* a4, u32* a5, u32* a6, u32* a7, u64 a8); + s64 calcMaybe(); + + inline void tryBuffDamage(s32& damage); + inline void tryApplyDamageRecovery(s32& damage); + +private: + s32 mField_40 = 0; + s32 mDamage = 0; + s32 mField_48 = 0; + s32 mMinDmg = 0; + s32 mField_50 = -1; + s32 mField_54 = -1; + s32 mFlags2 = 0; + s32 mDamageType = 0; + s32 mDamageReactionTableStuff = -1; + u8 mField_64 = 0; + bool mIsOwnedByPlayer; +}; +KSYS_CHECK_SIZE_NX150(DamageManagerBase, 0x68); + +// FIXME: Move into static helper class? +bool isPlayerClass(ksys::act::Actor* Actor); + +} // namespace ksys::dmg diff --git a/src/KingSystem/Damage/dmgStruct20.cpp b/src/KingSystem/Damage/dmgStruct20.cpp new file mode 100644 index 00000000..10c91acb --- /dev/null +++ b/src/KingSystem/Damage/dmgStruct20.cpp @@ -0,0 +1,53 @@ +#include "KingSystem/Damage/dmgStruct20.h" + +namespace ksys::dmg { + +void Struct20::reset() { + mField_8 = 0; + mField_C = 0; + mField_10 = 0; + mField_14 = -1; + mField_18 = -1; +} + +void Struct20::combineMaybe(Struct20Base* other) { + Struct20* otherStruct = sead::DynamicCast(other); + if (!otherStruct) { + return; + } + + mField_8 += otherStruct->mField_8; + mField_C += otherStruct->mField_C; + mField_10 += otherStruct->mField_10; + if (mField_18 < otherStruct->mField_18) { + mField_14 = otherStruct->mField_14; + mField_18 = otherStruct->mField_18; + } +} + +void Struct20_2::reset() { + mField_1C = 0; + mField_30 = false; + + Struct20::reset(); +} + +void Struct20_2::combineMaybe(Struct20Base* other) { + Struct20_2* otherStruct = sead::DynamicCast(other); + if (!otherStruct) { + Struct20::combineMaybe(other); + return; + } + + mField_1C |= otherStruct->mField_1C; + Struct20::combineMaybe(other); + if (mField_18 == otherStruct->mField_18 && otherStruct->mField_30) { + mField_30 = true; + mField_20 = otherStruct->mField_20; + mField_24 = otherStruct->mField_24; + mField_28 = otherStruct->mField_28; + mField_2C = otherStruct->mField_2C; + } +} + +} // namespace ksys::dmg \ No newline at end of file diff --git a/src/KingSystem/Damage/dmgStruct20.h b/src/KingSystem/Damage/dmgStruct20.h new file mode 100644 index 00000000..3bc8cb04 --- /dev/null +++ b/src/KingSystem/Damage/dmgStruct20.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +#include "KingSystem/Utils/Types.h" + +namespace ksys::dmg { + +// What exactly Struct20 is, isn't known yet. +// It is used by the Damage Managers, especially DamageManager and up, not so much in +// DamageManagerBase. It contains flags and values which seems to be returned and modified when +// handling damage. + +// TODO: Figure out exactly what Struct20 does and rename struct + variables to fit. + +class Struct20Base { + SEAD_RTTI_BASE(Struct20Base) + +public: + virtual ~Struct20Base(){}; + + virtual void reset(); + virtual void combineMaybe(Struct20Base* other); +}; + +class Struct20 : public Struct20Base { + SEAD_RTTI_OVERRIDE(Struct20, Struct20Base) + +public: + ~Struct20() override { ; } + + void reset() override; + + __attribute__((noinline)) virtual void combineMaybe(Struct20Base* other) override; + + // Unknown which fields belong in Struct20 vs Struct20Base + u32 mField_8 = 0; + u32 mField_C = 0; + s32 mField_10 = 0; + s32 mField_14 = -1; + s32 mField_18 = -1; + u32 mField_1C; // Flag of some kind +}; +KSYS_CHECK_SIZE_NX150(Struct20, 0x20); + +class Struct20_2 : public Struct20 { + SEAD_RTTI_OVERRIDE(Struct20_2, Struct20) + +public: + ~Struct20_2() override { ; } + + void reset() override; + void combineMaybe(Struct20Base* other) override; + + f32 mField_20; + f32 mField_24; + f32 mField_28; + f32 mField_2C; + bool mField_30; +}; +KSYS_CHECK_SIZE_NX150(Struct20_2, 0x38); + +} // namespace ksys::dmg