mirror of
https://github.com/zeldaret/botw
synced 2026-08-02 00:14:36 -04:00
ksys/dmg: Implementing some of DamageManagerBase. Added some temporary classes/variables used by DamageManagerBase.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <prim/seadBitFlag.h>
|
||||
#include <prim/seadEnum.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#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
|
||||
|
||||
@@ -31,6 +31,7 @@ target_sources(uking PRIVATE
|
||||
actBaseProcMgr.h
|
||||
actBaseProcUnit.cpp
|
||||
actBaseProcUnit.h
|
||||
actLifeRecoveryInfo.h
|
||||
actInstParamPack.cpp
|
||||
actInstParamPack.h
|
||||
actTag.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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
|
||||
#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
|
||||
@@ -1,5 +1,6 @@
|
||||
add_subdirectory(ActorSystem)
|
||||
add_subdirectory(Ecosystem)
|
||||
add_subdirectory(Damage)
|
||||
add_subdirectory(Framework)
|
||||
add_subdirectory(GameData)
|
||||
add_subdirectory(Map)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
target_sources(uking PRIVATE
|
||||
dmgDamageCallback.h
|
||||
dmgDamageInfoManager.h
|
||||
dmgDamageManagerBase.h
|
||||
dmgDamageManagerBase.cpp
|
||||
dmgStruct20.h
|
||||
dmgStruct20.cpp
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
#include <container/seadBuffer.h>
|
||||
#include <container/seadSafeArray.h>
|
||||
#include <heap/seadDisposer.h>
|
||||
|
||||
#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<u8, 3> mCanTakeDamageFromType;
|
||||
};
|
||||
|
||||
u8 TEMP1[0x5F8]; // Fields
|
||||
res::Handle* mReactionTable; // 0x5D0
|
||||
sead::Buffer<DamageItem> mDamagesArray; // 0x620
|
||||
};
|
||||
// KSYS_CHECK_SIZE_NX150(DamageInfoMgr, 0x12F0);
|
||||
|
||||
} // namespace ksys::dmg
|
||||
@@ -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<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 ksys::dmg
|
||||
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
#include <container/seadBuffer.h>
|
||||
#include <heap/seadExpHeap.h>
|
||||
#include <prim/seadRuntimeTypeInfo.h>
|
||||
|
||||
#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<DamageCallback*> 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
|
||||
@@ -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<Struct20>(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<Struct20_2>(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
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
#include <prim/seadRuntimeTypeInfo.h>
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user