mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-19 21:03:42 -07:00
Merge branch 'develop' of garrettjoecox.github.com:HarbourMasters/Shipwright into let-it-snow
This commit is contained in:
commit
c47f1d6d92
30 changed files with 790 additions and 1408 deletions
|
@ -537,7 +537,7 @@ void func_80034BA0(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overr
|
|||
PostLimbDraw postLimbDraw, Actor* actor, s16 alpha);
|
||||
void func_80034CC4(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw,
|
||||
PostLimbDraw postLimbDraw, Actor* actor, s16 alpha);
|
||||
s16 func_80034DD4(Actor* actor, PlayState* play, s16 arg2, f32 arg3);
|
||||
s16 Actor_UpdateAlphaByDistance(Actor* actor, PlayState* play, s16 arg2, f32 arg3);
|
||||
void Animation_ChangeByInfo(SkelAnime* skelAnime, AnimationInfo* animationInfo, s32 index);
|
||||
void func_80034F54(PlayState* play, s16* arg1, s16* arg2, s32 arg3);
|
||||
void Actor_Noop(Actor* actor, PlayState* play);
|
||||
|
|
|
@ -281,6 +281,9 @@ typedef enum {
|
|||
VB_SPAWN_BLUE_WARP,
|
||||
// Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF
|
||||
VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE,
|
||||
// Vanilla condition: SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2
|
||||
// Opt: int (original next entrance index)
|
||||
VB_SET_VOIDOUT_FROM_SURFACE,
|
||||
// Vanilla condition: this->collider.base.acFlags & 2
|
||||
VB_BG_BREAKWALL_BREAK,
|
||||
// Vanilla condition: true
|
||||
|
|
|
@ -2493,86 +2493,91 @@ void StaticData::HintTable_Init() {
|
|||
/*--------------------------
|
||||
| BOSS HINT TEXT |
|
||||
---------------------------*/
|
||||
|
||||
hintTextTable[RHT_QUEEN_GOHMA] = HintText(CustomMessage("#Queen Gohma# holds",
|
||||
/*german*/ "#Königin Gohma# hält",
|
||||
/*french*/ "la #Reine Gohma# possède"),
|
||||
// /*spanish*/la #Reina Goma# porta
|
||||
//RANDOTODO check the beginning and end on the french and german translations
|
||||
hintTextTable[RHT_QUEEN_GOHMA] = HintText(CustomMessage("They say that #Queen Gohma# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Königin Gohma# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, la #Reine Gohma# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/la #Reina Goma# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Parasitic Armored Arachnid# holds",
|
||||
/*german*/ "die #gepanzerte parasitäre Spinne# hält",
|
||||
/*french*/ "le #monstre insectoïde géant# possède")});
|
||||
// /*spanish*/el #arácnido parasitario acorazado# porta
|
||||
{CustomMessage("They say that the #Parasitic Armored Arachnid# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß die #gepanzerte parasitäre Spinne# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, le #monstre insectoïde géant# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/el #arácnido parasitario acorazado# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_KING_DODONGO] = HintText(CustomMessage("#King Dodongo# holds",
|
||||
/*german*/ "#König Dodongo# hält",
|
||||
/*french*/ "le #Roi Dodongo# possède"),
|
||||
// /*spanish*/el #Rey Dodongo# porta
|
||||
hintTextTable[RHT_KING_DODONGO] = HintText(CustomMessage("They say that #King Dodongo# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #König Dodongo# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, le #Roi Dodongo# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/el #Rey Dodongo# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Infernal Dinosaur# holds",
|
||||
/*german*/ "der #infernalische Dinosaurier# hält",
|
||||
/*french*/ "le #dinosaure infernal# possède")});
|
||||
// /*spanish*/el #dinosaurio infernal# porta
|
||||
{CustomMessage("They say that the #Infernal Dinosaur# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß der #infernalische Dinosaurier# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, le #dinosaure infernal# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/el #dinosaurio infernal# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_BARINADE] = HintText(CustomMessage("#Barinade# holds",
|
||||
/*german*/ "#Barinade# hält",
|
||||
/*french*/ "#Barinade# possède"),
|
||||
// /*spanish*/#Barinade# porta
|
||||
hintTextTable[RHT_BARINADE] = HintText(CustomMessage("They say that #Barinade# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Barinade# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Barinade# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Barinade# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Bio-Electric Anemone# holds",
|
||||
/*german*/ "die #bioelektrische Anemone# hält",
|
||||
/*french*/ "l'#anémone bioélectrique# possède")});
|
||||
// /*spanish*/la #anémona bioeléctrica# porta
|
||||
{CustomMessage("They say that the #Bio-Electric Anemone# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß die #bioelektrische Anemone# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, l'#anémone bioélectrique# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/la #anémona bioeléctrica# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_PHANTOM_GANON] = HintText(CustomMessage("#Phantom Ganon# holds",
|
||||
/*german*/ "#Phantom-Ganon# hält",
|
||||
/*french*/ "#Ganon Spectral# possède"),
|
||||
// /*spanish*/#Ganon Fantasma# porta
|
||||
hintTextTable[RHT_PHANTOM_GANON] = HintText(CustomMessage("They say that #Phantom Ganon# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Phantom-Ganon# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Ganon Spectral# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Ganon Fantasma# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Evil Spirit from Beyond# holds",
|
||||
/*german*/ "der #böse Geist aus dem Jenseits# hält",
|
||||
/*french*/ "l'#esprit maléfique de l'au-delà# possède")});
|
||||
// /*spanish*/el #espíritu maligno de ultratumba# porta
|
||||
{CustomMessage("They say that the #Evil Spirit from Beyond# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß der #böse Geist aus dem Jenseits# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, l'#esprit maléfique de l'au-delà# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/el #espíritu maligno de ultratumba# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_VOLVAGIA] = HintText(CustomMessage("#Volvagia# holds",
|
||||
/*german*/ "#Volvagia# hält",
|
||||
/*french*/ "#Volvagia# possède"),
|
||||
// /*spanish*/#Volvagia# porta
|
||||
hintTextTable[RHT_VOLVAGIA] = HintText(CustomMessage("They say that #Volvagia# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Volvagia# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Volvagia# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Volvagia# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Subterranean Lava Dragon# holds",
|
||||
/*german*/ "der #subterrane Lavadrache# hält",
|
||||
/*french*/ "le #dragon des profondeurs# possède")});
|
||||
// /*spanish*/el #dragón de lava subterráneo# porta
|
||||
{CustomMessage("They say that the #Subterranean Lava Dragon# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß der #subterrane Lavadrache# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, le #dragon des profondeurs# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/el #dragón de lava subterráneo# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_MORPHA] = HintText(CustomMessage("#Morpha# holds",
|
||||
/*german*/ "#Morpha# hält",
|
||||
/*french*/ "#Morpha# possède"),
|
||||
// /*spanish*/#Morpha# porta
|
||||
hintTextTable[RHT_MORPHA] = HintText(CustomMessage("They say that #Morpha# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Morpha# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Morpha# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Morpha# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Giant Aquatic Amoeba# holds",
|
||||
/*german*/ "die #gigantische aquatische Amöbe# hält",
|
||||
/*french*/ "l'#amibe aquatique géante# possède")});
|
||||
// /*spanish*/la #ameba acuática gigante# porta
|
||||
{CustomMessage("They say that the #Giant Aquatic Amoeba# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß die #gigantische aquatische Amöbe# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, l'#amibe aquatique géante# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/la #ameba acuática gigante# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_BONGO_BONGO] = HintText(CustomMessage("#Bongo Bongo# holds",
|
||||
/*german*/ "#Bongo Bongo# hält",
|
||||
/*french*/ "#Bongo Bongo# possède"),
|
||||
// /*spanish*/#Bongo Bongo# porta
|
||||
hintTextTable[RHT_BONGO_BONGO] = HintText(CustomMessage("They say that #Bongo Bongo# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Bongo Bongo# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Bongo Bongo# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Bongo Bongo# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Phantom Shadow Beast# holds",
|
||||
/*german*/ "das #Phantomschattenbiest# hält",
|
||||
/*french*/ "le #monstre de l'ombre# possède")});
|
||||
// /*spanish*/la #alimaña oscura espectral# porta
|
||||
{CustomMessage("They say that the #Phantom Shadow Beast# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß das #Phantomschattenbiest# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, le #monstre de l'ombre# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/la #alimaña oscura espectral# porta #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_TWINROVA] = HintText(CustomMessage("#Twinrova# holds",
|
||||
/*german*/ "#Twinrova# hält",
|
||||
/*french*/ "#Twinrova# possède"),
|
||||
// /*spanish*/#Birova# porta
|
||||
hintTextTable[RHT_TWINROVA] = HintText(CustomMessage("They say that #Twinrova# holds #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß #Twinrova# hält #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #Twinrova# possède #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
// /*spanish*/#Birova# porta #[[1]]#.
|
||||
{},
|
||||
{CustomMessage("the #Sorceress Sisters# hold",
|
||||
/*german*/ "die #Hexenschwestern# halten",
|
||||
/*french*/ "#les sorcières jumelles# possède")});
|
||||
// /*spanish*/las #hermanas hechiceras# portan
|
||||
{CustomMessage("They say that the #Sorceress Sisters# hold #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß die #Hexenschwestern# halten #[[1]]# lehre.",
|
||||
/*french*/ "Selon moi, #les sorcières jumelles# possède #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
// /*spanish*/las #hermanas hechiceras# portan #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_GIFT_FROM_SAGES] = HintText(CustomMessage("They say that the #Sage of Light# gifts @ #[[1]]#.", {QM_RED, QM_GREEN}),
|
||||
{},
|
||||
{CustomMessage("They say that #a former owl# gifts @ #[[1]]#.", {QM_RED, QM_GREEN})});
|
||||
|
||||
/*--------------------------
|
||||
| BRIDGE HINT TEXT |
|
||||
---------------------------*/
|
||||
|
|
|
@ -1026,7 +1026,7 @@ void GenerateItemPool() {
|
|||
}
|
||||
|
||||
//Gerudo Fortress
|
||||
if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN)) {
|
||||
if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE)) {
|
||||
ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true);
|
||||
ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true);
|
||||
ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true);
|
||||
|
@ -1071,7 +1071,7 @@ void GenerateItemPool() {
|
|||
}
|
||||
|
||||
//Gerudo Membership Card
|
||||
if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_OPEN)) {
|
||||
if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_FREE)) {
|
||||
AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
} else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
|
|
|
@ -16,7 +16,7 @@ void RegionTable_Init_GerudoValley() {
|
|||
Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}),
|
||||
Entrance(RR_GV_CRATE_LEDGE, {[]{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}),
|
||||
Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}),
|
||||
Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {
|
||||
|
@ -64,7 +64,7 @@ void RegionTable_Init_GerudoValley() {
|
|||
//Exits
|
||||
Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}),
|
||||
Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}),
|
||||
Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue;}}),
|
||||
Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) || logic->CarpenterRescue;}}),
|
||||
Entrance(RR_GV_CARPENTER_TENT, {[]{return logic->IsAdult;}}),
|
||||
Entrance(RR_GV_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}),
|
||||
Entrance(RR_GV_CRATE_LEDGE, {[]{return false;}}),
|
||||
|
|
|
@ -139,14 +139,11 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance)
|
|||
// Writes the settings (without excluded locations, starting inventory and tricks) to the spoilerLog document.
|
||||
static void WriteSettings() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
auto allOptionGroups = ctx->GetSettings()->GetOptionGroups();
|
||||
for (const Rando::OptionGroup& optionGroup : allOptionGroups) {
|
||||
if (optionGroup.GetContainsType() == Rando::OptionGroupType::DEFAULT && optionGroup.PrintInSpoiler()) {
|
||||
for (Rando::Option* option : optionGroup.GetOptions()) {
|
||||
std::string settingName = optionGroup.GetName() + ":" + option->GetName();
|
||||
jsonData["settings"][settingName] = option->GetSelectedOptionText();
|
||||
}
|
||||
}
|
||||
std::array<Rando::Option, RSK_MAX> options = ctx->GetSettings()->GetAllOptions();
|
||||
for (const Rando::Option& option : options) {
|
||||
if (option.GetName() != ""){
|
||||
jsonData["settings"][option.GetName()] = option.GetSelectedOptionText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ void GenerateStartingInventory() {
|
|||
AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
}
|
||||
|
||||
|
|
|
@ -1558,6 +1558,40 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
*should = !Flags_GetInfTable(INFTABLE_145) || Flags_GetInfTable(INFTABLE_146);
|
||||
break;
|
||||
}
|
||||
case VB_SET_VOIDOUT_FROM_SURFACE: {
|
||||
// ENTRTODO: Move all entrance rando handling to a dedicated file
|
||||
std::vector<s16> entrPersistTempFlags = {
|
||||
ENTR_DEKU_TREE_BOSS_ENTRANCE, ENTR_DEKU_TREE_BOSS_DOOR, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE,
|
||||
ENTR_DODONGOS_CAVERN_BOSS_DOOR, ENTR_JABU_JABU_BOSS_ENTRANCE, ENTR_JABU_JABU_BOSS_DOOR,
|
||||
ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, ENTR_FOREST_TEMPLE_BOSS_DOOR, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE,
|
||||
ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_WATER_TEMPLE_BOSS_ENTRANCE, ENTR_WATER_TEMPLE_BOSS_DOOR,
|
||||
ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, ENTR_SPIRIT_TEMPLE_BOSS_DOOR, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE,
|
||||
ENTR_SHADOW_TEMPLE_BOSS_DOOR, ENTR_SPIRIT_TEMPLE_ENTRANCE,
|
||||
};
|
||||
|
||||
s16 originalEntrance = (s16)va_arg(args, int);
|
||||
|
||||
// In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen
|
||||
if (*should == true && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
|
||||
// Check for dungeon special entrances that are randomized to a new location
|
||||
if (std::find(entrPersistTempFlags.begin(), entrPersistTempFlags.end(), originalEntrance) !=
|
||||
entrPersistTempFlags.end() && originalEntrance != gPlayState->nextEntranceIndex) {
|
||||
// Normally dungeons use a special voidout between scenes so that entering/exiting a boss room,
|
||||
// or leaving via Spirit Hands and going back in persist temp flags across scenes.
|
||||
// For ER, the temp flags should be wiped out so that they aren't transferred to the new location.
|
||||
gPlayState->actorCtx.flags.tempSwch = 0;
|
||||
gPlayState->actorCtx.flags.tempCollect = 0;
|
||||
|
||||
// If the respawnFlag is set for a grotto return, we don't want the void out to happen.
|
||||
// Set the data flag to one to prevent the respawn point from being overriden by dungeon doors.
|
||||
if (gSaveContext.respawnFlag == 2) {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].data = 1;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_FREEZE_ON_SKULL_TOKEN:
|
||||
case VB_TRADE_TIMER_ODD_MUSHROOM:
|
||||
case VB_TRADE_TIMER_FROG:
|
||||
|
@ -1623,6 +1657,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) {
|
|||
CheckTracker::RecalculateAllAreaTotals();
|
||||
}
|
||||
|
||||
// ENTRTODO: Move all entrance rando handling to a dedicated file
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
|
||||
// In ER, override roomNum to load based on scene and spawn during scene init
|
||||
if (gSaveContext.respawnFlag <= 0) {
|
||||
|
@ -2336,6 +2371,7 @@ void RandomizerRegisterHooks() {
|
|||
|
||||
if (!IS_RANDO) return;
|
||||
|
||||
// ENTRTODO: Move all entrance rando handling to a dedicated file
|
||||
// Setup the modified entrance table and entrance shuffle table for rando
|
||||
Entrance_Init();
|
||||
|
||||
|
|
|
@ -818,7 +818,7 @@ void Rando::StaticData::InitLocationTable() { //
|
|||
locationTable[RC_TWINROVA] = Location::Base(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), true);
|
||||
locationTable[RC_BONGO_BONGO] = Location::Base(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), true);
|
||||
locationTable[RC_GANON] = Location::Base(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE);
|
||||
locationTable[RC_GIFT_FROM_SAGES] = Location::Base(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, SpoilerCollectionCheck::EventChkInf(0xC9), true);
|
||||
locationTable[RC_GIFT_FROM_SAGES] = Location::Base(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION, SpoilerCollectionCheck::EventChkInf(0xC9), true);
|
||||
|
||||
// Heart Containers
|
||||
locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x11, 0x1F), true);
|
||||
|
|
|
@ -1124,7 +1124,7 @@ namespace Rando {
|
|||
bool Logic::CanFinishGerudoFortress(){
|
||||
return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) ||
|
||||
(ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) ||
|
||||
ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN);
|
||||
ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FREE);
|
||||
}
|
||||
|
||||
bool Logic::CanStandingShield(){
|
||||
|
|
|
@ -178,6 +178,15 @@ void Option::RemoveFlag(const int imFlag_) {
|
|||
imFlags &= ~imFlag_;
|
||||
}
|
||||
|
||||
void Option::SetContextIndexFromText(const std::string text) {
|
||||
if (optionsTextToVar.contains(text)){
|
||||
SetContextIndex(optionsTextToVar[text]);
|
||||
} else {
|
||||
SPDLOG_ERROR("Option {} does not have a var named {}.", name, text);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
Option::Option(uint8_t var_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
|
||||
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
|
||||
bool defaultHidden_, int imFlags_)
|
||||
|
@ -186,6 +195,7 @@ Option::Option(uint8_t var_, std::string name_, std::vector<std::string> options
|
|||
defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) {
|
||||
menuSelection = contextSelection = defaultOption;
|
||||
hidden = defaultHidden;
|
||||
PopulateTextToNum();
|
||||
SetFromCVar();
|
||||
}
|
||||
Option::Option(bool var_, std::string name_, std::vector<std::string> options_, const OptionCategory category_,
|
||||
|
@ -196,6 +206,7 @@ Option::Option(bool var_, std::string name_, std::vector<std::string> options_,
|
|||
defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) {
|
||||
menuSelection = contextSelection = defaultOption;
|
||||
hidden = defaultHidden;
|
||||
PopulateTextToNum();
|
||||
SetFromCVar();
|
||||
}
|
||||
|
||||
|
@ -333,6 +344,12 @@ bool Option::RenderSlider() {
|
|||
return changed;
|
||||
}
|
||||
|
||||
void Option::PopulateTextToNum(){
|
||||
for (uint8_t count = 0; count < options.size(); count++){
|
||||
optionsTextToVar[options[count]] = count;
|
||||
}
|
||||
}
|
||||
|
||||
TrickOption::TrickOption(const RandomizerCheckQuest quest_, const RandomizerArea area_, std::set<Tricks::Tag> tags_, const bool glitch_, const std::string& name_, std::string description_) :
|
||||
Option(false, name_, {"Disabled", "Enabled"}, OptionCategory::Setting, "",
|
||||
std::move(description_), WidgetType::Checkbox, 0, false, IMFLAG_NONE),
|
||||
|
@ -363,26 +380,26 @@ const std::set<Tricks::Tag>& TrickOption::GetTags() const {
|
|||
}
|
||||
|
||||
OptionGroup::OptionGroup(std::string name, std::vector<Option*> options, const OptionGroupType groupType,
|
||||
const bool printInSpoiler, const WidgetContainerType containerType, std::string description)
|
||||
: mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler),
|
||||
const WidgetContainerType containerType, std::string description)
|
||||
: mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType),
|
||||
mContainerType(containerType), mDescription(std::move(description)) {
|
||||
}
|
||||
|
||||
OptionGroup::OptionGroup(std::string name, std::vector<OptionGroup*> subGroups, const OptionGroupType groupType,
|
||||
const bool printInSpoiler, const WidgetContainerType containerType, std::string description)
|
||||
: mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler),
|
||||
const WidgetContainerType containerType, std::string description)
|
||||
: mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType),
|
||||
mContainsType(OptionGroupType::SUBGROUP), mContainerType(containerType), mDescription(std::move(description)) {
|
||||
}
|
||||
|
||||
OptionGroup OptionGroup::SubGroup(std::string name, std::vector<Option*> options, const bool printInSpoiler,
|
||||
OptionGroup OptionGroup::SubGroup(std::string name, std::vector<Option*> options,
|
||||
const WidgetContainerType containerType, std::string description) {
|
||||
return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, printInSpoiler, containerType,
|
||||
return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, containerType,
|
||||
std::move(description)};
|
||||
}
|
||||
|
||||
OptionGroup OptionGroup::SubGroup(std::string name, std::vector<OptionGroup*> subGroups, const bool printInSpoiler,
|
||||
OptionGroup OptionGroup::SubGroup(std::string name, std::vector<OptionGroup*> subGroups,
|
||||
const WidgetContainerType containerType, std::string description) {
|
||||
return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, printInSpoiler, containerType,
|
||||
return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, containerType,
|
||||
std::move(description)};
|
||||
}
|
||||
|
||||
|
@ -398,10 +415,6 @@ const std::vector<OptionGroup*>& OptionGroup::GetSubGroups() const {
|
|||
return mSubGroups;
|
||||
}
|
||||
|
||||
bool OptionGroup::PrintInSpoiler() const {
|
||||
return mPrintInSpoiler;
|
||||
}
|
||||
|
||||
OptionGroupType OptionGroup::GetGroupType() const {
|
||||
return mGroupType;
|
||||
}
|
||||
|
|
|
@ -56,9 +56,9 @@ class Option {
|
|||
* @param options_ A vector of value names for this Option. This vector should have a size of 2.
|
||||
* The name corresponding to the selected index for this option will be printed to the spoiler/patch file.
|
||||
* @param category_ The desired `OptionCategory` for this option.
|
||||
* @param cvarName_ The name ofthe CVar this option should correspond with. Set as an empty string to not
|
||||
* @param cvarName_ The name of the CVar this option should correspond with. Set as an empty string to not
|
||||
* link to any Cvar.
|
||||
* @param description_ A description of what this option affects. Will be rendered in a toolip in ImGui.
|
||||
* @param description_ A description of what this option affects. Will be rendered in a tooltip in ImGui.
|
||||
* Can be left as an empty string if desired, no tooltip will be rendered.
|
||||
* @param widgetType_ What type of widget should be rendered. Should probably be `Checkbox` but technically
|
||||
* `Combobox` or `Slider` would render and function correctly.
|
||||
|
@ -305,6 +305,8 @@ class Option {
|
|||
void SetFlag(int imFlag_);
|
||||
void RemoveFlag(int imFlag_);
|
||||
|
||||
void SetContextIndexFromText(std::string text);
|
||||
|
||||
protected:
|
||||
Option(uint8_t var_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
|
||||
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
|
||||
|
@ -318,6 +320,7 @@ protected:
|
|||
bool RenderTristateCheckbox();
|
||||
bool RenderCombobox();
|
||||
bool RenderSlider();
|
||||
void PopulateTextToNum();
|
||||
std::variant<bool, uint8_t> var;
|
||||
std::string name;
|
||||
std::vector<std::string> options;
|
||||
|
@ -335,6 +338,7 @@ protected:
|
|||
bool disabled = false;
|
||||
UIWidgets::CheckboxGraphics disabledGraphic = UIWidgets::CheckboxGraphics::Cross;
|
||||
std::string disabledText;
|
||||
std::unordered_map<std::string, uint8_t> optionsTextToVar = {};
|
||||
};
|
||||
|
||||
class TrickOption : public Option {
|
||||
|
@ -416,13 +420,11 @@ class OptionGroup {
|
|||
* @param options A vector of Option pointers
|
||||
* @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a
|
||||
* subgroup of another group.
|
||||
* @param printInSpoiler Whether or not to print the contents of this group to the spoiler/patch file.
|
||||
* @param containerType Specifies the type of container this widget should render as in ImGui.
|
||||
* @param description A description that can appear in a tooltip in ImGui.
|
||||
*/
|
||||
OptionGroup(std::string name, std::vector<Option*> options, OptionGroupType groupType = OptionGroupType::DEFAULT,
|
||||
bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
std::string description = "");
|
||||
WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = "");
|
||||
|
||||
/**
|
||||
* @brief Construct a new Option Group containing a list of `OptionGroup` pointers.
|
||||
|
@ -431,13 +433,11 @@ class OptionGroup {
|
|||
* @param subGroups A vector of OptionGroup pointers that will be subgroups of this group.
|
||||
* @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a
|
||||
* subgroup of another group.
|
||||
* @param printInSpoiler Whether or not to print the contents of this group to spoiler/patch file.
|
||||
* @param containerType Specifies the type of container this widget should render as in ImGui.
|
||||
* @param description A description that can appear in a tooltip in ImGui.
|
||||
*/
|
||||
OptionGroup(std::string name, std::vector<OptionGroup*> subGroups, OptionGroupType groupType = OptionGroupType::DEFAULT,
|
||||
bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
std::string description = "");
|
||||
WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = "");
|
||||
|
||||
/**
|
||||
* @brief Convenience function for constructing an OptionGroup of groupType `SUBGROUP` with
|
||||
|
@ -445,13 +445,11 @@ class OptionGroup {
|
|||
*
|
||||
* @param name The name of this option group. Appears in the spoiler/patch file.
|
||||
* @param options A vector of Option pointers.
|
||||
* @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file.
|
||||
* @param containerType Specifies the type of container this widget should render as in ImGui.
|
||||
* @param description A description that can appear in a tooltip in ImGui.
|
||||
* @return OptionGroup
|
||||
*/
|
||||
static OptionGroup SubGroup(std::string name, std::vector<Option*> options, bool printInSpoiler = true,
|
||||
WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
static OptionGroup SubGroup(std::string name, std::vector<Option*> options, WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
std::string description = "");
|
||||
|
||||
/**
|
||||
|
@ -460,13 +458,11 @@ class OptionGroup {
|
|||
*
|
||||
* @param name The name of this option group. Appears in the spoiler/patch file.
|
||||
* @param subGroups A vector of OptionGroup pointers.
|
||||
* @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file.
|
||||
* @param containerType Specifies the type of container this widget should render as in ImGui.
|
||||
* @param description A description that can appear in a tooltip in ImGui.
|
||||
* @return OptionGroup
|
||||
*/
|
||||
static OptionGroup SubGroup(std::string name, std::vector<OptionGroup*> subGroups, bool printInSpoiler = true,
|
||||
WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
static OptionGroup SubGroup(std::string name, std::vector<OptionGroup*> subGroups, WidgetContainerType containerType = WidgetContainerType::BASIC,
|
||||
std::string description = "");
|
||||
|
||||
/**
|
||||
|
@ -490,15 +486,6 @@ class OptionGroup {
|
|||
*/
|
||||
const std::vector<OptionGroup*>& GetSubGroups() const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not this `OptionGroup`'s contents should be printed to the
|
||||
* spoiler/patch file.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool PrintInSpoiler() const;
|
||||
|
||||
/**
|
||||
* @brief Get the Group Type of this `OptionGroup`. `DEFAULT` means this group is not contained
|
||||
* within any other groups, while `SUBGROUP` means that it is contained within at least one other.
|
||||
|
@ -532,7 +519,6 @@ class OptionGroup {
|
|||
std::vector<Option*> mOptions;
|
||||
std::vector<OptionGroup*> mSubGroups;
|
||||
OptionGroupType mGroupType = OptionGroupType::DEFAULT;
|
||||
bool mPrintInSpoiler = true;
|
||||
OptionGroupType mContainsType = OptionGroupType::DEFAULT;
|
||||
WidgetContainerType mContainerType = WidgetContainerType::BASIC;
|
||||
std::string mDescription;
|
||||
|
|
|
@ -43,14 +43,15 @@ void Settings::CreateOptionDescriptions() {
|
|||
"Choose which age Link will start as.\n\n"
|
||||
"Starting as adult means you start with the Master Sword in your inventory.\n"
|
||||
"The child option is forcefully set if it would conflict with other options.";
|
||||
mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the amount of carpenters required to repair the bridge "
|
||||
"in Gerudo Valley.\n"
|
||||
mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the state of the carpenters captured by Gerudo "
|
||||
"in Gerudo Fortress, and with it the number of guards that spawn.\n"
|
||||
"\n"
|
||||
"Normal - All 4 carpenters are required to be saved.\n"
|
||||
"\n"
|
||||
"Fast - Only the bottom left carpenter requires rescuing.\n"
|
||||
"\n"
|
||||
"Open - The bridge is repaired from the start.\n"
|
||||
"Free - The bridge is repaired from the start, and Nabooru cannot spawn.\n"
|
||||
"If the Gerudo Membership Card isn't shuffled, you start with it.\n"
|
||||
"\n"
|
||||
"Only \"Normal\" is compatible with Gerudo Fortress Key Rings.";
|
||||
mOptionDescriptions[RSK_RAINBOW_BRIDGE] =
|
||||
|
|
|
@ -2661,6 +2661,7 @@ typedef enum {
|
|||
RHT_MORPHA,
|
||||
RHT_BONGO_BONGO,
|
||||
RHT_TWINROVA,
|
||||
RHT_GIFT_FROM_SAGES,
|
||||
RHT_SONG_FROM_IMPA,
|
||||
RHT_SONG_FROM_MALON,
|
||||
RHT_SONG_FROM_SARIA,
|
||||
|
@ -4198,7 +4199,7 @@ typedef enum {
|
|||
typedef enum {
|
||||
RO_GF_NORMAL,
|
||||
RO_GF_FAST,
|
||||
RO_GF_OPEN,
|
||||
RO_GF_FREE,
|
||||
} RandoOptionGerudoFortress;
|
||||
|
||||
//Kakariko Gate settings (closed/open)
|
||||
|
|
|
@ -206,7 +206,7 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
|
|||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) !=
|
||||
RO_GANON_BOSS_KEY_KAK_TOKENS) && // 100 skull reward ganon boss key
|
||||
(location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD ||
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_OPEN &&
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_FREE &&
|
||||
location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD) ||
|
||||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_FAST &&
|
||||
((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD &&
|
||||
|
|
|
@ -1185,7 +1185,7 @@ void LoadSettings() {
|
|||
fortressFast = false;
|
||||
fortressNormal = false;
|
||||
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) {
|
||||
case RO_GF_OPEN:
|
||||
case RO_GF_FREE:
|
||||
showGerudoFortressKeys = false;
|
||||
showGerudoCard = false;
|
||||
break;
|
||||
|
|
|
@ -267,13 +267,6 @@ s16 Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex) {
|
|||
}
|
||||
|
||||
s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) {
|
||||
// When entering Spirit Temple, clear temp flags so they don't carry over to the randomized dungeon
|
||||
if (nextEntranceIndex == ENTR_SPIRIT_TEMPLE_ENTRANCE && Entrance_GetOverride(nextEntranceIndex) != nextEntranceIndex &&
|
||||
gPlayState != NULL) {
|
||||
gPlayState->actorCtx.flags.tempSwch = 0;
|
||||
gPlayState->actorCtx.flags.tempCollect = 0;
|
||||
}
|
||||
|
||||
// Exiting through the crawl space from Hyrule Castle courtyard is the same exit as leaving Ganon's castle
|
||||
// Don't override the entrance if we came from the Castle courtyard (day and night scenes)
|
||||
if (gPlayState != NULL && (gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_DAY || gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_NIGHT) &&
|
||||
|
|
|
@ -453,7 +453,7 @@ extern "C" void Randomizer_InitSaveFile() {
|
|||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FAST ||
|
||||
Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) {
|
||||
Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FREE) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1));
|
||||
Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2));
|
||||
Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3));
|
||||
|
@ -471,7 +471,7 @@ extern "C" void Randomizer_InitSaveFile() {
|
|||
gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F);
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) {
|
||||
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FREE) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0));
|
||||
gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door
|
||||
gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,14 @@ class Settings {
|
|||
*/
|
||||
void CreateOptions();
|
||||
|
||||
/**
|
||||
* @brief Populates the map used to translate strings into RandomiserSettingKeys
|
||||
*
|
||||
* @return std::unordered_map<std::string, RandomizerSettingKey>
|
||||
*/
|
||||
|
||||
std::unordered_map<std::string, RandomizerSettingKey> PopulateOptionNameToEnum();
|
||||
|
||||
/**
|
||||
* @brief Get a reference to the `Option` corresponding to the provided RandomizerSettingKey.
|
||||
*
|
||||
|
@ -192,7 +200,6 @@ class Settings {
|
|||
std::array<OptionGroup, RSG_MAX> mOptionGroups = {};
|
||||
std::array<TrickOption, RT_MAX> mTrickOptions = {};
|
||||
std::vector<std::vector<Option*>> mExcludeLocationsOptionsAreas = {};
|
||||
std::unordered_map<std::string, RandomizerSettingKey> mSpoilerfileSettingNameToEnum;
|
||||
RandoOptionStartingAge mResolvedStartingAge = RO_AGE_CHILD;
|
||||
RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA;
|
||||
std::string mHash;
|
||||
|
|
|
@ -251,7 +251,8 @@ std::unordered_map<std::string, uint32_t> StaticData::hintNameToEnum = {};
|
|||
std::unordered_map<std::string, uint32_t> StaticData::hintTypeNameToEnum = {};
|
||||
std::unordered_map<std::string, uint32_t> StaticData::areaNameToEnum = {};
|
||||
std::unordered_map<std::string, uint32_t> StaticData::trialNameToEnum = {};
|
||||
std::unordered_map<std::string, RandomizerCheck> StaticData::locationNameToEnum = {}; //is filled in context based on location table, not touching that because of VB
|
||||
std::unordered_map<std::string, RandomizerSettingKey> StaticData::optionNameToEnum = {};
|
||||
std::unordered_map<std::string, RandomizerCheck> StaticData::locationNameToEnum = {}; //is filled in context based on location table
|
||||
|
||||
std::unordered_map<u32, RandomizerHint> StaticData::stoneParamsToHint{
|
||||
{0x1, RH_ZF_FAIRY_GOSSIP_STONE},
|
||||
|
|
|
@ -61,6 +61,7 @@ class StaticData {
|
|||
static std::unordered_map<std::string, uint32_t> areaNameToEnum;
|
||||
static std::unordered_map<uint32_t, RandomizerHintTextKey> trialData;
|
||||
static std::unordered_map<std::string, uint32_t> trialNameToEnum;
|
||||
static std::unordered_map<std::string, RandomizerSettingKey> optionNameToEnum;
|
||||
static std::unordered_map<RandomizerHint, StaticHintInfo> staticHintInfoMap;
|
||||
static std::unordered_map<u32, RandomizerHint> stoneParamsToHint;
|
||||
static std::unordered_map<u32, RandomizerHint> grottoChestParamsToHint;
|
||||
|
|
|
@ -38,7 +38,7 @@ extern int32_t D_8011D3AC;
|
|||
extern void BgSpot03Taki_HandleWaterfallState(BgSpot03Taki* bgSpot03Taki, PlayState* play);
|
||||
extern void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* bgSpot03Taki, s32 bufferIndex);
|
||||
|
||||
extern void func_80AF36EC(EnRu2* enRu2, PlayState* play);
|
||||
extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
|
||||
}
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex()
|
||||
|
@ -340,11 +340,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
|||
if (ForcedDialogIsDisabled(FORCED_DIALOG_SKIP_NAVI)) {
|
||||
ElfMsg* naviTalk = va_arg(args, ElfMsg*);
|
||||
int32_t paramsHighByte = naviTalk->actor.params >> 8;
|
||||
if ((paramsHighByte & 0x80) == 0 && (paramsHighByte & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(gPlayState, paramsHighByte & 0x3F);
|
||||
Actor_Kill(&naviTalk->actor);
|
||||
*should = false;
|
||||
if ((paramsHighByte & 0x80) != 0) {
|
||||
break;
|
||||
}
|
||||
if ((paramsHighByte & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(gPlayState, paramsHighByte & 0x3F);
|
||||
}
|
||||
Actor_Kill(&naviTalk->actor);
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -893,7 +896,7 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
|||
if (actor->id == ACTOR_EN_RU2 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
EnRu2* enRu2 = (EnRu2*)actor;
|
||||
func_80AF36EC(enRu2, gPlayState);
|
||||
EnRu2_SetEncounterSwitchFlag(enRu2, gPlayState);
|
||||
Actor_Kill(actor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4558,25 +4558,25 @@ void func_80034CC4(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overr
|
|||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
s16 func_80034DD4(Actor* actor, PlayState* play, s16 arg2, f32 arg3) {
|
||||
s16 Actor_UpdateAlphaByDistance(Actor* actor, PlayState* play, s16 alpha, f32 radius) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
f32 var;
|
||||
f32 distance;
|
||||
|
||||
if ((play->csCtx.state != CS_STATE_IDLE) || (gDbgCamEnabled)) {
|
||||
var = Math_Vec3f_DistXYZ(&actor->world.pos, &play->view.eye) * 0.25f;
|
||||
distance = Math_Vec3f_DistXYZ(&actor->world.pos, &play->view.eye) * 0.25f;
|
||||
} else {
|
||||
var = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos);
|
||||
distance = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos);
|
||||
}
|
||||
|
||||
if (arg3 < var) {
|
||||
if (radius < distance) {
|
||||
actor->flags &= ~ACTOR_FLAG_TARGETABLE;
|
||||
Math_SmoothStepToS(&arg2, 0, 6, 0x14, 1);
|
||||
Math_SmoothStepToS(&alpha, 0, 6, 0x14, 1);
|
||||
} else {
|
||||
actor->flags |= ACTOR_FLAG_TARGETABLE;
|
||||
Math_SmoothStepToS(&arg2, 0xFF, 6, 0x14, 1);
|
||||
Math_SmoothStepToS(&alpha, 0xFF, 6, 0x14, 1);
|
||||
}
|
||||
|
||||
return arg2;
|
||||
return alpha;
|
||||
}
|
||||
|
||||
void Animation_ChangeByInfo(SkelAnime* skelAnime, AnimationInfo* animationInfo, s32 index) {
|
||||
|
|
|
@ -629,7 +629,7 @@ void func_80AAB5A4(EnMd* this, PlayState* play) {
|
|||
: 400.0f;
|
||||
}
|
||||
|
||||
this->alpha = func_80034DD4(&this->actor, play, this->alpha, temp);
|
||||
this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, temp);
|
||||
this->actor.shape.shadowAlpha = this->alpha;
|
||||
} else {
|
||||
this->alpha = 255;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,18 +14,18 @@ typedef struct EnRu2 {
|
|||
/* 0x014C */ SkelAnime skelAnime;
|
||||
/* 0x0190 */ Vec3s jointTable[23];
|
||||
/* 0x021A */ Vec3s morphTable[23];
|
||||
/* 0x02A4 */ s16 unk_2A4;
|
||||
/* 0x02A6 */ s16 unk_2A6;
|
||||
/* 0x02A4 */ s16 eyeIndex;
|
||||
/* 0x02A6 */ s16 blinkTimer;
|
||||
/* 0x02A8 */ s32 action;
|
||||
/* 0x02AC */ s32 drawConfig;
|
||||
/* 0x02B0 */ f32 unk_2B0;
|
||||
/* 0x02B0 */ f32 fadeTimer;
|
||||
/* 0x02B4 */ u32 alpha;
|
||||
/* 0x02B8 */ s32 unk_2B8;
|
||||
/* 0x02BC */ s32 unk_2BC;
|
||||
/* 0x02C0 */ u16 unk_2C0;
|
||||
/* 0x02C2 */ u8 unk_2C2;
|
||||
/* 0x02C3 */ u8 unk_2C3;
|
||||
/* 0x02C4 */ f32 unk_2C4;
|
||||
/* 0x02B8 */ s32 isLightBall;
|
||||
/* 0x02BC */ s32 cueId;
|
||||
/* 0x02C0 */ u16 swimmingUpFrame;
|
||||
/* 0x02C2 */ u8 textboxCount;
|
||||
/* 0x02C3 */ u8 lastDialogState;
|
||||
/* 0x02C4 */ f32 encounterTimer;
|
||||
/* 0x02C8 */ ColliderCylinder collider;
|
||||
/* 0x02C8 */ s16 subCamId;
|
||||
} EnRu2; // size = 0x0314
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "z64cutscene_commands.h"
|
||||
|
||||
// clang-format off
|
||||
static CutsceneData D_80AF411C[] = {
|
||||
static CutsceneData gWaterMedallionCs[] = {
|
||||
CS_BEGIN_CUTSCENE(35, 3338),
|
||||
CS_UNK_DATA_LIST(0x00000020, 1),
|
||||
CS_UNK_DATA(0x00010000, 0x0BB80000, 0x00000000, 0x00000000, 0xFFFFFFFC, 0x00000002, 0x00000000, 0xFFFFFFFC, 0x00000002, 0x00000000, 0x00000000, 0x00000000),
|
||||
|
|
|
@ -742,10 +742,10 @@ void EnSa_Update(Actor* thisx, PlayState* play) {
|
|||
|
||||
if (this->actionFunc != func_80AF68E4) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), 0) != 0) {
|
||||
this->alpha = func_80034DD4(&this->actor, play, this->alpha, 32767);
|
||||
this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, 32767);
|
||||
}
|
||||
else {
|
||||
this->alpha = func_80034DD4(&this->actor, play, this->alpha, 400.0f);
|
||||
this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, 400.0f);
|
||||
}
|
||||
} else {
|
||||
this->alpha = 255;
|
||||
|
|
|
@ -5147,9 +5147,9 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol
|
|||
|
||||
Scene_SetTransitionForNextEntrance(play);
|
||||
} else {
|
||||
// In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen
|
||||
if (SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 &&
|
||||
(!IS_RANDO || (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && gSaveContext.respawnFlag != 2))) {
|
||||
if (GameInteractor_Should(VB_SET_VOIDOUT_FROM_SURFACE,
|
||||
SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2,
|
||||
play->setupExitList[exitIndex - 1])) {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = play->nextEntranceIndex;
|
||||
Play_TriggerVoidOut(play);
|
||||
gSaveContext.respawnFlag = -2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue