Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions soh/include/z64save.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,35 @@ typedef struct {
typedef struct ShipRandomizerSaveContextData {
u8 triforcePiecesCollected;
u8 bombchuUpgradeLevel;
s8 silverShadowBlades;
s8 silverShadowPit;
s8 silverShadowSpikes;
s8 silverSpiritChild;
s8 silverSpiritSun;
s8 silverSpiritBoulders;
s8 silverBotw;
s8 silverIceCavernBlades;
s8 silverIceCavernBlock;
s8 silverGtgSlope;
s8 silverGtgLava;
s8 silverGtgWater;
s8 silverGanonLight;
s8 silverGanonForest;
s8 silverGanonFire;
s8 silverGanonSpirit;
s8 silverMqDodongosCavern;
s8 silverMqShadowBlades;
s8 silverMqShadowPit;
s8 silverMqShadowInvisibleBlades;
s8 silverMqShadowSpikes;
s8 silverMqSpiritLobby;
s8 silverMqSpiritBigWall;
s8 silverMqGtgSlope;
s8 silverMqGtgLava;
s8 silverMqGtgWater;
s8 silverMqGanonFire;
s8 silverMqGanonWater;
s8 silverMqGanonShadow;
} ShipRandomizerSaveContextData;

typedef struct ShipBossRushSaveContextData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,30 @@ typedef enum {
// - None
VB_SHOW_TITLE_CARD,

// #### `result`
// ```c
// this->actor.xyzDistToPlayerSq < 900.0f
// ```
// #### `args`
// - *EnGSwitch
VB_SILVER_COLLECT,

// #### `result`
// ```c
// true
// ```
// #### `args`
// - *EnGSwitch
VB_SILVER_COUNT_CHECK,

// #### `result`
// ```c
// Flags_GetSwitch(play, this->switchFlag)
// ```
// #### `args`
// - *EnGSwitch
VB_SILVER_DESPAWN,

// #### `result`
// ```c
// true
Expand Down
4 changes: 2 additions & 2 deletions soh/soh/Enhancements/randomizer/3drando/fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals
RandomizerGet locItem = location->GetPlacedRandomizerGet();
RandomizerCheckQuest quest = Rando::StaticData::GetLocation(loc)->GetQuest();
assert(ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || quest == RCQUEST_BOTH ||
(quest == RCQUEST_VANILLA && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsVanilla()) ||
(quest == RCQUEST_MQ && ctx->GetDungeons()->GetDungeonFromScene(parentRegion->scene)->IsMQ()));
(quest == RCQUEST_VANILLA && ctx->GetDungeonFromScene(parentRegion->scene)->IsVanilla()) ||
(quest == RCQUEST_MQ && ctx->GetDungeonFromScene(parentRegion->scene)->IsMQ()));

if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, logic->CalculatingAvailableChecks)) {
location->AddToPool();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ namespace Rando {
void StaticData::HintTable_Init_Exclude_Dungeon() {
// clang-format off

// TODO move these to region specific sections when hint text stable
hintTextTable[RHT_DODONGOS_CAVERN_SILVER] = HintText(CustomMessage("They say that silver in #Dodongo's Cavern# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_SHADOW_TEMPLE_SILVER] = HintText(CustomMessage("They say that silver in #Shadow Temple# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_SPIRIT_TEMPLE_SILVER] = HintText(CustomMessage("They say that silver in #Spirit Temple# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_BOTW_SILVER] = HintText(CustomMessage("They say that silver in #Bottom of the Well# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_ICE_CAVERN_SILVER] = HintText(CustomMessage("They say that silver in #Ice Cavern# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_GTG_SILVER] = HintText(CustomMessage("They say that silver in #Gerudo Training Ground# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));
hintTextTable[RHT_GANONS_CASTLE_SILVER] = HintText(CustomMessage("They say that silver in #Ganon's Castle# holds #[[1]]#.", TODO_TRANSLATE, TODO_TRANSLATE, {QM_RED, QM_GREEN}));

/*--------------------------
| DEKU TREE |
---------------------------*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,8 @@ void StaticData::HintTable_Init_Item() {
}, {
CustomMessage("sack of mice", /*german*/"ein Sack Mäuse", /*french*/"un Sac rempli de souris")});

hintTextTable[RHT_SILVER] = HintText(CustomMessage("a Silver Rupee", /*german*/ TODO_TRANSLATE, /*french*/ TODO_TRANSLATE));

hintTextTable[RHT_SKELETON_KEY] = HintText(CustomMessage("a Skeleton Key", /*german*/ "der Skelettschlüssel", /*french*/ "une Clé Squelette"),
// /*spanish*/una Llave Maestra
{
Expand Down
67 changes: 66 additions & 1 deletion soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void GenerateItemPool() {
1 + infiniteProgressive);
//clang-format on

int extraWallets =(ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET) ? 1 : 0) + (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET) ? 1 : 0);
int extraWallets = (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET) ? 1 : 0) + (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET) ? 1 : 0);
AddItemToPool(RG_PROGRESSIVE_WALLET, 3 + infiniteProgressive + extraWallets,
2 + infiniteProgressive + extraWallets,
2 + infiniteProgressive + extraWallets,
Expand Down Expand Up @@ -853,6 +853,71 @@ void GenerateItemPool() {
}
}

bool silverActive = ctx->GetOption(RSK_SHUFFLE_SILVER).Get();
if (silverActive) {
PlaceItemsForType(RCTYPE_SILVER, silverActive, silverActive);
}

