Migrate ganon trials

This commit is contained in:
Garrett Cox 2024-04-18 20:42:25 -05:00
parent 54b1505137
commit edf6d9334a
10 changed files with 48 additions and 131 deletions

View File

@ -358,13 +358,6 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" },
{ RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" },
{ RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" },
{ RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" },
{ RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" },
{ RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" },
{ RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" },
{ RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" },
{ RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" }, { RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" },
{ RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" }, { RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" },
{ RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" }, { RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" },

View File

@ -107,6 +107,15 @@ bool MeetsLACSRequirements() {
return false; return false;
} }
bool CompletedAllTrials() {
return Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_WATER_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_LIGHT_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FIRE_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SHADOW_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SPIRIT_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL);
}
// Todo Move this to randomizer context, clear it out on save load etc // Todo Move this to randomizer context, clear it out on save load etc
static std::queue<RandomizerCheck> randomizerQueuedChecks; static std::queue<RandomizerCheck> randomizerQueuedChecks;
static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK;
@ -1307,6 +1316,12 @@ void RandomizerOnActorInitHandler(void* actorRef) {
enGe1->actionFunc = (EnGe1ActionFunc)EnGe1_SetNormalText; enGe1->actionFunc = (EnGe1ActionFunc)EnGe1_SetNormalText;
} }
} }
if (actor->id == ACTOR_DEMO_KEKKAI && actor->params == 0) { // 0 == KEKKAI_TOWER
if (CompletedAllTrials()) {
Actor_Kill(actor);
}
}
} }
void RandomizerRegisterHooks() { void RandomizerRegisterHooks() {

View File

@ -164,21 +164,6 @@ Randomizer::Randomizer() {
Randomizer::~Randomizer() { Randomizer::~Randomizer() {
} }
std::unordered_map<std::string, RandomizerInf> spoilerFileTrialToEnum = {
{ "the Forest Trial", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
{ "l'épreuve de la Forêt", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
{ "the Fire Trial", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
{ "l'épreuve du Feu", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
{ "the Water Trial", RAND_INF_TRIALS_DONE_WATER_TRIAL },
{ "l'épreuve de l'Eau", RAND_INF_TRIALS_DONE_WATER_TRIAL },
{ "the Spirit Trial", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
{ "l'épreuve de l'Esprit", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
{ "the Shadow Trial", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
{ "l'épreuve de l'Ombre", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
{ "the Light Trial", RAND_INF_TRIALS_DONE_LIGHT_TRIAL },
{ "l'épreuve de la Lumière", RAND_INF_TRIALS_DONE_LIGHT_TRIAL }
};
std::unordered_map<std::string, SceneID> spoilerFileDungeonToScene = { std::unordered_map<std::string, SceneID> spoilerFileDungeonToScene = {
{ "Deku Tree", SCENE_DEKU_TREE }, { "Deku Tree", SCENE_DEKU_TREE },
{ "Dodongo's Cavern", SCENE_DODONGOS_CAVERN }, { "Dodongo's Cavern", SCENE_DODONGOS_CAVERN },
@ -576,8 +561,17 @@ void Randomizer::LoadMerchantMessages() {
"\x08{{item}} {{price}} Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02")); "\x08{{item}} {{price}} Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02"));
} }
bool Randomizer::IsTrialRequired(RandomizerInf trial) { std::map<s32, Rando::TrialKey> trialFlagToTrialKey = {
return Rando::Context::GetInstance()->GetTrial(trial - RAND_INF_TRIALS_DONE_LIGHT_TRIAL)->IsRequired(); { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, Rando::TrialKey::LIGHT_TRIAL, },
{ EVENTCHKINF_COMPLETED_FOREST_TRIAL, Rando::TrialKey::FOREST_TRIAL, },
{ EVENTCHKINF_COMPLETED_FIRE_TRIAL, Rando::TrialKey::FIRE_TRIAL, },
{ EVENTCHKINF_COMPLETED_WATER_TRIAL, Rando::TrialKey::WATER_TRIAL, },
{ EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, Rando::TrialKey::SPIRIT_TRIAL, },
{ EVENTCHKINF_COMPLETED_SHADOW_TRIAL, Rando::TrialKey::SHADOW_TRIAL, }
};
bool Randomizer::IsTrialRequired(s32 trialFlag) {
return Rando::Context::GetInstance()->GetTrial(trialFlagToTrialKey[trialFlag])->IsRequired();
} }
GetItemEntry Randomizer::GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, GetItemEntry Randomizer::GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId,

View File

@ -46,7 +46,7 @@ class Randomizer {
bool SpoilerFileExists(const char* spoilerFileName); bool SpoilerFileExists(const char* spoilerFileName);
void LoadMerchantMessages(); void LoadMerchantMessages();
void LoadHintMessages(); void LoadHintMessages();
bool IsTrialRequired(RandomizerInf trial); bool IsTrialRequired(s32 trialFlag);
u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey);
RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf);
RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc); RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc);

View File

@ -10,13 +10,6 @@ typedef enum {
RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE,
RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE,
RAND_INF_TRIALS_DONE_LIGHT_TRIAL,
RAND_INF_TRIALS_DONE_FOREST_TRIAL,
RAND_INF_TRIALS_DONE_FIRE_TRIAL,
RAND_INF_TRIALS_DONE_WATER_TRIAL,
RAND_INF_TRIALS_DONE_SPIRIT_TRIAL,
RAND_INF_TRIALS_DONE_SHADOW_TRIAL,
RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW,
RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW,
RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW,

View File

@ -351,10 +351,15 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.entranceIndex = -1; gSaveContext.entranceIndex = -1;
} }
// If any trials aren't required, set them as completed for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL,
for (u16 i = RAND_INF_TRIALS_DONE_LIGHT_TRIAL; i <= RAND_INF_TRIALS_DONE_SHADOW_TRIAL; i++) { EVENTCHKINF_COMPLETED_FOREST_TRIAL,
if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired((RandomizerInf)i)) { EVENTCHKINF_COMPLETED_FIRE_TRIAL,
Flags_SetRandomizerInf((RandomizerInf)i); EVENTCHKINF_COMPLETED_WATER_TRIAL,
EVENTCHKINF_COMPLETED_SPIRIT_TRIAL,
EVENTCHKINF_COMPLETED_SHADOW_TRIAL }
) {
if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) {
Flags_SetEventChkInf(trialFlag);
} }
} }

View File

@ -2359,8 +2359,8 @@ extern "C" void Randomizer_LoadMerchantMessages() {
OTRGlobals::Instance->gRandomizer->LoadMerchantMessages(); OTRGlobals::Instance->gRandomizer->LoadMerchantMessages();
} }
extern "C" bool Randomizer_IsTrialRequired(RandomizerInf trial) { extern "C" bool Randomizer_IsTrialRequired(s32 trialFlag) {
return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trial); return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag);
} }
extern "C" u32 SpoilerFileExists(const char* spoilerFileName) { extern "C" u32 SpoilerFileExists(const char* spoilerFileName) {

View File

@ -159,7 +159,7 @@ FishIdentity Randomizer_IdentifyFish(s32 sceneNum, s32 actorParams);
void Randomizer_ParseSpoiler(const char* fileLoc); void Randomizer_ParseSpoiler(const char* fileLoc);
void Randomizer_LoadHintMessages(); void Randomizer_LoadHintMessages();
void Randomizer_LoadMerchantMessages(); void Randomizer_LoadMerchantMessages();
bool Randomizer_IsTrialRequired(RandomizerInf trial); bool Randomizer_IsTrialRequired(s32 trialFlag);
GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId); GetItemEntry Randomizer_GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId);
GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId); GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogId);
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);

View File

