Implemented Unleash gauge hooks

- Implements "Unleash Cancel" to allow cancelling Unleash after activating it.
- Implements out of control fixes to prevent the gauge from draining when the player cannot utilise it.
This commit is contained in:
Hyper 2024-10-20 02:54:49 +01:00
parent bdfa5e874f
commit dd74392279
9 changed files with 77 additions and 2 deletions

View file

@ -1,6 +1,7 @@
#pragma once
#include "SWA/Camera/Camera.h"
#include "SWA/Player/Character/EvilSonic/EvilSonic.h"
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
#include "SWA/System/ApplicationDocument.h"
#include "SWA/System/GameDocument.h"

View file

@ -0,0 +1,14 @@
#pragma once
#include "SWA.inl"
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
namespace SWA::Player
{
class CEvilSonic
{
public:
SWA_INSERT_PADDING(0xC4);
xpointer<CEvilSonicContext> m_spContext;
};
}

View file

@ -11,5 +11,7 @@ namespace SWA::Player
be<float> m_DarkGaiaEnergy;
SWA_INSERT_PADDING(0x138);
be<uint32_t> m_AnimationID;
SWA_INSERT_PADDING(0x104);
be<uint32_t> m_OutOfControlCount;
};
}

View file

@ -9,6 +9,7 @@ void Config::Load()
TOML_READ_ENUM(ELanguage, Language);
TOML_READ_ENUM(EScoreBehaviour, ScoreBehaviour);
TOML_READ_BOOLEAN(Hints);
TOML_READ_BOOLEAN(UnleashOutOfControlDrain);
TOML_READ_BOOLEAN(WerehogHubTransformVideo);
}
TOML_END_SECTION();

View file

@ -50,6 +50,7 @@ public:
inline static ELanguage Language = ELanguage_English;
inline static EScoreBehaviour ScoreBehaviour = EScoreBehaviour_CheckpointReset;
inline static bool Hints = true;
inline static bool UnleashOutOfControlDrain = true;
inline static bool WerehogHubTransformVideo = true;
// Controls

View file

@ -8,6 +8,10 @@ const char* m_pStageID;
uint32_t m_lastCheckpointScore = 0;
float m_lastDarkGaiaEnergy = 0.0f;
bool m_isUnleashCancelled = false;
#pragma region Aspect Ratio Hooks
bool CameraAspectRatioMidAsmHook(PPCRegister& r31)
@ -145,6 +149,51 @@ PPC_FUNC(sub_824DCF38)
#pragma endregion
#pragma region Player Hooks
// Dark Gaia energy change hook.
PPC_FUNC_IMPL(__imp__sub_823AF7A8);
PPC_FUNC(sub_823AF7A8)
{
auto pEvilSonicContext = (SWA::Player::CEvilSonicContext*)g_memory.Translate(ctx.r3.u32);
m_lastDarkGaiaEnergy = pEvilSonicContext->m_DarkGaiaEnergy;
// Don't drain energy if out of control.
if (!Config::UnleashOutOfControlDrain && pEvilSonicContext->m_OutOfControlCount && ctx.f1.f64 < 0.0)
return;
__imp__sub_823AF7A8(ctx, base);
if (!Config::UnleashCancel)
return;
auto pInputState = SWA::CInputState::GetInstance();
// Don't allow cancelling Unleash if the intro anim is still playing.
if (!pInputState || pEvilSonicContext->m_AnimationID == 39)
return;
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_RightBumper))
{
pEvilSonicContext->m_DarkGaiaEnergy = 0.0f;
m_isUnleashCancelled = true;
}
}
void PostUnleashMidAsmHook(PPCRegister& r30)
{
if (m_isUnleashCancelled)
{
if (auto pEvilSonicContext = (SWA::Player::CEvilSonicContext*)g_memory.Translate(r30.u32))
pEvilSonicContext->m_DarkGaiaEnergy = m_lastDarkGaiaEnergy;
m_isUnleashCancelled = false;
}
}
#pragma endregion
#pragma region Miscellaneous Hooks
bool DisableHintsMidAsmHook()

View file

@ -1,5 +1,6 @@
#pragma once
#include "Mutex.h"
#include "mutex.h"
#include <o1heap.h>
struct Heap

View file

@ -4,6 +4,7 @@ Language = 1 # The language displayed by the game.
ScoreBehaviour = 0 # Determines how the score behaves when restarting at a checkpoint.
# Reset to zero = 0; Reset to last checkpoint score = 1.
Hints = true # Determines whether to spawn hint rings and volumes.
UnleashOutOfControlDrain = true # Determines whether to drain Dark Gaia energy whilst the player cannot move.
WerehogHubTransformVideo = true # Determines whether to play the transition video for switching time of day in the hub areas.
# Setting this to false will instead play a generic transition without artificial loading times.

View file

@ -192,4 +192,9 @@ registers = ["f1"]
[[midasm_hook]]
name = "GetStageIDMidAsmHook"
address = 0x82528198
registers = ["r5"]
registers = ["r5"]
[[midasm_hook]]
name = "PostUnleashMidAsmHook"
address = 0x823C6788
registers = ["r30"]