if (ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_ON) ||
ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET)) {
ctx->possibleIceTrapModels.insert(RG_SHADOW_SILVER_BLADES); // ice traps reroll this into a random silver rupee
bool isWallet = ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_WALLET);
auto dungeons = ctx->GetDungeons();
if (dungeons->GetDungeonFromScene(SCENE_DODONGOS_CAVERN)->IsMQ()) {
AddFixedItemToPool(RG_DODONGOS_CAVERN_MQ_SILVER, isWallet ? 1 : 5, false);
}

if (dungeons->GetDungeonFromScene(SCENE_SHADOW_TEMPLE)->IsVanilla()) {
AddFixedItemToPool(RG_SHADOW_SILVER_BLADES, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SHADOW_SILVER_PIT, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SHADOW_SILVER_SPIKES, isWallet ? 1 : 5, false);
} else {
AddFixedItemToPool(RG_SHADOW_MQ_SILVER_BLADES, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SHADOW_MQ_SILVER_PIT, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SHADOW_MQ_SILVER_INVISIBLE_BLADES, isWallet ? 1 : 10, false);
AddFixedItemToPool(RG_SHADOW_MQ_SILVER_SPIKES, isWallet ? 1 : 10, false);
}

if (dungeons->GetDungeonFromScene(SCENE_SPIRIT_TEMPLE)->IsVanilla()) {
AddFixedItemToPool(RG_SPIRIT_SILVER_CHILD, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SPIRIT_SILVER_SUN, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SPIRIT_SILVER_BOULDERS, isWallet ? 1 : 5, false);
} else {
AddFixedItemToPool(RG_SPIRIT_MQ_SILVER_LOBBY, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_SPIRIT_MQ_SILVER_BIG_WALL, isWallet ? 1 : 5, false);
}

if (dungeons->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL)->IsVanilla()) {
AddFixedItemToPool(RG_BOTW_SILVER, isWallet ? 1 : 5, false);
}

if (dungeons->GetDungeonFromScene(SCENE_ICE_CAVERN)->IsVanilla()) {
AddFixedItemToPool(RG_ICE_CAVERN_SILVER_BLADES, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_ICE_CAVERN_SILVER_BLOCK, isWallet ? 1 : 5, false);
}

if (dungeons->GetDungeonFromScene(SCENE_GERUDO_TRAINING_GROUND)->IsVanilla()) {
AddFixedItemToPool(RG_GTG_SILVER_SLOPE, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GTG_SILVER_LAVA, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GTG_SILVER_WATER, isWallet ? 1 : 5, false);
} else {
AddFixedItemToPool(RG_GTG_MQ_SILVER_SLOPE, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GTG_MQ_SILVER_LAVA, isWallet ? 1 : 6, false);
AddFixedItemToPool(RG_GTG_MQ_SILVER_WATER, isWallet ? 1 : 3, false);
}

if (dungeons->GetDungeonFromScene(SCENE_INSIDE_GANONS_CASTLE)->IsVanilla()) {
AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_LIGHT, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_FOREST, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_FIRE, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GANONS_CASTLE_SILVER_SPIRIT, isWallet ? 1 : 5, false);
} else {
AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_FIRE, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_WATER, isWallet ? 1 : 5, false);
AddFixedItemToPool(RG_GANONS_CASTLE_MQ_SILVER_SHADOW, isWallet ? 1 : 5, false);
}
}

int maxHearts = 20;
switch (ctx->GetOption(RSK_ITEM_POOL).Get()) {
case RO_ITEM_POOL_PLENTIFUL:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ void GenerateStartingInventory() {
AddItemToInventory(RG_SHADOW_TEMPLE_BOSS_KEY);
}

if (ctx->GetOption(RSK_SHUFFLE_SILVER).Is(RO_SHUFFLE_SILVER_STARTWITH)) {
for (int rg = (int)RG_SHADOW_SILVER_BLADES; rg <= (int)RG_GANONS_CASTLE_MQ_SILVER_SHADOW; rg++) {
AddItemToInventory((RandomizerGet)rg);
}
}

// Add Ganon's Boss key with Triforce Hunt's Win setting so the game thinks it's obtainable from the start.
// During save init, the boss key isn't actually given and it's instead given when completing the triforce.
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) ||
Expand Down
5 changes: 5 additions & 0 deletions soh/soh/Enhancements/randomizer/SeedContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ void Context::GenerateLocationPool() {
mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_OFF)) ||
(location.GetRCType() == RCTYPE_FREESTANDING &&
mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) ||
(location.GetRCType() == RCTYPE_SILVER && !mOptions[RSK_SHUFFLE_SILVER]) ||
(location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) {
continue;
}
Expand Down Expand Up @@ -512,6 +513,10 @@ DungeonInfo* Context::GetDungeon(size_t key) const {
return mDungeons->GetDungeon(static_cast<DungeonKey>(key));
}

DungeonInfo* Context::GetDungeonFromScene(SceneID scene) const {
return mDungeons->GetDungeonFromScene(scene);
}

std::shared_ptr<Logic> Context::GetLogic() {
if (mLogic.get() == nullptr) {
mLogic = std::make_shared<Logic>();
Expand Down
1 change: 1 addition & 0 deletions soh/soh/Enhancements/randomizer/SeedContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Context {
std::shared_ptr<Dungeons> GetDungeons();
std::shared_ptr<Fishsanity> GetFishsanity();
DungeonInfo* GetDungeon(size_t key) const;
DungeonInfo* GetDungeonFromScene(SceneID key) const;
std::shared_ptr<Logic> GetLogic();
std::shared_ptr<Trials> GetTrials();
std::shared_ptr<Kaleido> GetKaleido();
Expand Down
Loading
Loading