diff --git a/README.md b/README.md
index a662c26..ea16390 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,50 @@
# Tunic Randomizer Archipelago Client
-This is the Archipelago version of the TUNIC Randomizer mod. If you are looking for the standalone, single-player version of the mod, you can find it [here](https://github.com/silent-destroyer/tunic-randomizer).
-This mod features randomization of every item in the game through Archipelago, as well as enemy randomization, enhanced fox customization, custom items, and much, much more!
+# PLEASE READ!
+The Tunic Archipelago mod has been combined with the single-player randomizer into a single mod, and has moved to the [original Tunic Randomizer repository](https://github.com/silent-destroyer/tunic-randomizer). As a result, this repository will no longer be updated, and all future updates for the Tunic Archipelago integration will be released there.
-For questions, feedback, or discussion related to the randomizer, please visit the dedicated randomizer channel in the [Tunic Speedrunning Discord](https://discord.gg/HXkztJgQWj)!
+This randomizer features item, entrance, and enemy randomization, as well as a variety of additional settings and features to help customize the experience, such as hints, custom items, and custom fox colors!
-The Archipelago version of the TUNIC Randomizer is still very much a work-in-progress, so expect bugs to happen and things to not work correctly. The quickest way to report bugs is to message me (silentdestroyer) directly on Discord.
+This mod contains both the standalone, single-player randomizer and the Archipelago Multiworld integration.
+
+For questions, feedback, bug reports, or other discussion related to the randomizer, please visit the dedicated randomizer channel in the [Tunic Speedrunning Discord](https://discord.gg/HXkztJgQWj)!
+
+For discussion around the Archipelago side of things, please visit the dedicated Tunic thread in the [Archipelago Discord](https://discord.gg/8Z65BR2).
## Installation
- Must use a compatible PC version of TUNIC on the latest update. The mod has been tested on Steam and PC Game Pass versions, but should realistically work on any PC version (including Steam Deck).
- If playing on Steam Deck, first follow this guide to [setting up BepInEx on Steam Deck via Proton](https://docs.bepinex.dev/articles/advanced/proton_wine.html).
-- Download the correct build/version of BepInEx from here: https://builds.bepinex.dev/projects/bepinex_be/572/BepInEx_UnityIL2CPP_x64_9c2b17f_6.0.0-be.572.zip, or alternatively search for it yourself by going to https://builds.bepinex.dev/projects/bepinex_be, finding Artifact #572, and downloading the "BepInEx Unity IL2CPP for Windows (x64) games" build.
+- Download the appropriate IL2CPP release of [BepInEx 6](https://github.com/BepInEx/BepInEx/releases/download/v6.0.0-pre.1/BepInEx_UnityIL2CPP_x64_6.0.0-pre.1.zip).
- ![image](https://user-images.githubusercontent.com/110704408/188519149-d9476aa9-55f6-4f38-9ce9-93d137fa71af.png)
-- Extract the zip folder you downloaded from the previous step into your game's install directory (For example: C:\Program Files (x86)\Steam\steamapps\common\TUNIC)
+- Extract the BepInEx zip folder you downloaded from the previous step into your game's install directory (For example: C:\Program Files (x86)\Steam\steamapps\common\TUNIC)
- For the PC Game Pass version, extract the zip into the `Content` folder, i.e. C:\XboxGames\Tunic\Content
- Launch the game and close it. This will finalize the BepInEx installation.
-- [Download and extract the TunicArchipelago.zip file from the latest release.](https://github.com/silent-destroyer/tunic-randomizer-archipelago/releases/latest)
- - Copy the `Tunic Archipelago` folder from the release zip into BepInEx/plugins under your game's install directory.
- - This folder contains an `ArchipelagoSettings.json` file, which is where you will fill in your PlayerName, Hostname, Port, and Password (if needed).
- - The release download contains two files called `tunic.apworld` and `tunic.yaml`. These are not needed for the mod itself but are used in the next section for setting up a multiworld game. See "Generating a Multiworld".
-- Launch the game again and you should see `Randomizer + Archipelago Mod Ver. x.y.z` on the top left of the title screen!
-- To uninstall the mod, either remove/delete the `Tunic Archipelago` folder from the plugins folder or rename the winhttp.dll file located in the game's root directory (this will disable all installed mods from running).
+- [Download and extract the `Tunic Randomizer.zip` file from the latest release.](https://github.com/silent-destroyer/tunic-randomizer/releases/latest)
+ - Copy the `Tunic Randomizer` folder from the release zip into `BepInEx/plugins` under your game's install directory.
+ - Your plugins folder should have a `Tunic Randomizer` folder with `three .dll files` inside.
+- Launch the game again and you should see `Randomizer Mod Ver. x.y.z` on the top left of the title screen!
+- To uninstall the mod, either remove/delete the `Tunic Randomizer` folder from the plugins folder or rename the winhttp.dll file located in the game's root directory (this will disable all installed mods from running).
+## Starting a Single Player Randomizer
+- On the Title Screen, select `Single Player`, and select any additional settings you wish to play with. Descriptions of all of them can be found below.
+- Optionally, clicking Generate Seed will create a seed that you can then share with others by pressing the Copy Seed/Settings button. This will generate a settings string that another player can import by copying and then pressing Paste Seed/Settings.
+- Click New Game and have fun!
-## Generating a Multiworld
+## Generating a Multiworld with Archipelago
- In order to setup a multiworld you must first install the latest release of [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases/latest).
- When running the Archipelago Setup exe, you'll at least want to install the Generator and Text Client, but can install any other components you may need as well for other games.
- After installing, run `Archipelago Launcher` and click on `Browse Files`.
- This will open the local file directory for your Archipelago installation.
-- Place `tunic.yaml` from the TunicArchipelago release inside of the `Players` folder.
+- In the .zip you downloaded from the release page, there should be two files called `tunic.apworld` and `tunic.yaml`.
+- Place `tunic.yaml` from the Tunic Randomizer release inside of the `Players` folder.
- `tunic.yaml` needs to be configured before you can generate a game. Open the file in a text editor and fill in your player name and choose the settings you want.
- You will also need to get the .yaml files for everyone who is joining your multiworld and place them inside of the `Players` folder as well.
-- Place `tunic.apworld` from the TunicArchipelago release inside of `lib/worlds`.
+- Place `tunic.apworld` from the Tunic Randomizer release inside of `lib/worlds`.
- Once all of the .yaml fies have been configured and placed into `Players`, click `Generate` in the Archipelago Launcher.
-- A .zip file will be created in the `output` folder containing the information for your multiworld. In order to host your game, go to [https://archipelago.gg/uploads](https://archipelago.gg/uploads) and upload the .zip file, then click `Create New Room`.
-- Configure your `ArchipelagoSettings.json` from before with your player name and the hostname/port you see in the newly created room (Ex: archipelago.gg:32517, the hostname is `archipelago.gg` and the port is `32517`).
-- All that's left is to launch the game and, if it says `Connected`, start a New Game and being your game!
+- A .zip file will be created in the `output` folder containing the information for your multiworld. In order to host your game, go to [https://archipelago.gg/uploads](https://archipelago.gg/uploads) and upload the .zip file, then click `Create New Room`. Once the room is generated, write down/copy the port number that is displayed for the port.
+- Launch the game and select `Archipelago` on the Title Screen, then click `Edit AP Config` and fill in your connection details. Alternatively, you can click `Open Settings File` to edit the file with the connection settings directly.
+- All that's left is to press Connect, and if it says `Connected`, simply start a New Game and have fun!
- For more information, see the official [Archipelago Setup Guide](https://archipelago.gg/tutorial/Archipelago/setup/en).
## Helpful Tips
@@ -45,6 +52,7 @@ The Archipelago version of the TUNIC Randomizer is still very much a work-in-pro
- West Garden is logically accessible with either the Lantern or Hero's Laurels.
- The Eastern Vault Fortress is accessible with either the Lantern (and Prayer) or Hero's Laurels (with or without Prayer).
- The Library is accessible with either the Hero's Laurels or the Magic Orb.
+ - The Swamp is available from the start via a secret path beneath the Overworld fuse, and another through the water to the right of the Swamp save statue.
- The Cathedral is accessible during the day by using the Hero's Laurels to access and activate the Overworld fuse near the Swamp entrance.
- The Scavenger's Mask is in logic to not be shuffled into the lower areas of Quarry or within the Ziggurat.
- The Holy Cross chest from the dancing fox ghost in East Forest can be spawned in during the daytime.
@@ -61,117 +69,122 @@ The Archipelago version of the TUNIC Randomizer is still very much a work-in-pro
- The portal in the trophy room in the back of the Old House is active from the start.
- The elevator in Cathedral is immediately accessible without activating the fuse. Activating the fuse does nothing.
- Regarding Hints:
- - The Mailbox will hint the general location of the Lantern.
- - The Hero's Grave in the Swamp, Monastery, and Library will hint the location of the three Hexagon keys.
- - The Hero's Grave in East Forest, West Garden, and the Eastern Vault Fortress are "Path of the Hero" hints, which hint towards a major progression item, such as Grapple, Lantern, Fire Wand, Ice Dagger, and/or the Prayer/Holy Cross pages (if playing with Ability Shuffling).
+ - The Mailbox will give a "First Steps" hint, pointing you in the direction of a useful/progression item that can be reached from the start of the game.
+ - The Hero's Graves in the Swamp, Monastery, and Library will hint the location of the three Hexagon keys.
+ - The Hero's Graves in East Forest, West Garden, and the Eastern Vault Fortress hint towards a major progression item, such as the Magic Orb, Lantern, Magic Wand, Magic Dagger, and/or the Prayer/Holy Cross pages if abilities are shuffled.
- The statue in the Sealed Temple will always hint the general location of the Hero's Laurels.
-- The "Fairy Seeker" Holy Cross spell (ULURDR) can now be used to seek out all items in an area, instead of just fairies. If all items in an area have been found, the fairy seeker will seek out the closest load zone that has items immediately beyond it. Useful for finding missing checks in areas with lots of obscured or hidden items!
-- Save files created by the randomizer will be marked with a "randomizer" tag in the file select screen to help differentiate them from your vanilla save files while the mod is loaded.
-- The Randomizer will routinely write to a couple of files in the Randomizer folder under the game's AppData directory (typically C:\Users\You\AppData\LocalLow\Andrew Shouldice\Secret Legend\Randomizer):
+- The "Fairy Seeker" Holy Cross spell (ULURDR) can be used to seek out all items in an area, instead of just fairies. If all items in an area have been found, the fairy seeker will seek out the closest load zone that has items immediately beyond it. Useful for finding missing checks in areas with lots of obscured or hidden items!
+- Save files created by the randomizer will be marked with a "randomizer" or "archipelago" tag in the file select screen to help differentiate them from your vanilla save files while the mod is loaded. The mod has protections in place to avoid loading vanilla saves on accident as well.
+- The mod will routinely write to a couple of files in the Randomizer folder under the game's AppData directory (typically C:\Users\You\AppData\LocalLow\Andrew Shouldice\Secret Legend\Randomizer):
- Spoiler.log - This file lists every check in the game and what item they contain. It will also mark off which checks you have collected.
- - ItemTracker.json - This file contains information such as the current seed number, what important items have been obtained, and a running list of all checks that have been found. Can be useful for creating external programs that interface with the randomizer, such as this [Tunic Rando Tracker](https://github.com/radicoon/tunic-rando-tracker) by Radicoon.
-- Custom seeds can be set on the title screen before starting a New Game, or can be changed by modifying the seed value in the save file created after starting a New Game. Pressing '2' on keyboard while in-game will display the current seed and settings being used.
-- The Randomizer will notify you on the title screen if a new update is available for the mod.
-- An [EmoTracker Package](https://github.com/SapphireSapphic/TunicTracker) exists for this game with a full map tracker, created by SapphireSapphic and ScoutJD.
+ - ItemTracker.json - This file contains information such as the current seed number, what important items have been obtained, and a running list of all checks that have been found. Can be useful for creating external programs that interface with the randomizer, such as this [Item Tracker](https://github.com/radicoon/tunic-rando-tracker) by Radicoon.
+- Custom seeds can be set on the title screen before starting a New Game.
+- The Randomizer will notify you on the title screen if a new update is available.
+- A [Map Tracker Package](https://github.com/SapphireSapphic/TunicTracker) exists for this game with a full map tracker, created by SapphireSapphic and ScoutJD. It can also be used with Poptracker, thanks to Br00ty.
## Settings
With the exception of the Logic settings (which are determined in your Archipelago yaml settings), all options can be freely toggled or changed at any point while playing.
-### Archipelago
-- Death Link
- - Want a more chaotice experience? When a player with Death Link enabled dies, everyone else with the setting on *also* dies. Be careful!
-- Auto-open !collect-ed Checks
- - With this enabled, chests and other item pickup locations that you haven't already found but were retrieved by another player via !collect will appear as open/already picked up.
- - This will also reflect the item counts on the inventory screen and on the end summary screen.
- - This setting can be toggled on/off at will, and the world will update/revert accordingly on the next scene transition.
### Logic
-- Game Mode
- - Choose between a classic randomizer experience or Hexagon Quest, a separate game mode inspired by Triforce Hunt in Zelda randomizers.
- - Classic Randomizer: Find the three Hexagon Keys and defeat The Heir or Share Your Wisdom to win.
- - Hexagon Quest: 30 Gold Hexagons are shuffled into the item pool. Find 20 of them and visit The Heir to win.
+- Hexagon Quest
+ - Gold Hexagons are shuffled into the item pool. Find the required amount of them and visit The Heir to win. The required amount can be customized in the Advanced Options menu.
- Keys Behind Bosses
- - Choose if the three Hexagon Keys are randomly shuffled or placed behind their respective bossfight.
- - In Hexagon Quest, this option guarantees a Gold Hexagon is placed behind each of the three major bosses.
+ - Places the three Hexagon Keys behind their respective bossfight. In Hexagon Quest, this option guarantees a Gold Hexagon is placed behind each of the three major bosses.
- Sword Progression
- - Replaces the stick and swords in the item pool with four Sword Upgrades that progressively level up as you find them.
+ - Replaces the stick and swords in the item pool with four Sword Upgrades that progressively level up as you find them, with the final two upgrades being custom swords that offer extended reach compared to the standard Sword and a free +1 to your Attack level when found.
- Level 1: Stick -> Level 2: Sword -> Level 3: Librarian's Sword -> Level 4: Heir's Sword
- - The Level 3 and 4 Swords are custom swords that offer extended reach compared to the standard Sword and a free +1 to your Attack level when found.
- Start With Sword
- The player will spawn with a Sword in the inventory on New Game. Does not count towards Sword Progression.
- Shuffle Abilities
- - Locks the ability to use Prayer, most Holy Cross codes*, and the Ice Rod combo technique until the respective manual page for each ability is found.
- - Prayer is unlocked by Page 24, Holy Cross is unlocked by Page 43, and Ice Rod is unlocked by Page 53.
+ - Locks the ability to use Prayer, most Holy Cross codes*, and the Icebolt combo technique until the respective manual page for each ability is found.
+ - Prayer is unlocked by Page 24, Holy Cross is unlocked by Page 43, and the Icebolt technique is unlocked by Page 53. If playing Hexagon Quest, abilities are unlocked when reaching 25%, 50%, and 75% of the required amount of Gold Hexagons.
- *This option only locks Holy Cross codes that block access to checks in the randomizer. The free bomb codes and other player-facing codes like Big Head Mode, Sunglasses, Fairy Seeker, etc. are still usable from the start.
- - This option does not currently apply when playing Hexagon Quest, as all pages are given from the start in that mode.
+- Entrance Randomizer
+ - Shuffles all the connections between doors, teleporters, portals, and more. Where will the fox end up?
+- Entrance Randomizer: Fewer Shop Entrances
+ - Reduces the amount of possible shops that can be found, and places a guaranteed shop entrance at the Overworld Windmill entrance.
+- Hero Laurels Location
+ - Place the Laurels at a predetermined location, currently the options are the 6 coin reward, 10 coin reward, or 10 fairy reward.
+- Lanternless Logic
+ - Removes the Lantern as a requirement for dark areas, allowing it (or items that grant access to it) to be shuffled into places like Dark Tomb, etc.
+- Maskless Logic
+ - Removes the Mask as a requirement for the miasma in Quarry, allowing it to get shuffled into lower Quarry or beyond.
+- Mystery Seed
+ - Randomly chooses logic options for you on New Game. Good luck!
+### Archipelago-Specific Settings
+- Death Link
+ - Want a more chaotic experience? When a player with Death Link enabled dies, everyone else with the setting on *also* dies. Be careful!
+- Auto-open !collect-ed Checks
+ - Makes checks that you haven't found but were completed by another player (via !collect, slot co-op, etc) appear as already been opened/picked up. Also reflects the item counts on the inventory screen/ending summary. Can be toggled on/off freely, and will revert the appearance of checks to their previous state on the next scene transition.
+- Send hints to server
+ - This setting will record certain hints from the ghost foxes and any shop items you inspect in the Archipelago Text Client.
### Hints
- Path of the Hero
- Places a major hint at specific locations around the world, including the Mailbox, the Hero Graves, and the statue in the Sealed Temple. These hint towards major progression items, such as Magic Items, Laurels, Hexagons, and more.
- Ghost Foxes
- Spawns 15 Ghost Fox NPCs around the world that give minor hints. These hints include the locations of useful non-progression items, items in hard-to-reach locations, and barren locations.
- - There are over 50 unique Ghost Fox spawns, all with their own custom Trunic dialogue!
+ - There are over 50 unique Ghost Fox spawns, so be on the lookout!
- Freestanding Items and Chests Match Contents
- All freestanding items (Item Pickups, Page Pickups, Shop Items, Hero's Grave Relics, etc.) will have their model swapped to appear as the item they are randomized as.
- Chest textures will be swapped to indicate what item is in them. Currently, the items with different chest textures are Fairies, Golden Trophies, the three Hexagons, and the Hero's Laurels.
+- Display Hints in Trunic
+ - For the experienced Ruin Seekers out there, this option removes most English words from custom dialogue, hints, or other text produced by the randomizer, leaving it up to your own knowledge to figure out what is where.
### General
- Easier Heir Fight
- Attacks deal additional damage to The Heir based on the total number of checks found.
- Cheaper Shop Items
- - Reduces the cost of the four randomized Shop items from 1000 to 300.
+ - Reduces the cost of the four randomized Shop items to 300 bits each.
- Bonus Upgrades
- Makes the Golden Trophy items give free Level Ups for certain stats, allowing you to get up to +8 in every stat in a single playthrough when combined with the regular stat upgrades and the +2 Attack levels from Sword Progression.
- - Note: Bonus upgrades will not be retroactively awarded if this setting is turned on after obtaining Golden Trophies with it disabled. The +2 Attack Levels from Sword Progression are always awarded and not affected by this setting.
+ - Note: Bonus upgrades will not be retroactively awarded if this setting is turned on after obtaining Golden Trophies with it disabled. The +2 Attack Levels from Sword Progression are always awarded and are not affected by this setting.
- Disable Chest Interruption
- Enemies will not be able to interrupt you while opening chests if this option is turned on.
+- Skip Item Popups
+ - Turns off the item/page popups when receiving items.
+- Skip Upgrade Animations
+ - Skips the animation that plays when upgrading stats.
- Fool Traps
- - Enables fool traps, which replace low-value money rewards when enabled and apply damage or other negative effects to the player.
- - The different options determine how many fools are present, with None/Normal/Double/Onslaught containing 0/15/32/50 fools respectively.
+ - Enables fool traps, which replace low-value money rewards when enabled and apply damage/other negative effects to the player. Turning the setting up increases the amount of traps in the item pool.
+ - For Single Player seeds, this option can be changed mid-run by changing the value and reloading the save file. For Archipelago games, this is a yaml option and cannot be changed after the game starts.
- ???
- !esirprus a rof no nruT
+- More Skulls
+ - Does exactly what it says on the tin.
+- Arachnophobia Mode
+ - Turns the spiders and another mulit-legged enemy into...something else.
### Enemy Randomization
- Enemy Randomizer
- - Randomly swaps out enemies with new ones when you load into a scene. See below settings for ways to affect enemy difficulty/generation.
- - There is currently no logic for certain edge cases where grappling to an enemy may be required to reach a check (ex. East Forest Slime, Turret in Overworld/Frog's Domain). The Enemy Randomizer can be toggled on or off at any point while playing however, so if you find yourself unable to reach certain checks it is recommended to briefly turn the setting off to get the check and then turn it back on afterwards.
- - Enemy Randomization is still a work-in-progress feature and may randomly stop working or cause the game to stutter/lag after a while. If either of these situations occur, restarting the game should temporarily fix the issue.
+ - Randomly swaps out enemies with new ones when you load into a scene. You may even see some enemies you've never seen before!
- Extra Enemies
- Enables certain NG+ and nighttime enemy slots to add more enemies into the mix for increased chaos.
- Enemy Difficulty
- Random: No balancing is performed, and all new enemy spawns are chosen randomly from the full pool of enemies.
- - Balanced: Enemies will only be replaced with an enemy of similar difficulty.
+ - Balanced: Enemies are replaced with an enemy of similar difficulty.
- Enemy Generation
- Random: Enemies will change every time you leave and come back to an area.
- Seeded: Enemy spawns will remain consistent per area.
### Fox Customization 🦊
- Random Fox Colors
- - Fox colors will randomize everytime you enter a new scene, rest at a shrine, or load from the menu.
- - Pressing '5' on keyboard will randomize fox colors on demand.
+ - Fox colors will randomize on every load/scene transition.
- Keepin' It real
- Toggles Sunglasses on/off without needing to use the Holy Cross code.
- Fox Color Editor
- - Opens an in-depth fox palette editor that allows you to create/save/load a custom color palette texture for the fox.
-- Use Custom Texture
- - When enabled, will always apply the saved custom texture to the fox. Note: Random Fox Colors should be disabled when using this setting or it may not work properly.
- - The custom texture can be found under AppData in the same folder as the Spoiler log and Item Tracker file.
-
-## Custom Items
-### Dath Stone
-![image](https://github.com/silent-destroyer/tunic-randomizer/assets/110704408/a5797e96-66c6-4abd-ba94-ca61019a79d8)
-- This item combines two unused items in the game into one and allows you to warp back to the last statue you saved at when used.
-- What does Dath mean? The trunic characters on the item icon were presumably meant to spell "Dash", but instead they spell out "Dath", so the community has dubbed this item the "Dath Stone".
-
-### Librarian and Heir Swords
-![image](https://github.com/silent-destroyer/tunic-randomizer/assets/110704408/412935ea-b5ab-4d96-b181-678a39025901) ![image](https://github.com/silent-destroyer/tunic-randomizer/assets/110704408/92e6b5d3-1d30-49ff-a344-1d8295e593dd)
-- These familiar swords are now usable in the game as part of the Sword Progression mode!
-- The Librarian Sword (Level 3) offers additional reach over the base sword, as well as a free +1 to your Attack stat level.
-- the Heir Sword (Level 4) offers slightly more range than the Librarian Sword, another free +1 Attack, and also has the added bonus of ignoring collision with metalllic objecs, including enemy shields.
-
-## Golden Hexagons
-![image](https://github.com/silent-destroyer/tunic-randomizer/assets/110704408/361efdaa-1849-44ee-9b2c-504d7f05c46e)
-- These appear when playing the Hexagon Quest mode. Finding 20 of them allows you to end the game by visiting The Heir.
-
-## ???
-![image](https://github.com/silent-destroyer/tunic-randomizer/assets/110704408/ed015b2c-7b93-4d23-8728-b36b5cba36d1)
-- ???
+ - Allows you to customize the colors of your fox with more options than what the base game offers, and save it as a custom texture for future use.
+- Custom Fox Texture
+ - When enabled, will always apply the saved custom texture to the fox. The custom texture can be found under AppData in the same folder as the Spoiler log and Item Tracker file.
+### Race Mode Settings
+- Race Mode
+ - An option to help facilitate ranomizer races more easily. Disables the spoiler log, and enables the options below to be used.
+- Disable Icebolt in The Heir Fight
+ - Disables use of the icebolt technique when fighting The Heir.
+- Disable Long-Distance Bell Shots
+ - Prevents you from ringing the West Bell early, by shoowing it with the Magic Wand from far away.
+- Disable Ice Grappling
+ - Prevents you from pulling yourself towards frozen enemies with the Magic Orb. (The East Forest blob is excluded from this.)
+- Disable Ladder Storage
+ - Prevents the Ladder Storage glitch from being used.
## Credits
- Glace and RisingStar111 for helping research how to mod this game, and Jabberrock for creating an initial Archipelago integration.
-- Radicoon, kingsamps0n, Landie, JimTheEternal, SapphireSapphic, ScoutJD, Scipio, and many others for playtesting and helping to improve the mod.
+- Scipio for helping out with the entrance randomizer and Archipelago implementation.
+- Radicoon, Glace, RisingStar111, kingsamps0n, Landie, JimTheEternal, SapphireSapphic, ScoutJD, and many others for playtesting and helping to improve the mod.
- Andrew Shouldice, Kevin Regamey, Finji, and everyone else involved in making this wonderful game.
diff --git a/Tunic.yaml b/Tunic.yaml
index 01a384e..d75be50 100644
--- a/Tunic.yaml
+++ b/Tunic.yaml
@@ -8,10 +8,10 @@
#
name: Ruin Seeker
description: tunc
-game: Tunic
+game: TUNIC
requires:
version: 0.4.4
-Tunic:
+TUNIC:
# Play with sword upgrades enabled.
sword_progression: 'true'
# Start with a sword.
diff --git a/TunicArchipelago.csproj b/TunicArchipelago.csproj
index bb944bf..9429dd5 100644
--- a/TunicArchipelago.csproj
+++ b/TunicArchipelago.csproj
@@ -8,7 +8,7 @@
Library
Properties
TunicArchipelago
- TunicArchipelago
+ TunicRandomizer
v4.8
512
true
@@ -166,11 +166,13 @@
-
+
+
+
diff --git a/src/Archipelago/Archipelago.cs b/src/Archipelago/Archipelago.cs
index a20d886..4e69cad 100644
--- a/src/Archipelago/Archipelago.cs
+++ b/src/Archipelago/Archipelago.cs
@@ -41,7 +41,9 @@ public void ActivateCheck(string LocationId) {
}
public void UpdateDataStorage(string Key, object Value) {
- integration.UpdateDataStorage(Key, Value);
+ if (SaveFlags.IsArchipelago()) {
+ integration.UpdateDataStorage(Key, Value);
+ }
}
public void Release() {
diff --git a/src/Archipelago/ArchipelagoIntegration.cs b/src/Archipelago/ArchipelagoIntegration.cs
index c5eb96f..b8d71cc 100644
--- a/src/Archipelago/ArchipelagoIntegration.cs
+++ b/src/Archipelago/ArchipelagoIntegration.cs
@@ -41,6 +41,10 @@ public class ArchipelagoIntegration {
private int ItemIndex = 0;
public void Update() {
+ if ((SceneManager.GetActiveScene().name == "TitleScreen" && TunicArchipelago.Settings.Mode != RandomizerSettings.RandomizerType.ARCHIPELAGO) || SaveFile.GetInt("archipelago") == 0) {
+ return;
+ }
+
if (!connected) {
return;
}
@@ -64,7 +68,6 @@ public void Update() {
if (SpeedrunData.gameComplete != 0 && !sentCompletion) {
sentCompletion = true;
SendCompletion();
- SpeedrunFinishlineDisplayPatches.SetupCompletionStatsDisplay();
}
}
@@ -81,7 +84,11 @@ public void TryConnect() {
return;
}
if (session == null) {
- session = ArchipelagoSessionFactory.CreateSession(TunicArchipelago.Settings.ConnectionSettings.Hostname, TunicArchipelago.Settings.ConnectionSettings.Port);
+ try {
+ session = ArchipelagoSessionFactory.CreateSession(TunicArchipelago.Settings.ConnectionSettings.Hostname, int.Parse(TunicArchipelago.Settings.ConnectionSettings.Port));
+ } catch (Exception e) {
+ Logger.LogInfo("Failed to create archipelago session!");
+ }
}
incomingItemHandler = IncomingItemHandler();
outgoingItemHandler = OutgoingItemHandler();
@@ -285,6 +292,11 @@ public void ActivateCheck(string LocationId) {
if (Locations.VanillaLocations.Keys.Where(key => Locations.VanillaLocations[key].Location.SceneName == SceneLoaderPatches.SceneName && !Locations.CheckedLocations[key]).ToList().Count == 0) {
FairyTargets.CreateLoadZoneTargets();
}
+
+ if (TunicArchipelago.Settings.CreateSpoilerLog && !TunicArchipelago.Settings.RaceMode) {
+ ItemTracker.PopulateSpoilerLog();
+ }
+
session.Locations.ScoutLocationsAsync(location)
.ContinueWith(locationInfoPacket =>
outgoingItems.Enqueue(locationInfoPacket.Result.Locations[0]));
@@ -303,7 +315,7 @@ public void SendCompletion() {
}
public void Release() {
- if (sentCompletion && !sentRelease) {
+ if (connected && sentCompletion && !sentRelease) {
session.Socket.SendPacket(new SayPacket() { Text = "!release" });
sentRelease = true;
Logger.LogInfo("Released remaining checks.");
@@ -311,7 +323,7 @@ public void Release() {
}
public void Collect() {
- if (sentCompletion && !sentCollect) {
+ if (connected && sentCompletion && !sentCollect) {
session.Socket.SendPacket(new SayPacket() { Text = "!collect" });
sentCollect = true;
Logger.LogInfo("Collected remaining items.");
diff --git a/src/Data/Check.cs b/src/Data/Check.cs
new file mode 100644
index 0000000..71a70aa
--- /dev/null
+++ b/src/Data/Check.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TunicArchipelago {
+
+ public struct Location {
+ public string LocationId;
+ public string Position;
+ public List> RequiredItems;
+ public List> RequiredItemsDoors;
+ public int SceneId;
+ public string SceneName;
+
+ public bool reachable(Dictionary inventory) {
+ List> itemsRequired;
+ if (SaveFile.GetInt("randomizer entrance rando enabled") == 1) {
+ itemsRequired = this.RequiredItemsDoors;
+ } else {
+ itemsRequired = this.RequiredItems;
+ }
+
+ //if there are no requirements, the location is reachable
+ if (itemsRequired.Count == 0) {
+ return true;
+ }
+
+ //if there are requirements, loop through each requirement to see if any are fully met
+ foreach (Dictionary req in itemsRequired) {
+ //ensure req and items use same terms
+ if (SaveFile.GetInt("randomizer sword progression enabled") != 0) {
+ if (req.ContainsKey("Stick")) {
+ req["Sword Progression"] = 1;
+ req.Remove("Stick");
+ }
+ if (req.ContainsKey("Sword")) {
+ req["Sword Progression"] = 2;
+ req.Remove("Sword");
+ }
+ }
+
+ //check if this requirement is fully met, otherwise move to the next requirement
+ int met = 0;
+ foreach (string item in req.Keys) {
+ //Logger.LogInfo(item);
+ if (!inventory.ContainsKey(item)) {
+ break;
+ } else if (inventory[item] >= req[item]) {
+ met += 1;
+ }
+ }
+ if (met == req.Count) {
+ return true;
+ }
+ }
+ //if no requirements are met, the location isn't reachable
+ return false;
+ }
+ }
+ public struct Reward {
+ public int Amount;
+ public string Name;
+ public string Type;
+ }
+ public class Check {
+ public Location Location;
+ public Reward Reward;
+
+ public Check() { }
+
+ public Check(Location location, Reward reward) {
+ Location = location;
+ Reward = reward;
+ }
+ public Check(Reward reward, Location location) {
+ Location = location;
+ Reward = reward;
+ }
+ }
+}
diff --git a/src/Data/ConnectionSettings.cs b/src/Data/ConnectionSettings.cs
index 03d8c54..d793dea 100644
--- a/src/Data/ConnectionSettings.cs
+++ b/src/Data/ConnectionSettings.cs
@@ -18,7 +18,7 @@ public string Hostname {
set;
}
- public int Port {
+ public string Port {
get;
set;
}
@@ -29,9 +29,9 @@ public string Password {
}
public ConnectionSettings() {
- Player = "Player";
+ Player = "Ruin Seeker";
Hostname = "localhost";
- Port = 38281;
+ Port = "38281";
Password = "";
}
}
diff --git a/src/Data/Hints.cs b/src/Data/Hints.cs
index 87b2dba..4aac278 100644
--- a/src/Data/Hints.cs
+++ b/src/Data/Hints.cs
@@ -11,6 +11,7 @@
using UnityEngine;
using Archipelago.MultiClient.Net.Models;
using Il2CppSystem;
+using UnityEngine.InputSystem;
namespace TunicArchipelago {
public class Hints {
@@ -59,47 +60,6 @@ public HeroGraveHint(string pathHintId, string pathHint, string relicHintId, str
public static Dictionary HintMessages = new Dictionary();
- // Used for getting what sphere 1 is if you have ER on
- // Gives you items in Overworld or items in adjacent scenes
- // will need updating if/when we do a different starting spot
- public static List GetERSphereOne()
- {
- List PortalInventory = new List();
- List CombinedInventory = new List{"Overworld"};
-
- // add starting sword and abilities if applicable
- if (SaveFile.GetInt("randomizer started with sword") == 1)
- { CombinedInventory.Add("Sword"); }
- if (SaveFile.GetInt(AbilityShuffle) == 0)
- {
- CombinedInventory.Add("12");
- CombinedInventory.Add("21");
- }
-
- // find which portals you can reach from spawn without additional progression
- foreach (PortalCombo portalCombo in TunicPortals.RandomizedPortals.Values)
- {
- if (portalCombo.Portal1.Region == "Overworld")
- { PortalInventory.Add(portalCombo.Portal2); }
- if (portalCombo.Portal1.Region == "Overworld Ability" && SaveFile.GetInt(AbilityShuffle) == 0)
- { PortalInventory.Add(portalCombo.Portal2); }
-
- if (portalCombo.Portal2.Region == "Overworld")
- { PortalInventory.Add(portalCombo.Portal1); }
- if (portalCombo.Portal2.Region == "Overworld Ability" && SaveFile.GetInt(AbilityShuffle) == 0)
- { PortalInventory.Add(portalCombo.Portal1); }
- }
-
- // add the new portals and any applicable new scenes to the inventory
- foreach (Portal portal in PortalInventory)
- {
- CombinedInventory.Add(portal.SceneDestinationTag);
- CombinedInventory.AddRange(portal.Rewards(CombinedInventory));
- }
-
- return CombinedInventory;
- }
-
public static void PopulateHints() {
HintMessages.Clear();
HeroGraveHints.Clear();
@@ -107,116 +67,79 @@ public static void PopulateHints() {
string Hint = "";
string Scene = "";
string Prefix = "";
- List Vowels = new List() { 'A', 'E', 'I', 'O', 'U' };
+ List Vowels = new List() { 'A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u' };
- int Player = Archipelago.instance.GetPlayerSlot();
- List MailboxItems = new List() { "Stick", "Sword", "Sword Upgrade", "Magic Dagger", "Magic Wand", "Magic Orb", "Lantern", "Gun", "Scavenger Mask", "Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)" };
- Dictionary SphereOnePlayer = new Dictionary();
- Dictionary SphereOneOthers = new Dictionary();
- List ERSphereOneItemsAndAreas = GetERSphereOne();
- foreach (string itemkey in ItemLookup.ItemList.Keys) {
- ArchipelagoItem item = ItemLookup.ItemList[itemkey];
- // In ER, we need to check more info, since every item has a required item count
- if (SaveFile.GetInt(EntranceRando) == 1) {
- if (Archipelago.instance.IsTunicPlayer(item.Player) && MailboxItems.Contains(item.ItemName)) {
- var requirements = Locations.VanillaLocations[itemkey].Location.RequiredItemsDoors[0].Keys;
- foreach (string req in requirements) {
- int checkCount = 0;
- if (ERSphereOneItemsAndAreas.Contains(req)) {
- checkCount++;
- } else {
- continue;
- }
- if (checkCount == requirements.Count) {
- SphereOnePlayer.Add(itemkey, item);
- }
- }
- }
- else if (item.Player != Archipelago.instance.GetPlayerSlot() && item.Classification == ItemFlags.Advancement) {
- var requirements = Locations.VanillaLocations[itemkey].Location.RequiredItemsDoors[0].Keys;
- foreach (string req in requirements) {
- int checkCount = 0;
- if (ERSphereOneItemsAndAreas.Contains(req)) {
- checkCount++;
- } else {
- continue;
- }
- if (checkCount == requirements.Count)
- { SphereOneOthers.Add(itemkey, item); }
- }
- }
- } else {
- if (Archipelago.instance.IsTunicPlayer(item.Player) && MailboxItems.Contains(item.ItemName) && Locations.VanillaLocations[itemkey].Location.RequiredItems.Count == 0) {
- SphereOnePlayer.Add(itemkey, item);
- }
- if (item.Player != Archipelago.instance.GetPlayerSlot() && item.Classification == ItemFlags.Advancement && Locations.VanillaLocations[itemkey].Location.RequiredItems.Count == 0) {
- SphereOneOthers.Add(itemkey, item);
- }
- }
- }
- ArchipelagoItem mailboxitem = null;
- string key = "";
- if (SphereOnePlayer.Count > 0) {
- key = SphereOnePlayer.Keys.ToList()[random.Next(SphereOnePlayer.Count)];
- mailboxitem = SphereOnePlayer[key];
- } else if (SphereOneOthers.Count > 0) {
- key = SphereOneOthers.Keys.ToList()[random.Next(SphereOneOthers.Count)];
- mailboxitem = SphereOneOthers[key];
- }
- if (mailboxitem != null) {
- Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[key].Location.SceneName].ToUpper();
- Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- SaveFile.SetString("randomizer mailbox hint location", key);
- Hint = $"lehjehnd sehz {Prefix} \"{Scene.ToUpper()}\"\nkuhntAnz wuhn uhv mehnE \"<#00FFFF>FIRST STEPS<#ffffff>\" ahn yor jurnE.";
- } else {
- SaveFile.SetString("randomizer mailbox hint location", "no first steps");
- Hint = $"yor frehndz muhst furst hehlp yoo fInd yor wA...\ngoud luhk, rooin sEkur.";
+ (bool, bool, bool, bool) SinglePlayerItemsHinted = (false, false, false, false);
+
+ if (IsArchipelago()) {
+ CreateAPMailboxHint(random);
+ } else if (IsSinglePlayer()) {
+ SinglePlayerItemsHinted = CreateSinglePlayerMailboxHint(random);
}
- HintMessages.Add("Mailbox", Hint);
- ArchipelagoHint Hyperdash = Locations.MajorItemLocations["Hero's Laurels"][0];
+
Hint = $"lehjehnd sehz <#FF00FF>suhm%i^ ehkstruhordinArE<#FFFFFF> [laurels] ";
- if (Hyperdash.Player == Player) {
- Scene = Hyperdash.Location == "Your Pocket" ? Hyperdash.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[Hyperdash.Location]].Location.SceneName].ToUpper();
+ if (IsArchipelago()) {
+ int Player = Archipelago.instance.GetPlayerSlot();
+ ArchipelagoHint Hyperdash = Locations.MajorItemLocations["Hero's Laurels"][0];
+ if (Hyperdash.Player == Player) {
+ Scene = Hyperdash.Location == "Your Pocket" ? Hyperdash.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[Hyperdash.Location]].Location.SceneName].ToUpper();
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ Hint += $"\nuhwAts yoo in {Prefix} \"{Scene}...\"";
+ } else if (Archipelago.instance.IsTunicPlayer((int)Hyperdash.Player)) {
+ Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[Hyperdash.Location]].Location.SceneName].ToUpper();
+ Hint += $"\nuhwAts yoo in \"{Archipelago.instance.GetPlayerName((int)Hyperdash.Player).ToUpper()}'S\"\n\"{Scene}...\"";
+ } else {
+ Hint += $" uhwAts yoo aht\n{WordWrapString($"\"{Hyperdash.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}\nin\"{Archipelago.instance.GetPlayerName((int)Hyperdash.Player).ToUpper()}'S WORLD...\"";
+ }
+ } else if (IsSinglePlayer()) {
+ Check LaurelsCheck = ItemRandomizer.FindRandomizedItemByName("Hyperdash");
+ Scene = Locations.SimplifiedSceneNames[LaurelsCheck.Location.SceneName];
Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- Hint += $"\nuhwAts yoo in {Prefix} \"{Scene}...\"";
- } else if (Archipelago.instance.IsTunicPlayer((int)Hyperdash.Player)) {
- Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[Hyperdash.Location]].Location.SceneName].ToUpper();
- Hint += $"\nuhwAts yoo in \"{Archipelago.instance.GetPlayerName((int)Hyperdash.Player).ToUpper()}'S\"\n\"{Scene}...\"";
- } else {
- Hint += $" uhwAts yoo aht\n\"{WordWrapString($"\"{Hyperdash.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}\"\nin\"{Archipelago.instance.GetPlayerName((int)Hyperdash.Player).ToUpper()}'S WORLD...\"";
+ Hint += TunicArchipelago.Settings.UseTrunicTranslations ? $"\n<#FFFFFF>uhwAts yoo aht {Prefix} {Translations.Translate(Scene, false)}\"...\"" : $"\nuhwAts yoo in {Prefix} \"{Scene.ToUpper()}...\"";
}
HintMessages.Add("Temple Statue", Hint);
-
List<(string, string)> relicHints = CreateHeroRelicHints();
- List HintItems = new List() { "Magic Wand", "Magic Orb", "Magic Dagger" };
+ List HintItems = new List() { SinglePlayerItemsHinted.Item1 ? "Lantern" : "Magic Wand", SinglePlayerItemsHinted.Item2 ? "Lantern" : "Magic Orb", "Magic Dagger" };
if (SaveFile.GetInt(AbilityShuffle) == 1 && SaveFile.GetInt(HexagonQuestEnabled) == 0) {
- HintItems.Add("Pages 24-25 (Prayer)");
- HintItems.Add("Pages 42-43 (Holy Cross)");
+ HintItems.Add(SinglePlayerItemsHinted.Item3 ? "Lantern" : "Pages 24-25 (Prayer)");
+ HintItems.Add(SinglePlayerItemsHinted.Item4 ? "Lantern" : "Pages 42-43 (Holy Cross)");
HintItems.Remove("Magic Dagger");
}
List HintGraves = new List() { "East Forest Relic", "Fortress Relic", "West Garden Relic" };
while (HintGraves.Count > 0) {
string HintItem = HintItems[random.Next(HintItems.Count)];
- ArchipelagoHint ItemHint = Locations.MajorItemLocations[HintItem][0];
string HintGrave = HintGraves[random.Next(HintGraves.Count)];
+ string slotLocation = "";
(string, string) RelicHint = relicHints[random.Next(relicHints.Count)];
-
- if (ItemHint.Player == Player) {
- Scene = ItemHint.Location == "Your Pocket" ? ItemHint.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[ItemHint.Location]].Location.SceneName].ToUpper();
- if (HintItem == "Pages 24-25 (Prayer)" && Scene == "Fortress Relic") {
- continue;
+ Hint = $"lehjehnd sehz ";
+ if (IsArchipelago()) {
+ ArchipelagoHint ItemHint = Locations.MajorItemLocations[HintItem][0];
+ int Player = Archipelago.instance.GetPlayerSlot();
+
+ if (ItemHint.Player == Player) {
+ Scene = ItemHint.Location == "Your Pocket" ? ItemHint.Location : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[ItemHint.Location]].Location.SceneName];
+ if (HintItem == "Pages 24-25 (Prayer)" && Scene == "Fortress Relic") {
+ continue;
+ }
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ Hint += $"{Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")}";
+ } else if (Archipelago.instance.IsTunicPlayer((int)ItemHint.Player)) {
+ Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[ItemHint.Location]].Location.SceneName];
+ Hint += $"\"{Archipelago.instance.GetPlayerName((int)ItemHint.Player).ToUpper()}'S\"\n{(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")}";
+ } else {
+ Hint += $"\"{Archipelago.instance.GetPlayerName((int)ItemHint.Player).ToUpper()}'S WORLD\" aht\n{WordWrapString($"\"{ItemHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}";
}
+ slotLocation = ItemHint.Location == "Your Pocket" ? $"0, Server" : $"{ItemHint.Player}, {ItemHint.Location}";
+ } else if (IsSinglePlayer()) {
+ ItemData Item = ItemLookup.Items[HintItem];
+ Check ItemCheck = ItemRandomizer.FindRandomizedItemByName(Item.ItemNameForInventory);
+ Scene = Locations.SimplifiedSceneNames[ItemCheck.Location.SceneName];
Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- Hint = $"lehjehnd sehz {Prefix} \"{Scene}\"";
- } else if (Archipelago.instance.IsTunicPlayer((int)ItemHint.Player)) {
- Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[ItemHint.Location]].Location.SceneName].ToUpper();
- Hint = $"lehjehnd sehz \"{Archipelago.instance.GetPlayerName((int)ItemHint.Player).ToUpper()}'S\"\n\"{Scene}\"";
- } else {
- Hint = $"lehjehnd sehz \"{Archipelago.instance.GetPlayerName((int)ItemHint.Player).ToUpper()}'S WORLD\" aht\n{WordWrapString($"\"{ItemHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}";
+ Hint += TunicArchipelago.Settings.UseTrunicTranslations ? $"lehjehnd sehz {Prefix} {Translations.Translate(Scene, false)}" : $"lehjehnd sehz {Prefix} \"{Scene.ToUpper()}\"";
+ slotLocation = $"{ItemCheck.Location.LocationId} [{ItemCheck.Location.SceneName}]";
}
- Hint += $"\niz lOkAtid awn #uh \"<#ffd700>PATH OF THE HERO<#ffffff>...\"";
+ Hint += $"\niz lOkAtid awn #uh {(TunicArchipelago.Settings.UseTrunicTranslations ? $"<#ffd700>pah% uhv #uh hErO<#ffffff>\"...\"" : $"\"<#ffd700>PATH OF THE HERO<#ffffff>...\"")}";
- string slotLocation = ItemHint.Location == "Your Pocket" ? $"0, Server" : $"{ItemHint.Player}, {ItemHint.Location}";
if (HintGrave == "East Forest Relic") {
HeroGraveHints.Add(HintGrave, new HeroGraveHint(slotLocation, Hint, RelicHint.Item1, RelicHint.Item2, "Sword Access", "_Setpieces/RelicPlinth (1)/", true));
} else if (HintGrave == "Fortress Relic") {
@@ -241,22 +164,33 @@ public static void PopulateHints() {
for (int i = 0; i < 3; i++) {
string Hexagon = Hexagons[random.Next(Hexagons.Count)];
string HexagonHintArea = HexagonHintGraves[random.Next(HexagonHintGraves.Count)];
+ string slotLocation = "";
(string, string) RelicHint = relicHints[random.Next(relicHints.Count)];
- ArchipelagoHint HexHint = Hexagon == "Gold Questagon" ? Locations.MajorItemLocations[Hexagon][i] : Locations.MajorItemLocations[Hexagon][0];
- if (HexHint.Player == Player) {
- Scene = HexHint.Location == "Your Pocket" ? HexHint.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HexHint.Location]].Location.SceneName].ToUpper();
- Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- Hint = $"#A sA {Prefix} \"{Scene.ToUpper()}\" iz \nwAr #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd\"...\"";
- } else if (Archipelago.instance.IsTunicPlayer((int)HexHint.Player)) {
- Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HexHint.Location]].Location.SceneName].ToUpper();
+ if (IsArchipelago()) {
+ ArchipelagoHint HexHint = Hexagon == "Gold Questagon" ? Locations.MajorItemLocations[Hexagon][i] : Locations.MajorItemLocations[Hexagon][0];
+ int Player = Archipelago.instance.GetPlayerSlot();
+ if (HexHint.Player == Player) {
+ Scene = HexHint.Location == "Your Pocket" ? HexHint.Location : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HexHint.Location]].Location.SceneName];
+ Prefix = Vowels.Contains(Scene.ToUpper()[0]) ? "#E" : "#uh";
+ Hint = $"#A sA {Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")} iz \nwAr #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd\"...\"";
+ } else if (Archipelago.instance.IsTunicPlayer((int)HexHint.Player)) {
+ Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HexHint.Location]].Location.SceneName];
+ Prefix = Vowels.Contains(Scene.ToUpper()[0]) ? "#E" : "#uh";
+ Hint = $"#A sA \"{Archipelago.instance.GetPlayerName((int)HexHint.Player).ToUpper()}'S\"\n{(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")}\niz wAr #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd\"...\"";
+ } else {
+ Hint = $"#A sA #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd aht\n{WordWrapString($"\"{HexHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}\nin \"{Archipelago.instance.GetPlayerName((int)HexHint.Player).ToUpper()}'S WORLD...\"";
+ }
+ slotLocation = HexHint.Location == "Your Pocket" ? $"0, Server" : $"{HexHint.Player}, {HexHint.Location}";
+ } else if (IsSinglePlayer()) {
+ ItemData Hex = ItemLookup.Items[Hexagon];
+ Check HexCheck = ItemRandomizer.FindRandomizedItemByName(Hex.ItemNameForInventory);
+ Scene = Locations.SimplifiedSceneNames[HexCheck.Location.SceneName];
Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- Hint = $"#A sA \"{Archipelago.instance.GetPlayerName((int)HexHint.Player).ToUpper()}'S\"\n\"{Scene}\"\niz wAr #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd\"...\"";
- } else {
- Hint = $"#A sA #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd aht\n{WordWrapString($"\"{HexHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}\nin \"{Archipelago.instance.GetPlayerName((int)HexHint.Player).ToUpper()}'S WORLD...\"";
+ Hint = $"#A sA {Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")} iz \nwAr #uh {HexagonColors[Hexagon]}kwehstuhgawn [hexagram]<#FFFFFF> iz fownd\"...\"";
+ slotLocation = $"{HexCheck.Location.LocationId} [{HexCheck.Location.SceneName}]";
}
- string slotLocation = HexHint.Location == "Your Pocket" ? $"0, Server" : $"{HexHint.Player}, {HexHint.Location}";
if (HexagonHintArea == "Swamp Relic") {
HeroGraveHints.Add(HexagonHintArea, new HeroGraveHint(slotLocation, Hint, RelicHint.Item1, RelicHint.Item2, "Swamp Redux 2", "_Setpieces Etc/RelicPlinth/", false));
@@ -280,47 +214,47 @@ public static void PopulateHints() {
foreach (PortalCombo Portal in TunicPortals.RandomizedPortals.Values)
{
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Forest Belltower_")
- { HintMessages.Add("East Forest Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("East Forest Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])} [arrow_right]"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Forest Belltower_")
- { HintMessages.Add("East Forest Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("East Forest Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])} [arrow_right]"); }
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Archipelagos Redux_lower")
- { HintMessages.Add("West Garden Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\""); }
+ { HintMessages.Add("West Garden Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])}"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Archipelagos Redux_lower")
- { HintMessages.Add("West Garden Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\""); }
+ { HintMessages.Add("West Garden Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])}"); }
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Fortress Courtyard_")
- { HintMessages.Add("Fortress Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("Fortress Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])} [arrow_right]"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Fortress Courtyard_")
- { HintMessages.Add("Fortress Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("Fortress Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])} [arrow_right]"); }
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Darkwoods Tunnel_")
- { HintMessages.Add("Quarry Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\" [arrow_up]"); }
+ { HintMessages.Add("Quarry Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])} [arrow_up]"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Darkwoods Tunnel_")
- { HintMessages.Add("Quarry Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\" [arrow_up]"); }
+ { HintMessages.Add("Quarry Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])} [arrow_up]"); }
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Ruins Passage_west")
- { HintMessages.Add("Ruined Hall Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("Ruined Hall Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])} [arrow_right]"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Ruins Passage_west")
- { HintMessages.Add("Ruined Hall Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\" [arrow_right]"); }
+ { HintMessages.Add("Ruined Hall Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])} [arrow_right]"); }
if (Portal.Portal1.SceneDestinationTag == "Overworld Redux, Overworld Interiors_house")
- { HintMessages.Add("Town Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\""); }
+ { HintMessages.Add("Town Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])}"); }
if (Portal.Portal2.SceneDestinationTag == "Overworld Redux, Overworld Interiors_house")
- { HintMessages.Add("Town Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\""); }
+ { HintMessages.Add("Town Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])}"); }
if (Portal.Portal1.SceneDestinationTag == "East Forest Redux, Sword Access_lower") {
- HintMessages.Add("East East Forest Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\" [arrow_right]");
+ HintMessages.Add("East East Forest Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])} [arrow_right]");
}
if (Portal.Portal2.SceneDestinationTag == "East Forest Redux, Sword Access_lower") {
- HintMessages.Add("East East Forest Sign", $"\"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\" [arrow_right]");
+ HintMessages.Add("East East Forest Sign", $"{Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])} [arrow_right]");
}
if (Portal.Portal1.SceneDestinationTag == "East Forest Redux, East Forest Redux Laddercave_lower") {
- HintMessages.Add("West East Forest Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal2.Scene]}\"");
+ HintMessages.Add("West East Forest Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal2.Scene])}");
}
if (Portal.Portal2.SceneDestinationTag == "East Forest Redux, East Forest Redux Laddercave_lower") {
- HintMessages.Add("West East Forest Sign", $"[arrow_left] \"{Locations.SimplifiedSceneNames[Portal.Portal1.Scene]}\"");
+ HintMessages.Add("West East Forest Sign", $"[arrow_left] {Translations.TranslateDefaultQuotes(Locations.SimplifiedSceneNames[Portal.Portal1.Scene])}");
}
}
}
@@ -332,28 +266,211 @@ public static void PopulateHints() {
string Scene = "";
string Prefix = "";
string RelicHint = "";
- int Player = Archipelago.instance.GetPlayerSlot();
foreach (ItemData Relic in Relics) {
- ArchipelagoHint RelicItemHint = Locations.MajorItemLocations[Relic.Name][0];
- string itemDisplayText = $"{TextBuilderPatches.ItemNameToAbbreviation[Relic.Name]} {ItemLookup.BonusUpgrades[Relic.ItemNameForInventory].CustomPickupMessage.ToUpper()}";
+ string itemDisplayText = $"{TextBuilderPatches.ItemNameToAbbreviation[Relic.Name]} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(ItemLookup.BonusUpgrades[Relic.ItemNameForInventory].CustomPickupMessage, false) : ItemLookup.BonusUpgrades[Relic.ItemNameForInventory].CustomPickupMessage.ToUpper())}";
+
+ if (IsArchipelago()) {
+ int Player = Archipelago.instance.GetPlayerSlot();
+ ArchipelagoHint RelicItemHint = Locations.MajorItemLocations[Relic.Name][0];
+
+ if (RelicItemHint.Player == Player) {
+ Scene = RelicItemHint.Location == "Your Pocket" ? RelicItemHint.Location : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[RelicItemHint.Location]].Location.SceneName];
+
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd aht {Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) + "." : $"\"{Scene.ToUpper()}.\"")}";
+ } else if (Archipelago.instance.IsTunicPlayer((int)RelicItemHint.Player)) {
+ Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[RelicItemHint.Location]].Location.SceneName];
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd aht {Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) : $"\"{Scene.ToUpper()}\"")}\nin \"{Archipelago.instance.GetPlayerName((int)RelicItemHint.Player).ToUpper()}'S WORLD.\"";
+ } else {
+ RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd in \"{Archipelago.instance.GetPlayerName((int)RelicItemHint.Player).ToUpper()}'S WORLD\"\naht {WordWrapString($"\"{RelicItemHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}.";
+ }
+ string slotLocation = RelicItemHint.Player == Player && RelicItemHint.Location == "Your Pocket" ? "0, Server" : $"{RelicItemHint.Player}, {RelicItemHint.Location}";
+ RelicHints.Add((slotLocation, RelicHint));
+ } else if (IsSinglePlayer()) {
+ Check RelicCheck = ItemRandomizer.FindRandomizedItemByName(Relic.ItemNameForInventory);
+ Scene = Locations.SimplifiedSceneNames[RelicCheck.Location.SceneName];
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- if (RelicItemHint.Player == Player) {
- Scene = RelicItemHint.Location == "Your Pocket" ? RelicItemHint.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[RelicItemHint.Location]].Location.SceneName].ToUpper();
+ RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd aht {Prefix} {(TunicArchipelago.Settings.UseTrunicTranslations ? Translations.Translate(Scene, false) + "." : $"\"{Scene.ToUpper()}.\"")}";
+ RelicHints.Add(($"{RelicCheck.Location.LocationId} [{RelicCheck.Location.SceneName}]", RelicHint));
+ }
+ }
- Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd aht {Prefix} \"{Scene}.\"";
- } else if (Archipelago.instance.IsTunicPlayer((int)RelicItemHint.Player)) {
- Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[RelicItemHint.Location]].Location.SceneName].ToUpper();
- Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd aht {Prefix} \"{Scene}\"\nin \"{Archipelago.instance.GetPlayerName((int)RelicItemHint.Player).ToUpper()}'S WORLD.\"";
+ return RelicHints;
+ }
+
+ public static (bool, bool, bool, bool) CreateSinglePlayerMailboxHint(System.Random random) {
+ string Scene = "";
+ string Prefix = "";
+ string HintMessage = "";
+ List MailboxItems = new List() { "Stick", "Sword", "Sword Progression", "Stundagger", "Techbow", "Wand", "Lantern", "Shotgun", "Mask" };
+ if (SaveFile.GetInt("randomizer shuffled abilities") == 1 && SaveFile.GetInt(HexagonQuestEnabled) != 1) {
+ MailboxItems.Add("12");
+ MailboxItems.Add("21");
+ }
+ List mailboxHintables = new List();
+ foreach (string Item in MailboxItems) {
+ mailboxHintables.AddRange(ItemRandomizer.FindAllRandomizedItemsByName(Item));
+ }
+ Shuffle(mailboxHintables, random);
+ int n = 0;
+ Check HintItem = null;
+ while (HintItem == null && n < mailboxHintables.Count) {
+ if (mailboxHintables[n].Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = mailboxHintables[n];
+ }
+ n++;
+ }
+ if (HintItem == null) {
+ n = 0;
+ while (HintItem == null && n < mailboxHintables.Count) {
+ if (mailboxHintables[n].Location.SceneName == "Trinket Well") {
+ foreach (Check itemData in ItemRandomizer.FindAllRandomizedItemsByName("Trinket Coin")) {
+ if (itemData.Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = itemData;
+ }
+ }
+ } else if (mailboxHintables[n].Location.SceneName == "Waterfall") {
+ foreach (Check itemData in ItemRandomizer.FindAllRandomizedItemsByType("Fairy")) {
+ if (itemData.Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = itemData;
+ }
+ }
+ } else if (mailboxHintables[n].Location.SceneName == "Overworld Interiors" && SaveFile.GetInt("randomizer entrance rando enabled") == 0) {
+ Check itemData = ItemRandomizer.FindRandomizedItemByName("Key (House)");
+ if (itemData.Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = itemData;
+ }
+ } else if (mailboxHintables[n].Location.LocationId == "71" || mailboxHintables[n].Location.LocationId == "73") {
+ foreach (Check itemData in ItemRandomizer.FindAllRandomizedItemsByName("Key")) {
+ if (itemData.Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = itemData;
+ }
+ }
+ } else if (SaveFile.GetInt("randomizer entrance rando enabled") == 1 && mailboxHintables[n].Location.RequiredItemsDoors.Count == 1 && mailboxHintables[n].Location.RequiredItemsDoors[0].ContainsKey("Mask")
+ || mailboxHintables[n].Location.RequiredItems.Count == 1 && mailboxHintables[n].Location.RequiredItems[0].ContainsKey("Mask")) {
+ Check itemData = ItemRandomizer.FindRandomizedItemByName("Mask");
+ if (itemData.Location.reachable(ItemRandomizer.SphereZero)) {
+ HintItem = itemData;
+ }
+ }
+ n++;
+ }
+ }
+ if (HintItem == null) {
+ HintMessage = "nO lehjehnd forsaw yor uhrIvuhl, rooin sEker.\nyoo hahv uh difikuhlt rOd uhhehd. \"GOOD LUCK\".";
+ //TrunicHint = HintMessage;
+ } else {
+ Scene = Locations.SimplifiedSceneNames[HintItem.Location.SceneName];
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ HintMessage = $"lehjehnd sehz {Prefix} \"{Scene.ToUpper()}\"\nkuhntAnz wuhn uhv mehnE \"<#00FFFF>FIRST STEPS<#ffffff>\" ahn yor jurnE.";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ HintMessage = $"lehjehnd sehz {Prefix} {Translations.Translate(Scene, false)}\nkuhntAnz wuhn uhv mehnE <#00FFFF>furst stehps<#ffffff> ahn yor jurnE.";
+ }
+ SaveFile.SetString("randomizer mailbox hint location", $"{HintItem.Location.LocationId} [{HintItem.Location.SceneName}]");
+
+ }
+ HintMessages.Add("Mailbox", HintMessage);
+ return HintItem == null ? (false, false, false, false) : (HintItem.Reward.Name == "Techbow", HintItem.Reward.Name == "Wand", HintItem.Reward.Name == "12", HintItem.Reward.Name == "21");
+ }
+
+ public static void CreateAPMailboxHint(System.Random random) {
+ string Scene = "";
+ string Prefix = "";
+ string Hint = "";
+ int Player = Archipelago.instance.GetPlayerSlot();
+ List MailboxItems = new List() { "Stick", "Sword", "Sword Upgrade", "Magic Dagger", "Magic Wand", "Magic Orb", "Lantern", "Gun", "Scavenger Mask", "Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)" };
+ Dictionary SphereOnePlayer = new Dictionary();
+ Dictionary SphereOneOthersTunic = new Dictionary();
+ Dictionary SphereOneOthers = new Dictionary();
+ List ERSphereOneItemsAndAreas = ItemRandomizer.GetERSphereOne();
+ foreach (string itemkey in ItemLookup.ItemList.Keys) {
+ ArchipelagoItem item = ItemLookup.ItemList[itemkey];
+ // In ER, we need to check more info, since every item has a required item count
+ if (SaveFile.GetInt(EntranceRando) == 1) {
+ if (Archipelago.instance.IsTunicPlayer(item.Player) && MailboxItems.Contains(item.ItemName)) {
+ var requirements = Locations.VanillaLocations[itemkey].Location.RequiredItemsDoors[0].Keys;
+ foreach (string req in requirements) {
+ int checkCount = 0;
+ if (ERSphereOneItemsAndAreas.Contains(req)) {
+ checkCount++;
+ } else {
+ continue;
+ }
+ if (checkCount == requirements.Count) {
+ if (item.Player == Archipelago.instance.GetPlayerSlot()) {
+ SphereOnePlayer.Add(itemkey, item);
+ } else {
+ SphereOneOthersTunic.Add(itemkey, item);
+ }
+ }
+ }
+ } else if (item.Player != Archipelago.instance.GetPlayerSlot() && item.Classification == ItemFlags.Advancement) {
+ var requirements = Locations.VanillaLocations[itemkey].Location.RequiredItemsDoors[0].Keys;
+ foreach (string req in requirements) {
+ int checkCount = 0;
+ if (ERSphereOneItemsAndAreas.Contains(req)) {
+ checkCount++;
+ } else {
+ continue;
+ }
+ if (checkCount == requirements.Count) {
+ SphereOneOthers.Add(itemkey, item);
+ }
+ }
+ }
} else {
- RelicHint = $"lehjehnd sehz #uh {itemDisplayText}\nkahn bE fownd in \"{Archipelago.instance.GetPlayerName((int)RelicItemHint.Player).ToUpper()}'S WORLD\"\naht {WordWrapString($"\"{RelicItemHint.Location.Replace("_", " ").Replace(" ", "\" \"").ToUpper()}\"").Replace("\" \"", " ")}.";
+ if (Archipelago.instance.IsTunicPlayer(item.Player) && MailboxItems.Contains(item.ItemName) && Locations.VanillaLocations[itemkey].Location.RequiredItems.Count == 0) {
+ if (item.Player == Archipelago.instance.GetPlayerSlot()) {
+ SphereOnePlayer.Add(itemkey, item);
+ } else {
+ SphereOneOthersTunic.Add(itemkey, item);
+ }
+ }
+ if (item.Player != Archipelago.instance.GetPlayerSlot() && item.Classification == ItemFlags.Advancement && Locations.VanillaLocations[itemkey].Location.RequiredItems.Count == 0) {
+ SphereOneOthers.Add(itemkey, item);
+ }
+ }
+ }
+ ArchipelagoItem mailboxitem = null;
+ string key = "";
+ if (SphereOnePlayer.Count > 0) {
+ key = SphereOnePlayer.Keys.ToList()[random.Next(SphereOnePlayer.Count)];
+ mailboxitem = SphereOnePlayer[key];
+ } else if (SphereOneOthersTunic.Count > 0) {
+ key = SphereOneOthersTunic.Keys.ToList()[random.Next(SphereOneOthersTunic.Count)];
+ mailboxitem = SphereOneOthersTunic[key];
+ } else if (SphereOneOthers.Count > 0) {
+ key = SphereOneOthers.Keys.ToList()[random.Next(SphereOneOthers.Count)];
+ mailboxitem = SphereOneOthers[key];
+ }
+ if (mailboxitem != null) {
+ Scene = Locations.SimplifiedSceneNames[Locations.VanillaLocations[key].Location.SceneName];
+ Prefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
+ SaveFile.SetString("randomizer mailbox hint location", key);
+ Hint = $"lehjehnd sehz {Prefix} \"{Scene.ToUpper()}\"\nkuhntAnz wuhn uhv mehnE \"<#00FFFF>FIRST STEPS<#ffffff>\" ahn yor jurnE.";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"lehjehnd sehz {Prefix} {Translations.Translate(Scene, false)}\nkuhntAnz wuhn uhv mehnE <#00FFFF>furst stehps<#ffffff> ahn yor jurnE.";
}
- string slotLocation = RelicItemHint.Player == Player && RelicItemHint.Location == "Your Pocket" ? "0, Server" : $"{RelicItemHint.Player}, {RelicItemHint.Location}";
- RelicHints.Add((slotLocation, RelicHint));
+ } else {
+ SaveFile.SetString("randomizer mailbox hint location", "no first steps");
+ Hint = $"yor frehndz muhst furst hehlp yoo fInd yor wA...\ngoud luhk, rooin sEkur.";
}
+ HintMessages.Add("Mailbox", Hint);
+ }
- return RelicHints;
+ private static void Shuffle(List list, System.Random random) {
+ int n = list.Count;
+ int r;
+ while (n > 1) {
+ n--;
+ r = random.Next(n + 1);
+
+ Check holder = list[r];
+ list[r] = list[n];
+ list[n] = holder;
+ }
}
public static string WordWrapString(string Hint) {
diff --git a/src/Data/ItemListJson.cs b/src/Data/ItemListJson.cs
index 5739ca1..0bae532 100644
--- a/src/Data/ItemListJson.cs
+++ b/src/Data/ItemListJson.cs
@@ -7,11 +7,10 @@ public class ItemListJson
""LocationId"": ""999"",
""Position"": ""(0.0, 0.0, 0.0)"",
""RequiredItems"": [
- {""Hyperdash"": 1}
+ {""Hyperdash"": 1, ""Sword"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Cathedral Arena, Swamp Redux_"": 1, ""Sword"": 1},
- {""Cathedral Arena, Shop_"": 1, ""Sword"": 1}
+ {""Cathedral Gauntlet"": 1, ""Sword"": 1}
],
""SceneId"": 61,
""SceneName"": ""Cathedral Arena""
@@ -28,7 +27,7 @@ public class ItemListJson
""Position"": ""(-135.2, 34.1, -43.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Furnace, Overworld Redux_gyro_upper_north"": 1}
+ {""Furnace Fuse"": 1}
],
""SceneId"": 57,
""SceneName"": ""Furnace""
@@ -45,7 +44,7 @@ public class ItemListJson
""Position"": ""(50.8, 22.3, -11.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main, Frog Stairs_Entrance"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -64,7 +63,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -83,7 +82,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""CubeRoom"": 1, ""21"": 1}
+ {""Cube Cave"": 1, ""21"": 1}
],
""SceneId"": 66,
""SceneName"": ""CubeRoom""
@@ -100,7 +99,7 @@ public class ItemListJson
""Position"": ""(8.8, 0.0, 9.9)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sword Cave"": 1}
+ {""Stick House"": 1}
],
""SceneId"": 5,
""SceneName"": ""Sword Cave""
@@ -117,7 +116,7 @@ public class ItemListJson
""Position"": ""(-19.0, 28.0, -89.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -134,7 +133,7 @@ public class ItemListJson
""Position"": ""(-51.0, 28.0, -87.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -151,7 +150,7 @@ public class ItemListJson
""Position"": ""(-68.0, 40.0, -29.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -170,7 +169,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -187,7 +186,7 @@ public class ItemListJson
""Position"": ""(-31.5, 40.3, -39.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -204,7 +203,7 @@ public class ItemListJson
""Position"": ""(25.0, 36.0, -110.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -221,7 +220,7 @@ public class ItemListJson
""Position"": ""(26.0, 28.0, -116.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -240,7 +239,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""EastFiligreeCache"": 1}
+ {""Southeast Cross Room"": 1}
],
""SceneId"": 82,
""SceneName"": ""EastFiligreeCache""
@@ -259,7 +258,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""EastFiligreeCache"": 1}
+ {""Southeast Cross Room"": 1}
],
""SceneId"": 82,
""SceneName"": ""EastFiligreeCache""
@@ -278,7 +277,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""EastFiligreeCache"": 1}
+ {""Southeast Cross Room"": 1}
],
""SceneId"": 82,
""SceneName"": ""EastFiligreeCache""
@@ -295,7 +294,7 @@ public class ItemListJson
""Position"": ""(79.3, 2.5, -173.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -314,7 +313,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Cave"": 1, ""21"": 1}
+ {""Caustic Light Cave"": 1, ""21"": 1}
],
""SceneId"": 50,
""SceneName"": ""Overworld Cave""
@@ -331,7 +330,7 @@ public class ItemListJson
""Position"": ""(176.0, 16.0, 39.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Ruins Passage"": 1}
+ {""Ruined Passage"": 1}
],
""SceneId"": 8,
""SceneName"": ""Ruins Passage""
@@ -350,7 +349,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Ruins Passage"": 1, ""21"": 1}
+ {""Ruined Passage"": 1, ""21"": 1}
],
""SceneId"": 8,
""SceneName"": ""Ruins Passage""
@@ -367,7 +366,7 @@ public class ItemListJson
""Position"": ""(96.5, 28.0, -137.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -386,7 +385,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -403,7 +402,7 @@ public class ItemListJson
""Position"": ""(54.0, 48.8, -90.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -454,7 +453,7 @@ public class ItemListJson
""Position"": ""(91.0, 8.0, 67.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -471,7 +470,7 @@ public class ItemListJson
""Position"": ""(85.0, 4.0, 6.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -488,7 +487,7 @@ public class ItemListJson
""Position"": ""(109.7, 0.0, 10.1)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -505,7 +504,7 @@ public class ItemListJson
""Position"": ""(124.0, 1.4, -16.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -522,7 +521,7 @@ public class ItemListJson
""Position"": ""(92.0, 17.0, 70.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux, East Forest Redux Laddercave_upper"": 1}
+ {""East Forest Dance Fox Spot"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -541,7 +540,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""East Forest Redux, East Forest Redux Laddercave_upper"": 1, ""21"": 1}
+ {""East Forest Dance Fox Spot"": 1, ""21"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -558,7 +557,7 @@ public class ItemListJson
""Position"": ""(-48.0, 0.0, -172.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sword Access"": 1}
+ {""Forest Grave Path Main"": 1}
],
""SceneId"": 12,
""SceneName"": ""Sword Access""
@@ -575,7 +574,7 @@ public class ItemListJson
""Position"": ""(-25.0, 8.0, -172.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sword Access"": 1}
+ {""Forest Grave Path Main"": 1}
],
""SceneId"": 12,
""SceneName"": ""Sword Access""
@@ -592,7 +591,7 @@ public class ItemListJson
""Position"": ""(28.2, 6.1, -190.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sword Access, RelicVoid_teleporter_relic plinth"": 1}
+ {""Forest Grave Path by Grave"": 1}
],
""SceneId"": 12,
""SceneName"": ""Sword Access""
@@ -611,7 +610,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Sword Access, RelicVoid_teleporter_relic plinth"": 1, ""21"": 1}
+ {""Forest Grave Path by Grave"": 1, ""21"": 1}
],
""SceneId"": 12,
""SceneName"": ""Sword Access""
@@ -628,7 +627,7 @@ public class ItemListJson
""Position"": ""(162.2, 0.1, -8.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux Interior"": 1}
+ {""Guard House 2"": 1}
],
""SceneId"": 54,
""SceneName"": ""East Forest Redux Interior""
@@ -645,7 +644,7 @@ public class ItemListJson
""Position"": ""(193.9, -32.0, -23.8)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux Interior"": 1}
+ {""Guard House 2"": 1}
],
""SceneId"": 54,
""SceneName"": ""East Forest Redux Interior""
@@ -662,7 +661,7 @@ public class ItemListJson
""Position"": ""(91.0, -26.0, -58.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -679,7 +678,7 @@ public class ItemListJson
""Position"": ""(88.0, -30.5, -59.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -698,7 +697,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1, ""21"": 1}
+ {""East Forest"": 1, ""21"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -717,7 +716,7 @@ public class ItemListJson
{""Wand"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""East Forest Redux"": 1}
+ {""Wand"": 1, ""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -736,7 +735,7 @@ public class ItemListJson
{""Wand"": 1, ""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""Hyperdash"": 1, ""East Forest Redux"": 1}
+ {""Wand"": 1, ""Hyperdash"": 1, ""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -755,7 +754,7 @@ public class ItemListJson
{""Wand"": 1, ""Stundagger"": 1, ""Techbow"": 1, ""26"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""Stundagger"": 1, ""Techbow"": 1, ""26"": 1, ""East Forest Redux"": 1}
+ {""Wand"": 1, ""Stundagger"": 1, ""Techbow"": 1, ""26"": 1, ""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -772,7 +771,7 @@ public class ItemListJson
""Position"": ""(-46.0, 8.0, -171.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sword Access, East Forest Redux_upper"": 1}
+ {""Forest Grave Path Upper"": 1}
],
""SceneId"": 12,
""SceneName"": ""Sword Access""
@@ -789,7 +788,7 @@ public class ItemListJson
""Position"": ""(154.0, 8.0, 4.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -806,7 +805,7 @@ public class ItemListJson
""Position"": ""(173.0, 8.0, -1.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux"": 1}
+ {""East Forest"": 1}
],
""SceneId"": 53,
""SceneName"": ""East Forest Redux""
@@ -823,7 +822,7 @@ public class ItemListJson
""Position"": ""(166.5, 16.0, 62.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux Laddercave"": 1}
+ {""Guard House 1 East"": 1}
],
""SceneId"": 55,
""SceneName"": ""East Forest Redux Laddercave""
@@ -840,7 +839,7 @@ public class ItemListJson
""Position"": ""(147.0, 16.0, 77.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""East Forest Redux Laddercave"": 1}
+ {""Guard House 1 East"": 1}
],
""SceneId"": 55,
""SceneName"": ""East Forest Redux Laddercave""
@@ -891,7 +890,7 @@ public class ItemListJson
""Position"": ""(-13.0, -4.0, -143.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Fortress Courtyard, Forest Belltower_"": 1}
+ {""Fortress Exterior from East Forest"": 1}
],
""SceneId"": 15,
""SceneName"": ""Fortress Courtyard""
@@ -910,7 +909,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -927,7 +926,7 @@ public class ItemListJson
""Position"": ""(86.0, 46.0, -51.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""PatrolCave"": 1}
+ {""Patrol Cave"": 1}
],
""SceneId"": 67,
""SceneName"": ""PatrolCave""
@@ -946,7 +945,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""PatrolCave"": 1, ""21"": 1}
+ {""Patrol Cave"": 1, ""21"": 1}
],
""SceneId"": 67,
""SceneName"": ""PatrolCave""
@@ -963,7 +962,7 @@ public class ItemListJson
""Position"": ""(67.0, 66.0, 22.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -980,7 +979,7 @@ public class ItemListJson
""Position"": ""(-95.0, 73.0, 46.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -999,7 +998,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1016,7 +1015,7 @@ public class ItemListJson
""Position"": ""(-111.7, 66.0, 38.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1033,7 +1032,7 @@ public class ItemListJson
""Position"": ""(-142.0, 40.0, 29.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1050,7 +1049,7 @@ public class ItemListJson
""Position"": ""(-73.0, 40.0, -4.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1069,7 +1068,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Waterfall"": 1, ""21"": 1}
+ {""Secret Gathering Place"": 1, ""21"": 1}
],
""SceneId"": 49,
""SceneName"": ""Waterfall""
@@ -1086,7 +1085,7 @@ public class ItemListJson
""Position"": ""(-19.3, 43.0, 21.7)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1105,7 +1104,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1122,7 +1121,7 @@ public class ItemListJson
""Position"": ""(-70.0, 30.5, -70.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1139,7 +1138,7 @@ public class ItemListJson
""Position"": ""(27.9, 8.0, -34.7)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Ruined Shop"": 1}
+ {""Ruined Shop"": 1}
],
""SceneId"": 6,
""SceneName"": ""Ruined Shop""
@@ -1156,7 +1155,7 @@ public class ItemListJson
""Position"": ""(25.1, 8.0, -25.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Ruined Shop"": 1}
+ {""Ruined Shop"": 1}
],
""SceneId"": 6,
""SceneName"": ""Ruined Shop""
@@ -1173,7 +1172,7 @@ public class ItemListJson
""Position"": ""(22.4, 8.0, -24.7)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Ruined Shop"": 1}
+ {""Ruined Shop"": 1}
],
""SceneId"": 6,
""SceneName"": ""Ruined Shop""
@@ -1192,7 +1191,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1209,7 +1208,7 @@ public class ItemListJson
""Position"": ""(-118.0, 28.0, -46.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1228,7 +1227,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Town_FiligreeRoom"": 1}
+ {""Fountain Cross Room"": 1}
],
""SceneId"": 30,
""SceneName"": ""Town_FiligreeRoom""
@@ -1247,7 +1246,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1266,7 +1265,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1283,7 +1282,7 @@ public class ItemListJson
""Position"": ""(33.0, 8.0, 27.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Changing Room"": 1}
+ {""Changing Room"": 1}
],
""SceneId"": 70,
""SceneName"": ""Changing Room""
@@ -1300,7 +1299,7 @@ public class ItemListJson
""Position"": ""(-119.5, 16.0, -111.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1320,8 +1319,8 @@ public class ItemListJson
{""Wand"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1},
- {""Wand"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1},
+ {""Wand"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1338,7 +1337,7 @@ public class ItemListJson
""Position"": ""(-65.0, 12.3, -138.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1355,7 +1354,7 @@ public class ItemListJson
""Position"": ""(-83.0, 12.0, -174.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1372,7 +1371,7 @@ public class ItemListJson
""Position"": ""(-60.0, 9.0, -119.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1389,7 +1388,7 @@ public class ItemListJson
""Position"": ""(-33.3, 0.3, -169.8)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1408,7 +1407,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1427,7 +1426,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1, ""21"": 1}
+ {""Overworld"": 1, ""21"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1444,7 +1443,7 @@ public class ItemListJson
""Position"": ""(-83.2, 4.0, -177.1)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1461,7 +1460,7 @@ public class ItemListJson
""Position"": ""(-202.0, 3.0, 74.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Town Basement"": 1}
+ {""Hourglass Cave"": 1}
],
""SceneId"": 7,
""SceneName"": ""Town Basement""
@@ -1480,7 +1479,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Town Basement"": 1, ""21"": 1}
+ {""Hourglass Cave"": 1, ""21"": 1}
],
""SceneId"": 7,
""SceneName"": ""Town Basement""
@@ -1497,7 +1496,7 @@ public class ItemListJson
""Position"": ""(-130.0, 12.0, -119.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1514,7 +1513,7 @@ public class ItemListJson
""Position"": ""(65.0, 22.0, -138.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1551,8 +1550,8 @@ public class ItemListJson
{""Wand"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1},
- {""Wand"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1},
+ {""Wand"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1569,7 +1568,7 @@ public class ItemListJson
""Position"": ""(-3.0, 1.5, -152.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1588,7 +1587,7 @@ public class ItemListJson
{""12"": 1}
],
""RequiredItemsDoors"": [
- {""Transit, Overworld Redux_teleporter_starting island"": 1}
+ {""Far Shore to Spawn"": 1}
],
""SceneId"": 39,
""SceneName"": ""Transit""
@@ -1607,7 +1606,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Transit"": 1, ""Hyperdash"": 1}
+ {""Far Shore"": 1, ""Hyperdash"": 1}
],
""SceneId"": 39,
""SceneName"": ""Transit""
@@ -1624,7 +1623,7 @@ public class ItemListJson
""Position"": ""(-56.0, 24.0, -95.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1641,7 +1640,7 @@ public class ItemListJson
""Position"": ""(1.0, 0.0, 16.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Maze Room"": 1}
+ {""Maze Cave"": 1}
],
""SceneId"": 68,
""SceneName"": ""Maze Room""
@@ -1660,7 +1659,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Maze Room"": 1, ""21"": 1}
+ {""Maze Cave"": 1, ""21"": 1}
],
""SceneId"": 68,
""SceneName"": ""Maze Room""
@@ -1677,7 +1676,7 @@ public class ItemListJson
""Position"": ""(15.5, 1.0, -147.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1696,7 +1695,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -1713,7 +1712,7 @@ public class ItemListJson
""Position"": ""(51.5, 1.0, 78.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux, Overworld Redux_lower"": 1}
+ {""Ruined Atoll Lower Entry Area"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1730,7 +1729,7 @@ public class ItemListJson
""Position"": ""(-7.0, 16.9, -72.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1747,7 +1746,7 @@ public class ItemListJson
""Position"": ""(38.0, 16.0, -72.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1764,7 +1763,7 @@ public class ItemListJson
""Position"": ""(-7.3, 2.2, -110.7)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1781,7 +1780,7 @@ public class ItemListJson
""Position"": ""(71.8, 13.0, -44.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1798,7 +1797,7 @@ public class ItemListJson
""Position"": ""(5.8, 0.3, 33.1)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1815,7 +1814,7 @@ public class ItemListJson
""Position"": ""(0.0, 4.0, 33.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1832,7 +1831,7 @@ public class ItemListJson
""Position"": ""(-77.0, 3.5, 40.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1849,7 +1848,7 @@ public class ItemListJson
""Position"": ""(-55.5, 2.0, 17.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1868,7 +1867,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Atoll Redux"": 1}
+ {""Hyperdash"": 1, ""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1902,7 +1901,7 @@ public class ItemListJson
""Position"": ""(-38.0, 2.3, -106.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1919,7 +1918,7 @@ public class ItemListJson
""Position"": ""(78.1, 6.3, 84.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1939,8 +1938,8 @@ public class ItemListJson
{""Key"": 2}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Atoll Redux"": 1},
- {""Key"": 2, ""Atoll Redux"": 1}
+ {""Hyperdash"": 1, ""Ruined Atoll"": 1},
+ {""Key"": 2, ""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1960,8 +1959,8 @@ public class ItemListJson
{""Key"": 2}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Atoll Redux"": 1},
- {""Key"": 2, ""Atoll Redux"": 1}
+ {""Hyperdash"": 1, ""Ruined Atoll"": 1},
+ {""Key"": 2, ""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1978,7 +1977,7 @@ public class ItemListJson
""Position"": ""(73.1, 4.0, 56.6)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -1995,7 +1994,7 @@ public class ItemListJson
""Position"": ""(-20.3, 28.0, -9.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2015,8 +2014,8 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""frog cave main"": 1},
- {""Hyperdash"": 1, ""frog cave main"": 1}
+ {""Wand"": 1, ""Frog's Domain"": 1},
+ {""Hyperdash"": 1, ""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2033,7 +2032,7 @@ public class ItemListJson
""Position"": ""(60.5, 36.0, 4.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2050,7 +2049,7 @@ public class ItemListJson
""Position"": ""(69.0, 36.0, -3.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2067,7 +2066,7 @@ public class ItemListJson
""Position"": ""(-114.5, 28.0, 10.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2087,8 +2086,8 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""frog cave main"": 1},
- {""Hyperdash"": 1, ""frog cave main"": 1}
+ {""Wand"": 1, ""Frog's Domain"": 1},
+ {""Hyperdash"": 1, ""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2105,7 +2104,7 @@ public class ItemListJson
""Position"": ""(-75.0, 9.8, -25.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2122,7 +2121,7 @@ public class ItemListJson
""Position"": ""(-8.5, 8.0, -43.2)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2139,7 +2138,7 @@ public class ItemListJson
""Position"": ""(13.6, -2.0, -77.1)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""frog cave main"": 1}
+ {""Frog's Domain"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2159,9 +2158,8 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""frog cave main, Frog Stairs_Exit"": 1},
- {""Hyperdash"": 1, ""frog cave main, Frog Stairs_Exit"": 1},
- {""Wand"": 1, ""frog cave main, Frog Stairs_Entrance"": 1}
+ {""Wand"": 1, ""Frog's Domain Back"": 1},
+ {""Hyperdash"": 1, ""Frog's Domain Back"": 1}
],
""SceneId"": 52,
""SceneName"": ""frog cave main""
@@ -2178,7 +2176,7 @@ public class ItemListJson
""Position"": ""(73.0, 14.0, 29.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Atoll Redux"": 1}
+ {""Ruined Atoll"": 1}
],
""SceneId"": 32,
""SceneName"": ""Atoll Redux""
@@ -2377,7 +2375,7 @@ public class ItemListJson
{""Key (House)"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Interiors"": 1}
+ {""Old House Front"": 1}
],
""SceneId"": 26,
""SceneName"": ""Overworld Interiors""
@@ -2396,7 +2394,7 @@ public class ItemListJson
{""Key (House)"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Interiors"": 1, ""21"": 1}
+ {""Old House Front"": 1, ""21"": 1}
],
""SceneId"": 26,
""SceneName"": ""Overworld Interiors""
@@ -2415,7 +2413,7 @@ public class ItemListJson
{""Key (House)"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Interiors"": 1}
+ {""Old House Front"": 1}
],
""SceneId"": 26,
""SceneName"": ""Overworld Interiors""
@@ -2434,7 +2432,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Interiors, Overworld Redux_under_checkpoint"": 1, ""21"": 1}
+ {""Old House Back"": 1, ""21"": 1}
],
""SceneId"": 26,
""SceneName"": ""Overworld Interiors""
@@ -2453,7 +2451,7 @@ public class ItemListJson
{""Fairy"": 10}
],
""RequiredItemsDoors"": [
- {""Fairy"": 10, ""Waterfall"": 1}
+ {""Fairy"": 10, ""Secret Gathering Place"": 1}
],
""SceneId"": 49,
""SceneName"": ""Waterfall""
@@ -2472,7 +2470,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -2489,7 +2487,7 @@ public class ItemListJson
""Position"": ""(-36.0, 40.0, -13.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -2508,7 +2506,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2527,7 +2525,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2546,7 +2544,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2565,7 +2563,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2584,7 +2582,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2603,7 +2601,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2622,7 +2620,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2641,7 +2639,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2660,7 +2658,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2679,7 +2677,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer, Sewer_Boss_"": 1}
+ {""Beneath the Well Main, Sewer_Boss_"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2698,7 +2696,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer, Overworld Redux_west_aqueduct"": 1}
+ {""Beneath the Well Back"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2717,7 +2715,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer, Sewer_Boss_"": 1}
+ {""Beneath the Well Back"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2734,7 +2732,7 @@ public class ItemListJson
""Position"": ""(57.0, 9.4, -10.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Sewer_Boss, Crypt Redux_"": 1}
+ {""Dark Tomb Checkpoint"": 1}
],
""SceneId"": 51,
""SceneName"": ""Sewer_Boss""
@@ -2753,7 +2751,7 @@ public class ItemListJson
{""Stick"": 1}
],
""RequiredItemsDoors"": [
- {""Sewer"": 1, ""Stick"": 1}
+ {""Beneath the Well Main"": 1, ""Stick"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2772,7 +2770,7 @@ public class ItemListJson
{""12"": 1}
],
""RequiredItemsDoors"": [
- {""Furnace, Overworld Redux_gyro_upper_north"": 1, ""12"": 1}
+ {""Beneath the Well Back"": 1, ""Furnace Fuse"": 1, ""12"": 1}
],
""SceneId"": 27,
""SceneName"": ""Sewer""
@@ -2789,7 +2787,7 @@ public class ItemListJson
""Position"": ""(-138.2, 28.0, 10.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Overworld Redux"": 1}
+ {""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -2808,7 +2806,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2827,7 +2825,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2846,7 +2844,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2865,7 +2863,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2884,7 +2882,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2903,7 +2901,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2922,7 +2920,7 @@ public class ItemListJson
{""Lantern"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Crypt Redux"": 1}
+ {""Lantern"": 1, ""Dark Tomb Main"": 1}
],
""SceneId"": 64,
""SceneName"": ""Crypt Redux""
@@ -2942,7 +2940,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Furnace, Crypt Redux_"": 1}
+ {""Furnace Walking Path"": 1}
],
""SceneId"": 57,
""SceneName"": ""Furnace""
@@ -2962,7 +2960,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux, Archipelagos Redux_lower"": 1}
+ {""Overworld to West Garden from Furnace"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -2982,7 +2980,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3002,7 +3000,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1, ""21"": 1}
+ {""West Garden"": 1, ""21"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3022,7 +3020,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3041,7 +3039,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Archipelagos Redux"": 1}
+ {""Hyperdash"": 1, ""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3060,7 +3058,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Archipelagos Redux"": 1}
+ {""Hyperdash"": 1, ""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3080,7 +3078,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3100,7 +3098,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3120,7 +3118,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3140,7 +3138,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3159,7 +3157,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Archipelagos Redux"": 1, ""21"": 1}
+ {""Hyperdash"": 1, ""West Garden"": 1, ""21"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3179,7 +3177,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3199,7 +3197,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3219,7 +3217,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3239,7 +3237,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3259,7 +3257,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""archipelagos_house"": 1}
+ {""Magic Dagger House"": 1}
],
""SceneId"": 41,
""SceneName"": ""archipelagos_house""
@@ -3278,7 +3276,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Archipelagos Redux, Transit_teleporter_archipelagos_teleporter"": 1}
+ {""Hyperdash"": 1, ""West Garden Portal"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3297,7 +3295,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Archipelagos Redux"": 1}
+ {""Hyperdash"": 1, ""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3317,7 +3315,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3337,7 +3335,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1, ""21"": 1}
+ {""West Garden"": 1, ""21"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3357,7 +3355,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux"": 1}
+ {""West Garden"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3376,7 +3374,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Overworld Redux"": 1}
+ {""Hyperdash"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -3396,7 +3394,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Archipelagos Redux, Overworld Redux_upper"": 1}
+ {""West Garden after Boss"": 1}
],
""SceneId"": 31,
""SceneName"": ""Archipelagos Redux""
@@ -3416,7 +3414,7 @@ public class ItemListJson
{""Lantern"": 1, ""Sword"": 1}
],
""RequiredItemsDoors"": [
- {""Overworld Redux, Archipelagos Redux_upper"": 1}
+ {""Overworld Belltower"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -3437,7 +3435,7 @@ public class ItemListJson
{""Lantern"": 1, ""Sword"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Temple"": 1, ""21"": 1}
+ {""Sealed Temple"": 1, ""21"": 1}
],
""SceneId"": 24,
""SceneName"": ""Temple""
@@ -3458,7 +3456,7 @@ public class ItemListJson
{""Lantern"": 1, ""Sword"": 1}
],
""RequiredItemsDoors"": [
- {""Temple"": 1}
+ {""Sealed Temple"": 1}
],
""SceneId"": 24,
""SceneName"": ""Temple""
@@ -3477,7 +3475,7 @@ public class ItemListJson
{""Wand"": 1}
],
""RequiredItemsDoors"": [
- {""Wand"": 1, ""Overworld Redux"": 1}
+ {""Wand"": 1, ""Overworld"": 1}
],
""SceneId"": 25,
""SceneName"": ""Overworld Redux""
@@ -3494,7 +3492,7 @@ public class ItemListJson
""Position"": ""(-18.0, -4.5, -130.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Fortress Courtyard, Overworld Redux_"": 1}
+ {""Fortress Exterior from Overworld"": 1}
],
""SceneId"": 15,
""SceneName"": ""Fortress Courtyard""
@@ -3511,7 +3509,7 @@ public class ItemListJson
""Position"": ""(6.4, 0.3, -123.8)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Fortress Courtyard, Overworld Redux_"": 1}
+ {""Fortress Exterior from Overworld"": 1}
],
""SceneId"": 15,
""SceneName"": ""Fortress Courtyard""
@@ -3531,7 +3529,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Courtyard, Shop_"": 1}
+ {""Fortress Exterior near cave"": 1}
],
""SceneId"": 15,
""SceneName"": ""Fortress Courtyard""
@@ -3551,7 +3549,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Courtyard, Shop_"": 1}
+ {""Fortress Exterior near cave"": 1}
],
""SceneId"": 15,
""SceneName"": ""Fortress Courtyard""
@@ -3571,7 +3569,7 @@ public class ItemListJson
{""Lantern"": 1, ""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Fortress Basement"": 1}
+ {""Lantern"": 1, ""Beneath the Vault Front"": 1}
],
""SceneId"": 14,
""SceneName"": ""Fortress Basement""
@@ -3593,9 +3591,10 @@ public class ItemListJson
{""Lantern"": 1, ""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Stick"": 1, ""Fortress Basement"": 1},
- {""Lantern"": 1, ""Sword"": 1, ""Fortress Basement"": 1},
- {""Lantern"": 1, ""Techbow"": 1, ""Fortress Basement"": 1}
+ {""Stick"": 1, ""Beneath the Vault Back"": 1},
+ {""Sword"": 1, ""Beneath the Vault Back"": 1},
+ {""Techbow"": 1, ""Beneath the Vault Back"": 1},
+ {""Hyperdash"": 1, ""Beneath the Vault Back"": 1}
],
""SceneId"": 14,
""SceneName"": ""Fortress Basement""
@@ -3615,8 +3614,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Fortress Basement, Fortress Courtyard_"": 1},
- {""Fortress Basement, Fortress Main_"": 1}
+ {""Beneath the Vault Back"": 1}
],
""SceneId"": 14,
""SceneName"": ""Fortress Basement""
@@ -3636,8 +3634,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Fortress Basement, Fortress Courtyard_"": 1},
- {""Fortress Basement, Fortress Main_"": 1}
+ {""Beneath the Vault Back"": 1}
],
""SceneId"": 14,
""SceneName"": ""Fortress Basement""
@@ -3657,8 +3654,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Lantern"": 1, ""Fortress Basement, Fortress Courtyard_"": 1},
- {""Fortress Basement, Fortress Main_"": 1}
+ {""Beneath the Vault Back"": 1}
],
""SceneId"": 14,
""SceneName"": ""Fortress Basement""
@@ -3678,7 +3674,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Main"": 1}
+ {""Eastern Vault Fortress"": 1}
],
""SceneId"": 13,
""SceneName"": ""Fortress Main""
@@ -3698,7 +3694,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Main"": 1}
+ {""Eastern Vault Fortress"": 1}
],
""SceneId"": 13,
""SceneName"": ""Fortress Main""
@@ -3718,7 +3714,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Main"": 1}
+ {""Eastern Vault Fortress"": 1}
],
""SceneId"": 13,
""SceneName"": ""Fortress Main""
@@ -3738,7 +3734,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""21"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Main"": 1, ""21"": 1}
+ {""Eastern Vault Fortress"": 1, ""21"": 1}
],
""SceneId"": 13,
""SceneName"": ""Fortress Main""
@@ -3758,7 +3754,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Main"": 1}
+ {""Eastern Vault Fortress"": 1}
],
""SceneId"": 13,
""SceneName"": ""Fortress Main""
@@ -3778,7 +3774,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Reliquary, Fortress Courtyard_Upper"": 1}
+ {""Fortress Grave Path Upper"": 1}
],
""SceneId"": 48,
""SceneName"": ""Fortress Reliquary""
@@ -3798,7 +3794,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Reliquary"": 1}
+ {""Fortress Grave Path"": 1}
],
""SceneId"": 48,
""SceneName"": ""Fortress Reliquary""
@@ -3818,7 +3814,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress Reliquary"": 1}
+ {""Fortress Grave Path"": 1}
],
""SceneId"": 48,
""SceneName"": ""Fortress Reliquary""
@@ -3837,7 +3833,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Dusty"": 1}
+ {""Fortress Leaf Piles"": 1}
],
""SceneId"": 83,
""SceneName"": ""Dusty""
@@ -3857,7 +3853,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Fortress East, Fortress Main_lower"": 1}
+ {""Fortress East Shortcut Lower"": 1}
],
""SceneId"": 47,
""SceneName"": ""Fortress East""
@@ -3916,7 +3912,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""ShopSpecial"": 1}
+ {""Special Shop"": 1}
],
""SceneId"": 65,
""SceneName"": ""ShopSpecial""
@@ -3933,7 +3929,7 @@ public class ItemListJson
""Position"": ""(49.0, 41.2, 3.7)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Mountain"": 1}
+ {""Lower Mountain"": 1}
],
""SceneId"": 9,
""SceneName"": ""Mountain""
@@ -3952,7 +3948,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Mountaintop"": 1}
+ {""Top of the Mountain"": 1}
],
""SceneId"": 10,
""SceneName"": ""Mountaintop""
@@ -3971,7 +3967,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""21"": 1}
+ {""Quarry Back"": 1, ""21"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -3987,10 +3983,11 @@ public class ItemListJson
""LocationId"": ""126"",
""Position"": ""(80.0, 16.0, 13.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4006,10 +4003,11 @@ public class ItemListJson
""LocationId"": ""133"",
""Position"": ""(3.4, -8.0, -21.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4024,9 +4022,12 @@ public class ItemListJson
""Location"": {
""LocationId"": ""200"",
""Position"": ""(0.2, 25.0, 175.4)"",
- ""RequiredItems"": [],
+ ""RequiredItems"": [
+ {""Sword"": 1},
+ {""Techbow"": 1}
+ ],
""RequiredItemsDoors"": [
- {""Monastery"": 1}
+ {""Monastery Back"": 1}
],
""SceneId"": 22,
""SceneName"": ""Monastery""
@@ -4043,7 +4044,7 @@ public class ItemListJson
""Position"": ""(-55.0, 22.0, 48.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Quarry Redux, Mountain_"": 1}
+ {""Quarry Back"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4060,7 +4061,7 @@ public class ItemListJson
""Position"": ""(-56.0, 0.0, 43.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Quarry Redux, Mountain_"": 1}
+ {""Quarry Back"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4077,7 +4078,7 @@ public class ItemListJson
""Position"": ""(-49.5, -12.0, 21.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Quarry Redux, Mountain_"": 1}
+ {""Quarry Back"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4093,10 +4094,11 @@ public class ItemListJson
""LocationId"": ""127"",
""Position"": ""(-71.0, -20.0, 40.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4112,10 +4114,11 @@ public class ItemListJson
""LocationId"": ""120"",
""Position"": ""(-149.7, -39.7, 8.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4131,10 +4134,11 @@ public class ItemListJson
""LocationId"": ""265"",
""Position"": ""(-78.9, -40.0, 38.8)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4150,10 +4154,11 @@ public class ItemListJson
""LocationId"": ""121"",
""Position"": ""(-140.0, -48.0, -6.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4169,10 +4174,11 @@ public class ItemListJson
""LocationId"": ""130"",
""Position"": ""(-80.0, -56.0, -57.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4188,10 +4194,11 @@ public class ItemListJson
""LocationId"": ""131"",
""Position"": ""(1.0, -47.6, -78.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4207,10 +4214,11 @@ public class ItemListJson
""LocationId"": ""262"",
""Position"": ""(-88.0, -43.5, -66.5)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4226,10 +4234,11 @@ public class ItemListJson
""LocationId"": ""122"",
""Position"": ""(-131.0, -77.0, -103.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4245,10 +4254,11 @@ public class ItemListJson
""LocationId"": ""129"",
""Position"": ""(-100.0, -69.0, -153.0)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4264,10 +4274,11 @@ public class ItemListJson
""LocationId"": ""132"",
""Position"": ""(-7.4, -80.3, -77.3)"",
""RequiredItems"": [
- {""Mask"": 1}
+ {""Mask"": 1, ""Sword"": 1},
+ {""Mask"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Mask"": 1, ""Quarry Redux"": 1}
+ {""Mask"": 1, ""Lower Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4283,10 +4294,11 @@ public class ItemListJson
""LocationId"": ""123"",
""Position"": ""(-9.0, -12.0, -64.7)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4302,10 +4314,11 @@ public class ItemListJson
""LocationId"": ""117"",
""Position"": ""(-23.0, 0.0, 7.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4321,10 +4334,11 @@ public class ItemListJson
""LocationId"": ""224"",
""Position"": ""(28.5, 0.0, -3.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4340,10 +4354,11 @@ public class ItemListJson
""LocationId"": ""289"",
""Position"": ""(52.0, 0.0, 2.5)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4359,10 +4374,11 @@ public class ItemListJson
""LocationId"": ""118"",
""Position"": ""(125.4, 16.0, 14.8)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4378,10 +4394,11 @@ public class ItemListJson
""LocationId"": ""268"",
""Position"": ""(-13.0, 8.0, 21.6)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4397,10 +4414,11 @@ public class ItemListJson
""LocationId"": ""125"",
""Position"": ""(38.7, 24.5, 28.6)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4416,10 +4434,11 @@ public class ItemListJson
""LocationId"": ""124"",
""Position"": ""(62.0, 8.0, 15.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4435,10 +4454,11 @@ public class ItemListJson
""LocationId"": ""119"",
""Position"": ""(81.0, 56.0, 25.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4454,10 +4474,11 @@ public class ItemListJson
""LocationId"": ""250"",
""Position"": ""(21.8, 63.0, 51.4)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux, Monastery_front"": 1}
+ {""Quarry Monastery Entry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4476,7 +4497,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Quarry Redux"": 1}
+ {""Hyperdash"": 1, ""Quarry"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4492,10 +4513,11 @@ public class ItemListJson
""LocationId"": ""134"",
""Position"": ""(1.0, 40.0, -19.0)"",
""RequiredItems"": [
- {""Sword"": 1}
+ {""Sword"": 1},
+ {""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""Quarry Redux"": 1, ""Sword"": 1}
+ {""Quarry"": 1, ""Sword"": 1}
],
""SceneId"": 60,
""SceneName"": ""Quarry Redux""
@@ -4511,10 +4533,11 @@ public class ItemListJson
""LocationId"": ""274"",
""Position"": ""(135.0, 138.0, -58.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_1"": 1, ""Sword"": 1}
+ {""Rooted Ziggurat Upper Front"": 1, ""Sword"": 1}
],
""SceneId"": 43,
""SceneName"": ""ziggurat2020_1""
@@ -4530,10 +4553,11 @@ public class ItemListJson
""LocationId"": ""275"",
""Position"": ""(130.0, 106.0, -129.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_1, ziggurat2020_2_"": 1}
+ {""Rooted Ziggurat Upper Back"": 1}
],
""SceneId"": 43,
""SceneName"": ""ziggurat2020_1""
@@ -4549,10 +4573,11 @@ public class ItemListJson
""LocationId"": ""229"",
""Position"": ""(149.9, 424.3, -42.6)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_2"": 1}
+ {""Rooted Ziggurat Middle Top"": 1}
],
""SceneId"": 42,
""SceneName"": ""ziggurat2020_2""
@@ -4568,10 +4593,11 @@ public class ItemListJson
""LocationId"": ""230"",
""Position"": ""(74.0, 4.0, 5.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4587,10 +4613,11 @@ public class ItemListJson
""LocationId"": ""231"",
""Position"": ""(-7.0, 4.0, -24.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4606,10 +4633,11 @@ public class ItemListJson
""LocationId"": ""234"",
""Position"": ""(67.6, 4.0, -38.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4625,10 +4653,11 @@ public class ItemListJson
""LocationId"": ""261"",
""Position"": ""(129.1, 4.1, -27.3)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4644,10 +4673,11 @@ public class ItemListJson
""LocationId"": ""260"",
""Position"": ""(149.2, 4.0, -53.5)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4663,10 +4693,11 @@ public class ItemListJson
""LocationId"": ""232"",
""Position"": ""(85.6, 4.0, -51.8)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1}
+ {""Rooted Ziggurat Lower Front"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4682,10 +4713,11 @@ public class ItemListJson
""LocationId"": ""233"",
""Position"": ""(153.0, 0.0, -61.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3"": 1, ""12"": 1, ""Sword"": 1}
+ {""Rooted Ziggurat Lower Front"": 1, ""12"": 1, ""Sword"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4701,10 +4733,11 @@ public class ItemListJson
""LocationId"": ""Hexagon Blue"",
""Position"": ""(521.0, -32.9, -146.0)"",
""RequiredItems"": [
- {""Wand"": 1, ""Mask"": 1, ""12"": 1}
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Sword"": 1},
+ {""Wand"": 1, ""Mask"": 1, ""12"": 1, ""Techbow"": 1}
],
""RequiredItemsDoors"": [
- {""ziggurat2020_3, ziggurat2020_FTRoom_"": 1, ""Sword"": 1}
+ {""Rooted Ziggurat Lower Back"": 1, ""Sword"": 1}
],
""SceneId"": 44,
""SceneName"": ""ziggurat2020_3""
@@ -4723,7 +4756,7 @@ public class ItemListJson
{""Fairy"": 20}
],
""RequiredItemsDoors"": [
- {""Fairy"": 20, ""Waterfall"": 1}
+ {""Fairy"": 20, ""Secret Gathering Place"": 1}
],
""SceneId"": 49,
""SceneName"": ""Waterfall""
@@ -4742,7 +4775,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Swamp Redux, Overworld Redux_wall"": 1}
+ {""Hyperdash"": 1, ""Back of Swamp Laurels Area"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4759,7 +4792,7 @@ public class ItemListJson
""Position"": ""(-47.7, -1.5, -33.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4776,7 +4809,7 @@ public class ItemListJson
""Position"": ""(-41.6, -0.6, 55.4)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4793,7 +4826,7 @@ public class ItemListJson
""Position"": ""(14.5, 0.0, -73.5)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4810,7 +4843,7 @@ public class ItemListJson
""Position"": ""(39.2, -0.1, -85.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4827,7 +4860,7 @@ public class ItemListJson
""Position"": ""(83.7, 0.0, -73.8)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4844,7 +4877,7 @@ public class ItemListJson
""Position"": ""(166.0, 0.0, -82.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4861,7 +4894,7 @@ public class ItemListJson
""Position"": ""(147.0, 5.8, -33.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4878,7 +4911,7 @@ public class ItemListJson
""Position"": ""(100.0, 4.0, -70.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4895,7 +4928,7 @@ public class ItemListJson
""Position"": ""(38.0, 12.8, -29.8)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4914,7 +4947,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""Swamp Redux 2"": 1}
+ {""Hyperdash"": 1, ""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4929,9 +4962,11 @@ public class ItemListJson
""Location"": {
""LocationId"": ""1005"",
""Position"": ""(59.8, 0.0, -70.6)"",
- ""RequiredItems"": [],
+ ""RequiredItems"": [
+ {""Sword"": 1}
+ ],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4948,7 +4983,7 @@ public class ItemListJson
""Position"": ""(102.0, 6.0, -40.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4965,7 +5000,7 @@ public class ItemListJson
""Position"": ""(47.0, -1.0, 42.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4982,7 +5017,7 @@ public class ItemListJson
""Position"": ""(85.0, 0.0, 85.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -4999,7 +5034,7 @@ public class ItemListJson
""Position"": ""(145.0, 4.0, 23.3)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5016,7 +5051,7 @@ public class ItemListJson
""Position"": ""(160.5, 4.0, -63.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5033,7 +5068,7 @@ public class ItemListJson
""Position"": ""(153.0, 16.0, -55.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5050,7 +5085,7 @@ public class ItemListJson
""Position"": ""(184.8, 15.0, 51.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5067,7 +5102,7 @@ public class ItemListJson
""Position"": ""(160.5, 12.0, 22.0)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5086,7 +5121,7 @@ public class ItemListJson
{""Hyperdash"": 1}
],
""RequiredItemsDoors"": [
- {""Swamp Back"": 1}
+ {""Back of Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5103,7 +5138,7 @@ public class ItemListJson
""Position"": ""(75.0, 14.0, 172.6)"",
""RequiredItems"": [],
""RequiredItemsDoors"": [
- {""Swamp Redux 2"": 1}
+ {""Swamp"": 1}
],
""SceneId"": 59,
""SceneName"": ""Swamp Redux 2""
@@ -5122,7 +5157,7 @@ public class ItemListJson
{""21"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux, Swamp Redux 2_secret"": 1, ""21"": 1}
+ {""Cathedral Secret Legend Room"": 1, ""21"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5141,7 +5176,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5160,7 +5195,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5179,7 +5214,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5198,7 +5233,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5217,7 +5252,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5236,7 +5271,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5255,7 +5290,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5274,7 +5309,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5293,7 +5328,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Cathedral Redux"": 1}
+ {""Cathedral"": 1}
],
""SceneId"": 69,
""SceneName"": ""Cathedral Redux""
@@ -5388,7 +5423,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Sword Access_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - East Forest"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
@@ -5407,7 +5442,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Library Hall_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - Library"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
@@ -5426,7 +5461,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Monastery_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - Quarry"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
@@ -5445,7 +5480,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Fortress Reliquary_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - Fortress"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
@@ -5464,7 +5499,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Archipelagos Redux_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - West Garden"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
@@ -5483,7 +5518,7 @@ public class ItemListJson
{""Hyperdash"": 1, ""12"": 1}
],
""RequiredItemsDoors"": [
- {""Hyperdash"": 1, ""RelicVoid, Swamp Redux 2_teleporter_relic plinth"": 1}
+ {""Hyperdash"": 1, ""Hero Relic - Swamp"": 1}
],
""SceneId"": 62,
""SceneName"": ""RelicVoid""
diff --git a/src/Data/ItemTracker.cs b/src/Data/ItemTracker.cs
index eb307be..7359dec 100644
--- a/src/Data/ItemTracker.cs
+++ b/src/Data/ItemTracker.cs
@@ -41,9 +41,9 @@ public struct SceneInfo {
{"Flask Shard", 0},
{"Flask Container", 0},
{"Pages", 0},
- {"Prayer Page", 0},
- {"Holy Cross Page", 0},
- {"Ice Rod Page", 0},
+ {"Prayer", 0},
+ {"Holy Cross", 0},
+ {"Icebolt", 0},
{"Fairies", 0},
{"Golden Trophies", 0},
{"Dath Stone", 0},
@@ -124,9 +124,9 @@ public void SetCollectedItem(string ItemName, bool WriteToDisk) {
if (Item.Type == ItemTypes.PAGE) {
ImportantItems["Pages"]++;
- if (Item.Name == "Pages 24-25 (Prayer)") { ImportantItems["Prayer Page"]++; }
- if (Item.Name == "Pages 42-43 (Holy Cross)") { ImportantItems["Holy Cross Page"]++; }
- if (Item.Name == "Pages 52-53 (Ice Rod)") { ImportantItems["Ice Rod Page"]++; }
+ if (Item.Name == "Pages 24-25 (Prayer)") { ImportantItems["Prayer"]++; }
+ if (Item.Name == "Pages 42-43 (Holy Cross)") { ImportantItems["Holy Cross"]++; }
+ if (Item.Name == "Pages 52-53 (Icebolt)") { ImportantItems["Icebolt"]++; }
}
if (Item.Type == ItemTypes.GOLDENTROPHY) {
@@ -136,6 +136,12 @@ public void SetCollectedItem(string ItemName, bool WriteToDisk) {
Inventory.GetItemByName("Spear").Quantity = 1;
}
}
+
+ if (Item.Type == ItemTypes.HEXAGONQUEST && SaveFile.GetInt(AbilityShuffle) == 1) {
+ if (Inventory.GetItemByName("Hexagon Gold").Quantity == SaveFile.GetInt(HexagonQuestPrayer)) { ImportantItems["Prayer"]++; }
+ if (Inventory.GetItemByName("Hexagon Gold").Quantity == SaveFile.GetInt(HexagonQuestHolyCross)) { ImportantItems["Holy Cross"]++; }
+ if (Inventory.GetItemByName("Hexagon Gold").Quantity == SaveFile.GetInt(HexagonQuestIcebolt)) { ImportantItems["Icebolt"]++; }
+ }
if (Item.Type == ItemTypes.SWORDUPGRADE) {
if (SaveFile.GetInt(SwordProgressionEnabled) == 1) {
@@ -168,6 +174,8 @@ public static void SaveTrackerFile() {
}
public static void PopulateSpoilerLog() {
+ if (TunicArchipelago.Settings.RaceMode) { return; }
+
int seed = SaveFile.GetInt("seed");
Dictionary> SpoilerLog = new Dictionary>();
foreach (string Key in Locations.SceneNamesForSpoilerLog.Keys)
@@ -175,34 +183,64 @@ public static void PopulateSpoilerLog() {
SpoilerLog[Key] = new List();
}
- foreach (string Key in ItemLookup.ItemList.Keys) {
- ArchipelagoItem Item = ItemLookup.ItemList[Key];
+ if (IsArchipelago()) {
+ foreach (string Key in ItemLookup.ItemList.Keys) {
+ ArchipelagoItem Item = ItemLookup.ItemList[Key];
- string Spoiler = $"\t{((Locations.CheckedLocations[Key] || SaveFile.GetInt($"randomizer picked up {Key}") == 1 || (TunicArchipelago.Settings.CollectReflectsInWorld && SaveFile.GetInt($"randomizer {Key} was collected") == 1)) ? "x" : "-")} {Locations.LocationIdToDescription[Key]}: {Item.ItemName} ({Archipelago.instance.GetPlayerName(Item.Player)})";
+ string Spoiler = $"\t{((Locations.CheckedLocations[Key] || SaveFile.GetInt($"randomizer picked up {Key}") == 1 || (TunicArchipelago.Settings.CollectReflectsInWorld && SaveFile.GetInt($"randomizer {Key} was collected") == 1)) ? "x" : "-")} {Locations.LocationIdToDescription[Key]}: {Item.ItemName} ({Archipelago.instance.GetPlayerName(Item.Player)})";
- SpoilerLog[Locations.VanillaLocations[Key].Location.SceneName].Add(Spoiler);
+ SpoilerLog[Locations.VanillaLocations[Key].Location.SceneName].Add(Spoiler);
+ }
+ }
+ if (IsSinglePlayer()) {
+ foreach(string Key in Locations.RandomizedLocations.Keys) {
+ Check Check = Locations.RandomizedLocations[Key];
+ ItemData Item = ItemLookup.GetItemDataFromCheck(Check);
+ string Spoiler = $"\t{(Locations.CheckedLocations[Key] ? "x" : "-")} {Locations.LocationIdToDescription[Key]}: {Item.Name}";
+ SpoilerLog[Locations.VanillaLocations[Key].Location.SceneName].Add(Spoiler);
+ }
}
-
List SpoilerLogLines = new List() {
- "Seed: " + SaveFile.GetString("seed"),
+ "Seed: " + seed,
"Lines that start with 'x' instead of '-' represent items that have been collected\n",
- "Major Items"
};
-
- foreach (string MajorItem in ItemLookup.MajorItems) {
+ if (IsArchipelago()) {
+ SpoilerLogLines.Add("Major Items");
+ foreach (string MajorItem in ItemLookup.MajorItems) {
if(MajorItem == "Gold Questagon") { continue; }
- if(Locations.MajorItemLocations.ContainsKey(MajorItem) && Locations.MajorItemLocations[MajorItem].Count > 0) {
- foreach (ArchipelagoHint apHint in Locations.MajorItemLocations[MajorItem]) {
+ if(Locations.MajorItemLocations.ContainsKey(MajorItem) && Locations.MajorItemLocations[MajorItem].Count > 0) {
+ foreach (ArchipelagoHint apHint in Locations.MajorItemLocations[MajorItem]) {
- bool HasItem = false;
- if (Archipelago.instance.integration.session.Locations.AllLocationsChecked.Contains(Archipelago.instance.integration.session.Locations.GetLocationIdFromName(Archipelago.instance.GetPlayerGame((int)apHint.Player), apHint.Location))) {
- HasItem = true;
+ bool HasItem = false;
+ if (Archipelago.instance.integration.session.Locations.AllLocationsChecked.Contains(Archipelago.instance.integration.session.Locations.GetLocationIdFromName(Archipelago.instance.GetPlayerGame((int)apHint.Player), apHint.Location))) {
+ HasItem = true;
+ }
+ string Spoiler = $"\t{(HasItem ? "x" : "-")} {MajorItem}: {apHint.Location} ({Archipelago.instance.GetPlayerName((int)apHint.Player)}'s World)";
+ SpoilerLogLines.Add(Spoiler);
}
- string Spoiler = $"\t{(HasItem ? "x" : "-")} {MajorItem}: {apHint.Location} ({Archipelago.instance.GetPlayerName((int)apHint.Player)}'s World)";
+ }
+ }
+ }
+ if (IsSinglePlayer()) {
+ SpoilerLogLines.AddRange(GetMysterySeedSettingsForSpoilerLog());
+
+ SpoilerLogLines.Add("Major Items");
+ foreach (string MajorItem in ItemLookup.LegacyMajorItems) {
+ foreach (Check Check in ItemRandomizer.FindAllRandomizedItemsByName(MajorItem)) {
+ ItemData ItemData = ItemLookup.GetItemDataFromCheck(Check);
+ string Key = $"{Check.Location.LocationId} [{Check.Location.SceneName}]";
+ string Spoiler = $"\t{(Locations.CheckedLocations[Key] ? "x" : "-")} {ItemData.Name}: {Locations.SceneNamesForSpoilerLog[Check.Location.SceneName]} - {Locations.LocationIdToDescription[Key]}";
SpoilerLogLines.Add(Spoiler);
}
}
}
+
+ if (SaveFile.GetInt(HexagonQuestEnabled) == 1 && SaveFile.GetInt(AbilityShuffle) == 1) {
+ SpoilerLogLines.Add($"\t{(SaveFile.GetInt(PrayerUnlocked) == 1 ? "x" : "-")} Prayer: {SaveFile.GetInt(HexagonQuestPrayer)} Gold Questagons");
+ SpoilerLogLines.Add($"\t{(SaveFile.GetInt(HolyCrossUnlocked) == 1 ? "x" : "-")} Holy Cross: {SaveFile.GetInt(HexagonQuestHolyCross)} Gold Questagons");
+ SpoilerLogLines.Add($"\t{(SaveFile.GetInt(IceBoltUnlocked) == 1 ? "x" : "-")} Icebolt: {SaveFile.GetInt(HexagonQuestIcebolt)} Gold Questagons");
+ }
+
foreach (string Key in SpoilerLog.Keys) {
SpoilerLogLines.Add(Locations.SceneNamesForSpoilerLog[Key]);
SpoilerLog[Key].Sort();
@@ -210,11 +248,6 @@ public static void PopulateSpoilerLog() {
SpoilerLogLines.Add(line);
}
}
- if (SaveFile.GetInt(HexagonQuestEnabled) == 1 && SaveFile.GetInt(AbilityShuffle) == 1) {
- SpoilerLogLines.Add($"\t{(SaveFile.GetInt(PrayerUnlocked) == 1 ? "x" : "-")} Prayer: {SaveFile.GetInt(HexagonQuestPrayer)} Gold Questagons");
- SpoilerLogLines.Add($"\t{(SaveFile.GetInt(HolyCrossUnlocked) == 1 ? "x" : "-")} Holy Cross: {SaveFile.GetInt(HexagonQuestHolyCross)} Gold Questagons");
- SpoilerLogLines.Add($"\t{(SaveFile.GetInt(IceRodUnlocked) == 1 ? "x" : "-")} Ice Rod: {SaveFile.GetInt(HexagonQuestIceRod)} Gold Questagons");
- }
if (SaveFile.GetInt(EntranceRando) == 1)
{
@@ -237,5 +270,26 @@ public static void PopulateSpoilerLog() {
}
Logger.LogInfo("Wrote spoiler log to " + TunicArchipelago.SpoilerLogPath);
}
+
+ private static List GetMysterySeedSettingsForSpoilerLog() {
+ if (SaveFile.GetInt("randomizer mystery seed") == 0) { return new List(); };
+ List MysterySettings = new List() {
+ "Mystery Seed Settings:",
+ $"\t- Hexagon Quest: {SaveFile.GetInt(HexagonQuestEnabled) == 1}",
+ SaveFile.GetInt(HexagonQuestEnabled) == 1 ? $"\t- Hexagon Quest Goal: {SaveFile.GetInt("randomizer hexagon quest goal")}" : "",
+ SaveFile.GetInt(HexagonQuestEnabled) == 1 ? $"\t- Extra Hexagons: {SaveFile.GetInt("randomizer hexagon quest extras")}%" : "",
+ $"\t- Sword Progression: {SaveFile.GetInt(SwordProgressionEnabled) == 1}",
+ $"\t- Keys Behind Bosses: {SaveFile.GetInt(KeysBehindBosses) == 1}",
+ $"\t- Start with Sword: {SaveFile.GetInt("randomizer started with sword") == 1}",
+ $"\t- Shuffled Abilities: {SaveFile.GetInt(AbilityShuffle) == 1}",
+ $"\t- Entrance Randomizer: {SaveFile.GetInt(EntranceRando) == 1}",
+ SaveFile.GetInt(EntranceRando) == 1 ? $"\t- Entrance Randomizer (Fewer Shops): {SaveFile.GetInt("randomizer ER fixed shop") == 1}" : "",
+ $"\t- Maskless Logic: {SaveFile.GetInt(MasklessLogic) == 1}",
+ $"\t- Lanternless Logic: {SaveFile.GetInt(LanternlessLogic) == 1}",
+ $"\t- Laurels Location: {((RandomizerSettings.FixedLaurelsType)SaveFile.GetInt("randomizer laurels location")).ToString()}\n",
+ };
+ MysterySettings.RemoveAll(x => x == "");
+ return MysterySettings;
+ }
}
}
diff --git a/src/Data/Items.cs b/src/Data/Items.cs
index 4f98590..ac99b47 100644
--- a/src/Data/Items.cs
+++ b/src/Data/Items.cs
@@ -1,6 +1,8 @@
using Archipelago.MultiClient.Net.Enums;
+using BepInEx.Logging;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace TunicArchipelago {
@@ -276,10 +278,23 @@ public class ItemLookup {
{ "Pages 46-47", new ItemData("Pages 46-47", "useful", "23", ItemTypes.PAGE, 1) },
{ "Pages 48-49", new ItemData("Pages 48-49", "useful", "24", ItemTypes.PAGE, 1) },
{ "Pages 50-51", new ItemData("Pages 50-51", "useful", "25", ItemTypes.PAGE, 1) },
- { "Pages 52-53 (Ice Rod)", new ItemData("Pages 52-53 (Ice Rod)", "progression", "26", ItemTypes.PAGE, 1) },
+ { "Pages 52-53 (Icebolt)", new ItemData("Pages 52-53 (Icebolt)", "progression", "26", ItemTypes.PAGE, 1) },
{ "Pages 54-55", new ItemData("Pages 54-55", "useful", "27", ItemTypes.PAGE, 1) },
};
+ public static ItemData GetItemDataFromCheck(Check Check) {
+ if (ItemLookup.FairyLookup.ContainsKey(Check.Reward.Name)) {
+ return Items["Fairy"];
+ } else if (Check.Reward.Name == "Sword Progression") {
+ return Items["Sword Upgrade"];
+ } else if (Check.Reward.Name == "Fool Trap") {
+ return Items["Fool Trap"];
+ } else {
+ string itemName = ItemLookup.Items.Values.Where(itemdata => itemdata.ItemNameForInventory == Check.Reward.Name && itemdata.QuantityToGive == Check.Reward.Amount).FirstOrDefault().Name;
+ return Items.ContainsKey(itemName) ? Items[itemName] : Items["Money x1"];
+ }
+ }
+
public static List LevelUpItems = new List() { "Level Up - Attack", "Level Up - DamageResist", "Level Up - PotionEfficiency", "Level Up - Health", "Level Up - Stamina", "Level Up - Magic" };
public static Dictionary BonusUpgrades = new Dictionary() {
@@ -338,13 +353,17 @@ public class ItemLookup {
public static List MajorItems = new List() { "Stick", "Sword", "Sword Upgrade", "Magic Dagger", "Magic Wand", "Magic Orb", "Hero's Laurels", "Lantern", "Shield", "Gun", "Scavenger Mask",
"Old House Key", "Fortress Vault Key", "Dath Stone", "Hourglass", "Hero Relic - ATT", "Hero Relic - DEF", "Hero Relic - POTION", "Hero Relic - HP", "Hero Relic - SP",
- "Hero Relic - MP", "Red Questagon", "Green Questagon", "Blue Questagon", "Gold Questagon", "Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)", "Pages 52-53 (Ice Rod)"
+ "Hero Relic - MP", "Red Questagon", "Green Questagon", "Blue Questagon", "Gold Questagon", "Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)", "Pages 52-53 (Icebolt)"
+ };
+
+ public static List LegacyMajorItems = new List() { "Sword", "Sword Progression", "Stundagger", "Techbow", "Wand", "Hyperdash", "Lantern", "Shield", "Shotgun", "Mask",
+ "Key (House)", "Vault Key (Red)", "Dath Stone", "Relic - Hero Sword", "Relic - Hero Crown", "Relic - Hero Water", "Relic - Hero Pendant HP", "Relic - Hero Pendant SP",
+ "Relic - Hero Pendant MP", "Hexagon Red", "Hexagon Green", "Hexagon Blue", "12", "21", "26"
};
public static string PrayerUnlockedLine = $"\"PRAYER Unlocked.\" Jahnuhl yor wizduhm, rooin sEkur.";
public static string HolyCrossUnlockedLine = $"\"HOLY CROSS Unlocked.\" sEk wuht iz rItfuhlE yorz.";
- public static string IceRodUnlockedLine = $"\"ICE ROD Unlocked.\" #A wOnt nO wuht hit #ehm";
-
+ public static string IceboltUnlockedLine = $"\"ICEBOLT Unlocked.\" #A wOnt nO wuht hit #ehm";
public static Dictionary SimplifiedItemNames = new Dictionary() {
{"Firecracker", "Firecracker"},
@@ -361,6 +380,7 @@ public class ItemLookup {
{"Stick", "Stick"},
{"Sword", "Sword"},
{"Sword Progression", "Sword Upgrade"},
+ {"Sword Upgrade", "Sword Upgrade"},
{"Stundagger", "Magic Dagger"},
{"Techbow", "Magic Wand"},
{"Wand", "Magic Orb"},
@@ -429,6 +449,7 @@ public class ItemLookup {
{"Archipelagos Redux-(-236.0, 8.0, 86.3)", "Fairy"},
{"Fortress Main-(-75.0, -1.0, 17.0)", "Fairy"},
{"East Forest Redux-(164.0, -25.0, -56.0)", "Fairy"},
+ {"Fairy", "Fairy"},
{"GoldenTrophy_1", "Mr Mayor"},
{"GoldenTrophy_2", "Secret Legend"},
{"GoldenTrophy_3", "Sacred Geometry"},
@@ -467,7 +488,7 @@ public class ItemLookup {
{"23", "Pages 46-47"},
{"24", "Pages 48-49"},
{"25", "Pages 50-51"},
- {"26", "Pages 52-53 (Ice Rod)"},
+ {"26", "Pages 52-53 (Icebolt)"},
{"27", "Pages 54-55"},
};
@@ -476,6 +497,18 @@ public class ItemLookup {
{ "lurdrurdrurdl", "Granted Firebomb" },
{ "ldrurdrurdrul", "Granted Icebomb" },
};
+
+ public static Dictionary> FillerItems = new Dictionary>() {
+ { "Firecracker", new List() { 2, 3, 4, 5, 6 } },
+ { "Firebomb", new List() { 2, 3 } },
+ { "Ice Bomb", new List() { 2, 3, 5 } },
+ { "Bait", new List() { 1, 2 } },
+ { "Pepper", new List() { 2 } },
+ { "Ivy", new List() { 3 } },
+ { "Berry_HP", new List() { 1, 2, 3 } },
+ { "Berry_MP", new List() { 1, 2, 3 } },
+ { "money", new List() { 20, 25, 30, 32, 40, 48, 50 } },
+ };
}
}
diff --git a/src/Data/Locations.cs b/src/Data/Locations.cs
index 4b40d3a..6e9800f 100644
--- a/src/Data/Locations.cs
+++ b/src/Data/Locations.cs
@@ -15,7 +15,8 @@ public class Locations {
public static Dictionary LocationIdToDescription = new Dictionary();
public static Dictionary LocationDescriptionToId = new Dictionary();
- public static Dictionary VanillaLocations = new Dictionary() { };
+ public static Dictionary VanillaLocations = new Dictionary() { };
+ public static Dictionary RandomizedLocations = new Dictionary { };
public static Dictionary CheckedLocations = new Dictionary();
public static Dictionary> MajorItemLocations = new Dictionary>();
@@ -25,7 +26,7 @@ public class Locations {
public static string LocationNamesJson = "{\"5 [Overworld Redux]\":\"Overworld - [East] Between Ladders Near Ruined Passage\",\"55 [Archipelagos Redux]\":\"West Garden - [North] Obscured Beneath Hero's Memorial\",\"217 [Archipelagos Redux]\":\"West Garden - [North] Behind Holy Cross Door\",\"west_garden [Archipelagos Redux]\":\"West Garden - [North] Page Pickup\",\"256 [Archipelagos Redux]\":\"West Garden - [North] Across From Page Pickup\",\"280 [Archipelagos Redux]\":\"West Garden - [West] In Flooded Walkway\",\"283 [Archipelagos Redux]\":\"West Garden - [West] Past Flooded Walkway\",\"57 [Archipelagos Redux]\":\"West Garden - [West Highlands] Upper Left Walkway\",\"253 [Archipelagos Redux]\":\"West Garden - [Central Lowlands] Passage Beneath Bridge\",\"56 [Archipelagos Redux]\":\"West Garden - [Central Lowlands] Chest Near Shortcut Bridge\",\"Archipelagos Redux-(-396.3, 1.4, 42.3) [Archipelagos Redux]\":\"West Garden - [West Lowlands] Tree Holy Cross Chest\",\"58 [Archipelagos Redux]\":\"West Garden - [Central Lowlands] Chest Beneath Save Point\",\"206 [Archipelagos Redux]\":\"West Garden - [Central Lowlands] Chest Beneath Faeries\",\"94 [Archipelagos Redux]\":\"West Garden - [South Highlands] Secret Chest Beneath Fuse\",\"111 [Archipelagos Redux]\":\"West Garden - [Southeast Lowlands] Outside Cave\",\"archipelagos_night [Archipelagos Redux]\":\"West Garden - [East Lowlands] Page Behind Ice Dagger House\",\"257 [Archipelagos Redux]\":\"West Garden - [Central Lowlands] Below Left Walkway\",\"59 [Archipelagos Redux]\":\"West Garden - [Central Highlands] Behind Guard Captain\",\"Archipelagos Redux-(-236.0, 8.0, 86.3) [Archipelagos Redux]\":\"West Garden - [Central Highlands] Holy Cross (Blue Lines)\",\"223 [Archipelagos Redux]\":\"West Garden - [Central Highlands] Top of Ladder Before Boss\",\"93 [Archipelagos Redux]\":\"West Garden - [Central Highlands] After Garden Knight\",\"Stundagger [archipelagos_house]\":\"West Garden House - [Southeast Lowlands] Ice Dagger Pickup\",\"72 [Atoll Redux]\":\"Ruined Atoll - [North] From Lower Overworld Entrance\",\"67 [Atoll Redux]\":\"Ruined Atoll - [South] Upper Floor On Bricks\",\"218 [Atoll Redux]\":\"Ruined Atoll - [South] Upper Floor On Power Line\",\"219 [Atoll Redux]\":\"Ruined Atoll - [South] Chest Near Big Crabs\",\"76 [Atoll Redux]\":\"Ruined Atoll - [Southeast] Chest Near Fuse\",\"66 [Atoll Redux]\":\"Ruined Atoll - [North] Obscured Beneath Bridge\",\"220 [Atoll Redux]\":\"Ruined Atoll - [North] Guarded By Bird\",\"287 [Atoll Redux]\":\"Ruined Atoll - [Northwest] Bombable Wall\",\"69 [Atoll Redux]\":\"Ruined Atoll - [Northwest] Behind Envoy\",\"1010 [Atoll Redux]\":\"Ruined Atoll - [West] Near Kevin Block\",\"70 [Atoll Redux]\":\"Ruined Atoll - [Southwest] Obscured Behind Fuse\",\"68 [Atoll Redux]\":\"Ruined Atoll - [South] Near Birds\",\"Key [Atoll Redux]\":\"Ruined Atoll - [Northeast] Key Pickup\",\"73 [Atoll Redux]\":\"Ruined Atoll - [East] Locked Room Lower Chest\",\"71 [Atoll Redux]\":\"Ruined Atoll - [East] Locked Room Upper Chest\",\"221 [Atoll Redux]\":\"Ruined Atoll - [Northeast] Chest Beneath Brick Walkway\",\"75 [Atoll Redux]\":\"Ruined Atoll - [Northeast] Chest On Brick Walkway\",\"999 [Cathedral Arena]\":\"Cathedral Gauntlet - Gauntlet Reward\",\"1002 [Cathedral Redux]\":\"Cathedral - Secret Legend Trophy Chest\",\"240 [Cathedral Redux]\":\"Cathedral - [1F] Library\",\"244 [Cathedral Redux]\":\"Cathedral - [1F] Library Secret\",\"236 [Cathedral Redux]\":\"Cathedral - [1F] Guarded By Lasers\",\"237 [Cathedral Redux]\":\"Cathedral - [1F] Near Spikes\",\"243 [Cathedral Redux]\":\"Cathedral - [2F] Bird Room Secret\",\"238 [Cathedral Redux]\":\"Cathedral - [2F] Bird Room\",\"239 [Cathedral Redux]\":\"Cathedral - [2F] Entryway Upper Walkway\",\"241 [Cathedral Redux]\":\"Cathedral - [2F] Library\",\"242 [Cathedral Redux]\":\"Cathedral - [2F] Guarded By Lasers\",\"60 [Changing Room]\":\"Changing Room - Normal Chest\",\"52 [Crypt Redux]\":\"Dark Tomb - Skulls Chest\",\"213 [Crypt Redux]\":\"Dark Tomb - Spike Maze Upper Walkway\",\"53 [Crypt Redux]\":\"Dark Tomb - Spike Maze Near Stairs\",\"210 [Crypt Redux]\":\"Dark Tomb - Spike Maze Near Exit\",\"54 [Crypt Redux]\":\"Dark Tomb - 1st Laser Room Obscured\",\"212 [Crypt Redux]\":\"Dark Tomb - 1st Laser Room\",\"211 [Crypt Redux]\":\"Dark Tomb - 2nd Laser Room\",\"CubeRoom-(321.1, 3.0, 217.0) [CubeRoom]\":\"Cube Cave - Holy Cross Chest\",\"1011 [Dusty]\":\"Fortress Leaf Piles - Secret Chest\",\"286 [East Forest Redux]\":\"East Forest - Bombable Wall\",\"25 [East Forest Redux]\":\"East Forest - Near Telescope\",\"24 [East Forest Redux]\":\"East Forest - Near Save Point\",\"forest [East Forest Redux]\":\"East Forest - Page On Teleporter\",\"23 [East Forest Redux]\":\"East Forest - From Guardhouse 1 Chest\",\"East Forest Redux-(104.0, 16.0, 61.0) [East Forest Redux]\":\"East Forest - Dancing Fox Spirit Holy Cross\",\"26 [East Forest Redux]\":\"East Forest - Spider Chest\",\"248 [East Forest Redux]\":\"East Forest - Beneath Spider Chest\",\"East Forest Redux-(164.0, -25.0, -56.0) [East Forest Redux]\":\"East Forest - Golden Obelisk Holy Cross\",\"284 [East Forest Redux]\":\"East Forest - Lower Grapple Chest\",\"281 [East Forest Redux]\":\"East Forest - Lower Dash Chest\",\"1006 [East Forest Redux]\":\"East Forest - Ice Rod Grapple Chest\",\"21 [East Forest Redux]\":\"East Forest - Above Save Point\",\"22 [East Forest Redux]\":\"East Forest - Above Save Point Obscured\",\"29 [East Forest Redux Interior]\":\"Guardhouse 2 - Upper Floor\",\"30 [East Forest Redux Interior]\":\"Guardhouse 2 - Bottom Floor Secret\",\"27 [East Forest Redux Laddercave]\":\"Guardhouse 1 - Upper Floor Obscured\",\"28 [East Forest Redux Laddercave]\":\"Guardhouse 1 - Upper Floor\",\"270 [EastFiligreeCache]\":\"Southeast Cross Door - Chest 3\",\"271 [EastFiligreeCache]\":\"Southeast Cross Door - Chest 2\",\"272 [EastFiligreeCache]\":\"Southeast Cross Door - Chest 1\",\"forest shortcut [Forest Belltower]\":\"Forest Belltower - Page Pickup\",\"205 [Forest Belltower]\":\"Forest Belltower - Obscured Beneath Bell Bottom Floor\",\"20 [Forest Belltower]\":\"Forest Belltower - After Guard Captain\",\"204 [Forest Belltower]\":\"Forest Belltower - Obscured Near Bell Top Floor\",\"19 [Forest Belltower]\":\"Forest Belltower - Near Save Point\",\"Vault Key (Red) [Fortress Arena]\":\"Fortress Arena - Siege Engine/Vault Key Pickup\",\"Hexagon Red [Fortress Arena]\":\"Fortress Arena - Hexagon Red\",\"63 [Fortress Basement]\":\"Beneath the Fortress - Obscured Behind Waterfall\",\"61 [Fortress Basement]\":\"Beneath the Fortress - Bridge\",\"62 [Fortress Basement]\":\"Beneath the Fortress - Cell Chest 1\",\"65 [Fortress Basement]\":\"Beneath the Fortress - Cell Chest 2\",\"64 [Fortress Basement]\":\"Beneath the Fortress - Back Room Chest\",\"86 [Fortress Courtyard]\":\"Fortress Courtyard - From East Belltower\",\"96 [Fortress Courtyard]\":\"Fortress Courtyard - Below Walkway\",\"88 [Fortress Courtyard]\":\"Fortress Courtyard - Near Fuse\",\"87 [Fortress Courtyard]\":\"Fortress Courtyard - Chest Near Cave\",\"spidercave [Fortress Courtyard]\":\"Fortress Courtyard - Page Near Cave\",\"112 [Fortress East]\":\"Fortress East Shortcut - Chest Near Slimes\",\"fortress [Fortress Main]\":\"Eastern Vault Fortress - [West Wing] Page Pickup\",\"83 [Fortress Main]\":\"Eastern Vault Fortress - [West Wing] Dark Room Chest 1\",\"84 [Fortress Main]\":\"Eastern Vault Fortress - [West Wing] Dark Room Chest 2\",\"Fortress Main-(-75.0, -1.0, 17.0) [Fortress Main]\":\"Eastern Vault Fortress - [West Wing] Candles Holy Cross\",\"85 [Fortress Main]\":\"Eastern Vault Fortress - [East Wing] Bombable Wall\",\"113 [Fortress Reliquary]\":\"Fortress Grave Path - Upper Walkway\",\"114 [Fortress Reliquary]\":\"Fortress Grave Path - Chest Right of Grave\",\"115 [Fortress Reliquary]\":\"Fortress Grave Path - Obscured Chest Left of Grave\",\"Wand [frog cave main]\":\"Frog's Domain - Magic Orb Pickup\",\"77 [frog cave main]\":\"Frog's Domain - Above Vault\",\"82 [frog cave main]\":\"Frog's Domain - Side Room Grapple Secret\",\"81 [frog cave main]\":\"Frog's Domain - Side Room Chest\",\"80 [frog cave main]\":\"Frog's Domain - Side Room Secret Passage\",\"78 [frog cave main]\":\"Frog's Domain - Main Room Top Floor\",\"279 [frog cave main]\":\"Frog's Domain - Grapple Above Hot Tub\",\"79 [frog cave main]\":\"Frog's Domain - Main Room Bottom Floor\",\"222 [frog cave main]\":\"Frog's Domain - Near Vault\",\"259 [frog cave main]\":\"Frog's Domain - Slorm Room\",\"276 [frog cave main]\":\"Frog's Domain - Escape Chest\",\"Lantern [Furnace]\":\"West Furnace - Lantern Pickup\",\"92 [Furnace]\":\"West Furnace - Chest\",\"Hexagon Green [Library Arena]\":\"Librarian - Hexagon Green\",\"Library Hall-(133.3, 10.0, -43.2) [Library Hall]\":\"Library Hall - Holy Cross Chest\",\"library_2 [Library Lab]\":\"Library Lab - Page 1\",\"library_3 [Library Lab]\":\"Library Lab - Page 2\",\"library_1 [Library Lab]\":\"Library Lab - Page 3\",\"226 [Library Lab]\":\"Library Lab - Chest By Shrine 1\",\"225 [Library Lab]\":\"Library Lab - Chest By Shrine 2\",\"227 [Library Lab]\":\"Library Lab - Chest By Shrine 3\",\"228 [Library Lab]\":\"Library Lab - Behind Chalkboard by Fuse\",\"216 [Maze Room]\":\"Maze Cave - Maze Room Chest\",\"Maze Room-(1.0, 0.0, -1.0) [Maze Room]\":\"Maze Cave - Maze Room Holy Cross\",\"200 [Monastery]\":\"Monastery - Monastery Chest\",\"mountain [Mountain]\":\"Lower Mountain - Page Before Door\",\"final [Mountaintop]\":\"Top of the Mountain - Page At The Peak\",\"Overworld Cave-(-90.4, 515.0, -738.9) [Overworld Cave]\":\"Caustic Light Cave - Holy Cross Chest\",\"89 [Overworld Interiors]\":\"Old House - Normal Chest\",\"Overworld Interiors-(-28.0, 27.0, -50.5) [Overworld Interiors]\":\"Old House - Holy Cross Chest\",\"Shield [Overworld Interiors]\":\"Old House - Shield Pickup\",\"under_overworld [Overworld Interiors]\":\"Old House - Holy Cross Door Page\",\"1013 [Overworld Redux]\":\"Overworld - [South] Starting Platform Holy Cross\",\"8 [Overworld Redux]\":\"Overworld - [Central] Chest Across From Well\",\"11 [Overworld Redux]\":\"Overworld - [West] Obscured Near Well\",\"1 [Overworld Redux]\":\"Overworld - [West] Obscured Behind Windmill\",\"1003 [Overworld Redux]\":\"Overworld - [West] Windmill Holy Cross\",\"Key [Overworld Redux]\":\"Overworld - [West] Key Pickup\",\"12 [Overworld Redux]\":\"Overworld - [Central] Bombable Wall\",\"90 [Overworld Redux]\":\"Overworld - [East] Chest In Trees\",\"255 [Overworld Redux]\":\"Overworld - [Southeast] Chest Near Swamp\",\"15 [Overworld Redux]\":\"Overworld - [East] Chest Near Pots\",\"Overworld Redux-(90.4, 36.0, -122.1) [Overworld Redux]\":\"Overworld - [East] Weathervane Holy Cross\",\"overworld post-forest [Overworld Redux]\":\"Overworld - [East] Page Near Secret Shop\",\"Overworld Redux-(64.5, 44.0, -40.0) [Overworld Redux]\":\"Overworld - [Northeast] Flowers Holy Cross\",\"6 [Overworld Redux]\":\"Overworld - [Northeast] Chest Above Patrol Cave\",\"Techbow [Overworld Redux]\":\"Overworld - [Northwest] Fire Wand Pickup\",\"stonehenge_reward [Overworld Redux]\":\"Overworld - [Northwest] Golden Obelisk Page\",\"16 [Overworld Redux]\":\"Overworld - [Northwest] Chest Near Golden Obelisk\",\"9 [Overworld Redux]\":\"Overworld - [Northwest] Chest Near Quarry Gate\",\"13 [Overworld Redux]\":\"Overworld - [Northwest] Chest Near Turret\",\"207 [Overworld Redux]\":\"Overworld - [Northwest] Shadowy Corner Chest\",\"1008 [Overworld Redux]\":\"Overworld - [West] Windchimes Holy Cross\",\"town_upper [Overworld Redux]\":\"Overworld - [West] Page On Teleporter\",\"Overworld Redux-(-132.0, 28.0, -55.5) [Overworld Redux]\":\"Overworld - [West] Moss Wall Holy Cross\",\"91 [Overworld Redux]\":\"Overworld - [West] Chest Behind Moss Wall\",\"overworld_dash [Overworld Redux]\":\"Overworld - [Southwest] Fountain Page\",\"Overworld Redux-(-83.0, 20.0, -117.5) [Overworld Redux]\":\"Overworld - [Southwest] Fountain Holy Cross\",\"2 [Overworld Redux]\":\"Overworld - [Southwest] Chest Guarded By Turret\",\"209 [Overworld Redux]\":\"Overworld - [Southwest] Grapple Chest Over Walkway\",\"Key (House) [Overworld Redux]\":\"Overworld - [Southwest] Key Pickup\",\"17 [Overworld Redux]\":\"Overworld - [Southwest] South Chest Near Guard\",\"208 [Overworld Redux]\":\"Overworld - [Southwest] Obscured In Tunnel To Beach\",\"273 [Overworld Redux]\":\"Overworld - [Southwest] Beach Chest Near Flowers\",\"Overworld Redux-(-52.0, 2.0, -174.8) [Overworld Redux]\":\"Overworld - [Southwest] Flowers Holy Cross\",\"1004 [Overworld Redux]\":\"Overworld - [Southwest] Haiku Holy Cross\",\"7 [Overworld Redux]\":\"Overworld - [Southwest] Beach Chest Beneath Guard\",\"4 [Overworld Redux]\":\"Overworld - [Southwest] Tunnel Guarded By Turret\",\"18 [Overworld Redux]\":\"Overworld - [Southwest] West Beach Guarded By Turret\",\"267 [Overworld Redux]\":\"Overworld - [Southwest] West Beach Guarded By Turret 2\",\"beach [Overworld Redux]\":\"Overworld - [South] Beach Page\",\"285 [Overworld Redux]\":\"Overworld - [Southwest] Bombable Wall Near Fountain\",\"10 [Overworld Redux]\":\"Overworld - [South] Beach Chest\",\"cathedral [Overworld Redux]\":\"Overworld - [Southeast] Page on Pillar by Swamp\",\"tablet [Overworld Redux]\":\"Overworld - [Northwest] Page on Pillar by Dark Tomb\",\"town_well [Overworld Redux]\":\"Overworld - [Northwest] Page By Well\",\"245 [Overworld Redux]\":\"Overworld - [Northwest] Chest Beneath Quarry Gate\",\"14 [Overworld Redux]\":\"Overworld - [West] Near West Garden Entrance\",\"258 [Overworld Redux]\":\"Overworld - [Southwest] From West Garden\",\"3 [Overworld Redux]\":\"Overworld - [West] Chest After Bell\",\"266 [Overworld Redux]\":\"Overworld - [East] Grapple Chest\",\"214 [PatrolCave]\":\"Patrol Cave - Normal Chest\",\"PatrolCave-(74.0, 46.0, 24.0) [PatrolCave]\":\"Patrol Cave - Holy Cross Chest\",\"Quarry Redux-(0.7, 68.0, 84.7) [Quarry Redux]\":\"Quarry - [Back Entrance] Bushes Holy Cross\",\"126 [Quarry Redux]\":\"Quarry - [East] Obscured Near Telescope\",\"133 [Quarry Redux]\":\"Quarry - [Central] Obscured Below Entry Walkway\",\"116 [Quarry Redux]\":\"Quarry - [Back Entrance] Chest\",\"128 [Quarry Redux]\":\"Quarry - [Back Entrance] Obscured Behind Wall\",\"288 [Quarry Redux]\":\"Quarry - [West] Upper Area Bombable Wall\",\"127 [Quarry Redux]\":\"Quarry - [West] Upper Area Near Waterfall\",\"120 [Quarry Redux]\":\"Quarry - [West] Near Shooting Range\",\"265 [Quarry Redux]\":\"Quarry - [West] Shooting Range Secret Path\",\"121 [Quarry Redux]\":\"Quarry - [West] Below Shooting Range\",\"130 [Quarry Redux]\":\"Quarry - [West] Lower Area Below Bridge\",\"131 [Quarry Redux]\":\"Quarry - [West] Lower Area Isolated Chest\",\"262 [Quarry Redux]\":\"Quarry - [West] Lower Area After Bridge\",\"122 [Quarry Redux]\":\"Quarry - [Lowlands] Below Broken Ladder\",\"129 [Quarry Redux]\":\"Quarry - [Lowlands] Upper Walkway\",\"132 [Quarry Redux]\":\"Quarry - [Lowlands] Near Elevator\",\"123 [Quarry Redux]\":\"Quarry - [Central] Below Entry Walkway\",\"117 [Quarry Redux]\":\"Quarry - [Central] Near Shortcut Ladder\",\"224 [Quarry Redux]\":\"Quarry - [East] Near Bridge\",\"289 [Quarry Redux]\":\"Quarry - [East] Bombable Wall\",\"118 [Quarry Redux]\":\"Quarry - [East] Near Telescope\",\"268 [Quarry Redux]\":\"Quarry - [Central] Obscured Behind Staircase\",\"125 [Quarry Redux]\":\"Quarry - [East] Obscured Beneath Scaffolding\",\"124 [Quarry Redux]\":\"Quarry - [East] Obscured Near Winding Staircase\",\"119 [Quarry Redux]\":\"Quarry - [East] Upper Floor\",\"250 [Quarry Redux]\":\"Quarry - [Central] Above Ladder\",\"282 [Quarry Redux]\":\"Quarry - [Central] Above Ladder Dash Chest\",\"134 [Quarry Redux]\":\"Quarry - [Central] Top Floor Overhang\",\"Relic PIckup (6) Sword) [RelicVoid]\":\"Hero's Grave - Tooth Relic\",\"Relic PIckup (5) (MP) [RelicVoid]\":\"Hero's Grave - Mushroom Relic\",\"Relic PIckup (4) (water) [RelicVoid]\":\"Hero's Grave - Ash Relic\",\"Relic PIckup (3) (HP) [RelicVoid]\":\"Hero's Grave - Flowers Relic\",\"Relic PIckup (2) (Crown) [RelicVoid]\":\"Hero's Grave - Effigy Relic\",\"Relic PIckup (1) (SP) [RelicVoid]\":\"Hero's Grave - Feathers Relic\",\"35 [Ruined Shop]\":\"Ruined Shop - Chest 1\",\"36 [Ruined Shop]\":\"Ruined Shop - Chest 2\",\"37 [Ruined Shop]\":\"Ruined Shop - Chest 3\",\"first [Ruins Passage]\":\"Ruined Passage - Page Pickup\",\"1001 [Ruins Passage]\":\"Ruined Passage - Holy Cross Chest\",\"40 [Sewer]\":\"Beneath the Well - [Entryway] Chest\",\"43 [Sewer]\":\"Beneath the Well - [Entryway] Obscured Behind Waterfall\",\"sewer [Sewer]\":\"Beneath the Well - [Second Room] Page\",\"49 [Sewer]\":\"Beneath the Well - [Second Room] Obscured Behind Waterfall\",\"47 [Sewer]\":\"Beneath the Well - [Back Corridor] Right Secret\",\"48 [Sewer]\":\"Beneath the Well - [Back Corridor] Left Secret\",\"41 [Sewer]\":\"Beneath the Well - [Third Room] Beneath Platform Chest\",\"42 [Sewer]\":\"Beneath the Well - [Third Room] Tentacle Chest\",\"46 [Sewer]\":\"Beneath the Well - [Second Room] Underwater Chest\",\"50 [Sewer]\":\"Beneath the Well - [Side Room] Chest By Pots\",\"44 [Sewer]\":\"Beneath the Well - [Save Room] Upper Floor Chest 1\",\"45 [Sewer]\":\"Beneath the Well - [Save Room] Upper Floor Chest 2\",\"51 [Sewer]\":\"Beneath the Well - [Side Room] Chest By Phrends\",\"264 [Sewer]\":\"Beneath the Well - [Powered Secret Room] Chest\",\"below_crypt [Sewer_Boss]\":\"Dark Tomb Checkpoint - [Passage To Dark Tomb] Page Pickup\",\"Potion (First) [Shop]\":\"Shop - Potion 1\",\"Potion (West Garden) [Shop]\":\"Shop - Potion 2\",\"Trinket Coin 1 (day) [Shop]\":\"Shop - Coin 1\",\"Trinket Coin 2 (night) [Shop]\":\"Shop - Coin 2\",\"skullcave [ShopSpecial]\":\"Special Shop - Secret Page Pickup\",\"105 [Swamp Redux 2]\":\"Swamp - [Entrance] Above Entryway\",\"235 [Swamp Redux 2]\":\"Swamp - [Entrance] Obscured Inside Watchtower\",\"254 [Swamp Redux 2]\":\"Swamp - [Entrance] North Small Island\",\"246 [Swamp Redux 2]\":\"Swamp - [Entrance] South Near Fence\",\"249 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Chest Near Graves\",\"247 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Guarded By Big Skeleton\",\"108 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Guarded By Tentacles\",\"104 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Obscured Beneath Telescope\",\"98 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Above Big Skeleton\",\"107 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Upper Walkway On Pedestal\",\"97 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Upper Walkway Dash Chest\",\"1005 [Swamp Redux 2]\":\"Swamp - [South Graveyard] 4 Orange Skulls\",\"103 [Swamp Redux 2]\":\"Swamp - [South Graveyard] Obscured Behind Ridge\",\"278 [Swamp Redux 2]\":\"Swamp - [Central] Obscured Behind Northern Mountain\",\"99 [Swamp Redux 2]\":\"Swamp - [Central] Beneath Memorial\",\"101 [Swamp Redux 2]\":\"Swamp - [Central] Near Ramps Up\",\"106 [Swamp Redux 2]\":\"Swamp - [Central] South Secret Passage\",\"109 [Swamp Redux 2]\":\"Swamp - [Upper Graveyard] Near Telescope\",\"100 [Swamp Redux 2]\":\"Swamp - [Upper Graveyard] Obscured Behind Hill\",\"102 [Swamp Redux 2]\":\"Swamp - [Upper Graveyard] Near Shield Fleemers\",\"277 [Swamp Redux 2]\":\"Swamp - [Outside Cathedral] Obscured Behind Memorial\",\"110 [Swamp Redux 2]\":\"Swamp - [Outside Cathedral] Near Moonlight Bridge Door\",\"32 [Sword Access]\":\"Forest Grave Path - Obscured Chest\",\"31 [Sword Access]\":\"Forest Grave Path - Above Gate\",\"Sword [Sword Access]\":\"Forest Grave Path - Sword Pickup\",\"1009 [Sword Access]\":\"Forest Grave Path - Holy Cross Code by Grave\",\"33 [Sword Access]\":\"Forest Grave Path - Upper Walkway\",\"19 [Sword Cave]\":\"Stick House - Stick Chest\",\"Temple-(14.0, 0.1, 42.4) [Temple]\":\"Sealed Temple - Holy Cross Chest\",\"temple [Temple]\":\"Sealed Temple - Page Pickup\",\"95 [Town Basement]\":\"Hourglass Cave - Hourglass Chest\",\"Town Basement-(-202.0, 28.0, 150.0) [Town Basement]\":\"Hourglass Cave - Holy Cross Chest\",\"town_filigree [Town_FiligreeRoom]\":\"Fountain Cross Door - Page Pickup\",\"FT_Island [Transit]\":\"Far Shore - Page Pickup\",\"1012 [Transit]\":\"Far Shore - Secret Chest\",\"Well Reward (3 Coins) [Trinket Well]\":\"Coins in the Well - 3 Coins\",\"Well Reward (6 Coins) [Trinket Well]\":\"Coins in the Well - 6 Coins\",\"Well Reward (10 Coins) [Trinket Well]\":\"Coins in the Well - 10 Coins\",\"Well Reward (15 Coins) [Trinket Well]\":\"Coins in the Well - 15 Coins\",\"Waterfall-(-47.0, 45.0, 10.0) [Waterfall]\":\"Secret Gathering Place - Holy Cross Chest\",\"waterfall [Waterfall]\":\"Secret Gathering Place - 10 Fairy Reward\",\"1007 [Waterfall]\":\"Secret Gathering Place - 20 Fairy Reward\",\"274 [ziggurat2020_1]\":\"Rooted Ziggurat Upper - Near Bridge Switch\",\"275 [ziggurat2020_1]\":\"Rooted Ziggurat Upper - Beneath Bridge To Administrator\",\"229 [ziggurat2020_2]\":\"Rooted Ziggurat Tower - Inside Tower\",\"230 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Near Corpses\",\"231 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Spider Ambush\",\"234 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Guarded By Double Turrets\",\"261 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Guarded By Double Turrets 2\",\"260 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - After 2nd Double Turret Chest\",\"232 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Left Of Checkpoint Before Fuse\",\"233 [ziggurat2020_3]\":\"Rooted Ziggurat Lower - After Guarded Fuse\",\"Hexagon Blue [ziggurat2020_3]\":\"Rooted Ziggurat Lower - Hexagon Blue\"}";
public static void CreateLocationLookups() {
- foreach (VanillaCheck info in JsonConvert.DeserializeObject>(ItemListJson.ItemList)) {
+ foreach (Check info in JsonConvert.DeserializeObject>(ItemListJson.ItemList)) {
string locationId = $"{info.Location.LocationId} [{info.Location.SceneName}]";
VanillaLocations.Add(locationId, info);
}
diff --git a/src/Data/Portal.cs b/src/Data/Portal.cs
index 99ff18b..5254d7f 100644
--- a/src/Data/Portal.cs
+++ b/src/Data/Portal.cs
@@ -5,196 +5,24 @@ public class Portal {
//private static ManualLogSource Logger = TunicRandomizer.Logger;
public string Scene { get; set; }
public string Destination { get; set; }
- public string Tag { get; set; }
public string Name { get; set; }
public string Region { get; set; }
- public Dictionary RequiredItems { get; set; } = new Dictionary();
- public List> RequiredItemsOr { get; set; } = new List>();
- public Dictionary EntryItems { get; set; } = new Dictionary();
- public List GivesAccess { get; set; } = new List();
- public bool DeadEnd { get; set; } = false;
- public bool PrayerPortal { get; set; } = false;
- public bool OneWay { get; set; } = false;
- public bool IgnoreScene { get; set; } = false;
public string SceneDestinationTag { get; set; }
- public Portal(string destination, string tag, string name, string scene) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, bool deadEnd = false, bool prayerPortal = false, bool oneWay = false, bool ignoreScene = false) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- Region = region;
- DeadEnd = deadEnd;
- PrayerPortal = prayerPortal;
- OneWay = oneWay;
- IgnoreScene = ignoreScene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, Dictionary requiredItems) {
- Destination = destination;
- Tag = tag;
+ public Portal(string name, string destination, string scene, string region) {
Name = name;
- Scene = scene;
- Region = region;
- RequiredItems = requiredItems;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, List> requiredItemsOr) {
Destination = destination;
- Tag = tag;
- Name = name;
Scene = scene;
Region = region;
- RequiredItemsOr = requiredItemsOr;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
+ SceneDestinationTag = (Scene + ", " + Destination);
}
- public Portal(string destination, string tag, string name, string scene, string region, Dictionary entryItems, bool deadEnd = false, bool prayerPortal = false, bool oneWay = false, bool ignoreScene = false) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- Region = region;
- EntryItems = entryItems;
- DeadEnd = deadEnd;
- PrayerPortal = prayerPortal;
- OneWay = oneWay;
- IgnoreScene = ignoreScene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, List givesAccess, bool deadEnd = false, bool prayerPortal = false, bool oneWay = false, bool ignoreScene = false) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- Region = region;
- GivesAccess = givesAccess;
- DeadEnd = deadEnd;
- PrayerPortal = prayerPortal;
- OneWay = oneWay;
- IgnoreScene = ignoreScene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, Dictionary requiredItems, List givesAccess, bool deadEnd = false, bool prayerPortal = false, bool oneWay = false, bool ignoreScene = false) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- Region = region;
- RequiredItems = requiredItems;
- GivesAccess = givesAccess;
- DeadEnd = deadEnd;
- PrayerPortal = prayerPortal;
- OneWay = oneWay;
- IgnoreScene = ignoreScene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
- public Portal(string destination, string tag, string name, string scene, string region, Dictionary requiredItems, List> requiredItemsOr, Dictionary entryItems, List givesAccess, bool deadEnd = false, bool prayerPortal = false, bool oneWay = false, bool ignoreScene = false) {
- Destination = destination;
- Tag = tag;
- Name = name;
- Scene = scene;
- Region = region;
- RequiredItems = requiredItems;
- RequiredItemsOr = requiredItemsOr;
- EntryItems = entryItems;
- GivesAccess = givesAccess;
- DeadEnd = deadEnd;
- PrayerPortal = prayerPortal;
- OneWay = oneWay;
- IgnoreScene = ignoreScene;
- SceneDestinationTag = (Scene + ", " + Destination + "_" + Tag);
- }
-
- public bool CanReachCenterFromPortal(List inventory) {
- // if ignore scene is set, we don't care about this function since we give the region elsewhere
- if (this.IgnoreScene == true) {
- return false;
- }
-
- // create our list of dicts of required items
- List> itemsRequired = new List>();
- if (this.RequiredItems != null) {
- if (this.RequiredItems.Count != 0) {
- itemsRequired.Add(new Dictionary(this.RequiredItems));
- }
- } else if (this.RequiredItemsOr != null) {
- if (this.RequiredItemsOr.Count != 0) {
- foreach (Dictionary reqSet in this.RequiredItemsOr) {
- itemsRequired.Add(reqSet);
- }
- }
- }
-
- // see if we meet any of the requirement dicts for the portal
- if (itemsRequired != null) {
- // if there are no required items, we can reach the center of the region without items (can just walk there)
- if (itemsRequired.Count == 0) {
- return true;
- }
- foreach (Dictionary req in itemsRequired) {
- //ensure req and items use same terms
- if (SaveFile.GetInt("randomizer sword progression enabled") != 0) {
- if (req.ContainsKey("Stick")) {
- req["Sword Progression"] = 1;
- req.Remove("Stick");
- }
- if (req.ContainsKey("Sword")) {
- req["Sword Progression"] = 2;
- req.Remove("Sword");
- }
- }
-
- //check if this requirement is fully met, otherwise move to the next requirement
- int met = 0;
- foreach (string item in req.Keys) {
- if (!inventory.Contains(item)) {
- break;
- } else {
- met += 1;
- }
- }
- if (met == req.Count) {
- return true;
- }
- }
- } else {
+ public bool CanReach(Dictionary inventory) {
+ if (inventory.ContainsKey(this.Region)) {
return true;
+ } else {
+ return false;
}
-
- return false;
- }
-
- public List Rewards(List inventory) {
- List rewardsList = new List();
-
- // if you can reach, you get the center of the region. One-ways give you the center too
- if (CanReachCenterFromPortal(inventory) || this.OneWay == true) {
- rewardsList.Add(this.Scene);
- }
-
- if (this.Region == "Swamp Back") {
- rewardsList.Add("Swamp Back");
- } else if (this.Region == "Forest Belltower Upper") {
- rewardsList.Add("Forest Belltower Upper");
- rewardsList.Add("Forest Belltower Main");
- rewardsList.Add("Forest Belltower Lower");
- } else if (this.Region == "Forest Belltower Main") {
- rewardsList.Add("Forest Belltower Main");
- rewardsList.Add("Forest Belltower Lower");
- } else if (this.Region == "Forest Belltower Lower") {
- rewardsList.Add("Forest Belltower Lower");
- }
-
- return rewardsList;
}
-
}
}
diff --git a/src/Data/PortalCombo.cs b/src/Data/PortalCombo.cs
index 8f459f8..6943021 100644
--- a/src/Data/PortalCombo.cs
+++ b/src/Data/PortalCombo.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace TunicArchipelago {
public class PortalCombo {
@@ -20,5 +21,29 @@ public PortalCombo(Portal portal1, Portal portal2) {
};
}
+ public bool CanReach(Dictionary inventory) {
+ if (inventory.ContainsKey(this.Portal1.Region) || inventory.ContainsKey(this.Portal2.Region)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public Dictionary AddComboRegions(Dictionary inventory) {
+ // if both regions are in here already, just skip it
+ if (inventory.ContainsKey(this.Portal1.Region) && inventory.ContainsKey(this.Portal2.Region)) {
+ return inventory;
+ }
+ // if you can reach this portal combo, add whichever region you don't have yet
+ if (this.CanReach(inventory)) {
+ if (!inventory.ContainsKey(this.Portal1.Region)) {
+ inventory.Add(this.Portal1.Region, 1);
+ }
+ if (!inventory.ContainsKey(this.Portal2.Region)) {
+ inventory.Add(this.Portal2.Region, 1);
+ }
+ }
+ return inventory;
+ }
}
}
diff --git a/src/Data/RandomizerSettings.cs b/src/Data/RandomizerSettings.cs
index e5ad9b5..3d16b93 100644
--- a/src/Data/RandomizerSettings.cs
+++ b/src/Data/RandomizerSettings.cs
@@ -10,6 +10,87 @@ public class RandomizerSettings {
public ConnectionSettings ConnectionSettings { get; set; }
+ public enum RandomizerType {
+ SINGLEPLAYER,
+ ARCHIPELAGO
+ }
+
+ public RandomizerType Mode {
+ get;
+ set;
+ }
+
+ // Single Player Settings
+ public GameModes GameMode {
+ get;
+ set;
+ }
+
+ public bool KeysBehindBosses {
+ get;
+ set;
+ }
+
+ public bool StartWithSwordEnabled {
+ get;
+ set;
+ }
+
+ public bool SwordProgressionEnabled {
+ get;
+ set;
+ }
+
+ public bool ShuffleAbilities {
+ get;
+ set;
+ }
+
+ public bool EntranceRandoEnabled {
+ get;
+ set;
+ }
+
+ public bool ERFixedShop {
+ get;
+ set;
+ }
+
+ public int HexagonQuestGoal {
+ get;
+ set;
+ }
+
+ public int HexagonQuestExtraPercentage {
+ get;
+ set;
+ }
+
+ public bool Lanternless {
+ get;
+ set;
+ }
+
+ public bool Maskless {
+ get;
+ set;
+ }
+
+ public FixedLaurelsType FixedLaurelsOption {
+ get;
+ set;
+ }
+
+ public FoolTrapOption FoolTrapIntensity {
+ get;
+ set;
+ }
+
+ public bool MysterySeed {
+ get;
+ set;
+ }
+
// Archipelago Settings
public bool DeathLinkEnabled {
get;
@@ -52,6 +133,16 @@ public bool ChestsMatchContentsEnabled {
set;
}
+ public bool UseTrunicTranslations {
+ get;
+ set;
+ }
+
+ public bool CreateSpoilerLog {
+ get;
+ set;
+ }
+
// Gameplay Settings
public bool HeirAssistModeEnabled {
get;
@@ -114,6 +205,36 @@ public bool ExtraEnemiesEnabled {
set;
}
+ // Race Mode Settings
+ public bool RaceMode {
+ get;
+ set;
+ }
+
+ public bool DisableIceboltInHeirFight {
+ get;
+ set;
+ }
+
+ public bool DisableDistantBellShots {
+ get;
+ set;
+ }
+
+ public bool DisableIceGrappling {
+ get;
+ set;
+ }
+
+ public bool DisableLadderStorage {
+ get;
+ set;
+ }
+
+ public bool DisableUpgradeStealing {
+ get;
+ set;
+ }
// Fox Settings
public bool RandomFoxColorsEnabled {
@@ -131,6 +252,12 @@ public bool UseCustomTexture {
set;
}
+ public enum GameModes {
+ RANDOMIZER,
+ HEXAGONQUEST,
+ VANILLA
+ }
+
public enum FoolTrapOption {
NONE,
NORMAL,
@@ -148,24 +275,49 @@ public enum EnemyRandomizationType {
BALANCED
}
+ public enum FixedLaurelsType {
+ RANDOM,
+ SIXCOINS,
+ TENCOINS,
+ TENFAIRIES,
+ }
+
public RandomizerSettings() {
ConnectionSettings = new ConnectionSettings();
-/* GameMode = GameModes.RANDOMIZER;
+ Mode = RandomizerType.SINGLEPLAYER;
+
+ // Single Player
+ GameMode = GameModes.RANDOMIZER;
KeysBehindBosses = false;
SwordProgressionEnabled = true;
StartWithSwordEnabled = false;
- ShuffleAbilities = false;*/
+ ShuffleAbilities = false;
+ EntranceRandoEnabled = false;
+ ERFixedShop = false;
+ HexagonQuestGoal = 20;
+ HexagonQuestExtraPercentage = 50;
+ FixedLaurelsOption = FixedLaurelsType.RANDOM;
+ FoolTrapIntensity = FoolTrapOption.NORMAL;
+ Lanternless = false;
+ Maskless = false;
+ MysterySeed = false;
+
+ // Archipelago
DeathLinkEnabled = false;
CollectReflectsInWorld = false;
SkipItemAnimations = false;
SendHintsToServer = false;
+ // Hints
HeroPathHintsEnabled = true;
GhostFoxHintsEnabled = true;
ShowItemsEnabled = true;
ChestsMatchContentsEnabled = true;
+ UseTrunicTranslations = false;
+ CreateSpoilerLog = true;
+ // General
HeirAssistModeEnabled = false;
ClearEarlyBushes = false;
CheaperShopItemsEnabled = true;
@@ -175,11 +327,21 @@ public RandomizerSettings() {
MoreSkulls = false;
ArachnophobiaMode = false;
+ // Enemy Randomizer
EnemyRandomizerEnabled = false;
EnemyDifficulty = EnemyRandomizationType.BALANCED;
EnemyGeneration = EnemyGenerationType.SEEDED;
ExtraEnemiesEnabled = false;
+ // Race Settings
+ RaceMode = false;
+ DisableIceboltInHeirFight = false;
+ DisableDistantBellShots = false;
+ DisableIceGrappling = false;
+ DisableLadderStorage = false;
+ DisableUpgradeStealing = false;
+
+ // Fox Customization
RandomFoxColorsEnabled = true;
RealestAlwaysOn = false;
UseCustomTexture = false;
diff --git a/src/Data/SaveFlags.cs b/src/Data/SaveFlags.cs
index 223ccbf..cb2dfff 100644
--- a/src/Data/SaveFlags.cs
+++ b/src/Data/SaveFlags.cs
@@ -8,7 +8,7 @@ public class SaveFlags {
public const string HexagonQuestEnabled = "randomizer hexagon quest enabled";
public const string HexagonQuestPrayer = "randomizer hexagon quest prayer requirement";
public const string HexagonQuestHolyCross = "randomizer hexagon quest holy cross requirement";
- public const string HexagonQuestIceRod = "randomizer hexagon quest ice rod requirement";
+ public const string HexagonQuestIcebolt = "randomizer hexagon quest icebolt requirement";
public const string GoldHexagonQuantity = "inventory quantity Hexagon Gold";
public const string HexagonQuestGoal = "randomizer hexagon quest goal";
@@ -16,10 +16,10 @@ public class SaveFlags {
public const string AbilityShuffle = "randomizer shuffled abilities";
public const string PrayerUnlocked = "randomizer prayer unlocked";
public const string HolyCrossUnlocked = "randomizer holy cross unlocked";
- public const string IceRodUnlocked = "randomizer ice rod unlocked";
+ public const string IceBoltUnlocked = "randomizer icebolt unlocked";
public const string PrayerUnlockedTime = "randomizer prayer unlocked time";
public const string HolyCrossUnlockedTime = "randomizer holy cross unlocked time";
- public const string IceRodUnlockedTime = "randomizer ice rod unlocked time";
+ public const string IceboltUnlockedTime = "randomizer icebolt unlocked time";
// Keys Behind Bosses Flag
public const string KeysBehindBosses = "randomizer keys behind bosses";
@@ -31,10 +31,22 @@ public class SaveFlags {
// Entrance Rando Flag
public const string EntranceRando = "randomizer entrance rando enabled";
+ // Other Logic Flags
+ public const string MasklessLogic = "randomizer maskless logic enabled";
+ public const string LanternlessLogic = "randomizer lanternless logic enabled";
+
// Special Flags
public const string PlayerDeathCount = "randomizer death count";
public const string EnemiesDefeatedCount = "randomizer enemies defeated";
public const string DiedToHeir = "randomizer died to heir";
public const string RescuedLostFox = "randomizer sent lost fox home";
+
+ public static bool IsArchipelago() {
+ return SaveFile.GetInt("archipelago") == 1 && (Archipelago.instance != null && Archipelago.instance.integration != null && Archipelago.instance.integration.connected);
+ }
+
+ public static bool IsSinglePlayer() {
+ return SaveFile.GetInt("randomizer") == 1;
+ }
}
}
diff --git a/src/Data/Translations.cs b/src/Data/Translations.cs
new file mode 100644
index 0000000..82ceaa7
--- /dev/null
+++ b/src/Data/Translations.cs
@@ -0,0 +1,297 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TunicArchipelago {
+ public class Translations {
+
+ public static string Translate(string Input, bool CheckSetting) {
+
+ return ((CheckSetting ? TunicArchipelago.Settings.UseTrunicTranslations : true) && EnglishToTrunic.ContainsKey(Input)) ? EnglishToTrunic[Input] : Input.StartsWith($"\"") ? Input : $"\"{Input}\"";
+ }
+
+ public static string TranslateDefaultNoQuotes(string Input) {
+
+ return (TunicArchipelago.Settings.UseTrunicTranslations && EnglishToTrunic.ContainsKey(Input)) ? EnglishToTrunic[Input] : Input;
+ }
+
+ public static string TranslateDefaultNoQuotes(string Input, bool CheckSetting) {
+
+ return ((CheckSetting ? TunicArchipelago.Settings.UseTrunicTranslations : true) && EnglishToTrunic.ContainsKey(Input)) ? EnglishToTrunic[Input] : Input;
+ }
+
+ public static string TranslateDefaultQuotes(string Input) {
+ return (TunicArchipelago.Settings.UseTrunicTranslations && EnglishToTrunic.ContainsKey(Input)) ? EnglishToTrunic[Input] : $"\"{Input}\"";
+ }
+
+ public static Dictionary EnglishToTrunic = new Dictionary() {
+ {"Firecracker", "fIurkrahkur"},
+ {"Fire Bomb", "fIur bawm"},
+ {"Ice Bomb", "Is bawm"},
+ {"Lure", "lour"},
+ {"Pepper", "pehpur"},
+ {"Ivy", "IvE"},
+ {"Effigy", "ehfijE"},
+ {"Money", "muhnE"},
+ {"HP Berry", "Aj pE bArE"},
+ {"MP Berry", "ehm pE bArE"},
+ {"Fool Trap", "fool trahp"},
+ {"Stick", "stik"},
+ {"Sword", "sord"},
+ {"Sword Upgrade", "sord uhpgrAd"},
+ {"Magic Dagger", "mahjik dahgur"},
+ {"Magic Wand", "mahjik wawnd"},
+ {"Magic Orb", "mahjik orb"},
+ {"Hero's Laurels", "hErOz loruhlz"},
+ {"Lantern", "lahnturn"},
+ {"Shotgun", "$awtguhn"},
+ {"Gun", "guhn"},
+ {"Shield", "$Eld"},
+ {"Dath Stone", "dah% stOn"},
+ {"Hourglass", "owurglahs"},
+ {"Old House Key", "Old hows kE"},
+ {"Key", "kE"},
+ {"Fortress Vault Key", "fOrtris vawlt kE"},
+ {"Flask Shard", "flahsk #Rd"},
+ {"Potion Flask", "pO$uhn flahsk"},
+ {"Golden Coin", "gOldin koin"},
+ {"Card Slot", "kRd slawt"},
+ {"Red Hexagon", "rehd kwehstuhgawn"},
+ {"Green Hexagon", "grEn kwehstuhgawn"},
+ {"Blue Hexagon", "bloo kwehstuhgawn"},
+ {"Gold Hexagon", "gOld kwehstuhgawn"},
+ {"ATT Offering", "uhtahk awfuri^"},
+ {"DEF Offering", "difehns awfuri^"},
+ {"Potion Offering", "pO$uhn awfuri^"},
+ {"HP Offering", "Aj pE awfuri^"},
+ {"SP Offering", "ehs pE awfuri^"},
+ {"MP Offering", "ehm pE awfuri^"},
+ {"Hero Relic - ATT", $"hErO rehlik \"-\" uhtahk"},
+ {"Hero Relic - DEF", $"hErO rehlik \"-\" difehns"},
+ {"Hero Relic - POTION", $"hErO rehlik \"-\" pO$uhn"},
+ {"Hero Relic - HP", $"hErO rehlik \"-\" Aj pE"},
+ {"Hero Relic - SP", $"hErO rehlik \"-\" ehs pE"},
+ {"Hero Relic - MP", $"hErO rehlik \"-\" ehm pE"},
+ {"Orange Peril Ring", "oruhnj pAruhl ri^"},
+ {"Tincture", "ti^kJur"},
+ {"Scavenger Mask", "skahvuhnjur mahsk"},
+ {"Cyan Peril Ring", "sIahn pAruhl ri^"},
+ {"Bracer", "brAsur"},
+ {"Dagger Strap", "dahgur strahp"},
+ {"Inverted Ash", "invurtid ah$"},
+ {"Lucky Cup", "luhkE kuhp"},
+ {"Magic Echo", "mahjik ehkO"},
+ {"Anklet", "ah^klit"},
+ {"Muffling Bell", "muhfli^ behl"},
+ {"Glass Cannon", "glahs kahnuhn"},
+ {"Perfume", "purfyoom"},
+ {"Louder Echo", "lowdur ehkO"},
+ {"Aura's Gem", "oruhz jehm"},
+ {"Bone Card", "bOn kRd"},
+ {"Fairy", "fArE"},
+ {"Mr Mayor", "mistur mAor"},
+ {"Secret Legend", "sEkrit lehjehnd"},
+ {"Sacred Geometry", "sAkrid jEawmuhtrE"},
+ {"Vintage", "vintij"},
+ {"Just Some Pals", "juhst suhm pahlz"},
+ {"Regal Weasel", "rEguhl wEzuhl"},
+ {"Spring Falls", "spri^ fawlz"},
+ {"Power Up", "powur uhp"},
+ {"Back To Work", "bahk too wurk"},
+ {"Phonomath", "fOnuhmah%"},
+ {"Dusty", "duhstE"},
+ {"Forever Friend", "forehvur frehnd"},
+ {"Pages 0-1", $"pAjuhz \"0-1\""},
+ {"Pages 2-3", $"pAjuhz \"2-3\""},
+ {"Pages 4-5", $"pAjuhz \"4-5\""},
+ {"Pages 6-7", $"pAjuhz \"6-7\""},
+ {"Pages 8-9", $"pAjuhz \"8-9\""},
+ {"Pages 10-11", $"pAjuhz \"10-11\""},
+ {"Pages 12-13", $"pAjuhz \"12-13\""},
+ {"Pages 14-15", $"pAjuhz \"14-15\""},
+ {"Pages 16-17", $"pAjuhz \"16-17\""},
+ {"Pages 18-19", $"pAjuhz \"18-19\""},
+ {"Pages 20-21", $"pAjuhz \"20-21\""},
+ {"Pages 22-23", $"pAjuhz \"22-23\""},
+ {"Pages 24-25 (Prayer)", $"pAjuhz \"24-25\" (prAr)"},
+ {"Pages 26-27", $"pAjuhz \"26-27\""},
+ {"Pages 28-29", $"pAjuhz \"28-29\""},
+ {"Pages 30-31", $"pAjuhz \"30-31\""},
+ {"Pages 32-33", $"pAjuhz \"32-33\""},
+ {"Pages 34-35", $"pAjuhz \"34-35\""},
+ {"Pages 36-37", $"pAjuhz \"36-37\""},
+ {"Pages 38-39", $"pAjuhz \"38-39\""},
+ {"Pages 40-41", $"pAjuhz \"40-41\""},
+ {"Pages 42-43 (Holy Cross)", $"pAjuhz \"42-43\" (hOlE kraws)"},
+ {"Pages 44-45", $"pAjuhz \"44-45\""},
+ {"Pages 46-47", $"pAjuhz \"46-47\""},
+ {"Pages 48-49", $"pAjuhz \"48-49\""},
+ {"Pages 50-51", $"pAjuhz \"50-51\""},
+ {"Pages 52-53 (Icebolt)", $"pAjuhz \"52-53\" (IsbOlt)"},
+ {"Pages 54-55", $"pAjuhz \"54-55\""},
+ {"Overworld", "Ovurwurld"},
+ {"West Furnace", "wehst furnis"},
+ {"Cube Cave", "kyoob kAv"},
+ {"Stick House", "stik hows"},
+ {"Windmill", "windmil"},
+ {"Southeast Cross Room", "sow%Est kraws room"},
+ {"Caustic Light Cave", "kawstik lIt kAv"},
+ {"Ruined Passage", "rooind"},
+ {"Patrol Cave", "pahsuhj"},
+ {"Secret Gathering Place", "sEkrit gah#uri^ plAs"},
+ {"Fountain Cross Room", "fowntin kraws room"},
+ {"Hourglass Cave", "owurglahs kAv"},
+ {"Maze Cave", "mAz kAv"},
+ {"Ruined Shop", "rooind $awp"},
+ {"Changing Room", "JAnji^ room"},
+ {"Special Shop", "speh$uhl $awp"},
+ {"Old House", "Old hows"},
+ {"Far Shore", "fR $or"},
+ {"Sealed Temple", "sEld tehmpuhl"},
+ {"Shop", "$awp"},
+ {"Coins in the Well", "koinz in #uh wehl"},
+ {"Forest Belltower", "foruhst behltowur"},
+ {"East Forest", "Est foruhst"},
+ {"Forest Grave Path", "foruhst grAv pah%"},
+ {"Guardhouse 2", "gRdhows 2"},
+ {"Guardhouse 1", "gRdhows 1"},
+ {"Forest Boss Room", "forist baws room"},
+ {"Bottom of the Well", "bawtuhm uhv #uh wehl"},
+ {"Dark Tomb Checkpoint", "dRk toom Jehkpoint"},
+ {"Dark Tomb", "dRk toom"},
+ {"West Garden", "wehst gRdin"},
+ {"West Garden House", "wehst gRdin hows"},
+ {"Ruined Atoll", "rooind ahtawl"},
+ {"Frog Stairway", "frawg stArwA"},
+ {"Frog's Domain", "frawgz dOmAn"},
+ {"Library Exterior", "lIbrArE ehkstErEur"},
+ {"Library Hall", "lIbrArE hawl"},
+ {"Library Rotunda", "lIbrArE rOtuhnduh"},
+ {"Library Lab", "lIbrArE lahb"},
+ {"Librarian", "lIbrArEuhn"},
+ {"Beneath the Fortress", "bEnE% #uh fortruhs"},
+ {"Eastern Vault Fortress", "Esturn vawlt fortruhs"},
+ {"Fortress East Shortcut", "fortruhs Est $ortkuht"},
+ {"Fortress Grave Path", "fortruhs grAv pah%"},
+ {"Fortress Courtyard", "fortruhs kortyRd"},
+ {"Fortress Leaf Piles", "fortruhs lEf pIlz"},
+ {"Fortress Arena", "fortruhs uhrEnuh"},
+ {"Lower Mountain", "lOur mowntin"},
+ {"Top of the Mountain", "tawp uhv #uh mowntin"},
+ {"Quarry Entryway", "kworE ehntrEwA"},
+ {"Quarry", "kworE"},
+ {"Monastery", "mawnuhstArE"},
+ {"Rooted Ziggurat Entrance", "ziguraht ehntruhns"},
+ {"Rooted Ziggurat Upper", "uhpur ziguraht"},
+ {"Rooted Ziggurat Tower", "ziguraht towur"},
+ {"Rooted Ziggurat Lower", "lOur ziguraht"},
+ {"Rooted Ziggurat Teleporter", "ziguraht tehluhportur"},
+ {"Swamp", "swawmp"},
+ {"Cathedral", "kuh%Edruhl"},
+ {"Cathedral Gauntlet", "kuh%Edruhl gawntluht"},
+ {"Hero's Grave", "hErOz grAv"},
+ {"Glyph Tower", "glif towur"},
+ {"The Heir", "#uh Ar"},
+ {"Purgatory", "purguhtorE"},
+ {"Your Pocket", "yor pawkit"},
+ {"FOUR SKULLS", "for skuhlz"},
+ {"EAST FOREST SLIME", "Est foruhst slIm"},
+ {"CATHEDRAL GAUNTLET", "kuh%Edruhl gawntluht"},
+ {"SIEGE ENGINE", "sEj ehnhjuhn"},
+ {"LIBRARIAN", "lIbrArEuhn"},
+ {"SCAVENGER BOSS", "skahvuhnjur baws"},
+ {"VAULT KEY PLINTH", "vawlt kE plin%"},
+ {"20 FAIRIES", "20 fArEz"},
+ {"10 COIN TOSSES", "10 koin tawsiz"},
+ {"15 COIN TOSSES", "15 koin tawsiz"},
+ {"PILES OF LEAVES", "pIlz uhv lEvs"},
+ {"WEST GARDEN TREE", "wehst gRdin trE"},
+ {"TOP OF THE MOUNTAIN", "tawp uhv #uh mowntin"},
+ {"BONUS CUSTOMIZATION Unlocked", "bOnuhs kuhstuhmizA$uhn uhnlawkd"},
+ {"PRAYER Unlocked", "prAr uhnlawkd"},
+ {"HOLY CROSS Unlocked", "hOlE kraws uhnlawkd"},
+ {"ICEBOLT Unlocked", "IsbOlt uhnlawkd"},
+ {"\"Blob\"", "blawb"},
+ {"\"Hedgehog\"", "hehjhawg"},
+ {"\"Rudeling\"", "roodli^"},
+ {"\"Plover\"", "plOvur"},
+ {"\"Baby Slorm\"", "bAbE slorm"},
+ {"\"Crabbit\"", "krahbit"},
+ {"gAmkyoob \"Crabbit\"", "gAmkyoob krahbit"},
+ {"yoo...\"?\"", "yoo...?"},
+ {"\"Blob\" (big)", "blawb (big)"},
+ {"\"Blob\" (bigur)", "blawb (bigur)"},
+ {"\"Hedgehog\" (big)", "hehjhawg (big)"},
+ {"\"Phrend\"", "frehnd"},
+ {"\"Spyrite\"", "spIrIt"},
+ {"\"Fleemer\"", "flEmur"},
+ {"\"Fairy\" (Is)", "fArE (Is)"},
+ {"\"Fairy\" (fIur)", "fArE (fIur)"},
+ {"\"Rudeling\" ($Eld)", "roodli^ ($Eld)"},
+ {"\"Crabbo\"", "krahbO"},
+ {"\"Slorm\"", "slorm"},
+ {"\"Autobolt\"", "awtObOlt"},
+ {"\"Laser Turret\"", "lAzur turit"},
+ {"\"Administrator\" (frehnd)", "ahdminuhstrAtur (frehnd)"},
+ {"slorm...\"?\"", "slorm...?"},
+ {"\"???\"", "???"},
+ {"\"Custodian\" (kahnduhlahbruh)", "kuhstOdEuhn (kahnduhlahbruh)"},
+ {"\"Tentacle\"", "tehntuhkuhl"},
+ {"\"Envoy\"", "awnvoi"},
+ {"\"Guard Captain\"", "gRd kahptuhn"},
+ {"\"Husher\"", "huh$ur"},
+ {"\"Terry\"", "tArE"},
+ {"\"Terry\" (void)", "tArE (void)"},
+ {"\"Scavenger\" (snIpur)", "skahvuhnjur (snIpur)"},
+ {"\"Scavenger\" (mInur)", "skahvuhnjur (mInur)"},
+ {"\"Scavenger\" (suhport)", "skahvuhnjur (suhport)"},
+ {"\"Scavenger\" (stuhnur)", "skahvuhnjur (stuhnur)"},
+ {"\"Fleemer\" (fehnsur)", "flEmur (fehnsur)"},
+ {"\"Lost Echo\"", "lawst ehkO"},
+ {"\"Voidling\"", "voidli^"},
+ {"\"Frog\" (spEr) [frog]", "frawg (spEr) [frog]"},
+ {"\"Frog\" [frog]", "frawg [frog]"},
+ {"\"Frog\" (smawl) [frog]", "frawg (smawl) [frog]"},
+ {"\"Sappharach\"", "sahfuhrahk"},
+ {"\"Custodian\"", "kuhstOdEuhn"},
+ {"\"Custodian\" (suhport)", "kuhstOdEuhn (suhport)"},
+ {"\"Husher\" (void)", "huh$ur (void)"},
+ {"\"Woodcutter\"", "woudkuhtur"},
+ {"\"You...?\"", "yoo...?"},
+ {"\"Administrator\"", "ahdminuhstrAtur"},
+ {"\"Gunslinger\"", "guhnsli^ur"},
+ {"\"Beefboy\"", "bEfboi"},
+ {"\"Fleemer\" (lRj)", "flEmur (lRj)"},
+ {"\"Garden Knight...?\"", "gRdin nIt...?"},
+ {"gRdin nIt...\"?\"", "gRdin nIt...?"},
+ {"\"Voidtouched\"", "voidtuhJd"},
+ {"\"Centipede\"", "sehntipEd"},
+ {"\"Shadowreaper\"", "$ahdOrEpur"},
+ {"\"Phrend\" (void)", "frehnd (void)"},
+ {"\"Rudeling\" (void)", "roodli^ (void)"},
+ {"\"Frog...?\" (smawl) [frog]", "frawg...? (smawl) [frog]"},
+ {"\"Frog...?\" (spEr) [frog]", "frawg...? (spEr) [frog]"},
+ {"\"Fairy...?\"", "fArE...?"},
+ {"\"Fleemer...?\"", "flEmur...?"},
+ {"\"Fleemer...?\" (lRj)", "flEmur...? (lRj)"},
+ {"\"Custodian...?\" (suhport)", "kuhstOdEuhn...? (suhport)"},
+ {"\"Rudeling...?\"", "roodli^...?"},
+ {"\"Rudeling...?\" ($Eld)", "roodli^...? ($Eld)"},
+ {"\"Guard Captain...?\"", "gRd kahptuhn...?"},
+ {$"kawngrahJoulA$uhnz! \"(<#e99d4c>+1 ATT<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#e99d4c>[arrow_up]1 uhtahk<#FFFFFF>)"},
+ {$"kawngrahJoulA$uhnz! \"(<#5de7cf>+1 DEF<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#5de7cf>[arrow_up]1 difehns<#FFFFFF>)"},
+ {$"kawngrahJoulA$uhnz! \"(<#ca7be4>+1 POTION<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#ca7be4>[arrow_up]1 pO$uhn<#FFFFFF>)"},
+ {$"kawngrahJoulA$uhnz! \"(<#f03c67>+1 HP<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#f03c67>[arrow_up]1 Aj pE<#FFFFFF>)"},
+ {$"kawngrahJoulA$uhnz! \"(<#8ddc6e>+1 SP<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#8ddc6e>[arrow_up]1 ehs pE<#FFFFFF>)"},
+ {$"kawngrahJoulA$uhnz! \"(<#2a8fed>+1 MP<#FFFFFF>)\"", $"kawngrahJoulA$uhnz! (<#2a8fed>[arrow_up]1 ehm pE<#FFFFFF>)"},
+ {$"\"Hero Relic - <#e99d4c>ATT\"", $"hErO rehlik \"-\" <#e99d4c>uhtahk"},
+ {$"\"Hero Relic - <#5de7cf>DEF\"", $"hErO rehlik \"-\" <#5de7cf>difehns"},
+ {$"\"Hero Relic - <#ca7be4>POTION\"", $"hErO rehlik \"-\" <#ca7be4>pO$uhn"},
+ {$"\"Hero Relic - <#f03c67>HP\"", $"hErO rehlik \"-\" <#f03c67>Aj pE"},
+ {$"\"Hero Relic - <#8ddc6e>SP\"", $"hErO rehlik \"-\" <#8ddc6e>ehs pE"},
+ {$"\"Hero Relic - <#2a8fed>MP\"", $"hErO rehlik \"-\" <#2a8fed>ehm pE"},
+ };
+ }
+}
diff --git a/src/Data/VanillaCheck.cs b/src/Data/VanillaCheck.cs
deleted file mode 100644
index b520e51..0000000
--- a/src/Data/VanillaCheck.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace TunicArchipelago {
-
- public struct VanillaLocation {
- public string LocationId;
- public string Position;
- public List> RequiredItems;
- public List> RequiredItemsDoors;
- public int SceneId;
- public string SceneName;
- }
- public struct VanillaReward {
- public int Amount;
- public string Name;
- public string Type;
- }
- public class VanillaCheck {
- public VanillaLocation Location;
- public VanillaReward Reward;
-
- public VanillaCheck() { }
-
- public VanillaCheck(VanillaLocation location, VanillaReward reward) {
- Location = location;
- Reward = reward;
- }
- }
-}
diff --git a/src/Patches/CustomItemBehaviors.cs b/src/Patches/CustomItemBehaviors.cs
index f83a863..646b9e1 100644
--- a/src/Patches/CustomItemBehaviors.cs
+++ b/src/Patches/CustomItemBehaviors.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
+using UnityEngine.SceneManagement;
using static TunicArchipelago.SaveFlags;
namespace TunicArchipelago {
@@ -166,6 +167,29 @@ public static bool BoneItemBehavior_confirmBoneUseCallback_PrefixPatch(BoneItemB
return true;
}
+ public static bool ForcewandItemBehaviour__throwBeamCoroutine_d__32_MoveNext_PrefixPatch(ForcewandItemBehaviour._throwBeamCoroutine_d__32 __instance) {
+
+ // Checks if the toggle for disabling ice grappling is on, and if target is a frozen enemy
+ if (__instance.__8__1 != null && __instance.__8__1.gameObjectToTether != null
+ && __instance.__8__1.gameObjectToTether.GetComponent() != null && __instance.__8__1.gameObjectToTether.GetComponent().Frozen
+ && TunicArchipelago.Settings.RaceMode && TunicArchipelago.Settings.DisableIceGrappling) {
+ // Allow the east forest slime to be grappled still
+ if (SceneManager.GetActiveScene().name == "East Forest Redux" && __instance.__8__1.gameObjectToTether.transform.parent != null && __instance.__8__1.gameObjectToTether.transform.parent.name == "_MONSTERS ALWAYS") {
+ return true;
+ }
+
+ // Cancel orb animation and refund mp to player if ice grapples are disabled
+ __instance.__8__1.gameObjectToTether = null;
+ __instance.__8__1.ztargOfTetheredObject = null;
+ __instance.__4__this.tentacleBeamRenderer.enabled = false;
+
+ __instance.__4__this.StopAllCoroutines();
+ PlayerCharacter.SetMP(PlayerCharacter.GetMP() + __instance.__4__this.usageCostDat.IntValue);
+
+ }
+ return true;
+ }
+
public static void SetupTorchItemBehaviour(PlayerCharacter instance) {
instance.GetComponent().item = Inventory.GetItemByName("Dath Stone").TryCast();
List itemBehaviours = instance.itemBehaviours.ToList();
diff --git a/src/Patches/EnemyRandomizer.cs b/src/Patches/EnemyRandomizer.cs
index 43393c0..957cf9a 100644
--- a/src/Patches/EnemyRandomizer.cs
+++ b/src/Patches/EnemyRandomizer.cs
@@ -34,9 +34,33 @@ public class EnemyRandomizer {
};
public static List ExcludedScenes = new List() {
+ "PatrolCave",
"Library Arena",
"Fortress Arena",
- "Spirit Arena"
+ "Spirit Arena",
+ };
+
+ public static List DoNotPlaceCoffeeTableHere = new List() {
+ "Cathedral Redux Fox enemy zombie (13)",
+ "Fortress Basement Spider Small (3)",
+ "Fortress Basement Spider Small (5)",
+ "Sewer Bat (7)", "Sewer Bat (8)", "Sewer Bat (9)",
+ "Sewer Bat (10)", "Sewer Bat (11)", "Sewer Bat (12)",
+ "East Forest Redux Skuladot redux (4)",
+ "East Forest Redux Skuladot redux (5)",
+ "East Forest Redux Skuladot redux (6)",
+ };
+ public static List DoNotPlaceTurretHere = new List() {
+ "Cathedral Redux Fox enemy zombie (13)",
+ "Fortress Basement Spider Small (3)",
+ "Fortress Basement Spider Small (5)",
+ "Sewer Bat (7)", "Sewer Bat (8)", "Sewer Bat (9)",
+ "Sewer Bat (10)", "Sewer Bat (11)", "Sewer Bat (12)",
+ "East Forest Redux Skuladot redux (4)",
+ "East Forest Redux Skuladot redux (5)",
+ "East Forest Redux Skuladot redux (6)",
+ "East Forest Redux Spider Small (8)",
+ "Overworld Redux Honourguard",
};
public static Dictionary> LocationEnemies = new Dictionary>() {
@@ -136,6 +160,15 @@ public class EnemyRandomizer {
"Cathedral Arena",
new List() {
"tech knight ghost",
+ "Frog Small_Ghost",
+ "Frog Spear_Ghost",
+ "Fairyprobe Archipelagos (Ghost)",
+ "bomezome_easy_ghost",
+ "bomezome_easy_ghost (tweaked)",
+ "Wizard_Support_Ghost",
+ "Skuladot redux_ghost",
+ "Skuladot redux_shield_ghost",
+ "Skuladot redux Big_ghost",
}
},
{
@@ -175,6 +208,13 @@ public class EnemyRandomizer {
"administrator_servant"
}
},
+ {
+ "Library Arena",
+ new List () {
+ "Bat_librarian add",
+ "Skuladot redux_librarian add"
+ }
+ },
{
"Posterity",
new List () {
@@ -191,26 +231,30 @@ public class EnemyRandomizer {
"Blob",
"Hedgehog",
"Skuladot redux",
+ "Skuladot redux void",
+ "Skuladot redux_ghost",
"plover",
"Spinnerbot Baby",
"Crabbit",
- "Crabbit with Shell",
"Fox enemy zombie",
"BlobBig",
"BlobBigger",
"HedgehogBig",
"Bat",
+ "Bat void",
"Spider Small",
"bomezome_easy",
+ "bomezome_easy_ghost",
"Fairyprobe Archipelagos",
+ "Fairyprobe Archipelagos (Ghost)",
"Fairyprobe Archipelagos (Dmg)",
"Skuladot redux_shield",
- "Crabbo",
- "Spinnerbot Corrupted",
+ "Skuladot redux_shield_ghost",
"Turret",
"Hedgehog Trap",
"administrator_servant",
"Phage",
+ "Spinnerbot Corrupted",
}
},
{
@@ -220,7 +264,9 @@ public class EnemyRandomizer {
"sewertentacle",
"Honourguard",
"Skuladot redux Big",
+ "Skuladot redux Big_ghost",
"Crow",
+ "Crow Voidtouched",
"crocodoo",
"crocodoo Voidtouched",
"Scavenger",
@@ -230,17 +276,22 @@ public class EnemyRandomizer {
"bomezome_fencer",
"Ghostfox_monster",
"voidling redux",
- "Frog Spear",
"Frog",
"Frog Small",
+ "Frog Small_Ghost",
+ "Frog Spear",
+ "Frog Spear_Ghost",
"Spider Big",
+ "Crabbo",
+ "Crabbit with Shell",
"Wizard_Sword",
"Wizard_Support",
- "Crow Voidtouched",
+ "Wizard_Support_Ghost",
"woodcutter",
"Fox enemy",
"Centipede",
"Ghost Knight",
+ "bomezome_easy_ghost (tweaked)",
}
},
{
@@ -315,6 +366,17 @@ public class EnemyRandomizer {
{ "Voidtouched", $"\"Voidtouched\"" },
{ "Centipede", $"\"Centipede\"" },
{ "Shadowreaper", $"\"Shadowreaper\"" },
+ { "Bat void", $"\"Phrend\" (void)" },
+ { "Skuladot redux void", $"\"Rudeling\" (void)" },
+ { "Frog Small_Ghost", $"\"Frog...?\" (smawl) [frog]" },
+ { "Frog Spear_Ghost", $"\"Frog...?\" (spEr) [frog]" },
+ { "Fairyprobe Archipelagos (Ghost)", $"\"Fairy...?\"" },
+ { "bomezome_easy_ghost", $"\"Fleemer...?\"" },
+ { "bomezome_easy_ghost (tweaked)", $"\"Fleemer...?\" (lRj)" },
+ { "Wizard_Support_Ghost", $"\"Custodian...?\" (suhport)" },
+ { "Skuladot redux_ghost", $"\"Rudeling...?\"" },
+ { "Skuladot redux_shield_ghost", $"\"Rudeling...?\" ($Eld)" },
+ { "Skuladot redux Big_ghost", $"\"Guard Captain...?\"" },
};
public static void CreateAreaSeeds() {
@@ -333,6 +395,8 @@ public static void InitializeEnemies(string SceneName) {
{ "Hedgehog Trap (1)", "Hedgehog Trap" },
{ "Centipede from egg (Varient)", "Centipede" },
{ "Spinnerbot (3)", "Spinnerbot Corrupted" },
+ { "Bat_librarian add", "Bat void" },
+ { "Skuladot redux_librarian add", "Skuladot redux void" },
};
foreach (string LocationEnemy in LocationEnemies[SceneName]) {
string EnemyName = LocationEnemy;
@@ -360,6 +424,7 @@ public static void InitializeEnemies(string SceneName) {
if (EnemyName == "Centipede") {
Enemies[EnemyName].GetComponent().maxBeamDistance = 10f;
Enemies[EnemyName].GetComponent().attackDistance = 5f;
+ Enemies[EnemyName].GetComponent().monsterAggroDistance = 20f;
}
if (EnemyName == "Crabbit with Shell") {
Enemies["Crabbit"] = GameObject.Instantiate(Enemies[EnemyName]);
@@ -383,6 +448,32 @@ public static void InitializeEnemies(string SceneName) {
GameObject.DontDestroyOnLoad(Enemies["Crabbo"]);
}
+ if (EnemyName == "Bat void") {
+ Enemies[EnemyName].GetComponent().monsterAggroDistance = 4;
+ }
+
+ if (EnemyName == "Skuladot redux_ghost") {
+ Enemies[EnemyName].GetComponent().dropValue = Enemies["Skuladot redux"].GetComponent().dropValue;
+ }
+ if (EnemyName == "Skuladot redux_shield_ghost") {
+ Enemies[EnemyName].GetComponent().dropValue = Enemies["Skuladot redux_shield"].GetComponent().dropValue;
+ }
+ if (EnemyName == "Skuladot redux Big_ghost") {
+ Enemies[EnemyName].GetComponent().dropValue = Enemies["Skuladot redux Big"].GetComponent().dropValue;
+ }
+ if (EnemyName == "bomezome_easy") {
+ Enemies["bomezome_easy_ghost"].GetComponent().dropValue = Enemies["bomezome_easy"].GetComponent().dropValue;
+ }
+ if (EnemyName == "Frog Small") {
+ Enemies["Frog Small_Ghost"].GetComponent().dropValue = Enemies["Frog Small"].GetComponent().dropValue;
+ }
+ if (EnemyName == "Frog Spear") {
+ Enemies["Frog Spear_Ghost"].GetComponent().dropValue = Enemies["Frog Spear"].GetComponent().dropValue;
+ }
+ if (EnemyName == "Wizard_Support") {
+ Enemies["Wizard_Support_Ghost"].GetComponent().dropValue = Enemies["Wizard_Support"].GetComponent().dropValue;
+ }
+
Enemies[EnemyName].name = EnemyName + " Prefab";
}
if (SceneName == "Archipelagos Redux") {
@@ -440,6 +531,12 @@ public static void SpawnNewEnemies() {
if (CurrentScene == "Forest Boss Room" && GameObject.Find("Skuladot redux") != null) {
Monsters.Add(GameObject.Find("Skuladot redux"));
}
+ if (CurrentScene == "Fortress Basement") {
+ Monsters.AddRange(Resources.FindObjectsOfTypeAll().Where(slorm => slorm.GetComponent() != null && slorm.gameObject.scene.name == CurrentScene && slorm.name == "Spinnerbot Baby").ToList());
+ }
+ if (CurrentScene == "frog cave main") {
+ Monsters.Add(GameObject.Find("Wizard_Support"));
+ }
if (TunicArchipelago.Settings.ExtraEnemiesEnabled && CurrentScene == "Monastery") {
Resources.FindObjectsOfTypeAll().ToList()[0].gameObject.transform.parent = null;
}
@@ -469,6 +566,7 @@ public static void SpawnNewEnemies() {
if (CurrentScene == "ziggurat2020_1" && Enemy.GetComponent() != null) {
EnemyKeys.Remove("Hedgehog Trap");
EnemyKeys.Remove("administrator_servant");
+ EnemyKeys.Remove("Shadowreaper");
}
if (CurrentScene == "Forest Boss Room" && Enemy.GetComponent() != null) {
EnemyKeys.Remove("administrator_servant");
@@ -478,10 +576,36 @@ public static void SpawnNewEnemies() {
Enemy.name = Enemy.name.Replace("Spinnerbot", "Spinnerbot Corrupted");
}
if (TunicArchipelago.Settings.ExtraEnemiesEnabled) {
- if (Enemy.transform.parent != null && Enemy.transform.parent.name.Contains("NG+")) {
+ if (Enemy.transform.parent != null && (Enemy.transform.parent.name.Contains("NG+") || Enemy.transform.parent.name.ToLower().Contains("night"))) {
Enemy.transform.parent.gameObject.SetActive(true);
}
+
+ if (CurrentScene == "Monastery") {
+ if (GameObject.Find("_NIGHT/Corruption Blocker/") != null) {
+ GameObject.Find("_NIGHT/Corruption Blocker/").SetActive(false);
+ }
+ if (GameObject.Find("_NIGHT/Corruption Blocker (retreat door)/") != null) {
+ GameObject.Find("_NIGHT/Corruption Blocker (retreat door)/").SetActive(false);
+ }
+ }
}
+ if (DoNotPlaceCoffeeTableHere.Contains($"{CurrentScene} {Enemy.name}")) {
+ EnemyKeys.Remove("administrator_servant");
+ }
+ if (DoNotPlaceTurretHere.Contains($"{CurrentScene} {Enemy.name}")) {
+ EnemyKeys.Remove("Turret");
+ }
+ // Make alternate variants of certain enemies slightly less common
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Frog Small" : "Frog Small_Ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Frog Spear" : "Frog Spear_Ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Fairyprobe Archipelagos" : "Fairyprobe Archipelagos (Ghost)");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "bomezome_easy" : "bomezome_easy_ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Wizard_Support" : "Wizard_Support_Ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.50 ? "Skuladot redux void" : "Skuladot redux_ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Skuladot redux_shield" : "Skuladot redux_shield_ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Skuladot redux Big" : "Skuladot redux Big_ghost");
+ EnemyKeys.Remove(Random.NextDouble() < 0.25 ? "Bat" : "Bat void");
+
string NewEnemyName = "";
if (TunicArchipelago.Settings.EnemyDifficulty == RandomizerSettings.EnemyRandomizationType.RANDOM) {
NewEnemy = GameObject.Instantiate(Enemies[EnemyKeys[Random.Next(EnemyKeys.Count)]]);
@@ -513,13 +637,7 @@ public static void SpawnNewEnemies() {
if (EnemyTypes == null) {
NewEnemy = GameObject.Instantiate(Enemies[EnemyKeys[Random.Next(EnemyKeys.Count)]]);
} else {
- if (CurrentScene == "Cathedral Arena") {
- EnemyTypes.Remove("administrator_servant");
- EnemyTypes.Remove("Hedgehog Trap");
- if (Inventory.GetItemByName("Wand").Quantity == 0) {
- EnemyTypes.Remove("Crabbit with Shell");
- }
- }
+ EnemyTypes = EnemyTypes.Where(x => EnemyKeys.Contains(x)).ToList();
NewEnemy = GameObject.Instantiate(Enemies[EnemyTypes[Random.Next(EnemyTypes.Count)]]);
}
} else {
@@ -552,7 +670,7 @@ public static void SpawnNewEnemies() {
TopLine.text = $"\"Enemy\"";
foreach (string Key in ProperEnemyNames.Keys) {
if (NewEnemy.name.Replace(" Prefab", "").Replace("(Clone)", "") == Key) {
- TopLine.text = ProperEnemyNames[Key];
+ TopLine.text = Translations.TranslateDefaultNoQuotes(ProperEnemyNames[Key]);
if (NewEnemy.name.Contains("crocodoo")) {
BottomLine.text = $"#uh wuhn ahnd OnlE";
} else if (EnemyRankings["Average"].Contains(Key)) {
@@ -612,6 +730,10 @@ public static void SpawnNewEnemies() {
}
}
+ if (NewEnemy.GetComponent() != null && NewEnemy.name.ToLower().Contains("servant")) {
+ NewEnemy.GetComponent().extents /= 2;
+ }
+
NewEnemy.name += $" {i}";
EnemiesInCurrentScene.Add(NewEnemy.name, NewEnemy.transform.position.ToString());
@@ -709,9 +831,8 @@ private static GameObject CreateRune(string name, Transform parent, Vector3 loca
}
public static bool Monster_Die_MoveNext_PrefixPatch(Monster._Die_d__77 __instance, ref bool __result) {
- if (__instance.__4__this.GetComponent() != null) {
+ if (__instance.__4__this.GetComponent() != null && IsArchipelago()) {
if (SceneManager.GetActiveScene().name == "Forest Boss Room") {
- StateVariable.GetStateVariableByName("SV_Forest Boss Room_Skuladot redux Big").BoolValue = true;
Archipelago.instance.UpdateDataStorage("Defeated Guard Captain", true);
}
if (__instance.__4__this.GetComponent() != null) {
@@ -728,6 +849,11 @@ public static bool Monster_Die_MoveNext_PrefixPatch(Monster._Die_d__77 __instanc
}
}
+ if (SceneLoaderPatches.SceneName == "Forest Boss Room" && __instance.__4__this.GetComponent() != null) {
+ StateVariable.GetStateVariableByName("SV_Forest Boss Room_Skuladot redux Big").BoolValue = true;
+ }
+
+
if (__instance.__4__this.GetComponent() != null) {
CoinSpawner.SpawnCoins(50, __instance.__4__this.transform.position);
MPPickup.Drop(100f, __instance.__4__this.transform.position);
diff --git a/src/Patches/FairyTargets.cs b/src/Patches/FairyTargets.cs
index c61c831..821abb5 100644
--- a/src/Patches/FairyTargets.cs
+++ b/src/Patches/FairyTargets.cs
@@ -1,23 +1,34 @@
-using System;
+using BepInEx.Logging;
+using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UnhollowerBaseLib;
using UnityEngine;
+using UnityEngine.SceneManagement;
namespace TunicArchipelago {
public class FairyTargets {
+ public static Il2CppSystem.Collections.Generic.List EntranceTargets = new Il2CppSystem.Collections.Generic.List { };
+ public static Il2CppSystem.Collections.Generic.List ItemTargets = new Il2CppSystem.Collections.Generic.List { };
public static void CreateFairyTargets() {
+
foreach (FairyTarget FairyTarget in Resources.FindObjectsOfTypeAll()) {
GameObject.Destroy(FairyTarget);
}
- if (ItemLookup.ItemList.Count > 0) {
- List ItemIdsInScene = Locations.VanillaLocations.Keys.Where(ItemId => Locations.VanillaLocations[ItemId].Location.SceneName == SceneLoaderPatches.SceneName && SaveFile.GetInt($"randomizer picked up {ItemId}") == 0 && (TunicArchipelago.Settings.CollectReflectsInWorld ? SaveFile.GetInt($"randomizer {ItemId} was collected") == 0 : true)).ToList();
+
+ if (ItemLookup.ItemList.Count > 0 || Locations.RandomizedLocations.Count > 0) {
+
+ List ItemIdsInScene = Locations.VanillaLocations.Keys.Where(ItemId => Locations.VanillaLocations[ItemId].Location.SceneName == SceneManager.GetActiveScene().name
+ && SaveFile.GetInt($"randomizer picked up {ItemId}") == 0 &&
+ ((SaveFlags.IsArchipelago() && TunicArchipelago.Settings.CollectReflectsInWorld) ? SaveFile.GetInt($"randomizer {ItemId} was collected") == 0 : true)).ToList();
+
if (ItemIdsInScene.Count > 0) {
foreach (string ItemId in ItemIdsInScene) {
- VanillaLocation Location = Locations.VanillaLocations[ItemId].Location;
+ Location Location = Locations.VanillaLocations[ItemId].Location;
if (GameObject.Find($"fairy target {ItemId}") == null) {
CreateFairyTarget($"fairy target {ItemId}", StringToVector3(Location.Position));
@@ -25,11 +36,16 @@ public static void CreateFairyTargets() {
}
if (GameObject.FindObjectOfType() != null) {
int CoinCount = Inventory.GetItemByName("Trinket Coin").Quantity + TunicArchipelago.Tracker.ImportantItems["Coins Tossed"];
- Dictionary CoinLevels = new Dictionary() { { 0, 3 }, { 1, 6 }, { 2, 10 }, { 3, 15 }, { 4, 20 } };
- int CoinsNeededForNextReward = CoinLevels[Locations.VanillaLocations.Keys.Where(ItemId => Locations.VanillaLocations[ItemId].Location.SceneName == "Trinket Well" && (SaveFile.GetInt($"randomizer picked up {ItemId}") == 1 || (TunicArchipelago.Settings.CollectReflectsInWorld && SaveFile.GetInt($"randomizer {ItemId} was collected") == 1))).ToList().Count];
+ List CoinLevels = new List() { 3, 6, 10, 15, 20 };
+ int CoinsNeededForNextReward = 3;
+ for (int i = 0; i < CoinLevels.Count - 1; i++) {
+ if (SaveFile.GetInt($"randomizer picked up Well Reward ({CoinLevels[i]} Coins) [Trinket Well]") == 1) {
+ CoinsNeededForNextReward = CoinLevels[i + 1];
+ }
+ }
- if ((Inventory.GetItemByName("Trinket Coin").Quantity + TunicArchipelago.Tracker.ImportantItems["Coins Tossed"]) > CoinsNeededForNextReward) {
- CreateFairyTarget($"fairy target Well Reward ({CoinsNeededForNextReward} Coins)", GameObject.FindObjectOfType().transform.position);
+ if ((Inventory.GetItemByName("Trinket Coin").Quantity + TunicArchipelago.Tracker.ImportantItems["Coins Tossed"]) >= CoinsNeededForNextReward) {
+ CreateFairyTarget($"fairy target Well Reward ({CoinsNeededForNextReward} Coins) [Trinket Well]", GameObject.FindObjectOfType().transform.position);
}
}
} else {
@@ -45,17 +61,28 @@ public static void CreateLoadZoneTargets() {
FairyTarget.enabled = false;
}
- foreach (string ItemId in Locations.VanillaLocations.Keys.Where(itemId => Locations.VanillaLocations[itemId].Location.SceneName != SceneLoaderPatches.SceneName && SaveFile.GetInt($"randomizer picked up {itemId}") == 0 && (TunicArchipelago.Settings.CollectReflectsInWorld ? SaveFile.GetInt($"randomizer {itemId} was collected") == 0 : true))) {
+ foreach (string ItemId in Locations.VanillaLocations.Keys.Where(itemId => Locations.VanillaLocations[itemId].Location.SceneName != SceneLoaderPatches.SceneName && (SaveFile.GetInt($"randomizer picked up {itemId}") == 0 &&
+ ((SaveFlags.IsArchipelago() && TunicArchipelago.Settings.CollectReflectsInWorld) ? SaveFile.GetInt($"randomizer {itemId} was collected") == 0 : true)))) {
ScenesWithItems.Add(Locations.VanillaLocations[ItemId].Location.SceneName);
}
foreach (ScenePortal ScenePortal in Resources.FindObjectsOfTypeAll()) {
+ if (ScenePortal.id.Contains("heirfasttravel")) { continue; }
if (ScenesWithItems.Contains(ScenePortal.destinationSceneName)) {
CreateFairyTarget($"fairy target {ScenePortal.destinationSceneName}", ScenePortal.transform.position);
}
}
}
+ public static void CreateEntranceTargets() {
+ foreach (ScenePortal ScenePortal in Resources.FindObjectsOfTypeAll()) {
+ if (ScenePortal.id.Contains("heirfasttravel")) { continue; }
+ if (ScenePortal.isActiveAndEnabled && SaveFile.GetInt("randomizer entered portal " + ScenePortal.name) != 1) {
+ CreateFairyTarget($"entrance target {ScenePortal.destinationSceneName}", ScenePortal.transform.position);
+ }
+ }
+ }
+
private static void CreateFairyTarget(string Name, Vector3 Position) {
GameObject FairyTarget = new GameObject(Name);
FairyTarget.SetActive(true);
@@ -64,6 +91,21 @@ private static void CreateFairyTarget(string Name, Vector3 Position) {
FairyTarget.transform.position = Position;
}
+ public static void FindFairyTargets() {
+ ItemTargets.Clear();
+ EntranceTargets.Clear();
+ foreach (FairyTarget fairyTarget in Resources.FindObjectsOfTypeAll()) {
+ if (fairyTarget.isActiveAndEnabled) {
+ if (fairyTarget.name.StartsWith("entrance")) {
+ EntranceTargets.Add(fairyTarget);
+ } else {
+ ItemTargets.Add(fairyTarget);
+ }
+ }
+ }
+ FairyTarget.registered = ItemTargets;
+ }
+
private static Vector3 StringToVector3(string Position) {
Position = Position.Replace("(", "").Replace(")", "");
string[] coords = Position.Split(',');
@@ -72,4 +114,34 @@ private static Vector3 StringToVector3(string Position) {
}
}
+
+ public class EntranceSeekerSpell : FairySpell {
+ public static List CustomInputs = new List() { };
+
+ public EntranceSeekerSpell(IntPtr ptr) : base(ptr) { }
+
+ private void Awake() {
+ base.inputsToCast = new UnhollowerBaseLib.Il2CppStructArray(1L);
+
+ CustomInputs = new List() { DPAD.RIGHT, DPAD.DOWN, DPAD.RIGHT, DPAD.UP, DPAD.LEFT, DPAD.UP };
+ }
+
+ public override bool CheckInput(Il2CppStructArray inputs, int length) {
+ if (length == CustomInputs.Count) {
+ for (int i = 0; i < length; i++) {
+ if (inputs[i] != CustomInputs[i]) {
+ return false;
+ }
+ }
+ DoSpell();
+ }
+ return false;
+ }
+
+ public void DoSpell() {
+ FairyTarget.registered = FairyTargets.EntranceTargets;
+ PlayerCharacter.instance.GetComponent().SpellEffect();
+ FairyTarget.registered = FairyTargets.ItemTargets;
+ }
+ }
}
diff --git a/src/Patches/GhostHints.cs b/src/Patches/GhostHints.cs
index c4371bf..26ae883 100644
--- a/src/Patches/GhostHints.cs
+++ b/src/Patches/GhostHints.cs
@@ -4,6 +4,7 @@
using UnityEngine;
using BepInEx.Logging;
using static TunicArchipelago.SaveFlags;
+using static TunicArchipelago.GhostHints;
namespace TunicArchipelago {
@@ -28,6 +29,7 @@ public class HintGhost {
public Quaternion Rotation;
public NPC.NPCAnimState AnimState;
public string Dialogue;
+ public string TrunicDialogue;
public string Hint;
public string HintedItem;
public string OptionalCheckID;
@@ -41,6 +43,19 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
Position = position;
Rotation = rotation;
Dialogue = dialogue;
+ TrunicDialogue = dialogue;
+ AnimState = animState;
+ Hint = "";
+ HintedItem = "";
+ OptionalCheckID = "";
+ }
+ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rotation, NPC.NPCAnimState animState, string dialogue, string trunicDialogue) {
+ Name = name;
+ SceneName = sceneName;
+ Position = position;
+ Rotation = rotation;
+ Dialogue = dialogue;
+ TrunicDialogue = trunicDialogue;
AnimState = animState;
Hint = "";
HintedItem = "";
@@ -52,7 +67,7 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
public static GameObject GhostFox;
- public static List Vowels = new List() { 'A', 'E', 'I', 'O', 'U' };
+ public static List Vowels = new List() { 'A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u' };
public static List<(string, string, string)> LocationHints = new List<(string, string, string)>();
public static List<(string, string, string)> ItemHints = new List<(string, string, string)>();
public static List<(string, string, string)> BarrenAndTreasureHints = new List<(string, string, string)>();
@@ -68,7 +83,7 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
{ "Vault Key (Red) [Fortress Arena]", "SIEGE ENGINE" },
{ "Hexagon Green [Library Arena]", "LIBRARIAN" },
{ "Hexagon Blue [ziggurat2020_3]", "SCAVENGER BOSS" },
- { "Hexagon Red [Fortress Arena]", "VAULT KEY" },
+ { "Hexagon Red [Fortress Arena]", "VAULT KEY PLINTH" },
{ "1007 [Waterfall]", "20 FAIRIES" },
{ "Well Reward (10 Coins) [Trinket Well]", "10 COIN TOSSES" },
{ "Well Reward (15 Coins) [Trinket Well]", "15 COIN TOSSES" },
@@ -95,6 +110,24 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
"Dath Stone",
};
+ public static List HintableItemNamesSinglePlayer = new List() {
+ "Stick",
+ "Sword",
+ "Sword Progression",
+ "Shotgun",
+ "Shield",
+ "SlowmoItem",
+ "Mask",
+ "Key (House)",
+ "Relic - Hero Sword",
+ "Relic - Hero Pendant MP",
+ "Relic - Hero Water",
+ "Relic - Hero Pendant HP",
+ "Relic - Hero Crown",
+ "Relic - Hero Pendant SP",
+ "Dath Stone",
+ };
+
public static List BarrenItemNames = new List() {
"Firecracker x2",
"Firecracker x3",
@@ -135,6 +168,19 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
"Money x255",
};
+ public static List BarrenItemNamesSinglePlayer = new List() {
+ "Firecracker",
+ "Ice Bomb",
+ "Firebomb",
+ "Pepper",
+ "Ivy",
+ "Bait",
+ "money",
+ "Piggybank L1",
+ "Berry_MP",
+ "Berry_HP"
+ };
+
public static Dictionary> GhostLocations = new Dictionary>() {
{ "Sword Cave", new List() {
new HintGhost("Hint Ghost Sword Cave", "Sword Cave", new Vector3(5.1151f, 0.0637f, 12.6657f), new Quaternion(0f, 0.9642988f, 0f, 0.2648164f), NPC.NPCAnimState.SIT, $"its dAnjuris too gO uhlOn, tAk #is hint:"), }
@@ -144,10 +190,10 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
new HintGhost("Hint Ghost Far Shore 2", "Transit", new Vector3(-18.6177f, 8.0314f, -81.6153f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, "I stoud awn #aht skwAr ahnd ehndid uhp hEr suhmhow.\nwAr igzahktlE R wE?" ) }
},
{ "Ruined Passage", new List() {
- new HintGhost("Hint Ghost Ruins Passage", "Ruins Passage", new Vector3(184.1698f, 17.3268f, 40.54981f), new Quaternion(0f, 0.9659258f, 0f, 0.2588191f), NPC.NPCAnimState.TIRED, $"nahp tIm! haw haw haw... geht it?") }
+ new HintGhost("Hint Ghost Ruins Passage", "Ruins Passage", new Vector3(184.1698f, 17.3268f, 40.54981f), new Quaternion(0f, 0.9659258f, 0f, 0.2588191f), NPC.NPCAnimState.TIRED, $"nahp tIm! z z z z z z z. . .") }
},
{ "Windmill", new List() {
- new HintGhost("Hint Ghost Windmill", "Windmill", new Vector3(-58.33329f, 54.0833f, -27.8653f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, $"viziti^ #uh \"SHOPKEEPER?\" doo nawt bE uhlRmd, #A R\nA frehnd.") }
+ new HintGhost("Hint Ghost Windmill", "Windmill", new Vector3(-58.33329f, 54.0833f, -27.8653f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, $"viziti^ #uh \"SHOPKEEPER?\" doo nawt bE uhlRmd, #A R\nA frehnd.", $"viziti^ #uh $awpkEpur? doo nawt bE uhlRmd, #A R A frehnd.") }
},
{ "Old House Back", new List() {
new HintGhost("Hint Ghost Overworld Interiors 1", "Overworld Interiors", new Vector3(11.0359f, 29.0833f, -7.3707f), new Quaternion(0f, 0.8660254f, 0f, -0.5000001f), NPC.NPCAnimState.PRAY, $"nuh%i^ wurks! mAbE #Arz suhm trik too #is dor...") }
@@ -157,7 +203,7 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
new HintGhost("Hint Ghost Overworld Interiors 3", "Overworld Interiors", new Vector3(12.0368f, 21.1446f, -72.81052f), new Quaternion(0f, 0.8660254f, 0f, -0.5000001f), NPC.NPCAnimState.SIT, $"wuht R #Ez pehduhstuhlz for? doo yoo nO?") }
},
{ "Overworld Above Ruins", new List() {
- new HintGhost("Hint Ghost Overworld Above Ruins 1", "Overworld Redux", new Vector3(28.53184f, 36.0833f, -108.3734f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.IDLE, $"I wuhz hIdi^ fruhm #uh \"SLIMES,\" buht yoo dOnt louk\nlIk wuhn uhv #ehm."),
+ new HintGhost("Hint Ghost Overworld Above Ruins 1", "Overworld Redux", new Vector3(28.53184f, 36.0833f, -108.3734f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.IDLE, $"I wuhz hIdi^ fruhm #uh \"SLIMES,\" buht yoo dOnt louk\nlIk wuhn uhv #ehm.", $"I wuhz hIdi^ fruhm #uh slImz, buht yoo dOnt louk\nlIk wuhn uhv #ehm."),
new HintGhost("Hint Ghost Overworld Above Ruins 2", "Overworld Redux", new Vector3(22.3667f, 27.9833f, -126.3728f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, $"wAr did I lEv #aht kE..."),
new HintGhost("Hint Ghost Overworld Above Ruins 3", "Overworld Redux", new Vector3(51.20462f, 28.00694f, -129.722f), new Quaternion(0f, 1f, 0f, -4.371139E-08f), NPC.NPCAnimState.SIT, $"I %awt #aht Jehst wuhz ehmptE. how suhspi$is.") }
},
@@ -166,15 +212,15 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
new HintGhost("Hint Ghost Early Overworld Spawns 2", "Overworld Redux", new Vector3(-34.0649f, 37.9833f, -59.2506f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.GAZE, $"sO mehnE roodli^z. Im stAi^ uhp hEr.") }
},
{ "Inside Temple", new List() {
- new HintGhost("Hint Ghost Inside Temple 1", "Temple", new Vector3(7.067f, -0.224f, 59.9285f), new Quaternion(0f, 1f, 0f, -4.371139E-08f), NPC.NPCAnimState.IDLE, $"yur naht uh \"RUIN SEEKER,\" R yoo? mAbE yoo $oud gO\nsuhmwAr ehls."),
- new HintGhost("Hint Ghost Inside Temple 2", "Temple", new Vector3(0.9350182f, 4.076f, 133.7965f), new Quaternion(0f, 0.8660254f, 0f, 0.5f), NPC.NPCAnimState.GAZE_UP, $"yur guhnuh frE \"THE HEIR?\" iznt #aht... bahd?") }
+ new HintGhost("Hint Ghost Inside Temple 1", "Temple", new Vector3(7.067f, -0.224f, 59.9285f), new Quaternion(0f, 1f, 0f, -4.371139E-08f), NPC.NPCAnimState.IDLE, $"yur naht uh \"RUIN SEEKER,\" R yoo? mAbE yoo $oud gO\nsuhmwAr ehls.", $"yur naht uh rooin sEkur, R yoo? mAbE yoo $oud gO suhmwAr ehls."),
+ new HintGhost("Hint Ghost Inside Temple 2", "Temple", new Vector3(0.9350182f, 4.076f, 133.7965f), new Quaternion(0f, 0.8660254f, 0f, 0.5f), NPC.NPCAnimState.GAZE_UP, $"yur guhnuh frE \"THE HEIR?\" iznt #aht... bahd?", $"yur guhnuh frE #uh Ar? iznt #aht... bahd?") }
},
{ "Ruined Shop", new List() {
new HintGhost("Hint Ghost Ruined Shop 1", "Ruined Shop", new Vector3(16.5333f, 8.983299f, -45.60382f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, $"hehlO. wuht iz yor nAm?---...tuhnk? wuht A strAnj nAm."),
new HintGhost("Hint Ghost Ruined Shop 2", "Ruined Shop", new Vector3(9.8111f, 8.0833f, -37.52119f), new Quaternion(0f, 0.9659258f, 0f, 0.2588191f), NPC.NPCAnimState.IDLE, $"wehl, if yur nawt bIi^ ehnE%i^..." ) }
},
{ "West Filigree", new List() {
- new HintGhost("Hint Ghost West Filigree", "Town_FiligreeRoom", new Vector3(-79.4348f, 22.0379f, -59.8104f), new Quaternion(0f, 1f, 0f, -4.371139E-08f), NPC.NPCAnimState.PRAY, $"wow, yoo hahv #uh powur uhv #uh \"Holy Cross!\"") }
+ new HintGhost("Hint Ghost West Filigree", "Town_FiligreeRoom", new Vector3(-79.4348f, 22.0379f, -59.8104f), new Quaternion(0f, 1f, 0f, -4.371139E-08f), NPC.NPCAnimState.PRAY, $"wow, yoo hahv #uh powur uhv #uh \"Holy Cross!\"", $"wow, yoo hahv #uh powur uhv #uh hOlE kraws!") }
},
{ "East Filigree", new List() {
new HintGhost("Hint Ghost East Filigree", "EastFiligreeCache", new Vector3(14.3719f, 0.0167f, -8.8614f), new Quaternion(0f, 0.7071068f, 0f, -0.7071068f), NPC.NPCAnimState.SIT, $"wAt, how did yoo Opehn #aht dOr?") }
@@ -206,7 +252,7 @@ public HintGhost(string name, string sceneName, Vector3 position, Quaternion rot
new HintGhost("Hint Ghost Furnace", "Furnace", new Vector3(-131.9886f, 12.0833f, -51.0197f), new Quaternion(0f, 0f, 0f, 1f), NPC.NPCAnimState.GAZE_UP, $"#Ez powur sorsehz... I dOnt truhst #ehm.") }
},
{ "Golden Obelisk", new List() {
- new HintGhost("Hint Ghost Golden Obelisk", "Overworld Redux", new Vector3(-94.5973f, 70.0937f, 36.38749f), new Quaternion(0f, 0f, 0f, 1f), NPC.NPCAnimState.FISHING, $"pEpuhl yoost too wur$ip #is. it rehprEzehnts #uh\n\"Holy Cross.\"") }
+ new HintGhost("Hint Ghost Golden Obelisk", "Overworld Redux", new Vector3(-94.5973f, 70.0937f, 36.38749f), new Quaternion(0f, 0f, 0f, 1f), NPC.NPCAnimState.FISHING, $"pEpuhl yoost too wur$ip #is. it rehprEzehnts #uh\n\"Holy Cross.\"", $"pEpuhl yoost too wur$ip #is. it rehprEzehnts #uh\nhOlE kraws.") }
},
{ "Overworld Before Garden", new List(){
new HintGhost("Hint Ghost Overworld Before Garden", "Overworld Redux", new Vector3(-146.1464f, 11.6929f, -67.55009f), new Quaternion(0f, 0.3007058f, 0f, 0.9537169f), NPC.NPCAnimState.IDLE, "A vi$is baws blawks #uh wA too #uh behl uhp #Ar.\nbE kArfuhl, it wil kil yoo.") }
@@ -282,7 +328,7 @@ public static void SpawnHintGhosts(string SceneName) {
NewGhostFox.transform.position = HintGhost.Position;
NewGhostFox.transform.rotation = HintGhost.Rotation;
LanguageLine HintText = ScriptableObject.CreateInstance();
- HintText.text = $"{HintGhost.Dialogue}---{HintGhost.Hint}";
+ HintText.text = $"{(TunicArchipelago.Settings.UseTrunicTranslations ? HintGhost.TrunicDialogue : HintGhost.Dialogue)}---{HintGhost.Hint}";
NewGhostFox.GetComponent().script = HintText;
if (PaletteEditor.CelShadingEnabled && PaletteEditor.ToonFox != null) {
@@ -383,16 +429,35 @@ public static void GenerateLocationHints() {
HintableLocations.Remove("final [Mountaintop]");
}
foreach (string Key in HintableLocations) {
- ArchipelagoItem Item = ItemLookup.ItemList[Key];
string Location = HintableLocationIds[Key];
string LocationSuffix = Location[Location.Length - 1] == 'S' ? "R" : "iz";
- string ItemPrefix = Item.ItemName.Contains("Money") ? "suhm" : Vowels.Contains(Item.ItemName.ToUpper()[0]) ? "ahn" : "uh";
- string PlayerName = Archipelago.instance.GetPlayerName(Item.Player);
- string ItemToDisplay = Archipelago.instance.IsTunicPlayer(Item.Player) && TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(Item.ItemName)
- ? TextBuilderPatches.ItemNameToAbbreviation[Item.ItemName] : "[archipelago]";
- string Hint = $"bI #uh wA, I hurd #aht \"{HintableLocationIds[Key].Replace(" ", "\" \"")}\" {LocationSuffix} gRdi^ {ItemToDisplay} \"{PlayerName.ToUpper().Replace(" ", "\" \"")}'S {Item.ItemName.ToUpper().Replace(" ", "\" \"").Replace("_", "\" \"")}.\"";
- string ItemForHint = Archipelago.instance.IsTunicPlayer(Item.Player) ? Item.ItemName : "Archipelago Item";
- LocationHints.Add((WordWrapString(Hint), ItemForHint, Locations.LocationIdToDescription[Key]));
+
+ if (SaveFlags.IsArchipelago()) {
+ ArchipelagoItem Item = ItemLookup.ItemList[Key];
+ string ItemPrefix = Item.ItemName.Contains("Money") ? "suhm" : Vowels.Contains(Item.ItemName.ToUpper()[0]) ? "ahn" : "uh";
+ string PlayerName = Archipelago.instance.GetPlayerName(Item.Player);
+ bool IsTunicItem = Archipelago.instance.IsTunicPlayer(Item.Player);
+ string ItemToDisplay = IsTunicItem && TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(Item.ItemName)
+ ? TextBuilderPatches.ItemNameToAbbreviation[Item.ItemName] : "[archipelago]";
+ string Hint = $"bI #uh wA, I hurd #aht \"{HintableLocationIds[Key].Replace(" ", "\" \"")}\" {LocationSuffix} gRdi^ {ItemToDisplay} \"{PlayerName.ToUpper().Replace(" ", "\" \"")}'S {Item.ItemName.ToUpper().Replace(" ", "\" \"").Replace("_", "\" \"")}.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"bI #uh wA, I hurd #aht {Translations.Translate(HintableLocationIds[Key], false)} {LocationSuffix} gRdi^ \"{PlayerName.ToUpper().Replace(" ", "\" \"")}'S\" {(IsTunicItem ? Translations.Translate(ItemLookup.SimplifiedItemNames[ItemLookup.Items[Item.ItemName].ItemNameForInventory], false) + "." : $"\"{Item.ItemName.ToUpper().Replace(" ", "\" \"").Replace("_", "\" \"")}.\"")}";
+ }
+ string ItemForHint = Archipelago.instance.IsTunicPlayer(Item.Player) ? Item.ItemName : "Archipelago Item";
+ LocationHints.Add((WordWrapString(Hint), ItemForHint, Locations.LocationIdToDescription[Key]));
+ } else if (IsSinglePlayer()) {
+ Check Check = Locations.RandomizedLocations[Key];
+ string ItemName = ItemLookup.GetItemDataFromCheck(Check).Name;
+ string ItemPrefix = ItemName == "Money" ? "suhm" : Vowels.Contains(ItemName.ToUpper()[0]) ? "ahn" : "uh";
+ string ItemToDisplay = TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(ItemName)
+ ? TextBuilderPatches.ItemNameToAbbreviation[ItemName] : "";
+ string Hint = $"bI #uh wA, I hurd #aht \"{HintableLocationIds[Key].Replace(" ", "\" \"")}\" {LocationSuffix} gRdi^ {ItemPrefix} {ItemToDisplay} \"{ItemName.ToUpper().Replace(" ", "\" \"").Replace("_", "\" \"")}.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"bI #uh wA, I hurd #aht {Translations.Translate(HintableLocationIds[Key], false)} {LocationSuffix} gRdi^ {ItemPrefix} {Translations.Translate(ItemLookup.SimplifiedItemNames[Check.Reward.Name], false)}.";
+ }
+
+ LocationHints.Add((WordWrapString(Hint), ItemName, Locations.LocationIdToDescription[Key]));
+ }
}
}
@@ -402,34 +467,59 @@ public static void GenerateItemHints() {
string Hint = "";
List HintableItems = new List(HintableItemNames);
+ List HintableItemsSolo = new List(HintableItemNamesSinglePlayer);
if (SaveFile.GetInt(AbilityShuffle) == 1) {
- HintableItems.Add("Pages 52-53 (Ice Rod)");
+ HintableItems.Add("Pages 52-53 (Icebolt)");
+ HintableItemsSolo.Add("26");
}
for (int i = 0; i < HintableItems.Count; i++) {
string Item = HintableItems[i];
-
- List ItemLocations = Locations.MajorItemLocations[Item];
- foreach(ArchipelagoHint HintLocation in ItemLocations) {
- if (HintLocation.Player == Archipelago.instance.GetPlayerSlot()) {
- string Scene = HintLocation.Location == "Your Pocket" ? HintLocation.Location.ToUpper() : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HintLocation.Location]].Location.SceneName].ToUpper();
- string ScenePrefix = Scene == "Trinket Well" ? "%rOi^" : "aht #uh";
- string ItemToDisplay = TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(HintLocation.Item) ? TextBuilderPatches.ItemNameToAbbreviation[HintLocation.Item] : "";
- Hint = $"bI #uh wA, I saw A {ItemToDisplay} \"{Item.ToUpper().Replace(" ", "\" \"")}\" #uh lahst tIm I wuhs {ScenePrefix} \"{Scene.Replace(" ", "\" \"")}.\"";
-
- ItemHints.Add((WordWrapString(Hint), HintLocation.Item, ""));
+ if (SaveFlags.IsArchipelago()) {
+ List ItemLocations = Locations.MajorItemLocations[Item];
+ foreach(ArchipelagoHint HintLocation in ItemLocations) {
+ if (HintLocation.Player == Archipelago.instance.GetPlayerSlot()) {
+ string Scene = HintLocation.Location == "Your Pocket" ? HintLocation.Location : Locations.SimplifiedSceneNames[Locations.VanillaLocations[Locations.LocationDescriptionToId[HintLocation.Location]].Location.SceneName];
+ string ScenePrefix = Scene == "Trinket Well" ? "%rOi^" : "aht #uh";
+ string ItemToDisplay = TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(HintLocation.Item) ? TextBuilderPatches.ItemNameToAbbreviation[HintLocation.Item] : "";
+ Hint = $"bI #uh wA, I saw A {ItemToDisplay} \"{Item.ToUpper().Replace(" ", "\" \"")}\" #uh lahst tIm I wuhs {ScenePrefix} \"{Scene.ToUpper().Replace(" ", "\" \"")}.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"bI #uh wA, I saw A {Translations.Translate(Item, false)} #uh lahst tIm I wuhs {ScenePrefix} {Translations.Translate(Scene, false)}.";
+ }
+ ItemHints.Add((WordWrapString(Hint), HintLocation.Item, ""));
+ }
+ }
+ } else if (SaveFlags.IsSinglePlayer()) {
+ List Items = ItemRandomizer.FindAllRandomizedItemsByName(HintableItemsSolo[i]);
+ foreach (Check Check in Items) {
+ string ScenePrefix = Check.Location.SceneName == "Trinket Well" ? "%rOi^" : "aht #uh";
+ string Scene = Locations.SimplifiedSceneNames[Check.Location.SceneName];
+ string TrunicHint = $"";
+ ItemData ItemData = ItemLookup.GetItemDataFromCheck(Check);
+ string ItemToDisplay = TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(ItemData.Name) ? TextBuilderPatches.ItemNameToAbbreviation[ItemData.Name] : "";
+
+ Hint = $"bI #uh wA, I saw A {ItemToDisplay} \"{Item.ToUpper().Replace(" ", "\" \"")}\" #uh lahst tIm I wuhs {ScenePrefix} \"{Scene.ToUpper().Replace(" ", "\" \"")}.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"bI #uh wA, I saw A {Translations.Translate(ItemLookup.SimplifiedItemNames[Check.Reward.Name], false)} #uh lahst tIm I wuhs {ScenePrefix} {Translations.Translate(Scene, false)}.";
+ }
+ ItemHints.Add((WordWrapString(Hint), ItemData.Name, ""));
}
}
}
if (SaveFile.GetInt(HexagonQuestEnabled) == 1 && SaveFile.GetInt(AbilityShuffle) == 1) {
string prayerHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestPrayer)} GOLD QUESTAGONS\"\nwil grahnt yoo #uh powur uhv \"PRAYER.\"";
string holyCrossHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestHolyCross)} GOLD QUESTAGONS\"\nwil grahnt yoo #uh powur uhv #uh \"HOLY CROSS.\"";
- string iceRodHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestIceRod)} GOLD QUESTAGONS\"\nwil grahnt yoo #uh #uh powur uhv #uh \"ICE ROD.\"";
+ string iceboltHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestIcebolt)} GOLD QUESTAGONS\"\nwil grahnt yoo #uh #uh powur uhv #uh \"ICEBOLT.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ prayerHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestPrayer)}\" gOld kwehstuhgawn\nwil grahnt yoo #uh powur uhv prAr.";
+ holyCrossHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestHolyCross)}\" gOld kwehstuhgawn\nwil grahnt yoo #uh powur uhv #uh hOlE kraws.";
+ iceboltHint = $"bI #uh wA, I hurd #aht [goldhex] \"{SaveFile.GetInt(HexagonQuestIcebolt)}\" gOld kwehstuhgawn\nwil grahnt yoo #uh #uh powur uhv #uh IsbOlt.";
+ }
ItemHints.Add((prayerHint, "", ""));
ItemHints.Add((holyCrossHint, "", ""));
- ItemHints.Add((iceRodHint, "", ""));
+ ItemHints.Add((iceboltHint, "", ""));
HexQuestHintLookup.Add(prayerHint, "Prayer");
HexQuestHintLookup.Add(holyCrossHint, "Holy Cross");
- HexQuestHintLookup.Add(iceRodHint, "Ice Rod");
+ HexQuestHintLookup.Add(iceboltHint, "Icebolt");
}
}
@@ -466,14 +556,24 @@ public static void GenerateBarrenAndMoneySceneHints() {
string Scene = Locations.SimplifiedSceneNames[Key];
int SceneItemCount = 0;
int MoneyInScene = 0;
- foreach (string ItemKey in ItemLookup.ItemList.Keys.Where(item => Locations.VanillaLocations[item].Location.SceneName == Key).ToList()) {
- ArchipelagoItem Item = ItemLookup.ItemList[ItemKey];
- ItemsInScene.Add(Item.ItemName);
- APItemsInScene.Add(Item);
- if (Item.Player == Archipelago.instance.GetPlayerSlot() && ItemLookup.Items[Item.ItemName].Type == ItemTypes.MONEY) {
- MoneyInScene += ItemLookup.Items[Item.ItemName].QuantityToGive;
+ if (SaveFlags.IsArchipelago()) {
+ foreach (string ItemKey in ItemLookup.ItemList.Keys.Where(item => Locations.VanillaLocations[item].Location.SceneName == Key).ToList()) {
+ ArchipelagoItem Item = ItemLookup.ItemList[ItemKey];
+ ItemsInScene.Add(Item.ItemName);
+ APItemsInScene.Add(Item);
+ if (Item.Player == Archipelago.instance.GetPlayerSlot() && ItemLookup.Items[Item.ItemName].Type == ItemTypes.MONEY) {
+ MoneyInScene += ItemLookup.Items[Item.ItemName].QuantityToGive;
+ }
+ SceneItemCount++;
+ }
+ } else if (SaveFlags.IsSinglePlayer()) {
+ foreach (Check Item in Locations.RandomizedLocations.Values.Where(item => item.Location.SceneName == Key).ToList()) {
+ ItemsInScene.Add(Item.Reward.Name);
+ if (Item.Reward.Name == "money") {
+ MoneyInScene += Item.Reward.Amount;
+ }
+ SceneItemCount++;
}
- SceneItemCount++;
}
if (SceneItemCount == 0) {
@@ -482,7 +582,11 @@ public static void GenerateBarrenAndMoneySceneHints() {
if (MoneyInScene >= 200 && SceneItemCount < 10) {
string ScenePrefix = Vowels.Contains(Scene[0]) ? "#E" : "#uh";
- BarrenAndTreasureHints.Add(($"ahn EzE plAs too fInd A [realmoney] \"LOT OF MONEY\" iz {ScenePrefix}\n\"{Scene.ToUpper()}.\"", "", ""));
+ string Hint = $"ahn EzE plAs too fInd A [realmoney] \"LOT OF MONEY\" iz {ScenePrefix}\n\"{Scene.ToUpper()}.\"";
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"ahn EzE plAs too fInd A lawt uhv muhnE iz\n{ScenePrefix} {Translations.Translate(Scene, false)}.";
+ }
+ BarrenAndTreasureHints.Add((Hint, "", ""));
} else {
bool BarrenArea = true;
foreach(ArchipelagoItem Item in APItemsInScene) {
@@ -494,11 +598,17 @@ public static void GenerateBarrenAndMoneySceneHints() {
BarrenArea = false;
break;
}
- if (HintGhosts.Where(HintGhost => HintGhost.Value.SceneName == Key).ToList().Count > 0) {
+ }
+ foreach (string Item in ItemsInScene) {
+ if (!BarrenItemNamesSinglePlayer.Contains(Item)) {
BarrenArea = false;
break;
}
}
+ if (HintGhosts.Where(HintGhost => HintGhost.Value.SceneName == Key).ToList().Count > 0) {
+ BarrenArea = false;
+ break;
+ }
if(BarrenArea) {
string Hint = "";
if (Scene.Length > 15) {
@@ -507,6 +617,9 @@ public static void GenerateBarrenAndMoneySceneHints() {
} else {
Hint = $"if I wur yoo, I woud uhvoid \"{Scene.ToUpper()}.\"\n#aht plAs iz \"NOT IMPORTANT.\"";
}
+ if (TunicArchipelago.Settings.UseTrunicTranslations) {
+ Hint = $"if I wur yoo, I woud uhvoid {Translations.Translate(Scene, false)}.\n#aht plAs iz nawt importahnt.";
+ }
BarrenAndTreasureHints.Add((Hint, "", ""));
}
}
diff --git a/src/Patches/InteractionPatches.cs b/src/Patches/InteractionPatches.cs
index 8714aa8..c8dca8f 100644
--- a/src/Patches/InteractionPatches.cs
+++ b/src/Patches/InteractionPatches.cs
@@ -21,12 +21,17 @@ public static bool InteractionTrigger_Interact_PrefixPatch(Item item, Interactio
}
}
+ if (GhostHints.HintGhosts.ContainsKey(__instance.name)) {
+ GhostHints.HintGhost hintGhost = GhostHints.HintGhosts[__instance.name];
+ __instance.GetComponent().script.text = $"{(TunicArchipelago.Settings.UseTrunicTranslations ? hintGhost.TrunicDialogue : hintGhost.Dialogue)}---{hintGhost.Hint}";
+ }
+
if (GhostHints.HintGhosts.ContainsKey(__instance.name) && GhostHints.HexQuestHintLookup.ContainsKey(GhostHints.HintGhosts[__instance.name].Hint)) {
SaveFile.SetInt($"randomizer hex quest read {GhostHints.HexQuestHintLookup[GhostHints.HintGhosts[__instance.name].Hint]} hint", 1);
ItemStatsHUD.UpdateAbilitySection();
}
- if (TunicArchipelago.Settings.SendHintsToServer) {
+ if (IsArchipelago() && TunicArchipelago.Settings.SendHintsToServer) {
GhostHints.CheckForServerHint(__instance.name);
}
}
@@ -93,6 +98,10 @@ private static void ChangeDayNightHourglass() {
if (isNight) {
CycleController.AnimateSunrise();
} else {
+ SaveFile.SetString("last campfire scene name", "Overworld Interiors");
+ SaveFile.SetString("last campfire id", "bed");
+ SaveFile.SetString("randomizer last campfire scene name for dath stone", "Overworld Interiors");
+ SaveFile.SetString("randomizer last campfire id for dath stone", "bed");
CycleController.AnimateSunset();
}
CycleController.IsNight = !isNight;
diff --git a/src/Patches/ItemPatches.cs b/src/Patches/ItemPatches.cs
index bfeb1d5..1912308 100644
--- a/src/Patches/ItemPatches.cs
+++ b/src/Patches/ItemPatches.cs
@@ -44,7 +44,11 @@ public static void Chest_openSequence_MoveNext_PostfixPatch(Chest._openSequence_
SaveFile.SetInt($"randomizer opened fairy chest {FairyId}", 1);
}
Logger.LogInfo("Checking Location: " + LocationId + " - " + Locations.LocationIdToDescription[LocationId]);
- Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ if (IsArchipelago()) {
+ Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
+ }
}
}
@@ -53,9 +57,7 @@ public static bool Chest_InterruptOpening_PrefixPatch(Chest __instance) {
if (TunicArchipelago.Settings.DisableChestInterruption) {
return false;
}
-/* if (__instance.chestID == 0 || __instance.chestID == 5) {
- return false;
- }*/
+
return true;
}
@@ -104,7 +106,11 @@ public static bool ItemPickup_onGetIt_PrefixPatch(ItemPickup __instance) {
}
string LocationId = $"{__instance.itemToGive.name} [{SceneLoaderPatches.SceneName}]";
- Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ if (IsArchipelago()) {
+ Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
+ }
__instance.pickupStateVar.BoolValue = true;
return false;
@@ -112,7 +118,11 @@ public static bool ItemPickup_onGetIt_PrefixPatch(ItemPickup __instance) {
public static bool HeroRelicPickup_onGetIt_PrefixPatch(HeroRelicPickup __instance) {
string LocationId = $"{__instance.name} [{SceneLoaderPatches.SceneName}]";
- Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ if (IsArchipelago()) {
+ Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
+ }
__instance.pickupStateVar.BoolValue = true;
__instance.destroyOrDisable();
@@ -121,7 +131,11 @@ public static bool HeroRelicPickup_onGetIt_PrefixPatch(HeroRelicPickup __instanc
public static bool PagePickup_onGetIt_PrefixPatch(PagePickup __instance) {
string LocationId = $"{__instance.pageName} [{SceneLoaderPatches.SceneName}]";
- Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ if (IsArchipelago()) {
+ Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
+ }
SaveFile.SetInt($"unlocked page {PagePickup.LeafNameToLeafNumber(__instance.pageName)}", 1);
SaveFile.SetInt($"randomizer picked up page {PagePickup.LeafNameToLeafNumber(__instance.pageName)}", 1);
@@ -132,12 +146,22 @@ public static bool ShopItem_IInteractionReceiver_Interact_PrefixPatch(Item i, Sh
string LocationId = $"{__instance.name} [Shop]";
if (Locations.LocationIdToDescription.ContainsKey(LocationId)) {
int Price = TunicArchipelago.Settings.CheaperShopItemsEnabled ? 300 : __instance.price;
- ArchipelagoItem ShopItem = ItemLookup.ItemList[LocationId];
- string itemToDisplay = Archipelago.instance.IsTunicPlayer(ShopItem.Player) && TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(ShopItem.ItemName) ? TextBuilderPatches.ItemNameToAbbreviation[ShopItem.ItemName] : "[archipelago]";
- __instance.confirmPurchaseFormattedLanguageLine.text = $"bI for {Price} [money]?\n {itemToDisplay} " + GhostHints.WordWrapString($"\"{Archipelago.instance.GetPlayerName(ShopItem.Player).ToUpper().Replace(" ", "\" \"")}'S\" \"{ShopItem.ItemName.ToUpper().Replace($" ", $"\" \"")}\"");
+ string itemToDisplay = "";
+ if (IsArchipelago()) {
+ ArchipelagoItem ShopItem = ItemLookup.ItemList[LocationId];
+ itemToDisplay = Archipelago.instance.IsTunicPlayer(ShopItem.Player) && TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(ShopItem.ItemName) ? TextBuilderPatches.ItemNameToAbbreviation[ShopItem.ItemName] : "[archipelago]";
+ __instance.confirmPurchaseFormattedLanguageLine.text = $"bI for {Price} [money]?\n {itemToDisplay} " + GhostHints.WordWrapString($"\"{Archipelago.instance.GetPlayerName(ShopItem.Player).ToUpper().Replace(" ", "\" \"")}'S\" \"{ShopItem.ItemName.ToUpper().Replace($" ", $"\" \"")}\"");
+ } else if (IsSinglePlayer()) {
+ ItemData itemData = ItemLookup.GetItemDataFromCheck(Locations.RandomizedLocations[LocationId]);
+ itemToDisplay = TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(itemData.Name) ? TextBuilderPatches.ItemNameToAbbreviation[itemData.Name] : "";
+ __instance.confirmPurchaseFormattedLanguageLine.text = $"bI for {Price} [money]?";
+ if (TunicArchipelago.Settings.ShowItemsEnabled) {
+ __instance.confirmPurchaseFormattedLanguageLine.text += $"\n{itemToDisplay} \"{itemData.Name}\"";
+ }
+ }
string CheckName = Locations.LocationIdToDescription[LocationId];
- if (TunicArchipelago.Settings.SendHintsToServer && SaveFile.GetInt($"archipelago sent optional hint to server {CheckName}") == 0) {
+ if (IsArchipelago() && TunicArchipelago.Settings.SendHintsToServer && SaveFile.GetInt($"archipelago sent optional hint to server {CheckName}") == 0) {
Archipelago.instance.integration.session.Locations.ScoutLocationsAsync(true, Archipelago.instance.GetLocationId(CheckName));
SaveFile.SetInt($"archipelago sent optional hint to server {CheckName}", 1);
}
@@ -163,8 +187,11 @@ public static bool ShopItem_buy_PrefixPatch(ShopItem __instance) {
GenericMessage.ShowMessage($"nawt Enuhf [money]...");
} else {
Inventory.GetItemByName("MoneySmall").Quantity -= Price;
-
- Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ if (IsArchipelago()) {
+ Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
+ }
__instance.boughtStatevar.BoolValue = true;
}
@@ -179,8 +206,10 @@ public static void TrinketWell_TossedInCoin_PostfixPatch(TrinketWell __instance)
public static bool TrinketWell_giveTrinketUpgrade_PrefixPatch(TrinketWell._giveTrinketUpgrade_d__14 __instance) {
string LocationId = $"Well Reward ({StateVariable.GetStateVariableByName("Trinket Coins Tossed").IntValue} Coins) [Trinket Well]";
- if (Locations.LocationIdToDescription.ContainsKey(LocationId)) {
+ if (IsArchipelago() && Locations.LocationIdToDescription.ContainsKey(LocationId)) {
Archipelago.instance.ActivateCheck(Locations.LocationIdToDescription[LocationId]);
+ } else if (IsSinglePlayer()) {
+ GiveItem(Locations.RandomizedLocations[LocationId]);
}
return false;
}
@@ -256,7 +285,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
}
}
GameObject.Instantiate(ModelSwaps.FairyAnimation, PlayerCharacter.instance.transform.position, Quaternion.identity).SetActive(true);
- NotificationBottom = $"\"{TunicArchipelago.Tracker.ImportantItems["Fairies"] + 1}/20\" fArEz fownd.";
+ NotificationBottom = $"\"{(TunicArchipelago.Tracker.ImportantItems["Fairies"] + 1)}/20\" fArEz fownd.";
}
if (Item.Type == ItemTypes.PAGE) {
@@ -275,7 +304,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
Dictionary pagesForAbilities = new Dictionary() {
{ "12", (PrayerUnlocked, PrayerUnlockedTime, ItemLookup.PrayerUnlockedLine) },
{ "21", (HolyCrossUnlocked, HolyCrossUnlockedTime, ItemLookup.HolyCrossUnlockedLine) },
- { "26", (IceRodUnlocked, IceRodUnlockedTime, ItemLookup.IceRodUnlockedLine) },
+ { "26", (IceBoltUnlocked, IceboltUnlockedTime, ItemLookup.IceboltUnlockedLine) },
};
if (pagesForAbilities.ContainsKey(Item.ItemNameForInventory)) {
SaveFile.SetInt(pagesForAbilities[Item.ItemNameForInventory].Item1, 1);
@@ -302,7 +331,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
// Apply bonus upgrade text
if (TunicArchipelago.Settings.BonusStatUpgradesEnabled) {
GoldenTrophy.collectionMessage = ScriptableObject.CreateInstance();
- GoldenTrophy.collectionMessage.text = ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage;
+ GoldenTrophy.collectionMessage.text = Translations.TranslateDefaultNoQuotes(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true);
Inventory.GetItemByName(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].LevelUp).Quantity += 1;
} else {
GoldenTrophy.collectionMessage = ScriptableObject.CreateInstance();
@@ -310,6 +339,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
}
ItemPresentation.PresentItem(GoldenTrophy);
+ NotificationBottom = TunicArchipelago.Settings.BonusStatUpgradesEnabled ? Translations.TranslateDefaultNoQuotes(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true) : $"kawngrahJoulA$uhnz!";
}
if (Item.Type == ItemTypes.RELIC) {
@@ -322,7 +352,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
// Apply custom pickup text
RelicItem.collectionMessage = new LanguageLine();
- RelicItem.collectionMessage.text = ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage;
+ RelicItem.collectionMessage.text = Translations.Translate(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true);
ItemPresentation.PresentItem(RelicItem);
}
@@ -340,7 +370,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
Dictionary hexesForAbilities = new Dictionary() {
{ SaveFile.GetInt(HexagonQuestPrayer), (PrayerUnlocked, PrayerUnlockedTime, ItemLookup.PrayerUnlockedLine) },
{ SaveFile.GetInt(HexagonQuestHolyCross), (HolyCrossUnlocked, HolyCrossUnlockedTime, ItemLookup.HolyCrossUnlockedLine) },
- { SaveFile.GetInt(HexagonQuestIceRod), (IceRodUnlocked, IceRodUnlockedTime, ItemLookup.IceRodUnlockedLine) },
+ { SaveFile.GetInt(HexagonQuestIcebolt), (IceBoltUnlocked, IceboltUnlockedTime, ItemLookup.IceboltUnlockedLine) },
};
if (hexesForAbilities.ContainsKey(GoldHexes)) {
SaveFile.SetInt(hexesForAbilities[GoldHexes].Item1, 1);
@@ -365,7 +395,7 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
if (Item.Type == ItemTypes.PAGE) {
SaveFile.SetFloat($"randomizer {Item.Name} 1 time", SpeedrunData.inGameTime);
} else {
- SaveFile.SetFloat($"randomizer {Item.Name} {TunicArchipelago.Tracker.ImportantItems[Item.ItemNameForInventory] + 1} time", SpeedrunData.inGameTime);
+ SaveFile.SetFloat($"randomizer {Item.Name} {(TunicArchipelago.Tracker.ImportantItems[Item.ItemNameForInventory] + 1)} time", SpeedrunData.inGameTime);
}
}
@@ -396,6 +426,213 @@ public static ItemResult GiveItem(string ItemName, NetworkItem networkItem) {
return ItemResult.Success;
}
+ public static void GiveItem(Check Check) {
+
+ string NotificationTop = "";
+ string NotificationBottom = "";
+ bool DisplayMessageAnyway = false;
+
+ ItemData Item = ItemLookup.GetItemDataFromCheck(Check);
+
+ if (Item.Type == ItemTypes.MONEY) {
+ int AmountToGive = Check.Reward.Amount;
+
+ Dictionary OriginalShopPrices = new Dictionary() {
+ { "Potion (First)", 300 },
+ { "Potion (West Garden)", 1000 },
+ { "Trinket Coin 1 (day)", 999 },
+ { "Trinket Coin 2 (night)", 999 }
+ };
+ if (OriginalShopPrices.ContainsKey(Check.Location.LocationId)) {
+ AmountToGive += TunicArchipelago.Settings.CheaperShopItemsEnabled ? 300 : OriginalShopPrices[Check.Location.LocationId];
+ }
+
+ CoinSpawner.SpawnCoins(AmountToGive, PlayerCharacter.instance.transform.position);
+ }
+
+ if (Item.Type == ItemTypes.INVENTORY || Item.Type == ItemTypes.TRINKET) {
+ Item InventoryItem = Inventory.GetItemByName(Item.ItemNameForInventory);
+ InventoryItem.Quantity += Check.Reward.Amount;
+ if (Item.Name == "Stick" || Item.Name == "Sword") {
+ InventoryItem.collectionMessage = ScriptableObject.CreateInstance();
+ InventoryItem.collectionMessage.text = $"fownd ahn Itehm!";
+ }
+ if (Item.Name == "Dath Stone") {
+ Inventory.GetItemByName("Torch").Quantity = 1;
+ }
+ ItemPresentation.PresentItem(InventoryItem, Check.Reward.Amount);
+ if (TunicArchipelago.Settings.SkipItemAnimations && Item.Name == "Flask Shard" && Inventory.GetItemByName("Flask Shard").Quantity >= 3) {
+ Inventory.GetItemByName("Flask Shard").Quantity -= 3;
+ Inventory.GetItemByName("Flask Container").Quantity += 1;
+ }
+ }
+
+ if (Item.Type == ItemTypes.SWORDUPGRADE) {
+
+ if (SaveFile.GetInt(SwordProgressionEnabled) == 1 && Item.Name == "Sword Upgrade") {
+ int SwordLevel = SaveFile.GetInt(SwordProgressionLevel);
+ SwordProgression.UpgradeSword(SwordLevel + 1);
+ }
+ if (TunicArchipelago.Settings.ShowItemsEnabled) {
+ ModelSwaps.SwapItemsInScene();
+ }
+ }
+
+ if (Item.Type == ItemTypes.FAIRY) {
+ foreach (string Fairy in ItemLookup.FairyLookup.Keys) {
+ if (SaveFile.GetInt($"randomizer obtained fairy {Fairy}") == 0) {
+ SaveFile.SetInt($"randomizer obtained fairy {Fairy}", 1);
+ break;
+ }
+ }
+ GameObject.Instantiate(ModelSwaps.FairyAnimation, PlayerCharacter.instance.transform.position, Quaternion.identity).SetActive(true);
+ NotificationBottom = $"\"{(TunicArchipelago.Tracker.ImportantItems["Fairies"] + 1)}/20\" fArEz fownd.";
+ }
+
+ if (Item.Type == ItemTypes.PAGE) {
+ SaveFile.SetInt($"randomizer obtained page {Item.ItemNameForInventory}", 1);
+ bool HasAllPages = true;
+ for (int i = 0; i < 28; i++) {
+ if (SaveFile.GetInt($"randomizer obtained page {i}") == 0) {
+ HasAllPages = false;
+ break;
+ }
+ }
+ if (!StateVariable.GetStateVariableByName("Has Been Betrayed").BoolValue && HasAllPages) {
+ StateVariable.GetStateVariableByName("Has Been Betrayed").BoolValue = HasAllPages;
+ }
+ if (SaveFile.GetInt(AbilityShuffle) == 1) {
+ Dictionary pagesForAbilities = new Dictionary() {
+ { "12", (PrayerUnlocked, PrayerUnlockedTime, ItemLookup.PrayerUnlockedLine) },
+ { "21", (HolyCrossUnlocked, HolyCrossUnlockedTime, ItemLookup.HolyCrossUnlockedLine) },
+ { "26", (IceBoltUnlocked, IceboltUnlockedTime, ItemLookup.IceboltUnlockedLine) },
+ };
+ if (pagesForAbilities.ContainsKey(Item.ItemNameForInventory)) {
+ SaveFile.SetInt(pagesForAbilities[Item.ItemNameForInventory].Item1, 1);
+ SaveFile.SetFloat(pagesForAbilities[Item.ItemNameForInventory].Item2, SpeedrunData.inGameTime);
+ NotificationBottom = pagesForAbilities[Item.ItemNameForInventory].Item3;
+ DisplayMessageAnyway = true;
+ if (Item.ItemNameForInventory == "21") {
+ ToggleHolyCrossObjects(true);
+ }
+ ItemStatsHUD.UpdateAbilitySection();
+ }
+ }
+ if (!TunicArchipelago.Settings.SkipItemAnimations) {
+ PageDisplay.ShowPage(int.Parse(Item.ItemNameForInventory, CultureInfo.InvariantCulture));
+ } else {
+ SaveFile.SetInt("last page viewed", int.Parse(Item.ItemNameForInventory, CultureInfo.InvariantCulture));
+ }
+ }
+
+ if (Item.Type == ItemTypes.GOLDENTROPHY) {
+
+ Item GoldenTrophy = Inventory.GetItemByName(Item.ItemNameForInventory);
+ GoldenTrophy.Quantity += Check.Reward.Amount;
+ // Apply bonus upgrade text
+ if (TunicArchipelago.Settings.BonusStatUpgradesEnabled) {
+ GoldenTrophy.collectionMessage = ScriptableObject.CreateInstance();
+ GoldenTrophy.collectionMessage.text = Translations.TranslateDefaultNoQuotes(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true);
+ Inventory.GetItemByName(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].LevelUp).Quantity += 1;
+ } else {
+ GoldenTrophy.collectionMessage = ScriptableObject.CreateInstance();
+ GoldenTrophy.collectionMessage.text = $"kawngrahJoulA$uhnz!";
+ }
+
+ ItemPresentation.PresentItem(GoldenTrophy);
+ NotificationBottom = TunicArchipelago.Settings.BonusStatUpgradesEnabled ? Translations.TranslateDefaultNoQuotes(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true) : $"kawngrahJoulA$uhnz!";
+ }
+
+ if (Item.Type == ItemTypes.RELIC) {
+
+ Item RelicItem = Inventory.GetItemByName(Item.ItemNameForInventory);
+ RelicItem.Quantity += Check.Reward.Amount;
+ if (TunicArchipelago.Settings.BonusStatUpgradesEnabled) {
+ Inventory.GetItemByName(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].LevelUp).Quantity += 1;
+ }
+
+ // Apply custom pickup text
+ RelicItem.collectionMessage = new LanguageLine();
+ RelicItem.collectionMessage.text = Translations.Translate(ItemLookup.BonusUpgrades[Item.ItemNameForInventory].CustomPickupMessage, true);
+
+ ItemPresentation.PresentItem(RelicItem);
+ }
+
+ if (Item.Type == ItemTypes.FOOLTRAP) {
+ (NotificationTop, NotificationBottom) = ApplyFoolEffect(-1);
+ DisplayMessageAnyway = true;
+ }
+
+ if (Item.Type == ItemTypes.HEXAGONQUEST) {
+ Inventory.GetItemByName("Hexagon Gold").Quantity += 1;
+ int GoldHexes = Inventory.GetItemByName("Hexagon Gold").Quantity;
+
+ if (SaveFile.GetInt(AbilityShuffle) == 1) {
+ Dictionary hexesForAbilities = new Dictionary() {
+ { SaveFile.GetInt(HexagonQuestPrayer), (PrayerUnlocked, PrayerUnlockedTime, ItemLookup.PrayerUnlockedLine) },
+ { SaveFile.GetInt(HexagonQuestHolyCross), (HolyCrossUnlocked, HolyCrossUnlockedTime, ItemLookup.HolyCrossUnlockedLine) },
+ { SaveFile.GetInt(HexagonQuestIcebolt), (IceBoltUnlocked, IceboltUnlockedTime, ItemLookup.IceboltUnlockedLine) },
+ };
+ if (hexesForAbilities.ContainsKey(GoldHexes)) {
+ SaveFile.SetInt(hexesForAbilities[GoldHexes].Item1, 1);
+ SaveFile.SetFloat(hexesForAbilities[GoldHexes].Item2, SpeedrunData.inGameTime);
+ NotificationBottom = hexesForAbilities[GoldHexes].Item3;
+ DisplayMessageAnyway = true;
+ if (GoldHexes == SaveFile.GetInt(HexagonQuestHolyCross)) {
+ ToggleHolyCrossObjects(true);
+ }
+
+ ItemStatsHUD.UpdateAbilitySection();
+ }
+ }
+
+ ItemPresentation.PresentItem(Inventory.GetItemByName(Item.ItemNameForInventory));
+ }
+
+ if (ItemLookup.MajorItems.Contains(Item.Name)) {
+ if (Item.Type == ItemTypes.SWORDUPGRADE && SaveFile.GetInt(SwordProgressionEnabled) == 1) {
+ SaveFile.SetFloat($"randomizer Sword Progression {SaveFile.GetInt(SwordProgressionLevel)} time", SpeedrunData.inGameTime);
+ } else if (Item.Type == ItemTypes.PAGE) {
+ SaveFile.SetFloat($"randomizer {Item.Name} 1 time", SpeedrunData.inGameTime);
+ } else {
+ SaveFile.SetFloat($"randomizer {Item.Name} {(TunicArchipelago.Tracker.ImportantItems[Item.ItemNameForInventory] + 1)} time", SpeedrunData.inGameTime);
+ }
+ }
+
+ if (TunicArchipelago.Settings.SkipItemAnimations || DisplayMessageAnyway) {
+ NotificationTop = NotificationTop == "" ? $"yoo fownd {(TextBuilderPatches.ItemNameToAbbreviation.ContainsKey(Item.Name) ? TextBuilderPatches.ItemNameToAbbreviation[Item.Name] : "")} \"{Item.Name}!\"" : NotificationTop;
+ NotificationBottom = NotificationBottom == "" ? $"$oud bE yoosfuhl!" : NotificationBottom;
+ Notifications.Show(NotificationTop, NotificationBottom);
+ }
+
+ string slotLoc = $"{Check.Location.LocationId} [{Check.Location.SceneName}]";
+ if (Hints.HeroGraveHints.Values.Where(hint => hint.PathHintId == slotLoc || hint.RelicHintId == slotLoc).Any()) {
+ SaveFile.SetInt($"randomizer hint found {slotLoc}", 1);
+ }
+ if (Hints.HeroGraveHints.Values.Where(hint => SaveFile.GetInt($"randomizer hint found {hint.PathHintId}") == 1).Count() == 6) {
+ StateVariable.GetStateVariableByName("randomizer got all 6 grave items").BoolValue = true;
+ }
+
+ TunicArchipelago.Tracker.SetCollectedItem(Item.Name, true);
+
+ string CheckId = $"{Check.Location.LocationId} [{Check.Location.SceneName}]";
+ Logger.LogInfo("Picked up item " + CheckId + " (" + Item.Name + ")");
+
+ Locations.CheckedLocations[CheckId] = true;
+ SaveFile.SetInt($"randomizer picked up {CheckId}", 1);
+ GameObject FairyTarget = GameObject.Find($"fairy target {CheckId}");
+ if (FairyTarget != null) {
+ GameObject.Destroy(FairyTarget);
+ }
+ if (Locations.VanillaLocations.Keys.Where(key => Locations.VanillaLocations[key].Location.SceneName == SceneLoaderPatches.SceneName && !Locations.CheckedLocations[key]).ToList().Count == 0) {
+ FairyTargets.CreateLoadZoneTargets();
+ }
+
+ if (TunicArchipelago.Settings.CreateSpoilerLog && !TunicArchipelago.Settings.RaceMode) {
+ ItemTracker.PopulateSpoilerLog();
+ }
+ }
+
private static (string, string) ApplyFoolEffect(int Player) {
System.Random Random = new System.Random();
int FoolType = PlayerCharacterPatches.StungByBee ? Random.Next(21, 100) : Random.Next(100);
@@ -425,13 +662,28 @@ private static (string, string) ApplyFoolEffect(int Player) {
FoolMessageBottom = $"hahvi^ ahn Is tIm?";
}
- if (Player != Archipelago.instance.GetPlayerSlot()) {
+ if (Player == -1 && IsSinglePlayer()) {
+
+ } else if (IsArchipelago() && Player != Archipelago.instance.GetPlayerSlot()) {
FoolMessageTop = $"\"{Archipelago.instance.GetPlayerName(Player)}\" %i^ks {FoolMessageTop}";
}
return (FoolMessageTop, FoolMessageBottom);
}
+ public static void CheckFoolTrapSetting(string RewardId) {
+ Reward Reward = Locations.RandomizedLocations[RewardId].Reward;
+ if (Reward.Type == "MONEY") {
+ if ((TunicArchipelago.Settings.FoolTrapIntensity == RandomizerSettings.FoolTrapOption.NORMAL && Reward.Amount < 20)
+ || (TunicArchipelago.Settings.FoolTrapIntensity == RandomizerSettings.FoolTrapOption.DOUBLE && Reward.Amount <= 20)
+ || (TunicArchipelago.Settings.FoolTrapIntensity == RandomizerSettings.FoolTrapOption.ONSLAUGHT && Reward.Amount <= 30)) {
+ Reward.Name = "Fool";
+ Reward.Type = "FOOL";
+ Reward.Amount = 1;
+ }
+ }
+ }
+
public static void ToggleHolyCrossObjects(bool isEnabled) {
foreach (ToggleObjectBySpell SpellToggle in Resources.FindObjectsOfTypeAll()) {
foreach (ToggleObjectBySpell Spell in SpellToggle.gameObject.GetComponents()) {
@@ -448,7 +700,9 @@ public static void PotionCombine_Show_PostFixPatch(PotionCombine __instance) {
public static void ButtonAssignableItem_CheckFreeItemSpell_PostfixPatch(ButtonAssignableItem __instance, ref string s) {
if (ItemLookup.BombCodes.ContainsKey(s) && StateVariable.GetStateVariableByName(ItemLookup.BombCodes[s]).BoolValue) {
if (SaveFile.GetInt($"randomizer used free bomb code {s}") == 0) {
- Archipelago.instance.UpdateDataStorage(ItemLookup.BombCodes[s], true);
+ if (IsArchipelago()) {
+ Archipelago.instance.UpdateDataStorage(ItemLookup.BombCodes[s], true);
+ }
SaveFile.SetInt($"randomizer used free bomb code {s}", 1);
if (TunicArchipelago.Settings.SkipItemAnimations) {
switch(ItemLookup.BombCodes[s]) {
@@ -469,8 +723,18 @@ public static void ButtonAssignableItem_CheckFreeItemSpell_PostfixPatch(ButtonAs
}
}
+ public static bool UpgradeMenu___Buy_PrefixPatch(UpgradeMenu __instance) {
+
+ if (TunicArchipelago.Settings.RaceMode && TunicArchipelago.Settings.DisableUpgradeStealing && UpgradeAltar.nearbyThings.Count == 0) {
+ UpgradeMenu.instance.__Exit();
+ return false;
+ }
+
+ return true;
+ }
public static bool UpgradeAltar_DoOfferingSequence_PrefixPatch(UpgradeAltar __instance, OfferingItem offeringItemToOffer) {
+
if (TunicArchipelago.Settings.FasterUpgrades) {
Notifications.Show($"{TextBuilderPatches.SpriteNameToAbbreviation[offeringItemToOffer.icon.name]} \"{offeringItemToOffer.statLabelLocKey}\" wehnt uhp fruhm {offeringItemToOffer.upgradeItemReceived.Quantity} [arrow_right] {offeringItemToOffer.upgradeItemReceived.Quantity+1}!", $"#E Ar ahksehpts yor awfuri^.");
UpgradeMenu.instance.__Exit();
diff --git a/src/Patches/ItemRandomizer.cs b/src/Patches/ItemRandomizer.cs
new file mode 100644
index 0000000..951608f
--- /dev/null
+++ b/src/Patches/ItemRandomizer.cs
@@ -0,0 +1,469 @@
+using BepInEx.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static UnityEngine.InputSystem.LowLevel.InputStateHistory;
+using UnityEngine.InputSystem.Utilities;
+using Newtonsoft.Json;
+
+namespace TunicArchipelago {
+ public class ItemRandomizer {
+ private static ManualLogSource Logger = TunicArchipelago.Logger;
+
+ public static Dictionary SphereZero = new Dictionary();
+
+ public static void PopulateSphereZero() {
+ SphereZero.Clear();
+ if (SaveFile.GetInt("randomizer shuffled abilities") == 0) {
+ SphereZero.Add("12", 1);
+ SphereZero.Add("21", 1);
+ SphereZero.Add("26", 1);
+ }
+ if (SaveFile.GetInt("randomizer started with sword") == 1) {
+ SphereZero.Add("Sword", 1);
+ }
+ }
+
+ public static void RandomizeAndPlaceItems() {
+ Logger.LogInfo("randomize and place items starting");
+
+ System.Random random = new System.Random(SaveFile.GetInt("seed"));
+ Locations.RandomizedLocations.Clear();
+ Locations.CheckedLocations.Clear();
+
+ List ProgressionNames = new List{ "Hyperdash", "Wand", "Techbow", "Stundagger", "Trinket Coin", "Lantern", "Stick", "Sword", "Sword Progression", "Key", "Key (House)", "Mask", "Vault Key (Red)" };
+ if (SaveFile.GetInt("randomizer shuffled abilities") == 1) {
+ if (SaveFile.GetInt(SaveFlags.HexagonQuestEnabled) == 1) {
+ ProgressionNames.Add("Hexagon Gold");
+ } else {
+ ProgressionNames.Add("12"); // Prayer
+ ProgressionNames.Add("21"); // Holy Cross
+ ProgressionNames.Add("26"); // Icebolt
+ }
+ }
+ if (SaveFile.GetInt(SaveFlags.LanternlessLogic) == 1) {
+ ProgressionNames.Remove("Lantern");
+ }
+ if (SaveFile.GetInt(SaveFlags.MasklessLogic) == 1) {
+ ProgressionNames.Remove("Mask");
+ }
+
+ List InitialItems = JsonConvert.DeserializeObject>(ItemListJson.ItemList);
+ List InitialRewards = new List();
+ List InitialLocations = new List();
+ List