aoc2: Fix the struct and implement more functions

This commit is contained in:
Léo Lam
2020-11-06 23:57:01 +01:00
parent f918d1f805
commit f60734bded
8 changed files with 175 additions and 48 deletions
+86 -2
View File
@@ -1,9 +1,78 @@
#include "Game/DLC/aoc2.h"
#include <math/seadMathCalcCommon.h>
#include "KingSystem/Utils/InitTimeInfo.h"
namespace uking {
SEAD_ENUM_IMPL(aoc2::Flags1)
SEAD_ENUM_IMPL(aoc2::Flags2)
SEAD_ENUM_IMPL(aoc2::HardModeChange)
SEAD_ENUM_IMPL(aoc2::Flag)
SEAD_ENUM_IMPL(aoc2::MultiplierType)
SEAD_SINGLETON_DISPOSER_IMPL(aoc2)
namespace {
struct aoc2StaticData {
ksys::util::InitConstants init_constants;
sead::SafeString flag_name_HardMode_HighScore{"HardMode_HighScore"};
sead::SafeString flag_name_AoC_HardMode_Enabled{"AoC_HardMode_Enabled"};
sead::SafeString flag_name_IsLastPlayHardMode{"IsLastPlayHardMode"};
};
aoc2StaticData sData;
sead::FixedSafeString<64> sStr{""};
} // namespace
aoc2::aoc2()
: mGdtResetSlot{sead::Delegate1<aoc2, ksys::gdt::Manager::ResetEvent*>(
this, &aoc2::setHardModeEnabledFlag)},
mGdtReinitSlot{
sead::Delegate1<aoc2, ksys::gdt::Manager::ReinitEvent*>(this, &aoc2::initFlagHandles)} {
mMultipliers.fill(0.5);
setHardModeChange(HardModeChange::IsLastPlayHardMode, true);
setHardModeChange(HardModeChange::EnableShorterEnemyNotice, true);
setHardModeChange(HardModeChange::EnableLifeRegen, true);
setHardModeChange(HardModeChange::DisableNoDeathDamage, true);
setHardModeChange(HardModeChange::PatchGanonStunLock, true);
setHardModeChange(HardModeChange::RandomizeGuardianChargeBeam, true);
setHardModeChange(HardModeChange::ApplyDamageMultiplier, true);
}
void aoc2::initFlagHandles(ksys::gdt::Manager::ReinitEvent*) {
auto* gdm = ksys::gdt::Manager::instance();
mHardModeHighScoreFlag = gdm->getS32Handle(sData.flag_name_HardMode_HighScore);
mAoCHardModeEnabledFlag = gdm->getS32Handle(sData.flag_name_AoC_HardMode_Enabled);
mIsLastPlayHardModeFlag = gdm->getS32Handle(sData.flag_name_IsLastPlayHardMode);
}
aoc2::~aoc2() {
mFileHandle.requestUnload2();
if (_120) {
// TODO: use the normal operator delete once we figure out what _120 is
::operator delete(_120);
_120 = nullptr;
}
}
void aoc2::init(sead::Heap*) {
init_();
}
void aoc2::init_() {
initFlagHandles();
ksys::gdt::Manager::instance()->addReinitCallback(mGdtReinitSlot);
}
void aoc2::nerfHpRestore(f32* hp) const {
*hp = sead::Mathf::max(*hp * getMultiplier(MultiplierType::HpRestore), 1.0f);
}
void aoc2::nerfHpRestore(s32* hp) const {
*hp = sead::Mathi::max(*hp * getMultiplier(MultiplierType::HpRestore), 1);
}
void aoc2::modifyEnemyNoticeDuration(f32* value) const {
*value = sead::Mathf::max(*value * getMultiplier(MultiplierType::EnemyNoticeDuration), 0);
}
bool aoc2::shouldApplyMasterModeDamageMultiplier(const ksys::act::ActorConstDataAccess& accessor) {
if (!accessor.hasProc())
@@ -45,6 +114,21 @@ bool aoc2::shouldApplyMasterModeDamageMultiplier(const ksys::act::ActorConstData
return false;
}
bool aoc2::isTestOfStrengthShrine() const {
if (mMapType != "CDungeon")
return false;
// There are 20 ToS shrines in the base game (070-089).
if (mMapName.startsWith("Dungeon07") || mMapName.startsWith("Dungeon08"))
return true;
// Ruvo Korbah
if (mMapName == "Dungeon135")
return true;
return false;
}
bool aoc2::rankUpEnemy(const sead::SafeString& actor_name, const ksys::map::Object& obj,
const char** new_name) {
if (obj.getFlags().isOn(ksys::map::Object::Flag::HasUniqueName) ||
+36 -8
View File
@@ -5,23 +5,34 @@
#include <prim/seadEnum.h>
#include <prim/seadSafeString.h>
#include "KingSystem/ActorSystem/actActorConstDataAccess.h"
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Map/mapObject.h"
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/Utils/Types.h"
namespace uking {
// FIXME: incomplete
class aoc2 {
class aoc2 final {
SEAD_SINGLETON_DISPOSER(aoc2)
aoc2();
virtual ~aoc2();
public:
SEAD_ENUM(Flags1, F0, F1, F2, F3, F4, EnableLifeRegen, F7, ApplyDamageMultiplier);
SEAD_ENUM(Flags2, EnableHardMode);
SEAD_ENUM(HardModeChange, IsLastPlayHardMode = 0, NerfHpRestore = 1, _2 = 2,
DisableNoDeathDamage = 3, PatchGanonStunLock = 4, EnableLifeRegen = 5,
RandomizeGuardianChargeBeam = 6, ApplyDamageMultiplier = 7,
EnableShorterEnemyNotice = 8);
SEAD_ENUM(Flag, EnableHardMode = 0);
SEAD_ENUM(MultiplierType, HpRestore = 0, _1 = 1, EnemyNoticeDuration = 2)
void init(sead::Heap* heap);
void nerfHpRestore(f32* hp) const;
void nerfHpRestore(s32* hp) const;
void modifyEnemyNoticeDuration(f32* value) const;
static bool
shouldApplyMasterModeDamageMultiplier(const ksys::act::ActorConstDataAccess& accessor);
static void buffDamage(s32& damage);
@@ -31,12 +42,29 @@ public:
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); }
void setHardModeChange(HardModeChange flag, bool on) { mHardModeChanges.changeBit(flag, on); }
bool isHardModeChangeOn(HardModeChange flag) const { return mHardModeChanges.isOnBit(flag); }
bool checkFlag(Flag flag) const { return mFlags.isOnBit(flag); }
f32 getMultiplier(MultiplierType type) const { return mMultipliers[type]; }
u8 TEMP[0x28]; // Temp to get flag offsets correct
sead::BitFlag32 mFlags1;
sead::BitFlag32 mFlags2;
private:
void setHardModeEnabledFlag(ksys::gdt::Manager::ResetEvent* event = nullptr);
void initFlagHandles(ksys::gdt::Manager::ReinitEvent* event = nullptr);
void init_();
sead::BitFlag32 mHardModeChanges;
sead::BitFlag32 mFlags;
sead::SafeArray<f32, 3> mMultipliers;
ksys::gdt::Manager::ResetSignal::Slot mGdtResetSlot;
ksys::gdt::Manager::ReinitSignal::Slot mGdtReinitSlot;
void* _120 = nullptr;
ksys::res::Handle mFileHandle;
ksys::gdt::FlagHandle mHardModeHighScoreFlag = ksys::gdt::InvalidHandle;
ksys::gdt::FlagHandle mAoCHardModeEnabledFlag = ksys::gdt::InvalidHandle;
ksys::gdt::FlagHandle mIsLastPlayHardModeFlag = ksys::gdt::InvalidHandle;
sead::FixedSafeString<256> mMapType;
sead::FixedSafeString<256> mMapName;
};
KSYS_CHECK_SIZE_NX150(aoc2, 0x3b8);
} // namespace uking
@@ -139,11 +139,12 @@ void DamageManagerBase::tryBuffDamage(s32& damage) {
return;
}
if (!uking::aoc2::instance()->checkFlag2(uking::aoc2::Flags2::EnableHardMode)) {
if (!uking::aoc2::instance()->checkFlag(uking::aoc2::Flag::EnableHardMode)) {
return;
}
if (!uking::aoc2::instance()->checkFlag1(uking::aoc2::Flags1::ApplyDamageMultiplier)) {
if (!uking::aoc2::instance()->isHardModeChangeOn(
uking::aoc2::HardModeChange::ApplyDamageMultiplier)) {
return;
}
@@ -159,11 +160,12 @@ void DamageManagerBase::tryApplyDamageRecovery(s32& damage) {
return;
}
if (!uking::aoc2::instance()->checkFlag2(uking::aoc2::Flags2::EnableHardMode)) {
if (!uking::aoc2::instance()->checkFlag(uking::aoc2::Flag::EnableHardMode)) {
return;
}
if (!uking::aoc2::instance()->checkFlag1(uking::aoc2::Flags1::EnableLifeRegen)) {
if (!uking::aoc2::instance()->isHardModeChangeOn(
uking::aoc2::HardModeChange::EnableLifeRegen)) {
return;
}
+4
View File
@@ -132,4 +132,8 @@ void Manager::unloadResources() {
mGameDataArcHandle.requestUnload();
}
void Manager::addReinitCallback(sead::DelegateEvent<ReinitEvent*>::Slot&) {
// Stubbed in release builds.
}
} // namespace ksys::gdt
+2
View File
@@ -199,6 +199,8 @@ public:
void init(sead::Heap* heap, sead::Framework* framework);
void addReinitCallback(ReinitSignal::Slot& slot);
private:
enum class BitFlag {
_1 = 0x1,
+13 -7
View File
@@ -21,22 +21,28 @@ private:
};
KSYS_CHECK_SIZE_NX150(InitTimeInfo, 0x10);
class InitTimeInfoEx {
public:
explicit InitTimeInfoEx(sead::TickTime start_time = {}) : mInfo(start_time) {
struct InitConstants {
InitConstants() {
_0 = 0;
_4 = 0x8004EF;
}
u32 getField0() const { return _0; }
u32 getField4() const { return _4; }
u32 _0;
u32 _4;
};
class InitTimeInfoEx {
public:
explicit InitTimeInfoEx(sead::TickTime start_time = {}) : mInfo(start_time) {
mConstants._0 = 0;
mConstants._4 = 0x8004EF;
}
InitTimeInfo& getInfo() { return mInfo; }
const InitTimeInfo& getInfo() const { return mInfo; }
private:
u32 _0 = 0;
u32 _4 = 0;
InitConstants mConstants;
InitTimeInfo mInfo;
};
KSYS_CHECK_SIZE_NX150(InitTimeInfoEx, 0x18);