Merge branch 'develop' of garrettjoecox.github.com:HarbourMasters/Shipwright into let-it-snow

This commit is contained in:
Garrett Cox 2024-12-09 21:01:45 -06:00
commit c47f1d6d92
30 changed files with 790 additions and 1408 deletions

View file

@ -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);

View file

@ -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

View file

@ -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 |
---------------------------*/

View file

@ -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)) {

View file

@ -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;}}),

View file

@ -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();
}
}
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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);

View file

@ -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(){

View file

@ -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;
}

View file

@ -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;

View file

@ -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] =

View file

@ -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)

View file

@ -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 &&

View file

@ -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;

View file

@ -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) &&

View file

@ -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

View file

@ -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;

View file

@ -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},

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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),

View file

@ -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;

View file

@ -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;