Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add death feature in player menu #6

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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