Skip to content

Commit

Permalink
Add death feature in player menu
Browse files Browse the repository at this point in the history
  • Loading branch information
UltiNaruto committed Dec 5, 2023
1 parent ad195e4 commit 83934b2
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/prime/CFirstPersonCamera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ class CFirstPersonCameraMP1 : public CGameCameraMP1 {

class CCameraManagerMP1 {
public:
inline bool IsInCinematicCamera()
{
// camera count
if(*GetField<int>(this, 0x8) != 0) {
return true;
}
return *GetField<int>(this, 0x18) != 0;
}
static float GetDefaultFirstPersonVerticalFOV();
};

Expand Down
11 changes: 11 additions & 0 deletions src/prime/CGameState.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include "CObjectId.hpp"
#include "prime/CFirstPersonCamera.hpp"
#include "prime/CWorldMP1.hpp"
#include "program/GetField.hpp"
#include "types.h"

Expand Down Expand Up @@ -89,6 +91,12 @@ class CStateManager {
inline CStateManagerGameLogicMP1* GameLogic() {
return GetField<CStateManagerGameLogicMP1>(this, 0x4e0150);
}
inline CCameraManagerMP1* GetCameraManager() {
auto* ptr = reinterpret_cast<size_t*>(reinterpret_cast<size_t>(this) + 0x4e0150);
if (ptr != nullptr)
return *reinterpret_cast<CCameraManagerMP1**>(reinterpret_cast<size_t>(*ptr) + 0x30);
return nullptr;
}
};

class CStateManagerUpdateAccess;
Expand All @@ -110,4 +118,7 @@ class CStateManagerGameLogicMP1 {
static CPlayerStateMP1* PlayerState();
CPlayerMP1* PlayerActor();
void SetGameState(EGameState state);

inline CWorldMP1* GetWorld() { return *GetField<CWorldMP1*>(this, 0x20); }
inline CCameraManagerMP1* GetCameraManager() { return *GetField<CCameraManagerMP1*>(this, 0x30); }
};
4 changes: 4 additions & 0 deletions src/prime/CPlayerStateMP1.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

class CStateManager;

class CPowerUp {
public:
int amount;
Expand Down Expand Up @@ -60,8 +62,10 @@ class CPlayerStateMP1 {
void SetPowerUp(EItemType type, int amount);
int GetPowerUp(EItemType type);
int GetItemCapacity(EItemType type) const;
void Kill(CStateManager&);

inline CPowerUp* GetPowerups() { return reinterpret_cast<CPowerUp*>(reinterpret_cast<size_t>(this) + 0x44); }
inline bool IsPlayerAlive() { return (*reinterpret_cast<u8*>(this) & 1) == 1; }

static int GetItemMax(EItemType type);
// _ZN15CPlayerStateMP110GetItemMaxE9EItemType
Expand Down
9 changes: 9 additions & 0 deletions src/prime/CWorldMP1.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "program/GetField.hpp"
#include "types.h"

class CWorldMP1 {
public:
inline int32_t GetLoadPhase() { return *GetField<int32_t>(this, 8); }
};
8 changes: 8 additions & 0 deletions src/program/PlayerMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ namespace GUI {
// u32 savedWorldAssetID{0};
// u32 savedAreaAssetID{0};

bool isInCutscene = true;
bool alive = false;
bool kill = false;
int32_t loadPhase = -1;

void drawPlayerMenu() {
// CStateManager *stateManager = mostRecentStateManager;
// if (stateManager == nullptr) return;
Expand Down Expand Up @@ -124,6 +129,9 @@ namespace GUI {
// player->setFluidCounter((u32) fluidCounter);
// }
// ImGui::DragFloat("Water depth", player->getDepthUnderWater(), 1.f, -FLT_MAX, FLT_MAX, "%.3f", flags);
if (!isInCutscene && loadPhase == 4 && ImGui::Button("Death")) {
kill = alive;
}

ImGui::TreePop();
}
Expand Down
6 changes: 6 additions & 0 deletions src/program/PlayerMenu.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "prime/Math.hpp"
#include "types.h"

namespace GUI {
extern bool hasDesiredPositionData;
Expand All @@ -17,6 +18,11 @@ namespace GUI {

extern double desiredTime;

extern bool isInCutscene;
extern bool alive;
extern bool kill;
extern int32_t loadPhase;

void drawPlayerMenu();
void savePos();
void loadPos();
Expand Down
24 changes: 23 additions & 1 deletion src/program/patches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ HOOK_DEFINE_INLINE(CheckFloatVar) {
HOOK_DEFINE_TRAMPOLINE(CPlayerMP1_ProcessInput) {
static void Callback(CPlayerMP1 *thiz, const CFinalInput &input, CStateManager &stateManager) {
mostRecentStateManager = &stateManager;

auto *gameState = stateManager.GameState();
GUI::igt = gameState->GetPlayTime();

GUI::moveState = thiz->GetMoveState();
GUI::bombJumpState = thiz->GetMorphBall()->GetBombJumpState();
GUI::isInHalfPipeMode = thiz->GetMorphBall()->GetIsInHalfPipeMode();
Expand Down Expand Up @@ -161,6 +161,11 @@ HOOK_DEFINE_TRAMPOLINE(CPlayerMP1_ProcessInput) {
int etanks = CStateManagerGameLogicMP1::PlayerState()->GetItemCapacity(CPlayerStateMP1::EItemType::EnergyTanks);
thiz->HealthInfo(stateManager).heatlh = (float)etanks * 100.0f + 99.0f;
}

if (GUI::kill) {
CStateManagerGameLogicMP1::PlayerState()->Kill(stateManager);
GUI::kill = false;
}
}
};

Expand Down Expand Up @@ -209,6 +214,17 @@ HOOK_DEFINE_TRAMPOLINE(NTonemap_build_tonemap_eval_params){

HOOK_DEFINE_TRAMPOLINE(CStateManagerGameLogicMP1_GameMainLoop){
static void Callback(CStateManagerGameLogicMP1 *self, CStateManager &mgr, CStateManagerUpdateAccess &mgrUpdAcc, float dt) {
auto *playerState = CStateManagerGameLogicMP1::PlayerState();
auto *cameraManager = self->GetCameraManager();
auto *world = self->GetWorld();

// Consider not alive when loading game
GUI::alive = false;
// Consider in cutscene when loading game
GUI::isInCutscene = true;
// set by default to undefined
GUI::loadPhase = -1;

if(PATCH_CONFIG.enable_stop_time) {
if ((InputHelper::isHoldLeftStick() && InputHelper::isPressL()) || (InputHelper::isPressLeftStick() && InputHelper::isHoldL())) {
const auto new_state = GUI::is_time_stopped ? CStateManagerGameLogicMP1::EGameState::Running
Expand All @@ -219,6 +235,12 @@ HOOK_DEFINE_TRAMPOLINE(CStateManagerGameLogicMP1_GameMainLoop){
self->PlayerActor()->BreakOrbit((CPlayerMP1::EOrbitBrokenType)1, mgr);
}
}
} else {
if(playerState != nullptr && cameraManager != nullptr && world != nullptr) {
GUI::alive = playerState->IsPlayerAlive();
GUI::isInCutscene = !GUI::alive ? true : cameraManager->IsInCinematicCamera();
GUI::loadPhase = !GUI::alive ? -1 : world->GetLoadPhase();
}
}

Orig(self, mgr, mgrUpdAcc, dt);
Expand Down

0 comments on commit 83934b2

Please sign in to comment.