Rando: Shuffle Crawl (#5032)
This commit is contained in:
@@ -326,6 +326,14 @@ typedef enum {
|
||||
// - `*ObjKibako2`
|
||||
VB_CRATE_SETUP_DRAW,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_CRAWL,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
||||
@@ -2107,6 +2107,7 @@ void StaticData::HintTable_Init_Item() {
|
||||
},
|
||||
{ CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") });
|
||||
// /*spanish*/un desbloqueador maestro
|
||||
hintTextTable[RHT_CRAWL] = HintText(CustomMessage("the ability to crawl", /*german*/TODO_TRANSLATE, /*french*/"la capacité de ramper"));
|
||||
|
||||
//RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints
|
||||
hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini"));
|
||||
|
||||
@@ -392,6 +392,10 @@ void GenerateItemPool() {
|
||||
int bronzeScale = ctx->GetOption(RSK_SHUFFLE_SWIM) ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_SCALE, 3 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale);
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) {
|
||||
AddItemToPool(RG_CRAWL, 2, 1, 1, 1);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) {
|
||||
PlaceItemsForType(RCTYPE_BEEHIVE, true, true);
|
||||
}
|
||||
|
||||
@@ -997,6 +997,11 @@ void InitTrickNames() {
|
||||
Text{ "Stalfos Key" }, Text{ "Nightmare Key" }, Text{ "Graveyard Key" },
|
||||
Text{ "King's Key" }, Text{ "Hero's Key" },
|
||||
};
|
||||
trickNameTable[RG_CRAWL] = {
|
||||
// TODO_TRANSLATE
|
||||
Text{ "Crouch" },
|
||||
};
|
||||
|
||||
trickNameTable[RG_OCARINA_A_BUTTON] = {
|
||||
Text{ "Ocarina J Button", "Touche Ha de l'Ocarina", "J-Taste der Okarina" },
|
||||
Text{ "Ocarina Ayy Button", "Touche Ah de l'Ocarina", "A-Taste der Flöte" },
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "randomizerTypes.h"
|
||||
#include <array>
|
||||
#include "soh_assets.h"
|
||||
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
||||
|
||||
@@ -35,6 +34,7 @@ extern "C" {
|
||||
#include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h"
|
||||
#include "objects/object_tw/object_tw.h"
|
||||
#include "objects/object_ganon2/object_ganon2.h"
|
||||
#include "objects/object_gi_shield_1/object_gi_shield_1.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
@@ -1136,6 +1136,23 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) {
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
Matrix_Translate(-35, -5, 0, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.4f, 0.8f, 1.2f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiDekuShieldDL);
|
||||
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
Matrix_Translate(35, -7, 4, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiDekuShieldDL);
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry) {
|
||||
Vec3f pos;
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
@@ -22,6 +22,7 @@ void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry);
|
||||
void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry);
|
||||
void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry);
|
||||
|
||||
@@ -850,6 +850,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
va_copy(args, originalArgs);
|
||||
|
||||
switch (id) {
|
||||
case VB_CRAWL:
|
||||
*should = !RAND_GET_OPTION(RSK_SHUFFLE_CRAWL) || Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL);
|
||||
break;
|
||||
case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: {
|
||||
s32 entranceIndex = va_arg(args, s32);
|
||||
|
||||
|
||||
@@ -369,9 +369,12 @@ void Rando::StaticData::InitItemTable() {
|
||||
itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "C-Rechts-Taste der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
|
||||
|
||||
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale);
|
||||
|
||||
itemTable[RG_CRAWL] = Item(RG_CRAWL, Text{ "Crawl", "Ramper", "Kriechen" }, ITEMTYPE_ITEM, GI_SHIELD_DEKU, true, LOGIC_NONE, RHT_CRAWL, RG_CRAWL, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawKneePads);
|
||||
|
||||
itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag);
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
//Exits
|
||||
//Technically involves an fake wall, but passing it lensless is intended in vanilla and it is well telegraphed
|
||||
//Backshot should be implemented here, or new regions should be added
|
||||
Entrance(RR_BOTW_CORRIDOR, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild/*CanCrawl*/;}),
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild/*CanCrawl*/;}),
|
||||
Entrance(RR_BOTW_CORRIDOR, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_KAK_WELL, []{return true;}),
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
|
||||
areaTable[RR_BOTW_CORRIDOR] = Region("Bottom of the Well Corridor", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_BOTW_ENTRYWAY, []{return logic->IsChild/*CanCrawl && CanClimb*/;}),
|
||||
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) /* && CanClimb*/;}),
|
||||
Entrance(RR_BOTW_PERIMETER, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
|
||||
});
|
||||
|
||||
@@ -46,11 +46,11 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
Entrance(RR_BOTW_MIDDLE, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
|
||||
Entrance(RR_BOTW_PIT_CAGE, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
|
||||
Entrance(RR_BOTW_HIDDEN_POTS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
|
||||
Entrance(RR_BOTW_CORNER_CRAWLSPACE, []{return logic->IsChild/*CanCrawl*/;}),
|
||||
Entrance(RR_BOTW_CORNER_CRAWLSPACE, []{return logic->CanUse(RG_CRAWL);}),
|
||||
//Climb always needed in case water is lowered out of logic
|
||||
Entrance(RR_BOTW_BEHIND_MOAT, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE) ||
|
||||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/*CanClimb*/);}),
|
||||
Entrance(RR_BOTW_NEAR_BOSS_LOWER, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) && logic->IsChild/*CanCrawl*/;}),
|
||||
Entrance(RR_BOTW_NEAR_BOSS_LOWER, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) && logic->CanUse(RG_CRAWL);}),
|
||||
//Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick
|
||||
//kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64
|
||||
Entrance(RR_BOTW_B3_OOZE, []{return true;}),
|
||||
@@ -84,7 +84,7 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
|
||||
areaTable[RR_BOTW_CORNER_CRAWLSPACE] = Region("Bottom of the Well Corner Crawlspace", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_BOTW_PERIMETER, []{return logic->IsChild;}),
|
||||
Entrance(RR_BOTW_PERIMETER, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_BOTW_HIDDEN_PITS_ROOM, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}),
|
||||
});
|
||||
|
||||
@@ -166,7 +166,7 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
//Exits
|
||||
//Climb always needed in case the water is lowered out of logic
|
||||
//Adult can ground jump out of the pit without climb but needs a way through the crawlspace
|
||||
Entrance(RR_BOTW_PERIMETER, []{return logic->IsChild/*CanCrawl*/ && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
|
||||
Entrance(RR_BOTW_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
|
||||
Entrance(RR_BOTW_NEAR_BOSS_UPPER, []{return true/*CanClimb or (isAdult && CanGroundJump)*/;}),
|
||||
});
|
||||
|
||||
@@ -280,14 +280,14 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_BOTW_ENTRYWAY, []{return logic->IsChild/*CanCrawl() && CanClimb()*/;}),
|
||||
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) /* && CanClimb()*/;}),
|
||||
Entrance(RR_BOTW_MQ_MIDDLE, []{return logic->Get(LOGIC_BOTW_MQ_OPENED_GATES);}),
|
||||
Entrance(RR_BOTW_MQ_PIT_CAGE, []{return AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
|
||||
//Climb always needed in case water is lowered out of logic
|
||||
Entrance(RR_BOTW_MQ_BEHIND_MOAT, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE) ||
|
||||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/*&& CanClimb()*/);}),
|
||||
Entrance(RR_BOTW_MQ_CORNER_CRAWLSPACE, []{return logic->IsChild/*CanCrawl()*/;}),
|
||||
Entrance(RR_BOTW_MQ_NEAR_BOSS_LOWER, []{return logic->IsChild/*CanCrawl()*/ && logic->Get(LOGIC_BOTW_LOWERED_WATER);}),
|
||||
Entrance(RR_BOTW_MQ_CORNER_CRAWLSPACE, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_BOTW_MQ_NEAR_BOSS_LOWER, []{return logic->CanUse(RG_CRAWL) && logic->Get(LOGIC_BOTW_LOWERED_WATER);}),
|
||||
Entrance(RR_BOTW_MQ_B3, []{return true;}),
|
||||
});
|
||||
|
||||
@@ -365,7 +365,7 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
});
|
||||
|
||||
areaTable[RR_BOTW_MQ_CORNER_CRAWLSPACE] = Region("Bottom of the Well MQ Northeast Crawlspace", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->IsChild;}),
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_BOTW_MQ_FLOORMASTER_ROOM, []{return logic->CanUseProjectile();}),
|
||||
});
|
||||
|
||||
@@ -379,14 +379,14 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
EventAccess(LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE, []{return logic->HasExplosives();}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_BOTW_MQ_FLOORMASTER_ROOM, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
|
||||
Entrance(RR_BOTW_MQ_FLOORMASTER_ROOM, []{return logic->CanUse(RG_CRAWL) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
|
||||
});
|
||||
|
||||
areaTable[RR_BOTW_MQ_NEAR_BOSS_LOWER] = Region("Bottom of the Well MQ Near Boss Lower", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
|
||||
//Exits
|
||||
//Climb always needed in case the water is lowered out of logic
|
||||
//Adult can ground jump out of the pit without climb but needs a way through the crawlspace
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->IsChild/*CanCrawl*/ && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
|
||||
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
|
||||
Entrance(RR_BOTW_MQ_NEAR_BOSS_UPPER, []{return true/*CanClimb*/;}),
|
||||
});
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ void RegionTable_Init_DekuTree() {
|
||||
//Exits
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return true;}),
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_BACK_ROOM, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && AnyAgeTime([]{return logic->BlastOrSmash();});}),
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->IsChild;}),
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->CanUse(RG_CRAWL);}),
|
||||
});
|
||||
|
||||
areaTable[RR_DEKU_TREE_BASEMENT_BACK_ROOM] = Region("Deku Tree Basement Back Room", SCENE_DEKU_TREE, {}, {
|
||||
@@ -168,7 +168,7 @@ void RegionTable_Init_DekuTree() {
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}),
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
|
||||
});
|
||||
|
||||
@@ -397,7 +397,7 @@ void RegionTable_Init_DekuTree() {
|
||||
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, logic->CanCutShrubs()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->IsChild && AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->CanUse(RG_CRAWL) && AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return true;}),
|
||||
//Using a bow to get past here as adult is a bit precise on standing position but simple, doing as as child requires a side-hop with the bow out to shoot through the torch and may be trick worthy
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
|
||||
@@ -425,7 +425,7 @@ void RegionTable_Init_DekuTree() {
|
||||
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, logic->CanCutShrubs()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->IsChild;}),
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return true;}),
|
||||
//If strength 0 is shuffled, add hovers or block push to the stick check
|
||||
//recoiling to skip swim is possible, but would be a trick
|
||||
|
||||
@@ -28,7 +28,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
|
||||
});
|
||||
|
||||
@@ -37,8 +37,8 @@ void RegionTable_Init_SpiritTemple() {
|
||||
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanBreakSmallCrates();}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOYER, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_BOXES, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOYER, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_BOXES, []{return logic->CanUse(RG_CRAWL);}),
|
||||
//Implies logic->CanKillEnemy(RE_KEESE)
|
||||
Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_ARMOS);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_ARMOS);});}),
|
||||
@@ -109,7 +109,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
||||
@@ -223,7 +223,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
//they will be able to exit the dungeon through the intended entrance and vice versa
|
||||
//for needing to open the west hand lock to block the intended child route
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && /*str0 &&*/
|
||||
logic->IsChild/*CanUse(RG_CRAWL)*/ && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
logic->CanUse(RG_CRAWL) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_INNER_WEST_HAND] = Region("Spirit Temple Inner West Hand", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
@@ -564,7 +564,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB, []{return logic->IsChild/*logic->CanUse(RG_CRAWL) && logic->HasSoul(RG_NABOORU_SOUL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB, []{return logic->CanUse(RG_CRAWL) /*&& logic->HasSoul(RG_NABOORU_SOUL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BEHIND_GEYSER, []{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_MEGATON_HAMMER) || (logic->CanStandingShield() && (logic->CanUseSword() || logic->CanUse(RG_STICKS))));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_HOLE, []{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}),
|
||||
});
|
||||
@@ -582,10 +582,10 @@ void RegionTable_Init_SpiritTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
//Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOYER, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOYER, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_GIBDO_GRAVES, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_ANUBIS_BRIDGE_CHEST, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_CHEST_SWITCH, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_CHEST_SWITCH, []{return logic->CanUse(RG_CRAWL) && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_GIBDO_GRAVES] = Region("Spirit Temple MQ Gibdo Graves", SCENE_SPIRIT_TEMPLE, {
|
||||
@@ -667,7 +667,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
EventAccess(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD_SIDE_HUB, []{return logic->CanUse(RG_CRAWL) && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}),
|
||||
//This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
@@ -706,7 +706,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
//This is because with 6 keys it becomes impossible to avoid opening either the west hand lock or the first child side lock
|
||||
//and either direction lets child reach colossus. CanHitSwitch and CanKillEnemy(RE_IRON_KNUCKLE) is implied.
|
||||
//Logic can then allow child back into spirit, putting 1F west in logic with only 6 keys without forwards entry
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->IsChild/*CanUse(RG_CRAWL)*/ && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->CanUse(RG_CRAWL) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6) && logic->MQSpiritStatueToSunBlock() &&
|
||||
(logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);})));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6);}),
|
||||
|
||||
@@ -45,18 +45,24 @@ void RegionTable_Init_CastleGrounds() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
|
||||
Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}),
|
||||
Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->BlastOrSmash();}),
|
||||
Entrance(RR_HC_LEDGE, []{return logic->CanUse(RG_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}),
|
||||
Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->CanUse(RG_CRAWL) && logic->BlastOrSmash();}),
|
||||
Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
|
||||
});
|
||||
|
||||
areaTable[RR_HC_LEDGE] = Region("HC Ledge", SCENE_HYRULE_CASTLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return true;}),
|
||||
Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_CRAWL);}),
|
||||
});
|
||||
|
||||
areaTable[RR_HC_GARDEN] = Region("HC Garden", SCENE_CASTLE_COURTYARD_ZELDA, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_HC_ZELDAS_LETTER, true),
|
||||
LOCATION(RC_SONG_FROM_IMPA, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return true;}),
|
||||
Entrance(RR_HC_LEDGE, []{return true;}), // if this ever gets shuffled leaving garden area should come out crawlspace
|
||||
});
|
||||
|
||||
areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, {
|
||||
|
||||
@@ -11,7 +11,6 @@ void RegionTable_Init_KokiriForest() {
|
||||
EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
|
||||
LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanGetNightTimeGS()),
|
||||
LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)),
|
||||
LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->CanGetNightTimeGS() &&
|
||||
@@ -28,8 +27,6 @@ void RegionTable_Init_KokiriForest() {
|
||||
LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild),
|
||||
LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild),
|
||||
LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild),
|
||||
LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild),
|
||||
LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild),
|
||||
LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
|
||||
LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
|
||||
LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))),
|
||||
@@ -53,9 +50,6 @@ void RegionTable_Init_KokiriForest() {
|
||||
LOCATION(RC_KF_CHILD_GRASS_10, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_11, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_12, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_ADULT_GRASS_1, logic->IsAdult && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_ADULT_GRASS_2, logic->IsAdult && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_ADULT_GRASS_3, logic->IsAdult && logic->CanCutShrubs()),
|
||||
@@ -78,6 +72,7 @@ void RegionTable_Init_KokiriForest() {
|
||||
LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_KF_BOULDER_LOOP, []{return logic->CanUse(RG_CRAWL);}),
|
||||
Entrance(RR_KF_LINKS_HOUSE, []{return true;}),
|
||||
Entrance(RR_KF_MIDOS_HOUSE, []{return true;}),
|
||||
Entrance(RR_KF_SARIAS_HOUSE, []{return true;}),
|
||||
@@ -90,6 +85,19 @@ void RegionTable_Init_KokiriForest() {
|
||||
Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
|
||||
});
|
||||
|
||||
areaTable[RR_KF_BOULDER_LOOP] = Region("KF Boulder Loop", SCENE_KOKIRI_FOREST, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
|
||||
LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild),
|
||||
LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_1, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_2, logic->IsChild && logic->CanCutShrubs()),
|
||||
LOCATION(RC_KF_CHILD_GRASS_MAZE_3, logic->IsChild && logic->CanCutShrubs()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_KOKIRI_FOREST, []{return logic->CanUse(RG_CRAWL);}),
|
||||
});
|
||||
|
||||
areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Region("KF Outside Deku Tree", SCENE_KOKIRI_FOREST, {
|
||||
//Events
|
||||
EventAccess(LOGIC_STICK_ACCESS, []{return logic->CanGetDekuBabaSticks();}),
|
||||
|
||||
@@ -56,7 +56,7 @@ void RegionTable_Init_LonLonRanch() {
|
||||
|
||||
areaTable[RR_LLR_TOWER] = Region("LLR Tower", SCENE_LON_LON_BUILDINGS, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild),
|
||||
LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild && logic->HasItem(RG_CRAWL)),
|
||||
LOCATION(RC_LLR_TOWER_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)),
|
||||
LOCATION(RC_LLR_TOWER_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)),
|
||||
}, {
|
||||
|
||||
@@ -227,6 +227,8 @@ bool Logic::HasItem(RandomizerGet itemName) {
|
||||
return CurrentUpgrade(UPG_SCALE) >= 1;
|
||||
case RG_GOLDEN_SCALE:
|
||||
return CurrentUpgrade(UPG_SCALE) >= 2;
|
||||
case RG_CRAWL:
|
||||
return CheckRandoInf(RAND_INF_CAN_CRAWL);
|
||||
case RG_POCKET_EGG:
|
||||
return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG);
|
||||
case RG_COJIRO:
|
||||
@@ -377,6 +379,8 @@ bool Logic::CanUse(RandomizerGet itemName) {
|
||||
// Misc. Items
|
||||
case RG_FISHING_POLE:
|
||||
return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies
|
||||
case RG_CRAWL:
|
||||
return IsChild;
|
||||
|
||||
// Bottle Items
|
||||
case RG_BOTTLE_WITH_BUGS:
|
||||
@@ -1713,6 +1717,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
|
||||
case RG_CLAIM_CHECK:
|
||||
SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state);
|
||||
break;
|
||||
case RG_CRAWL:
|
||||
SetRandoInf(RAND_INF_CAN_CRAWL, state);
|
||||
break;
|
||||
case RG_PROGRESSIVE_HOOKSHOT: {
|
||||
uint8_t i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -2576,6 +2583,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
|
||||
SetRandoInf(RAND_INF_CAN_SWIM, true);
|
||||
}
|
||||
|
||||
// If we're not shuffling crawl, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) {
|
||||
SetRandoInf(RAND_INF_CAN_CRAWL, true);
|
||||
}
|
||||
|
||||
// If we're not shuffling child's wallet, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) {
|
||||
SetRandoInf(RAND_INF_HAS_WALLET, true);
|
||||
|
||||
@@ -256,6 +256,7 @@ void Settings::CreateOptionDescriptions() {
|
||||
"\n"
|
||||
"If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n"
|
||||
"If you void out in Water Temple you will immediately be kicked out to prevent a softlock.";
|
||||
mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool.";
|
||||
mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling "
|
||||
"\"Skip Child Zelda\" disables this feature.\n"
|
||||
"\n"
|
||||
|
||||
@@ -4945,7 +4945,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) {
|
||||
void Randomizer::CreateCustomMessages() {
|
||||
// RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED
|
||||
// with GIMESSAGE(getItemID, itemID, english, german, french).
|
||||
const std::array<GetItemMessage, 122> getItemMessages = { {
|
||||
const std::array<GetItemMessage, 123> getItemMessages = { {
|
||||
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!",
|
||||
"Félicitation! Vous avez trouvé %gGreg%w!"),
|
||||
GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!",
|
||||
@@ -5290,6 +5290,9 @@ void Randomizer::CreateCustomMessages() {
|
||||
GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!",
|
||||
"Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!",
|
||||
"Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_CRAWL, ITEM_SCALE_SILVER, // TODO_TRANSLATE
|
||||
"You got the %rAbility to Crawl%w!&The power of kneecaps is yours!",
|
||||
"Vous obtenez la %rCapacité à Ramper%w!"),
|
||||
GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!",
|
||||
"Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!",
|
||||
"Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"),
|
||||
@@ -5454,6 +5457,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem);
|
||||
std::map<RandomizerGet, RandomizerInf> randomizerGetToRandInf = {
|
||||
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND },
|
||||
{ RG_BRONZE_SCALE, RAND_INF_CAN_SWIM },
|
||||
{ RG_CRAWL, RAND_INF_CAN_CRAWL },
|
||||
{ RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER },
|
||||
{ RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG },
|
||||
{ RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG },
|
||||
|
||||
@@ -530,6 +530,7 @@ typedef enum {
|
||||
RR_NOCTURNE_OF_SHADOW_WARP,
|
||||
RR_PRELUDE_OF_LIGHT_WARP,
|
||||
RR_KOKIRI_FOREST,
|
||||
RR_KF_BOULDER_LOOP,
|
||||
RR_KF_LINKS_HOUSE,
|
||||
RR_KF_MIDOS_HOUSE,
|
||||
RR_KF_SARIAS_HOUSE,
|
||||
@@ -636,6 +637,7 @@ typedef enum {
|
||||
RR_CASTLE_GROUNDS,
|
||||
RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE,
|
||||
RR_HYRULE_CASTLE_GROUNDS,
|
||||
RR_HC_LEDGE,
|
||||
RR_HC_GARDEN,
|
||||
RR_HC_GREAT_FAIRY_FOUNTAIN,
|
||||
RR_HC_STORMS_GROTTO,
|
||||
@@ -4603,6 +4605,7 @@ typedef enum {
|
||||
RG_HINT,
|
||||
RG_TYCOON_WALLET,
|
||||
RG_BRONZE_SCALE,
|
||||
RG_CRAWL,
|
||||
RG_CHILD_WALLET,
|
||||
RG_PROGRESSIVE_BOMBCHU_BAG,
|
||||
RG_QUIVER_INF,
|
||||
@@ -5809,6 +5812,7 @@ typedef enum {
|
||||
RHT_OCARINA_C_LEFT_BUTTON,
|
||||
RHT_OCARINA_C_RIGHT_BUTTON,
|
||||
RHT_BRONZE_SCALE,
|
||||
RHT_CRAWL,
|
||||
RHT_FISHING_POLE,
|
||||
RHT_SKELETON_KEY,
|
||||
RHT_EPONA,
|
||||
@@ -6405,6 +6409,7 @@ typedef enum {
|
||||
RSK_SHUFFLE_OCARINA,
|
||||
RSK_SHUFFLE_OCARINA_BUTTONS,
|
||||
RSK_SHUFFLE_SWIM,
|
||||
RSK_SHUFFLE_CRAWL,
|
||||
RSK_STARTING_DEKU_SHIELD,
|
||||
RSK_STARTING_KOKIRI_SWORD,
|
||||
RSK_STARTING_MASTER_SWORD,
|
||||
|
||||
@@ -1139,6 +1139,7 @@ DEFINE_RAND_INF(RAND_INF_ZF_BUSH_6)
|
||||
DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH)
|
||||
|
||||
DEFINE_RAND_INF(RAND_INF_CAN_SWIM)
|
||||
DEFINE_RAND_INF(RAND_INF_CAN_CRAWL)
|
||||
|
||||
DEFINE_RAND_INF(RAND_INF_HAS_WALLET)
|
||||
|
||||
|
||||
@@ -313,6 +313,10 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
Flags_SetRandomizerInf(RAND_INF_CAN_SWIM);
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) {
|
||||
Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL);
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) {
|
||||
Flags_SetRandomizerInf(RAND_INF_HAS_WALLET);
|
||||
}
|
||||
|
||||
@@ -778,6 +778,7 @@ void Settings::CreateOptions() {
|
||||
});
|
||||
OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]);
|
||||
OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]);
|
||||
OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]);
|
||||
OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]);
|
||||
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
|
||||
OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_POTS_OFF);
|
||||
@@ -2388,6 +2389,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
|
||||
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],
|
||||
&mOptions[RSK_SHUFFLE_SWIM],
|
||||
&mOptions[RSK_SHUFFLE_CRAWL],
|
||||
&mOptions[RSK_SHUFFLE_BEAN_SOULS],
|
||||
&mOptions[RSK_ROCS_FEATHER],
|
||||
&mOptions[RSK_BOMBCHU_BAG],
|
||||
@@ -2605,6 +2607,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_SHUFFLE_OCARINA],
|
||||
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],
|
||||
&mOptions[RSK_SHUFFLE_SWIM],
|
||||
&mOptions[RSK_SHUFFLE_CRAWL],
|
||||
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
|
||||
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
|
||||
&mOptions[RSK_SHUFFLE_MERCHANTS],
|
||||
|
||||
@@ -7633,6 +7633,10 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
|
||||
s32 i;
|
||||
|
||||
if (!LINK_IS_ADULT && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (interactWallFlags & 0x30)) {
|
||||
if (!GameInteractor_Should(VB_CRAWL, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wallPoly = this->actor.wallPoly;
|
||||
CollisionPoly_GetVerticesByBgId(wallPoly, this->actor.wallBgId, &play->colCtx, wallVertices);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user