mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-13 06:58:03 -05:00
Merge branch 'rando-next' of https://github.com/HarbourMasters/Shipwright into get-item-rework-rando-next
Hopefully everything works here. Need to do some testing.
This commit is contained in:
commit
c8d085cb49
@ -9,7 +9,6 @@
|
||||
#include "Cvar.h"
|
||||
|
||||
namespace Ship {
|
||||
uint8_t* controllerBits;
|
||||
|
||||
void ControlDeck::Init(uint8_t* bits) {
|
||||
ScanPhysicalDevices();
|
||||
@ -187,4 +186,9 @@ namespace Ship {
|
||||
std::shared_ptr<Controller> ControlDeck::GetPhysicalDeviceFromVirtualSlot(int slot) {
|
||||
return GetPhysicalDevice(GetVirtualDevice(slot));
|
||||
}
|
||||
|
||||
uint8_t* ControlDeck::GetControllerBits() {
|
||||
return controllerBits;
|
||||
}
|
||||
|
||||
}
|
@ -18,8 +18,10 @@ namespace Ship {
|
||||
size_t GetNumPhysicalDevices();
|
||||
int GetVirtualDevice(int slot);
|
||||
size_t GetNumVirtualDevices();
|
||||
uint8_t* GetControllerBits();
|
||||
private:
|
||||
std::vector<int> virtualDevices;
|
||||
std::vector<int> virtualDevices = {};
|
||||
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
|
||||
uint8_t* controllerBits = nullptr;
|
||||
};
|
||||
}
|
||||
|
@ -1760,9 +1760,30 @@ namespace SohImGui {
|
||||
needs_save = true;
|
||||
customWindows["Item Tracker"].enabled = CVar_GetS32("gItemTrackerEnabled", 0);
|
||||
}
|
||||
InsertPadding();
|
||||
if (ImGui::Button(GetWindowButtonText("Item Tracker Settings", CVar_GetS32("gItemTrackerSettingsEnabled", 0)).c_str(), buttonSize))
|
||||
{
|
||||
bool currentValue = CVar_GetS32("gItemTrackerSettingsEnabled", 0);
|
||||
CVar_SetS32("gItemTrackerSettingsEnabled", !currentValue);
|
||||
needs_save = true;
|
||||
customWindows["Item Tracker Settings"].enabled = CVar_GetS32("gItemTrackerSettingsEnabled", 0);
|
||||
}
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
PaddedSeparator();
|
||||
|
||||
if (ImGui::BeginMenu("Rando Enhancements"))
|
||||
{
|
||||
EnhancementCheckbox("Quest Item Fanfares", "gRandoQuestItemFanfares");
|
||||
Tooltip(
|
||||
"Play unique fanfares when obtaining quest items\n"
|
||||
"(medallions/stones/songs). Note that these fanfares\n"
|
||||
"are longer than usual."
|
||||
);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Ship
|
||||
{
|
||||
Vertex::Vertex()
|
||||
ModelVertex::ModelVertex()
|
||||
{
|
||||
pos = Vec3f(0, 0, 0);
|
||||
normal = Vec3f(0, 0, 0);
|
||||
@ -10,7 +10,7 @@ namespace Ship
|
||||
uv = Vec2f(0, 0);
|
||||
}
|
||||
|
||||
Vertex::Vertex(BinaryReader* reader)
|
||||
ModelVertex::ModelVertex(BinaryReader* reader)
|
||||
{
|
||||
pos = reader->ReadVec3f();
|
||||
normal = reader->ReadVec3f();
|
||||
@ -36,7 +36,7 @@ namespace Ship
|
||||
uvCoords = reader->ReadUInt32();
|
||||
boneWeights = reader->ReadUInt32();
|
||||
|
||||
Vertex* vtxData = new Vertex[numVerts];
|
||||
ModelVertex* vtxData = new ModelVertex[numVerts];
|
||||
uint32_t* indicesData = new uint32_t[numPolys];
|
||||
|
||||
if (vertices != 0)
|
||||
|
@ -43,15 +43,15 @@ namespace Ship
|
||||
void ParseFileBinary(BinaryReader* reader, Resource* res) override;
|
||||
};
|
||||
|
||||
struct Vertex
|
||||
struct ModelVertex
|
||||
{
|
||||
Vec3f pos;
|
||||
Vec3f normal;
|
||||
Color3b color;
|
||||
Vec2f uv;
|
||||
|
||||
Vertex();
|
||||
Vertex(BinaryReader* reader);
|
||||
ModelVertex();
|
||||
ModelVertex(BinaryReader* reader);
|
||||
};
|
||||
|
||||
class Model : public Resource
|
||||
@ -62,7 +62,7 @@ namespace Ship
|
||||
uint32_t numVerts;
|
||||
uint32_t numPolys;
|
||||
|
||||
Vertex* vertices;
|
||||
ModelVertex* vertices;
|
||||
Vec2f* boneWeights;
|
||||
uint32_t* indices;
|
||||
};
|
||||
|
@ -174,6 +174,7 @@ source_group("Header Files\\soh\\Enhancements\\debugger" FILES ${Header_Files__s
|
||||
set(Header_Files__soh__Enhancements__randomizer
|
||||
"soh/Enhancements/randomizer/randomizer.h"
|
||||
"soh/Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
"soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
)
|
||||
source_group("Header Files\\soh\\Enhancements\\randomizer" FILES ${Header_Files__soh__Enhancements__randomizer})
|
||||
|
||||
@ -274,6 +275,7 @@ source_group("Source Files\\soh\\Enhancements\\debugger" FILES ${Source_Files__s
|
||||
set(Source_Files__soh__Enhancements__randomizer
|
||||
"soh/Enhancements/randomizer/randomizer.cpp"
|
||||
"soh/Enhancements/randomizer/randomizer_item_tracker.cpp"
|
||||
"soh/Enhancements/randomizer/adult_trade_shuffle.c"
|
||||
)
|
||||
source_group("Source Files\\soh\\Enhancements\\randomizer" FILES ${Source_Files__soh__Enhancements__randomizer})
|
||||
|
||||
|
@ -1057,6 +1057,7 @@ s32 Inventory_HasEmptyBottle(void);
|
||||
s32 Inventory_HasSpecificBottle(u8 bottleItem);
|
||||
void Inventory_UpdateBottleItem(GlobalContext* globalCtx, u8 item, u8 cButton);
|
||||
s32 Inventory_ConsumeFairy(GlobalContext* globalCtx);
|
||||
bool Inventory_HatchPocketCucco(GlobalContext* globalCtx);
|
||||
void Interface_SetDoAction(GlobalContext* globalCtx, u16 action);
|
||||
void Interface_SetNaviCall(GlobalContext* globalCtx, u16 naviCallState);
|
||||
void Interface_LoadActionLabelB(GlobalContext* globalCtx, u16 action);
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
struct Player;
|
||||
|
||||
extern GetItemEntry sGetItemTable[195];
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ PLAYER_SWORD_NONE,
|
||||
/* 1 */ PLAYER_SWORD_KOKIRI,
|
||||
@ -366,6 +368,7 @@ typedef enum {
|
||||
FLAG_SCENE_CLEAR,
|
||||
FLAG_SCENE_COLLECTIBLE,
|
||||
FLAG_EVENT_CHECK_INF,
|
||||
FLAG_COW_MILKED
|
||||
} FlagType;
|
||||
|
||||
typedef struct {
|
||||
@ -627,9 +630,10 @@ typedef struct Player {
|
||||
/* 0x0A86 */ s8 unk_A86;
|
||||
/* 0x0A87 */ u8 unk_A87;
|
||||
/* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position
|
||||
/* 0x0A94 */ PendingFlag pendingFlag;
|
||||
/* 0x0AA0 */ u8 boomerangQuickRecall; // Has the player pressed the boomerang button while it's in the air still?
|
||||
/* 0x0AA1 */ GetItemEntry getItemEntry;
|
||||
} Player; // size = 0xAA9
|
||||
/* 0x0A89 */ bool pendingIceTrap;
|
||||
/* 0x0A95 */ PendingFlag pendingFlag;
|
||||
/* 0x0AA1 */ u8 boomerangQuickRecall; // Has the player pressed the boomerang button while it's in the air still?
|
||||
/* 0x0AA2 */ GetItemEntry getItemEntry;
|
||||
} Player; // size = 0xAAA
|
||||
|
||||
#endif
|
||||
|
@ -175,7 +175,7 @@ typedef struct {
|
||||
/* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
|
||||
/* 0x1424 */ s16 healthAccumulator;
|
||||
RandoSetting randoSettings[300];
|
||||
ItemLocationRando itemLocations[500];
|
||||
ItemLocationRando itemLocations[RC_MAX];
|
||||
HintLocationRando hintLocations[50];
|
||||
char childAltarText[250];
|
||||
char adultAltarText[750];
|
||||
@ -184,7 +184,9 @@ typedef struct {
|
||||
u8 seedIcons[5];
|
||||
u8 dungeonsDone[8];
|
||||
u8 trialsDone[6];
|
||||
u8 cowsMilked[10];
|
||||
u8 temporaryWeapon;
|
||||
u16 adultTradeItems;
|
||||
} SaveContext; // size = 0x1428
|
||||
|
||||
typedef enum {
|
||||
|
@ -30,4 +30,7 @@ typedef struct {
|
||||
#define GIMESSAGE_UNTRANSLATED(giid, iid, message) \
|
||||
{ giid, iid, message, message, message }
|
||||
|
||||
#define GIMESSAGE_NO_GERMAN(giid, iid, english, french) \
|
||||
{ giid, iid, english, english, french }
|
||||
|
||||
#endif
|
||||
|
@ -20,3 +20,13 @@ void InsertHelpHoverText(const std::string& text) {
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void PaddedSeparator(bool padTop, bool padBottom, float extraVerticalPadding) {
|
||||
if (padTop) {
|
||||
ImGui::Dummy(ImVec2(0.0f, extraVerticalPadding));
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (padBottom) {
|
||||
ImGui::Dummy(ImVec2(0.0f, extraVerticalPadding));
|
||||
}
|
||||
}
|
||||
|
@ -6,3 +6,5 @@
|
||||
void SetLastItemHoverText(const std::string& text);
|
||||
|
||||
void InsertHelpHoverText(const std::string& text);
|
||||
|
||||
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalPadding = 0);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "debugSaveEditor.h"
|
||||
#include "../../util.h"
|
||||
#include "../../OTRGlobals.h"
|
||||
#include "../libultraship/ImGuiImpl.h"
|
||||
#include "ImGuiHelpers.h"
|
||||
|
||||
@ -14,6 +15,7 @@ extern "C" {
|
||||
#include "variables.h"
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
extern GlobalContext* gGlobalCtx;
|
||||
|
||||
#include "textures/icon_item_static/icon_item_static.h"
|
||||
@ -525,6 +527,27 @@ void DrawInfoTab() {
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void DrawBGSItemFlag(uint8_t itemID) {
|
||||
const ItemMapEntry& slotEntry = itemMapping[itemID];
|
||||
ImGui::Image(SohImGui::GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
|
||||
ImGui::SameLine();
|
||||
int tradeIndex = itemID - ITEM_POCKET_EGG;
|
||||
bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0;
|
||||
bool shouldHaveItem = hasItem;
|
||||
ImGui::Checkbox(("##adultTradeFlag" + std::to_string(itemID)).c_str(), &shouldHaveItem);
|
||||
if (hasItem != shouldHaveItem) {
|
||||
if (shouldHaveItem) {
|
||||
gSaveContext.adultTradeItems |= (1 << tradeIndex);
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_NONE) {
|
||||
INV_CONTENT(ITEM_TRADE_ADULT) = ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
} else {
|
||||
gSaveContext.adultTradeItems &= ~(1 << tradeIndex);
|
||||
Inventory_ReplaceItem(gGlobalCtx, itemID, Randomizer_GetNextAdultTradeItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawInventoryTab() {
|
||||
static bool restrictToValid = true;
|
||||
|
||||
@ -566,6 +589,9 @@ void DrawInventoryTab() {
|
||||
if (ImGui::BeginPopup(itemPopupPicker)) {
|
||||
if (ImGui::Button("##itemNonePicker", ImVec2(32.0f, 32.0f))) {
|
||||
gSaveContext.inventory.items[selectedIndex] = ITEM_NONE;
|
||||
if (selectedIndex == SLOT_TRADE_ADULT) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SetLastItemHoverText("None");
|
||||
@ -596,6 +622,13 @@ void DrawInventoryTab() {
|
||||
if (ImGui::ImageButton(SohImGui::GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f),
|
||||
ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||
gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
|
||||
// Set adult trade item flag if you're playing adult trade shuffle in rando
|
||||
if (gSaveContext.n64ddFlag &&
|
||||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE);
|
||||
selectedIndex == SLOT_TRADE_ADULT &&
|
||||
slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) {
|
||||
gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id));
|
||||
@ -632,6 +665,16 @@ void DrawInventoryTab() {
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
// Trade quest flags are only used when shuffling the trade sequence, so
|
||||
// don't show this if it isn't needed.
|
||||
if (gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE)
|
||||
&& ImGui::TreeNode("Adult trade quest items")) {
|
||||
for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) {
|
||||
DrawBGSItemFlag(i);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a flag bitfield as an grid of checkboxes
|
||||
|
@ -103,11 +103,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((type == ITEMTYPE_BOSSKEY && getItemId != 0x9A) && (BossKeysanity.Is(BOSSKEYSANITY_VANILLA) || BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON))) {
|
||||
if ((type == ITEMTYPE_BOSSKEY && getItemId != 0xAD) && (BossKeysanity.Is(BOSSKEYSANITY_VANILLA) || BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON))) {
|
||||
return false;
|
||||
}
|
||||
//Ganons Castle Boss Key
|
||||
if (getItemId == 0x9A && (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA) || GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON))) {
|
||||
if (getItemId == 0xAD && (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA) || GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -229,11 +229,11 @@ void ItemTable_Init() { //English name
|
||||
itemTable[BUY_BOMBCHU_20] = Item(Text{"Buy Bombchu (20)", "Acheter: Missiles (20)", "Comprar bombchus (20)"}, ITEMTYPE_SHOP, 0x16, true, &BuyBombchus20, BOMBCHU_20, 180);
|
||||
itemTable[BUY_BOMBCHU_5] = Item(Text{"Buy Bombchu (5)", "Acheter: Missiles (5)", "Comprar bombchus (5)"}, ITEMTYPE_SHOP, 0x18, true, &BuyBombchus5, BOMBCHU_5, 60);
|
||||
itemTable[BUY_DEKU_SEEDS_30] = Item(Text{"Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Comprar semillas deku (30)"}, ITEMTYPE_SHOP, 0x1D, true, &BuySeed, DEKU_SEEDS_30, 30);
|
||||
itemTable[SOLD_OUT] = Item(Text{"Sold Out", "Vendu", "Vendido"}, ITEMTYPE_SHOP, 0x26, false, &noVariable, NONE, 0);
|
||||
itemTable[SOLD_OUT] = Item(Text{"Sold Out", "Rupture de stock", "Vendido"}, ITEMTYPE_SHOP, 0x26, false, &noVariable, NONE, 0);
|
||||
itemTable[BUY_BLUE_FIRE] = Item(Text{"Buy Blue Fire", "Acheter: Flamme Bleue", "Comprar fuego azul"}, ITEMTYPE_SHOP, 0x27, true, &BlueFireAccess, BOTTLE_WITH_BLUE_FIRE, 300);
|
||||
itemTable[BUY_BOTTLE_BUG] = Item(Text{"Buy Bottle Bug", "Acheter: Insecte en bouteille", "Comprar bichos"}, ITEMTYPE_SHOP, 0x28, true, &BugsAccess, BOTTLE_WITH_BUGS, 50);
|
||||
itemTable[BUY_POE] = Item(Text{"Buy Poe", "Acheter: Esprit", "Comprar Poe"}, ITEMTYPE_SHOP, 0x2A, false, &noVariable, BOTTLE_WITH_BIG_POE, 30);
|
||||
itemTable[BUY_FAIRYS_SPIRIT] = Item(Text{"Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Comprar hada"}, ITEMTYPE_SHOP, 0x2B, true, &FairyAccess, BOTTLE_WITH_FAIRY, 50);
|
||||
itemTable[BUY_POE] = Item(Text{"Buy Poe", "Acheter: Esprit", "Comprar Poe"}, ITEMTYPE_SHOP, 0x2A, false, &noVariable, BOTTLE_WITH_BIG_POE, 30);
|
||||
itemTable[BUY_FAIRYS_SPIRIT] = Item(Text{"Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Comprar hada"}, ITEMTYPE_SHOP, 0x2B, true, &FairyAccess, BOTTLE_WITH_FAIRY, 50);
|
||||
itemTable[BUY_ARROWS_10] = Item(Text{"Buy Arrows (10)", "Acheter: Flèches (10)", "Comprar flechas (10)"}, ITEMTYPE_SHOP, 0x2C, true, &BuyArrow, ARROWS_10, 20);
|
||||
itemTable[BUY_BOMBS_20] = Item(Text{"Buy Bombs (20)", "Acheter: Bombes (20)", "Comprar bombas (20)"}, ITEMTYPE_SHOP, 0x2D, true, &BuyBomb, BOMBS_20, 80);
|
||||
itemTable[BUY_BOMBS_30] = Item(Text{"Buy Bombs (30)", "Acheter: Bombes (30)", "Comprar bombas (30)"}, ITEMTYPE_SHOP, 0x2E, true, &BuyBomb, BOMBS_20, 120);
|
||||
|
@ -165,6 +165,11 @@ void LocationTable_Init() {
|
||||
//Zoras River
|
||||
locationTable[ZR_OPEN_GROTTO_CHEST] = ItemLocation::Chest (0x3E, 0x09, "ZR Open Grotto Chest", ZR_OPEN_GROTTO_CHEST, RED_RUPEE, {Category::cZorasRiver, Category::cGrotto,}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_MAGIC_BEAN_SALESMAN] = ItemLocation::Base (0x54, 0x16, "ZR Magic Bean Salesman", ZR_MAGIC_BEAN_SALESMAN, MAGIC_BEAN, {Category::cZorasRiver,}, SpoilerCollectionCheck::MagicBeans(0x54, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_ZELDAS_LULLABY] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs Zelda's Lullaby", ZR_FROGS_ZELDAS_LULLABY, PURPLE_RUPEE, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_EPONAS_SONG] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs Epona's Song", ZR_FROGS_EPONAS_SONG, PURPLE_RUPEE, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_SARIAS_SONG] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs Saria's Song", ZR_FROGS_SARIAS_SONG, PURPLE_RUPEE, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_SUNS_SONG] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs Sun's Song", ZR_FROGS_SUNS_SONG, PURPLE_RUPEE, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_SONG_OF_TIME] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs Song of Time", ZR_FROGS_SONG_OF_TIME, PURPLE_RUPEE, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_IN_THE_RAIN] = ItemLocation::Base (0x54, 0x3E, "ZR Frogs in the Rain", ZR_FROGS_IN_THE_RAIN, PIECE_OF_HEART, {Category::cZorasRiver,}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_FROGS_OCARINA_GAME] = ItemLocation::Base (0x54, 0x76, "ZR Frogs Ocarina Game", ZR_FROGS_OCARINA_GAME, PIECE_OF_HEART, {Category::cZorasRiver, Category::cMinigame,}, SpoilerCollectionCheck::EventChkInf(0xD0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
locationTable[ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = ItemLocation::Collectable(0x54, 0x04, "ZR Near Open Grotto Freestanding PoH", ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, PIECE_OF_HEART, {Category::cZorasRiver,}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER);
|
||||
@ -1302,6 +1307,11 @@ std::vector<uint32_t> overworldLocations = {
|
||||
//Zoras River
|
||||
ZR_OPEN_GROTTO_CHEST,
|
||||
ZR_MAGIC_BEAN_SALESMAN,
|
||||
ZR_FROGS_ZELDAS_LULLABY,
|
||||
ZR_FROGS_EPONAS_SONG,
|
||||
ZR_FROGS_SARIAS_SONG,
|
||||
ZR_FROGS_SUNS_SONG,
|
||||
ZR_FROGS_SONG_OF_TIME,
|
||||
ZR_FROGS_IN_THE_RAIN,
|
||||
ZR_FROGS_OCARINA_GAME,
|
||||
ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH,
|
||||
|
@ -729,6 +729,16 @@ void GenerateItemPool() {
|
||||
PlaceItemInLocation(WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, false, true);
|
||||
}
|
||||
|
||||
if (ShuffleFrogSongRupees) {
|
||||
AddItemToMainPool(PURPLE_RUPEE, 5);
|
||||
} else {
|
||||
PlaceItemInLocation(ZR_FROGS_ZELDAS_LULLABY, PURPLE_RUPEE, false, true);
|
||||
PlaceItemInLocation(ZR_FROGS_EPONAS_SONG, PURPLE_RUPEE, false, true);
|
||||
PlaceItemInLocation(ZR_FROGS_SARIAS_SONG, PURPLE_RUPEE, false, true);
|
||||
PlaceItemInLocation(ZR_FROGS_SUNS_SONG, PURPLE_RUPEE, false, true);
|
||||
PlaceItemInLocation(ZR_FROGS_SONG_OF_TIME, PURPLE_RUPEE, false, true);
|
||||
}
|
||||
|
||||
if (ShuffleAdultTradeQuest) {
|
||||
AddItemToMainPool(POCKET_EGG);
|
||||
AddItemToMainPool(COJIRO);
|
||||
|
@ -472,6 +472,11 @@ typedef enum {
|
||||
//ZORA'S_RIVER
|
||||
ZR_MAGIC_BEAN_SALESMAN,
|
||||
ZR_OPEN_GROTTO_CHEST,
|
||||
ZR_FROGS_ZELDAS_LULLABY,
|
||||
ZR_FROGS_EPONAS_SONG,
|
||||
ZR_FROGS_SARIAS_SONG,
|
||||
ZR_FROGS_SUNS_SONG,
|
||||
ZR_FROGS_SONG_OF_TIME,
|
||||
ZR_FROGS_IN_THE_RAIN,
|
||||
ZR_FROGS_OCARINA_GAME,
|
||||
ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH,
|
||||
|
@ -31,6 +31,21 @@ void AreaTable_Init_ZorasDomain() {
|
||||
LocationAccess(ZR_FROGS_IN_THE_RAIN, {[]{return IsChild && CanPlay(SongOfStorms);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && SongOfStorms;}}),
|
||||
LocationAccess(ZR_FROGS_ZELDAS_LULLABY, {[]{return IsChild && CanPlay(ZeldasLullaby);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && ZeldasLullaby;}}),
|
||||
LocationAccess(ZR_FROGS_EPONAS_SONG, {[]{return IsChild && CanPlay(EponasSong);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && EponasSong;}}),
|
||||
LocationAccess(ZR_FROGS_SARIAS_SONG, {[]{return IsChild && CanPlay(SariasSong);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && SariasSong;}}),
|
||||
LocationAccess(ZR_FROGS_SUNS_SONG, {[]{return IsChild && CanPlay(SunsSong);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && SunsSong;}}),
|
||||
LocationAccess(ZR_FROGS_SONG_OF_TIME, {[]{return IsChild && CanPlay(SongOfTime);},
|
||||
/*Glitched*/[]{return (CanDoGlitch(GlitchType::OutdoorBombOI, GlitchDifficulty::ADVANCED) || ((Bugs || Fish) && CanShield && CanDoGlitch(GlitchType::QPA, GlitchDifficulty::ADVANCED)) ||
|
||||
((Bugs || Fish) && CanShield && HasBombchus && CanDoGlitch(GlitchType::ActionSwap, GlitchDifficulty::ADVANCED))) && IsChild && SongOfTime;}}),
|
||||
LocationAccess(ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, {[]{return IsChild || CanUse(HOVER_BOOTS) || (IsAdult && LogicZoraRiverLower);}}),
|
||||
LocationAccess(ZR_NEAR_DOMAIN_FREESTANDING_POH, {[]{return IsChild || CanUse(HOVER_BOOTS) || (IsAdult && LogicZoraRiverUpper);}}),
|
||||
LocationAccess(ZR_GS_LADDER, {[]{return IsChild && AtNight && CanChildAttack && CanGetNightTimeGS;}}),
|
||||
|
@ -385,6 +385,13 @@ string_view merchantsHintsDesc = "These hints will make Medigoron and the
|
||||
"The Clearer Hints setting will affect how they\n" //
|
||||
"refer to the item."; //
|
||||
/*------------------------------ //
|
||||
| SHUFFLE FROG SONG RUPEES | //
|
||||
------------------------------*/ //
|
||||
string_view frogSongRupeesDesc = "Enabling this adds 5 Purple Rupees to the item\n" //
|
||||
"pool and shuffles the rewards from playing Zelda's\n"
|
||||
"Lullaby, Epona's Song, Saria's Song, Sun's Song,\n"
|
||||
"and Song of Time to the frogs in Zora's River.\n";//
|
||||
/*------------------------------ //
|
||||
| SHUFFLE ADULT TRADE | //
|
||||
------------------------------*/ //
|
||||
string_view adultTradeDesc = "Enabling this adds all of the adult trade quest\n"//
|
||||
@ -586,6 +593,13 @@ string_view kingZoraSpeedRandom = "King Zora will move out of the way in 1
|
||||
string_view completeMaskDesc = "Once the happy mask shop is opened, all masks\n" //
|
||||
"will be available to be borrowed."; //
|
||||
/*------------------------------ //
|
||||
| ENABLE GLITCH CUTSCENES | //
|
||||
------------------------------*/ //
|
||||
string_view glitchCutscenesDesc = "The cutscenes of the Poes in Forest Temple and\n" //
|
||||
"Darunia in Fire Temple will not be skipped.\n" //
|
||||
"These cutscenes are only useful for glitched\n" //
|
||||
"gameplay and can be safely skipped otherwise."; //
|
||||
/*------------------------------ //
|
||||
| QUICK TEXT | //
|
||||
------------------------------*/ //
|
||||
string_view quickTextDesc0 = "Quick text will be unchanged, requiring\n" //
|
||||
|
@ -126,6 +126,8 @@ extern string_view magicBeansDesc;
|
||||
extern string_view merchantsDesc;
|
||||
extern string_view merchantsHintsDesc;
|
||||
|
||||
extern string_view frogSongRupeesDesc;
|
||||
|
||||
extern string_view adultTradeDesc;
|
||||
|
||||
extern string_view chestMinigameDesc;
|
||||
@ -196,6 +198,8 @@ extern string_view kingZoraSpeedRandom;
|
||||
|
||||
extern string_view completeMaskDesc;
|
||||
|
||||
extern string_view glitchCutscenesDesc;
|
||||
|
||||
extern string_view quickTextDesc0;
|
||||
extern string_view quickTextDesc1;
|
||||
extern string_view quickTextDesc2;
|
||||
|
@ -52,19 +52,19 @@ namespace Settings {
|
||||
// Setting name, Options, Setting Descriptions (assigned in setting_descriptions.cpp) Category (default: Setting),Default index (default: 0), Default hidden (default: false)
|
||||
//Open Settings Any option index past the last description will use the last description
|
||||
Option RandomizeOpen = Option::Bool("Randomize Settings", {"No","Yes"}, {openRandomize}, OptionCategory::Toggle);
|
||||
Option OpenForest = Option::U8 ("Forest", {"Closed", "Open", "Closed Deku"}, {forestClosed, forestOpen, forestClosedDeku}, OptionCategory::Setting, OPENFOREST_OPEN);
|
||||
Option OpenForest = Option::U8 ("Forest", {"Closed", "Closed Deku", "Open"}, {forestClosed, forestClosedDeku, forestOpen}, OptionCategory::Setting, OPENFOREST_CLOSED);
|
||||
Option OpenKakariko = Option::U8 ("Kakariko Gate", {"Closed", "Open"}, {kakGateClosed, kakGateOpen});
|
||||
Option OpenDoorOfTime = Option::U8 ("Door of Time", {"Open", "Closed", "Intended"}, {doorOfTimeOpen, doorOfTimeClosed, doorOfTimeIntended});
|
||||
Option ZorasFountain = Option::U8 ("Zora's Fountain", {"Normal", "Adult", "Open"}, {fountainNormal, fountainAdult, fountainOpen});
|
||||
Option OpenDoorOfTime = Option::U8 ("Door of Time", {"Closed", "Song only", "Open"}, {doorOfTimeIntended, doorOfTimeClosed, doorOfTimeOpen});
|
||||
Option ZorasFountain = Option::U8 ("Zora's Fountain", {"Closed", "Closed as child", "Open"}, {fountainNormal, fountainAdult, fountainOpen});
|
||||
Option GerudoFortress = Option::U8 ("Gerudo Fortress", {"Normal", "Fast", "Open"}, {gerudoNormal, gerudoFast, gerudoOpen});
|
||||
Option Bridge = Option::U8 ("Rainbow Bridge", {"Open", "Vanilla", "Stones", "Medallions", "Rewards", "Dungeons", "Tokens"}, {bridgeOpen, bridgeVanilla, bridgeStones, bridgeMedallions, bridgeRewards, bridgeDungeons, bridgeTokens}, OptionCategory::Setting, RAINBOWBRIDGE_VANILLA);
|
||||
Option BridgeStoneCount = Option::U8 (" Stone Count", {NumOpts(0, 3)}, {bridgeStoneCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeMedallionCount= Option::U8 (" Medallion Count", {NumOpts(0, 6)}, {bridgeMedallionCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeRewardCount = Option::U8 (" Reward Count", {NumOpts(0, 9)}, {bridgeRewardCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeDungeonCount = Option::U8 (" Dungeon Count", {NumOpts(0, 8)}, {bridgeDungeonCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeTokenCount = Option::U8 (" Token Count", {NumOpts(0, 100)}, {bridgeTokenCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option Bridge = Option::U8 ("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens"}, {bridgeVanilla, bridgeOpen, bridgeStones, bridgeMedallions, bridgeRewards, bridgeDungeons, bridgeTokens}, OptionCategory::Setting, RAINBOWBRIDGE_VANILLA);
|
||||
Option BridgeStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 3)}, {bridgeStoneCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeMedallionCount= Option::U8 ("Medallion Count", {NumOpts(0, 6)}, {bridgeMedallionCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 9)}, {bridgeRewardCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 8)}, {bridgeDungeonCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option BridgeTokenCount = Option::U8 ("Token Count", {NumOpts(0, 100)}, {bridgeTokenCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option RandomGanonsTrials = Option::Bool("Random Ganon's Trials", {"Off", "On"}, {randomGanonsTrialsDesc}, OptionCategory::Setting, ON);
|
||||
Option GanonsTrialsCount = Option::U8 (" Trial Count", {NumOpts(0, 6)}, {ganonsTrialCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option GanonsTrialsCount = Option::U8 ("Trial Count", {NumOpts(0, 6)}, {ganonsTrialCountDesc}, OptionCategory::Setting, 1, true);
|
||||
std::vector<Option *> openOptions = {
|
||||
&RandomizeOpen,
|
||||
&OpenForest,
|
||||
@ -87,10 +87,10 @@ namespace Settings {
|
||||
Option StartingAge = Option::U8 ("Starting Age", {"Adult", "Child", "Random"}, {ageDesc}, OptionCategory::Setting, AGE_CHILD);
|
||||
uint8_t ResolvedStartingAge;
|
||||
Option ShuffleEntrances = Option::Bool("Shuffle Entrances", {"Off", "On"}, {shuffleEntrancesDesc});
|
||||
Option ShuffleDungeonEntrances = Option::U8 (" Dungeon Entrances", {"Off", "On", "On + Ganon"}, {dungeonEntrancesDesc});
|
||||
Option ShuffleOverworldEntrances = Option::Bool(" Overworld Entrances", {"Off", "On"}, {overworldEntrancesDesc});
|
||||
Option ShuffleInteriorEntrances = Option::U8 (" Interior Entrances", {"Off", "Simple", "All"}, {interiorEntrancesOff, interiorEntrancesSimple, interiorEntrancesAll});
|
||||
Option ShuffleGrottoEntrances = Option::Bool(" Grottos Entrances", {"Off", "On"}, {grottoEntrancesDesc});
|
||||
Option ShuffleDungeonEntrances = Option::U8 ("Dungeon Entrances", {"Off", "On", "On + Ganon"}, {dungeonEntrancesDesc});
|
||||
Option ShuffleOverworldEntrances = Option::Bool("Overworld Entrances", {"Off", "On"}, {overworldEntrancesDesc});
|
||||
Option ShuffleInteriorEntrances = Option::U8 ("Interior Entrances", {"Off", "Simple", "All"}, {interiorEntrancesOff, interiorEntrancesSimple, interiorEntrancesAll});
|
||||
Option ShuffleGrottoEntrances = Option::Bool("Grottos Entrances", {"Off", "On"}, {grottoEntrancesDesc});
|
||||
Option BombchusInLogic = Option::Bool("Bombchus in Logic", {"Off", "On"}, {bombchuLogicDesc});
|
||||
Option AmmoDrops = Option::U8 ("Ammo Drops", {"On", "On + Bombchu", "Off"}, {defaultAmmoDropsDesc, bombchuDropsDesc, noAmmoDropsDesc}, OptionCategory::Setting, AMMODROPS_BOMBCHU);
|
||||
Option HeartDropRefill = Option::U8 ("Heart Drops and Refills",{"On", "No Drop", "No Refill", "Off"}, {defaultHeartDropsDesc, noHeartDropsDesc, noHeartRefillDesc, scarceHeartsDesc}, OptionCategory::Setting, HEARTDROPREFILL_VANILLA);
|
||||
@ -98,18 +98,18 @@ namespace Settings {
|
||||
uint8_t MQSet;
|
||||
bool DungeonModesKnown[12];
|
||||
Option SetDungeonTypes = Option::Bool("Set Dungeon Types", {"Off", "On"}, {setDungeonTypesDesc});
|
||||
Option MQDeku = Option::U8 (" Deku Tree", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQDodongo = Option::U8 (" Dodongo's Cavern", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQJabu = Option::U8 (" Jabu-Jabu's Belly", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQForest = Option::U8 (" Forest Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQFire = Option::U8 (" Fire Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQWater = Option::U8 (" Water Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQSpirit = Option::U8 (" Spirit Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQShadow = Option::U8 (" Shadow Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQBotW = Option::U8 (" Bottom of the Well", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQIceCavern = Option::U8 (" Ice Cavern", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQGTG = Option::U8 (" Training Grounds", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQCastle = Option::U8 (" Ganon's Castle", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQDeku = Option::U8 ("Deku Tree", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQDodongo = Option::U8 ("Dodongo's Cavern", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQJabu = Option::U8 ("Jabu-Jabu's Belly", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQForest = Option::U8 ("Forest Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQFire = Option::U8 ("Fire Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQWater = Option::U8 ("Water Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQSpirit = Option::U8 ("Spirit Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQShadow = Option::U8 ("Shadow Temple", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQBotW = Option::U8 ("Bottom of the Well", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQIceCavern = Option::U8 ("Ice Cavern", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQGTG = Option::U8 ("Training Grounds", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
Option MQCastle = Option::U8 ("Ganon's Castle", {"Vanilla", "Master Quest", "Random"}, {setDungeonTypesDesc});
|
||||
std::vector<Option *> worldOptions = {
|
||||
&RandomizeWorld,
|
||||
&StartingAge,
|
||||
@ -153,9 +153,9 @@ namespace Settings {
|
||||
|
||||
//Shuffle Settings
|
||||
Option RandomizeShuffle = Option::Bool("Randomize Settings", {"No","Yes"}, {shuffleRandomize}, OptionCategory::Toggle);
|
||||
Option ShuffleRewards = Option::U8 ("Shuffle Dungeon Rewards",{"End of Dungeons", "Any Dungeon", "Overworld", "Anywhere"}, {shuffleRewardsEndOfDungeon, shuffleRewardsAnyDungeon, shuffleRewardsOverworld, shuffleRewardsAnywhere});
|
||||
Option ShuffleRewards = Option::U8 ("Shuffle Dungeon Rewards",{"End of dungeons", "Any dungeon", "Overworld", "Anywhere"}, {shuffleRewardsEndOfDungeon, shuffleRewardsAnyDungeon, shuffleRewardsOverworld, shuffleRewardsAnywhere});
|
||||
Option LinksPocketItem = Option::U8 ("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, {linksPocketDungeonReward, linksPocketAdvancement, linksPocketAnything, linksPocketNothing});
|
||||
Option ShuffleSongs = Option::U8 ("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, {songsSongLocations, songsDungeonRewards, songsAllLocations});
|
||||
Option ShuffleSongs = Option::U8 ("Shuffle Songs", {"Song locations", "Dungeon rewards", "Anywhere"}, {songsSongLocations, songsDungeonRewards, songsAllLocations});
|
||||
Option Shopsanity = Option::U8 ("Shopsanity", {MultiVecOpts({{"Off"}, NumOpts(0, 4), {"Random"}})}, {shopsOff, shopsZero, shopsOne, shopsTwo, shopsThree, shopsFour, shopsRandom});
|
||||
Option Tokensanity = Option::U8 ("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, {tokensOff, tokensDungeon, tokensOverworld, tokensAllTokens});
|
||||
Option Scrubsanity = Option::U8 ("Scrub Shuffle", {"Off", "Affordable", "Expensive", "Random Prices"}, {scrubsOff, scrubsAffordable, scrubsExpensive, scrubsRandomPrices});
|
||||
@ -163,9 +163,10 @@ namespace Settings {
|
||||
Option ShuffleKokiriSword = Option::Bool("Shuffle Kokiri Sword", {"Off", "On"}, {kokiriSwordDesc});
|
||||
Option ShuffleOcarinas = Option::Bool("Shuffle Ocarinas", {"Off", "On"}, {ocarinasDesc});
|
||||
Option ShuffleWeirdEgg = Option::Bool("Shuffle Weird Egg", {"Off", "On"}, {weirdEggDesc});
|
||||
Option ShuffleGerudoToken = Option::Bool("Shuffle Gerudo Membership Card", {"Off", "On"}, {gerudoTokenDesc});
|
||||
Option ShuffleGerudoToken = Option::Bool("Shuffle Gerudo Card", {"Off", "On"}, {gerudoTokenDesc});
|
||||
Option ShuffleMagicBeans = Option::Bool("Shuffle Magic Beans", {"Off", "On"}, {magicBeansDesc});
|
||||
Option ShuffleMerchants = Option::U8 ("Shuffle Merchants", {"Off", "On (No Hints)", "On (With Hints)"}, {merchantsDesc, merchantsHintsDesc});
|
||||
Option ShuffleFrogSongRupees = Option::Bool("Shuffle Frog Song Rupees",{"Off", "On"}, {frogSongRupeesDesc});
|
||||
Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"}, {adultTradeDesc});
|
||||
Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}, {chestMinigameDesc});
|
||||
std::vector<Option *> shuffleOptions = {
|
||||
@ -183,6 +184,7 @@ namespace Settings {
|
||||
&ShuffleGerudoToken,
|
||||
&ShuffleMagicBeans,
|
||||
&ShuffleMerchants,
|
||||
&ShuffleFrogSongRupees,
|
||||
&ShuffleAdultTradeQuest,
|
||||
&ShuffleChestMinigame,
|
||||
};
|
||||
@ -197,24 +199,24 @@ namespace Settings {
|
||||
{gerudoKeysVanilla, gerudoKeysAnyDungeon, gerudoKeysOverworld, gerudoKeysAnywhere});
|
||||
Option BossKeysanity = Option::U8 ("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"},
|
||||
{bossKeyStartWith, bossKeyVanilla, bossKeyOwnDungeon, bossKeyAnyDungeon, bossKeyOverworld, bossKeyAnywhere}, OptionCategory::Setting, BOSSKEYSANITY_OWN_DUNGEON);
|
||||
Option GanonsBossKey = Option::U8 ("Ganon's Boss Key", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Medallions", "LACS-Stones", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens"},
|
||||
{ganonKeyStartWith, ganonKeyVanilla, ganonKeyOwnDungeon, ganonKeyAnyDungeon, ganonKeyOverworld, ganonKeyAnywhere, ganonKeyLACS}, OptionCategory::Setting, GANONSBOSSKEY_OWN_DUNGEON);
|
||||
Option GanonsBossKey = Option::U8 ("Ganon's Boss Key", {"Vanilla", "Own dungeon", "Start with", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Medallions", "LACS-Stones", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens"},
|
||||
{ganonKeyVanilla, ganonKeyOwnDungeon, ganonKeyStartWith, ganonKeyAnyDungeon, ganonKeyOverworld, ganonKeyAnywhere, ganonKeyLACS}, OptionCategory::Setting, GANONSBOSSKEY_VANILLA);
|
||||
uint8_t LACSCondition = 0;
|
||||
Option LACSMedallionCount = Option::U8 (" Medallion Count", {NumOpts(0, 6)}, {lacsMedallionCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSStoneCount = Option::U8 (" Stone Count", {NumOpts(0, 3)}, {lacsStoneCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSRewardCount = Option::U8 (" Reward Count", {NumOpts(0, 9)}, {lacsRewardCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSDungeonCount = Option::U8 (" Dungeon Count", {NumOpts(0, 8)}, {lacsDungeonCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSTokenCount = Option::U8 (" Token Count", {NumOpts(0, 100)}, {lacsTokenCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSMedallionCount = Option::U8 ("Medallion Count", {NumOpts(0, 6)}, {lacsMedallionCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 3)}, {lacsStoneCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 9)}, {lacsRewardCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 8)}, {lacsDungeonCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option LACSTokenCount = Option::U8 ("Token Count", {NumOpts(0, 100)}, {lacsTokenCountDesc}, OptionCategory::Setting, 1, true);
|
||||
Option KeyRings = Option::Bool("Key Rings", {"Off", "On"}, {keyRingDesc});
|
||||
Option RingFortress = Option::Bool(" Gerudo Fortress", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingForest = Option::Bool(" Forest Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingFire = Option::Bool(" Fire Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingWater = Option::Bool(" Water Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingSpirit = Option::Bool(" Spirit Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingShadow = Option::Bool(" Shadow Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingWell = Option::Bool(" Bottom of the Well", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingGtg = Option::Bool(" GTG", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingCastle = Option::Bool(" Ganon's Castle", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingFortress = Option::Bool("Gerudo Fortress", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingForest = Option::Bool("Forest Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingFire = Option::Bool("Fire Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingWater = Option::Bool("Water Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingSpirit = Option::Bool("Spirit Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingShadow = Option::Bool("Shadow Temple", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingWell = Option::Bool("Bottom of the Well", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingGtg = Option::Bool("GTG", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
Option RingCastle = Option::Bool("Ganon's Castle", {"Off", "On"}, {keyRingDesc}, OptionCategory::Setting);
|
||||
|
||||
std::vector<Option *> shuffleDungeonItemOptions = {
|
||||
&RandomizeDungeon,
|
||||
@ -263,8 +265,9 @@ namespace Settings {
|
||||
Option NumRequiredCuccos = Option::U8 ("Cuccos to return", {NumOpts(0, 7)}, {numRequiredCuccosDesc});
|
||||
Option KingZoraSpeed = Option::U8 ("King Zora Speed", {"Fast", "Vanilla", "Random"}, {kingZoraSpeedFast, kingZoraSpeedVanilla, kingZoraSpeedRandom});
|
||||
Option CompleteMaskQuest = Option::Bool("Complete Mask Quest", {"Off", "On"}, {completeMaskDesc});
|
||||
Option EnableGlitchCutscenes = Option::Bool("Enable Glitch-Useful Cutscenes", {"Off", "On"}, {glitchCutscenesDesc});
|
||||
Option QuickText = Option::U8 ("Quick Text", {"0: Vanilla", "1: Skippable", "2: Instant", "3: Turbo"}, {quickTextDesc0, quickTextDesc1, quickTextDesc2, quickTextDesc3}, OptionCategory::Setting, QUICKTEXT_INSTANT);
|
||||
Option SkipSongReplays = Option::U8 (" Skip Song Replays", {"Don't Skip", "Skip (No SFX)", "Skip (Keep SFX)"}, {skipSongReplaysDesc});
|
||||
Option SkipSongReplays = Option::U8 ("Skip Song Replays", {"Don't Skip", "Skip (No SFX)", "Skip (Keep SFX)"}, {skipSongReplaysDesc});
|
||||
Option KeepFWWarpPoint = Option::Bool("Keep FW Warp Point", {"Off", "On"}, {keepFWWarpPointDesc});
|
||||
Option FastBunnyHood = Option::Bool("Fast Bunny Hood", {"Off", "On"}, {fastBunnyHoodDesc});
|
||||
std::vector<Option *> timesaverOptions = {
|
||||
@ -279,6 +282,7 @@ namespace Settings {
|
||||
&NumRequiredCuccos,
|
||||
&KingZoraSpeed,
|
||||
&CompleteMaskQuest,
|
||||
&EnableGlitchCutscenes,
|
||||
&QuickText,
|
||||
&SkipSongReplays,
|
||||
&KeepFWWarpPoint,
|
||||
@ -287,8 +291,8 @@ namespace Settings {
|
||||
|
||||
//Misc Settings
|
||||
Option GossipStoneHints = Option::U8 ("Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, {gossipStonesHintsDesc}, OptionCategory::Setting, HINTS_NEED_NOTHING);
|
||||
Option ClearerHints = Option::U8 (" Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, {obscureHintsDesc, ambiguousHintsDesc, clearHintsDesc});
|
||||
Option HintDistribution = Option::U8 (" Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, {uselessHintsDesc, balancedHintsDesc, strongHintsDesc, veryStrongHintsDesc}, OptionCategory::Setting, 1); // Balanced
|
||||
Option ClearerHints = Option::U8 ("Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, {obscureHintsDesc, ambiguousHintsDesc, clearHintsDesc});
|
||||
Option HintDistribution = Option::U8 ("Hint Distribution", {"Useless", "Balanced", "Strong", "Very Strong"}, {uselessHintsDesc, balancedHintsDesc, strongHintsDesc, veryStrongHintsDesc}, OptionCategory::Setting, 1); // Balanced
|
||||
Option CompassesShowReward = Option::U8 ("Compasses Show Rewards", {"No", "Yes"}, {compassesShowRewardsDesc}, OptionCategory::Setting, 1);
|
||||
Option CompassesShowWotH = Option::U8 ("Compasses Show WotH", {"No", "Yes"}, {compassesShowWotHDesc}, OptionCategory::Setting, 1);
|
||||
Option MapsShowDungeonMode = Option::U8 ("Maps Show Dungeon Modes",{"No", "Yes"}, {mapsShowDungeonModesDesc}, OptionCategory::Setting, 1);
|
||||
@ -321,22 +325,22 @@ namespace Settings {
|
||||
//Item Usability Settings
|
||||
Option FaroresWindAnywhere = Option::Bool("Farore's Wind Anywhere", {"Disabled", "Enabled"}, {faroresWindAnywhereDesc});
|
||||
Option AgeItemsToggle = Option::U8 ("Lift Age Restrictions", {"All Disabled", "All Enabled", "Choose"}, {ageRestrictionsDesc});
|
||||
Option StickAsAdult = Option::Bool(" Adult Deku Stick", {"Disabled", "Enabled"}, {adultStickDesc});
|
||||
Option BoomerangAsAdult = Option::Bool(" Adult Boomerang", {"Disabled", "Enabled"}, {adultBoomerangDesc});
|
||||
Option HammerAsChild = Option::Bool(" Child Hammer", {"Disabled", "Enabled"}, {childHammerDesc});
|
||||
Option SlingshotAsAdult = Option::Bool(" Adult Slingshot", {"Disabled", "Enabled"}, {adultSlingshotDesc});
|
||||
Option BowAsChild = Option::Bool(" Child Bow", {"Disabled", "Enabled"}, {childBowDesc});
|
||||
Option HookshotAsChild = Option::Bool(" Child Hookshot", {"Disabled", "Enabled"}, {childHookshotDesc});
|
||||
Option IronBootsAsChild = Option::Bool(" Child Iron Boots", {"Disabled", "Enabled"}, {childIronBootsDesc});
|
||||
Option HoverBootsAsChild = Option::Bool(" Child Hover Boots", {"Disabled", "Enabled"}, {childHoverBootsDesc});
|
||||
Option MasksAsAdult = Option::Bool(" Adult Masks", {"Disabled", "Enabled"}, {adultMasksDesc});
|
||||
Option KokiriSwordAsAdult = Option::Bool(" Adult Kokiri Sword", {"Disabled", "Enabled"}, {adultKokiriSwordDesc});
|
||||
Option MasterSwordAsChild = Option::Bool(" Child Master Sword", {"Disabled", "Enabled"}, {childMasterSwordDesc});
|
||||
Option BiggoronSwordAsChild= Option::Bool(" Child Biggoron Sword", {"Disabled", "Enabled"}, {childBiggoronSwordDesc});
|
||||
Option DekuShieldAsAdult = Option::Bool(" Adult Deku Shield", {"Disabled", "Enabled"}, {adultDekuShieldDesc});
|
||||
Option MirrorShieldAsChild = Option::Bool(" Child Mirror Shield", {"Disabled", "Enabled"}, {childMirrorShieldDesc});
|
||||
Option GoronTunicAsChild = Option::Bool(" Child Goron Tunic", {"Disabled", "Enabled"}, {childGoronTunicDesc});
|
||||
Option ZoraTunicAsChild = Option::Bool(" Child Zora Tunic", {"Disabled", "Enabled"}, {childZoraTunicDesc});
|
||||
Option StickAsAdult = Option::Bool("Adult Deku Stick", {"Disabled", "Enabled"}, {adultStickDesc});
|
||||
Option BoomerangAsAdult = Option::Bool("Adult Boomerang", {"Disabled", "Enabled"}, {adultBoomerangDesc});
|
||||
Option HammerAsChild = Option::Bool("Child Hammer", {"Disabled", "Enabled"}, {childHammerDesc});
|
||||
Option SlingshotAsAdult = Option::Bool("Adult Slingshot", {"Disabled", "Enabled"}, {adultSlingshotDesc});
|
||||
Option BowAsChild = Option::Bool("Child Bow", {"Disabled", "Enabled"}, {childBowDesc});
|
||||
Option HookshotAsChild = Option::Bool("Child Hookshot", {"Disabled", "Enabled"}, {childHookshotDesc});
|
||||
Option IronBootsAsChild = Option::Bool("Child Iron Boots", {"Disabled", "Enabled"}, {childIronBootsDesc});
|
||||
Option HoverBootsAsChild = Option::Bool("Child Hover Boots", {"Disabled", "Enabled"}, {childHoverBootsDesc});
|
||||
Option MasksAsAdult = Option::Bool("Adult Masks", {"Disabled", "Enabled"}, {adultMasksDesc});
|
||||
Option KokiriSwordAsAdult = Option::Bool("Adult Kokiri Sword", {"Disabled", "Enabled"}, {adultKokiriSwordDesc});
|
||||
Option MasterSwordAsChild = Option::Bool("Child Master Sword", {"Disabled", "Enabled"}, {childMasterSwordDesc});
|
||||
Option BiggoronSwordAsChild= Option::Bool("Child Biggoron Sword", {"Disabled", "Enabled"}, {childBiggoronSwordDesc});
|
||||
Option DekuShieldAsAdult = Option::Bool("Adult Deku Shield", {"Disabled", "Enabled"}, {adultDekuShieldDesc});
|
||||
Option MirrorShieldAsChild = Option::Bool("Child Mirror Shield", {"Disabled", "Enabled"}, {childMirrorShieldDesc});
|
||||
Option GoronTunicAsChild = Option::Bool("Child Goron Tunic", {"Disabled", "Enabled"}, {childGoronTunicDesc});
|
||||
Option ZoraTunicAsChild = Option::Bool("Child Zora Tunic", {"Disabled", "Enabled"}, {childZoraTunicDesc});
|
||||
Option GkDurability = Option::U8 ("GK Durability", {"Vanilla", "Random Risk", "Random Safe"}, {gkDurabilityVanilla, gkDurabilityRandomRisk, gkDurabilityRandomSafe});
|
||||
std::vector<Option *> itemUsabilityOptions = {
|
||||
&FaroresWindAnywhere,
|
||||
@ -430,7 +434,7 @@ namespace Settings {
|
||||
Option StartingStickCapacity = Option::U8 ("Deku Stick Capacity", {NumOpts(10, 30, 10, {}, " Deku Sticks")}, {""});
|
||||
Option StartingNutCapacity = Option::U8 ("Deku Nut Capacity", {NumOpts(20, 40, 10, {}, " Deku Nuts")}, {""});
|
||||
Option StartingSlingshot = Option::U8 ("Slingshot", {"Off", "Slingshot (30)", "Slingshot (40)", "Slingshot (50)"}, {""});
|
||||
Option StartingOcarina = Option::U8 ("Ocarina", {"Off", "Fairy Ocarina", "Ocarina of Time"}, {""});
|
||||
Option StartingOcarina = Option::U8 ("Start with Fairy Ocarina", {"Off", "Fairy Ocarina", "Ocarina of Time"}, {""});
|
||||
Option StartingBombBag = Option::U8 ("Bombs", {"Off", "Bomb Bag (20)", "Bomb Bag (30)", "Bomb Bag (40)"}, {""});
|
||||
Option StartingBombchus = Option::U8 ("Bombchus", {"Off", "20 Bombchus", "50 Bombchus"}, {""});
|
||||
Option StartingBoomerang = Option::U8 ("Boomerang", {"Off", "On"}, {""});
|
||||
@ -507,9 +511,9 @@ namespace Settings {
|
||||
&StartingPreludeOfLight,
|
||||
};
|
||||
|
||||
Option StartingKokiriSword = Option::U8 ("Kokiri Sword", {"Off", "On"}, {""});
|
||||
Option StartingKokiriSword = Option::U8 ("Start with Kokiri Sword", {"Off", "On"}, {""});
|
||||
Option StartingBiggoronSword = Option::U8 ("Biggoron Sword", {"Off", "Giant's Knife", "Biggoron Sword"}, {""});
|
||||
Option StartingDekuShield = Option::U8 ("Deku Shield", {"Off", "On"}, {""});
|
||||
Option StartingDekuShield = Option::U8 ("Start with Deku Shield", {"Off", "On"}, {""});
|
||||
Option StartingHylianShield = Option::U8 ("Hylian Shield", {"Off", "On"}, {""});
|
||||
Option StartingMirrorShield = Option::U8 ("Mirror Shield", {"Off", "On"}, {""});
|
||||
Option StartingGoronTunic = Option::U8 ("Goron Tunic", {"Off", "On"}, {""});
|
||||
@ -1263,6 +1267,7 @@ namespace Settings {
|
||||
ctx.shuffleGerudoToken = (ShuffleGerudoToken) ? 1 : 0;
|
||||
ctx.shuffleMagicBeans = (ShuffleMagicBeans) ? 1 : 0;
|
||||
ctx.shuffleMerchants = ShuffleMerchants.Value<uint8_t>();
|
||||
ctx.shuffleFrogSongRupees= (ShuffleFrogSongRupees) ? 1 : 0;
|
||||
ctx.shuffleAdultTradeQuest = (ShuffleAdultTradeQuest) ? 1 : 0;
|
||||
ctx.shuffleChestMinigame = ShuffleChestMinigame.Value<uint8_t>();
|
||||
|
||||
@ -1299,6 +1304,7 @@ namespace Settings {
|
||||
ctx.numRequiredCuccos = NumRequiredCuccos.Value<uint8_t>();
|
||||
ctx.kingZoraSpeed = KingZoraSpeed.Value<uint8_t>();
|
||||
ctx.completeMaskQuest = CompleteMaskQuest ? 1 : 0;
|
||||
ctx.enableGlitchCutscenes = EnableGlitchCutscenes ? 1 : 0;
|
||||
ctx.quickText = QuickText.Value<uint8_t>();
|
||||
ctx.skipSongReplays = SkipSongReplays.Value<uint8_t>();
|
||||
ctx.keepFWWarpPoint = KeepFWWarpPoint ? 1 : 0;
|
||||
@ -1724,6 +1730,21 @@ namespace Settings {
|
||||
IncludeAndHide({WASTELAND_BOMBCHU_SALESMAN});
|
||||
}
|
||||
|
||||
//Force include frog song rupees if they're not shuffled
|
||||
if (ShuffleFrogSongRupees) {
|
||||
Unhide({ZR_FROGS_ZELDAS_LULLABY});
|
||||
Unhide({ZR_FROGS_EPONAS_SONG});
|
||||
Unhide({ZR_FROGS_SARIAS_SONG});
|
||||
Unhide({ZR_FROGS_SUNS_SONG});
|
||||
Unhide({ZR_FROGS_SONG_OF_TIME});
|
||||
} else {
|
||||
IncludeAndHide({ZR_FROGS_ZELDAS_LULLABY});
|
||||
IncludeAndHide({ZR_FROGS_EPONAS_SONG});
|
||||
IncludeAndHide({ZR_FROGS_SARIAS_SONG});
|
||||
IncludeAndHide({ZR_FROGS_SUNS_SONG});
|
||||
IncludeAndHide({ZR_FROGS_SONG_OF_TIME});
|
||||
}
|
||||
|
||||
//Force include adult trade quest if Shuffle Adult Trade Quest is off
|
||||
std::vector<uint32_t> adultTradeLocations = {KAK_TRADE_POCKET_CUCCO, LW_TRADE_COJIRO, KAK_TRADE_ODD_MUSHROOM, LW_TRADE_ODD_POTION, GV_TRADE_SAW, DMT_TRADE_BROKEN_SWORD, ZD_TRADE_PRESCRIPTION, LH_TRADE_FROG, DMT_TRADE_EYEDROPS};
|
||||
if (ShuffleAdultTradeQuest) {
|
||||
@ -2261,6 +2282,7 @@ namespace Settings {
|
||||
&ShuffleCows,
|
||||
&ShuffleMagicBeans,
|
||||
&ShuffleMerchants,
|
||||
&ShuffleFrogSongRupees,
|
||||
&ShuffleAdultTradeQuest,
|
||||
&GossipStoneHints,
|
||||
};
|
||||
@ -2463,6 +2485,17 @@ namespace Settings {
|
||||
//Function to set flags depending on settings
|
||||
void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettings) {
|
||||
|
||||
// RANDTODO: Switch this back once all logic options are implemented
|
||||
// Logic.SetSelectedIndex(cvarSettings[RSK_LOGIC_RULES]);
|
||||
switch (cvarSettings[RSK_LOGIC_RULES]) {
|
||||
case 0:
|
||||
Logic.SetSelectedIndex(0);
|
||||
break;
|
||||
case 1:
|
||||
Logic.SetSelectedIndex(2);
|
||||
break;
|
||||
}
|
||||
|
||||
OpenForest.SetSelectedIndex(cvarSettings[RSK_FOREST]);
|
||||
OpenKakariko.SetSelectedIndex(cvarSettings[RSK_KAK_GATE]);
|
||||
ZorasFountain.SetSelectedIndex(cvarSettings[RSK_ZORAS_FOUNTAIN]);
|
||||
@ -2488,6 +2521,8 @@ namespace Settings {
|
||||
|
||||
ShuffleRewards.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS]);
|
||||
ShuffleSongs.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_SONGS]);
|
||||
Tokensanity.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_TOKENS]);
|
||||
ShuffleCows.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_COWS]);
|
||||
ShuffleKokiriSword.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD]);
|
||||
ShuffleOcarinas.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_OCARINA]);
|
||||
|
||||
@ -2503,6 +2538,9 @@ namespace Settings {
|
||||
SkipChildStealth.SetSelectedIndex(cvarSettings[RSK_SKIP_CHILD_STEALTH]);
|
||||
|
||||
ShuffleGerudoToken.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
|
||||
ShuffleFrogSongRupees.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_FROG_SONG_RUPEES]);
|
||||
|
||||
ShuffleAdultTradeQuest.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_ADULT_TRADE]);
|
||||
|
||||
// the checkbox works because 0 is "Off" and 1 is "Fairy Ocarina"
|
||||
StartingOcarina.SetSelectedIndex(cvarSettings[RSK_STARTING_OCARINA]);
|
||||
@ -2511,14 +2549,7 @@ namespace Settings {
|
||||
StartingDekuShield.SetSelectedIndex(cvarSettings[RSK_STARTING_DEKU_SHIELD]);
|
||||
StartingKokiriSword.SetSelectedIndex(cvarSettings[RSK_STARTING_KOKIRI_SWORD]);
|
||||
|
||||
if(cvarSettings[RSK_STARTING_MAPS_COMPASSES]) {
|
||||
// "Start With" is index 0
|
||||
MapsAndCompasses.SetSelectedIndex(0);
|
||||
} else {
|
||||
// We don't support maps/compasses outside of their own dungeon yet
|
||||
// "Own Dungeon" is index 2
|
||||
MapsAndCompasses.SetSelectedIndex(2);
|
||||
}
|
||||
MapsAndCompasses.SetSelectedIndex(cvarSettings[RSK_STARTING_MAPS_COMPASSES]);
|
||||
|
||||
StartingConsumables.SetSelectedIndex(cvarSettings[RSK_STARTING_CONSUMABLES]);
|
||||
StartingMaxRupees.SetSelectedIndex(cvarSettings[RSK_FULL_WALLETS]);
|
||||
@ -2530,6 +2561,9 @@ namespace Settings {
|
||||
ItemPoolValue.SetSelectedIndex(cvarSettings[RSK_ITEM_POOL]);
|
||||
IceTrapValue.SetSelectedIndex(cvarSettings[RSK_ICE_TRAPS]);
|
||||
|
||||
Keysanity.SetSelectedIndex(cvarSettings[RSK_KEYSANITY]);
|
||||
GerudoKeys.SetSelectedIndex(cvarSettings[RSK_GERUDO_KEYS]);
|
||||
BossKeysanity.SetSelectedIndex(cvarSettings[RSK_BOSS_KEYSANITY]);
|
||||
GanonsBossKey.SetSelectedIndex(cvarSettings[RSK_GANONS_BOSS_KEY]);
|
||||
|
||||
NumRequiredCuccos.SetSelectedIndex(cvarSettings[RSK_CUCCO_COUNT]);
|
||||
@ -2539,6 +2573,12 @@ namespace Settings {
|
||||
|
||||
SkipTowerEscape.SetSelectedIndex(cvarSettings[RSK_SKIP_TOWER_ESCAPE]);
|
||||
|
||||
CompleteMaskQuest.SetSelectedIndex(cvarSettings[RSK_COMPLETE_MASK_QUEST]);
|
||||
|
||||
EnableGlitchCutscenes.SetSelectedIndex(cvarSettings[RSK_ENABLE_GLITCH_CUTSCENES]);
|
||||
|
||||
NightGSExpectSuns.SetSelectedIndex(cvarSettings[RSK_SKULLS_SUNS_SONG]);
|
||||
|
||||
// RANDOTODO implement chest shuffle with keysanity
|
||||
// ShuffleChestMinigame.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]);
|
||||
|
||||
|
@ -34,8 +34,8 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
OPENFOREST_CLOSED,
|
||||
OPENFOREST_OPEN,
|
||||
OPENFOREST_CLOSED_DEKU,
|
||||
OPENFOREST_OPEN,
|
||||
} OpenForestSetting;
|
||||
|
||||
typedef enum {
|
||||
@ -44,9 +44,9 @@ typedef enum {
|
||||
} OpenKakarikoSetting;
|
||||
|
||||
typedef enum {
|
||||
OPENDOOROFTIME_OPEN,
|
||||
OPENDOOROFTIME_CLOSED,
|
||||
OPENDOOROFTIME_INTENDED,
|
||||
OPENDOOROFTIME_CLOSED,
|
||||
OPENDOOROFTIME_OPEN,
|
||||
} OpenDoorOfTimeSetting;
|
||||
|
||||
typedef enum {
|
||||
@ -62,8 +62,8 @@ typedef enum {
|
||||
} GerudoFortressSetting;
|
||||
|
||||
typedef enum {
|
||||
RAINBOWBRIDGE_OPEN,
|
||||
RAINBOWBRIDGE_VANILLA,
|
||||
RAINBOWBRIDGE_OPEN,
|
||||
RAINBOWBRIDGE_STONES,
|
||||
RAINBOWBRIDGE_MEDALLIONS,
|
||||
RAINBOWBRIDGE_REWARDS,
|
||||
@ -212,9 +212,9 @@ typedef enum {
|
||||
} BossKeysanitySetting;
|
||||
|
||||
typedef enum {
|
||||
GANONSBOSSKEY_START_WITH,
|
||||
GANONSBOSSKEY_VANILLA,
|
||||
GANONSBOSSKEY_OWN_DUNGEON,
|
||||
GANONSBOSSKEY_START_WITH,
|
||||
GANONSBOSSKEY_ANY_DUNGEON,
|
||||
GANONSBOSSKEY_OVERWORLD,
|
||||
GANONSBOSSKEY_ANYWHERE,
|
||||
@ -403,6 +403,7 @@ typedef struct {
|
||||
uint8_t shuffleGerudoToken;
|
||||
uint8_t shuffleMagicBeans;
|
||||
uint8_t shuffleMerchants;
|
||||
uint8_t shuffleFrogSongRupees;
|
||||
uint8_t shuffleAdultTradeQuest;
|
||||
uint8_t shuffleChestMinigame;
|
||||
|
||||
@ -439,6 +440,7 @@ typedef struct {
|
||||
uint8_t numRequiredCuccos;
|
||||
uint8_t kingZoraSpeed;
|
||||
uint8_t completeMaskQuest;
|
||||
uint8_t enableGlitchCutscenes;
|
||||
uint8_t quickText;
|
||||
uint8_t skipSongReplays;
|
||||
uint8_t keepFWWarpPoint;
|
||||
@ -904,6 +906,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
|
||||
extern Option ShuffleGerudoToken;
|
||||
extern Option ShuffleMagicBeans;
|
||||
extern Option ShuffleMerchants;
|
||||
extern Option ShuffleFrogSongRupees;
|
||||
extern Option ShuffleAdultTradeQuest;
|
||||
extern Option ShuffleChestMinigame;
|
||||
|
||||
@ -940,6 +943,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
|
||||
extern Option NumRequiredCuccos;
|
||||
extern Option KingZoraSpeed;
|
||||
extern Option CompleteMaskQuest;
|
||||
extern Option EnableGlitchCutscenes;
|
||||
extern Option QuickText;
|
||||
extern Option SkipSongReplays;
|
||||
extern Option KeepFWWarpPoint;
|
||||
|
@ -347,7 +347,9 @@ static void WriteSettings(const bool printAll = false) {
|
||||
setting->GetName() == "Cuccos to return" ||
|
||||
setting->GetName() == "Skip Epona Race" ||
|
||||
setting->GetName() == "Skip Tower Escape" ||
|
||||
setting->GetName() == "Skip Child Stealth") {
|
||||
setting->GetName() == "Skip Child Stealth" ||
|
||||
setting->GetName() == "Complete Mask Quest" ||
|
||||
setting->GetName() == "Enable Glitch-Useful Cutscenes") {
|
||||
std::string settingName = menu->name + ":" + setting->GetName();
|
||||
jsonData["settings"][settingName] = setting->GetSelectedOptionText();
|
||||
}
|
||||
@ -426,11 +428,11 @@ static void WriteStartingInventory() {
|
||||
// doesn't work, and because it'd be bad to set every single possible starting
|
||||
// inventory item as "false" in the json, we're just going to check
|
||||
// to see if the name is one of the 3 we're using rn
|
||||
if(setting->GetName() == "Deku Shield" || setting->GetName() == "Kokiri Sword" || setting->GetName() == "Ocarina") {
|
||||
jsonData["settings"]["Start With " + setting->GetName()] = setting->GetSelectedOptionText();
|
||||
}
|
||||
|
||||
if (setting->GetName() == "Start with Consumables" || setting->GetName() == "Start with Max Rupees") {
|
||||
if (setting->GetName() == "Start with Consumables" ||
|
||||
setting->GetName() == "Start with Max Rupees" ||
|
||||
setting->GetName() == "Start with Fairy Ocarina" ||
|
||||
setting->GetName() == "Start with Kokiri Sword" ||
|
||||
setting->GetName() == "Start with Deku Shield") {
|
||||
jsonData["settings"][setting->GetName()] = setting->GetSelectedOptionText();
|
||||
}
|
||||
}
|
||||
|
33
soh/soh/Enhancements/randomizer/adult_trade_shuffle.c
Normal file
33
soh/soh/Enhancements/randomizer/adult_trade_shuffle.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
#include "macros.h"
|
||||
|
||||
void Randomizer_ConsumeAdultTradeItem(GlobalContext* globalCtx, u8 itemId) {
|
||||
gSaveContext.adultTradeItems &= ~ADULT_TRADE_FLAG(itemId);
|
||||
Inventory_ReplaceItem(globalCtx, itemId, Randomizer_GetNextAdultTradeItem());
|
||||
}
|
||||
|
||||
u8 Randomizer_GetNextAdultTradeItem() {
|
||||
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
|
||||
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
|
||||
for (int i = 0; i < numTradeItems; i++) {
|
||||
u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems;
|
||||
if (gSaveContext.adultTradeItems & (1 << tradeIndex)) {
|
||||
return ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
}
|
||||
return ITEM_NONE;
|
||||
}
|
||||
|
||||
u8 Randomizer_GetPrevAdultTradeItem() {
|
||||
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
|
||||
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
|
||||
for (int i = 0; i < numTradeItems; i++) {
|
||||
u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems;
|
||||
if (gSaveContext.adultTradeItems & (1 << tradeIndex)) {
|
||||
return ITEM_POCKET_EGG + tradeIndex;
|
||||
}
|
||||
}
|
||||
return ITEM_NONE;
|
||||
}
|
13
soh/soh/Enhancements/randomizer/adult_trade_shuffle.h
Normal file
13
soh/soh/Enhancements/randomizer/adult_trade_shuffle.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef Z_ADULT_TRADE_SHUFFLE_H
|
||||
#define Z_ADULT_TRADE_SHUFFLE_H
|
||||
|
||||
#include <z64.h>
|
||||
|
||||
#define ADULT_TRADE_FLAG(itemId) (1 << (itemId - ITEM_POCKET_EGG))
|
||||
#define PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(itemID) (gSaveContext.adultTradeItems & ADULT_TRADE_FLAG(itemID))
|
||||
|
||||
void Randomizer_ConsumeAdultTradeItem(GlobalContext* globalCtx, u8 itemId);
|
||||
u8 Randomizer_GetNextAdultTradeItem();
|
||||
u8 Randomizer_GetPrevAdultTradeItem();
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,7 @@ typedef struct {
|
||||
} Sprite;
|
||||
|
||||
typedef enum {
|
||||
RC_UNKNOWN_CHECK,
|
||||
RC_LINKS_POCKET,
|
||||
RC_QUEEN_GOHMA,
|
||||
RC_KING_DODONGO,
|
||||
@ -757,7 +758,7 @@ typedef enum {
|
||||
RC_ZR_NEAR_DOMAIN_GOSSIP_STONE,
|
||||
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
|
||||
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
|
||||
RC_UNKNOWN_CHECK
|
||||
RC_MAX
|
||||
} RandomizerCheck;
|
||||
|
||||
// based on https://github.com/TestRunnerSRL/OoT-Randomizer/blob/e337d7f603b91a6bacb618fb32cc7fd70ed9ffca/ItemList.py
|
||||
@ -960,6 +961,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
RSK_NONE,
|
||||
RSK_LOGIC_RULES,
|
||||
RSK_FOREST,
|
||||
RSK_KAK_GATE,
|
||||
RSK_DOOR_OF_TIME,
|
||||
@ -978,16 +980,22 @@ typedef enum {
|
||||
RSK_STARTING_DEKU_SHIELD,
|
||||
RSK_STARTING_KOKIRI_SWORD,
|
||||
RSK_SHUFFLE_KOKIRI_SWORD,
|
||||
RSK_STARTING_MAPS_COMPASSES, //RANDOTODO more options for this, rn it's just start with or own dungeon
|
||||
RSK_STARTING_MAPS_COMPASSES,
|
||||
RSK_SHUFFLE_DUNGEON_REWARDS,
|
||||
RSK_SHUFFLE_SONGS,
|
||||
RSK_SHUFFLE_TOKENS,
|
||||
RSK_SHUFFLE_COWS,
|
||||
RSK_SHUFFLE_WEIRD_EGG,
|
||||
RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD,
|
||||
RSK_SHUFFLE_FROG_SONG_RUPEES,
|
||||
RSK_ITEM_POOL,
|
||||
RSK_ICE_TRAPS,
|
||||
RSK_GOSSIP_STONE_HINTS,
|
||||
RSK_HINT_CLARITY,
|
||||
RSK_HINT_DISTRIBUTION,
|
||||
RSK_KEYSANITY,
|
||||
RSK_GERUDO_KEYS,
|
||||
RSK_BOSS_KEYSANITY,
|
||||
RSK_GANONS_BOSS_KEY,
|
||||
RSK_SKIP_CHILD_STEALTH,
|
||||
RSK_SKIP_CHILD_ZELDA,
|
||||
@ -1004,5 +1012,9 @@ typedef enum {
|
||||
RSK_CUCCO_COUNT,
|
||||
RSK_BIG_POE_COUNT,
|
||||
RSK_SKIP_EPONA_RACE,
|
||||
RSK_SKIP_TOWER_ESCAPE
|
||||
RSK_SKIP_TOWER_ESCAPE,
|
||||
RSK_COMPLETE_MASK_QUEST,
|
||||
RSK_ENABLE_GLITCH_CUTSCENES,
|
||||
RSK_SKULLS_SUNS_SONG,
|
||||
RSK_SHUFFLE_ADULT_TRADE
|
||||
} RandomizerSettingKey;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void InitItemTracker();
|
||||
void DrawItemTracker(bool& open);
|
||||
void DrawItemTracker(bool& open);
|
||||
void DrawItemAmmo(int itemId);
|
||||
|
@ -1726,7 +1726,15 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) {
|
||||
}
|
||||
if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) {
|
||||
if (CVar_GetS32("gInjectSkulltulaCount", 0) != 0) {
|
||||
if (CVar_GetS32("gSkulltulaFreeze", 0) != 0) {
|
||||
// The freeze text cannot be manually dismissed and must be auto-dismissed.
|
||||
// This is fine and even wanted when skull tokens are not shuffled, but when
|
||||
// when they are shuffled we don't want to be able to manually dismiss the box.
|
||||
// Otherwise if we get a token from a chest or an NPC we get stuck in the ItemGet
|
||||
// animation until the text box auto-dismisses.
|
||||
// RANDOTODO: Implement a way to determine if an item came from a skulltula and
|
||||
// inject the auto-dismiss control code if it did.
|
||||
if (CVar_GetS32("gSkulltulaFreeze", 0) != 0 &&
|
||||
!(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_TOKENS) > 0)) {
|
||||
textId = TEXT_GS_NO_FREEZE;
|
||||
} else {
|
||||
textId = TEXT_GS_FREEZE;
|
||||
|
@ -88,6 +88,8 @@ void SaveManager::LoadRandomizerVersion1() {
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.ganonText); i++) {
|
||||
SaveManager::Instance->LoadData("gt" + std::to_string(i), gSaveContext.ganonText[i]);
|
||||
}
|
||||
|
||||
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||
}
|
||||
|
||||
void SaveManager::SaveRandomizer() {
|
||||
@ -130,6 +132,8 @@ void SaveManager::SaveRandomizer() {
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.ganonText); i++) {
|
||||
SaveManager::Instance->SaveData("gt" + std::to_string(i), gSaveContext.ganonText[i]);
|
||||
}
|
||||
|
||||
SaveManager::Instance->SaveData("adultTradeItems", gSaveContext.adultTradeItems);
|
||||
}
|
||||
|
||||
void SaveManager::Init() {
|
||||
@ -736,6 +740,10 @@ void SaveManager::LoadBaseVersion1() {
|
||||
|
||||
SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); });
|
||||
|
||||
SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]);
|
||||
});
|
||||
}
|
||||
|
||||
void SaveManager::LoadBaseVersion2() {
|
||||
@ -896,6 +904,10 @@ void SaveManager::LoadBaseVersion2() {
|
||||
|
||||
SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); });
|
||||
|
||||
SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]);
|
||||
});
|
||||
}
|
||||
|
||||
void SaveManager::SaveBase() {
|
||||
@ -1052,6 +1064,10 @@ void SaveManager::SaveBase() {
|
||||
|
||||
SaveManager::Instance->SaveArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone),
|
||||
[](size_t i) { SaveManager::Instance->SaveData("", gSaveContext.trialsDone[i]); });
|
||||
|
||||
SaveManager::Instance->SaveArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) {
|
||||
SaveManager::Instance->SaveData("", gSaveContext.cowsMilked[i]);
|
||||
});
|
||||
}
|
||||
|
||||
void SaveManager::SaveArray(const std::string& name, const size_t size, SaveArrayFunc func) {
|
||||
|
@ -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(ItemID getItemId);
|
||||
|
||||
// Function originally not called, so repurposing for DPad input
|
||||
void func_800EC960(u8 dpad) {
|
||||
@ -3889,6 +3890,49 @@ 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(ItemID getItemId) {
|
||||
s32 temp1;
|
||||
|
||||
if (((getItemId >= GI_RUPEE_GREEN) && (getItemId <= GI_RUPEE_RED)) ||
|
||||
((getItemId >= GI_RUPEE_PURPLE) && (getItemId <= GI_RUPEE_GOLD)) ||
|
||||
((getItemId >= GI_RUPEE_GREEN_LOSE) && (getItemId <= GI_RUPEE_PURPLE_LOSE)) || (getItemId == GI_HEART)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else {
|
||||
if ((getItemId == GI_HEART_CONTAINER_2) || (getItemId == GI_HEART_CONTAINER) ||
|
||||
((getItemId == GI_HEART_PIECE) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) {
|
||||
temp1 = NA_BGM_HEART_GET | 0x900;
|
||||
} else {
|
||||
temp1 = (getItemId == GI_HEART_PIECE) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900;
|
||||
}
|
||||
// If we get a skulltula token or the "WINNER" heart, play "get small item"
|
||||
if (getItemId == GI_SKULL_TOKEN || getItemId == GI_HEART_PIECE_WIN) {
|
||||
temp1 = NA_BGM_SMALL_ITEM_GET | 0x900;
|
||||
}
|
||||
// But if the "WINNER" heart is the 4th heart piece collected, play "get heart container"
|
||||
if (getItemId == GI_HEART_PIECE_WIN && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000)) {
|
||||
temp1 = NA_BGM_HEART_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 ((getItemId >= RG_FOREST_MEDALLION) && (getItemId <= RG_LIGHT_MEDALLION)) {
|
||||
temp1 = NA_BGM_MEDALLION_GET | 0x900;
|
||||
}
|
||||
// If it's a Spiritual Stone, play the "get a spiritual stone" fanfare
|
||||
if ((getItemId >= RG_KOKIRI_EMERALD) && (getItemId <= RG_ZORA_SAPPHIRE)) {
|
||||
temp1 = NA_BGM_SPIRITUAL_STONE | 0x900;
|
||||
}
|
||||
// If the item we're getting is a song, play the "learned a song" fanfare
|
||||
if ((getItemId >= RG_ZELDAS_LULLABY) && (getItemId <= RG_PRELUDE_OF_LIGHT)) {
|
||||
temp1 = NA_BGM_OCA_FAIRY_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);
|
||||
|
@ -1966,6 +1966,10 @@ s32 GiveItemWithoutActor(GlobalContext* globalCtx, s32 getItemId) {
|
||||
player->getItemId = getItemId;
|
||||
player->interactRangeActor = &player->actor;
|
||||
player->getItemDirection = player->actor.shape.rot.y;
|
||||
// Player state 26 = Player is frozen
|
||||
if (player->stateFlags1 & (PLAYER_STATE1_26)) {
|
||||
player->pendingIceTrap = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
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);
|
||||
// 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 &&
|
||||
|
@ -2101,7 +2101,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);
|
||||
}
|
||||
|
@ -1663,6 +1663,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) {
|
||||
|
@ -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>
|
||||
@ -1686,29 +1687,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
|
||||
}
|
||||
return ITEM_NONE;
|
||||
} else if (item == ITEM_KEY_SMALL) {
|
||||
// Small key exceptions for rando.
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
if (globalCtx->sceneNum == 10) { // ganon's tower -> ganon's castle
|
||||
if (gSaveContext.inventory.dungeonKeys[13] < 0) {
|
||||
gSaveContext.inventory.dungeonKeys[13] = 1;
|
||||
return ITEM_NONE;
|
||||
} else {
|
||||
gSaveContext.inventory.dungeonKeys[13]++;
|
||||
return ITEM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (globalCtx->sceneNum == 92) { // Desert Colossus -> Spirit Temple.
|
||||
if (gSaveContext.inventory.dungeonKeys[6] < 0) {
|
||||
gSaveContext.inventory.dungeonKeys[6] = 1;
|
||||
return ITEM_NONE;
|
||||
} else {
|
||||
gSaveContext.inventory.dungeonKeys[6]++;
|
||||
return ITEM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) {
|
||||
gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1;
|
||||
return ITEM_NONE;
|
||||
@ -2100,6 +2078,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;
|
||||
|
||||
@ -2241,6 +2223,98 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
|
||||
return ITEM_NONE;
|
||||
}
|
||||
}
|
||||
} else if ((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)) {
|
||||
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_GERUDO_FORTRESS_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;
|
||||
}
|
||||
}
|
||||
|
||||
temp = gSaveContext.inventory.items[slot];
|
||||
@ -2303,6 +2377,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) {
|
||||
@ -2504,6 +2585,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;
|
||||
|
||||
|
@ -400,7 +400,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;
|
||||
|
@ -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;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#define NUM_DUNGEONS 8
|
||||
#define NUM_TRIALS 6
|
||||
#define NUM_COWS 10
|
||||
|
||||
/**
|
||||
* Initialize new save.
|
||||
@ -416,6 +417,95 @@ void GiveLinkDungeonReward(uint16_t getItemId) {
|
||||
}
|
||||
}
|
||||
|
||||
void GiveLinkDungeonItem(GetItemID getItemId) {
|
||||
int mapIndex;
|
||||
|
||||
switch (getItemId) {
|
||||
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 ((getItemId >= RG_GERUDO_FORTRESS_SMALL_KEY) && (getItemId <= RG_GANONS_CASTLE_SMALL_KEY)) {
|
||||
if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) {
|
||||
gSaveContext.inventory.dungeonKeys[mapIndex] = 1;
|
||||
} else {
|
||||
gSaveContext.inventory.dungeonKeys[mapIndex]++;
|
||||
}
|
||||
} else {
|
||||
int bitmask;
|
||||
if ((getItemId >= RG_DEKU_TREE_MAP) && (getItemId <= RG_ICE_CAVERN_MAP)) {
|
||||
bitmask = gBitFlags[2];
|
||||
} else if ((getItemId >= RG_DEKU_TREE_COMPASS) && (getItemId <= RG_ICE_CAVERN_COMPASS)) {
|
||||
bitmask = gBitFlags[1];
|
||||
} else {
|
||||
bitmask = gBitFlags[0];
|
||||
}
|
||||
|
||||
gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask;
|
||||
}
|
||||
}
|
||||
|
||||
void GiveLinksPocketMedallion() {
|
||||
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
|
||||
|
||||
@ -563,13 +653,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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -620,14 +712,20 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
gSaveContext.trialsDone[i] = 0;
|
||||
}
|
||||
|
||||
// Sets all cows to unmilked when generating a rando save.
|
||||
for (u8 i = 0; i < NUM_COWS; i++) {
|
||||
gSaveContext.cowsMilked[i] = 0;
|
||||
}
|
||||
|
||||
// Set Cutscene flags to skip them
|
||||
gSaveContext.eventChkInf[0xC] |= 0x10; // returned to tot with medallions
|
||||
gSaveContext.eventChkInf[0xC] |= 0x20; //sheik at tot pedestal
|
||||
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);
|
||||
|
||||
@ -682,11 +780,12 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -762,6 +861,13 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
GiveLinkMagic(giid);
|
||||
} else if (giid == RG_DOUBLE_DEFENSE) {
|
||||
GiveLinkDoubleDefense();
|
||||
} else if (
|
||||
(giid >= RG_GERUDO_FORTRESS_SMALL_KEY && giid <= RG_GANONS_CASTLE_SMALL_KEY) ||
|
||||
(giid >= RG_FOREST_TEMPLE_BOSS_KEY && giid <= RG_GANONS_CASTLE_BOSS_KEY) ||
|
||||
(giid >= RG_DEKU_TREE_MAP && giid <= RG_ICE_CAVERN_MAP) ||
|
||||
(giid >= RG_DEKU_TREE_COMPASS && giid <= RG_ICE_CAVERN_COMPASS)
|
||||
) {
|
||||
GiveLinkDungeonItem(giid);
|
||||
} else {
|
||||
s32 iid = Randomizer_GetItemIDFromGetItemID(giid);
|
||||
if (iid != -1) INV_CONTENT(iid) = iid;
|
||||
@ -788,9 +894,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] = 2; // 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));
|
||||
@ -852,6 +980,21 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
GiveLinkGerudoCard();
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle adult trade quest
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
}
|
||||
|
||||
// complete mask quest
|
||||
if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) {
|
||||
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();
|
||||
|
@ -18,6 +18,8 @@ void func_809E0070(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_809DF494(EnCow* this, GlobalContext* globalCtx);
|
||||
void func_809DF6BC(EnCow* this, GlobalContext* globalCtx);
|
||||
CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx);
|
||||
void EnCow_MoveForRandomizer(EnCow* this, GlobalContext* globalCtx);
|
||||
void func_809DF778(EnCow* this, GlobalContext* globalCtx);
|
||||
void func_809DF7D8(EnCow* this, GlobalContext* globalCtx);
|
||||
void func_809DF870(EnCow* this, GlobalContext* globalCtx);
|
||||
@ -106,6 +108,10 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnCow* this = (EnCow*)thisx;
|
||||
s32 pad;
|
||||
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) {
|
||||
EnCow_MoveForRandomizer(thisx, globalCtx);
|
||||
}
|
||||
|
||||
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f);
|
||||
switch (this->actor.params) {
|
||||
case 0:
|
||||
@ -209,6 +215,85 @@ void func_809DF730(EnCow* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx) {
|
||||
struct CowInfo cowInfo;
|
||||
|
||||
cowInfo.cowId = -1;
|
||||
cowInfo.randomizerCheck = RC_UNKNOWN_CHECK;
|
||||
|
||||
switch (globalCtx->sceneNum) {
|
||||
case SCENE_SOUKO: // Lon Lon Tower
|
||||
if (this->actor.world.pos.x == -229 && this->actor.world.pos.z == 157) {
|
||||
cowInfo.cowId = 0;
|
||||
cowInfo.randomizerCheck = RC_LLR_TOWER_LEFT_COW;
|
||||
} else if (this->actor.world.pos.x == -142 && this->actor.world.pos.z == -140) {
|
||||
cowInfo.cowId = 1;
|
||||
cowInfo.randomizerCheck = RC_LLR_TOWER_RIGHT_COW;
|
||||
}
|
||||
break;
|
||||
case SCENE_MALON_STABLE:
|
||||
if (this->actor.world.pos.x == 116 && this->actor.world.pos.z == -254) {
|
||||
cowInfo.cowId = 2;
|
||||
cowInfo.randomizerCheck = RC_LLR_STABLES_RIGHT_COW;
|
||||
} else if (this->actor.world.pos.x == -122 && this->actor.world.pos.z == -254) {
|
||||
cowInfo.cowId = 3;
|
||||
cowInfo.randomizerCheck = RC_LLR_STABLES_LEFT_COW;
|
||||
}
|
||||
break;
|
||||
case SCENE_KAKUSIANA: // Grotto
|
||||
if (this->actor.world.pos.x == 2444 && this->actor.world.pos.z == -471) {
|
||||
cowInfo.cowId = 4;
|
||||
cowInfo.randomizerCheck = RC_DMT_COW_GROTTO_COW;
|
||||
} else if (this->actor.world.pos.x == 3485 && this->actor.world.pos.z == -291) {
|
||||
cowInfo.cowId = 5;
|
||||
cowInfo.randomizerCheck = RC_HF_COW_GROTTO_COW;
|
||||
}
|
||||
break;
|
||||
case SCENE_LINK_HOME:
|
||||
cowInfo.cowId = 6;
|
||||
cowInfo.randomizerCheck = RC_KF_LINKS_HOUSE_COW;
|
||||
break;
|
||||
case SCENE_LABO: // Impa's house
|
||||
cowInfo.cowId = 7;
|
||||
cowInfo.randomizerCheck = RC_KAK_IMPAS_HOUSE_COW;
|
||||
break;
|
||||
case SCENE_SPOT09: // Gerudo Valley
|
||||
cowInfo.cowId = 8;
|
||||
cowInfo.randomizerCheck = RC_GV_COW;
|
||||
break;
|
||||
case SCENE_SPOT08: // Jabu's Belly
|
||||
cowInfo.cowId = 9;
|
||||
cowInfo.randomizerCheck = RC_JABU_JABUS_BELLY_MQ_COW;
|
||||
break;
|
||||
}
|
||||
|
||||
return cowInfo;
|
||||
}
|
||||
|
||||
void EnCow_MoveForRandomizer(EnCow* this, GlobalContext* globalCtx) {
|
||||
// Only move the cow body (the tail will be moved with the body)
|
||||
if (this->actor.params != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move left cow in lon lon tower
|
||||
if (globalCtx->sceneNum == SCENE_SOUKO && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) {
|
||||
this->actor.world.pos.x = -229.0f;
|
||||
this->actor.world.pos.z = 157.0f;
|
||||
this->actor.shape.rot.y = 15783.0f;
|
||||
// Move right cow in lon lon stable
|
||||
} else if (globalCtx->sceneNum == SCENE_MALON_STABLE && this->actor.world.pos.x == -3 && this->actor.world.pos.z == -254) {
|
||||
this->actor.world.pos.x += 119.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void EnCow_SetCowMilked(EnCow* this, GlobalContext* globalCtx) {
|
||||
CowInfo cowInfo = EnCow_GetInfo(this, globalCtx);
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
player->pendingFlag.flagID = cowInfo.cowId;
|
||||
player->pendingFlag.flagType = FLAG_COW_MILKED;
|
||||
}
|
||||
|
||||
void func_809DF778(EnCow* this, GlobalContext* globalCtx) {
|
||||
if (Actor_HasParent(&this->actor, globalCtx)) {
|
||||
this->actor.parent = NULL;
|
||||
@ -250,6 +335,23 @@ void func_809DF8FC(EnCow* this, GlobalContext* globalCtx) {
|
||||
func_809DF494(this, globalCtx);
|
||||
}
|
||||
|
||||
bool EnCow_HasBeenMilked(EnCow* this, GlobalContext* globalCtx) {
|
||||
CowInfo cowInfo = EnCow_GetInfo(this, globalCtx);
|
||||
return gSaveContext.cowsMilked[cowInfo.cowId];
|
||||
}
|
||||
|
||||
void EnCow_GivePlayerRandomizedItem(EnCow* this, GlobalContext* globalCtx) {
|
||||
if (!EnCow_HasBeenMilked(this, globalCtx)) {
|
||||
CowInfo cowInfo = EnCow_GetInfo(this, globalCtx);
|
||||
GetItemID itemId = Randomizer_GetItemIdFromKnownCheck(cowInfo.randomizerCheck, GI_MILK);
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f);
|
||||
} else {
|
||||
// once we've gotten the rando reward from the cow,
|
||||
// return them to the their default action function
|
||||
this->actionFunc = func_809DF96C;
|
||||
}
|
||||
}
|
||||
|
||||
void func_809DF96C(EnCow* this, GlobalContext* globalCtx) {
|
||||
if ((globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_00) || (globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_04)) {
|
||||
if (DREG(53) != 0) {
|
||||
@ -260,6 +362,19 @@ void func_809DF96C(EnCow* this, GlobalContext* globalCtx) {
|
||||
if ((this->actor.xzDistToPlayer < 150.0f) &&
|
||||
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) {
|
||||
DREG(53) = 0;
|
||||
// when randomized with cowsanity, if we haven't gotten the
|
||||
// reward from this cow yet, give that, otherwise use the
|
||||
// vanilla cow behavior
|
||||
if (gSaveContext.n64ddFlag &&
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_COWS) &&
|
||||
!EnCow_HasBeenMilked(this, globalCtx)) {
|
||||
EnCow_SetCowMilked(this, globalCtx);
|
||||
// setting the ocarina mode here prevents intermittent issues
|
||||
// with the item get not triggering until walking away
|
||||
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_00;
|
||||
this->actionFunc = EnCow_GivePlayerRandomizedItem;
|
||||
return;
|
||||
}
|
||||
this->actionFunc = func_809DF8FC;
|
||||
this->actor.flags |= ACTOR_FLAG_16;
|
||||
func_8002F2CC(&this->actor, globalCtx, 170.0f);
|
||||
|
@ -21,4 +21,9 @@ typedef struct EnCow {
|
||||
/* 0x027C */ EnCowActionFunc actionFunc;
|
||||
} EnCow; // size = 0x0280
|
||||
|
||||
typedef struct CowInfo {
|
||||
int cowId;
|
||||
RandomizerCheck randomizerCheck;
|
||||
} CowInfo;
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_en_ds.h"
|
||||
#include "objects/object_ds/object_ds.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
|
||||
@ -91,7 +92,12 @@ void EnDs_GiveOddPotion(EnDs* this, GlobalContext* globalCtx) {
|
||||
this->actionFunc = EnDs_DisplayOddPotionText;
|
||||
gSaveContext.timer2State = 0;
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_ODD_POTION, 10000.0f, 50.0f);
|
||||
u32 itemId = GI_ODD_POTION;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_MUSHROOM);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +105,12 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, GlobalContext* globalCtx) {
|
||||
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) {
|
||||
Message_CloseTextbox(globalCtx);
|
||||
this->actionFunc = EnDs_GiveOddPotion;
|
||||
func_8002F434(&this->actor, globalCtx, GI_ODD_POTION, 10000.0f, 50.0f);
|
||||
u32 itemId = GI_ODD_POTION;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_MUSHROOM);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +131,7 @@ void EnDs_BrewOddPotion2(EnDs* this, GlobalContext* globalCtx) {
|
||||
this->brewTimer -= 1;
|
||||
} else {
|
||||
this->actionFunc = EnDs_BrewOddPotion3;
|
||||
this->brewTimer = 60;
|
||||
this->brewTimer = gSaveContext.n64ddFlag ? 0 : 60;
|
||||
Flags_UnsetSwitch(globalCtx, 0x3F);
|
||||
}
|
||||
}
|
||||
@ -130,7 +141,7 @@ void EnDs_BrewOddPotion1(EnDs* this, GlobalContext* globalCtx) {
|
||||
this->brewTimer -= 1;
|
||||
} else {
|
||||
this->actionFunc = EnDs_BrewOddPotion2;
|
||||
this->brewTimer = 20;
|
||||
this->brewTimer = gSaveContext.n64ddFlag ? 0 : 20;
|
||||
}
|
||||
|
||||
Math_StepToF(&this->unk_1E4, 1.0f, 0.01f);
|
||||
@ -144,7 +155,7 @@ void EnDs_OfferOddPotion(EnDs* this, GlobalContext* globalCtx) {
|
||||
switch (globalCtx->msgCtx.choiceIndex) {
|
||||
case 0: // yes
|
||||
this->actionFunc = EnDs_BrewOddPotion1;
|
||||
this->brewTimer = 60;
|
||||
this->brewTimer = gSaveContext.n64ddFlag ? 0 : 60;
|
||||
Flags_SetSwitch(globalCtx, 0x3F);
|
||||
globalCtx->msgCtx.msgMode = MSGMODE_PAUSED;
|
||||
player->exchangeItemId = EXCH_ITEM_NONE;
|
||||
|
@ -43,6 +43,7 @@ void EnFr_OcarinaMistake(EnFr* this, GlobalContext* globalCtx);
|
||||
void EnFr_SetupReward(EnFr* this, GlobalContext* globalCtx, u8 unkCondition);
|
||||
void EnFr_PrintTextBox(EnFr* this, GlobalContext* globalCtx);
|
||||
void EnFr_TalkBeforeReward(EnFr* this, GlobalContext* globalCtx);
|
||||
RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex);
|
||||
void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx);
|
||||
|
||||
// Deactivate
|
||||
@ -920,6 +921,23 @@ void EnFr_TalkBeforeReward(EnFr* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) {
|
||||
switch (songIndex) {
|
||||
case FROG_ZL:
|
||||
return RC_ZR_FROGS_ZELDAS_LULLABY;
|
||||
case FROG_EPONA:
|
||||
return RC_ZR_FROGS_EPONAS_SONG;
|
||||
case FROG_SARIA:
|
||||
return RC_ZR_FROGS_SARIAS_SONG;
|
||||
case FROG_SUNS:
|
||||
return RC_ZR_FROGS_SUNS_SONG;
|
||||
case FROG_SOT:
|
||||
return RC_ZR_FROGS_SONG_OF_TIME;
|
||||
default:
|
||||
return RC_UNKNOWN_CHECK;
|
||||
}
|
||||
}
|
||||
|
||||
void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) {
|
||||
u16 songIndex;
|
||||
|
||||
@ -930,7 +948,11 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) {
|
||||
if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) {
|
||||
if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) {
|
||||
gSaveContext.eventChkInf[13] |= sSongIndex[songIndex];
|
||||
this->reward = GI_RUPEE_PURPLE;
|
||||
if (!gSaveContext.n64ddFlag) {
|
||||
this->reward = GI_RUPEE_PURPLE;
|
||||
} else {
|
||||
this->reward = Randomizer_GetItemIdFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE);
|
||||
}
|
||||
} else {
|
||||
this->reward = GI_RUPEE_BLUE;
|
||||
}
|
||||
@ -1016,7 +1038,7 @@ void EnFr_GiveReward(EnFr* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnFr_SetIdle(EnFr* this, GlobalContext* globalCtx) {
|
||||
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) {
|
||||
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx) || (gSaveContext.n64ddFlag && this->reward == GI_ICE_TRAP)) {
|
||||
this->actionFunc = EnFr_Idle;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "objects/object_oF1d_map/object_oF1d_map.h"
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
||||
|
||||
@ -961,9 +962,17 @@ void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) {
|
||||
getItemId = GI_CLAIM_CHECK;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_EYEDROPS);
|
||||
}
|
||||
}
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) {
|
||||
getItemId = GI_PRESCRIPTION;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SWORD_BROKEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "objects/object_oF1d_map/object_oF1d_map.h"
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
||||
|
||||
@ -652,7 +653,12 @@ s16 EnGo2_GetStateGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) {
|
||||
if (Message_ShouldAdvance(globalCtx)) {
|
||||
if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) {
|
||||
if (globalCtx->msgCtx.choiceIndex == 0) {
|
||||
EnGo2_GetItem(this, globalCtx, GI_PRESCRIPTION);
|
||||
u32 getItemId = GI_PRESCRIPTION;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SWORD_BROKEN);
|
||||
}
|
||||
EnGo2_GetItem(this, globalCtx, getItemId);
|
||||
this->actionFunc = EnGo2_SetupGetItem;
|
||||
return 2;
|
||||
}
|
||||
@ -1847,12 +1853,14 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, GlobalContext* globalCtx) {
|
||||
this->actor.flags &= ~ACTOR_FLAG_0;
|
||||
this->actor.shape.rot.y += 0x5B0;
|
||||
this->unk_26E = 1;
|
||||
this->animTimer = this->skelAnime.endFrame + 60.0f + 60.0f; // eyeDrops animation timer
|
||||
this->animTimer = gSaveContext.n64ddFlag ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer
|
||||
this->eyeMouthTexState = 2;
|
||||
this->unk_20C = 0;
|
||||
this->goronState++;
|
||||
func_800F483C(0x28, 5);
|
||||
OnePointCutscene_Init(globalCtx, 4190, -99, &this->actor, MAIN_CAM);
|
||||
if (!gSaveContext.n64ddFlag) {
|
||||
OnePointCutscene_Init(globalCtx, 4190, -99, &this->actor, MAIN_CAM);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (DECR(this->animTimer)) {
|
||||
@ -1879,7 +1887,12 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, GlobalContext* globalCtx) {
|
||||
this->unk_26E = 2;
|
||||
this->skelAnime.playSpeed = 0.0f;
|
||||
this->skelAnime.curFrame = this->skelAnime.endFrame;
|
||||
EnGo2_GetItem(this, globalCtx, GI_CLAIM_CHECK);
|
||||
u32 getItemId = GI_CLAIM_CHECK;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_EYEDROPS);
|
||||
}
|
||||
EnGo2_GetItem(this, globalCtx, getItemId);
|
||||
this->actionFunc = EnGo2_SetupGetItem;
|
||||
this->goronState = 0;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "z_en_hs.h"
|
||||
#include "vt.h"
|
||||
#include "objects/object_hs/object_hs.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
|
||||
@ -78,7 +79,25 @@ void EnHs_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
// "chicken shop (adult era)"
|
||||
osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコの店(大人の時) \n" VT_RST);
|
||||
func_80A6E3A0(this, func_80A6E9AC);
|
||||
if (gSaveContext.itemGetInf[3] & 1) {
|
||||
bool shouldSpawn;
|
||||
bool tradedMushroom = gSaveContext.itemGetInf[3] & 1;
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
// To explain the logic because Fado and Grog are linked:
|
||||
// - If you have Cojiro, then spawn Grog and not Fado.
|
||||
// - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog.
|
||||
// - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom.
|
||||
// - If you don't have either but have traded the mushroom, don't spawn either.
|
||||
if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) {
|
||||
shouldSpawn = true;
|
||||
} else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) {
|
||||
shouldSpawn = false;
|
||||
} else {
|
||||
shouldSpawn = !tradedMushroom;
|
||||
}
|
||||
} else {
|
||||
shouldSpawn = !tradedMushroom;
|
||||
}
|
||||
if (!shouldSpawn) {
|
||||
// "chicken shop closed"
|
||||
osSyncPrintf(VT_FGCOL(CYAN) " ヒヨコ屋閉店 \n" VT_RST);
|
||||
Actor_Kill(&this->actor);
|
||||
@ -127,7 +146,9 @@ void func_80A6E5EC(EnHs* this, GlobalContext* globalCtx) {
|
||||
|
||||
void func_80A6E630(EnHs* this, GlobalContext* globalCtx) {
|
||||
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) {
|
||||
func_80088AA0(180);
|
||||
if (!gSaveContext.n64ddFlag) {
|
||||
func_80088AA0(180);
|
||||
}
|
||||
func_80A6E3A0(this, func_80A6E6B0);
|
||||
gSaveContext.eventInf[1] &= ~1;
|
||||
}
|
||||
@ -156,7 +177,12 @@ void func_80A6E740(EnHs* this, GlobalContext* globalCtx) {
|
||||
this->actor.parent = NULL;
|
||||
func_80A6E3A0(this, func_80A6E630);
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_ODD_MUSHROOM, 10000.0f, 50.0f);
|
||||
s32 itemId = GI_ODD_MUSHROOM;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_COJIRO);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f);
|
||||
}
|
||||
|
||||
this->unk_2A8 |= 1;
|
||||
@ -167,7 +193,12 @@ void func_80A6E7BC(EnHs* this, GlobalContext* globalCtx) {
|
||||
switch (globalCtx->msgCtx.choiceIndex) {
|
||||
case 0:
|
||||
func_80A6E3A0(this, func_80A6E740);
|
||||
func_8002F434(&this->actor, globalCtx, GI_ODD_MUSHROOM, 10000.0f, 50.0f);
|
||||
s32 itemId = GI_ODD_MUSHROOM;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_COJIRO);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f);
|
||||
break;
|
||||
case 1:
|
||||
Message_ContinueTextbox(globalCtx, 0x10B4);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "objects/object_km1/object_km1.h"
|
||||
#include "objects/object_kw1/object_kw1.h"
|
||||
#include "vt.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4)
|
||||
|
||||
@ -1025,7 +1026,20 @@ s32 EnKo_CanSpawn(EnKo* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
case SCENE_SPOT10:
|
||||
return (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false;
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
// To explain the logic because Fado and Grog are linked:
|
||||
// - If you have Cojiro, then spawn Grog and not Fado.
|
||||
// - If you don't have Cojiro but do have Odd Potion, spawn Fado and not Grog.
|
||||
// - If you don't have either, spawn Grog if you haven't traded the Odd Mushroom.
|
||||
// - If you don't have either but have traded the mushroom, don't spawn either.
|
||||
if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) {
|
||||
return false;
|
||||
} else {
|
||||
return PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION);
|
||||
}
|
||||
} else {
|
||||
return (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -1216,7 +1230,12 @@ void func_80A99504(EnKo* this, GlobalContext* globalCtx) {
|
||||
this->actor.parent = NULL;
|
||||
this->actionFunc = func_80A99560;
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_SAW, 120.0f, 10.0f);
|
||||
s32 itemId = GI_SAW;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_ODD_POTION, GI_SAW);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_POTION);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 120.0f, 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_en_kz.h"
|
||||
#include "objects/object_kz/object_kz.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
|
||||
@ -465,6 +466,7 @@ void EnKz_SetupGetItem(EnKz* this, GlobalContext* globalCtx) {
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
if (this->isTrading) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_PRESCRIPTION);
|
||||
Flags_SetTreasure(globalCtx, 0x1F);
|
||||
} else {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA);
|
||||
@ -480,7 +482,7 @@ void EnKz_SetupGetItem(EnKz* this, GlobalContext* globalCtx) {
|
||||
|
||||
void EnKz_StartTimer(EnKz* this, GlobalContext* globalCtx) {
|
||||
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) {
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG) {
|
||||
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && !gSaveContext.n64ddFlag) {
|
||||
func_80088AA0(180); // start timer2 with 3 minutes
|
||||
gSaveContext.eventInf[1] &= ~1;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_en_mk.h"
|
||||
#include "objects/object_mk/object_mk.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4)
|
||||
|
||||
@ -93,17 +94,29 @@ void func_80AACA94(EnMk* this, GlobalContext* globalCtx) {
|
||||
if (Actor_HasParent(&this->actor, globalCtx) != 0) {
|
||||
this->actor.parent = NULL;
|
||||
this->actionFunc = func_80AACA40;
|
||||
func_80088AA0(240);
|
||||
gSaveContext.eventInf[1] &= ~1;
|
||||
if (!gSaveContext.n64ddFlag) {
|
||||
func_80088AA0(240);
|
||||
gSaveContext.eventInf[1] &= ~1;
|
||||
}
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_EYEDROPS, 10000.0f, 50.0f);
|
||||
s32 getItemID = GI_EYEDROPS;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemID = Randomizer_GetItemIdFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_FROG);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AACB14(EnMk* this, GlobalContext* globalCtx) {
|
||||
if (Actor_TextboxIsClosing(&this->actor, globalCtx)) {
|
||||
this->actionFunc = func_80AACA94;
|
||||
func_8002F434(&this->actor, globalCtx, GI_EYEDROPS, 10000.0f, 50.0f);
|
||||
s32 getItemID = GI_EYEDROPS;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemID = Randomizer_GetItemIdFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_FROG);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +142,7 @@ void func_80AACC04(EnMk* this, GlobalContext* globalCtx) {
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
} else {
|
||||
this->timer = 16;
|
||||
this->timer = gSaveContext.n64ddFlag ? 0 : 16;
|
||||
this->actionFunc = func_80AACBAC;
|
||||
Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f);
|
||||
@ -142,7 +155,7 @@ void func_80AACCA0(EnMk* this, GlobalContext* globalCtx) {
|
||||
this->timer--;
|
||||
this->actor.shape.rot.y += 0x800;
|
||||
} else {
|
||||
this->timer = 120;
|
||||
this->timer = gSaveContext.n64ddFlag ? 0 : 120;
|
||||
this->actionFunc = func_80AACC04;
|
||||
Animation_Change(&this->skelAnime, &object_mk_Anim_000724, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&object_mk_Anim_000724), ANIMMODE_LOOP, -4.0f);
|
||||
@ -158,7 +171,7 @@ void func_80AACD48(EnMk* this, GlobalContext* globalCtx) {
|
||||
this->actionFunc = func_80AACCA0;
|
||||
globalCtx->msgCtx.msgMode = MSGMODE_PAUSED;
|
||||
player->exchangeItemId = EXCH_ITEM_NONE;
|
||||
this->timer = 16;
|
||||
this->timer = gSaveContext.n64ddFlag ? 0 : 16;
|
||||
Animation_Change(&this->skelAnime, &object_mk_Anim_000D88, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&object_mk_Anim_000D88), ANIMMODE_LOOP, -4.0f);
|
||||
this->flags &= ~2;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "objects/object_os_anime/object_os_anime.h"
|
||||
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
|
||||
#include "vt.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4)
|
||||
|
||||
@ -454,8 +455,13 @@ void func_80ABAC00(EnNiwLady* this, GlobalContext* globalCtx) {
|
||||
if (LINK_IS_ADULT) {
|
||||
getItemId = !(gSaveContext.itemGetInf[2] & 0x1000) ? GI_POCKET_EGG : GI_COJIRO;
|
||||
|
||||
if (gSaveContext.n64ddFlag && getItemId == GI_POCKET_EGG) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG);
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
if (getItemId == GI_POCKET_EGG) {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG);
|
||||
} else {
|
||||
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_POCKET_CUCCO, GI_COJIRO);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_POCKET_CUCCO);
|
||||
}
|
||||
}
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, getItemId, 200.0f, 100.0f);
|
||||
|
@ -183,7 +183,7 @@ void EnPoSisters_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->epoch++;
|
||||
|
||||
// Skip Poe Intro Cutscene
|
||||
if (gSaveContext.n64ddFlag && thisx->params == 4124) {
|
||||
if (gSaveContext.n64ddFlag && thisx->params == 4124 && !Randomizer_GetSettingValue(RSK_ENABLE_GLITCH_CUTSCENES)) {
|
||||
Flags_SetSwitch(globalCtx, 0x1B);
|
||||
Actor_Kill(thisx);
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx);
|
||||
void func_80AFB89C(EnSi* this, GlobalContext* globalCtx);
|
||||
void func_80AFB950(EnSi* this, GlobalContext* globalCtx);
|
||||
|
||||
s32 textId = 0xB4;
|
||||
s32 giveItemId = ITEM_SKULL_TOKEN;
|
||||
s32 getItemId;
|
||||
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
@ -93,12 +97,36 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) {
|
||||
|
||||
if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) {
|
||||
this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER;
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
if (CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
GetItemEntry getItem = Randomizer_GetRandomizedItem(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum);
|
||||
getItemId = getItem.getItemId;
|
||||
if (getItem.getItemId == RG_ICE_TRAP) {
|
||||
player->pendingIceTrap = true;
|
||||
textId = 0xF8;
|
||||
} else {
|
||||
textId = getItem.textId;
|
||||
giveItemId = getItem.itemId;
|
||||
if (getItem.modIndex == MOD_NONE) {
|
||||
Item_Give(globalCtx, giveItemId);
|
||||
} else if (getItem.modIndex == MOD_RANDOMIZER) {
|
||||
Randomizer_Item_Give(globalCtx, getItem);
|
||||
}
|
||||
}
|
||||
player->getItemEntry = getItem;
|
||||
player->getItemId = getItemId;
|
||||
} else {
|
||||
Item_Give(globalCtx, giveItemId);
|
||||
}
|
||||
if ((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != RG_ICE_TRAP) {
|
||||
player->actor.freezeTimer = 20;
|
||||
}
|
||||
Message_StartTextbox(globalCtx, 0xB4, NULL);
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
Message_StartTextbox(globalCtx, textId, NULL);
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Audio_PlayFanfare_Rando(getItemId);
|
||||
} else {
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
}
|
||||
this->actionFunc = func_80AFB950;
|
||||
} else {
|
||||
Collider_UpdateCylinder(&this->actor, &this->collider);
|
||||
@ -117,9 +145,32 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
|
||||
this->actor.shape.rot.y += 0x400;
|
||||
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_13)) {
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
Message_StartTextbox(globalCtx, 0xB4, NULL);
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
GetItemEntry getItem = Randomizer_GetRandomizedItem(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum);
|
||||
getItemId = getItem.getItemId;
|
||||
if (getItemId == RG_ICE_TRAP) {
|
||||
player->pendingIceTrap = true;
|
||||
textId = 0xF8;
|
||||
} else {
|
||||
textId = getItem.textId;
|
||||
giveItemId = getItem.itemId;
|
||||
if (getItem.modIndex == MOD_NONE) {
|
||||
Item_Give(globalCtx, giveItemId);
|
||||
} else if (getItem.modIndex == MOD_RANDOMIZER) {
|
||||
Randomizer_Item_Give(globalCtx, getItem);
|
||||
}
|
||||
}
|
||||
player->getItemId = getItemId;
|
||||
player->getItemEntry = getItem;
|
||||
} else {
|
||||
Item_Give(globalCtx, giveItemId);
|
||||
}
|
||||
Message_StartTextbox(globalCtx, textId, NULL);
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
Audio_PlayFanfare_Rando(getItemId);
|
||||
} else {
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
}
|
||||
this->actionFunc = func_80AFB950;
|
||||
}
|
||||
}
|
||||
@ -127,7 +178,8 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
|
||||
void func_80AFB950(EnSi* this, GlobalContext* globalCtx) {
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
|
||||
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING && CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
|
||||
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING &&
|
||||
((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != GI_ICE_TRAP)) {
|
||||
player->actor.freezeTimer = 10;
|
||||
} else {
|
||||
SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF);
|
||||
@ -150,6 +202,17 @@ void EnSi_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
if (this->actionFunc != func_80AFB950) {
|
||||
func_8002ED80(&this->actor, globalCtx, 0);
|
||||
func_8002EBCC(&this->actor, globalCtx, 0);
|
||||
GetItem_Draw(globalCtx, GID_SKULL_TOKEN_2);
|
||||
if (!gSaveContext.n64ddFlag) {
|
||||
GetItem_Draw(globalCtx, GID_SKULL_TOKEN_2);
|
||||
} else {
|
||||
GetItemEntry getItem = Randomizer_GetRandomizedItem(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum);
|
||||
EnItem00_CustomItemsParticles(&this->actor, globalCtx, getItem);
|
||||
if (getItem.itemId != ITEM_SKULL_TOKEN) {
|
||||
f32 mtxScale = 1.5f;
|
||||
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
||||
}
|
||||
GetItem_Draw(globalCtx, getItem.gid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -613,9 +613,9 @@ void func_80B0D878(EnSw* this, GlobalContext* globalCtx) {
|
||||
x = (this->unk_364.x * 10.0f);
|
||||
y = (this->unk_364.y * 10.0f);
|
||||
z = (this->unk_364.z * 10.0f);
|
||||
temp_v0 =
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_SI, this->actor.world.pos.x + x,
|
||||
this->actor.world.pos.y + y, this->actor.world.pos.z + z, 0, 0, 0, this->actor.params);
|
||||
temp_v0 = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_SI,
|
||||
this->actor.world.pos.x + x, this->actor.world.pos.y + y,
|
||||
this->actor.world.pos.z + z, 0, 0, 0, this->actor.params);
|
||||
if (temp_v0 != NULL) {
|
||||
temp_v0->parent = NULL;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_en_toryo.h"
|
||||
#include "objects/object_toryo/object_toryo.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
|
||||
@ -313,7 +314,12 @@ void func_80B20768(EnToryo* this, GlobalContext* globalCtx) {
|
||||
this->actor.parent = NULL;
|
||||
this->unk_1E4 = 5;
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_SWORD_BROKEN, 100.0f, 10.0f);
|
||||
s32 itemId = GI_SWORD_BROKEN;
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
itemId = Randomizer_GetItemIdFromKnownCheck(RC_GV_TRADE_SAW, GI_SWORD_BROKEN);
|
||||
Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SAW);
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, itemId, 100.0f, 10.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -6083,8 +6083,8 @@ void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx) {
|
||||
case FLAG_SCENE_TREASURE:
|
||||
Flags_SetTreasure(globalCtx, this->pendingFlag.flagID);
|
||||
break;
|
||||
case FLAG_EVENT_CHECK_INF:
|
||||
Flags_SetEventChkInf(this->pendingFlag.flagID);
|
||||
case FLAG_COW_MILKED:
|
||||
gSaveContext.cowsMilked[this->pendingFlag.flagID] = 1;
|
||||
break;
|
||||
case FLAG_NONE:
|
||||
default:
|
||||
@ -10889,6 +10889,10 @@ void Player_UpdateCommon(Player* this, GlobalContext* globalCtx, Input* input) {
|
||||
|
||||
Collider_ResetQuadAC(globalCtx, &this->shieldQuad.base);
|
||||
Collider_ResetQuadAT(globalCtx, &this->shieldQuad.base);
|
||||
|
||||
if (this->pendingIceTrap) {
|
||||
GiveItemWithoutActor(globalCtx, GI_ICE_TRAP);
|
||||
}
|
||||
}
|
||||
|
||||
static Vec3f D_80854838 = { 0.0f, 0.0f, -30.0f };
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "z_kaleido_scope.h"
|
||||
#include "textures/parameter_static/parameter_static.h"
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
|
||||
u8 gAmmoItems[] = {
|
||||
ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_NONE, ITEM_NONE, ITEM_SLINGSHOT, ITEM_NONE,
|
||||
@ -10,6 +12,7 @@ static s16 sEquipState = 0;
|
||||
static s16 sEquipAnimTimer = 0;
|
||||
static s16 sEquipMoveTimer = 10;
|
||||
bool gSelectingMask;
|
||||
bool gSelectingAdultTrade;
|
||||
|
||||
static s16 sAmmoVtxOffset[] = {
|
||||
0, 2, 4, 6, 99, 99, 8, 99, 10, 99, 99, 99, 99, 99, 12,
|
||||
@ -109,7 +112,7 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
|
||||
pauseCtx->nameColorSet = 0;
|
||||
|
||||
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_ITEM)) {
|
||||
moveCursorResult = 0 || gSelectingMask;
|
||||
moveCursorResult = 0 || gSelectingMask || gSelectingAdultTrade;
|
||||
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_ITEM];
|
||||
|
||||
cursorItem = pauseCtx->cursorItem[PAUSE_ITEM];
|
||||
@ -283,7 +286,7 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
|
||||
if (pauseCtx->cursorSpecialPos == 0) {
|
||||
if (cursorItem != PAUSE_ITEM_NONE) {
|
||||
if ((ABS(pauseCtx->stickRelY) > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) {
|
||||
moveCursorResult = 0 || gSelectingMask;
|
||||
moveCursorResult = 0 || gSelectingMask || gSelectingAdultTrade;
|
||||
|
||||
cursorPoint = pauseCtx->cursorPoint[PAUSE_ITEM];
|
||||
cursorY = pauseCtx->cursorY[PAUSE_ITEM];
|
||||
@ -351,8 +354,16 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
|
||||
KaleidoScope_SetCursorVtx(pauseCtx, index, pauseCtx->itemVtx);
|
||||
|
||||
if ((pauseCtx->debugState == 0) && (pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0)) {
|
||||
if (CVar_GetS32("gMaskSelect", 0) && (gSaveContext.eventChkInf[8] & 0x8000) &&
|
||||
cursorSlot == SLOT_TRADE_CHILD && CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
// only allow mask select when:
|
||||
// the shop is open:
|
||||
// * zelda's letter check: gSaveContext.eventChkInf[4] & 1
|
||||
// * kak gate check: gSaveContext.infTable[7] & 0x40
|
||||
// and the mask quest is complete: gSaveContext.eventChkInf[8] & 0x8000
|
||||
if (CVar_GetS32("gMaskSelect", 0) &&
|
||||
(gSaveContext.eventChkInf[8] & 0x8000) &&
|
||||
cursorSlot == SLOT_TRADE_CHILD && CHECK_BTN_ALL(input->press.button, BTN_A) &&
|
||||
(gSaveContext.eventChkInf[4] & 1) &&
|
||||
(gSaveContext.infTable[7] & 0x40)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
gSelectingMask = !gSelectingMask;
|
||||
}
|
||||
@ -385,6 +396,24 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
|
||||
}
|
||||
gSelectingMask = cursorSlot == SLOT_TRADE_CHILD;
|
||||
}
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
|
||||
cursorSlot == SLOT_TRADE_ADULT && CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
gSelectingAdultTrade = !gSelectingAdultTrade;
|
||||
}
|
||||
if (gSelectingAdultTrade) {
|
||||
pauseCtx->cursorColorSet = 8;
|
||||
if (((pauseCtx->stickRelX > 30 || pauseCtx->stickRelY > 30) ||
|
||||
dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT | BTN_DUP))) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Inventory_ReplaceItem(globalCtx, INV_CONTENT(ITEM_TRADE_ADULT), Randomizer_GetNextAdultTradeItem());
|
||||
} else if (((pauseCtx->stickRelX < -30 || pauseCtx->stickRelY < -30) ||
|
||||
dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DDOWN))) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Inventory_ReplaceItem(globalCtx, INV_CONTENT(ITEM_TRADE_ADULT), Randomizer_GetPrevAdultTradeItem());
|
||||
}
|
||||
gSelectingAdultTrade = cursorSlot == SLOT_TRADE_ADULT;
|
||||
}
|
||||
u16 buttonsToCheck = BTN_CLEFT | BTN_CDOWN | BTN_CRIGHT;
|
||||
if (CVar_GetS32("gDpadEquips", 0) && (!CVar_GetS32("gDpadPauseName", 0) || CHECK_BTN_ALL(input->cur.button, BTN_CUP))) {
|
||||
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
||||
@ -510,6 +539,7 @@ void KaleidoScope_SetupItemEquip(GlobalContext* globalCtx, u16 item, u16 slot, s
|
||||
Input* input = &globalCtx->state.input[0];
|
||||
PauseContext* pauseCtx = &globalCtx->pauseCtx;
|
||||
gSelectingMask = false;
|
||||
gSelectingAdultTrade = false;
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
|
||||
pauseCtx->equipTargetCBtn = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user