summaryrefslogtreecommitdiff
path: root/soh/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'soh/src/code')
-rw-r--r--soh/src/code/code_80097A00.c2
-rw-r--r--soh/src/code/code_800EC960.c53
-rw-r--r--soh/src/code/z_actor.c16
-rw-r--r--soh/src/code/z_draw.c24
-rw-r--r--soh/src/code/z_en_item00.c36
-rw-r--r--soh/src/code/z_game_over.c22
-rw-r--r--soh/src/code/z_kankyo.c2
-rw-r--r--soh/src/code/z_message_PAL.c3
-rw-r--r--soh/src/code/z_parameter.c243
-rw-r--r--soh/src/code/z_play.c6
-rw-r--r--soh/src/code/z_player_lib.c10
-rw-r--r--soh/src/code/z_scene_table.c8
-rw-r--r--soh/src/code/z_sram.c510
13 files changed, 461 insertions, 474 deletions
diff --git a/soh/src/code/code_80097A00.c b/soh/src/code/code_80097A00.c
index f07102b0f..727c199ac 100644
--- a/soh/src/code/code_80097A00.c
+++ b/soh/src/code/code_80097A00.c
@@ -27,7 +27,7 @@ u16 gUpgradeCapacities[][4] = {
{ 0, 20, 30, 40 }, // Bomb Bags
{ 0, 0, 0, 0 }, // Unused (Scale)
{ 0, 0, 0, 0 }, // Unused (Strength)
- { 99, 200, 500, 500 }, // Wallets
+ { 99, 200, 500, 999 }, // Wallets
{ 0, 30, 40, 50 }, // Deku Seed Bullet Bags
{ 0, 10, 20, 30 }, // Deku Stick Upgrades
{ 0, 20, 30, 40 }, // Deku Nut Upgrades
diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c
index f7d073a8d..f5f1b980e 100644
--- a/soh/src/code/code_800EC960.c
+++ b/soh/src/code/code_800EC960.c
@@ -1246,6 +1246,7 @@ void Audio_StepFreqLerp(FreqLerp* lerp);
void func_800F56A8(void);
void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId);
s32 Audio_SetGanonDistVol(u8 targetVol);
+void Audio_PlayFanfare_Rando(GetItemEntry getItem);
// Right stick as virtual C buttons
#define RSTICK_UP 0x100000
@@ -3954,6 +3955,58 @@ void Audio_ResetSfxChannelState(void) {
sAudioCodeReverb = 0;
}
+// Function to play "get-item" fanfares according to the type of item obtained (used in rando)
+// Longer fanfares for medallions/stones/songs are behind the Cvar
+void Audio_PlayFanfare_Rando(GetItemEntry getItem) {
+ s32 temp1;
+ s16 getItemId = getItem.getItemId;
+ s16 itemId = getItem.itemId;
+
+ if (getItem.modIndex == MOD_NONE) {
+ if (((itemId >= ITEM_RUPEE_GREEN) && (itemId <= ITEM_RUPEE_GOLD)) || (itemId == ITEM_HEART)) {
+ Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
+ } else {
+ if (itemId == ITEM_HEART_CONTAINER ||
+ ((itemId == ITEM_HEART_PIECE_2) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) {
+ temp1 = NA_BGM_HEART_GET | 0x900;
+ } else {
+ temp1 = (itemId == ITEM_HEART_PIECE_2) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900;
+ }
+ // If we get a skulltula token or the "WINNER" heart, play "get small item"
+ // Also make sure "WINNER" heart is not the 4th heart piece.
+ if (itemId == ITEM_SKULL_TOKEN || (getItemId == GI_HEART_PIECE_WIN && itemId == ITEM_HEART_PIECE_2 &&
+ (gSaveContext.inventory.questItems & 0xF0000000) != 0x40000000)) {
+ temp1 = NA_BGM_SMALL_ITEM_GET | 0x900;
+ }
+ // If the setting is toggled on and we get special quest items (longer fanfares):
+ if (CVar_GetS32("gRandoQuestItemFanfares", 0) != 0) {
+ // If we get a medallion, play the "get a medallion" fanfare
+ if ((itemId >= ITEM_MEDALLION_FOREST) && (itemId <= ITEM_MEDALLION_LIGHT)) {
+ temp1 = NA_BGM_MEDALLION_GET | 0x900;
+ }
+ // If it's a Spiritual Stone, play the "get a spiritual stone" fanfare
+ if ((itemId >= ITEM_KOKIRI_EMERALD) && (itemId <= ITEM_ZORA_SAPPHIRE)) {
+ temp1 = NA_BGM_SPIRITUAL_STONE | 0x900;
+ }
+ // If the item we're getting is a song, play the "learned a song" fanfare
+ if ((itemId >= ITEM_SONG_MINUET) && (itemId <= ITEM_SONG_STORMS)) {
+ temp1 = NA_BGM_OCA_FAIRY_GET | 0x900;
+ }
+ }
+ Audio_PlayFanfare(temp1);
+ }
+ } else if (getItem.modIndex == MOD_RANDOMIZER) {
+ if ((itemId >= RG_BOTTLE_WITH_RED_POTION && itemId <= RG_BOTTLE_WITH_BIG_POE) ||
+ (itemId >= RG_DEKU_TREE_MAP && itemId <= RG_GANONS_CASTLE_SMALL_KEY)) {
+ temp1 = NA_BGM_ITEM_GET | 0x900;
+ } else {
+ // Just in case nothing else matches.
+ temp1 = NA_BGM_ITEM_GET | 0x900;
+ }
+ Audio_PlayFanfare(temp1);
+ }
+}
+
void func_800F3F3C(u8 arg0) {
if (gSoundBankMuted[0] != 1) {
Audio_StartSeq(SEQ_PLAYER_BGM_SUB, 0, NA_BGM_VARIOUS_SFX);
diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c
index f4fda54a1..1c87ed859 100644
--- a/soh/src/code/z_actor.c
+++ b/soh/src/code/z_actor.c
@@ -4701,6 +4701,20 @@ void Flags_SetInfTable(s32 flag) {
gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF));
}
+/**
+ * Tests if "randomizerInf" flag is set.
+ */
+s32 Flags_GetRandomizerInf(RandomizerInf flag) {
+ return gSaveContext.randomizerInf[flag >> 4] & (1 << (flag & 0xF));
+}
+
+/**
+ * Sets "randomizerInf" flag.
+ */
+void Flags_SetRandomizerInf(RandomizerInf flag) {
+ gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
+}
+
u32 func_80035BFC(GlobalContext* globalCtx, s16 arg1) {
u16 retTextId = 0;
@@ -6108,7 +6122,7 @@ GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, GlobalContext* glob
s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) {
GetItemEntry randoGetItem = GetChestGameRandoGetItem(room, ogDrawId, globalCtx);
- if (randoGetItem.itemId != RG_NONE) {
+ if (randoGetItem.itemId != ITEM_NONE) {
return randoGetItem.gid;
}
diff --git a/soh/src/code/z_draw.c b/soh/src/code/z_draw.c
index 203f3c3c9..7d98c8e2c 100644
--- a/soh/src/code/z_draw.c
+++ b/soh/src/code/z_draw.c
@@ -395,6 +395,20 @@ void GetItem_Draw(GlobalContext* globalCtx, s16 drawId) {
sDrawItemTable[drawId].drawFunc(globalCtx, drawId);
}
+/**
+ * Draw "Get Item" Model from a `GetItemEntry`
+ * Uses the Custom Draw Function if it exists, or just calls `GetItem_Draw`
+ */
+void GetItemEntry_Draw(GlobalContext* globalCtx, GetItemEntry getItemEntry) {
+ // RANDOTODO: Make this more flexible for easier toggling of individual item recolors in the future.
+ if (getItemEntry.drawFunc != NULL &&
+ (CVar_GetS32("gRandoMatchKeyColors", 0) || getItemEntry.getItemId == RG_DOUBLE_DEFENSE)) {
+ getItemEntry.drawFunc(globalCtx, &getItemEntry);
+ } else {
+ GetItem_Draw(globalCtx, getItemEntry.gid);
+ }
+}
+
// All remaining functions in this file are draw functions referenced in the table and called by the function above
/* 0x0178 */ u8 primXluColor[3];
@@ -813,12 +827,12 @@ void GetItem_DrawGenericMusicNote(GlobalContext* globalCtx, s16 drawId) {
OPEN_DISPS(globalCtx->state.gfxCtx);
- gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, __FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
- gsDPSetGrayscaleColor(POLY_OPA_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
- gsSPGrayscale(POLY_OPA_DISP++, true);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, __FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
+ gsDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
+ gsSPGrayscale(POLY_XLU_DISP++, true);
func_80093D18(globalCtx->state.gfxCtx);
- gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[0]);
- gsSPGrayscale(POLY_OPA_DISP++, false);
+ gSPDisplayList(POLY_XLU_DISP++, sDrawItemTable[drawId].dlists[0]);
+ gsSPGrayscale(POLY_XLU_DISP++, false);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c
index 899984b89..d4ddd18e9 100644
--- a/soh/src/code/z_en_item00.c
+++ b/soh/src/code/z_en_item00.c
@@ -519,7 +519,8 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) {
if (!gSaveContext.n64ddFlag) {
func_8002F554(&this->actor, globalCtx, getItemId);
} else {
- getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
+ getItem = Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, getItemId);
+ getItem.getItemFrom = ITEM_FROM_FREESTANDING;
GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem);
}
}
@@ -686,7 +687,8 @@ void func_8001E5C8(EnItem00* this, GlobalContext* globalCtx) {
func_8002F434(&this->actor, globalCtx, this->getItemId, 50.0f, 80.0f);
} else {
GetItemEntry getItemEntry =
- Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
+ Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, this->getItemId);
+ getItemEntry.getItemFrom = ITEM_FROM_FREESTANDING;
GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 50.0f, 80.0f);
}
this->unk_15A++;
@@ -911,8 +913,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
if (!gSaveContext.n64ddFlag) {
func_8002F554(&this->actor, globalCtx, getItemId);
} else {
- getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
+ getItem = Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, getItemId);
getItemId = getItem.getItemId;
+ getItem.getItemFrom = ITEM_FROM_FREESTANDING;
GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem);
}
}
@@ -1290,10 +1293,11 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI
switch (giEntry.itemId) {
case RG_MAGIC_SINGLE:
case RG_MAGIC_DOUBLE:
+ case RG_MAGIC_BEAN_PACK:
color_slot = 0;
break;
case RG_DOUBLE_DEFENSE:
- color_slot = 1;
+ color_slot = 8;
break;
default:
return;
@@ -1305,14 +1309,14 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI
s16* colors[9][3] = {
{ 34, 255, 76 }, // Minuet and Magic Upgrades Colors
- { 177, 35, 35 }, // Bolero and Double Defense Colors
+ { 177, 35, 35 }, // Bolero Colors
{ 115, 251, 253 }, // Serenade Color
{ 177, 122, 35 }, // Requiem Color
{ 177, 28, 212 }, // Nocturne Color
{ 255, 255, 92 }, // Prelude Color
{ 31, 152, 49 }, // Stick Upgrade Color
{ 222, 182, 20 }, // Nut Upgrade Color
- { 255, 255, 255 } // White Color placeholder
+ { 255, 255, 255 } // Double Defense Color
};
s16* colorsEnv[9][3] = {
@@ -1338,8 +1342,15 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI
velocity.y = -0.05f;
accel.y = -0.025f;
pos.x = Rand_CenteredFloat(32.0f) + Parent->world.pos.x;
- pos.y = (Rand_ZeroOne() * 6.0f) + Parent->world.pos.y + 25;
+ // Shop items are rendered at a different height than the rest, so a different y offset is required
+ if (Parent->id == ACTOR_EN_GIRLA) {
+ pos.y = (Rand_ZeroOne() * 6.0f) + Parent->world.pos.y + 5;
+ } else {
+ pos.y = (Rand_ZeroOne() * 6.0f) + Parent->world.pos.y + 25;
+ }
pos.z = Rand_CenteredFloat(32.0f) + Parent->world.pos.z;
+
+
EffectSsKiraKira_SpawnDispersed(globalCtx, &pos, &velocity, &accel, &primColor, &envColor, 1000, 50);
}
@@ -1379,9 +1390,9 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) {
f32 mtxScale = 16.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItemEntry randoGetItemEntry =
- Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
+ Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, this->getItemId);
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry);
- GetItem_Draw(globalCtx, randoGetItemEntry.gid);
+ GetItemEntry_Draw(globalCtx, randoGetItemEntry);
} else {
s32 texIndex = this->actor.params - 3;
@@ -1441,9 +1452,9 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) {
f32 mtxScale = 16.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItemEntry randoGetItemEntry =
- Randomizer_GetRandomizedItem(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum);
+ Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, GI_HEART_PIECE);
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry);
- GetItem_Draw(globalCtx, randoGetItemEntry.gid);
+ GetItemEntry_Draw(globalCtx, randoGetItemEntry);
} else {
s32 pad;
@@ -1506,7 +1517,8 @@ s16 func_8001F404(s16 dropId) {
}
}
- if (CVar_GetS32("gBombchuDrops", 0) &&
+ if ((CVar_GetS32("gBombchuDrops", 0) ||
+ (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1)) &&
(dropId == ITEM00_BOMBS_A || dropId == ITEM00_BOMBS_B || dropId == ITEM00_BOMBS_SPECIAL)) {
dropId = EnItem00_ConvertBombDropToBombchu(dropId);
}
diff --git a/soh/src/code/z_game_over.c b/soh/src/code/z_game_over.c
index 86ba7c6e1..bb4be8711 100644
--- a/soh/src/code/z_game_over.c
+++ b/soh/src/code/z_game_over.c
@@ -33,19 +33,21 @@ void GameOver_Update(GlobalContext* globalCtx) {
gSaveContext.eventInf[1] &= ~1;
// search inventory for spoiling items and revert if necessary
- for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) {
- if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[i]) {
- INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i];
-
- // search c buttons for the found spoiling item and revert if necessary
- for (j = 1; j < ARRAY_COUNT(gSaveContext.equips.buttonItems); j++) {
- if (gSaveContext.equips.buttonItems[j] == gSpoilingItems[i]) {
- gSaveContext.equips.buttonItems[j] = gSpoilingItemReverts[i];
- Interface_LoadItemIcon1(globalCtx, j);
+ if (!(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) {
+ for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) {
+ if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[i]) {
+ INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i];
+
+ // search c buttons for the found spoiling item and revert if necessary
+ for (j = 1; j < ARRAY_COUNT(gSaveContext.equips.buttonItems); j++) {
+ if (gSaveContext.equips.buttonItems[j] == gSpoilingItems[i]) {
+ gSaveContext.equips.buttonItems[j] = gSpoilingItemReverts[i];
+ Interface_LoadItemIcon1(globalCtx, j);
+ }
}
}
}
- }
+ }
// restore "temporary B" to the B Button if not a sword item
if (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI &&
diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c
index 34503619e..540e58a76 100644
--- a/soh/src/code/z_kankyo.c
+++ b/soh/src/code/z_kankyo.c
@@ -2095,7 +2095,7 @@ void func_80075B44(GlobalContext* globalCtx) {
gSaveContext.dogIsLost = true;
func_80078884(NA_SE_EV_CHICKEN_CRY_M);
if ((Inventory_ReplaceItem(globalCtx, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
- Inventory_ReplaceItem(globalCtx, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO)) &&
+ Inventory_HatchPocketCucco(globalCtx)) &&
globalCtx->csCtx.state == 0 && !Player_InCsMode(globalCtx)) {
Message_StartTextbox(globalCtx, 0x3066, NULL);
}
diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c
index 693187fb7..4ed8a3f62 100644
--- a/soh/src/code/z_message_PAL.c
+++ b/soh/src/code/z_message_PAL.c
@@ -1696,7 +1696,7 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
// Increments text id based on piece of heart count, assumes the piece of heart text is all
// in order and that you don't have more than the intended amount of heart pieces.
textId += (gSaveContext.inventory.questItems & 0xF0000000 & 0xF0000000) >> 0x1C;
- } else if (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_SWORD, 2)) {
+ } else if (!gSaveContext.n64ddFlag && (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_SWORD, 2))) {
textId = 0xB; // Traded Giant's Knife for Biggoron Sword
} else if (msgCtx->textId == 0xB4 && (gSaveContext.eventChkInf[9] & 0x40)) {
textId = 0xB5; // Destroyed Gold Skulltula
@@ -1718,6 +1718,7 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
gSaveContext.eventInf[0] = gSaveContext.eventInf[1] = gSaveContext.eventInf[2] = gSaveContext.eventInf[3] = 0;
}
+ // RANDOTODO: Use this for ice trap messages
if (CustomMessage_RetrieveIfExists(globalCtx)) {
osSyncPrintf("Found custom message");
} else if (sTextIsCredits) {
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index d5b8113c3..83a1b19e8 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -3,6 +3,7 @@
#include "textures/parameter_static/parameter_static.h"
#include "textures/do_action_static/do_action_static.h"
#include "textures/icon_item_static/icon_item_static.h"
+#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#ifdef _MSC_VER
#include <stdlib.h>
@@ -1574,6 +1575,17 @@ void func_80084BF4(GlobalContext* globalCtx, u16 flag) {
}
}
+/**
+ * @brief Adds the given item to Link's inventory.
+ *
+ * NOTE: This function has been edited to be safe to use with a NULL globalCtx.
+ * If you need to add to this function, be sure you check if the globalCtx is not
+ * NULL before doing any operations requiring it.
+ *
+ * @param globalCtx
+ * @param item
+ * @return u8
+ */
u8 Item_Give(GlobalContext* globalCtx, u8 item) {
static s16 sAmmoRefillCounts[] = { 5, 10, 20, 30, 5, 10, 30, 0, 5, 20, 1, 5, 20, 50, 200, 10 };
s16 i;
@@ -1646,15 +1658,21 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
} else if ((item >= ITEM_SWORD_KOKIRI) && (item <= ITEM_SWORD_BGS)) {
gSaveContext.inventory.equipment |= gBitFlags[item - ITEM_SWORD_KOKIRI] << gEquipShifts[EQUIP_SWORD];
+ // Both Giant's Knife and Biggoron Sword have the same Item ID, so this part handles both of them
if (item == ITEM_SWORD_BGS) {
gSaveContext.swordHealth = 8;
- if (ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xF
- ||(gSaveContext.n64ddFlag && ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xE)) { // In rando, when buying Giant's Knife, also check
- gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD]; // for 0xE in case we don't have Kokiri Sword
+ // In rando, when buying Giant's Knife, also check
+ // for 0xE in case we don't have Kokiri Sword
+ if (ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xF || (gSaveContext.n64ddFlag && ALL_EQUIP_VALUE(EQUIP_SWORD) == 0xE)) {
+
+ gSaveContext.inventory.equipment ^= 8 << gEquipShifts[EQUIP_SWORD];
+
if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
- Interface_LoadItemIcon1(globalCtx, 0);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, 0);
+ }
}
}
@@ -1662,7 +1680,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
gSaveContext.equips.equipment &= 0xFFF0;
gSaveContext.equips.equipment |= 0x0002;
- Interface_LoadItemIcon1(globalCtx, 0);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, 0);
+ }
}
PerformAutosave(globalCtx, item);
@@ -1681,7 +1701,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
return ITEM_NONE;
} else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) {
// Boss Key, Compass, and Dungeon Map exceptions for rando.
- if (gSaveContext.n64ddFlag) {
+ // Rando should never be able to get here for Link's Pocket unless something goes wrong,
+ // but we check for a globalCtx here so the game won't crash if we do somehow get here.
+ if (gSaveContext.n64ddFlag && globalCtx != NULL) {
if (globalCtx->sceneNum == 13) { // ganon's castle -> ganon's tower
gSaveContext.inventory.dungeonItems[10] |= 1;
} else if (globalCtx->sceneNum == 92) { // Desert Colossus -> Spirit Temple.
@@ -1695,8 +1717,10 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
PerformAutosave(globalCtx, item);
return ITEM_NONE;
} else if (item == ITEM_KEY_SMALL) {
- // Small key exceptions for rando.
- if (gSaveContext.n64ddFlag) {
+ // Small key exceptions for rando with keysanity off.
+ // Rando should never be able to get here for Link's Pocket unless something goes wrong,
+ // but we check for a globalCtx here so the game won't crash if we do somehow get here.
+ if (gSaveContext.n64ddFlag && globalCtx != NULL) {
if (globalCtx->sceneNum == 10) { // ganon's tower -> ganon's castle
if (gSaveContext.inventory.dungeonKeys[13] < 0) {
gSaveContext.inventory.dungeonKeys[13] = 1;
@@ -1721,7 +1745,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
}
}
}
-
if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) {
gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1;
PerformAutosave(globalCtx, item);
@@ -1859,7 +1882,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
if (gSaveContext.equips.buttonItems[i] == ITEM_HOOKSHOT) {
gSaveContext.equips.buttonItems[i] = ITEM_LONGSHOT;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
}
}
// update the adult/child equips when rando'd (accounting for equp swapped hookshot as child)
@@ -1867,7 +1892,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (i = 1; i < ARRAY_COUNT(gSaveContext.adultEquips.buttonItems); i++) {
if (gSaveContext.adultEquips.buttonItems[i] == ITEM_HOOKSHOT) {
gSaveContext.adultEquips.buttonItems[i] = ITEM_LONGSHOT;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
}
}
}
@@ -1875,7 +1902,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (i = 1; i < ARRAY_COUNT(gSaveContext.childEquips.buttonItems); i++) {
if (gSaveContext.childEquips.buttonItems[i] == ITEM_HOOKSHOT) {
gSaveContext.childEquips.buttonItems[i] = ITEM_LONGSHOT;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
}
}
}
@@ -2034,7 +2063,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (i = 1; i < ARRAY_COUNT(gSaveContext.adultEquips.buttonItems); i++) {
if (gSaveContext.adultEquips.buttonItems[i] == ITEM_OCARINA_FAIRY) {
gSaveContext.adultEquips.buttonItems[i] = ITEM_OCARINA_TIME;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
}
}
}
@@ -2042,7 +2073,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (i = 1; i < ARRAY_COUNT(gSaveContext.childEquips.buttonItems); i++) {
if (gSaveContext.childEquips.buttonItems[i] == ITEM_OCARINA_FAIRY) {
gSaveContext.childEquips.buttonItems[i] = ITEM_OCARINA_TIME;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
}
}
}
@@ -2070,15 +2103,21 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
return ITEM_NONE;
} else if (item == ITEM_HEART) {
osSyncPrintf("回復ハート回復ハート回復ハート\n"); // "Recovery Heart"
- Health_ChangeBy(globalCtx, 0x10);
+ if (globalCtx != NULL) {
+ Health_ChangeBy(globalCtx, 0x10);
+ }
PerformAutosave(globalCtx, item);
return item;
} else if (item == ITEM_MAGIC_SMALL) {
if (gSaveContext.unk_13F0 != 10) {
- Magic_Fill(globalCtx);
+ if (globalCtx != NULL) {
+ Magic_Fill(globalCtx);
+ }
}
- func_80087708(globalCtx, 12, 5);
+ if (globalCtx != NULL) {
+ func_80087708(globalCtx, 12, 5);
+ }
if (!(gSaveContext.infTable[25] & 0x100)) {
gSaveContext.infTable[25] |= 0x100;
@@ -2090,10 +2129,13 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
return item;
} else if (item == ITEM_MAGIC_LARGE) {
if (gSaveContext.unk_13F0 != 10) {
- Magic_Fill(globalCtx);
+ if (globalCtx != NULL) {
+ Magic_Fill(globalCtx);
+ }
+ }
+ if (globalCtx != NULL) {
+ func_80087708(globalCtx, 24, 5);
}
-
- func_80087708(globalCtx, 24, 5);
if (!(gSaveContext.infTable[25] & 0x100)) {
gSaveContext.infTable[25] |= 0x100;
@@ -2136,7 +2178,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
for (int buttonIndex = 1; buttonIndex < ARRAY_COUNT(gSaveContext.equips.buttonItems); buttonIndex++) {
if ((temp + i) == gSaveContext.equips.cButtonSlots[buttonIndex - 1]) {
gSaveContext.equips.buttonItems[buttonIndex] = item;
- Interface_LoadItemIcon2(globalCtx, buttonIndex);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon2(globalCtx, buttonIndex);
+ }
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(buttonIndex)] = BTN_ENABLED;
break;
}
@@ -2161,6 +2205,10 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
gSaveContext.itemGetInf[1] |= 0x8000;
}
+ if (item >= ITEM_POCKET_EGG) {
+ gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(item);
+ }
+
temp = INV_CONTENT(item);
INV_CONTENT(item) = item;
@@ -2169,7 +2217,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
if (temp == gSaveContext.equips.buttonItems[i]) {
if (item != ITEM_SOLD_OUT) {
gSaveContext.equips.buttonItems[i] = item;
- Interface_LoadItemIcon1(globalCtx, i);
+ if (globalCtx != NULL) {
+ Interface_LoadItemIcon1(globalCtx, i);
+ }
} else {
gSaveContext.equips.buttonItems[i] = ITEM_NONE;
}
@@ -2214,6 +2264,14 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
return RG_NONE;
}
+ if (item == RG_MAGIC_BEAN_PACK) {
+ if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) {
+ INV_CONTENT(ITEM_BEAN) = ITEM_BEAN;
+ AMMO(ITEM_BEAN) = 10;
+ }
+ return RG_NONE;
+ }
+
if (item == RG_DOUBLE_DEFENSE) {
gSaveContext.doubleDefense = true;
gSaveContext.inventory.defenseHearts = 20;
@@ -2259,6 +2317,106 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
return ITEM_NONE;
}
}
+ } else if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) ||
+ (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) ||
+ (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) ||
+ (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) {
+ int mapIndex = gSaveContext.mapIndex;
+ switch (item) {
+ case RG_DEKU_TREE_MAP:
+ case RG_DEKU_TREE_COMPASS:
+ mapIndex = SCENE_YDAN;
+ break;
+ case RG_DODONGOS_CAVERN_MAP:
+ case RG_DODONGOS_CAVERN_COMPASS:
+ mapIndex = SCENE_DDAN;
+ break;
+ case RG_JABU_JABUS_BELLY_MAP:
+ case RG_JABU_JABUS_BELLY_COMPASS:
+ mapIndex = SCENE_BDAN;
+ break;
+ case RG_FOREST_TEMPLE_MAP:
+ case RG_FOREST_TEMPLE_COMPASS:
+ case RG_FOREST_TEMPLE_SMALL_KEY:
+ case RG_FOREST_TEMPLE_BOSS_KEY:
+ mapIndex = SCENE_BMORI1;
+ break;
+ case RG_FIRE_TEMPLE_MAP:
+ case RG_FIRE_TEMPLE_COMPASS:
+ case RG_FIRE_TEMPLE_SMALL_KEY:
+ case RG_FIRE_TEMPLE_BOSS_KEY:
+ mapIndex = SCENE_HIDAN;
+ break;
+ case RG_WATER_TEMPLE_MAP:
+ case RG_WATER_TEMPLE_COMPASS:
+ case RG_WATER_TEMPLE_SMALL_KEY:
+ case RG_WATER_TEMPLE_BOSS_KEY:
+ mapIndex = SCENE_MIZUSIN;
+ break;
+ case RG_SPIRIT_TEMPLE_MAP:
+ case RG_SPIRIT_TEMPLE_COMPASS:
+ case RG_SPIRIT_TEMPLE_SMALL_KEY:
+ case RG_SPIRIT_TEMPLE_BOSS_KEY:
+ mapIndex = SCENE_JYASINZOU;
+ break;
+ case RG_SHADOW_TEMPLE_MAP:
+ case RG_SHADOW_TEMPLE_COMPASS:
+ case RG_SHADOW_TEMPLE_SMALL_KEY:
+ case RG_SHADOW_TEMPLE_BOSS_KEY:
+ mapIndex = SCENE_HAKADAN;
+ break;
+ case RG_BOTTOM_OF_THE_WELL_MAP:
+ case RG_BOTTOM_OF_THE_WELL_COMPASS:
+ case RG_BOTTOM_OF_THE_WELL_SMALL_KEY:
+ mapIndex = SCENE_HAKADANCH;
+ break;
+ case RG_ICE_CAVERN_MAP:
+ case RG_ICE_CAVERN_COMPASS:
+ mapIndex = SCENE_ICE_DOUKUTO;
+ break;
+ case RG_GANONS_CASTLE_BOSS_KEY:
+ mapIndex = SCENE_GANON;
+ break;
+ case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY:
+ mapIndex = SCENE_MEN;
+ break;
+ case RG_GERUDO_FORTRESS_SMALL_KEY:
+ mapIndex = SCENE_GERUDOWAY;
+ break;
+ case RG_GANONS_CASTLE_SMALL_KEY:
+ mapIndex = SCENE_GANONTIKA;
+ break;
+ }
+
+ if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) {
+ if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) {
+ gSaveContext.inventory.dungeonKeys[mapIndex] = 1;
+ return RG_NONE;
+ } else {
+ gSaveContext.inventory.dungeonKeys[mapIndex]++;
+ return RG_NONE;
+ }
+ } else {
+ int bitmask;
+ if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) {
+ bitmask = gBitFlags[2];
+ } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) {
+ bitmask = gBitFlags[1];
+ } else {
+ bitmask = gBitFlags[0];
+ }
+
+ gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask;
+ return RG_NONE;
+ }
+ }
+
+ if (item == RG_TYCOON_WALLET) {
+ Inventory_ChangeUpgrade(UPG_WALLET, 3);
+ if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
+ Rupees_ChangeBy(999);
+ }
+ return RG_NONE;
}
temp = gSaveContext.inventory.items[slot];
@@ -2268,7 +2426,6 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
return temp;
}
-
u8 Item_CheckObtainability(u8 item) {
s16 i;
s16 slot = SLOT(item);
@@ -2321,6 +2478,13 @@ u8 Item_CheckObtainability(u8 item) {
} else {
return ITEM_NONE;
}
+ } else if ( gSaveContext.n64ddFlag &&
+ ((item >= RG_GERUDO_FORTRESS_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY) ||
+ (item >= RG_FOREST_TEMPLE_BOSS_KEY) && (item <= RG_GANONS_CASTLE_BOSS_KEY) ||
+ (item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP) ||
+ (item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS))
+ ) {
+ return ITEM_NONE;
} else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) {
return ITEM_NONE;
} else if (item == ITEM_KEY_SMALL) {
@@ -2507,6 +2671,17 @@ s32 Inventory_HasEmptyBottle(void) {
}
}
+bool Inventory_HasEmptyBottleSlot(void) {
+ u8* items = gSaveContext.inventory.items;
+
+ return (
+ items[SLOT_BOTTLE_1] == ITEM_NONE ||
+ items[SLOT_BOTTLE_2] == ITEM_NONE ||
+ items[SLOT_BOTTLE_3] == ITEM_NONE ||
+ items[SLOT_BOTTLE_4] == ITEM_NONE
+ );
+}
+
s32 Inventory_HasSpecificBottle(u8 bottleItem) {
u8* items = gSaveContext.inventory.items;
@@ -2568,6 +2743,21 @@ s32 Inventory_ConsumeFairy(GlobalContext* globalCtx) {
return 0;
}
+bool Inventory_HatchPocketCucco(GlobalContext* globalCtx) {
+ if (!gSaveContext.n64ddFlag) {
+ return Inventory_ReplaceItem(globalCtx, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO);
+ }
+
+ if (!PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_POCKET_EGG)) {
+ return 0;
+ }
+
+ gSaveContext.adultTradeItems &= ~ADULT_TRADE_FLAG(ITEM_POCKET_EGG);
+ gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(ITEM_POCKET_CUCCO);
+ Inventory_ReplaceItem(globalCtx, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO);
+ return 1;
+}
+
void func_80086D5C(s32* buf, u16 size) {
u16 i;
@@ -4509,14 +4699,15 @@ void Interface_Draw(GlobalContext* globalCtx) {
static s16 D_80125B1C[][3] = {
{ 0, 150, 0 }, { 100, 255, 0 }, { 255, 255, 255 }, { 0, 0, 0 }, { 255, 255, 255 },
};
- static s16 rupeeDigitsFirst[] = { 1, 0, 0 };
- static s16 rupeeDigitsCount[] = { 2, 3, 3 };
+ static s16 rupeeDigitsFirst[] = { 1, 0, 0, 0 };
+ static s16 rupeeDigitsCount[] = { 2, 3, 3, 3 };
// courtesy of https://github.com/TestRunnerSRL/OoT-Randomizer/blob/Dev/ASM/c/hud_colors.c
- static s16 rupeeWalletColors[3][3] = {
+ static s16 rupeeWalletColors[4][3] = {
{ 0xC8, 0xFF, 0x64 }, // Base Wallet (Green)
{ 0x82, 0x82, 0xFF }, // Adult's Wallet (Blue)
{ 0xFF, 0x64, 0x64 }, // Giant's Wallet (Red)
+ { 0xFF, 0x5A, 0xFF }, // Tycoon's Wallet (Purple). Only used in rando shopsanity.
};
Color_RGB8 rColor_ori = { 200, 255, 100 };
Color_RGB8 rColor;
diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c
index ff5e879ce..b10ee5bf9 100644
--- a/soh/src/code/z_play.c
+++ b/soh/src/code/z_play.c
@@ -200,7 +200,7 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c
Player* player = GET_PLAYER(globalCtx);
if (gSaveContext.entranceIndex == 0x050F && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
- !Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) {
+ !Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF && !gSaveContext.pendingIceTrapCount) {
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME);
GiveItemEntryWithoutActor(globalCtx, getItemEntry);
player->pendingFlag.flagID = 0x1F;
@@ -245,7 +245,7 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi
!Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
globalCtx->sceneLoadFlag == 0) {
GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT);
- if (player->pendingFlag.flagType == FLAG_NONE && GiveItemEntryWithoutActor(globalCtx, getItem)) {
+ if (GiveItemEntryWithoutActor(globalCtx, getItem)) {
player->pendingFlag.flagID = 0x1E;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
@@ -401,7 +401,7 @@ void Gameplay_Init(GameState* thisx) {
gSaveContext.bgsDayCount++;
gSaveContext.dogIsLost = true;
if (Inventory_ReplaceItem(globalCtx, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
- Inventory_ReplaceItem(globalCtx, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO)) {
+ Inventory_HatchPocketCucco(globalCtx)) {
Message_StartTextbox(globalCtx, 0x3066, NULL);
}
gSaveContext.nextDayTime = 0xFFFE;
diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c
index 315af9e9e..522e7d851 100644
--- a/soh/src/code/z_player_lib.c
+++ b/soh/src/code/z_player_lib.c
@@ -1170,7 +1170,15 @@ void Player_DrawGetItemImpl(GlobalContext* globalCtx, Player* this, Vec3f* refPo
Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY);
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
- GetItem_Draw(globalCtx, drawIdPlusOne - 1);
+ if (!(this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId == RG_ICE_TRAP)) {
+ // RANDOTODO: Make this more flexible for easier toggling of individual item recolors in the future.
+ if (this->getItemEntry.drawFunc != NULL &&
+ (CVar_GetS32("gRandoMatchKeyColors", 0) || this->getItemEntry.getItemId == RG_DOUBLE_DEFENSE)) {
+ this->getItemEntry.drawFunc(globalCtx, &this->getItemEntry);
+ } else {
+ GetItem_Draw(globalCtx, drawIdPlusOne - 1);
+ }
+ }
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
diff --git a/soh/src/code/z_scene_table.c b/soh/src/code/z_scene_table.c
index 4987cba2f..9bf710af1 100644
--- a/soh/src/code/z_scene_table.c
+++ b/soh/src/code/z_scene_table.c
@@ -23,6 +23,8 @@
#include "overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h"
+#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
+
#define ENTRANCE(scene, spawn, continueBgm, displayTitleCard, fadeIn, fadeOut) \
{ \
scene, spawn, \
@@ -2136,7 +2138,11 @@ void func_8009EE44(GlobalContext* globalCtx) {
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
- if ((globalCtx->roomCtx.unk_74[0] == 0) && (INV_CONTENT(ITEM_COJIRO) == ITEM_COJIRO)) {
+ bool playerHasCojiro = INV_CONTENT(ITEM_COJIRO) == ITEM_COJIRO;
+ if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
+ playerHasCojiro = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO);
+ }
+ if ((globalCtx->roomCtx.unk_74[0] == 0) && playerHasCojiro) {
if (globalCtx->roomCtx.unk_74[1] == 50) {
func_8002F7DC(&GET_PLAYER(globalCtx)->actor, NA_SE_EV_CHICKEN_CRY_M);
globalCtx->roomCtx.unk_74[0] = 1;
diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c
index c71bb4def..16cbcdd33 100644
--- a/soh/src/code/z_sram.c
+++ b/soh/src/code/z_sram.c
@@ -3,9 +3,11 @@
#include <string.h>
#include <soh/Enhancements/randomizer/randomizerTypes.h>
+#include <soh/Enhancements/randomizer/randomizer_inf.h>
+#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#define NUM_DUNGEONS 8
-#define NUM_TRIALS 6
+#define NUM_COWS 10
/**
* Initialize new save.
@@ -51,31 +53,6 @@ void GiveLinkRupees(int numOfRupees) {
}
}
-void GiveLinkRupeesByGetItemId(GetItemID giid) {
- if (giid == GI_RUPEE_GREEN) {
- GiveLinkRupees(1);
- } else if (giid == GI_RUPEE_BLUE) {
- GiveLinkRupees(5);
- } else if (giid == GI_RUPEE_RED) {
- GiveLinkRupees(20);
- } else if (giid == GI_RUPEE_PURPLE) {
- GiveLinkRupees(50);
- } else if (giid == GI_RUPEE_GOLD) {
- GiveLinkRupees(100);
- }
-}
-
-void GiveLinkBombchus(GetItemID giid) {
- INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU;
- if (giid == GI_BOMBCHUS_5) {
- AMMO(ITEM_BOMBCHU) += 5;
- } else if (giid == GI_BOMBCHUS_10) {
- AMMO(ITEM_BOMBCHU) += 10;
- } else if (giid == GI_BOMBCHUS_20) {
- AMMO(ITEM_BOMBCHU) += 20;
- }
-}
-
void GiveLinkDekuSticks(int howManySticks) {
int maxStickCount;
if (CUR_UPG_VALUE(UPG_STICKS) == 0) {
@@ -97,16 +74,6 @@ void GiveLinkDekuSticks(int howManySticks) {
}
}
-void GiveLinkDekuSticksByGetItemId(GetItemID giid) {
- if (giid == GI_STICKS_1) {
- GiveLinkDekuSticks(1);
- } else if (giid == GI_STICKS_5) {
- GiveLinkDekuSticks(5);
- } else if (giid == GI_STICKS_10) {
- GiveLinkDekuSticks(10);
- }
-}
-
void GiveLinkDekuNuts(int howManyNuts) {
int maxNutCount;
if (CUR_UPG_VALUE(UPG_NUTS) == 0) {
@@ -128,300 +95,25 @@ void GiveLinkDekuNuts(int howManyNuts) {
}
}
-void GiveLinkDekuNutsByGetItemId(GetItemID giid) {
- if (giid == GI_NUTS_5) {
- GiveLinkDekuNuts(5);
- } else if (giid == GI_NUTS_10) {
- GiveLinkDekuNuts(10);
- }
-}
-
-void GiveLinkBeans() {
- INV_CONTENT(ITEM_BEAN) = ITEM_BEAN;
- AMMO(ITEM_BEAN)++;
-}
-
-void GiveLinkKokiriSword() {
- uint32_t bitMask = 1 << 0;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkGiantsKnife() {
- gSaveContext.bgsFlag = 0;
- gSaveContext.swordHealth = 8;
- uint32_t bitMask = 1 << 2;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkBiggoronSword() {
- gSaveContext.bgsFlag = 1;
- gSaveContext.swordHealth = 8;
- uint32_t bitMask = 1 << 2;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkDekuShield() {
- uint32_t bitMask = 1 << 4;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkHylianShield() {
- uint32_t bitMask = 1 << 5;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkMirrorShield() {
- uint32_t bitMask = 1 << 6;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkGoronTunic() {
- uint32_t bitMask = 1 << 9;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkZoraTunic() {
- uint32_t bitMask = 1 << 10;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkIronBoots() {
- uint32_t bitMask = 1 << 13;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkHoverBoots() {
- uint32_t bitMask = 1 << 14;
- gSaveContext.inventory.equipment |= bitMask;
-}
-
-void GiveLinkStoneOfAgony() {
- uint32_t bitMask = 1 << QUEST_STONE_OF_AGONY;
- gSaveContext.inventory.questItems |= bitMask;
-}
-
-void GiveLinkGerudoCard() {
- uint32_t bitMask = 1 << QUEST_GERUDO_CARD;
- gSaveContext.inventory.questItems |= bitMask;
-}
-
-void GiveLinkPieceOfHeart() {
- int32_t pohCount = (gSaveContext.inventory.questItems & 0xF0000000) >> 28;
- pohCount++;
- gSaveContext.inventory.questItems |= (pohCount << 28);
-}
-
-void GiveLinkHeartContainer() {
- gSaveContext.healthCapacity += 16;
- gSaveContext.health += 16;
-}
-
-void GiveLinkBulletBagUpgrade(GetItemID giid) {
- if (giid == GI_SLINGSHOT) {
- INV_CONTENT(ITEM_SLINGSHOT) = ITEM_SLINGSHOT;
- AMMO(ITEM_SLINGSHOT) = 30;
- Inventory_ChangeUpgrade(UPG_BULLET_BAG, 1);
- } else if (giid == GI_BULLET_BAG_40) {
- Inventory_ChangeUpgrade(UPG_BULLET_BAG, 2);
- AMMO(ITEM_SLINGSHOT) = 40;
- } else if (giid == GI_BULLET_BAG_50) {
- Inventory_ChangeUpgrade(UPG_BULLET_BAG, 3);
- AMMO(ITEM_SLINGSHOT) = 50;
- }
-}
-
-void GiveLinkQuiverUpgrade(GetItemID giid) {
- if (giid == GI_BOW) {
- INV_CONTENT(ITEM_BOW) = ITEM_BOW;
- Inventory_ChangeUpgrade(UPG_QUIVER, 1);
- AMMO(ITEM_BOW) = 30;
- } else if (giid == GI_QUIVER_40) {
- Inventory_ChangeUpgrade(UPG_QUIVER, 2);
- AMMO(ITEM_BOW) = 40;
- } else if (giid == GI_QUIVER_50) {
- Inventory_ChangeUpgrade(UPG_QUIVER, 3);
- AMMO(ITEM_BOW) = 50;
- }
-}
-
-void GiveLinkBombBagUpgrade(GetItemID giid) {
- if (giid == GI_BOMB_BAG_20) {
- INV_CONTENT(ITEM_BOMB) = ITEM_BOMB;
- Inventory_ChangeUpgrade(UPG_BOMB_BAG, 1);
- AMMO(ITEM_BOMB) = 20;
- } else if (giid == GI_BOMB_BAG_30) {
- Inventory_ChangeUpgrade(UPG_BOMB_BAG, 2);
- AMMO(ITEM_BOMB) = 30;
- } else if (giid == GI_BOMB_BAG_40) {
- Inventory_ChangeUpgrade(UPG_BOMB_BAG, 3);
- AMMO(ITEM_BOMB) = 40;
- }
-}
-
-void GiveLinkStrengthUpgrade(GetItemID giid) {
- if (giid == GI_BRACELET) {
- Inventory_ChangeUpgrade(UPG_STRENGTH, 1);
- } else if (giid == GI_GAUNTLETS_SILVER) {
- Inventory_ChangeUpgrade(UPG_STRENGTH, 2);
- } else if (giid == GI_GAUNTLETS_GOLD) {
- Inventory_ChangeUpgrade(UPG_STRENGTH, 3);
- }
-}
-
-void GiveLinkScaleUpgrade(GetItemID giid) {
- if (giid == GI_SCALE_SILVER) {
- Inventory_ChangeUpgrade(UPG_SCALE, 1);
- } else if (giid == GI_SCALE_GOLD) {
- Inventory_ChangeUpgrade(UPG_SCALE, 2);
- }
-}
-
-void GiveLinkWalletUpgrade(GetItemID giid) {
- if (giid == GI_WALLET_ADULT) {
- Inventory_ChangeUpgrade(UPG_WALLET, 1);
- } else if (giid == GI_WALLET_GIANT) {
- Inventory_ChangeUpgrade(UPG_WALLET, 2);
- }
-}
-
-void GiveLinkDekuStickUpgrade(GetItemID giid) {
- if (giid == GI_STICK_UPGRADE_20) {
- INV_CONTENT(ITEM_STICK) = ITEM_STICK;
- Inventory_ChangeUpgrade(UPG_STICKS, 2);
- AMMO(ITEM_STICK) = 20;
- } else if (giid == GI_STICK_UPGRADE_30) {
- Inventory_ChangeUpgrade(UPG_STICKS, 3);
- AMMO(ITEM_STICK) = 30;
- }
-}
-
-void GiveLinkDekuNutUpgrade(GetItemID giid) {
- if (giid == GI_NUT_UPGRADE_30) {
- INV_CONTENT(ITEM_NUT) = ITEM_NUT;
- Inventory_ChangeUpgrade(UPG_NUTS, 2);
- AMMO(ITEM_NUT) = 30;
- } else if (giid == GI_NUT_UPGRADE_40) {
- Inventory_ChangeUpgrade(UPG_NUTS, 3);
- AMMO(ITEM_NUT) = 40;
- }
-}
-
-void GiveLinkMagic(GetItemID giid) {
- if (giid == RG_MAGIC_SINGLE) {
- gSaveContext.magicLevel = 1;
- gSaveContext.magicAcquired = true;
- gSaveContext.doubleMagic = false;
- } else if (giid == RG_MAGIC_DOUBLE) {
- gSaveContext.magicLevel = 2;
- gSaveContext.magicAcquired = true;
- gSaveContext.doubleMagic = true;
- }
-}
-
-void GiveLinkDoubleDefense() {
- gSaveContext.doubleDefense = 1;
- gSaveContext.inventory.defenseHearts = 20;
-}
-
-void GiveLinkSong(GetItemID getItemId) {
- uint32_t bitMask;
-
- switch (getItemId) {
- case RG_ZELDAS_LULLABY:
- bitMask = 1 << QUEST_SONG_LULLABY;
- break;
- case RG_SUNS_SONG:
- bitMask = 1 << QUEST_SONG_SUN;
- break;
- case RG_EPONAS_SONG:
- bitMask = 1 << QUEST_SONG_EPONA;
- break;
- case RG_SONG_OF_STORMS:
- bitMask = 1 << QUEST_SONG_STORMS;
- break;
- case RG_SONG_OF_TIME:
- bitMask = 1 << QUEST_SONG_TIME;
- break;
- case RG_SARIAS_SONG:
- bitMask = 1 << QUEST_SONG_SARIA;
- break;
- case RG_MINUET_OF_FOREST:
- bitMask = 1 << QUEST_SONG_MINUET;
- break;
- case RG_BOLERO_OF_FIRE:
- bitMask = 1 << QUEST_SONG_BOLERO;
- break;
- case RG_SERENADE_OF_WATER:
- bitMask = 1 << QUEST_SONG_SERENADE;
- break;
- case RG_NOCTURNE_OF_SHADOW:
- bitMask = 1 << QUEST_SONG_NOCTURNE;
- break;
- case RG_REQUIEM_OF_SPIRIT:
- bitMask = 1 << QUEST_SONG_REQUIEM;
- break;
- case RG_PRELUDE_OF_LIGHT:
- bitMask = 1 << QUEST_SONG_PRELUDE;
- break;
- }
-
- gSaveContext.inventory.questItems |= bitMask;
-}
-
-void GiveLinkDungeonReward(uint16_t getItemId) {
- s16 item;
-
- u8 medallion = 0;
-
- switch (getItemId) {
- case RG_FOREST_MEDALLION:
- item = ITEM_MEDALLION_FOREST;
- medallion = 1;
- break;
- case RG_FIRE_MEDALLION:
- item = ITEM_MEDALLION_FIRE;
- medallion = 1;
- break;
- case RG_WATER_MEDALLION:
- item = ITEM_MEDALLION_WATER;
- medallion = 1;
- break;
- case RG_SHADOW_MEDALLION:
- item = ITEM_MEDALLION_SHADOW;
- medallion = 1;
- break;
- case RG_SPIRIT_MEDALLION:
- item = ITEM_MEDALLION_SPIRIT;
- medallion = 1;
- break;
- case RG_LIGHT_MEDALLION:
- item = ITEM_MEDALLION_LIGHT;
- medallion = 1;
- break;
- case RG_KOKIRI_EMERALD:
- item = ITEM_KOKIRI_EMERALD;
- break;
- case RG_GORON_RUBY:
- item = ITEM_GORON_RUBY;
- break;
- case RG_ZORA_SAPPHIRE:
- item = ITEM_ZORA_SAPPHIRE;
- break;
- }
+void GiveLinksPocketItem() {
+ if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) < 3) {
+ GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
- if (medallion == 1) {
- gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST];
- } else {
- gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_KOKIRI_EMERALD + QUEST_KOKIRI_EMERALD];
+ if (getItemEntry.modIndex == MOD_NONE) {
+ if (getItemEntry.getItemId == GI_SWORD_BGS) {
+ gSaveContext.bgsFlag = true;
+ }
+ Item_Give(NULL, getItemEntry.itemId);
+ } else if (getItemEntry.modIndex == MOD_RANDOMIZER) {
+ if (getItemEntry.getItemId == RG_ICE_TRAP) {
+ gSaveContext.pendingIceTrapCount++;
+ } else {
+ Randomizer_Item_Give(NULL, getItemEntry);
+ }
+ }
}
}
-void GiveLinksPocketMedallion() {
- GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
-
- GiveLinkDungeonReward(getItemEntry.getItemId);
-}
-
/**
* Copy save currently on the buffer to Save Context and complete various tasks to open the save.
* This includes:
@@ -563,13 +255,15 @@ void Sram_OpenSave() {
gSaveContext.equips.equipment |= 2;
}
- for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) {
- if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[i]) {
- INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i];
+ if (!(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) {
+ for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) {
+ if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[i]) {
+ INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i];
- for (j = 1; j < ARRAY_COUNT(gSaveContext.equips.buttonItems); j++) {
- if (gSaveContext.equips.buttonItems[j] == gSpoilingItems[i]) {
- gSaveContext.equips.buttonItems[j] = gSpoilingItemReverts[i];
+ for (j = 1; j < ARRAY_COUNT(gSaveContext.equips.buttonItems); j++) {
+ if (gSaveContext.equips.buttonItems[j] == gSpoilingItems[i]) {
+ gSaveContext.equips.buttonItems[j] = gSpoilingItemReverts[i];
+ }
}
}
}
@@ -610,14 +304,18 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
fileChooseCtx->n64ddFlag = 1;
gSaveContext.n64ddFlag = 1;
- // Sets all the dungeons to incomplete when generating a rando save. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/82
- for (u8 i = 0; i < NUM_DUNGEONS; i++) {
- gSaveContext.dungeonsDone[i] = 0;
+ // Sets all rando flags to false
+ for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.randomizerInf); i++) {
+ gSaveContext.randomizerInf[i] = 0;
}
- // Sets all Ganon's Trials to incomplete when generating a rando save. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131
- for (u8 i = 0; i < NUM_TRIALS; i++) {
- gSaveContext.trialsDone[i] = 0;
+ // Set all trials to cleared if trial count is random or anything other than 6
+ if (Randomizer_GetSettingValue(RSK_RANDOM_TRIALS) || (Randomizer_GetSettingValue(RSK_TRIAL_COUNT) != 6)) {
+ for (u16 i = RAND_INF_TRIALS_DONE_LIGHT_TRIAL; i <= RAND_INF_TRIALS_DONE_SHADOW_TRIAL; i++) {
+ if (!Randomizer_IsTrialRequired(i)) {
+ Flags_SetRandomizerInf(i);
+ }
+ }
}
// Set Cutscene flags to skip them
@@ -626,8 +324,9 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
gSaveContext.eventChkInf[4] |= 0x20; // master sword pulled
gSaveContext.eventChkInf[4] |= 0x8000; // entered master sword chamber
gSaveContext.infTable[0] |= 1;
- // RANDTODO: Don't skip this scene if Don't Skip Glitch Useful Cutscenes is enabled.
- gSaveContext.infTable[17] |= 0x400; // Darunia in Fire Temple
+ if (!Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) {
+ gSaveContext.infTable[17] |= 0x400; // Darunia in Fire Temple
+ }
gSaveContext.cutsceneIndex = 0;
Flags_SetEventChkInf(5);
@@ -645,8 +344,16 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
gSaveContext.eventChkInf[3] |= 0x800;
gSaveContext.eventChkInf[12] |= 1;
+ // shuffle adult trade quest
+ if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
+ gSaveContext.adultTradeItems = 0;
+ }
+
+ // Starts pending ice traps out at 0 before potentially incrementing them down the line.
+ gSaveContext.pendingIceTrapCount = 0;
+
// Give Link's pocket item
- GiveLinksPocketMedallion();
+ GiveLinksPocketItem();
int openForest = Randomizer_GetSettingValue(RSK_FOREST);
switch (openForest) {
@@ -675,18 +382,19 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
break;
}
- if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword();
- if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield();
+ if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) Item_Give(NULL, ITEM_SWORD_KOKIRI);
+ if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) Item_Give(NULL, ITEM_SHIELD_DEKU);
if(Randomizer_GetSettingValue(RSK_STARTING_OCARINA)) {
INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY;
}
- if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES)) {
+ // "Start with" == 0 for Maps and Compasses
+ if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES) == 0) {
uint32_t mapBitMask = 1 << 1;
uint32_t compassBitMask = 1 << 2;
uint32_t startingDungeonItemsBitMask = mapBitMask | compassBitMask;
- for(int scene = 0; scene <= 9; scene++) {
+ for(int scene = SCENE_YDAN; scene <= SCENE_ICE_DOUKUTO; scene++) {
gSaveContext.inventory.dungeonItems[scene] |= startingDungeonItemsBitMask;
}
}
@@ -701,71 +409,16 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
s32 giid = getItem.getItemId;
if (getItem.modIndex == MOD_NONE) {
- if (getItem.itemId >= ITEM_MEDALLION_FOREST && getItem.itemId <= ITEM_ZORA_SAPPHIRE) {
- GiveLinkDungeonReward(getItem.getItemId);
- } else if (getItem.itemId >= ITEM_SONG_MINUET && getItem.itemId <= ITEM_SONG_STORMS) {
- GiveLinkSong(getItem.getItemId);
- } else if (giid == GI_RUPEE_GREEN || giid == GI_RUPEE_BLUE || giid == GI_RUPEE_RED ||
- giid == GI_RUPEE_PURPLE || giid == GI_RUPEE_GOLD) {
- GiveLinkRupeesByGetItemId(giid);
- } else if (giid == GI_BOMBCHUS_10 || giid == GI_BOMBCHUS_5 || giid == GI_BOMBCHUS_20) {
- GiveLinkBombchus(giid);
- } else if (giid == GI_STICKS_1 || giid == GI_STICKS_5 || giid == GI_STICKS_10) {
- GiveLinkDekuSticksByGetItemId(giid);
- } else if (giid == GI_NUTS_5 || giid == GI_NUTS_10) {
- GiveLinkDekuNutsByGetItemId(giid);
- } else if (giid == GI_BEAN) {
- GiveLinkBeans();
- } else if (giid == GI_SWORD_KOKIRI) {
- GiveLinkKokiriSword();
- } else if (giid == GI_SWORD_BGS) {
- GiveLinkBiggoronSword();
- } else if (giid == GI_SWORD_KNIFE) {
- GiveLinkGiantsKnife();
- } else if (giid == GI_SHIELD_DEKU) {
- GiveLinkDekuShield();
- } else if (giid == GI_SHIELD_HYLIAN) {
- GiveLinkHylianShield();
- } else if (giid == GI_SHIELD_MIRROR) {
- GiveLinkMirrorShield();
- } else if (giid == GI_TUNIC_GORON) {
- GiveLinkGoronTunic();
- } else if (giid == GI_TUNIC_ZORA) {
- GiveLinkZoraTunic();
- } else if (giid == GI_BOOTS_IRON) {
- GiveLinkIronBoots();
- } else if (giid == GI_BOOTS_HOVER) {
- GiveLinkHoverBoots();
- } else if (giid == GI_SLINGSHOT || giid == GI_BULLET_BAG_40 || giid == GI_BULLET_BAG_50) {
- GiveLinkBulletBagUpgrade(giid);
- } else if (giid == GI_BOW || giid == GI_QUIVER_40 || giid == GI_QUIVER_50) {
- GiveLinkQuiverUpgrade(giid);
- } else if (giid == GI_BOMB_BAG_20 || giid == GI_BOMB_BAG_30 || giid == GI_BOMB_BAG_40) {
- GiveLinkBombBagUpgrade(giid);
- } else if (giid == GI_BRACELET || giid == GI_GAUNTLETS_SILVER || giid == GI_GAUNTLETS_GOLD) {
- GiveLinkStrengthUpgrade(giid);
- } else if (giid == GI_SCALE_SILVER || giid == GI_SCALE_GOLD) {
- GiveLinkScaleUpgrade(giid);
- } else if (giid == GI_WALLET_ADULT || giid == GI_WALLET_GIANT) {
- GiveLinkWalletUpgrade(giid);
- } else if (giid == GI_STONE_OF_AGONY) {
- GiveLinkStoneOfAgony();
- } else if (giid == GI_GERUDO_CARD) {
- GiveLinkGerudoCard();
- } else if (giid == GI_HEART_PIECE) {
- GiveLinkPieceOfHeart();
- } else if (giid == GI_HEART_CONTAINER) {
- GiveLinkHeartContainer();
- } else if (giid == GI_STICK_UPGRADE_20 || giid == GI_STICK_UPGRADE_30) {
- GiveLinkDekuStickUpgrade(giid);
- } else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) {
- GiveLinkDekuNutUpgrade(giid);
- } else {
- s32 iid = getItem.itemId;
- if (iid != -1) INV_CONTENT(iid) = iid;
+ if (getItem.getItemId == GI_SWORD_BGS) {
+ gSaveContext.bgsFlag = true;
}
+ Item_Give(NULL, getItem.itemId);
} else if (getItem.modIndex == MOD_RANDOMIZER) {
- Randomizer_Item_Give(NULL, getItem);
+ if (getItem.getItemId == RG_ICE_TRAP) {
+ gSaveContext.pendingIceTrapCount++;
+ } else {
+ Randomizer_Item_Give(NULL, getItem);
+ }
}
// malon/talon back at ranch
@@ -789,9 +442,31 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
GiveLinkRupees(9001);
}
- // For Ganon's boss key "Start With" is 0
- if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 0) {
- gSaveContext.inventory.dungeonItems[10] |= 1;
+ // "Start with" == 0 for Keysanity
+ if(Randomizer_GetSettingValue(RSK_KEYSANITY) == 0) {
+ // TODO: If master quest there are different key counts
+ gSaveContext.inventory.dungeonKeys[SCENE_BMORI1] = 5; // Forest
+ gSaveContext.inventory.dungeonKeys[SCENE_HIDAN] = 8; // Fire
+ gSaveContext.inventory.dungeonKeys[SCENE_MIZUSIN] = 6; // Water
+ gSaveContext.inventory.dungeonKeys[SCENE_JYASINZOU] = 5; // Spirit
+ gSaveContext.inventory.dungeonKeys[SCENE_HAKADAN] = 5; // Shadow
+ gSaveContext.inventory.dungeonKeys[SCENE_HAKADANCH] = 3; // BotW
+ gSaveContext.inventory.dungeonKeys[SCENE_MEN] = 9; // GTG
+ gSaveContext.inventory.dungeonKeys[SCENE_GANONTIKA] = 2; // Ganon
+ }
+
+ // "Start with" == 0 for Boss Kesanity
+ if(Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == 0) {
+ gSaveContext.inventory.dungeonItems[SCENE_BMORI1] |= 1; // Forest
+ gSaveContext.inventory.dungeonItems[SCENE_HIDAN] |= 1; // Fire
+ gSaveContext.inventory.dungeonItems[SCENE_MIZUSIN] |= 1; // Water
+ gSaveContext.inventory.dungeonItems[SCENE_JYASINZOU] |= 1; // Spirit
+ gSaveContext.inventory.dungeonItems[SCENE_HAKADAN] |= 1; // Shadow
+ }
+
+ // "Start with" == 2 for Ganon's Boss Key
+ if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 2) {
+ gSaveContext.inventory.dungeonItems[SCENE_GANON] |= 1;
}
HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT));
@@ -850,9 +525,20 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
gSaveContext.sceneFlags[12].collect |= (1 << 0x0C);
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
- GiveLinkGerudoCard();
+ Item_Give(NULL, ITEM_GERUDO_CARD);
}
}
+
+ // complete mask quest
+ if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) {
+ gSaveContext.infTable[7] |= 0x80; // Soldier Wears Keaton Mask
+ gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask
+ gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask
+ gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask
+ gSaveContext.itemGetInf[3] |= 0x800; // bunny hood related
+ gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth
+ gSaveContext.eventChkInf[8] |= 0x8000; // sold all masks
+ }
}
Save_SaveFile();