diff --git a/Z3DR b/Z3DR index 6c916cc..9801871 160000 --- a/Z3DR +++ b/Z3DR @@ -1 +1 @@ -Subproject commit 6c916cc5518cdefc0f560441004fee9742061009 +Subproject commit 980187171e5c06006b97bdb0fe5102110ed8aa41 diff --git a/docs/release-notes/changelog-latest-nightly.md b/docs/release-notes/changelog-latest-nightly.md index 0483cc7..c35c9ba 100644 --- a/docs/release-notes/changelog-latest-nightly.md +++ b/docs/release-notes/changelog-latest-nightly.md @@ -1,8 +1,103 @@ # Latest Nightly Changes ## Features -- N/A -## Fixes -- Adjust fairies to ensure they are repeatable if the item is not in inventory. -- Adjust fairies to properly respect the fairy bits stored in ext data. \ No newline at end of file +### Shopsanity +- **Shopsanity.** New setting *Off* / *On*. Shuffles 21 shop slots across five shops: + + | Shop | Slots | Vanilla stock | + |---|---|---| + | West Clock Town Trading Post | 8 | Red Potion, Green Potion, Hero's Shield, Bottle with Fairy, Deku Stick, 30 Arrows, 10 Deku Nuts, Magic Bean | + | West Clock Town Bomb Shop | 4 | 10 Bombs, 10 Bombchu, Bomb Bag purchase, Big Bomb Bag purchase | + | Southern Swamp Magic Hags' Potion Shop | 3 | Blue Potion, Green Potion, Red Potion | + | Goron Village Shop | 3 | 10 Bombs, 10 Bombchu, Red Potion | + | Zora Hall Shop | 3 | Hero's Shield, 10 Arrows, Red Potion | + + The **Milk Bar** (Milk and Chateau Romani, sold separately) and the **Gorman Track milk** purchase + are shuffled in the same pass. The two Bomb Bag purchases also need **Shuffle Main Inventory** to + be on. Tingle maps, scrub purchases and the Curiosity Shop's All-Night Mask keep their own + settings. +- **Shared shelves.** Alternate versions of a shelf sell the same check, share its price and text, + and sell out together: the Trading Post part-timer after 10pm, the Goron Shop in spring, and the + stolen Bomb Bag Sakon fences at the Curiosity Shop (the Bomb Shop's Big Bomb Bag — buying either + one retires both). +- **Shopsanity Prices.** *Random* or *Affordable*. *Random* + + +### Magic beans +- **Beansanity.** **Shuffle Magic Beans** is no longer hidden and can be turned on. It adds a + **Magic Bean Pack** (a stack of 20 beans) to the item pool and turns the Deku Palace Bean Salesman + into a randomized check costing 60 rupees. + (`71011b5` (Shopsanity), mm3dr `7537273` (shopsanity)) +- **The Bean Pack unlocks buying beans.** Logic requires the pack before any bean purchase counts, + and the pack is never placed in a shop since you could not buy it there. The Trading Post's bean + shelf refuses the sale until you have found beans. + (`71011b5` (Shopsanity), mm3dr `e0991d3` (shopsanity)) + +### Music and sound +- **Music randomizer.** New cosmetic option **Shuffle Music**: *Off*, *Background Music*, *Fanfares* or *All*. The generator shuffles tracks within compatible groups (area, event, battle, fanfare and ocarina music) and the patch plays the shuffled track in place of the original. The same option is also available from the new in-game Options menu. + ([MM3D_Randomizer#204](https://github.com/Z3DR/MM3D_Randomizer/pull/204), [mm3dr#190](https://github.com/Z3DR/mm3dr/pull/190)) +- **Sound effect randomizer.** New in-game option **Shuffle Sound Effects**: *Off*, *Categorical* or *Chaos*. + ([mm3dr#191](https://github.com/Z3DR/mm3dr/pull/191)) +- **Mute toggles.** New in-game options **Mute Sound Effects** and **Mute Background Music**. + ([mm3dr#189](https://github.com/Z3DR/mm3dr/pull/189)) + +### Ocarina +- **Fast Ocarina Songs.** New in-game option that skips the song replay after playing any ocarina song: *Don't Skip*, *Skip (No Audio)* or *Skip (Keep Audio)*. This replaces the old fast playback that only applied to Elegy of Emptiness and Song of Soaring. + ([mm3dr#188](https://github.com/Z3DR/mm3dr/pull/188)) + +### Options +- **In-game Options menu.** New Options page on the ingame menu. It holds Fast Ocarina Songs, the mute toggles, Shuffle Music and Shuffle Sound Effects. + ([mm3dr#188](https://github.com/Z3DR/mm3dr/pull/188)) +- New **In-Game Options** menu in the generator. Lets you override the initial settings of new saves. + (`9886b27`, mm3dr `82c0c77`) + +### Quality of life +- **Pirates' cutscene skip.** Skips the cutscene played when heading to Great Bay Temple. *A generator option to toggle this still needs to be added.* + ([mm3dr#181](https://github.com/Z3DR/mm3dr/pull/181)) + +### Ice traps +- **More ice trap disguises.** Ice traps can now look like masks (including transformation masks), trade items, Bomber's Notebook, Tingle maps, the Ocarina of Time, and Skulltula tokens. + (`ec8f371` (Shopsanity)) + +## Bug Fixes + +### Stray fairies +- Fairy chests are now overridden when the fairy inside holds a major item. + ([mm3dr#178](https://github.com/Z3DR/mm3dr/pull/178)) +- Chest flags now account for fairies. + ([mm3dr#184](https://github.com/Z3DR/mm3dr/pull/184)) +- Stray fairies are only counted in the stray fairy bits. + ([mm3dr#185](https://github.com/Z3DR/mm3dr/pull/185)) +- Fairies without a collider no longer give their item twice or show an overhead item. + ([mm3dr#186](https://github.com/Z3DR/mm3dr/pull/186), [mm3dr#187](https://github.com/Z3DR/mm3dr/pull/187)) +- Stray fairy item text now names the correct progressive item. + ([mm3dr#183](https://github.com/Z3DR/mm3dr/pull/183)) +- Added a 120-tick delay to item updates with stray fairies so the item is given properly. + ([mm3dr#192](https://github.com/Z3DR/mm3dr/pull/192)) + +### Items +- Mystery Milk is removed correctly again; room key, letters and pendant are still kept. + ([mm3dr#187](https://github.com/Z3DR/mm3dr/pull/187)) +- Removed a bad instruction from the trade item hooks. + (mm3dr `319b404`) +- Ice traps disguised as Double Defense and as songs now use the correct models. +- Kokiri Sword removed from Ice Trap disguises (redundant with Progressive Sword). + (`ec8f371` (Shopsanity)) + +### Camera and movement +- Free camera no longer resets while swimming as Zora or rolling as Goron. + ([mm3dr#177](https://github.com/Z3DR/mm3dr/pull/177)) + +### Tracker and text +- Great Bay is now marked as discovered on the spoiler menu when entered. + ([mm3dr#179](https://github.com/Z3DR/mm3dr/pull/179)) + +## Other Changes + +- **Custom text commands.** Added two-character commands: `>[1-5]` starts a choice, and `>>`, `><` and `<<` align the active line right, center and left. + ([mm3dr#180](https://github.com/Z3DR/mm3dr/pull/180), [mm3dr#182](https://github.com/Z3DR/mm3dr/pull/182)) +- The in-game tracker now labels "Inside Clock Tower" as "Clock Tower". + (mm3dr `8f9f13e` (shopsanity)) +- New ingame options are ready to have generator settings added. + (mm3dr `34a5e15`) diff --git a/docs/release-notes/old-releases/nightlies/2.0.0/changelog-nightly-08cefa.md b/docs/release-notes/old-releases/nightlies/2.0.0/changelog-nightly-08cefa.md new file mode 100644 index 0000000..1eb04e7 --- /dev/null +++ b/docs/release-notes/old-releases/nightlies/2.0.0/changelog-nightly-08cefa.md @@ -0,0 +1,8 @@ +# Nightly 08CEFA + +## Features +- N/A + +## Fixes +- Adjust fairies to ensure they are repeatable if the item is not in inventory. +- Adjust fairies to properly respect the fairy bits stored in ext data. \ No newline at end of file diff --git a/source/custom_messages.cpp b/source/custom_messages.cpp index 3f2c3fc..ae574e1 100644 --- a/source/custom_messages.cpp +++ b/source/custom_messages.cpp @@ -335,13 +335,13 @@ void CreateBaselineCustomMessages() { // Ice Trap CreateMessage(0x0012, 0xFFFF, 0x3FFFFFFF, 0xFF0000, - {" #FOOL!#", + {"><#FOOL!#", // French - "#IDIOT!#", + "><#IDIOT!#", // NOT Spanish - " #FOOL!#", + "><#FOOL!#", // German - "#NARR!#", + "><#NARR!#", }, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_NORMAL); diff --git a/source/fill.cpp b/source/fill.cpp index 62faa15..74d0d93 100644 --- a/source/fill.cpp +++ b/source/fill.cpp @@ -12,7 +12,7 @@ #include "hints.hpp" #include "hint_list.hpp" #include "entrance.hpp" -//#include "shops.hpp" +#include "shops.hpp" #include "debug.hpp" #include @@ -522,6 +522,10 @@ static void AssumedFill(const std::vector& items, const std::vectorGetName()); itemsToPlace.push_back(item); } + else if (Location(selectedLocation)->IsCategory(Category::cShop) && (item == MAGIC_BEAN_PACK)) { + //Magic Bean Pack is what enables buying beans at shops so it cannot go into a shop itself + itemsToPlace.push_back(item); + } else { PlaceItemInLocation(selectedLocation, item); //PlacementLog_Msg("Placed " + ItemTable(item).GetName().GetNAEnglish() + " at " + Location(selectedLocation)->GetName()); @@ -781,6 +785,7 @@ static void RandomizeLinksPocket() { int VanillaFill() { //Perform minimum needed initialization // CitraPrint("Starting VanillaFill\n"); + ResetNonShopItems(); AreaTable_Init(); //Reset the world graph to intialize the proper locations ItemReset(); //Reset shops incase of shopsanity random GenerateLocationPool(); @@ -832,6 +837,7 @@ int Fill() { wothLocations.clear(); ocarinaObtainable = false; songOfTimeObtainable = false; + ResetNonShopItems(); //Before any placement -- see ResetNonShopItems AreaTable_Init(); //Reset the world graph to intialize the proper locations ItemReset(); //Reset shops incase of shopsanity random GenerateLocationPool(); @@ -839,7 +845,7 @@ int Fill() { GenerateStartingInventory(); RemoveStartingItemsFromPool(); FillExcludedLocations(); - + showItemProgress = true; //Place dungeon rewards @@ -994,6 +1000,30 @@ int Fill() { AssumedFill(gfItems, gfLocations, true); } + + //Place Shop Items first + //NonShopItems is already sized by ResetNonShopItems + if (Shopsanity){ + CitraPrint("Placing Shopsanity Items"); + for (size_t i = 0; i < ShopLocationLists.size(); i++) { + for (size_t j = 0; j < ShopLocationLists[i].size(); j++) { + int shopsanityPrice = GetShopPrice(); + NonShopItems[GetShopIndex(ShopLocationLists[i][j])].Price = shopsanityPrice; //Set the price for the item to be passed + Location(ShopLocationLists[i][j])->SetShopsanityPrice(shopsanityPrice); //Set the price for the location to be passed + } + } + } + //Below may not be needed? + // //Get all locations and items that dont have a shopsanity price attached + // std::vector shopLocations = {}; + // for (size_t i = 0; i < ShopLocationLists.size(); i++){ + // for (int j = 0; j < ShopLocationLists[i].size(); j++){ + // LocationKey loc = ShopLocationLists[i][j]; + // if (!(Location(loc)->HasShopsanityPrice())) { + // shopLocations.push_back(loc); + // } + // } + // } //Place Main Inventory First //So first get all items in the pool + DekuMask, diff --git a/source/hint_list.cpp b/source/hint_list.cpp index 1ec47bf..319ca28 100644 --- a/source/hint_list.cpp +++ b/source/hint_list.cpp @@ -43,7 +43,7 @@ void HintTable_Init() { ); hintTable[GREAT_FAIRYS_SWORD] = HintText::Item({ //obscure - Text{"A powerful fairy blade", "une lame féerique", "el poderoso acero de las hadas", "eine mächtige Feenklinge"} + Text{"a powerful fairy blade", "une lame féerique", "el poderoso acero de las hadas", "eine mächtige Feenklinge"} }, //clear Text{"the Great Fairy's Sword", "l'épée de la grande fée", "la Espada de la Gran Hada", "das Feenschwert", "", "la grande épée des fées", ""} ); @@ -115,7 +115,7 @@ void HintTable_Init() { ); hintTable[LETTER_MAMA] = HintText::Item({ //obscure - Text{"A special delivery", "une livraison spéciale", "una entrega especial", "eine besondere Zustellung"} + Text{"a special delivery", "une livraison spéciale", "una entrega especial", "eine besondere Zustellung"} }, //clear Text{"the Letter to Mama", "la lettre express pour Maman", "la Entrega especial a mamá", "die Eilpost an Mama", "", "la lettre express pour maman", ""} ); @@ -383,7 +383,7 @@ void HintTable_Init() { //obscure Text{"a lost fairy", "un fragment d'être", "una hada perdida", "eine verlorene Fee"} }, //clear - Text{"the Clock Town Stray Fairy", "la fée égarée de Cadranbourg", "la hada extraviada de la Ciudad", "eine verirrte Fee aus Unruh-Stadt", "", "la fée égarée de Bourg-Clocher", ""} + Text{"the Clock Town Stray Fairy", "la fée égarée de Cadranbourg", "la hada extraviada de la Ciudad", "die verirrte Fee aus Unruh-Stadt", "", "la fée égarée de Bourg-Clocher", ""} ); hintTable[WF_STRAY_FAIRY] = HintText::Item({ //obscure @@ -426,7 +426,7 @@ void HintTable_Init() { //obscure Text{"a progressive bow", "une capacité de tir accrue", "un arco progresivo", "ein wachsender Bogen"} }, //clear - Text{"a progressive quiver", "un carquois progressif", "un carcaj progresivo", "ein Köcher-Upgrade"} + Text{"a progressive quiver", "un carquois progressif", "un carcaj progresivo", "ein Bogen-Upgrade"} ); hintTable[PROGRESSIVE_WALLET] = HintText::Item({ //obscure @@ -442,9 +442,9 @@ void HintTable_Init() { ); hintTable[PROGRESSIVE_LULLABY] = HintText::Item({ //obscure - Text{"a progressive lullaby", "une fraction de mélodie", "una canción de cuna progresiva", ""} + Text{"a progressive lullaby", "une fraction de mélodie", "una canción de cuna progresiva", "ein unvollständiges Wiegenlied"} }, //clear - Text{"a progressive lullaby", "une berceuse progressive", "una canción de cuna progresiva", ""} + Text{"a progressive lullaby", "une berceuse progressive", "una canción de cuna progresiva", "ein Schlummerlied-Upgrade"} ); //PROGRESSIVE_BOMBCHUS //BOTTLE ITEMS @@ -587,7 +587,7 @@ void HintTable_Init() { //SONGS hintTable[SONG_OF_TIME] = HintText::Item({ //obscure - Text{"song of time", "une boucle temporelle", "una canción temporal", "das Lied der Zeit"} + Text{"a timely melody", "une boucle temporelle", "una canción temporal", "das Lied der Zeit"} }, //clear Text{"the Song of Time", "le Chant du temps", "la canción del tiempo", "die Hymne der Zeit"} ); @@ -623,7 +623,7 @@ void HintTable_Init() { //); hintTable[EPONAS_SONG] = HintText::Item({ //obscure - Text{"a horses song", "l'appel d'une partenaire", "una canción equina", "das Lied eines Pferdes"} + Text{"a horse's song", "l'appel d'une partenaire", "una canción equina", "das Lied eines Pferdes"} }, //clear Text{"Epona's Song", "le Chant d'Épona", "la canción de Epona", "Eponas Lied", "", "le Chant d'Epona", ""} ); @@ -814,25 +814,25 @@ void HintTable_Init() { //); hintTable[WOODFALL_TEMPLE_SMALL_KEY] = HintText::Item({ //obscure - Text{"swampy small key", "une clé marécageuse", "una llave pantanosa", "ein sumpfiger Schlüssel"} + Text{"a swampy small key", "une clé marécageuse", "una llave pantanosa", "ein sumpfiger Schlüssel"} }, //clear Text{"the Woodfall Temple Small Key", "la petite clé du temple de Boisé-les-Cascades", "la llave pequeña del Templo del Bosque Catarata", "den Kleinen Schlüssel des Dämmerwald-Tempels", "", "la petite clé du temple de Bois-Cascade", ""} ); hintTable[SNOWHEAD_TEMPLE_SMALL_KEY] = HintText::Item({ //obscure - Text{"icy small key", "une clé glacée", "una llave helada", "ein eisiger Schlüssel"} + Text{"an icy small key", "une clé glacée", "una llave helada", "ein eisiger Schlüssel"} }, //clear Text{"a Snowhead Temple Small Key", "une petite clé du temple du Pic des neiges", "una llave pequeña del Templo del Pico Nevado", "einen Kleinen Schlüssel des Pic-Hibernia-Tempels", "", "une petite clé du temple du pic des Neiges", ""} ); hintTable[GBT_SMALL_KEY] = HintText::Item({ //obscure - Text{"ocean small key", "une clé marine", "una llave húmeda", "ein feuchter Schlüssel"} + Text{"an oceanic small key", "une clé marine", "una llave húmeda", "ein feuchter Schlüssel"} }, //clear Text{"the Great Bay Temple Small Key", "la petite clé du temple de la Grande Baie", "la llave pequeña del Templo de la Gran Bahía", "den Kleinen Schlüssel des Schädelbucht-Tempels"} ); hintTable[STONE_TOWER_TEMPLE_SMALL_KEY] = HintText::Item({ //obscure - Text{"rocky small key", "une clé rocheuse", "una llave rocosa", "ein steinerner Schlüssel"} + Text{"a rocky small key", "une clé rocheuse", "una llave rocosa", "ein steinerner Schlüssel"} }, //clear Text{"a Stone Tower Temple Small Key", "une petite clé du temple de la forteresse de pierre", "una llave pequeña del Templo de la Torre de Piedra", "einen Kleinen Schlüssel des Felsenturm-Tempels"} ); @@ -867,43 +867,43 @@ void HintTable_Init() { -----------------------*/ hintTable[RECOVERY_HEART] = HintText::Item({ //obscure - Text{"Recovery Heart", "un petit soin", "un pequeño corazón", "ein Herz zur Genesung"} + Text{"a small heal", "un petit soin", "un pequeño corazón", "ein Herz zur Genesung"} }, //clear Text{"a Recovery Heart", "un cœur de vie", "un corazón", "ein Herz"} ); hintTable[GREEN_RUPEE] = HintText::Item({ //obscure - Text{"Green rupee", "le début de la richesse", "una gema verdeante", "ein grüner Rubin"} + Text{"budding wealth", "le début de la richesse", "una gema verdeante", "ein grüner Rubin"} }, //clear Text{"a Green Rupee", "un rubis vert", "una rupia verde", "einen grünen Rubin"} ); hintTable[BLUE_RUPEE] = HintText::Item({ //obscure - Text{"Blue rupee", "une richesse azurée", "una gema cerúlea", "ein blauer Rubin"} + Text{"a blue gem", "une richesse azurée", "una gema cerúlea", "ein blauer Rubin"} }, //clear Text{"a Blue Rupee", "un rubis bleu", "una rupia azul", "einen blauen Rubin"} ); hintTable[RED_RUPEE] = HintText::Item({ //obscure - Text{"Red rupee", "une richesse écarlate", "una gema carmesí", "ein roter Rubin"} + Text{"a scarlet stone", "une richesse écarlate", "una gema carmesí", "ein roter Rubin"} }, //clear Text{"a Red Rupee", "un rubis rouge", "una rupia roja", "einen roten Rubin"} ); hintTable[PURPLE_RUPEE] = HintText::Item({ //obscure - Text{"Purple rupee", "une richesse violacée", "una gema cárdena", "ein violetter Rubin"} + Text{"a purple gem", "une richesse violacée", "una gema cárdena", "ein violetter Rubin"} }, //clear Text{"a Purple Rupee", "un rubis mauve", "una rupia púrpura", "einen violetten Rubin", "", "un rubis violet", ""} ); hintTable[SILVER_RUPEE] = HintText::Item({ //obscure - Text{"Silver rupee", "une richesse scintillante", "una gema argéntea", "ein silberner Rubin"} + Text{"shining wealth", "une richesse scintillante", "una gema argéntea", "ein silberner Rubin"} }, //clear Text{"a Silver Rupee", "un rubis argenté", "una rupia plateada", "einen silbernen Rubin"} ); hintTable[HUGE_RUPEE] = HintText::Item({ //obscure - Text{"Huge rupee", "une richesse écrasante", "una gema enorme", "ein riesiger Rubin"} + Text{"great wealth", "une richesse écrasante", "una gema enorme", "ein riesiger Rubin"} }, //clear Text{"a Huge Rupee", "un énorme rubis", "una rupia enorme", "einen goldenen Rubin"} ); @@ -1009,6 +1009,12 @@ void HintTable_Init() { }, //clear Text{"a Deku Stick", "un bâton mojo", "un palo Deku", "einen Deku-Stab"} ); + hintTable[CHATEAU_ROMANI_REFILL] = HintText::Item({ + //obscure + Text{"an adult beverage", "un breuvage adulte", "un trago para adultos", "ein Getränk für Erwachsene"} + }, //clear + Text{"some Chateau Romani", "de la Cuvée Romani", "un relleno de Reserva Romani", "ein Chateau Romani"} + ); /*---------------- | SHOP ITEMS | @@ -1177,18 +1183,18 @@ void HintTable_Init() { }, //clear Text{"the #postbox# contains", "la #boîte aux lettres# contient", "el buzón contiene", "der #Briefkasten# enthält"} ); - //hintTable[E_CLOCK_TOWN_MILK_BAR_CHATEAU] = HintText::Sometimes({ - // //obscure - // Text{"**ENGLISH**", "un #spécialiste laitier# vend", "un lugar de copas vende", "ein #exklusives Getränk# entlohnt"} - // }, //clear - // Text{"the #Milk Bar# sells", "le #bar laitier# vend", "el Bar Lácteo vende", "die #Milchbar# verkauft"} - //); - //hintTable[E_CLOCK_TOWN_MILK_BAR_MILK] = HintText::Sometimes({ - // //obscure - // Text{"**ENGLISH**", "un #spécialiste laitier# vend", "un lugar de copas vende", "ein #Getränk# entlohnt"} - // }, //clear - // Text{"the #Milk Bar# sells", "le #bar laitier# vend", "el Bar Lácteo vende", "die #Milchbar# verkauft"} - //); + hintTable[E_CLOCK_TOWN_MILK_BAR_CHATEAU] = HintText::Sometimes({ + //obscure + Text{"an #exclusive establishment# sells", "un #spécialiste laitier# vend", "un lugar de copas vende", "ein #exklusives Getränk# entlohnt"} + }, //clear + Text{"the #Milk Bar# sells", "le #bar laitier# vend", "el Bar Lácteo vende", "die #Milchbar# verkauft"} + ); + hintTable[E_CLOCK_TOWN_MILK_BAR_MILK] = HintText::Sometimes({ + //obscure + Text{"an #exclusive establishment# sells", "un #spécialiste laitier# vend", "un lugar de copas vende", "ein #Getränk# entlohnt"} + }, //clear + Text{"the #Milk Bar# sells", "le #bar laitier# vend", "el Bar Lácteo vende", "die #Milchbar# verkauft"} + ); hintTable[GORMAN_TRACK_MYSTERY_MILK_QUEST] = HintText::Sometimes({ //obscure Text{"an #upset stomach cure# rewards", "#soigner un mal de ventre# produit", "la cura a un mal estomacal recompensa con", "die #Heilung eines verstimmten Magens# entlohnt"} @@ -1363,7 +1369,7 @@ void HintTable_Init() { //obscure Text{"the #pirates' loot# teaches", "le #butin des pirates# enseigne", "el botín de los piratas enseña", "die #Piratenbeute# lehrt"} }, //clear - Text{"the #baby Zoras# have", "les #bébés zoras# ont", "los bebés Zora tienen", "die #Zora-Babys# haben"} + Text{"the #baby Zoras# have", "les #bébés zoras# ont", "los bebés Zora tienen", "die #geschlüpften Zora-Babys# haben"} ); hintTable[GBC_GROTTO_CHEST] = HintText::Sometimes({ //obscure @@ -3853,7 +3859,7 @@ void HintTable_Init() { //obscure Text{"the home of pirates", "le foyer des pirates", "el hogar de las piratas", "die Heimat der Piraten"} }, //clear - Text{"the Pirates' Fortress", "la forteresse des pirates", "la Fortaleza Pirata", "die Piratenfestung"} + Text{"the Pirates' Fortress", "la forteresse des pirates", "la Fortaleza Pirata", "Piratenfestung"} ); hintTable[BENEATH_THE_WELL] = HintText::DungeonName({ //obscure @@ -3877,13 +3883,13 @@ void HintTable_Init() { //obscure Text{"a home to muddy spiders", "un nid puant d'araignées", "un hogar para arañas lodosas", "ein Zuhause für schlammige Spinnen"} }, //clear - Text{"the Swamp Spider House", "la maison des araignées des marais", "la Casa de las Arañas del Pantano", "das Sumpf-Spinnenhaus"} + Text{"the Swamp Spider House", "la maison des araignées des marais", "la Casa de las Arañas del Pantano", "das Spinnenhaus im Sumpf"} ); hintTable[OSH] = HintText::DungeonName({ //obscure Text{"a home To swimming spiders", "un nid poussiéreux d'araignées", "un hogar para arañas nadadoras", "ein Zuhause für schwimmende Spinnen"} }, //clear - Text{"the Ocean Spider House", "la maison des araignées de la côte", "la Casa de las Arañas de la Playa", "das Meer-Spinnenhaus"} + Text{"the Ocean Spider House", "la maison des araignées de la côte", "la Casa de las Arañas de la Playa", "das Spinnenhaus am Meer"} ); hintTable[THE_MOON] = HintText::DungeonName({ //obscure diff --git a/source/hints.cpp b/source/hints.cpp index f2c85e6..ed1a5a9 100644 --- a/source/hints.cpp +++ b/source/hints.cpp @@ -12,6 +12,7 @@ #include "custom_messages.hpp" //#include "trial.hpp" //#include "entrance.hpp" +#include "shops.hpp" //using namespace CustomMessages; using namespace Logic; @@ -436,56 +437,336 @@ static std::vector CalculateBarrenRegions() { return finalBarrenLocations; } +Text GetShopItemName(ItemKey itemKey) { + if (itemKey == ICE_TRAP) + return GetIceTrapName(ItemTable(itemKey).Value().looksLikeItemId); + else + return ItemTable(itemKey).GetName(); +} + void CreateTingleHintText() { // Create custom messages for Tingle items if we shuffled. if (Settings::ShuffleTingleMaps.Is(true)) { // Logic: Get item names from location. // Create custom message for each tingle location (6) - Text clockTownMap = Text{"#"}+ItemTable(Location(TINGLE_N_CLOCK_TOWN_CT)->GetPlacedItemKey()).GetName(); - Text woodfallMap = Text{"#"}+ItemTable(Location(TINGLE_N_CLOCK_TOWN_WF)->GetPlacedItemKey()).GetName(); - Text snowHeadMap = Text{"#"}+ItemTable(Location(TINGLE_TWIN_ISLANDS_SH)->GetPlacedItemKey()).GetName(); - Text romaniMap = Text{"#"}+ItemTable(Location(TINGLE_TWIN_ISLANDS_RR)->GetPlacedItemKey()).GetName(); - Text greatBayMap = Text{"#"}+ItemTable(Location(TINGLE_GBC_GB)->GetPlacedItemKey()).GetName(); - Text ikanaMap = Text{"#"}+ItemTable(Location(TINGLE_GBC_ST)->GetPlacedItemKey()).GetName(); - - // {"English", "French", "Spanish" "German" }; "Italian" - Text priceFive = {" ##5 Rupees#&", " ##5 Rubis#&", " ##5 rupias#&", " - ##5 Rubine#&" }; // , " ##5 rupie#&" - Text priceTwenty = {" ##20 Rupees#&", " ##20 Rubis#&", " ##20 rupias#&", " - ##20 Rubine#&"}; // , " ##20 rupie#&" - Text priceForty = {" ##40 Rupees#", " ##40 Rubis#", " ##40 rupias#", " - ##40 Rubine#" }; // , " ##40 rupie#" - Text leaveShop = {"&#No thanks#", "&#Non merci#", "&#No, gracias#", "&#Nein, danke!#" }; // , "&#No, grazie#" + Text clockTownMap = GetShopItemName(Location(TINGLE_N_CLOCK_TOWN_CT)->GetPlacedItemKey()); + Text woodfallMap = GetShopItemName(Location(TINGLE_N_CLOCK_TOWN_WF)->GetPlacedItemKey()); + Text snowHeadMap = GetShopItemName(Location(TINGLE_TWIN_ISLANDS_SH)->GetPlacedItemKey()); + Text romaniMap = GetShopItemName(Location(TINGLE_TWIN_ISLANDS_RR)->GetPlacedItemKey()); + Text greatBayMap = GetShopItemName(Location(TINGLE_GBC_GB)->GetPlacedItemKey()); + Text ikanaMap = GetShopItemName(Location(TINGLE_GBC_ST)->GetPlacedItemKey()); + u16 tingPriceTiny = 5; + u16 tingPriceSmall = 20; + u16 tingPriceBig = 40; + + // {"English", "French", "Spanish", "German", }; // "Italian" + Text tingSplit = {" ##", " ##", " ##", " - ##", }; // " ##" + Text tingNext = {" Rupees#&#", " Rubis#&#", " rupias#&#", " Rubine#&#", }; // " rupie#&" + Text tingLeave = tingNext+ + Text{"No thanks#", "Non merci#", "No, gracias#", "Nein, danke!#", }; // "&#No, grazie#" // Clock Town message - CustomMessages::CreateMessageFromTextObject(0x1D11, 0xFFFF, 0x3FF0A005, 0xFF1001, - clockTownMap+priceFive+woodfallMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D11, 0xFFFF, (0x3FF00000 | tingPriceTiny | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+clockTownMap+tingSplit+std::to_string(tingPriceTiny)+tingNext+woodfallMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); // Woodfall message - CustomMessages::CreateMessageFromTextObject(0x1D12, 0xFFFF, 0x3FF0A014, 0xFF1001, - woodfallMap+priceTwenty+snowHeadMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D12, 0xFFFF, (0x3FF00000 | tingPriceSmall | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+woodfallMap+tingSplit+std::to_string(tingPriceSmall)+tingNext+snowHeadMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); // Snowhead message - CustomMessages::CreateMessageFromTextObject(0x1D13, 0xFFFF, 0x3FF0A014, 0xFF1001, - snowHeadMap+priceTwenty+romaniMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D13, 0xFFFF, (0x3FF00000 | tingPriceSmall | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+snowHeadMap+tingSplit+std::to_string(tingPriceSmall)+tingNext+romaniMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); // Milk Road message - CustomMessages::CreateMessageFromTextObject(0x1D14, 0xFFFF, 0x3FF0A014, 0xFF1001, - romaniMap+priceTwenty+greatBayMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D14, 0xFFFF, (0x3FF00000 | tingPriceSmall | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+romaniMap+tingSplit+std::to_string(tingPriceSmall)+tingNext+greatBayMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); // Great Bay message - CustomMessages::CreateMessageFromTextObject(0x1D15, 0xFFFF, 0x3FF0A014, 0xFF1001, - greatBayMap+priceTwenty+ikanaMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D15, 0xFFFF, (0x3FF00000 | tingPriceSmall | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+greatBayMap+tingSplit+std::to_string(tingPriceSmall)+tingNext+ikanaMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); // Ikana message - CustomMessages::CreateMessageFromTextObject(0x1D16, 0xFFFF, 0x3FF0A014, 0xFF1001, - ikanaMap+priceTwenty+clockTownMap+priceForty+leaveShop, + CustomMessages::CreateMessageFromTextObject(0x1D16, 0xFFFF, (0x3FF00000 | tingPriceSmall | (tingPriceBig << 10)), 0xFF1001, + Text{">3#"}+ikanaMap+tingSplit+std::to_string(tingPriceSmall)+tingNext+clockTownMap+tingSplit+std::to_string(tingPriceBig)+tingLeave, {QM_GREEN, QM_RED, QM_GREEN, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); } } +void CreateShopMessages() { + //Create list of messages to create and their corresponding location + std::pair shopEntries[21] = { + //Trading Post + {0x06AC, TRADING_POST_ITEM_1}, {0x06B2, TRADING_POST_ITEM_2}, {0x06AE, TRADING_POST_ITEM_3}, {0x06B6, TRADING_POST_ITEM_4}, + {0x06B4, TRADING_POST_ITEM_5}, {0x06B8, TRADING_POST_ITEM_6}, {0x06B0, TRADING_POST_ITEM_7}, {0x06BA, TRADING_POST_ITEM_8}, + //Trading Post (Part-timer) + // {0x06C9, TRADING_POST_ITEM_1}, {0x06CF, TRADING_POST_ITEM_2}, {0x06CB, TRADING_POST_ITEM_3}, {0x06D3, TRADING_POST_ITEM_4}, + // {0x06D1, TRADING_POST_ITEM_5}, {0x06D5, TRADING_POST_ITEM_6}, {0x06CD, TRADING_POST_ITEM_7}, {0x06D7, TRADING_POST_ITEM_8}, + //Bomb Shop + {0x0650, BOMB_SHOP_ITEM_1}, {0x0652, BOMB_SHOP_ITEM_2}, {0x0654, W_CLOCK_TOWN_BOMB_BAG_BUY}, {0x0656, W_CLOCK_TOWN_BIG_BOMB_BAG_BUY}, + //Potion Shop + {0x083F, POTION_SHOP_ITEM_1}, {0x0841, POTION_SHOP_ITEM_2}, {0x0843, POTION_SHOP_ITEM_3}, + //Goron Shop + {0x0BC5, GORON_SHOP_ITEM_1}, {0x0BC7, GORON_SHOP_ITEM_2}, {0x0BC9, GORON_SHOP_ITEM_3}, + //Goron Shop (Spring Prices) + // {0x0BCB, GORON_SHOP_ITEM_1}, {0x0BCD, GORON_SHOP_ITEM_2}, {0x0BCF, GORON_SHOP_ITEM_3}, + //Zora Shop + {0x12DB, ZORA_SHOP_ITEM_1}, {0x12DD, ZORA_SHOP_ITEM_2}, {0x12DF, ZORA_SHOP_ITEM_3}, + // Curiosity Shop + // {0x29D9, W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY}, {0x29DB, W_CLOCK_TOWN_CURIOSITY_BOMB_BAG}, + // Curiosity Shop (Takkuri) + // {0x29F2}, {0x29F4}, {0x29F6}, {0x29F8}, + }; + + Text shopDescription = {""}; + Text slopDescription = {""}; + Text buyPrompt = Text{">2"}+Text{ + /*English*/"#Buy&Don't Buy#", + /*French */"#J'achète&J'achète pas#", + /*Spanish*/"#Comprar&No comprar#", + /*German */"#Kaufen!&Nicht kaufen!#", + // /*Italian*/"#Compra&Non comprare#", + }; + + //Generate Shop Message for every shopEntry + + for (u8 i = 0; i < 21; i++) { + u32 messageID = shopEntries[i].first; + u16 price = NonShopItems[GetShopIndex(shopEntries[i].second)].Price; + Text itemName = NonShopItems[GetShopIndex(shopEntries[i].second)].Name; + Text shopIntro = Text{"#"}+itemName+Text{ + "&>>" + // itemName.NAenglish.length() <= 30 ? ": " : "&>>", + // itemName.NAfrench.length() <= 30 ? " : " : "&>>", + // itemName.NAspanish.length() <= 30 ? ": " : "&>>", + // itemName.EURgerman.length() <= 30 ? ": " : "&>>", + // // itemName.EURitalian.length() <= 30 ? ": " : "&>>", + // itemName.EURenglish.length() <= 30 ? ": " : "&>>", + // itemName.EURfrench.length() <= 30 ? " : " : "&>>", + // itemName.EURspanish.length() <= 30 ? ": " : "&>>", + }+std::to_string(price)+Text{ + " Rupees#&", " rubis#&", " rupias#&", " Rubine#&",// " rupie#&" + }; + // Descriptions when hovering over the item + if (NonShopItems[GetShopIndex(shopEntries[i].second)].Repurchaseable) { + shopDescription = { + /*NaEnglish*/"Special deal!&Buy as many as you want!", + /*NaFrench */"Offre spéciale!&Achetez-en à volonté!", + /*NaSpanish*/"¡Oferta especial!&¡Compra todo lo que quieras!", + /*EuGerman */"Sonderangebot!&Kauft so viel ihr wollt!", + // /*EuItalian*/"Offerta speciale!&Compratene a volontà!", + /*EuEnglish*/"", + /*EuFrench */"Offre spéciale !&Achetez-en à volonté !", + /*EuSpanish*/"", + }; + slopDescription = { + /*English*/"Pretty sure we've got a bunch.&Oh and it's, like, a special deal.", + /*French */"On doit en avoir un tas dans le stock.&Ah oui, et c'est une offre spéciale.", + /*Spanish?*/"¡Oferta especial!&¡Compra todo lo que quieras!", + /*German ?*/"Sonderangebot!&Kauft so viel ihr wollt!", + // /*Italian?*/"Offerta speciale!&Compratene a volontà!", + }; + } else { + shopDescription = { + /*NaEnglish*/"Special deal! ONE LEFT!&Get it while it lasts!", + /*NaFrench */"Offre spéciale! DERNIER EN STOCK!&Maintenant ou jamais!", + /*NaSpanish*/"¡Oferta especial! ¡SOLO QUEDA UNA UNIDAD!&¡Hazte con ella antes de que se agote!", + /*EuGerman */"Sonderangebot! NUR EINS AUF LAGER!&Schlagt zu solange ihr noch könnt!", + // /*EuItalian*/"Offerta speciale! ULTIMO PEZZO!&Affrettatevi ad aquistarlo!", + /*EuEnglish*/"", + /*EuFrench */"Offre spéciale ! DERNIER EN STOCK !&Maintenant ou jamais !", + /*EuSpanish*/"", + }; + slopDescription = { + /*English*/"This one's a special deal, and uh,&I think we only have the one...", + /*French */"C't'un genre d'offre spéciale, ouais.&Et j'crois qu'c'est tout ce qu'on a...", + /*Spanish?*/"¡Oferta especial! ¡SOLO QUEDA UNA UNIDAD!&¡Hazte con ella antes de que se agote!", + /*German ?*/"Sonderangebot! NUR EINS AUF LAGER!&Schlagt zu solange ihr noch könnt!", + // /*Italian?*/"Offerta speciale! ULTIMO PEZZO!&Affrettatevi ad aquistarlo!", + }; + } + + // Create display and purchase messages + CustomMessages::CreateMessageFromTextObject(messageID , 0xFFFF, (0x3FFFFC00 | price), 0xFF0301, shopIntro + shopDescription, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + CustomMessages::CreateMessageFromTextObject(messageID + 1, 0xFFFF, (0x3FFFFC00 | price), 0xFF1301, shopIntro + buyPrompt, {QM_DEFAULT, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + // If Trading Post message, also generate part-timer version + if ((0x06AC <= messageID) && (messageID <= 0x06BA)) { + CustomMessages::CreateMessageFromTextObject(messageID + 0x1D, 0xFFFF, (0x3FFFFC00 | price), 0xFF0301, shopIntro + slopDescription, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + CustomMessages::CreateMessageFromTextObject(messageID + 0x1E, 0xFFFF, (0x3FFFFC00 | price), 0xFF1301, shopIntro + buyPrompt, {QM_DEFAULT, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + } + // If Goron Shop message, also generate spring copy + if ((0x0BC5 <= messageID) && (messageID <= 0x0BC9)) { + CustomMessages::CreateMessageFromTextObject(messageID + 0x6, 0xFFFF, (0x3FFFFC00 | price), 0xFF0301, shopIntro + shopDescription, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + CustomMessages::CreateMessageFromTextObject(messageID + 0x7, 0xFFFF, (0x3FFFFC00 | price), 0xFF1301, shopIntro + buyPrompt, {QM_DEFAULT, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + } + // If Big Bomb Bag write stolen variant (inelegantly) (Price is left unchanged... maybe someday?) + if (messageID == 0x0656) { + shopIntro = Text{"#"}+itemName+"&>>"+std::to_string(price)+Text{ + " Rupees#&", " rubis#&", " rupias#&", " Rubine#&",// " rupie#&" + }; + CustomMessages::CreateMessageFromTextObject(0x29DB, 0xFFFF, (0x3FFFFC00 | price), 0xFF0301, shopIntro+Text{ + /*English*/"This is just between us, but this is&actually a Bomb Shop product.", + /*French */"Ça reste entre nous, mais c'est&un article de la boutique de bombes.", + /*Spanish*/"Esto es entre nosotros, pero&es el de la tienda de bombas.", + /*German */"Verrat's nicht weiter, aber die ist eigentlich Eigentum des Bomben-Shops.", // OVERFLOW RISK + // /*Italian*/"he resti tra noi, ma in realtà&questo articolo appartiene al&negozio delle bombe.", // OVERFLOW RISK + }, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + CustomMessages::CreateMessageFromTextObject(0x29DC, 0xFFFF, (0x3FFFFC00 | price), 0xFF1301, shopIntro + buyPrompt, {QM_DEFAULT, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + } + //Special message for the potion shop witch if you haven't given her a mushroom yet + // WILL OVERFLOW IN MOST LANGUAGES WHEN ITEM NAME TRIGGERS LINE BREAK + if (messageID == 0x0843) { + CustomMessages::CreateMessageFromTextObject(0x0880, 0xFFFF, (0x3FFFFC00 | price), 0xFF0301, + shopIntro+Text{ + /*NaEnglish*/"Actually, I can't get the ingredients&for this, so I'm sold out. Sorry.", + /*NaFrench */"En fait, je n'arrive pas à trouver&les ingrédients pour ça, alors je&n'en ai plus. Désolée.", + /*NaSpanish*/"No puedo conseguir los&ingredientes, así que está&agotada. Lo siento.", + /*EuGerman */"Leider habe ich nicht die passenden&Zutaten auf Lager, daher ist dieser&Artikel gerade nicht lieferbar.", + // /*EuItalian*/"In realtà, questa pozione è esaurita&e non ho gli ingredienti per&prepararne altra. Mi spiace.", + /*EuEnglish*/"", + /*EuFrench */"", + /*EuSpanish*/"En realidad, no puedo conseguir&los ingredientes para esto, así que&no me queda más. Lo siento.", + }, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + } + } + + // Curiosity Shop dialogue !TEMPORARY! + Location(W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 allNightPrice = Location(W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY)->GetPrice(); + Text csMaskIntro = Text{"#"}+GetShopItemName(Location(W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY)->GetPlacedItemKey())+Text{ + "&>>" + // itemName.NAenglish.length() <= 30 ? ": " : "&>>", + // itemName.NAfrench.length() <= 30 ? " : " : "&>>", + // itemName.NAspanish.length() <= 30 ? ": " : "&>>", + // itemName.EURgerman.length() <= 30 ? ": " : "&>>", + // // itemName.EURitalian.length() <= 30 ? ": " : "&>>", + // itemName.EURenglish.length() <= 30 ? ": " : "&>>", + // itemName.EURfrench.length() <= 30 ? " : " : "&>>", + // itemName.EURspanish.length() <= 30 ? ": " : "&>>", + }+std::to_string(allNightPrice)+Text{ + " Rupees#&", " rubis#&", " rupias#&", " Rubine#&",// " rupie#&" + }; + CustomMessages::CreateMessageFromTextObject(0x29D9, 0xFFFF, (0x3FFFFC00 | allNightPrice), 0xFF0301, csMaskIntro + Text{ + "Wait, is this what I was just talking about?" + }, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_ENDLESS); + CustomMessages::CreateMessageFromTextObject(0x29DA, 0xFFFF, (0x3FFFFC00 | allNightPrice), 0xFF1301, csMaskIntro + buyPrompt, {QM_DEFAULT, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + + + // Custom Messages for Other Shops + // Milk Bar + Text MilkBarMilkItem = GetShopItemName(Location(E_CLOCK_TOWN_MILK_BAR_MILK)->GetPlacedItemKey()); + Text MilkBarChateauItem = GetShopItemName(Location(E_CLOCK_TOWN_MILK_BAR_CHATEAU)->GetPlacedItemKey()); + // Location(E_CLOCK_TOWN_MILK_BAR_MILK)->SetShopsanityPrice(static_cast(GetShopPrice())); + // Location(E_CLOCK_TOWN_MILK_BAR_CHATEAU)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 MilkBarMilkPrice = 20;// Location(E_CLOCK_TOWN_MILK_BAR_MILK)->GetPrice(); + u16 MilkBarChateauPrice = 200;// Location(E_CLOCK_TOWN_MILK_BAR_CHATEAU)->GetPrice(); + // {"English", "French", "Spanish", "German", }; // "Italian" + Text MilkBarIntro = {"What'll it be?&", "Qu'est-ce que ce s'ra?", "¿Qué quiere tomar?", "Was darf's sein?", // "Cosa prendi?", + "", "", "¿Qué va a ser?", }; + Text MilkSplit = {": ##", " : ##", ": ##", ": ##", }; // " ##", + Text MilkNext = {" Rupees#&#", " Rubis#&#", " rupias#&#", " Rubine#&#", }; // " rupie#&#", + Text MilkLeave = MilkNext + + Text{"Nothing#", "Rien#", "Nada#", "Nichts#", }; // "Niente#", + + CustomMessages::CreateMessageFromTextObject(0x2b0b, 0xFFFF, (0x3FF00000 | MilkBarMilkPrice | (MilkBarChateauPrice << 10)), 0xff1001, + MilkBarIntro+">3#"+MilkBarMilkItem+MilkSplit+std::to_string(MilkBarMilkPrice)+MilkNext+MilkBarChateauItem+MilkSplit+std::to_string(MilkBarChateauPrice)+MilkLeave, + {QM_GREEN, QM_MAGENTA, QM_GREEN, QM_MAGENTA, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + // CustomMessages::CreateMessage(0x614A, 0xFFFF, (0x3FFFFFFF), 0xff0000, + // {"With all due respect, sir, I think you've had enough of that."}, + // {}, {}, {}, 0x0, false, false, MESSAGE_END_NORMAL); // For refusing purchase + + // Milk Road Gorman Bros Milk + u16 gormanMilkPrice = 50; + CustomMessages::CreateMessageFromTextObject(0x3466, 0xFFFF, (0x3FFFFC00 | gormanMilkPrice), 0xff1001, Text{"#"} + std::to_string(gormanMilkPrice) + Text{ + " Rupees# for one #Mystery Item#&" + } + ">2" + Text{ + "#I'll buy it&No thanks#" + }, {QM_MAGENTA, QM_RED, QM_GREEN}, {}, {}, 0x0, false, false, MESSAGE_END_NULL); + +}; + +void CreateBeanDaddyHint() { + CustomMessages::CreateMessageFromTextObject(0x92f, 0x930, 0x3FFFFFFF, 0xFF0000, Text{ + /*NaEnglish*/"Do you need a #Mysterious Item#? ", + // /*NaFrench */"", + // /*NaSpanish*/"", + // /*EuGerman */"", + // // /*EuItalian*/"", + // /*EuEnglish*/"", + // /*EuFrench */"", + // /*EuSpanish*/"", + }, {QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); +}; + +void CreateScrubPurchaseText() { + //Set initial Scrub Prices + // Location(SOUTHERN_SWAMP_SCRUB_PURCHASE)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 SwampPrice = 10;// Location(SOUTHERN_SWAMP_SCRUB_PURCHASE)->GetPrice(); + // Location(GORON_VILLAGE_SCRUB_PURCHASE)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 GoronPrice = 200;// Location(GORON_VILLAGE_SCRUB_PURCHASE)->GetPrice(); + // Location(ZORA_HALL_SCRUB_PURCHASE)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 ZoraPrice = 40;// Location(ZORA_HALL_SCRUB_PURCHASE)->GetPrice(); + // Location(IKANA_CANYON_SCRUB_PURCHASE)->SetShopsanityPrice(static_cast(GetShopPrice())); + u16 IkanaPrice = 100;// Location(IKANA_CANYON_SCRUB_PURCHASE)->GetPrice(); + + Text RupeeText{" Rupees#", " rubis#", " rupias#", " Rubine#",/* " rupie#",*/ }; + Text ScrubSellTextOne = Text{ + /*NaEnglish*/"So, I'll sell you #" , + // /*NaFrench */"", + // /*NaSpanish*/"", + // /*EuGerman */"", + // // /*EuItalian*/"", + // /*EuEnglish*/"", + // /*EuFrench */"", + // /*EuSpanish*/"", + }; + Text ScrubSellTextTwo = Text{ + /*NaEnglish*/"# for #", + // /*NaFrench */"", + // /*NaSpanish*/"", + // /*EuGerman */"", + // // /*EuItalian*/"", + // /*EuEnglish*/"", + // /*EuFrench */"", + // /*EuSpanish*/"", + }; + + //Set prices on moved Scrub locations + Location(SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR)->SetShopsanityPrice(SwampPrice); + Location(S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE)->SetShopsanityPrice(SwampPrice); + Location(GORON_VILLAGE_SCRUB_PURCHASE_SPRING)->SetShopsanityPrice(GoronPrice); + Location(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE)->SetShopsanityPrice(GoronPrice); + Location(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR)->SetShopsanityPrice(GoronPrice); + Location(GORON_VILLAGE_ZORA_SCRUB_PURCHASE)->SetShopsanityPrice(ZoraPrice); + Location(GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING)->SetShopsanityPrice(ZoraPrice); + Location(ZORA_HALL_IKANA_SCRUB_PURCHASE)->SetShopsanityPrice(IkanaPrice); + + Text SwampScrubSellText = ScrubSellTextOne + ItemTable(Location(SOUTHERN_SWAMP_SCRUB_PURCHASE)->GetPlacedItemKey()).GetHint().GetText() + + ScrubSellTextTwo + std::to_string(SwampPrice) + RupeeText + Text{" if you know how to use #Magic Beans#."}; + CustomMessages::CreateMessageFromTextObject(0x15E9, 0xFFFF, 0x3FFFFFFF, 0xFF0000, SwampScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + CustomMessages::CreateMessageFromTextObject(0x15F3, 0xFFFF, 0x3FFFFFFF, 0xFF0000, SwampScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + + // This doesn't require bomb bag, right?? + Text GoronScrubSellText = ScrubSellTextOne + ItemTable(Location(GORON_VILLAGE_SCRUB_PURCHASE)->GetPlacedItemKey()).GetHint().GetText() + + ScrubSellTextTwo + std::to_string(GoronPrice) + RupeeText + Text{" if you have a #Bomb Bag# that can hold #at least 30 bombs#."}; + CustomMessages::CreateMessageFromTextObject(0x1600, 0xFFFF, 0x3FFFFFFF, 0xFF0000, GoronScrubSellText, {QM_RED, QM_MAGENTA, QM_RED, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + CustomMessages::CreateMessageFromTextObject(0x1606, 0xFFFF, 0x3FFFFFFF, 0xFF0000, GoronScrubSellText, {QM_RED, QM_MAGENTA, QM_RED, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + + Text ZoraScrubSellText = ScrubSellTextOne + ItemTable(Location(ZORA_HALL_SCRUB_PURCHASE)->GetPlacedItemKey()).GetHint().GetText() + + ScrubSellTextTwo + std::to_string(ZoraPrice) + RupeeText + Text{" if you have an #Empty Bottle#."}; + CustomMessages::CreateMessageFromTextObject(0x1612, 0xFFFF, 0x3FFFFFFF, 0xFF0000, ZoraScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + CustomMessages::CreateMessageFromTextObject(0x1617, 0xFFFF, 0x3FFFFFFF, 0xFF0000, ZoraScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + + Text IkanaScrubSellText = ScrubSellTextOne + ItemTable(Location(IKANA_CANYON_SCRUB_PURCHASE)->GetPlacedItemKey()).GetHint().GetText() + + ScrubSellTextTwo + std::to_string(IkanaPrice) + RupeeText + Text{" if you have an #Empty Bottle#."}; + CustomMessages::CreateMessageFromTextObject(0x1626, 0xFFFF, 0x3FFFFFFF, 0xFF0000, IkanaScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); + CustomMessages::CreateMessageFromTextObject(0x162D, 0xFFFF, 0x3FFFFFFF, 0xFF0000, IkanaScrubSellText, {QM_RED, QM_MAGENTA, QM_RED}, {}, {}, 0x0, false, false, MESSAGE_END_EVENTNEXT); +}; + void CreateOtherHints() { // Create other hints for various texts @@ -897,6 +1178,12 @@ static Text BuildCountReq(const HintKey req, const Option& count) { void CreateAllHints() { //CreateGanonText(); + // if (Settings::ShuffleMagicBeans) { + // CreateBeanDaddyHint(); + // } + if (Scrubsanity) { + CreateScrubPurchaseText(); + } PlacementLog_Msg("\nNOW CREATING HINTS\n"); const HintSetting& hintSetting = hintSettingTable[Settings::HintDistribution.Value()]; diff --git a/source/include/hints.hpp b/source/include/hints.hpp index 193989b..fdda974 100644 --- a/source/include/hints.hpp +++ b/source/include/hints.hpp @@ -168,4 +168,5 @@ extern void CreateAllHints(); extern void CreateTingleHintText(); extern void CreateClockTowerDoorHints(); extern void CreateMoonChildHint(); -extern void CreateOtherHints(); \ No newline at end of file +extern void CreateOtherHints(); +extern void CreateShopMessages(); \ No newline at end of file diff --git a/source/include/item_location.hpp b/source/include/item_location.hpp index e28a8f8..3e94c86 100644 --- a/source/include/item_location.hpp +++ b/source/include/item_location.hpp @@ -37,7 +37,8 @@ enum class ItemLocationType { HintStone, OtherHint, Misc, - Cow + Cow, + Shop }; class SpoilerCollectionCheck { @@ -91,8 +92,8 @@ class SpoilerCollectionCheck { return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SCRUB, scene, bit); } - static auto ShopItem(u8 scene, u8 itemSlot) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM, scene, itemSlot); + static auto Shop(u8 scene, u8 itemSlot) { + return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP, scene, itemSlot); } static auto MagicBeans(u8 scene, u8 flag) { @@ -139,6 +140,7 @@ class ItemLocation { //TO-DO else if (type == ItemLocationType::StrayFairy) {key.type = ItemOverride_Type::OVR_STRAY_FAIRY;} else if (type == ItemLocationType::Cow) {key.type = ItemOverride_Type::OVR_COW;} + else if (type == ItemLocationType::Shop) {key.type = ItemOverride_Type::OVR_SHOP;} //else if (type == ItemLocationType::HintStone) {key.type = ItemOverride_Type::OVR_HINT;} //else if (type == ItemLocationType::OtherHint) {key.type = ItemOverride_Type::OVR_OTHER_HINT;} //key.type = type; //TODO make sure these match up @@ -179,6 +181,7 @@ class ItemLocation { else if (type == ItemLocationType::TempleReward) {ovrtype = ItemOverride_Type::OVR_TEMPLE;} else if (type == ItemLocationType::StrayFairy) {ovrtype = ItemOverride_Type::OVR_STRAY_FAIRY;} else if (type == ItemLocationType::Cow) {ovrtype = ItemOverride_Type::OVR_COW;} + else if (type == ItemLocationType::Shop) {ovrtype = ItemOverride_Type::OVR_SHOP;} return ovrtype; } @@ -225,7 +228,7 @@ class ItemLocation { void SetPlacedItem(const ItemKey item) { placedItem = item; - //SetPrice(ItemTable(placedItem).GetPrice()); + SetPrice(ItemTable(placedItem).GetPrice()); } //Saves an item to be set as placedItem later @@ -406,6 +409,10 @@ class ItemLocation { return ItemLocation{ ItemLocationType::Cow, scene, flag, repeatable, std::move(name), hintKey, vanillaItem, std::move(categories), 0 , SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COW,scene, flag), collectionCheckGroup}; } + static auto Shop(u8 scene, u8 flag, bool repeatable, std::string&& name, const HintKey hintKey, const ItemKey vanillaItem, std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { + return ItemLocation{ ItemLocationType::Shop, scene, flag, repeatable, std::move(name), hintKey, vanillaItem, std::move(categories), 0 , SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP,scene, flag), collectionCheckGroup}; + } + void ResetVariables() { checked = false; addedToPool = false; @@ -453,7 +460,7 @@ void LocationTable_Init(); ItemLocation* Location(LocationKey locKey); -//extern std::vector> ShopLocationLists; +extern std::vector> ShopLocationLists; extern std::vector gossipStoneLocations; diff --git a/source/include/keys.hpp b/source/include/keys.hpp index 8e7f45e..e1393c1 100644 --- a/source/include/keys.hpp +++ b/source/include/keys.hpp @@ -186,6 +186,7 @@ typedef enum { HEART_CONTAINER, ICE_TRAP, MILK, + CHATEAU_ROMANI_REFILL, BOMBS_5, BOMBS_10, @@ -280,6 +281,7 @@ typedef enum { //Goron Village GORON_VILLAGE_POWDER_KEG_CHALLENGE, GORON_VILLAGE_SCRUB_PURCHASE, + GORON_VILLAGE_ZORA_SCRUB_PURCHASE, GORON_VILLAGE_LENS_OF_TRUTH_CHEST, GORON_VILLAGE_SCRUB_TRADE, GORON_VILLAGE_LEDGE, @@ -287,6 +289,7 @@ typedef enum { LENS_CAVE_PURPLE_RUPEE, GORON_VILLAGE_POWDER_KEG_CHALLENGE_SPRING, GORON_VILLAGE_SCRUB_PURCHASE_SPRING, + GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, GORON_VILLAGE_SCRUB_TRADE_SPRING, GORON_VILLAGE_LEDGE_SPRING, GORON_SHOP_ITEM_1, @@ -391,6 +394,7 @@ typedef enum { DOGGY_RACETRACK_ROOF_CHEST, //S Clock Town S_CLOCK_TOWN_SCRUB_TRADE, + S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, S_CLOCK_TOWN_POSTBOX, S_CLOCK_TOWN_CLOCK_TOWER_ENTRANCE, S_CLOCK_TOWN_STRAW_ROOF_CHEST, @@ -416,6 +420,8 @@ typedef enum { SOUTHERN_SWAMP_PICTOGRAPH_GOOD, SOUTHERN_SWAMP_SCRUB_PURCHASE, SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR, + SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, + SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, SOUTHERN_SWAMP_SCRUB_TRADE_CLEAR, SWAMP_TOURIST_CENTER_ROOF_CLEAR, POTION_SHOP_ITEM_1, @@ -499,6 +505,7 @@ typedef enum { ZORA_HALL_EVAN, ZORA_HALL_LULU_ROOM_LEDGE, ZORA_HALL_SCRUB_PURCHASE, + ZORA_HALL_IKANA_SCRUB_PURCHASE, ZORA_HALL_STAGE_LIGHTS, ZORA_HALL_BAD_PHOTO_LULU, ZORA_HALL_GOOD_PHOTO_LULU, diff --git a/source/include/logic.hpp b/source/include/logic.hpp index aede534..c1f85a4 100644 --- a/source/include/logic.hpp +++ b/source/include/logic.hpp @@ -331,6 +331,11 @@ namespace Logic { extern bool Milk; extern bool SpokeToKafei; extern bool PostedKafeiLetter; + extern bool CanTradeTownDeed; + extern bool CanTradeSwampDeed; + extern bool CanTradeMountainDeed; + extern bool CanTradeOceanDeed; + extern bool CanBuyBeans; extern bool CanGoToMoon; extern bool RemainsForMoon; diff --git a/source/include/setting_descriptions.hpp b/source/include/setting_descriptions.hpp index c3fa332..865aebc 100644 --- a/source/include/setting_descriptions.hpp +++ b/source/include/setting_descriptions.hpp @@ -123,12 +123,9 @@ extern string_view fastElegyStatuesDesc; extern string_view skipSongReplaysDesc; extern string_view shopsOff; -extern string_view shopsZero; -extern string_view shopsOne; -extern string_view shopsTwo; -extern string_view shopsThree; -extern string_view shopsFour; -extern string_view shopsRandom; +extern string_view shopsOn; +extern string_view shopPricesRandom; +extern string_view shopPricesAffordable; extern string_view tokensOff; extern string_view tokensDungeon; @@ -136,9 +133,7 @@ extern string_view tokensOverworld; extern string_view tokensAllTokens; extern string_view scrubsOff; -extern string_view scrubsAffordable; -extern string_view scrubsExpensive; -extern string_view scrubsRandomPrices; +extern string_view scrubsOn; extern string_view shuffleCowsDesc; @@ -230,6 +225,7 @@ extern string_view skipHMSCutsceneDesc; extern string_view skipDarmaniCutsceneDesc; extern string_view skipMikauCutsceneDesc; extern string_view skipGiantCutsceneDesc; +extern string_view skipPirateCutsceneDesc; extern string_view skipBombersMinigameDesc; extern string_view NARegionDesc; extern string_view EURegionDesc; @@ -247,4 +243,15 @@ extern string_view startingSwordGildedDesc; extern string_view startingShieldNoneDesc; extern string_view startingShieldHerosDesc; extern string_view startingShieldMirrorDesc; -extern string_view showPostmanItemDesc; \ No newline at end of file +extern string_view showPostmanItemDesc; + +extern string_view ingameLTargetingDesc; +extern string_view ingameFirstPersonCameraDesc; +extern string_view ingameFreeCameraDesc; +extern string_view ingameMotionControlsDesc; +extern string_view ingameSwimmingControlsDesc; +extern string_view ingameAdjustVolumeDesc; +extern string_view ingameMuteSoundDesc; +extern string_view ingameMuteBGMDesc; +extern string_view ingameFastSongsDesc; +extern string_view ingameShuffleSFXDesc; \ No newline at end of file diff --git a/source/include/settings.hpp b/source/include/settings.hpp index 3292c28..9864a7d 100644 --- a/source/include/settings.hpp +++ b/source/include/settings.hpp @@ -414,6 +414,7 @@ namespace Settings { extern Option ShuffleMagicBeans; extern Option ShuffleKokiriSword; extern Option Shopsanity; + extern Option ShopsanityPrices; extern Option Tokensanity; extern Option Scrubsanity; extern Option ShuffleCows; @@ -569,6 +570,13 @@ namespace Settings { //Custom Buttons extern Menu customInputs; extern std::vector customButtons; + extern Option IngameLTargeting; + extern Option IngameFirstPersonCamera; + extern Option IngameFreeCamera; + extern Option IngameMotionControls; + extern Option IngameSwimmingControls; + extern Option IngameAdjustVolume; + extern Option CustomMapButton; extern Option CustomItemsButton; extern Option CustomMasksButton; diff --git a/source/include/shops.hpp b/source/include/shops.hpp new file mode 100644 index 0000000..4641c3c --- /dev/null +++ b/source/include/shops.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "item.hpp" +#include "item_location.hpp" + +#include +#include +#include + +struct ItemAndPrice { + Text Name; + int Price; + bool Repurchaseable; +}; + +extern void PlaceVanillaShopItems(); +extern int GetShopPrice(); +extern s16 GetRandomScrubPrice(); +extern Text GetIceTrapName(u8 id); +extern int GetShopIndex(LocationKey loc); +extern void ResetNonShopItems(); + +extern std::vector NonShopItems; \ No newline at end of file diff --git a/source/item.cpp b/source/item.cpp index 4218504..40882fe 100644 --- a/source/item.cpp +++ b/source/item.cpp @@ -67,7 +67,7 @@ ItemOverride_Value Item::Value() const { //if (!Settings::ColoredBossKeys && (getItemId >= 0x95 && getItemId <= 0x9A)) { //Boss keys // val.looksLikeItemId = (u32)GetItemID::GI_KEY_BOSS; //} - //if (!Settings::ColoredKeys && (getItemId >= 0xAF && getItemId <= 0xB7)) { //Small keys + //if (!Settings::ColoredKeys && (getItemId == 0x76 || getItemId == 0x77 || getItemId == 0x90 || getItemId == 0xA2)) { //Small keys // val.looksLikeItemId = (u32)GetItemID::GI_KEY_SMALL; //} if (type == ITEMTYPE_SHOP) { diff --git a/source/item_list.cpp b/source/item_list.cpp index 3c6a606..5c00085 100644 --- a/source/item_list.cpp +++ b/source/item_list.cpp @@ -14,8 +14,8 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth itemTable[NONE] = Item(false, false, &noVariable, Text{"No Item", "Rien", "Sin Objeto", "Kein Item", }, NONE, (u32)GetItemID::GI_NONE, ITEMTYPE_EVENT); itemTable[KOKIRI_SWORD] = Item(true, false, &KokiriSword, Text{"Kokiri Sword", "Épée Kokiri", "Espada Kokiri", "Kokiri-Schwert", }, KOKIRI_SWORD, (u32)GetItemID::GI_KOKIRI_SWORD, ITEMTYPE_ITEM); itemTable[GREAT_FAIRYS_SWORD] = Item(true, false, &GreatFairySword, Text{"Great Fairy's Sword", "Épée de la grande fée", "Espada de la Gran Hada", "Feenschwert", "", "Grande épée des fées", "" }, GREAT_FAIRYS_SWORD, (u32)GetItemID::GI_GREAT_FAIRY_SWORD, ITEMTYPE_GFAIRY); - itemTable[HEROS_SHIELD] = Item(false, false, &HerosShield, Text{"Heros Shield", "Bouclier du Héros", "Escudo del Héroe", "Heroen-Schild", }, HEROS_SHIELD, (u32)GetItemID::GI_SHIELD_HERO, ITEMTYPE_ITEM); - itemTable[DEKU_STICK] = Item(true, false, &DekuStick, Text{"Deku Stick", "Bâton Mojo", "Palo deku", "Deku-Stab", }, DEKU_STICK, (u32)GetItemID::GI_STICKS_1, ITEMTYPE_ITEM); + itemTable[HEROS_SHIELD] = Item(false, false, &HerosShield, Text{"Hero's Shield", "Bouclier du Héros", "Escudo del Héroe", "Heroen-Schild", }, HEROS_SHIELD, (u32)GetItemID::GI_SHIELD_HERO, ITEMTYPE_REFILL); + itemTable[DEKU_STICK] = Item(true, false, &DekuStick, Text{"Deku Stick", "Bâton Mojo", "Palo deku", "Deku-Stab", }, DEKU_STICK, (u32)GetItemID::GI_STICKS_1, ITEMTYPE_REFILL); itemTable[LAND_TITLE] = Item(true, true, &LandTitle, Text{"Land Title Deed", "Titre de terre", "Escritura de propiedad de la Ciudad", "Land-Urkunde", }, LAND_TITLE, (u32)GetItemID::GI_TOWN_TITLE_DEED, ITEMTYPE_TRADE); itemTable[SWAMP_TITLE] = Item(true, true, &SwampTitle, Text{"Swamp Title Deed", "Titre de marais", "Escritura de propiedad del Pantano", "Sumpf-Urkunde", }, SWAMP_TITLE, (u32)GetItemID::GI_SWAMP_TITLE_DEED, ITEMTYPE_TRADE); itemTable[MOUNTAIN_TITLE] = Item(true, true, &MountainTitle, Text{"Mountain Title Deed", "Titre de montagne", "Escritura de propiedad de la Montañaa", "Berg-Urkunde", }, MOUNTAIN_TITLE, (u32)GetItemID::GI_MOUNTAIN_TITLE_DEED, ITEMTYPE_TRADE); @@ -33,12 +33,12 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth itemTable[ICE_ARROWS] = Item(true, false, &IceArrows, Text{"Ice Arrow", "Flèche de glace", "Flecha de hielo", "Eispfeile", }, ICE_ARROWS, (u32)GetItemID::GI_ICE_ARROW, ITEMTYPE_ITEM); itemTable[LIGHT_ARROWS] = Item(true, false, &LightArrows, Text{"Light Arrow", "Flèche de lumière", "Flecha de luz", "Lichtpfeile", }, LIGHT_ARROWS, (u32)GetItemID::GI_LIGHT_ARROW, ITEMTYPE_ITEM); itemTable[HOOKSHOT] = Item(true, false, &Hookshot, Text{"Hookshot", "Grappin", "Gancho", "Fanghaken", }, HOOKSHOT, (u32)GetItemID::GI_HOOKSHOT, ITEMTYPE_ITEM); - itemTable[MAGIC_BEAN] = Item(true, false, &MagicBean, Text{"Magic Bean", "Haricot magique", "Habichuelas mágicas", "Wundererbse", }, MAGIC_BEAN, (u32)GetItemID::GI_MAGIC_BEAN, ITEMTYPE_ITEM); + itemTable[MAGIC_BEAN] = Item(true, false, &MagicBean, Text{"Magic Bean", "Haricot magique", "Habichuelas mágicas", "Wundererbse", }, MAGIC_BEAN, (u32)GetItemID::GI_MAGIC_BEAN, ITEMTYPE_REFILL); itemTable[MAGIC_BEAN_PACK] = Item(true, false, &MagicBeanPack, Text{"Magic Bean Pack", "Paquet de haricots magiques", "Lote de habichuelas mágicas", "Wundererbsen-Paket", }, MAGIC_BEAN_PACK, (u32)GetItemID::GI_MAGIC_BEAN, ITEMTYPE_ITEM); itemTable[DOUBLE_DEFENSE] = Item(true, false, &noVariable, Text{"Double Defense", "Résistance Double", "Poder defensivo doble", "Verstärkter Rüstungsschutz", }, DOUBLE_DEFENSE, 0xB2, ITEMTYPE_GFAIRY); itemTable[OCARINA_OF_TIME] = Item(true, false, &Ocarina, Text{"Ocarina of Time", "Ocarina du temps", "Ocarina del Tiempo", "Ocarina der Zeit", }, OCARINA_OF_TIME, (u32)GetItemID::GI_OCARINA_OF_TIME, ITEMTYPE_ITEM); itemTable[PICTOGRAPH_BOX] = Item(true, false, &Pictobox, Text{"Pictograph Box", "Boite à image", "Caja Luminográfica", "Fotobox", }, PICTOGRAPH_BOX, (u32)GetItemID::GI_PICTOGRAPH_BOX, ITEMTYPE_ITEM); - itemTable[POWDER_KEG] = Item(true, false, &PowderKeg, Text{"Powder Keg", "Baril de poudre", "Barril de Pólvora", "Pulverfass", }, POWDER_KEG, (u32)GetItemID::GI_POWDER_KEG, ITEMTYPE_ITEM); + itemTable[POWDER_KEG] = Item(true, false, &PowderKeg, Text{"Powder Keg", "Baril de poudre", "Barril de Pólvora", "Pulverfass", }, POWDER_KEG, (u32)GetItemID::GI_POWDER_KEG, ITEMTYPE_REFILL); itemTable[KEATON_MASK] = Item(true, false, &KeatonMask, Text{"Keaton Mask", "Masque de keaton", "Máscara Keaton", "Fuchsmaske", "", "Masque de renard", "" }, KEATON_MASK, (u32)GetItemID::GI_MASK_KEATON, ITEMTYPE_MASK); itemTable[BUNNY_HOOD] = Item(true, false, &BunnyHood, Text{"Bunny Hood", "Capuchon de lapin", "Capucha de conejo", "Hasenohren", "", "Masque de lapin", "" }, BUNNY_HOOD, (u32)GetItemID::GI_MASK_BUNNY_HOOD, ITEMTYPE_MASK); itemTable[GORON_MASK] = Item(true, false, &GoronMask, Text{"Goron Mask", "Masque goron", "Máscara Goron", "Goronen-Haut", }, GORON_MASK, (u32)GetItemID::GI_MASK_GORON, ITEMTYPE_MASK); @@ -98,7 +98,7 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth itemTable[CHATEAU_ROMANI] = Item(true, false, &ChateauBottle, Text{"Chateau Romani", "Cuvée Romani", "Reserva Romani", "Chateau Romani", }, CHATEAU_ROMANI, (u32)GetItemID::GI_BOTTLE_CHATEAU_ROMANI, ITEMTYPE_ITEM); itemTable[BOTTLE_WITH_MYSTERY_MILK] = Item(true, true, &MysteryMilkBottle, Text{"Bottle with Mystery Milk", "Flacon de lait mystère", "Botella de leche sospechosa", "Flasche mit verdächtiger Milch", "", "Flacon de lait suspect", "" }, BOTTLE_WITH_MYSTERY_MILK, (u32)GetItemID::GI_BOTTLE_MYSTERY_MILK, ITEMTYPE_QUEST); //Other bottle items - itemTable[DEKU_PRINCESS] = Item(true, true, &DekuPrincess, Text{"Deku Princess", "Princesse Mojo", "Princesa Deku", "Deku-Prinzessin", }, DEKU_PRINCESS, (u32)GetItemID::GI_DEKU_PRINCESS_FAIRY, ITEMTYPE_ITEM); + itemTable[DEKU_PRINCESS] = Item(true, true, &DekuPrincess, Text{"Deku Princess", "Princesse Mojo", "Princesa Deku", "Deku-Prinzessin", }, DEKU_PRINCESS, (u32)GetItemID::GI_DEKU_PRINCESS_FAIRY, ITEMTYPE_REFILL); itemTable[BOTTLE_WITH_GREEN_POTION] = Item(false, false, &HasBottle, Text{"Bottle with Green Potion", "Flacon de potion verte", "Botella de poción verde", "Flasche mit grünem Elixir", }, BOTTLE_WITH_GREEN_POTION, (u32)GetItemID::GI_POTION_GREEN, ITEMTYPE_ITEM); itemTable[BOTTLE_WITH_BLUE_POTION] = Item(false, false, &HasBottle, Text{"Bottle with Blue Potion", "Flacon de potion bleue", "Botella de poción azul", "Flasche mit blauem Elixir", }, BOTTLE_WITH_BLUE_POTION, (u32)GetItemID::GI_POTION_BLUE, ITEMTYPE_ITEM); itemTable[BOTTLE_WITH_FAIRY] = Item(false, false, &HasBottle, Text{"Bottle with Fairy", "Fée en flacon", "Botella con hada", "Flasche mit einer kleinen Fee", }, BOTTLE_WITH_FAIRY, (u32)GetItemID::GI_FAIRY, ITEMTYPE_ITEM); @@ -111,7 +111,7 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth itemTable[BOTTLE_WITH_ZORA_EGG] = Item(false, true, &HasBottle, Text{"Bottle with Zora Egg", "Œuf de Zora en flacon", "Botella con huevo Zora", "Flasche mit einem Zora-Ei", }, BOTTLE_WITH_ZORA_EGG, (u32)GetItemID::GI_BOTTLE_ZORA_EGG, ITEMTYPE_ITEM); itemTable[BOTTLE_WITH_MUSHROOM] = Item(false, false, &HasBottle, Text{"Bottle with Mushroom", "Champignon magique en flacon", "Botella con champiñón mágico", "Flasche mit magischem Pilz", }, BOTTLE_WITH_MUSHROOM, (u32)GetItemID::GI_BOTTLE_MAGIC_MUSHROOM, ITEMTYPE_ITEM); itemTable[ZORA_EGG] = Item(false, true, &ZoraEgg, Text{"Zora Egg", "Œuf de Zora", "Huevo Zora", "Zora-Ei", }, ZORA_EGG, (u32)GetItemID::GI_BOTTLE_ZORA_EGG, ITEMTYPE_ITEM); - itemTable[SEAHORSE] = Item(true, true, &Seahorse, Text{"Seahorse", "Hippocampe", "Caballo de mar", "Seepferdchen", }, SEAHORSE, (u32)GetItemID::GI_BOTTLE_SEAHORSE, ITEMTYPE_ITEM); + itemTable[SEAHORSE] = Item(true, true, &Seahorse, Text{"Seahorse", "Hippocampe", "Caballo de mar", "Seepferdchen", }, SEAHORSE, (u32)GetItemID::GI_BOTTLE_SEAHORSE, ITEMTYPE_REFILL); //Upgrades itemTable[RAZOR_SWORD] = Item(true, false, &RazorSword, Text{"Razor Sword", "Lame Rasoir", "Espada Afilada", "Elfenschwert", }, RAZOR_SWORD, (u32)GetItemID::GI_RAZOR_SWORD, ITEMTYPE_ITEM); @@ -180,7 +180,7 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth //itemTable[PRE_CLOCK_TOWN_CHEST] = Item(false,0, &noVariable, Text{ "Deku Nuts (10)", "Noix Mojo (10)", "Nueces deku (10)" }, "Pre-Clock Town Chest", Region::BeneathClockTown, PRE_CLOCK_TOWN_CHEST, (u32)GetItemID::GI_NUTS_10, ItemCategory::DekuNuts, LocationCategory::GlitchesRequired); //Generic Items - itemTable[RECOVERY_HEART] = Item(false, false, &noVariable, Text{"Recovery Heart", "Cœur de vie", "Corazón", "Herz", }, RECOVERY_HEART, (u32)GetItemID::GI_RECOVERY_HEART_SINGLE, ITEMTYPE_ITEM); + itemTable[RECOVERY_HEART] = Item(false, false, &noVariable, Text{"Recovery Heart", "Cœur de vie", "Corazón", "Herz", }, RECOVERY_HEART, (u32)GetItemID::GI_RECOVERY_HEART_SINGLE, ITEMTYPE_REFILL); itemTable[GREEN_RUPEE] = Item(false, false, &noVariable, Text{"Green Rupee", "Rubis vert", "Rupia verde", "Grüner Rubin", }, GREEN_RUPEE, (u32)GetItemID::GI_RUPEE_GREEN, ITEMTYPE_ITEM); itemTable[BLUE_RUPEE] = Item(false, false, &noVariable, Text{"Blue Rupee", "Rubis bleu", "Rupia azul", "Blauer Rubin", }, BLUE_RUPEE, (u32)GetItemID::GI_RUPEE_BLUE, ITEMTYPE_ITEM); itemTable[RED_RUPEE] = Item(false, false, &noVariable, Text{"Red Rupee", "Rubis rouge", "Rupia roja", "Roter Rubin", }, RED_RUPEE, (u32)GetItemID::GI_RUPEE_RED, ITEMTYPE_ITEM); @@ -190,7 +190,8 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth itemTable[PIECE_OF_HEART] = Item(true, false, &PiecesOfHeart, Text{"Piece of Heart", "Quart de cœur", "Pieza de corazón", "Herzteil", "", "Fragment de cœur", "" }, PIECE_OF_HEART, (u32)GetItemID::GI_HEART_PIECE, ITEMTYPE_ITEM); itemTable[HEART_CONTAINER] = Item(true, false, &HeartContainers, Text{"Heart Container", "Réceptacle de cœur", "Contenedor de corazón", "Herzcontainer", }, HEART_CONTAINER, (u32)GetItemID::GI_HEART_CONTAINER, ITEMTYPE_ITEM); itemTable[ICE_TRAP] = Item(false, false, &noVariable, Text{"Ice Trap", "Piège de glace", "Trampa de hielo", "Eis-Falle", }, ICE_TRAP, 0x12, ITEMTYPE_ITEM); - itemTable[MILK] = Item(false, false, &HasBottle, Text{"Milk", "Lait", "Leche", "Milch", }, NONE, 0x92, ITEMTYPE_ITEM); + itemTable[MILK] = Item(false, false, &HasBottle, Text{"Milk", "Lait", "Leche", "Milch", }, NONE, 0x92, ITEMTYPE_REFILL); + itemTable[CHATEAU_ROMANI_REFILL] = Item(false, false, &HasBottle, Text{"Chateau Romani Refill", "Cuvée Romani", "Reserva Romani", "Chateau Romani", }, CHATEAU_ROMANI_REFILL, 0x91, ITEMTYPE_REFILL); //Refills itemTable[BOMBS_5] = Item(false, false, &noVariable, Text{"Bombs (5)", "Bombes (5)", "Bombas (5)", "5 Bomben", }, BOMBS_5, (u32)GetItemID::GI_BOMBS_5, ITEMTYPE_REFILL); @@ -227,7 +228,7 @@ void ItemTable_Init() { //repeatable denotes that an item in a vanilla playth //Progressive Items itemTable[PROGRESSIVE_SWORD] = Item(true, false, &ProgressiveSword, Text{"Progressive Sword", "Lame (prog.)", "Espada progresiva", "Schwert-Upgrade", }, PROGRESSIVE_SWORD, 0x4A, ITEMTYPE_ITEM); itemTable[PROGRESSIVE_BOMB_BAG] = Item(true, false, &ProgressiveBombBag, Text{"Progressive Bomb Bag", "Sac de bombes (prog.)", "Saco de bombas progresivo", "Bombentaschen-Upgrade", }, PROGRESSIVE_BOMB_BAG, 0x46, ITEMTYPE_ITEM); - itemTable[PROGRESSIVE_BOW] = Item(true, false, &ProgressiveBow, Text{"Progressive Bow", "Arc (prog.)", "Arco progresivo", "Köcher-Upgrade", }, PROGRESSIVE_BOW, 0x47, ITEMTYPE_ITEM); + itemTable[PROGRESSIVE_BOW] = Item(true, false, &ProgressiveBow, Text{"Progressive Bow", "Arc (prog.)", "Arco progresivo", "Bogen-Upgrade", }, PROGRESSIVE_BOW, 0x47, ITEMTYPE_ITEM); itemTable[PROGRESSIVE_WALLET] = Item(true, false, &ProgressiveWallet, Text{"Progressive Wallet", "Bourse (prog.)", "Bolsa de rupias progresiva", "Geldbörsen-Upgrade", }, PROGRESSIVE_WALLET, 0x48, ITEMTYPE_ITEM); itemTable[PROGRESSIVE_MAGIC_METER] = Item(true, false, &ProgressiveMagic, Text{"Progressive Magic Meter", "Jauge de magie (prog)", "Poder mágico progresivo", "Magie-Upgrade", "", "Capacité de magie (prog.)", "" }, PROGRESSIVE_MAGIC_METER, 0x49, ITEMTYPE_GFAIRY); itemTable[PROGRESSIVE_LULLABY] = Item(true, false, &ProgressiveLullaby, Text{"Progressive Lullaby", "Berceuse (prog.)", "Canción de cuna progresiva", "Schlummerlied-Upgrade", }, PROGRESSIVE_LULLABY, 0x45, ITEMTYPE_SONG); diff --git a/source/item_location.cpp b/source/item_location.cpp index 1c691b7..dbe1a26 100644 --- a/source/item_location.cpp +++ b/source/item_location.cpp @@ -3,7 +3,7 @@ #include "dungeon.hpp" #include "settings.hpp" #include "spoiler_log.hpp" -//#include "shops.hpp" +#include "shops.hpp" #include "debug.hpp" #include "keys.hpp" #include "fill.hpp" @@ -26,7 +26,7 @@ void LocationTable_Init() { locationTable[HMS_STARTING_SHIELD] = ItemLocation::Base (0x00, 0x32, false, "Starting Shield", HMS_STARTING_SHIELD, HEROS_SHIELD, {Category::cClockTower, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(6), SpoilerCollectionCheckGroup::GROUP_NO_GROUP ); //Deku Palace - locationTable[DEKU_PALACE_BEAN_SELLER] = ItemLocation::Base (0x07, 0x35, true, "DP Bean Seller", DEKU_PALACE_BEAN_SELLER, MAGIC_BEAN, {Category::cDekuPalace,Category::cWoodfall,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_DEKU_PALACE ); + locationTable[DEKU_PALACE_BEAN_SELLER] = ItemLocation::Base (0x07, 0x35, true, "DP Bean Seller", DEKU_PALACE_BEAN_SELLER, MAGIC_BEAN_PACK, {Category::cDekuPalace,Category::cWoodfall,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_DEKU_PALACE ); locationTable[DEKU_PALACE_WEST_GARDEN] = ItemLocation::Collectable(0x2B, 0x00, false, "DP West Garden", DEKU_PALACE_WEST_GARDEN, PIECE_OF_HEART, {Category::cDekuPalace,Category::cWoodfall, Category::cFreestandingItems, Category::cVanillaHeartPiece,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_DEKU_PALACE ); locationTable[DEKU_PALACE_BUTLER_RACE] = ItemLocation::Base (0x52, 0x8E, false, "DP Butler Race", DEKU_PALACE_BUTLER_RACE, MASK_OF_SCENTS, {Category::cDekuPalace,Category::cWoodfall, Category::cVanillaMask,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_DEKU_PALACE ); locationTable[DEKU_PALACE_IMPRISONED_MONKEY] = ItemLocation::Base (0x3E, 0x4B, false, "DP Imprisoned Monkey", DEKU_PALACE_IMPRISONED_MONKEY, SONATA_OF_AWAKENING, {Category::cDekuPalace,Category::cSong,Category::cWoodfall,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_DEKU_PALACE ); @@ -44,8 +44,8 @@ void LocationTable_Init() { locationTable[E_CLOCK_TOWN_AROMA_IN_OFFICE] = ItemLocation::Base (0x12, 0x8F, false, "ECT Mayor's Office Madame Aroma", E_CLOCK_TOWN_AROMA_IN_OFFICE, KAFEIS_MASK, {Category::cEastClockTown, Category::cDayOne, Category::cAnjuAndKafei}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); locationTable[BOMBERS_HIDEOUT_CHEST] = ItemLocation::Chest (0x29, 0x00, true, "Bombers' Hideout Chest", BOMBERS_HIDEOUT_CHEST, SILVER_RUPEE, {Category::cEastClockTown, Category::cChest,Category::cDayOne, Category::cNoOcarinaStart }, SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); locationTable[E_CLOCK_TOWN_CHEST] = ItemLocation::Chest (0x6C, 0x0A, true, "ECT Chest", E_CLOCK_TOWN_CHEST, SILVER_RUPEE, {Category::cEastClockTown, Category::cChest ,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); - //locationTable[E_CLOCK_TOWN_MILK_BAR_CHATEAU] = ItemLocation::Base (0x12, 0x00, true, "Milk Bar Chateau Buy", E_CLOCK_TOWN_MILK_BAR_CHATEAU, CHATEAU_ROMANI, {Category::cEastClockTown}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); - //locationTable[E_CLOCK_TOWN_MILK_BAR_MILK] = ItemLocation::Base (0x12, 0x00, true, "Milk Bar Milk Buy", E_CLOCK_TOWN_MILK_BAR_MILK, MILK, {Category::cEastClockTown}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); + locationTable[E_CLOCK_TOWN_MILK_BAR_CHATEAU] = ItemLocation::Base (0x15, 0x91, true, "Milk Bar Chateau Buy", E_CLOCK_TOWN_MILK_BAR_CHATEAU, CHATEAU_ROMANI_REFILL, {Category::cEastClockTown, Category::cDayOne, Category::cShop}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); + locationTable[E_CLOCK_TOWN_MILK_BAR_MILK] = ItemLocation::Base (0x15, 0x92, true, "Milk Bar Milk Buy", E_CLOCK_TOWN_MILK_BAR_MILK, MILK, {Category::cEastClockTown, Category::cDayOne, Category::cShop}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); //locationTable[E_CLOCK_TOWN_HONEY_DARLING_ANY_DAY] = ItemLocation::Base (0x11, 0x00, true, "Honey and Darling Any Day", E_CLOCK_TOWN_HONEY_DARLING_ANY_DAY, PURPLE_RUPEE, {Category::cEClockTown,Category::cMinigame}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); //locationTable[E_CLOCK_TOWN_TREASURE_CHEST_GAME_HUMAN] = ItemLocation::Base (0x17, 0x00, true, "Treasure Chest Game (Human)", E_CLOCK_TOWN_TREASURE_CHEST_GAME_HUMAN PURPLE_RUPEE, {Category::cEClockTown,Category::cMinigame,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); //locationTable[E_CLOCK_TOWN_TREASURE_CHEST_GAME_ZORA] = ItemLocation::Base (0x17, 0x00, true, "Treasure Chest Game (Zora)", E_CLOCK_TOWN_TREASURE_CHEST_GAME_ZORA, RED_RUPEE, {Category::cEClockTown,Category::cMinigame ,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_E_CLOCK_TOWN ); @@ -65,6 +65,8 @@ void LocationTable_Init() { locationTable[GORON_VILLAGE_SCRUB_PURCHASE_SPRING] = ItemLocation::Base (0x48, 0x1D, false, "GV Scrub Purchase (Spring)", GORON_VILLAGE_SCRUB_PURCHASE_SPRING, PROGRESSIVE_BOMB_BAG, {Category::cGoronVillage, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cAlternateCheck, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE ); locationTable[GORON_VILLAGE_SCRUB_TRADE_SPRING] = ItemLocation::Base (0x48, 0x99, true, "GV Deku Scrub Merchant Trade (Spring)", GORON_VILLAGE_SCRUB_TRADE_SPRING, MOUNTAIN_TITLE, {Category::cGoronVillage, Category::cDekuScrub,Category::cDayOne, Category::cAlternateCheck, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE ); locationTable[GORON_VILLAGE_LEDGE_SPRING] = ItemLocation::Collectable(0x48, 0x00, false, "GV Piece of Heart (Spring)", GORON_VILLAGE_LEDGE_SPRING, PIECE_OF_HEART, {Category::cGoronVillage, Category::cVanillaHeartPiece,Category::cDayOne, Category::cAlternateCheck, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE ); + locationTable[GORON_VILLAGE_ZORA_SCRUB_PURCHASE] = ItemLocation::Base (0x4D, 0x5C, false, "GV Zora Scrub Purchase", GORON_VILLAGE_ZORA_SCRUB_PURCHASE, GREEN_POTION_REFILL, {Category::cGoronVillage, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE ); + locationTable[GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING] = ItemLocation::Base (0x48, 0x5C, false, "GV Zora Scrub Purchase (Spring)", GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, GREEN_POTION_REFILL, {Category::cGoronVillage, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE ); //Great Bay Coast locationTable[GBC_OCEAN_SPIDER_DAY1] = ItemLocation::Base (0x28, 0x48, false, "OSH Reward", GBC_OCEAN_SPIDER_DAY1, PROGRESSIVE_WALLET, {Category::cGreatBayCoast ,Category::cDayOne, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_GREAT_BAY_COAST ); @@ -168,7 +170,8 @@ void LocationTable_Init() { locationTable[S_CLOCK_TOWN_BANK_REWARD_1] = ItemLocation::Base (0x6F, 0x48, false, "SCT Bank Reward 1 (200)", S_CLOCK_TOWN_BANK_REWARD_1, PROGRESSIVE_WALLET, {Category::cSouthClockTown,Category::cDayOne, Category::cMainInventory, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_S_CLOCK_TOWN ); locationTable[S_CLOCK_TOWN_BANK_REWARD_2] = ItemLocation::Base (0x6F, 0x03, false, "SCT Bank Reward 2 (500)", S_CLOCK_TOWN_BANK_REWARD_2, BLUE_RUPEE, {Category::cSouthClockTown,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_S_CLOCK_TOWN ); locationTable[S_CLOCK_TOWN_BANK_REWARD_3] = ItemLocation::Base (0x6F, 0x0C, false, "SCT Bank Reward 3 (1000)", S_CLOCK_TOWN_BANK_REWARD_3, PIECE_OF_HEART, {Category::cSouthClockTown, Category::cVanillaHeartPiece,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_S_CLOCK_TOWN ); - + locationTable[S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE] = ItemLocation::Base (0x6F, 0x35, true, "SCT Swamp Scrub Purchase", S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, MAGIC_BEAN, {Category::cSouthClockTown, Category::cDekuScrub,Category::cDayOne, Category::cTradeItem, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_S_CLOCK_TOWN ); + //Snowhead locationTable[SNOWHEAD_GREAT_FAIRY] = ItemLocation::Base (0x26, 0x2B, false, "SH Great Fairy", SNOWHEAD_GREAT_FAIRY, PROGRESSIVE_MAGIC_METER, {Category::cSnowhead, Category::cFairyFountain,Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SNOWHEAD ); @@ -191,6 +194,8 @@ void LocationTable_Init() { locationTable[SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR] = ItemLocation::Base (0x00, 0x35, true, "SS Deku Scrub Merchant Purchase (Cleared)", SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR, MAGIC_BEAN, {Category::cSouthernSwamp, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP ); locationTable[SWAMP_TOURIST_CENTER_ROOF_CLEAR] = ItemLocation::Collectable(0x00, 0x00, false, "SS Tourist Center Roof (Cleared)", SWAMP_TOURIST_CENTER_ROOF_CLEAR, PIECE_OF_HEART, {Category::cSouthernSwamp, Category::cVanillaHeartPiece,Category::cDayOne, Category::cAlternateCheck}, SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP ); locationTable[SOUTHERN_SWAMP_SCRUB_TRADE_CLEAR] = ItemLocation::Base (0x00, 0x98, true, "SS Deku Scrub Merchant Trade (Cleared)", SOUTHERN_SWAMP_SCRUB_TRADE_CLEAR, SWAMP_TITLE, {Category::cSouthernSwamp, Category::cDekuScrub,Category::cDayOne,Category::cTradeItem, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP ); + locationTable[SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE] = ItemLocation::Base (0x45, 0x1D, false, "SS Goron Scrub Merchant Purchase", SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, PROGRESSIVE_BOMB_BAG, {Category::cSouthernSwamp, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP ); + locationTable[SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR] = ItemLocation::Base (0x00, 0x1D, false, "SS Goron Scrub Merchant Purchase (Cleared)", SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, PROGRESSIVE_BOMB_BAG, {Category::cSouthernSwamp, Category::cDekuScrub,Category::cDayOne, Category::cShop, Category::cAlternateCheck}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP ); //Stock Pot Inn locationTable[STOCKPOTINN_RESERVATION] = ItemLocation::Base (0x61, 0xA0, true, "SPI Reservation", STOCKPOTINN_RESERVATION, ROOM_KEY, {Category::cStockPotInn,Category::cDayOne, Category::cAnjuAndKafei}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_STOCKPOTINN ); @@ -229,15 +234,13 @@ void LocationTable_Init() { locationTable[TWIN_ISLANDS_CAVE_CHEST] = ItemLocation::Chest (0x5E, 0x00, true, "TI Cave Chest", TWIN_ISLANDS_CAVE_CHEST, RED_RUPEE, {Category::cTwinIslands,Category::cChest ,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_TWIN_ISLANDS ); locationTable[TWIN_ISLANDS_LULLABY_INTRO] = ItemLocation::Base (0x5D, 0x74, false, "TI Lullaby Intro", TWIN_ISLANDS_LULLABY_INTRO, PROGRESSIVE_LULLABY, {Category::cTwinIslands, Category::cSong, Category::cDayOne}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_TWIN_ISLANDS ); //W Clock Town - locationTable[W_CLOCK_TOWN_BOMB_BAG_BUY] = ItemLocation::Base (0x0D, 0x1B, false, "WCT Bomb Bag Purchase", W_CLOCK_TOWN_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown,Category::cDayOne, Category::cShop, Category::cMainInventory, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); - locationTable[W_CLOCK_TOWN_BIG_BOMB_BAG_BUY] = ItemLocation::Base (0x0D, 0x1C, false, "WCT Big Bomb Bag Purchase", W_CLOCK_TOWN_BIG_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown,Category::cDayTwo, Category::cShop, Category::cMainInventory, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); locationTable[W_CLOCK_TOWN_POSTMANS_GAME] = ItemLocation::Base (0x2E, 0x0C, false, "WCT Postman's Game", W_CLOCK_TOWN_POSTMANS_GAME, PIECE_OF_HEART, {Category::cWestClockTown, Category::cVanillaHeartPiece,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); locationTable[W_CLOCK_TOWN_ROSA_SISTERS] = ItemLocation::Base (0x6D, 0x0C, false, "WCT Rosa Sisters", W_CLOCK_TOWN_ROSA_SISTERS, PIECE_OF_HEART, {Category::cWestClockTown, Category::cVanillaHeartPiece,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); locationTable[W_CLOCK_TOWN_SWORDSMANS_SCHOOL] = ItemLocation::Base (0x54, 0x0C, false, "WCT Swordsman's School", W_CLOCK_TOWN_SWORDSMANS_SCHOOL, PIECE_OF_HEART, {Category::cWestClockTown, Category::cVanillaHeartPiece,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); locationTable[W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY] = ItemLocation::Base (0x0D, 0x7E, false, "WCT All-Night Mask Purchase", W_CLOCK_TOWN_ALL_NIGHT_MASK_BUY, ALL_NIGHT_MASK, {Category::cWestClockTown, Category::cVanillaMask,Category::cDayThree}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); //locationTable[W_CLOCK_TOWN_LOTTERY] = ItemLocation::Base (0x39, 0x00, true, "WCT Lottery", W_CLOCK_TOWN_LOTTERY, PURPLE_RUPEE, {Category::cWestClockTown}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); - locationTable[W_CLOCK_TOWN_BOMB_SHOP_GORON] = ItemLocation::Base (0x0D, 0x34, true, "WCT Bomb Shop Goron", W_CLOCK_TOWN_BOMB_SHOP_GORON, POWDER_KEG, {Category::cWestClockTown, Category::cMerchant,Category::cDayOne, Category::cShop, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); - locationTable[W_CLOCK_TOWN_CURIOSITY_BOMB_BAG] = ItemLocation::Base (0x0D, 0x00, true, "WCT Curiosity Shop Bomb Bag", W_CLOCK_TOWN_CURIOSITY_BOMB_BAG, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown, Category::cDayTwo, Category::cShop, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); + locationTable[W_CLOCK_TOWN_BOMB_SHOP_GORON] = ItemLocation::Base (0x0D, 0x34, true, "WCT Bomb Shop Goron", W_CLOCK_TOWN_BOMB_SHOP_GORON, POWDER_KEG, {Category::cWestClockTown, Category::cMerchant,Category::cDayOne, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); + locationTable[W_CLOCK_TOWN_CURIOSITY_BOMB_BAG] = ItemLocation::Base (0x0D, 0x1D, true, "WCT Curiosity Shop Bomb Bag", W_CLOCK_TOWN_CURIOSITY_BOMB_BAG, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown, Category::cDayTwo, Category::cShop, Category::cMainInventory}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); //Woodfall locationTable[WOODFALL_BRIDGE_CHEST] = ItemLocation::Chest (0x46, 0x01, true, "WF Bridge Chest", WOODFALL_BRIDGE_CHEST, PIECE_OF_HEART, {Category::cWoodfall, Category::cVanillaHeartPiece, Category::cChest, Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_WOODFALL ); locationTable[WOODFALL_BEHIND_OWL_CHEST] = ItemLocation::Chest (0x46, 0x02, true, "WF Behind Owl Chest", WOODFALL_BEHIND_OWL_CHEST, BLUE_RUPEE, {Category::cWoodfall,Category::cChest ,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_WOODFALL ); @@ -262,7 +265,7 @@ void LocationTable_Init() { //locationTable[ZORA_HALL_STAGE_LIGHTS] = ItemLocation::Base (0x33, 0x00, true, "ZH Stage Lights", ZORA_HALL_STAGE_LIGHTS, BLUE_RUPEE, {Category::cZoraHall}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL ); //locationTable[ZORA_HALL_BAD_PHOTO_LULU] = ItemLocation::Base (0x4C, 0x00, true, "ZH Bad Photograph of Lulu", ZORA_HALL_SCRUB_TRADE, BLUE_RUPEE, {Category::cZoraHall, Category::cDekuScrub}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL ); //locationTable[ZORA_HALL_GOOD_PHOTO_LULU] = ItemLocation::Base (0x4C, 0x00, true, "ZH Good Photograph of Lulu", ZORA_HALL_SCRUB_TRADE, BLUE_RUPEE, {Category::cZoraHall, Category::cDekuScrub}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL ); - + locationTable[ZORA_HALL_IKANA_SCRUB_PURCHASE] = ItemLocation::Base (0x4C, 0x5D, true, "ZH Deku Scrub Merchant Purchase (Ikana)", ZORA_HALL_IKANA_SCRUB_PURCHASE, BLUE_POTION_REFILL, {Category::cZoraHall, Category::cDekuScrub,Category::cDayOne, Category::cShop}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL ); /*------------------- --- DUNGEONS -- @@ -302,7 +305,7 @@ void LocationTable_Init() { locationTable[STONE_TOWER_TEMPLE_BRIDGE_SWITCH_CHEST] = ItemLocation::Chest (0x16, 0x01, true, "Stone Tower Temple Bridge Switch Chest", STONE_TOWER_TEMPLE_BRIDGE_SWITCH_CHEST, STONE_TOWER_TEMPLE_SMALL_KEY, {Category::cStoneTowerTemple, Category::cVanillaSmallKey,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); locationTable[STONE_TOWER_TEMPLE_UPDRAFT_ROOM_CHEST] = ItemLocation::Chest (0x18, 0x04, true, "Stone Tower Temple Updraft Room Chest", STONE_TOWER_TEMPLE_UPDRAFT_ROOM_CHEST, STONE_TOWER_TEMPLE_SMALL_KEY, {Category::cStoneTowerTemple, Category::cVanillaSmallKey,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); locationTable[STONE_TOWER_TEMPLE_DEATH_ARMOS_ROOM_CHEST] = ItemLocation::Chest (0x18, 0x05, true, "Stone Tower Temple Death Armos Room Chest", STONE_TOWER_TEMPLE_DEATH_ARMOS_ROOM_CHEST, STONE_TOWER_TEMPLE_SMALL_KEY, {Category::cStoneTowerTemple, Category::cVanillaSmallKey,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); - locationTable[STONE_TOWER_TEMPLE_UPRIGHT_DEATH_ARMOS_ROOM_CHEST] = ItemLocation::Chest (0x16, 0x05, true, "Stone Tower Temple Upright Death Armos Room Chest", STONE_TOWER_TEMPLE_UPRIGHT_DEATH_ARMOS_ROOM_CHEST, STONE_TOWER_TEMPLE_SMALL_KEY, {Category::cStoneTowerTemple, Category::cVanillaSmallKey,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_NO_GROUP); + locationTable[STONE_TOWER_TEMPLE_UPRIGHT_DEATH_ARMOS_ROOM_CHEST] = ItemLocation::Chest (0x16, 0x05, true, "Stone Tower Temple Upright Death Armos Room Chest", STONE_TOWER_TEMPLE_UPRIGHT_DEATH_ARMOS_ROOM_CHEST, STONE_TOWER_TEMPLE_SMALL_KEY, {Category::cStoneTowerTemple, Category::cVanillaSmallKey,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); locationTable[STONE_TOWER_TEMPLE_LIGHT_ARROW_CHEST] = ItemLocation::Chest (0x16, 0x1B, true, "Stone Tower Temple Light Arrow Chest", STONE_TOWER_TEMPLE_LIGHT_ARROW_CHEST, LIGHT_ARROWS, {Category::cStoneTowerTemple,Category::cChest ,Category::cDayOne, Category::cMainInventory}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); locationTable[STONE_TOWER_TEMPLE_GIANTS_MASK_CHEST] = ItemLocation::Chest (0x36, 0x00, false, "Stone Tower Temple Giant's Mask Chest", STONE_TOWER_TEMPLE_GIANTS_MASK_CHEST, GIANTS_MASK, {Category::cStoneTowerTemple,Category::cChest, Category::cVanillaMask ,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_STONE_TOWER ); @@ -533,7 +536,7 @@ void LocationTable_Init() { locationTable[TINGLE_N_CLOCK_TOWN_CT] = ItemLocation::Base (0x6E, 0xB4, false, "NCT Tingle Clock Town Map Buy", TINGLE_N_CLOCK_TOWN_CT, CLOCK_TOWN_MAP, {Category::cNorthClockTown, Category::cTingleMap,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_N_CLOCK_TOWN); locationTable[TINGLE_N_CLOCK_TOWN_WF] = ItemLocation::Base (0x6E, 0xB5, false, "NCT Tingle Woodfall Map Buy", TINGLE_N_CLOCK_TOWN_WF, WOODFALL_MAP, {Category::cNorthClockTown, Category::cTingleMap, Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_N_CLOCK_TOWN); - locationTable[TINGLE_ROAD_TO_SS_WF] = ItemLocation::Base (0x40, 0xB5, false, "Road To Southern Swamp Tingle Woodfall Map Buy", TINGLE_ROAD_TO_SS_WF, WOODFALL_MAP, {Category::cRoadToSouthernSwamp, Category::cTingleMap,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); + locationTable[TINGLE_ROAD_TO_SS_WF] = ItemLocation::Base (0x40, 0xB5, false, "Road to Southern Swamp Tingle Woodfall Map Buy", TINGLE_ROAD_TO_SS_WF, WOODFALL_MAP, {Category::cRoadToSouthernSwamp, Category::cTingleMap,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); locationTable[TINGLE_ROAD_TO_SS_SH] = ItemLocation::Base (0x40, 0xB6, false, "Road to Southern Swamp Tingle Snowhead Map Buy", TINGLE_ROAD_TO_SS_SH, SNOWHEAD_MAP, {Category::cRoadToSouthernSwamp, Category::cTingleMap, Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); locationTable[TINGLE_TWIN_ISLANDS_SH] = ItemLocation::Base (0x5D, 0xB6, false, "TI Tingle Snowhead Map Buy", TINGLE_TWIN_ISLANDS_SH, SNOWHEAD_MAP, {Category::cTwinIslands, Category::cTingleMap,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ItemGetInf(0), SpoilerCollectionCheckGroup::GROUP_TWIN_ISLANDS); @@ -557,30 +560,31 @@ void LocationTable_Init() { 3 4 7 8 1 2 3 ------------------------------- -----------------------*/ - locationTable[TRADING_POST_ITEM_1] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 1", TRADING_POST_ITEM_1, BUY_RED_POTION, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_2] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 2", TRADING_POST_ITEM_2, BUY_GREEN_POTION, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 1), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_3] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 3", TRADING_POST_ITEM_3, BUY_HEROS_SHIELD, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 2), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_4] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 4", TRADING_POST_ITEM_4, BUY_FAIRYS_SPIRIT, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 3), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_5] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 5", TRADING_POST_ITEM_5, BUY_DEKU_STICK_1, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 4), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_6] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 6", TRADING_POST_ITEM_6, BUY_ARROWS_30, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 5), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_7] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 7", TRADING_POST_ITEM_7, BUY_DEKU_NUT_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 6), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[TRADING_POST_ITEM_8] = ItemLocation::Base (0x34,0x00, true, "Trading Post Item 8", TRADING_POST_ITEM_8, BUY_MAGIC_BEAN, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x34, 7), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_1] = ItemLocation::Shop (0x34,0x0A, true, "Trading Post Item 1", TRADING_POST_ITEM_1, RED_POTION_REFILL, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_2] = ItemLocation::Shop (0x34,0x05, true, "Trading Post Item 2", TRADING_POST_ITEM_2, GREEN_POTION_REFILL, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_3] = ItemLocation::Shop (0x34,0x06, true, "Trading Post Item 3", TRADING_POST_ITEM_3, HEROS_SHIELD, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_4] = ItemLocation::Shop (0x34,0x03, true, "Trading Post Item 4", TRADING_POST_ITEM_4, BOTTLE_WITH_FAIRY, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_5] = ItemLocation::Shop (0x34,0x07, true, "Trading Post Item 5", TRADING_POST_ITEM_5, DEKU_STICK, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_6] = ItemLocation::Shop (0x34,0x08, true, "Trading Post Item 6", TRADING_POST_ITEM_6, ARROWS_30, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_7] = ItemLocation::Shop (0x34,0x09, true, "Trading Post Item 7", TRADING_POST_ITEM_7, DEKU_NUTS_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[TRADING_POST_ITEM_8] = ItemLocation::Shop (0x34,0x2B, true, "Trading Post Item 8", TRADING_POST_ITEM_8, MAGIC_BEAN, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[BOMB_SHOP_ITEM_1] = ItemLocation::Base (0x68,0x00, true, "Bomb Shop Item 1", BOMB_SHOP_ITEM_1, BOMBS_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x68, 0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - locationTable[BOMB_SHOP_ITEM_2] = ItemLocation::Base (0x68,0x00, true, "Bomb Shop Item 2", BOMB_SHOP_ITEM_2, BOMBCHU_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x68, 1), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - //locationTable[BOMB_SHOP_ITEM_3] = ItemLocation::Base(0x68,0x00, true, "Bomb Shop Item 3", BOMB_SHOP_ITEM_3, BOMBS_20, {Category::cEastClockTown,Category::cShop,Category::cDayOne}, SpoilerCollectionCheck::ShopItem(0x00, 0), SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); - - locationTable[POTION_SHOP_ITEM_1] = ItemLocation::Base (0x0A,0x00, true, "Potion Shop Item 1", POTION_SHOP_ITEM_1, BLUE_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x0A, 0), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); - locationTable[POTION_SHOP_ITEM_2] = ItemLocation::Base (0x0A,0x00, true, "Potion Shop Item 2", POTION_SHOP_ITEM_2, GREEN_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x0A, 1), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); - locationTable[POTION_SHOP_ITEM_3] = ItemLocation::Base (0x0A,0x00, true, "Potion Shop Item 3", POTION_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x0A, 2), SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); + locationTable[BOMB_SHOP_ITEM_1] = ItemLocation::Shop (0x68,0x1A, true, "Bomb Shop Item 1", BOMB_SHOP_ITEM_1, BOMBS_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[BOMB_SHOP_ITEM_2] = ItemLocation::Shop (0x68,0x19, true, "Bomb Shop Item 2", BOMB_SHOP_ITEM_2, BOMBCHU_10, {Category::cEastClockTown,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN); + locationTable[W_CLOCK_TOWN_BOMB_BAG_BUY] = ItemLocation::Shop (0x68,0x17, false, "WCT Bomb Bag Purchase", W_CLOCK_TOWN_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown,Category::cDayOne, Category::cShop, Category::cMainInventory, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); + locationTable[W_CLOCK_TOWN_BIG_BOMB_BAG_BUY] = ItemLocation::Shop (0x68,0x18, false, "WCT Big Bomb Bag Purchase", W_CLOCK_TOWN_BIG_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG, {Category::cWestClockTown,Category::cDayTwo, Category::cShop, Category::cMainInventory, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_W_CLOCK_TOWN ); + + locationTable[POTION_SHOP_ITEM_1] = ItemLocation::Shop (0x0A,0x00, true, "Potion Shop Item 1", POTION_SHOP_ITEM_1, BLUE_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); + locationTable[POTION_SHOP_ITEM_2] = ItemLocation::Shop (0x0A,0x01, true, "Potion Shop Item 2", POTION_SHOP_ITEM_2, GREEN_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); + locationTable[POTION_SHOP_ITEM_3] = ItemLocation::Shop (0x0A,0x02, true, "Potion Shop Item 3", POTION_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cSouthernSwamp,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_SOUTHERN_SWAMP); - locationTable[GORON_SHOP_ITEM_1] = ItemLocation::Base (0x3D,0x00, true, "Goron Shop Item 1", GORON_SHOP_ITEM_1, BOMBS_10, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x3D, 0), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); - locationTable[GORON_SHOP_ITEM_2] = ItemLocation::Base (0x3D,0x00, true, "Goron Shop Item 2", GORON_SHOP_ITEM_2, ARROWS_10, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x3D, 1), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); - locationTable[GORON_SHOP_ITEM_3] = ItemLocation::Base (0x3D,0x00, true, "Goron Shop Item 3", GORON_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheck::ShopItem(0x3D, 2), SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); + locationTable[GORON_SHOP_ITEM_1] = ItemLocation::Shop (0x3D,0x1E, true, "Goron Shop Item 1", GORON_SHOP_ITEM_1, BOMBS_10, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); + locationTable[GORON_SHOP_ITEM_2] = ItemLocation::Shop (0x3D,0x1F, true, "Goron Shop Item 2", GORON_SHOP_ITEM_2, ARROWS_10, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); + locationTable[GORON_SHOP_ITEM_3] = ItemLocation::Shop (0x3D,0x20, true, "Goron Shop Item 3", GORON_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cGoronVillage,Category::cShop,Category::cDayOne, Category::cNoOcarinaStart}, SpoilerCollectionCheckGroup::GROUP_GORON_VILLAGE); - locationTable[ZORA_SHOP_ITEM_1] = ItemLocation::Base (0x4C,0x00, true, "Zora Shop Item 1", ZORA_SHOP_ITEM_1, HEROS_SHIELD, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheck::ShopItem(0x4C, 0), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); - locationTable[ZORA_SHOP_ITEM_2] = ItemLocation::Base (0x4C,0x00, true, "Zora Shop Item 2", ZORA_SHOP_ITEM_2, ARROWS_10, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheck::ShopItem(0x4C, 1), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); - locationTable[ZORA_SHOP_ITEM_3] = ItemLocation::Base (0x4C,0x00, true, "Zora Shop Item 3", ZORA_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheck::ShopItem(0x4C, 2), SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); + locationTable[ZORA_SHOP_ITEM_1] = ItemLocation::Shop (0x4C,0x1B, true, "Zora Shop Item 1", ZORA_SHOP_ITEM_1, HEROS_SHIELD, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); + locationTable[ZORA_SHOP_ITEM_2] = ItemLocation::Shop (0x4C,0x1C, true, "Zora Shop Item 2", ZORA_SHOP_ITEM_2, ARROWS_10, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); + locationTable[ZORA_SHOP_ITEM_3] = ItemLocation::Shop (0x4C,0x1D, true, "Zora Shop Item 3", ZORA_SHOP_ITEM_3, RED_POTION_REFILL, {Category::cZoraHall,Category::cShop,Category::cDayOne}, SpoilerCollectionCheckGroup::GROUP_ZORA_HALL); @@ -721,7 +725,6 @@ std::vector> ShopLocationLists = { SS_ShopLocations, GV_ShopLocations, ZH_ShopLocations, - TingleMapLocations, }; //List of gossip stone locations for hints @@ -816,8 +819,8 @@ std::vector overworldLocations = { BOMBERS_HIDEOUT_CHEST, E_CLOCK_TOWN_CHEST, E_CLOCK_TOWN_POSTBOX, - //E_CLOCK_TOWN_MILK_BAR_CHATEAU, - //E_CLOCK_TOWN_MILK_BAR_MILK, + E_CLOCK_TOWN_MILK_BAR_CHATEAU, + E_CLOCK_TOWN_MILK_BAR_MILK, GORMAN_TRACK_MYSTERY_MILK_QUEST, //E_CLOCK_TOWN_HONEY_DARLING_ANY_DAY, //E_CLOCK_TOWN_TREASURE_CHEST_GAME_HUMAN, @@ -827,6 +830,7 @@ std::vector overworldLocations = { //Goron Village GORON_VILLAGE_POWDER_KEG_CHALLENGE, GORON_VILLAGE_SCRUB_PURCHASE, + GORON_VILLAGE_ZORA_SCRUB_PURCHASE, GORON_VILLAGE_LENS_OF_TRUTH_CHEST, GORON_VILLAGE_SCRUB_TRADE, GORON_VILLAGE_LEDGE, @@ -835,6 +839,7 @@ std::vector overworldLocations = { LENS_CAVE_PURPLE_RUPEE, GORON_VILLAGE_POWDER_KEG_CHALLENGE_SPRING, GORON_VILLAGE_SCRUB_PURCHASE_SPRING, + GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, GORON_VILLAGE_SCRUB_TRADE_SPRING, GORON_VILLAGE_LEDGE_SPRING, GORON_SHOP_ITEM_1, @@ -938,6 +943,7 @@ std::vector overworldLocations = { DOGGY_RACETRACK_ROOF_CHEST, //S Clock Town S_CLOCK_TOWN_SCRUB_TRADE, + S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, S_CLOCK_TOWN_POSTBOX, S_CLOCK_TOWN_CLOCK_TOWER_ENTRANCE, S_CLOCK_TOWN_STRAW_ROOF_CHEST, @@ -963,7 +969,9 @@ std::vector overworldLocations = { //SOUTHERN_SWAMP_PICTOGRAPH_STANDARD, //SOUTHERN_SWAMP_PICTOGRAPH_GOOD, SOUTHERN_SWAMP_SCRUB_PURCHASE, + SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR, + SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, SOUTHERN_SWAMP_SCRUB_TRADE_CLEAR, SWAMP_TOURIST_CENTER_ROOF_CLEAR, POTION_SHOP_ITEM_1, @@ -1049,6 +1057,7 @@ std::vector overworldLocations = { ZORA_HALL_EVAN, ZORA_HALL_LULU_ROOM_LEDGE, ZORA_HALL_SCRUB_PURCHASE, + ZORA_HALL_IKANA_SCRUB_PURCHASE, //ZORA_HALL_STAGE_LIGHTS, //ZORA_HALL_BAD_PHOTO_LULU, //ZORA_HALL_GOOD_PHOTO_LULU, @@ -1118,11 +1127,13 @@ void PlaceItemInLocation(LocationKey locKey, ItemKey item, bool applyEffectImmed } //If we're placing a non-shop item in a shop location, we want to record it for custom messages - /* if (ItemTable(item).GetItemType() != ITEMTYPE_SHOP && loc->IsCategory(Category::cShop)) { - int index = TransformShopIndex(GetShopIndex(locKey)); - NonShopItems[index].Name = ItemTable(item).GetName(); - NonShopItems[index].Repurchaseable = ItemTable(item).GetItemType() == ITEMTYPE_REFILL || ItemTable(item).GetHintKey() == PROGRESSIVE_BOMBCHUS; - }*/ + if (ItemTable(item).GetItemType() != ITEMTYPE_SHOP && loc->IsCategory(Category::cShop)) { + const int index = GetShopIndex(locKey); + if (index >= 0) { + NonShopItems[index].Name = ItemTable(item).GetName(); + NonShopItems[index].Repurchaseable = ItemTable(item).GetItemType() == ITEMTYPE_REFILL; + } + } loc->SetPlacedItem(item); } @@ -1243,14 +1254,33 @@ void CreateItemOverrides() { PlaceItemInLocation(W_CLOCK_TOWN_CURIOSITY_BOMB_BAG, loc24->GetPlacedItemKey()); auto loc25 = Location(LAUNDRY_POOL_SF); PlaceItemInLocation(E_CLOCK_TOWN_SF, loc25->GetPlacedItemKey()); + //Scrubsanity - make sure all scrubs have the same item in both locations + auto loc26 = Location(SOUTHERN_SWAMP_SCRUB_PURCHASE); + auto loc27 = Location(GORON_VILLAGE_SCRUB_PURCHASE); + auto loc28 = Location(ZORA_HALL_SCRUB_PURCHASE); + auto loc29 = Location(IKANA_CANYON_SCRUB_PURCHASE); + PlaceItemInLocation(S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, loc26->GetPlacedItemKey()); + PlaceItemInLocation(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, loc27->GetPlacedItemKey()); + PlaceItemInLocation(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, loc27->GetPlacedItemKey()); + PlaceItemInLocation(GORON_VILLAGE_ZORA_SCRUB_PURCHASE, loc28->GetPlacedItemKey()); + PlaceItemInLocation(GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, loc28->GetPlacedItemKey()); + PlaceItemInLocation(ZORA_HALL_IKANA_SCRUB_PURCHASE, loc29->GetPlacedItemKey()); + + //Price adjustments for shopsanity - make sure shop prices are the same for both locations + u16 price1 = Location(W_CLOCK_TOWN_BIG_BOMB_BAG_BUY)->GetPrice(); + Location(W_CLOCK_TOWN_CURIOSITY_BOMB_BAG)->SetPrice(price1); + for (LocationKey locKey : allLocations) { auto loc = Location(locKey); ItemOverride_Value val = ItemTable(loc->GetPlacedItemKey()).Value(); //If this is an ice trap in a shop, change the name based on what the model will look like - //if (loc->GetPlacedItemKey() == ICE_TRAP && loc->IsCategory(Category::cShop)) { - //NonShopItems[TransformShopIndex(GetShopIndex(locKey))].Name = GetIceTrapName(val.looksLikeItemId); - //} + if (loc->GetPlacedItemKey() == ICE_TRAP && loc->IsCategory(Category::cShop)) { + const int index = GetShopIndex(locKey); + if (index >= 0) { + NonShopItems[index].Name = GetIceTrapName(val.looksLikeItemId); + } + } overrides.insert({ .key = loc->Key(), .value = val, diff --git a/source/item_pool.cpp b/source/item_pool.cpp index 9ad2175..1cd2007 100644 --- a/source/item_pool.cpp +++ b/source/item_pool.cpp @@ -239,12 +239,6 @@ const std::array shopsanityRupees = { RED_RUPEE, PURPLE_RUPEE, }; -const std::array dekuScrubItems = { - HUGE_RUPEE, - BLUE_POTION_REFILL, - MAGIC_BEAN, - GREEN_POTION_REFILL, -}; const std::array chestItems = { LENS_OF_TRUTH, @@ -258,16 +252,12 @@ const std::array chestItems = { }; const std::array songList = { - //SONG_OF_TIME, - //SONG_OF_DOUBLE_TIME, - //INVERTED_SONG_OF_TIME, //SoT not included yet + // Song of Soaring and Song of Time are not in this list + // As they are handled by different settings SONG_OF_STORMS, EPONAS_SONG, SONG_OF_HEALING, - //SONG_OF_SOARING, SONATA_OF_AWAKENING, - //LULLABY_INTRO, - //GORONS_LULLABY, PROGRESSIVE_LULLABY, PROGRESSIVE_LULLABY, NEW_WAVE_BOSSA_NOVA, @@ -307,7 +297,7 @@ const std::array maskList = { GIBDOS_MASK, GAROS_MASK, CAPTAINS_HAT, - GIANTS_MASK, + GIANTS_MASK, MASK_OF_TRUTH, }; @@ -444,13 +434,6 @@ const std::array vanillaCows = { MILK, }; -const std::array scrubPurchaseItems = { - MAGIC_BEAN, - PROGRESSIVE_BOMB_BAG,//BIGGEST_BOMB_BAG - GREEN_POTION_REFILL, - BLUE_POTION_REFILL, -}; - const std::array moonItemList = { //2Chests and 4 trial rewards, FDM separate //ARROWS_30, -just replace with junk @@ -469,6 +452,13 @@ const std::array scrubTradeItems = { OCEAN_TITLE, }; +const std::array scrubPurchases = { + MAGIC_BEAN, + PROGRESSIVE_BOMB_BAG,//BIGGEST_BOMB_BAG + BLUE_POTION_REFILL, + GREEN_POTION_REFILL, +}; + const std::array anjuKafeiTradeItems = { LETTER_KAFEI, LETTER_MAMA, @@ -497,6 +487,14 @@ std::array tingleMaps = { ROMANI_RANCH_MAP, }; +std::array shopItems = { // Only include non junk items/potions/milk + HEROS_SHIELD, + HEROS_SHIELD, + MAGIC_BEAN, + PROGRESSIVE_BOMB_BAG, + PROGRESSIVE_BOMB_BAG, + CHATEAU_ROMANI_REFILL, +}; void AddItemToPool(std::vector& pool, ItemKey item, size_t count /*= 1*/) { pool.insert(pool.end(), count, item); } @@ -603,74 +601,6 @@ static void PlaceVanillaStrayFairies() { dungeon->PlaceVanillaGBTStray(); dungeon->PlaceVanillaSTStray(); } - //Clock Town - PlaceItemInLocation(LAUNDRY_POOL_SF, CT_STRAY_FAIRY); - /* - //Woodfall Temple - PlaceItemInLocation(WF_SF_ENTRANCE_FAIRY, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_ENTRANCE_PLATFORM, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_MAIN_ROOM_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_MAIN_ROOM_SWITCH, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_PRE_BOSS_LOWER_RIGHT_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_PRE_BOSS_UPPER_RIGHT_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_PRE_BOSS_UPPER_LEFT_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_PRE_BOSS_PILLAR_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_DEKU_BABA, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_DRAGONFLY_ROOM_BUBBLE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_SKULLTULA, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_DARK_ROOM, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_JAR_FAIRY, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_BRIDGE_ROOM_BEEHIVE, WF_STRAY_FAIRY); - PlaceItemInLocation(WF_SF_PLATFORM_ROOM_BEEHIVE, WF_STRAY_FAIRY); - //SnowheadTemple - PlaceItemInLocation(SH_SF_SNOW_ROOM_BUBBLE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_CEILING_BUBBLE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_DINOLFOS_1, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_DINOLFOS_2, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_BRIDGE_ROOM_LEDGE_BUBBLE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_BRIDGE_ROOM_PILLAR_BUBBLE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_MAP_ROOM_FAIRY, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_MAP_ROOM_LEDGE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_BASEMENT, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_TWIN_BLOCK, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_ICICLE_ROOM_WALL, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_MAIN_ROOM_WALL, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_PILLAR_FREEZARDS, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_ICE_PUZZLE, SH_STRAY_FAIRY); - PlaceItemInLocation(SH_SF_CRATE, SH_STRAY_FAIRY); - //Great Bay Temple - PlaceItemInLocation(GBT_SF_SKULLTULA, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_WATER_CONTROL_UNDERWATER_BUBBLE, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_WATERWHEEL_ROOM_LOWER, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_WATERWHEEL_ROOM_UPPER, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_GREEN_VALVE, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_SEESAW_ROOM, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_ENTRANCE_TORCHES, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_BIO_BABAS, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_UNDERWATER_BARREL, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_WHIRLPOOL_JAR, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_WHIRLPOOL_BARREL, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_DEXIHANDS_JAR, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_LEDGE_JAR, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_PRE_BOSS_ROOM_BUBBLE, GBT_STRAY_FAIRY); - PlaceItemInLocation(GBT_SF_PRE_BOSS_ROOM_UNDERWATER_BUBBLE, GBT_STRAY_FAIRY); - //Stone Tower Temple - PlaceItemInLocation(ST_SF_MIRROR_SUN_BLOCK, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_LAVA_ROOM_LEDGE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_LAVA_ROOM_FIRE_RING, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_EYEGORE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_UPDRAFT_FIRE_RING, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_MIRROR_SUN_SWITCH, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_BOSS_WARP, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_WIZZROBE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_DEATH_ARMOS, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_UPDRAFT_FROZEN_EYE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_THIN_BRIDGE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_BASEMENT_LEDGE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_STATUE_EYE, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_UNDERWATER, ST_STRAY_FAIRY); - PlaceItemInLocation(ST_SF_BRIDGE_CRYSTAL, ST_STRAY_FAIRY); - */ }; static void PlaceVanillaSkulltulaTokens() { @@ -703,6 +633,9 @@ static void PlaceVanillaShopItems() { PlaceItemInLocation(TRADING_POST_ITEM_8, BUY_MAGIC_BEAN); PlaceItemInLocation(BOMB_SHOP_ITEM_1, BUY_BOMBS_10); PlaceItemInLocation(BOMB_SHOP_ITEM_2, BUY_BOMBCHU_10); + PlaceItemInLocation(W_CLOCK_TOWN_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG); + PlaceItemInLocation(W_CLOCK_TOWN_BIG_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG); + PlaceItemInLocation(W_CLOCK_TOWN_CURIOSITY_BOMB_BAG, PROGRESSIVE_BOMB_BAG); PlaceItemInLocation(W_CLOCK_TOWN_BOMB_SHOP_GORON, POWDER_KEG); PlaceItemInLocation(POTION_SHOP_ITEM_1, BUY_BLUE_POTION); PlaceItemInLocation(POTION_SHOP_ITEM_2, BUY_GREEN_POTION); @@ -713,12 +646,18 @@ static void PlaceVanillaShopItems() { PlaceItemInLocation(ZORA_SHOP_ITEM_1, BUY_HEROS_SHIELD); PlaceItemInLocation(ZORA_SHOP_ITEM_2, BUY_ARROWS_10); PlaceItemInLocation(ZORA_SHOP_ITEM_3, BUY_RED_POTION); + PlaceItemInLocation(MILK_ROAD_GORMAN_MILK_BUY, MILK); + PlaceItemInLocation(E_CLOCK_TOWN_MILK_BAR_MILK, MILK); + PlaceItemInLocation(E_CLOCK_TOWN_MILK_BAR_CHATEAU, CHATEAU_ROMANI_REFILL); + //other 2 scrub sales handled in beans and main inventory +}; + +static void PlaceVanillaScrubPurchases() { + PlaceItemInLocation(SOUTHERN_SWAMP_SCRUB_PURCHASE, MAGIC_BEAN); PlaceItemInLocation(GORON_VILLAGE_SCRUB_PURCHASE, PROGRESSIVE_BOMB_BAG); PlaceItemInLocation(GORON_VILLAGE_SCRUB_PURCHASE_SPRING, PROGRESSIVE_BOMB_BAG); PlaceItemInLocation(IKANA_CANYON_SCRUB_PURCHASE, BLUE_POTION_REFILL); PlaceItemInLocation(ZORA_HALL_SCRUB_PURCHASE, GREEN_POTION_REFILL); - PlaceItemInLocation(MILK_ROAD_GORMAN_MILK_BUY, MILK); - //other 2 scrub sales handled in beans and main inventory }; static void SetScarceItemPool() { @@ -756,47 +695,41 @@ void GenerateItemPool() { 0x25, //GetItemID::GI_FIRE_ARROW, 0x26, //GetItemID::GI_ICE_ARROW, 0x27, //GetItemID::GI_LIGHT_ARROW, - 0xB8, //Double defense + 0xB2, //Double defense 0x46, //Progressive bomb bag 0x47, //Progressive bow 0x48, //Progressive wallet 0x49, //Progressive magic - 0x4A, //ProgressiveSword + 0x4A, //Progressive Sword }; //Check song shuffle and dungeon reward shuffle just for ice traps if (ShuffleSongs.Value() != 0) { //Push item ids for songs - IceTrapModels.push_back(0x4B); - IceTrapModels.push_back(0x4C); - IceTrapModels.push_back(0x4D); - IceTrapModels.push_back(0x4E); - IceTrapModels.push_back(0x4F); - IceTrapModels.push_back(0x51); - IceTrapModels.push_back(0x53); - IceTrapModels.push_back(0x54); - IceTrapModels.push_back(0x6C); - IceTrapModels.push_back(0x72); - IceTrapModels.push_back(0x73); - //IceTrapModels.push_back(0xC6); + IceTrapModels.push_back(0x4B); //GI_SONATA_OF_AWAKENING + IceTrapModels.push_back(0x45); // Progressive Lullaby + IceTrapModels.push_back(0x4E); //GI_NEW_WAVE_BOSSA_NOVA + IceTrapModels.push_back(0x4F); //GI_ELEGY_OF_EMPTINESS + IceTrapModels.push_back(0x51); //GI_OATH_TO_ORDER + IceTrapModels.push_back(0x53); //GI_SONG_OF_TIME + IceTrapModels.push_back(0x54); // Song of Healing + IceTrapModels.push_back(0x6C); //GI_EPONAS_SONG + IceTrapModels.push_back(0x72); //GI_SONG_OF_SOARING + IceTrapModels.push_back(0x73); //GI_SONG_OF_STORMS + //IceTrapModels.push_back(0xC6); //????? } if (ShuffleRewards.Value() != 0) { //Push item ids for dungeon rewards - IceTrapModels.push_back(0x55); - IceTrapModels.push_back(0x56); - IceTrapModels.push_back(0x57); - IceTrapModels.push_back(0x58); + IceTrapModels.push_back(0x55); // GI_ODOLWAS_REMAINS + IceTrapModels.push_back(0x56); // GI_GOHTS_REMAINS + IceTrapModels.push_back(0x57); // GI_GYORGS_REMAINS + IceTrapModels.push_back(0x58); // GI_TWINMOLDS_REMAINS } - + //Fixed Item Locations PlaceItemInLocation(MAJORA, MAJORAS_MASK, true); PlaceItemInLocation(WOODFALL_TEMPLE_DEKU_PRINCESS, DEKU_PRINCESS); - PlaceItemInLocation(W_CLOCK_TOWN_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG); - PlaceItemInLocation(W_CLOCK_TOWN_BIG_BOMB_BAG_BUY, PROGRESSIVE_BOMB_BAG); - PlaceItemInLocation(W_CLOCK_TOWN_CURIOSITY_BOMB_BAG, PROGRESSIVE_BOMB_BAG); - - //temp placement until shopsanity works - PlaceItemInLocation(SOUTHERN_SWAMP_SCRUB_PURCHASE, MAGIC_BEAN); + PlaceItemInLocation(W_CLOCK_TOWN_BOMB_SHOP_GORON, POWDER_KEG);//Not Randomized for simplicity //Place Temp Items at alt locations so they don't get filled with important stuff - will be replaced later PlaceItemInLocation(SOUTHERN_SWAMP_KOTAKE_IN_WOODS, BLUE_RUPEE); @@ -813,11 +746,19 @@ void GenerateItemPool() { PlaceItemInLocation(SWAMP_TOURIST_CENTER_ROOF_CLEAR, BLUE_RUPEE); PlaceItemInLocation(STONE_TOWER_TEMPLE_UPRIGHT_DEATH_ARMOS_ROOM_CHEST, BLUE_RUPEE); PlaceItemInLocation(E_CLOCK_TOWN_SF, BLUE_RUPEE); + PlaceItemInLocation(S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, BLUE_RUPEE); + PlaceItemInLocation(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, BLUE_RUPEE); + PlaceItemInLocation(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, BLUE_RUPEE); + PlaceItemInLocation(GORON_VILLAGE_ZORA_SCRUB_PURCHASE, BLUE_RUPEE); + PlaceItemInLocation(GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, BLUE_RUPEE); + PlaceItemInLocation(ZORA_HALL_IKANA_SCRUB_PURCHASE, BLUE_RUPEE); + //Check Non Dungeon Settings //OCARINA SHUFFLE if(StartingOcarina.Value() == 0) {//If starting without ocarina add it to pool AddItemToMainPool(OCARINA_OF_TIME, 1); + IceTrapModels.push_back(0x4C); //GI_OCARINA_OF_TIME } else { //else place it vanilla cause we start with it PlaceItemInLocation(CLOCK_TOWER_OCARINA_OF_TIME, OCARINA_OF_TIME, true); @@ -826,7 +767,6 @@ void GenerateItemPool() { //KOKIRISWORD SHUFFLE if(StartingKokiriSword.Value() == (u8)StartingSwordSetting::STARTINGSWORD_NONE) {//if starting with no sword we need to add an extra to the pool AddItemToMainPool(PROGRESSIVE_SWORD, 1); - IceTrapModels.push_back(0x37);//GetItemID::GI_KOKIRI_SWORD PlaceItemInLocation(HMS_STARTING_SWORD,GREEN_RUPEE);//Add Junk to this location because theres no way to get it otherwise } else { PlaceItemInLocation(HMS_STARTING_SWORD, KOKIRI_SWORD); //if starting with any sword place this here because this location is unobtainable @@ -842,7 +782,8 @@ void GenerateItemPool() { //SHUFFLE BOMBERS NOTEBOOK if(ShuffleBombersNotebook){ AddItemToMainPool(BOMBERS_NOTEBOOK); - //PlaceItemInLocation(HMS_BOMBERS_NOTEBOOK, GREEN_RUPEE);//Need to add check if starting with Song of Healing + IceTrapModels.push_back(0x50); //GI_BOMBERS_NOTEBOOK + //PlaceItemInLocation(HMS_BOMBERS_NOTEBOOK, GREEN_RUPEE);//Need to add check if starting with Song of Healing } else {PlaceItemInLocation(HMS_BOMBERS_NOTEBOOK, BOMBERS_NOTEBOOK);} @@ -856,26 +797,16 @@ void GenerateItemPool() { PlaceVanillaCowMilk(); } - //MAGIC BEAN SHUFFLE--NEEDS WORK - PlaceItemInLocation(DEKU_PALACE_BEAN_SELLER, MAGIC_BEAN);//vanilla for now because replacing causes odd occurances where you cannot buy beans elsewhere - /* - if(ShuffleMagicBeans) { //does not shuffle bean salesman yet - AddItemToMainPool(MAGIC_BEAN); + //MAGIC BEAN SHUFFLE + if(ShuffleMagicBeans) { + AddItemToMainPool(MAGIC_BEAN_PACK); if (ItemPoolValue.Is(ItemPoolSetting::ITEMPOOL_PLENTIFUL)){ - AddItemToPool(PendingJunkPool, MAGIC_BEAN); - } - IceTrapModels.push_back(0x75); - - if(Shopsanity){ - AddItemToMainPool(MAGIC_BEAN); - if (ItemPoolValue.Is(ItemPoolSetting::ITEMPOOL_PLENTIFUL)){ - AddItemToPool(PendingJunkPool, MAGIC_BEAN); - } + AddItemToPool(PendingJunkPool, MAGIC_BEAN_PACK); } + IceTrapModels.push_back(0x35); // GI_MAGIC_BEAN } else { - PlaceItemInLocation(STONE_TOWER_INVERTED_LEFT_CHEST, MAGIC_BEAN); - if(!Shopsanity){PlaceItemInLocation(SOUTHERN_SWAMP_SCRUB_PURCHASE, MAGIC_BEAN);} - }*/ + PlaceItemInLocation(DEKU_PALACE_BEAN_SELLER, MAGIC_BEAN_PACK); + } //MAININVENTORY SHUFFLE if(ShuffleMainInventory){ @@ -890,6 +821,24 @@ void GenerateItemPool() { //NON TRANSFORM MASK SHUFFLE if (ShuffleMasks) { AddItemsToPool(ItemPool, maskList); + IceTrapModels.push_back(0x80); // GI_MASK_KEATON + IceTrapModels.push_back(0x7F); // GI_MASK_BUNNY_HOOD + IceTrapModels.push_back(0x84); // GI_MASK_POSTMANS + IceTrapModels.push_back(0x7E); // GI_MASK_ALL_NIGHT + IceTrapModels.push_back(0x8D); // GI_MASK_BLAST + IceTrapModels.push_back(0x8B); // GI_MASK_STONE + IceTrapModels.push_back(0x86); // GI_MASK_GREAT_FAIRYS + IceTrapModels.push_back(0x8C); // GI_MASK_BREMEN + IceTrapModels.push_back(0x88); // GI_MASK_DON_GEROS + IceTrapModels.push_back(0x8E); // GI_MASK_OF_SCENTS + IceTrapModels.push_back(0x82); // GI_MASK_ROMANIS + IceTrapModels.push_back(0x83); // GI_MASK_TROUPE_LEADERS + IceTrapModels.push_back(0x89); // GI_MASK_KAMARAOS + IceTrapModels.push_back(0x87); // GI_MASK_GIBDO + IceTrapModels.push_back(0x81); // GI_MASK_GARO + IceTrapModels.push_back(0x7C); // GI_MASK_CAPTAINS_HAT + IceTrapModels.push_back(0x7D); // GI_MASK_GIANTS + IceTrapModels.push_back(0x8A); // GI_MASK_OF_TRUTH } else { PlaceVanillaMasks(); @@ -947,6 +896,9 @@ void GenerateItemPool() { AddItemToMainPool(DEKU_MASK); AddItemToMainPool(GORON_MASK); AddItemToMainPool(ZORA_MASK); + IceTrapModels.push_back(0x78); // GI_MASK_DEKU + IceTrapModels.push_back(0x79); // GI_MASK_GORON + IceTrapModels.push_back(0x7A); // GI_MASK_ZORA } else { PlaceItemInLocation(HMS_DEKU_MASK,DEKU_MASK); @@ -957,6 +909,7 @@ void GenerateItemPool() { //FIERECE DEITY SHUFFLE if(ShuffleFierceDeity){ AddItemToMainPool(FIERCE_DEITY_MASK); + IceTrapModels.push_back(0x7B); // GI_MASK_FIERCE_DEITY } else{ PlaceItemInLocation(THE_MOON_MAJORA_CHILD,FIERCE_DEITY_MASK); @@ -990,6 +943,8 @@ void GenerateItemPool() { if(Tokensanity){ AddItemToMainPool(SWAMP_SKULLTULA_TOKEN, 30); AddItemToMainPool(OCEANSIDE_SKULLTULA_TOKEN, 30); + IceTrapModels.push_back(0x44); // Swamp Token + IceTrapModels.push_back(0x6D); // Ocean Token std::vector SwampSkullLocations = FilterFromPool(allLocations, [](const LocationKey loc) {return Location(loc)->IsCategory(Category::cSwampSkulltula);}); std::vector OceanSkullLocations = FilterFromPool(allLocations, [](const LocationKey loc1) {return Location(loc1)->IsCategory(Category::cOceanSkulltula);}); } @@ -1000,6 +955,11 @@ void GenerateItemPool() { //DEKU MERCHANT TRADE QUEST if (ShuffleMerchants){//Merchants is Deku Scrub Trade Quest AddItemsToPool(ItemPool, scrubTradeItems); + IceTrapModels.push_back(0x96); // GI_MOONS_TEAR + IceTrapModels.push_back(0x97); // GI_TOWN_TITLE_DEED + IceTrapModels.push_back(0x98); // GI_SWAMP_TITLE_DEED + IceTrapModels.push_back(0x99); // GI_MOUNTAIN_TITLE_DEED + IceTrapModels.push_back(0x9A); // GI_OCEAN_TITLE_DEED } else { PlaceItemInLocation(TERMINA_FIELD_MOONS_TEAR, MOONS_TEAR); PlaceItemInLocation(S_CLOCK_TOWN_SCRUB_TRADE, LAND_TITLE); @@ -1012,6 +972,12 @@ void GenerateItemPool() { //ANJU AND KAFEI QUEST ITEMS if (ShuffleTradeItems){//TradeItems refers to Anju&Kafei Items AddItemsToPool(ItemPool, anjuKafeiTradeItems); + IceTrapModels.push_back(0x8F); // GI_MASK_KAFEIS + IceTrapModels.push_back(0x85); // GI_MASK_COUPLES + IceTrapModels.push_back(0xAA); // GI_LETTER_TO_KAFEI + IceTrapModels.push_back(0xAB); // GI_PENDANT_OF_MEMORIES + IceTrapModels.push_back(0xA1); // GI_LETTER_TO_MAMA + IceTrapModels.push_back(0xA0); // GI_ROOM_KEY } else { PlaceItemInLocation(E_CLOCK_TOWN_AROMA_IN_OFFICE, KAFEIS_MASK); PlaceItemInLocation(STOCKPOTINN_ANJU_AND_KAFEI, COUPLES_MASK); @@ -1021,20 +987,32 @@ void GenerateItemPool() { PlaceItemInLocation(LAUNDRY_POOL_KAFEI,PENDANT_MEMORIES); } - //TO-DO----SHOP SANITY - //for now... its all vanilla lol - //if (Settings::Shopsanity.Is(ShopsanitySetting::SHOPSANITY_OFF) || Settings::Shopsanity.Is(ShopsanitySetting::SHOPSANITY_ZERO)) { - AddItemsToPool(ItemPool, normalRupees); - PlaceVanillaShopItems(); - // } else { //Shopsanity 1-4, random - //AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees - //PlaceVanillaShopItems(); - //} + //SHOPSANITY + if (Shopsanity) { + AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees + AddItemsToPool(ItemPool, shopItems); + } else { + AddItemsToPool(ItemPool, normalRupees); + PlaceVanillaShopItems(); + } + //SCRUBSANITY + if (Scrubsanity) { + AddItemsToPool(ItemPool, scrubPurchases); + } + else { + PlaceVanillaScrubPurchases(); + } //Then Place Tingle Maps if (ShuffleTingleMaps) { //Add the 6 maps AddItemsToPool(ItemPool, tingleMaps); + IceTrapModels.push_back(0xB4); // GI_MAP_OF_CLOCK_TOWN = 0xB4 + IceTrapModels.push_back(0xB5); // GI_MAP_OF_WOODFALL + IceTrapModels.push_back(0xB6); // GI_MAP_OF_SNOWHEAD + IceTrapModels.push_back(0xB7); // GI_MAP_OF_ROMANI_RANCH + IceTrapModels.push_back(0xB8); // GI_MAP_OF_GREAT_BAY + IceTrapModels.push_back(0xB9); // GI_MAP_OF_STONE_TOWER //Place Junk in "Duplicate spots" so each map check contains the same item in both locations PlaceItemInLocation(TINGLE_N_CLOCK_TOWN_WF, BLUE_RUPEE); PlaceItemInLocation(TINGLE_ROAD_TO_SS_SH, BLUE_RUPEE); @@ -1065,12 +1043,7 @@ void GenerateItemPool() { //DUNGEON STUFF - //PlaceVanillaBossRemains(); //done in fill.cpp - RandomizeDungeonRewards() - //PlaceVanillaBossKeys(); //todo Keysanity settings - //PlaceVanillaSmallKeys(); // for now all vanilla PlaceVanillaZoraEggs(); //for now all vanilla - //PlaceVanillaMapsAndCompasses();//for now all vanilla - //PlaceVanillaStrayFairies();//for now all vanilla if(ShuffleHeartContainers) { AddItemToMainPool(HEART_CONTAINER, 4); @@ -1137,6 +1110,10 @@ void GenerateItemPool() { AddItemToMainPool(SH_STRAY_FAIRY, 15); AddItemToMainPool(GBT_STRAY_FAIRY, 15); AddItemToMainPool(ST_STRAY_FAIRY, 15); + IceTrapModels.push_back(0xBC); // Woodfall Stray + IceTrapModels.push_back(0xBD); // Snowhead Stray + IceTrapModels.push_back(0xBE); // Great Bay Stray + IceTrapModels.push_back(0xBF); // Ikana Stray } //CLOCK TOWN STRAY FAIRY (Separated because it's not in a dungeon) @@ -1145,19 +1122,13 @@ void GenerateItemPool() { } else { AddItemToMainPool(CT_STRAY_FAIRY, 1); + IceTrapModels.push_back(0xBB); // Clock Town Stray } //DungeonRewards AddItemsToPool(ItemPool, dungeonRewards); - // TO-DO ItemPool for extra items & Scarce and Minimal pools - //if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - //AddItemsToPool(ItemPool, easyItems); - //} - //else { - //AddItemsToPool(ItemPool, normalItems); - //} if (ItemPoolValue.Is(ItemPoolSetting::ITEMPOOL_SCARCE)) {//TO DO SetScarceItemPool(); } diff --git a/source/location_access.cpp b/source/location_access.cpp index 17be4ff..4f360f1 100644 --- a/source/location_access.cpp +++ b/source/location_access.cpp @@ -24,7 +24,7 @@ bool LocationAccess::ConditionsMet() const { conditionsMet= true; } - return conditionsMet;// && CanBuy(); + return conditionsMet && CanBuy(); } bool LocationAccess::CanBuy() const { @@ -36,13 +36,13 @@ bool LocationAccess::CanBuy() const { //Check if current walet is large enough bool SufficientWallet = true; if (Location(location)->GetPrice() > 500) { - SufficientWallet = Logic::ProgressiveWallet >= 3; + SufficientWallet = Logic::ProgressiveWallet >= 2; } else if (Location(location)->GetPrice() > 200) { - SufficientWallet = Logic::ProgressiveWallet >= 2; + SufficientWallet = Logic::ProgressiveWallet >= 1; } else if (Location(location)->GetPrice() > 99) { - SufficientWallet = Logic::ProgressiveWallet >= 1; + SufficientWallet = Logic::ProgressiveWallet >= 0; } bool OtherCondition = true; @@ -382,8 +382,11 @@ void AreaTable_Init() { }, { //Locations - LocationAccess(E_CLOCK_TOWN_GORMAN, {[] {return DekuMask && GoronMask && ZoraMask && RomanisMask;}}), + LocationAccess(E_CLOCK_TOWN_GORMAN, {[] {return DekuMask && GoronMask && ZoraMask && RomanisMask && Ocarina;}}), LocationAccess(E_CLOCK_TOWN_AROMA_IN_BAR, {[] {return LetterMama && KafeisMask;}}), + LocationAccess(E_CLOCK_TOWN_MILK_BAR_MILK, {[] {return HasBottle;}}), + LocationAccess(E_CLOCK_TOWN_MILK_BAR_CHATEAU, {[] {return HasBottle;}}), + }, { //Exits @@ -550,6 +553,7 @@ void AreaTable_Init() { { //Locations LocationAccess(S_CLOCK_TOWN_SCRUB_TRADE, {[] {return MoonsTear;}}), + LocationAccess(S_CLOCK_TOWN_SWAMP_SCRUB_PURCHASE, {[] {return CanTradeTownDeed;}}), LocationAccess(S_CLOCK_TOWN_POSTBOX, {[] {return PostmansHat;}}), LocationAccess(S_CLOCK_TOWN_CLOCK_TOWER_ENTRANCE, {[] {return true;}}), LocationAccess(S_CLOCK_TOWN_STRAW_ROOF_CHEST, {[] {return Hookshot || (DekuMask && MoonsTear);}}), @@ -869,15 +873,18 @@ void AreaTable_Init() { EventAccess(&SpringWater, {[]{return AnyBottle;}}), EventAccess(&SwampFrog, {[]{return DonGerosMask;}}), EventAccess(&DekuBabaNuts, {[]{return Fighting;}}), + EventAccess(&CanTradeTownDeed, {[]{return LandTitle;}}), }, { //Locations LocationAccess(SOUTHERN_SWAMP_SCRUB_TRADE, {[] {return LandTitle;}}), LocationAccess(SOUTHERN_SWAMP_SCRUB_PURCHASE, {[]{return DekuMask;}}), + LocationAccess(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE, {[] {return CanTradeSwampDeed && LandTitle;}}), LocationAccess(SOUTHERN_SWAMP_MUSIC_STATUE, {[] {return true;}}), LocationAccess(SWAMP_TOURIST_CENTER_ROOF, {[] {return DekuMask && LandTitle;}}), LocationAccess(SOUTHERN_SWAMP_SCRUB_TRADE_CLEAR, {[] {return LandTitle && WoodfallClear;}}), LocationAccess(SOUTHERN_SWAMP_SCRUB_PURCHASE_CLEAR, {[]{return DekuMask && WoodfallClear;}}), + LocationAccess(SOUTHERN_SWAMP_GORON_SCRUB_PURCHASE_CLEAR, {[] {return CanTradeSwampDeed && LandTitle && WoodfallClear;}}), LocationAccess(SWAMP_TOURIST_CENTER_ROOF_CLEAR, {[] {return DekuMask && LandTitle && WoodfallClear;}}), //Gossip Stones LocationAccess(SS_GOSSIP, {[] {return true;}}), @@ -1019,7 +1026,7 @@ void AreaTable_Init() { areaTable[DEKU_PALACE_BEAN_GROTTO] = Area("Deku Palace Bean Grotto", "Deku Palace Bean Grotto", NONE, { //Events - EventAccess(&LimitlessBeans, {[]{return true;}}), + EventAccess(&LimitlessBeans, {[]{return CanBuyBeans;}}), EventAccess(&SpringWater, {[]{return AnyBottle;}}), EventAccess(&Mushroom, {[]{return false;}}),//Trick for obscure mushroom? EventAccess(&Bugs, {[]{return AnyBottle;}}), @@ -1230,17 +1237,20 @@ void AreaTable_Init() { areaTable[GORON_VILLAGE] = Area("Goron Village", "Goron Village", GORON_VILLAGE, { //Events //Owl talk? + EventAccess(&CanTradeSwampDeed, {[]{return SwampTitle && DekuMask;}}), }, { //Locations LocationAccess(GORON_VILLAGE_POWDER_KEG_CHALLENGE, {[] {return GoronMask && (SnowheadClear || CanUse(FIRE_ARROWS));}}), LocationAccess(GORON_VILLAGE_SCRUB_PURCHASE, {[] {return AnyWallet && GoronMask && (ProgressiveBombBag >= 2);}}), + LocationAccess(GORON_VILLAGE_ZORA_SCRUB_PURCHASE, {[] {return CanTradeMountainDeed && SwampTitle;}}), LocationAccess(GORON_VILLAGE_SCRUB_TRADE, {[] {return DekuMask && SwampTitle;}}), LocationAccess(GORON_VILLAGE_LEDGE, {[] {return DekuMask && SwampTitle;}}), LocationAccess(GORON_VILLAGE_POWDER_KEG_CHALLENGE_SPRING, {[] {return GoronMask && (SnowheadClear || CanUse(FIRE_ARROWS));}}), - LocationAccess(GORON_VILLAGE_SCRUB_PURCHASE_SPRING, {[] {return AnyWallet && GoronMask && (ProgressiveBombBag >= 2);}}), - LocationAccess(GORON_VILLAGE_SCRUB_TRADE_SPRING, {[] {return DekuMask && SwampTitle;}}), - LocationAccess(GORON_VILLAGE_LEDGE_SPRING, {[] {return DekuMask && SwampTitle;}}), + LocationAccess(GORON_VILLAGE_SCRUB_PURCHASE_SPRING, {[] {return AnyWallet && GoronMask && (ProgressiveBombBag >= 2) && SnowheadClear;}}), + LocationAccess(GORON_VILLAGE_ZORA_SCRUB_PURCHASE_SPRING, {[] {return CanTradeMountainDeed && SwampTitle && SnowheadClear;}}), + LocationAccess(GORON_VILLAGE_SCRUB_TRADE_SPRING, {[] {return DekuMask && SwampTitle && SnowheadClear;}}), + LocationAccess(GORON_VILLAGE_LEDGE_SPRING, {[] {return DekuMask && SwampTitle && SnowheadClear;}}), }, { //Exits @@ -1671,12 +1681,14 @@ void AreaTable_Init() { areaTable[ZORA_HALL_LULUS_ROOM] = Area("Zora Hall Lulu's Room", "Zora Hall Lulu's Room", NONE, { //Events + EventAccess(&CanTradeMountainDeed, {[] {return MountainTitle && GoronMask;}}), }, { //Locations LocationAccess(ZORA_HALL_SCRUB_TRADE, {[] {return GoronMask && MountainTitle;}}), LocationAccess(ZORA_HALL_LULU_ROOM_LEDGE, {[] {return GoronMask && DekuMask && MountainTitle;}}), LocationAccess(ZORA_HALL_SCRUB_PURCHASE, {[] {return ZoraMask;}}), + LocationAccess(ZORA_HALL_IKANA_SCRUB_PURCHASE, {[] {return HasBottle && CanTradeOceanDeed && MountainTitle;}}), }, { //Exits @@ -1895,6 +1907,7 @@ void AreaTable_Init() { areaTable[IKANA_CANYON] = Area("Lower Ikana Canyon", "Lower Ikana Canyon", IKANA_CANYON, { //Events EventAccess(&EnterSakonHideout, {[]{return SpokeToKafei;}}),//Sakon spawns if Kafei was met in Laundry Pool + EventAccess(&CanTradeOceanDeed, {[] {return OceanTitle && ZoraMask;}}), }, { //Locations diff --git a/source/logic.cpp b/source/logic.cpp index 413726e..58cfa4e 100644 --- a/source/logic.cpp +++ b/source/logic.cpp @@ -322,6 +322,11 @@ namespace Logic { bool Milk = false; bool SpokeToKafei = false; bool PostedKafeiLetter = false; + bool CanTradeTownDeed = false; + bool CanTradeSwampDeed = false; + bool CanTradeMountainDeed = false; + bool CanTradeOceanDeed = false; + bool CanBuyBeans = false; bool CanGoToMoon = false; @@ -516,12 +521,13 @@ namespace Logic { HasExplosives = AnyBombBag || (BlastMask && AnyShield);//Shield required to use Blast Mask without killing the player //Item Helpers - AnyMagicBean = MagicBean || LimitlessBeans; + AnyMagicBean = (MagicBean && CanBuyBeans) || LimitlessBeans; AnyWallet = Townwallet200 || OceanWallet500 || (ProgressiveWallet >= 1); AnyBottle = WitchBottle || AlienBottle || BeaverRaceBottle || ArcheryBottle || GoronRaceBottle || ChateauBottle || UsableMysteryMilkBottle || HasBottle; MagicMeter = (ProgressiveMagic >= 1) || MagicPower || ExtendedMagicPower; Scarecrow = Hookshot && CanPlay(ScarecrowSong); AnyPaper = (LandTitle || SwampTitle || OceanTitle || MountainTitle || LetterKafei || LetterMama); + CanBuyBeans = MagicBeanPack; //Bombs & Bombchus AnyBombBag = (ProgressiveBombBag >= 1) || BombBag20 || TownBombBag || MountainBombBag; @@ -879,7 +885,11 @@ namespace Logic { Milk = false; SpokeToKafei = false; PostedKafeiLetter = false; - + CanTradeTownDeed = false; + CanTradeSwampDeed = false; + CanTradeMountainDeed = false; + CanTradeOceanDeed = false; + CanBuyBeans = false; ZoraEgg = 0; CanGoToMoon = false; diff --git a/source/patch.cpp b/source/patch.cpp index ac98fc1..a5a742b 100644 --- a/source/patch.cpp +++ b/source/patch.cpp @@ -3,7 +3,7 @@ #include "cosmetics.hpp" #include "custom_messages.hpp" #include "music.hpp" -//#include "shops.hpp" +#include "shops.hpp" #include "spoiler_log.hpp" //#include "entrance.hpp" #include "item_location.hpp" @@ -230,25 +230,6 @@ bool WriteAllPatches() { } } */ - /*-------------------------------- - | rShopsanityPrices | - --------------------------------*/ -/* - if (Settings::Shopsanity.IsNot(SHOPSANITY_OFF) && Settings::Shopsanity.IsNot(SHOPSANITY_ZERO)) { - //Get prices from shop item vector - std::array rShopsanityPrices{}; - for (i = 0; i < 32; i++) { - rShopsanityPrices[i] = NonShopItems[i].Price; - } - - // Write shopsanity item prices to the patch - patchOffset = V_TO_P(RSHOPSANITYPRICES_ADDR); - patchSize = sizeof(rShopsanityPrices); - if (!WritePatch(patchOffset, patchSize, (char*)(&rShopsanityPrices), code, bytesWritten, totalRW, buf)) { - return false; - } - } - */ /*--------------------------------- | rDungeonRewardOverrides | ---------------------------------*/ diff --git a/source/playthrough.cpp b/source/playthrough.cpp index 0d20675..75fd2af 100644 --- a/source/playthrough.cpp +++ b/source/playthrough.cpp @@ -81,6 +81,9 @@ namespace Playthrough { CreateClockTowerDoorHints(); CreateMoonChildHint(); CreateOtherHints(); + if (Settings::Shopsanity.Value()) { + CreateShopMessages(); + } playthroughLocations.clear(); wothLocations.clear(); diff --git a/source/setting_descriptions.cpp b/source/setting_descriptions.cpp index 1a3bd0e..801dd2f 100644 --- a/source/setting_descriptions.cpp +++ b/source/setting_descriptions.cpp @@ -211,8 +211,8 @@ string_view shuffleRewardsAnywhere = "Boss Remains can appear anywhere.\n"; | SHUFFLE MAGIC BEANS | // ------------------------------*/ // string_view magicBeansDesc = "**OPTION CURRENTLY WIP**\n" // - "Enabling this adds a pack of 10 beans to the item\n" - "pool and changes the Magic Bean Salesman to sell a" + "Enabling this adds a pack of 20 beans to the item\n" + "pool and changes the Magic Bean Salesman to sell a\n" "random item at a price of 60 rupees."; // /*------------------------------ // | SHUFFLE KOKIRI SWORD | // @@ -455,29 +455,11 @@ string_view linksPocketNothing = "**OPTION CURRENTLY WIP**\n" | SHOPSANITY | // ------------------------------*/ // string_view shopsOff = "All shop items will be the same as vanilla."; // -string_view shopsZero = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops."; // -string_view shopsOne = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops, and each shop will contain\n" // - "one non-vanilla shop item."; // -string_view shopsTwo = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops, and each shop will contain\n" // - "two non-vanilla shop items."; // -string_view shopsThree = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops, and each shop will contain\n" // - "three non-vanilla shop items."; // -string_view shopsFour = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops, and each shop will contain\n" // - "four non-vanilla shop items."; // -string_view shopsRandom = "**OPTION CURRENTLY WIP**\n" // - "Vanilla shop items will be shuffled among\n" // - "different shops, and each shop will contain\n" // - "1-4 non-vanilla shop items."; // +string_view shopsOn = "Items in Shops will be randomized, this includes\n"// + "Trading Post, Bomb Shop, Swamp Potion Shop, Goron\n"// + "Village and Zora Hall Shops."; // +string_view shopPricesRandom = "Shop items will have random prices."; // +string_view shopPricesAffordable = "Shop items will have affordable prices."; // /*------------------------------ // | TOKENSANITY | // ------------------------------*/ // @@ -488,20 +470,14 @@ string_view tokensAllTokens = "Effectively adds 60 new locations for i /*------------------------------ // | SCRUB SHUFFLE | // ------------------------------*/ // -string_view scrubsOff = "Deku Scrub Salesmen will not be randomized"; // -string_view scrubsAffordable = "**OPTION CURRENTLY WIP**\n" // - "All Scrub prices will be reduced to 10 rupees each"; -string_view scrubsExpensive = "**OPTION CURRENTLY WIP**\n" // - "All Scrub prices will be their vanilla prices.\n";// -string_view scrubsRandomPrices = "**OPTION CURRENTLY WIP**\n" // - "All Scrub prices will be between 0-95 rupees. This" - "will on average be very, very expensive overall.";// +string_view scrubsOff = "Deku Scrub Purchases will not be randomized."; // +string_view scrubsOn = "Deku Scrub Purchases will be randomized."; // /*------------------------------ // | SHUFFLE COWS | // ------------------------------*/ // string_view shuffleCowsDesc = "Enabling this will let cows give you items upon\n"// "performing Epona's song in front of them. There\n"// - "are 7 cows"; // + "are 7 cows."; // // /*------------------------------ // | SHUFFLE OCARINAS | // @@ -509,7 +485,7 @@ string_view shuffleCowsDesc = "Enabling this will let cows give you it string_view ocarinasDesc = "Setting this to No shuffles the Ocarina of Time\n"// "into the item pool." // "\n" // - "This will require finding an Ocarina before being\n" + "This will require finding the Ocarina before being\n" "able to play songs or restart the cycle"; // /*------------------------------ // @@ -627,6 +603,8 @@ string_view skipHMSCutsceneDesc = "Skips the initial Happy Mask Salesman's c string_view skipDarmaniCutsceneDesc = "Skips the Song of Healing Cutscene for Darmani"; // string_view skipMikauCutsceneDesc = "Skips the Song of Healing Cutscene for Mikau"; // string_view skipGiantCutsceneDesc = "Skips the cutscene of the giants catching the moon";// +string_view skipPirateCutsceneDesc = "Skips the cutscene of the pirates attempting to enter\n"// + "Great Bay Temple after hookshotting onto the turtle";// /*------------------------------ // | REGION OPTIONS | // ------------------------------*/ // @@ -686,4 +664,31 @@ string_view startingShieldMirrorDesc = "Start with the Mirror Shield.\n" ------------------------------*/ // string_view showPostmanItemDesc = "Visually shows the reward for the \n" // "Postman's Freedom quest line \n" // - "above the Postman's head."; // \ No newline at end of file + "above the Postman's head."; // + +/*------------------------------ +| IN-GAME OPTIONS | +------------------------------*/ +string_view ingameLTargetingDesc = "Sets the L-Targeting mode on a new file.\n" // + "\"Vanilla\" is the game's default."; // +string_view ingameFirstPersonCameraDesc = "Sets the first person camera's inversion on a\n"// + "new file. \"Vanilla\" is the game's default."; // +string_view ingameFreeCameraDesc = "Sets the free camera's inversion on a new\n" // + "file. \"Vanilla\" is the game's default."; // +string_view ingameMotionControlsDesc = "Enables or disables motion controls on a new\n" // + "file. \"Vanilla\" is the game's default."; // +string_view ingameSwimmingControlsDesc = "Sets the Zora swimming control scheme on a new\n"// + "file. \"Vanilla\" is the game's default."; // +string_view ingameAdjustVolumeDesc = "Sets the overall volume on a new file.\n" // + "\"Vanilla\" is the game's default."; // +string_view ingameMuteSoundDesc = "Enables or Disables Sound Effects on a new file.";// +string_view ingameMuteBGMDesc = "Enables or Disables Background Music on a new file.";// +string_view ingameFastSongsDesc = "Allows for Adjusting length of playback of songs.\n"// + "Don't Skip = Vanilla,\n" // + "Skip allows for faster movement after playing song\n"// + "With or without song audio playback."; // +string_view ingameShuffleSFXDesc = "Shuffle Sound Effects: \n" // + "Categorical = SFX are shuffled amongst similar sounds\n"// + "Chaos = All SFX shuffled with no restrictions.\n"// + "Link Only = Only Link's actions, items and voice\n"// + "are shuffled, each among its own kind."; // \ No newline at end of file diff --git a/source/settings.cpp b/source/settings.cpp index de57cf7..73cc1ff 100644 --- a/source/settings.cpp +++ b/source/settings.cpp @@ -375,9 +375,10 @@ namespace Settings { Option ShuffleSongs = Option::U8 ("Shuffle Songs", {"Off", "Song Locations", "Anywhere"}, {songsVanilla, songsSongLocations, songsAllLocations}, OptionCategory::Setting, 0); Option ShuffleSoaring = Option::Bool("Shuffle Song of Soaring",{"Off", "On"}, {shuffleSoaringVanilla, shuffleSoaringRandom}, OptionCategory::Setting, 0); Option ShuffleSongOfTime = Option::Bool("Shuffle Song of Time", {"Off", "On"}, {songTimeVanilla, songTimeRandom}, OptionCategory::Setting, 0); - Option Shopsanity = Option::U8 ("Shopsanity", {"Off", "0", "1", "2", "3", "4", "Random"}, {shopsOff, shopsZero, shopsOne, shopsTwo, shopsThree, shopsFour, shopsRandom}); - Option Tokensanity = Option::Bool("Tokensanity", {"Off", "On"}, {tokensOff, tokensAllTokens}); - Option Scrubsanity = Option::U8 ("Shuffle Scrub Wares", {"Off", "Affordable", "Expensive", "Random Prices"}, {scrubsOff, scrubsAffordable, scrubsExpensive, scrubsRandomPrices}); + Option Shopsanity = Option::Bool("Shopsanity", {"Off", "On"}, {shopsOff, shopsOn}, OptionCategory::Setting, 0); + Option ShopsanityPrices = Option::Bool("Shopsanity Prices", {"Random", "Affordable"}, {shopPricesRandom, shopPricesAffordable}, OptionCategory::Setting, 0); + Option Tokensanity = Option::Bool("Tokensanity", {"Off", "On"}, {tokensOff, tokensAllTokens}, OptionCategory::Setting, 0); + Option Scrubsanity = Option::Bool("Shuffle Scrub Purchases",{"Off", "On"}, {scrubsOff, scrubsOn}, OptionCategory::Setting, 0); Option ShuffleMerchants = Option::Bool("Shuffle Scrub Trades", {"Off", "On"}, {shuffleMerchantsDesc}); Option ShuffleTradeItems = Option::Bool("Shuffle Anju and Kafei",{"Off", "On"}, {shuffleTradeItemsDesc}); Option ShuffleGFRewards = Option::U8 ("Shuffle Fairy Rewards", {"Off", "Great Fairies", "Anywhere" }, {shuffleGFVanilla, shuffleGFSelf, shuffleGFAnywhere}, OptionCategory::Setting, (u8)GreatFairyRewardShuffleSetting::GFREWARDSHUFFLE_VANILLA); @@ -402,7 +403,8 @@ namespace Settings { &ShuffleSoaring, &ShuffleSongOfTime, &Tokensanity, - //&Shopsanity, + &Shopsanity, + &ShopsanityPrices, &ShuffleGFRewards, }; @@ -412,7 +414,8 @@ namespace Settings { &ShuffleTingleMaps, &ShuffleBombersNotebook, &ShuffleCows, - //&ShuffleMagicBeans, + &ShuffleMagicBeans, + &Scrubsanity, &ShuffleMoonItems, &ShuffleFierceDeity, }; @@ -492,6 +495,37 @@ namespace Settings { Option BombchusInLogic = Option::U8("Bombchus In Logic", { "Off", "On" }, { bombchuInLogicDesc }); Option FastMasks = Option::Bool("Fast Mask Transform", {"No", "Yes"}, {fastMaskDesc}); Option NotebookAnimations = Option::Bool("Fast Notebook", {"No", "Yes"}, {disableBotebookAnimation}); + + // In-game options written into CommonDataSub1 when a new file is created. Index 0 is + // "Vanilla" throughout, which leaves the game's own default in place -- only the Adjust + // Volume encoding (0 Lower / 1 Normal / 2 Higher) is confirmed against the save data, so the + // rest are opt-in rather than applied silently. + Option IngameLTargeting = Option::U8("L-Targeting", {"Vanilla", "Switch", "Hold"}, {ingameLTargetingDesc}); + Option IngameFirstPersonCamera = Option::U8("First Person Camera", {"Vanilla", "Normal", "Invert Y Axis", "Invert X Axis", "Invert Both"}, {ingameFirstPersonCameraDesc}); + Option IngameFreeCamera = Option::U8("Free Camera", {"Vanilla", "Normal", "Invert Y Axis", "Invert X Axis", "Invert Both"}, {ingameFreeCameraDesc}); + Option IngameMotionControls = Option::U8("Motion Controls", {"Vanilla", "On", "Off"}, {ingameMotionControlsDesc}); + Option IngameSwimmingControls = Option::U8("Swimming Controls", {"Vanilla", "Normal", "Invert Y Axis"}, {ingameSwimmingControlsDesc}); + Option IngameAdjustVolume = Option::U8("Adjust Volume", {"Vanilla", "Lower", "Normal", "Higher"}, {ingameAdjustVolumeDesc}); + Option IngameMuteSound = Option::Bool("Mute Sound Effects", {"Off", "On"}, {ingameMuteSoundDesc}); + Option IngameMuteBGM = Option::Bool("Mute Background Music", {"Off", "On"}, {ingameMuteBGMDesc}); + Option IngameFastSongs = Option::U8("Fast Ocarina Songs", {"Don't Skip", "Skip (No Audio)", "Skip (W/ Audio)"}, {ingameFastSongsDesc}); + Option ShuffleMusic = Option::U8("Shuffle Music", {"Off", "BGM", "Fanfares", "All"}, {musicRandoDesc}); + Option IngameShuffleSFX = Option::U8("Shuffle Sound Effects", {"Off", "Categorical", "Chaos", "Link Only"}, {ingameShuffleSFXDesc}); + + std::vector ingameOptions = { + &IngameLTargeting, + &IngameFirstPersonCamera, + &IngameFreeCamera, + &IngameMotionControls, + &IngameSwimmingControls, + &IngameAdjustVolume, + &IngameFastSongs, + &IngameMuteSound, + &IngameMuteBGM, + &ShuffleMusic, + &IngameShuffleSFX, + }; + std::vector comfortOptions = { &BlastMaskCooldown, @@ -514,7 +548,7 @@ namespace Settings { Option GoodDampeRNG = Option::Bool("Good Dampe RNG", { "No", "Yes" }, { goodDampeRNGDesc }); Option IncreasePushSpeed = Option::Bool("Increased Push Speed", { "No", "Yes" }, { increasePushSpeedDesc }); Option FastArrowSwitch = Option::Bool("Fast Arrow Switching", { "No", "Yes" }, { fastArrowSwitchDesc }); - Option FastElegyStatues = Option::Bool("Fast Elegy Statues", { "No", "Yes" }, { fastElegyStatuesDesc }); + //Option FastElegyStatues = Option::Bool("Fast Elegy Statues", { "No", "Yes" }, { fastElegyStatuesDesc }); Option SkipSongReplays = Option::U8("Skip Song Replays", { "Don't Skip", "Skip (No SFX)", "Skip (Keep SFX)" }, {skipSongReplaysDesc}); Option SkipEponaRace = Option::Bool("Skip Epona Race", { "No", "Yes" }, { skipEponaRaceDesc }); Option OcarinaDive = Option::Bool("Ocarina Dive", { "No", "Yes" }, {ocarinaDiveDesc}); @@ -533,7 +567,7 @@ namespace Settings { //&GoodDampeRNG, //&IncreasePushSpeed, //&FastArrowSwitch, - &FastElegyStatues, + //&FastElegyStatues, &FastZoraSwim, &OcarinaDive, &DpadTransform, @@ -548,11 +582,13 @@ namespace Settings { Option SkipDarmaniCutscenes = Option::Bool("Skip Darmani Cutscenes", {"Don't Skip", "Skip"}, {skipDarmaniCutsceneDesc}); Option SkipMikauCutscenes = Option::Bool("Skip Mikau Cutscenes", {"Don't Skip", "Skip"}, {skipMikauCutsceneDesc}); Option SkipGiantCutscenes = Option::Bool("Skip Giants Cutscene", {"Don't Skip", "Skip"}, {skipGiantCutsceneDesc}); + Option SkipPirateCutscenes = Option::Bool("Skip Pirate Cutscenes", {"Don't Skip", "Skip"}, {skipPirateCutsceneDesc}); std::vector