Skip to content

Commit

Permalink
Initial commit for the develop-rando effort
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettjoecox committed Sep 18, 2024
1 parent b24fe23 commit 5900ce7
Show file tree
Hide file tree
Showing 27 changed files with 595 additions and 6 deletions.
1 change: 1 addition & 0 deletions mm/2s2h/BenGui/BenMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ void DrawEnhancementsMenu() {

void DrawCheatsMenu() {
if (UIWidgets::BeginMenu("Cheats")) {
UIWidgets::CVarCheckbox("Rando", "gRando.Enabled");
UIWidgets::CVarCheckbox("Infinite Health", "gCheats.InfiniteHealth");
UIWidgets::CVarCheckbox("Infinite Magic", "gCheats.InfiniteMagic");
UIWidgets::CVarCheckbox("Infinite Rupees", "gCheats.InfiniteRupees");
Expand Down
34 changes: 34 additions & 0 deletions mm/2s2h/BenJsonConversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,50 @@ void from_json(const json& j, DpadSaveInfo& dpadEquips) {
}
}

void to_json(json& j, const RandoSaveInfoCheck& check) {
j = json{
{ "item", check.item },
{ "eligible", check.eligible },
{ "obtained", check.obtained },
};
}

void from_json(const json& j, RandoSaveInfoCheck& check) {
j.at("item").get_to(check.item);
j.at("eligible").get_to(check.eligible);
j.at("obtained").get_to(check.obtained);
}

void to_json(json& j, const RandoSaveInfo& rando) {
j = json{
{ "checks", rando.checks },
};
}

void from_json(const json& j, RandoSaveInfo& rando) {
j.at("checks").get_to(rando.checks);
}

void to_json(json& j, const ShipSaveInfo& shipSaveInfo) {
j = json {
{ "dpadEquips", shipSaveInfo.dpadEquips },
{ "pauseSaveEntrance", shipSaveInfo.pauseSaveEntrance },
{ "saveType", shipSaveInfo.saveType },
};

if (shipSaveInfo.saveType == SAVETYPE_RANDO) {
j["rando"] = shipSaveInfo.rando;
}
}

void from_json(const json& j, ShipSaveInfo& shipSaveInfo) {
j.at("dpadEquips").get_to(shipSaveInfo.dpadEquips);
j.at("pauseSaveEntrance").get_to(shipSaveInfo.pauseSaveEntrance);
j.at("saveType").get_to(shipSaveInfo.saveType);

if (shipSaveInfo.saveType == SAVETYPE_RANDO) {
j.at("rando").get_to(shipSaveInfo.rando);
}
}

void to_json(json& j, const ItemEquips& itemEquips) {
Expand Down
2 changes: 2 additions & 0 deletions mm/2s2h/BenPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ CrowdControl* CrowdControl::Instance;
#include "2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.h"
#include "2s2h/DeveloperTools/DebugConsole.h"
#include "2s2h/DeveloperTools/DeveloperTools.h"
#include "2s2h/Rando/Rando.h"
#include "2s2h/SaveManager/SaveManager.h"

// Resource Types/Factories
Expand Down Expand Up @@ -472,6 +473,7 @@ extern "C" void InitOTR() {
BenGui::SetupGuiElements();
InitEnhancements();
InitDeveloperTools();
Rando::Init();
GfxPatcher_ApplyNecessaryAuthenticPatches();
DebugConsole_Init();

Expand Down
2 changes: 1 addition & 1 deletion mm/2s2h/CustomMessage/CustomMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern "C" {

// Not really sure what the best ID is for this, but it needs to be between 0-255
// because it's used as a u8 somewhere in the chain
static const u16 CUSTOM_MESSAGE_ID = 0x004B;
#define CUSTOM_MESSAGE_ID 0x004B

typedef enum ModId {
MOD_ID_VANILLA = 0,
Expand Down
2 changes: 1 addition & 1 deletion mm/2s2h/CustomMessage/ShipMessages.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DEFINE_MESSAGE(HELLO_WORLD, 0x00, "\x06\x00" "\xFE" "\xFF\xFF" "\xFF\xFF" "\xFF\
" - The Moon"
)
DEFINE_MESSAGE(GIVE_ITEM, 0x00, "\x02\x00" "\x0C" "\xFF\xFF" "\xFF\xFF" "\xFF\xFF" "\xFF\xFF"
"{{item}}"
"You recieved a(n) {{item}}!"
)
DEFINE_MESSAGE(GIVE_ITEM_NO_STOP, 0x00, "\x02\x00" "\x0C" "\xFF\xFF" "\xFF\xFF" "\xFF\xFF" "\xFF\xFF"
"{{item}}" "\x1C\x02\x10"
Expand Down
9 changes: 9 additions & 0 deletions mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ void GameInteractor_ExecuteOnSaveInit(s16 fileNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveInit>(fileNum);
}

void GameInteractor_ExecuteOnSaveLoad(s16 fileNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveLoad>(fileNum);
}

void GameInteractor_ExecuteBeforeEndOfCycleSave() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::BeforeEndOfCycleSave>();
}
Expand Down Expand Up @@ -331,6 +335,11 @@ void GameInteractor_ProcessEvents(Actor* actor) {
return;
}

// If the player is not on the solid ground, stop
if (!(player->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
return;
}

// If there is an event active, stop
const auto& currentEvent = GameInteractor::Instance->currentEvent;
bool shouldReturn = false;
Expand Down
5 changes: 5 additions & 0 deletions mm/2s2h/Enhancements/GameInteractor/GameInteractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ typedef enum {
GI_VB_DRAW_SLIME_BODY_ITEM,
GI_VB_ZTARGET_SPEED_CHECK,
GI_VB_GIVE_ITEM_FROM_ITEM00,
GI_VB_GIVE_ITEM_FROM_SCRIPT,
GI_VB_GIVE_ITEM_FROM_CHEST,
GI_VB_GIVE_ITEM_FROM_GURUGURU,
} GIVanillaBehavior;

typedef enum {
Expand Down Expand Up @@ -312,6 +315,7 @@ class GameInteractor {
DEFINE_HOOK(BeforeKaleidoDrawPage, (PauseContext * pauseCtx, u16 pauseIndex));
DEFINE_HOOK(AfterKaleidoDrawPage, (PauseContext * pauseCtx, u16 pauseIndex));
DEFINE_HOOK(OnSaveInit, (s16 fileNum));
DEFINE_HOOK(OnSaveLoad, (s16 fileNum));
DEFINE_HOOK(BeforeEndOfCycleSave, ());
DEFINE_HOOK(AfterEndOfCycleSave, ());
DEFINE_HOOK(BeforeMoonCrashSaveReset, ());
Expand Down Expand Up @@ -363,6 +367,7 @@ void GameInteractor_ExecuteOnKaleidoUpdate(PauseContext* pauseCtx);
void GameInteractor_ExecuteBeforeKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex);
void GameInteractor_ExecuteAfterKaleidoDrawPage(PauseContext* pauseCtx, u16 pauseIndex);
void GameInteractor_ExecuteOnSaveInit(s16 fileNum);
void GameInteractor_ExecuteOnSaveLoad(s16 fileNum);
void GameInteractor_ExecuteBeforeEndOfCycleSave();
void GameInteractor_ExecuteAfterEndOfCycleSave();
void GameInteractor_ExecuteBeforeMoonCrashSaveReset();
Expand Down
7 changes: 7 additions & 0 deletions mm/2s2h/Rando/ActorBehavior/ActorBehavior.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "ActorBehavior.h"

void Rando::InitActorBehavior(bool isRando) {
ActorBehavior::InitEnBoxBehavior(isRando);
ActorBehavior::InitEnElforgBehavior(isRando);
ActorBehavior::InitEnItem00Behavior(isRando);
}
20 changes: 20 additions & 0 deletions mm/2s2h/Rando/ActorBehavior/ActorBehavior.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef RANDO_ACTOR_BEHAVIOR_H
#define RANDO_ACTOR_BEHAVIOR_H

#include "Rando/Rando.h"

namespace Rando {

void InitActorBehavior(bool isRando);

namespace ActorBehavior {

void InitEnBoxBehavior(bool isRando);
void InitEnElforgBehavior(bool isRando);
void InitEnItem00Behavior(bool isRando);

} // namespace ActorBehavior

} // namespace Rando

#endif
43 changes: 43 additions & 0 deletions mm/2s2h/Rando/ActorBehavior/EnBox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "ActorBehavior.h"
#include <libultraship/libultraship.h>

extern "C" {
#include "variables.h"

s32 func_80832558(PlayState* play, Player* player, PlayerFuncD58 arg2);
void Player_SetAction_PreserveMoveFlags(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 arg3);
void Player_StopCutscene(Player* player);
void func_80848294(PlayState* play, Player* player);
}

void Player_Action_65_override(Player* player, PlayState* play) {
if (PlayerAnimation_Update(play, &player->skelAnime)) {
Player_StopCutscene(player);
func_80848294(play, player);
}
}

void func_80837C78_override(PlayState* play, Player* player) {
Player_SetAction_PreserveMoveFlags(play, player, Player_Action_65_override, 0);
player->stateFlags1 |= (PLAYER_STATE1_400 | PLAYER_STATE1_20000000);
}

// This simply prevents the player from getting an item from the chest, but still
// plays the chest opening animation and ensure the treasure chest flag is set
void Rando::ActorBehavior::InitEnBoxBehavior(bool isRando) {
static uint32_t shouldHookId = 0;
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::ShouldVanillaBehavior>(shouldHookId);

shouldHookId = 0;

if (!isRando) {
return;
}

shouldHookId = REGISTER_VB_SHOULD(GI_VB_GIVE_ITEM_FROM_CHEST, {
EnBox* enBox = static_cast<EnBox*>(opt);
Player* player = GET_PLAYER(gPlayState);
func_80832558(gPlayState, player, func_80837C78_override);
*should = false;
});
}
63 changes: 63 additions & 0 deletions mm/2s2h/Rando/ActorBehavior/EnElforg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "ActorBehavior.h"
#include <libultraship/libultraship.h>

extern "C" {
#include "variables.h"
#include "functions.h"
#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h"

void EnElforg_SpawnSparkles(EnElforg* thisx, PlayState* play, s32 life);
}

void EnElforg_DrawCustom(Actor* thisx, PlayState* play) {
EnElforg* enElforg = (EnElforg*)thisx;
Matrix_Scale(20.0f, 20.0f, 20.0f, MTXMODE_APPLY);
RandoCheck check = RC_UNKNOWN;

if (STRAY_FAIRY_TYPE(thisx) == STRAY_FAIRY_TYPE_CLOCK_TOWN) {
check = RC_CLOCK_TOWN_STRAY_FAIRY;
} else if (STRAY_FAIRY_TYPE(&enElforg->actor) == STRAY_FAIRY_TYPE_COLLECTIBLE) {
auto checkData = Rando::StaticData::GetCheckFromFlag(FLAG_CYCL_SCENE_COLLECTIBLE,
STRAY_FAIRY_GET_FLAG(&enElforg->actor), play->sceneId);
check = checkData.check;
} else if (STRAY_FAIRY_TYPE(&enElforg->actor) == STRAY_FAIRY_TYPE_FREE_FLOATING) {
auto checkData = Rando::StaticData::GetCheckFromFlag(FLAG_CYCL_SCENE_SWITCH,
STRAY_FAIRY_GET_FLAG(&enElforg->actor), play->sceneId);
check = checkData.check;
}

if (check == RC_UNKNOWN) {
return;
}

auto checkSaveData = gSaveContext.save.shipSaveInfo.rando.checks[check];

EnElforg_SpawnSparkles(enElforg, play, 16);
thisx->shape.rot.y = thisx->shape.rot.y + 960;

GetItem_Draw(play, Rando::StaticData::Items[checkSaveData.item].drawId);
}

void Rando::ActorBehavior::InitEnElforgBehavior(bool isRando) {
static uint32_t onActorInitHookId = 0;
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorInit>(onActorInitHookId);

onActorInitHookId = 0;

if (!isRando) {
return;
}

onActorInitHookId =
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_EN_ELFORG, [](Actor* actor) {
EnElforg* enElforg = (EnElforg*)actor;

// Currently this will override the draw of all stray fairies, but we should probably add a check for the
// ones we support until we capture all of them in the Checks static data.
if (STRAY_FAIRY_TYPE(&enElforg->actor) == STRAY_FAIRY_TYPE_CLOCK_TOWN ||
STRAY_FAIRY_TYPE(&enElforg->actor) == STRAY_FAIRY_TYPE_FREE_FLOATING ||
STRAY_FAIRY_TYPE(&enElforg->actor) == STRAY_FAIRY_TYPE_COLLECTIBLE) {
enElforg->actor.draw = EnElforg_DrawCustom;
}
});
}
74 changes: 74 additions & 0 deletions mm/2s2h/Rando/ActorBehavior/EnItem00.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "ActorBehavior.h"
#include <libultraship/libultraship.h>

extern "C" {
#include "functions.h"
#include "variables.h"
}

void EnItem00_DrawCustomForFreestanding(Actor* thisx, PlayState* play) {
EnItem00* enItem00 = (EnItem00*)thisx;
Matrix_Scale(20.0f, 20.0f, 20.0f, MTXMODE_APPLY);

auto checkData = Rando::StaticData::GetCheckFromFlag(FLAG_CYCL_SCENE_COLLECTIBLE, enItem00->collectibleFlag,
gPlayState->sceneId);
if (checkData.check == RC_UNKNOWN) {
return;
}

auto checkSaveData = gSaveContext.save.shipSaveInfo.rando.checks[checkData.check];

GetItem_Draw(play, Rando::StaticData::Items[checkSaveData.item].drawId);
}

void Rando::ActorBehavior::InitEnItem00Behavior(bool isRando) {
static uint32_t onActorInitHookId = 0;
static uint32_t shouldHookId = 0;
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorInit>(onActorInitHookId);
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::ShouldVanillaBehavior>(shouldHookId);

onActorInitHookId = 0;
shouldHookId = 0;

if (!isRando) {
return;
}

onActorInitHookId =
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_EN_ITEM00, [](Actor* actor) {
EnItem00* item00 = (EnItem00*)actor;

// If it's one of our items ignore it
if (item00->actor.params == ITEM00_NOTHING || item00->actor.params == (ITEM00_NOTHING | 0x8000)) {
return;
}

auto checkData = Rando::StaticData::GetCheckFromFlag(FLAG_CYCL_SCENE_COLLECTIBLE, item00->collectibleFlag,
gPlayState->sceneId);
if (checkData.check == RC_UNKNOWN) {
return;
}

auto checkSaveData = gSaveContext.save.shipSaveInfo.rando.checks[checkData.check];

if (checkSaveData.obtained) {
Actor_Kill(&item00->actor);
return;
}

actor->draw = EnItem00_DrawCustomForFreestanding;
});

shouldHookId = REGISTER_VB_SHOULD(GI_VB_GIVE_ITEM_FROM_ITEM00, {
EnItem00* item00 = static_cast<EnItem00*>(opt);

// If it's one of our items ignore it
if (item00->actor.params == ITEM00_NOTHING || item00->actor.params == (ITEM00_NOTHING | 0x8000)) {
return;
}

Flags_SetCollectible(gPlayState, item00->collectibleFlag);
Actor_Kill(&item00->actor);
*should = false;
});
}
Loading

0 comments on commit 5900ce7

Please sign in to comment.