@ -64,66 +64,23 @@ static u8 sEnergyColors[] = {
/* Forest prim */ 255, 255, 170, /* env */ 0, 200, 0, /* Forest prim */ 255, 255, 170, /* env */ 0, 200, 0,
}; };
// Translates from the barrier's actor params to their corresponding randInf flags.
RandomizerInf trialParamToRandInf(u16 params) {
switch (params) {
case KEKKAI_LIGHT:
return RAND_INF_TRIALS_DONE_LIGHT_TRIAL;
case KEKKAI_FOREST:
return RAND_INF_TRIALS_DONE_FOREST_TRIAL;
case KEKKAI_FIRE:
return RAND_INF_TRIALS_DONE_FIRE_TRIAL;
case KEKKAI_WATER:
return RAND_INF_TRIALS_DONE_WATER_TRIAL;
case KEKKAI_SPIRIT:
return RAND_INF_TRIALS_DONE_SPIRIT_TRIAL;
case KEKKAI_SHADOW:
return RAND_INF_TRIALS_DONE_SHADOW_TRIAL;
}
}
s32 DemoKekkai_CheckEventFlag(s32 params) { s32 DemoKekkai_CheckEventFlag(s32 params) {
static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB }; static s32 eventFlags[] = {
EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER,
EVENTCHKINF_COMPLETED_WATER_TRIAL,
EVENTCHKINF_COMPLETED_LIGHT_TRIAL,
EVENTCHKINF_COMPLETED_FIRE_TRIAL,
EVENTCHKINF_COMPLETED_SHADOW_TRIAL,
EVENTCHKINF_COMPLETED_SPIRIT_TRIAL,
EVENTCHKINF_COMPLETED_FOREST_TRIAL,
};
if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) { if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) {
return true; return true;
} }
if (IS_RANDO && params > KEKKAI_TOWER) {
return Flags_GetRandomizerInf(trialParamToRandInf(params));
}
return Flags_GetEventChkInf(eventFlags[params]); return Flags_GetEventChkInf(eventFlags[params]);
} }
u32 TrialsDoneCount() {
u8 trialCount = 0;
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) {
trialCount++;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) {
trialCount++;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) {
trialCount++;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) {
trialCount++;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) {
trialCount++;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) {
trialCount++;
}
return trialCount;
}
void DemoKekkai_Init(Actor* thisx, PlayState* play) { void DemoKekkai_Init(Actor* thisx, PlayState* play) {
s32 pad; s32 pad;
DemoKekkai* this = (DemoKekkai*)thisx; DemoKekkai* this = (DemoKekkai*)thisx;
@ -147,13 +104,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) {
this->collider2.dim.radius = thisx->scale.x * 6100.0f; this->collider2.dim.radius = thisx->scale.x * 6100.0f;
this->collider2.dim.height = thisx->scale.y * 5000.0f; this->collider2.dim.height = thisx->scale.y * 5000.0f;
this->collider2.dim.yShift = 300; this->collider2.dim.yShift = 300;
if (IS_RANDO) {
if (TrialsDoneCount() == NUM_TRIALS) {
Actor_Kill(thisx);
return;
}
}
break; break;
case KEKKAI_WATER: case KEKKAI_WATER:
case KEKKAI_LIGHT: case KEKKAI_LIGHT:
@ -161,10 +111,6 @@ void DemoKekkai_Init(Actor* thisx, PlayState* play) {
case KEKKAI_SHADOW: case KEKKAI_SHADOW:
case KEKKAI_SPIRIT: case KEKKAI_SPIRIT:
case KEKKAI_FOREST: case KEKKAI_FOREST:
if (IS_RANDO && Flags_GetRandomizerInf(trialParamToRandInf(thisx->params))) {
Actor_Kill(thisx);
return;
}
this->energyAlpha = 1.0f; this->energyAlpha = 1.0f;
this->orbScale = 1.0f; this->orbScale = 1.0f;
Actor_SetScale(thisx, 0.1f); Actor_SetScale(thisx, 0.1f);
@ -265,18 +211,10 @@ void DemoKekkai_Update(Actor* thisx, PlayState* play2) {
} }
void DemoKekkai_TrialBarrierDispel(Actor* thisx, PlayState* play) { void DemoKekkai_TrialBarrierDispel(Actor* thisx, PlayState* play) {
static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB };
static u16 csFrames[] = { 0, 280, 280, 280, 280, 280, 280 }; static u16 csFrames[] = { 0, 280, 280, 280, 280, 280, 280 };
s32 pad; s32 pad;
DemoKekkai* this = (DemoKekkai*)thisx; DemoKekkai* this = (DemoKekkai*)thisx;
if (IS_RANDO) {
Flags_SetRandomizerInf(trialParamToRandInf(thisx->params));
// May or may not be needed. Not sure if needed for anything
// that randoInf isn't already covering. Leaving it for safety.
Flags_SetEventChkInf(eventFlags[thisx->params]);
}
if (play->csCtx.frames == csFrames[this->actor.params]) { if (play->csCtx.frames == csFrames[this->actor.params]) {
func_800F3F3C(0xA); func_800F3F3C(0xA);
} }

View File

@ -136,27 +136,6 @@ void ObjectKankyo_Init(Actor* thisx, PlayState* play) {
this->effects[5].size = 0.0f; this->effects[5].size = 0.0f;
} }
if (IS_RANDO) {
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) {
this->effects[0].size = 0.0f;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) {
this->effects[1].size = 0.0f;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) {
this->effects[2].size = 0.0f;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) {
this->effects[3].size = 0.0f;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) {
this->effects[4].size = 0.0f;
}
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) {
this->effects[5].size = 0.0f;
}
}
if (gSaveContext.cutsceneTrigger != 0) { if (gSaveContext.cutsceneTrigger != 0) {
if (gSaveContext.entranceIndex == ENTR_INSIDE_GANONS_CASTLE_2) { if (gSaveContext.entranceIndex == ENTR_INSIDE_GANONS_CASTLE_2) {
this->effects[0].size = 0.1f; this->effects[0].size = 0.1f;