mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-26 03:33:20 -07:00
Merge remote-tracking branch 'upstream/main' into instruction_patch_kdl3
This commit is contained in:
@@ -177,7 +177,7 @@
|
||||
/worlds/tloz/ @Rosalie-A @t3hf1gm3nt
|
||||
|
||||
# TUNIC
|
||||
/worlds/tunic/ @silent-destroyer
|
||||
/worlds/tunic/ @silent-destroyer @ScipioWright
|
||||
|
||||
# Undertale
|
||||
/worlds/undertale/ @jonloveslegos
|
||||
|
||||
@@ -6,8 +6,8 @@ from logging import warning
|
||||
from BaseClasses import Item, ItemClassification, Tutorial
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
from .datatypes import Room, RoomEntrance
|
||||
from .items import ALL_ITEM_TABLE, LingoItem
|
||||
from .locations import ALL_LOCATION_TABLE
|
||||
from .items import ALL_ITEM_TABLE, ITEMS_BY_GROUP, LingoItem
|
||||
from .locations import ALL_LOCATION_TABLE, LOCATIONS_BY_GROUP
|
||||
from .options import LingoOptions
|
||||
from .player_logic import LingoPlayerLogic
|
||||
from .regions import create_regions
|
||||
@@ -46,6 +46,8 @@ class LingoWorld(World):
|
||||
location_name_to_id = {
|
||||
name: data.code for name, data in ALL_LOCATION_TABLE.items()
|
||||
}
|
||||
item_name_groups = ITEMS_BY_GROUP
|
||||
location_name_groups = LOCATIONS_BY_GROUP
|
||||
|
||||
player_logic: LingoPlayerLogic
|
||||
|
||||
|
||||
@@ -63,12 +63,13 @@
|
||||
# - item_name: Overrides the name of the item generated for this door.
|
||||
# If not specified, the item name will be generated from
|
||||
# the room name and the door name.
|
||||
# - item_group: If set, this item will be in the specified item group.
|
||||
# - location_name: Overrides the name of the location generated for this
|
||||
# door. If not specified, the location name will be
|
||||
# generated using the names of the panels.
|
||||
# - skip_location: If true, no location is generated for this door.
|
||||
# - skip_item: If true, no item is generated for this door.
|
||||
# - group: When simple doors is used, all doors with the same group
|
||||
# - door_group: When simple doors is used, all doors with the same group
|
||||
# will be covered by a single item.
|
||||
# - include_reduce: Door checks are assumed to be EXCLUDED when reduce checks
|
||||
# is on. This option includes the check anyway.
|
||||
@@ -144,7 +145,7 @@
|
||||
- Palindrome Room Area Doors/Door_racecar_racecar_2
|
||||
- Palindrome Room Area Doors/Door_solos_solos_2
|
||||
skip_location: True
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- room: The Tenacious
|
||||
panel: LEVEL (Black)
|
||||
@@ -231,7 +232,7 @@
|
||||
Dead End Door:
|
||||
id: Appendix Room Area Doors/Door_rat_tar_2
|
||||
skip_location: true
|
||||
group: Dead End Area Access
|
||||
door_group: Dead End Area Access
|
||||
panels:
|
||||
- room: Hub Room
|
||||
panel: RAT
|
||||
@@ -244,6 +245,7 @@
|
||||
Seeker Entrance:
|
||||
id: Entry Room Area Doors/Door_entrance_entrance
|
||||
item_name: The Seeker - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- OPEN
|
||||
Rhyme Room Entrance:
|
||||
@@ -251,7 +253,7 @@
|
||||
- Appendix Room Area Doors/Door_rat_tar_3
|
||||
- Double Room Area Doors/Door_room_entry_stairs
|
||||
skip_location: True
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- room: The Tenacious
|
||||
panel: LEVEL (Black)
|
||||
@@ -450,6 +452,7 @@
|
||||
id: Shuffle Room/Panel_lost_found
|
||||
colors: black
|
||||
tag: botblack
|
||||
check: True
|
||||
FORWARD:
|
||||
id: Entry Room/Panel_forward_forward
|
||||
tag: midwhite
|
||||
@@ -461,37 +464,39 @@
|
||||
tag: midwhite
|
||||
doors:
|
||||
Crossroads Entrance:
|
||||
id: Shuffle Room Area Doors/Door_chaos
|
||||
id:
|
||||
- Shuffle Room Area Doors/Door_chaos
|
||||
- Shuffle Room Area Doors/Door_swap
|
||||
- Shuffle Room Area Doors/Door_swap2
|
||||
- Shuffle Room Area Doors/Door_swap3
|
||||
- Shuffle Room Area Doors/Door_swap4
|
||||
panels:
|
||||
- ORDER
|
||||
Tenacious Entrance:
|
||||
id: Palindrome Room Area Doors/Door_slaughter_laughter
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- SLAUGHTER
|
||||
Shortcut to Hedge Maze:
|
||||
id: Maze Area Doors/Door_trace_trace
|
||||
group: Hedge Maze Doors
|
||||
door_group: Hedge Maze Doors
|
||||
panels:
|
||||
- TRACE
|
||||
Near RAT Door:
|
||||
id: Appendix Room Area Doors/Door_deadend_deadened
|
||||
skip_location: True
|
||||
group: Dead End Area Access
|
||||
door_group: Dead End Area Access
|
||||
panels:
|
||||
- room: Hidden Room
|
||||
panel: DEAD END
|
||||
Traveled Entrance:
|
||||
id: Appendix Room Area Doors/Door_open_open
|
||||
item_name: The Traveled - Entrance
|
||||
group: Entrance to The Traveled
|
||||
door_group: Entrance to The Traveled
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- OPEN
|
||||
Lost Door:
|
||||
id: Shuffle Room Area Doors/Door_lost_found
|
||||
junk_item: True
|
||||
panels:
|
||||
- LOST
|
||||
paintings:
|
||||
- id: maze_painting
|
||||
orientation: west
|
||||
@@ -546,6 +551,7 @@
|
||||
doors:
|
||||
Sun Painting:
|
||||
item_name: Pilgrim Room - Sun Painting
|
||||
item_group: Paintings
|
||||
location_name: Pilgrim Room - HOT CRUST
|
||||
painting_id: pilgrim_painting2
|
||||
panels:
|
||||
@@ -694,6 +700,8 @@
|
||||
door: Hollow Hallway
|
||||
tag: midwhite
|
||||
SWAP:
|
||||
# In vanilla doors, solving this panel will open the way to Hub Room. This does not impact logic at all because
|
||||
# Hub Room is always sphere 1 in vanilla doors.
|
||||
id: Shuffle Room/Panel_swap_wasp
|
||||
colors: yellow
|
||||
tag: midyellow
|
||||
@@ -715,12 +723,14 @@
|
||||
doors:
|
||||
Tenacious Entrance:
|
||||
id: Palindrome Room Area Doors/Door_decay_day
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- DECAY
|
||||
Discerning Entrance:
|
||||
id: Shuffle Room Area Doors/Door_nope_open
|
||||
item_name: The Discerning - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- NOPE
|
||||
Tower Entrance:
|
||||
@@ -729,13 +739,13 @@
|
||||
- Shuffle Room Area Doors/Door_tower2
|
||||
- Shuffle Room Area Doors/Door_tower3
|
||||
- Shuffle Room Area Doors/Door_tower4
|
||||
group: Crossroads - Tower Entrances
|
||||
door_group: Crossroads - Tower Entrances
|
||||
panels:
|
||||
- WE ROT
|
||||
Tower Back Entrance:
|
||||
id: Shuffle Room Area Doors/Door_runt
|
||||
location_name: Crossroads - TURN/RUNT
|
||||
group: Crossroads - Tower Entrances
|
||||
door_group: Crossroads - Tower Entrances
|
||||
panels:
|
||||
- TURN
|
||||
- room: Orange Tower Fourth Floor
|
||||
@@ -744,20 +754,20 @@
|
||||
id:
|
||||
- Shuffle Room Area Doors/Door_words_shuffle_3
|
||||
- Shuffle Room Area Doors/Door_words_shuffle_4
|
||||
group: Crossroads Doors
|
||||
door_group: Crossroads Doors
|
||||
panels:
|
||||
- WORDS
|
||||
- SWORD
|
||||
Eye Wall:
|
||||
id: Shuffle Room Area Doors/Door_behind
|
||||
junk_item: True
|
||||
group: Crossroads Doors
|
||||
door_group: Crossroads Doors
|
||||
panels:
|
||||
- BEND HI
|
||||
Hollow Hallway:
|
||||
id: Shuffle Room Area Doors/Door_crossroads6
|
||||
skip_location: True
|
||||
group: Crossroads Doors
|
||||
door_group: Crossroads Doors
|
||||
panels:
|
||||
- BEND HI
|
||||
Roof Access:
|
||||
@@ -934,7 +944,7 @@
|
||||
- Palindrome Room Area Doors/Door_racecar_racecar_1
|
||||
- Palindrome Room Area Doors/Door_solos_solos_1
|
||||
location_name: The Tenacious - Palindromes
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
panels:
|
||||
- LEVEL (Black)
|
||||
- RACECAR (Black)
|
||||
@@ -965,7 +975,7 @@
|
||||
id:
|
||||
- Symmetry Room Area Doors/Door_near_far
|
||||
- Symmetry Room Area Doors/Door_far_near
|
||||
group: Symmetry Doors
|
||||
door_group: Symmetry Doors
|
||||
item_name: Symmetry Room - Near Far Door
|
||||
location_name: Symmetry Room - NEAR, FAR
|
||||
panels:
|
||||
@@ -992,7 +1002,7 @@
|
||||
id:
|
||||
- Symmetry Room Area Doors/Door_warts_straw
|
||||
- Symmetry Room Area Doors/Door_straw_warts
|
||||
group: Symmetry Doors
|
||||
door_group: Symmetry Doors
|
||||
item_name: Symmetry Room - Warts Straw Door
|
||||
location_name: Symmetry Room - WARTS, STRAW
|
||||
panels:
|
||||
@@ -1019,7 +1029,7 @@
|
||||
id:
|
||||
- Symmetry Room Area Doors/Door_leaf_feel
|
||||
- Symmetry Room Area Doors/Door_feel_leaf
|
||||
group: Symmetry Doors
|
||||
door_group: Symmetry Doors
|
||||
item_name: Symmetry Room - Leaf Feel Door
|
||||
location_name: Symmetry Room - LEAF, FEEL
|
||||
panels:
|
||||
@@ -1156,34 +1166,37 @@
|
||||
doors:
|
||||
Tenacious Entrance:
|
||||
id: Palindrome Room Area Doors/Door_massacred_sacred
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- MASSACRED
|
||||
Black Door:
|
||||
id: Symmetry Room Area Doors/Door_black_white
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
panels:
|
||||
- BLACK
|
||||
Agreeable Entrance:
|
||||
id: Symmetry Room Area Doors/Door_close_open
|
||||
item_name: The Agreeable - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- CLOSE
|
||||
Painting Shortcut:
|
||||
item_name: Starting Room - Street Painting
|
||||
item_group: Paintings
|
||||
painting_id: eyes_yellow_painting2
|
||||
panels:
|
||||
- RIGHT
|
||||
Purple Barrier:
|
||||
id: Color Arrow Room Doors/Door_purple_3
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
panel: PURPLE
|
||||
Hallway Door:
|
||||
id: Red Blue Purple Room Area Doors/Door_room_2
|
||||
group: Hallway Room Doors
|
||||
door_group: Hallway Room Doors
|
||||
location_name: Hallway Room - First Room
|
||||
panels:
|
||||
- WALL
|
||||
@@ -1229,7 +1242,8 @@
|
||||
doors:
|
||||
Tenacious Entrance:
|
||||
id: Palindrome Room Area Doors/Door_dread_dead
|
||||
group: Entrances to The Tenacious
|
||||
door_group: Entrances to The Tenacious
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- DREAD
|
||||
The Agreeable:
|
||||
@@ -1287,7 +1301,7 @@
|
||||
id: Antonym Room/Panel_star_rats
|
||||
colors: black
|
||||
tag: midblack
|
||||
TAME:
|
||||
TUBE:
|
||||
id: Antonym Room/Panel_tame_mate
|
||||
colors: black
|
||||
tag: topblack
|
||||
@@ -1298,7 +1312,8 @@
|
||||
doors:
|
||||
Shortcut to Hedge Maze:
|
||||
id: Symmetry Room Area Doors/Door_bye_hi
|
||||
group: Hedge Maze Doors
|
||||
item_group: Achievement Room Entrances
|
||||
door_group: Hedge Maze Doors
|
||||
panels:
|
||||
- BYE
|
||||
Hedge Maze:
|
||||
@@ -1391,12 +1406,14 @@
|
||||
Perceptive Entrance:
|
||||
id: Maze Area Doors/Door_maze_maze
|
||||
item_name: The Perceptive - Entrance
|
||||
group: Hedge Maze Doors
|
||||
door_group: Hedge Maze Doors
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- DOWN
|
||||
Painting Shortcut:
|
||||
painting_id: garden_painting_tower2
|
||||
item_name: Starting Room - Hedge Maze Painting
|
||||
item_group: Paintings
|
||||
skip_location: True
|
||||
panels:
|
||||
- DOWN
|
||||
@@ -1407,7 +1424,8 @@
|
||||
- Maze Area Doors/Door_look_room_3
|
||||
skip_location: True
|
||||
item_name: The Observant - Entrance
|
||||
group: Observant Doors
|
||||
door_group: Observant Doors
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- room: The Perceptive
|
||||
panel: GAZE
|
||||
@@ -1473,7 +1491,7 @@
|
||||
Second Floor:
|
||||
id: Naps Room Doors/Door_hider_5
|
||||
location_name: The Fearless - First Floor Puzzles
|
||||
group: Fearless Doors
|
||||
door_group: Fearless Doors
|
||||
panels:
|
||||
- SPAN
|
||||
- TEAM
|
||||
@@ -1525,7 +1543,7 @@
|
||||
- Naps Room Doors/Door_hider_1b2
|
||||
- Naps Room Doors/Door_hider_new1
|
||||
location_name: The Fearless - Second Floor Puzzles
|
||||
group: Fearless Doors
|
||||
door_group: Fearless Doors
|
||||
panels:
|
||||
- NONE
|
||||
- SUM
|
||||
@@ -1680,13 +1698,13 @@
|
||||
doors:
|
||||
Backside Door:
|
||||
id: Maze Area Doors/Door_backside
|
||||
group: Backside Doors
|
||||
door_group: Backside Doors
|
||||
panels:
|
||||
- FOUR (1)
|
||||
- FOUR (2)
|
||||
Stairs:
|
||||
id: Maze Area Doors/Door_stairs
|
||||
group: Observant Doors
|
||||
door_group: Observant Doors
|
||||
panels:
|
||||
- SIX
|
||||
The Incomparable:
|
||||
@@ -1764,7 +1782,7 @@
|
||||
Eight Door:
|
||||
id: Red Blue Purple Room Area Doors/Door_a_strands
|
||||
location_name: Giant Sevens
|
||||
group: Observant Doors
|
||||
door_group: Observant Doors
|
||||
panels:
|
||||
- I (Seven)
|
||||
- room: Courtyard
|
||||
@@ -1915,13 +1933,13 @@
|
||||
doors:
|
||||
Shortcut to Hub Room:
|
||||
id: Shuffle Room Area Doors/Door_secret_secret
|
||||
group: Orange Tower First Floor - Shortcuts
|
||||
door_group: Orange Tower First Floor - Shortcuts
|
||||
panels:
|
||||
- SECRET
|
||||
Salt Pepper Door:
|
||||
id: Count Up Room Area Doors/Door_salt_pepper
|
||||
location_name: Orange Tower First Floor - Salt Pepper Door
|
||||
group: Orange Tower First Floor - Shortcuts
|
||||
door_group: Orange Tower First Floor - Shortcuts
|
||||
panels:
|
||||
- SALT
|
||||
- room: Directional Gallery
|
||||
@@ -1952,6 +1970,7 @@
|
||||
door: Shortcut to Tower
|
||||
Rhyme Room (Smiley):
|
||||
door: Rhyme Room Entrance
|
||||
Art Gallery: True # mark this as a warp in the sunwarps branch
|
||||
panels:
|
||||
RED:
|
||||
id: Color Arrow Room/Panel_red_afar
|
||||
@@ -1967,7 +1986,7 @@
|
||||
doors:
|
||||
Red Barrier:
|
||||
id: Color Arrow Room Doors/Door_red_6
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
@@ -1975,7 +1994,7 @@
|
||||
Rhyme Room Entrance:
|
||||
id: Double Room Area Doors/Door_room_entry_stairs2
|
||||
skip_location: True
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- room: The Tenacious
|
||||
panel: LEVEL (Black)
|
||||
@@ -1989,7 +2008,7 @@
|
||||
- Color Arrow Room Doors/Door_orange_hider_2
|
||||
- Color Arrow Room Doors/Door_orange_hider_3
|
||||
location_name: Color Barriers - RED and YELLOW
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
item_name: Color Hunt - Orange Barrier
|
||||
panels:
|
||||
- RED
|
||||
@@ -2150,7 +2169,7 @@
|
||||
doors:
|
||||
Welcome Back:
|
||||
id: Entry Room Area Doors/Door_sizes
|
||||
group: Welcome Back Doors
|
||||
door_group: Welcome Back Doors
|
||||
panels:
|
||||
- SIZE (Small)
|
||||
- SIZE (Big)
|
||||
@@ -2404,6 +2423,7 @@
|
||||
Painting Shortcut:
|
||||
painting_id: flower_painting_8
|
||||
item_name: Starting Room - Flower Painting
|
||||
item_group: Paintings
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: First Second Third Fourth
|
||||
@@ -2416,7 +2436,7 @@
|
||||
panel: FOURTH
|
||||
Green Barrier:
|
||||
id: Color Arrow Room Doors/Door_green_5
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
@@ -2470,7 +2490,7 @@
|
||||
doors:
|
||||
Backside Door:
|
||||
id: Count Up Room Area Doors/Door_yellow_backside
|
||||
group: Backside Doors
|
||||
door_group: Backside Doors
|
||||
location_name: Courtyard - FIRST, SECOND, THIRD, FOURTH
|
||||
item_name: Courtyard - Backside Door
|
||||
panels:
|
||||
@@ -2491,7 +2511,7 @@
|
||||
Progress Door:
|
||||
id: Doorway Room Doors/Door_white
|
||||
item_name: The Colorful - White Door
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
location_name: The Colorful - White
|
||||
panels:
|
||||
- BEGIN
|
||||
@@ -2512,7 +2532,7 @@
|
||||
id: Doorway Room Doors/Door_black
|
||||
item_name: The Colorful - Black Door
|
||||
location_name: The Colorful - Black
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- FOUND
|
||||
The Colorful (Red):
|
||||
@@ -2532,7 +2552,7 @@
|
||||
id: Doorway Room Doors/Door_red
|
||||
item_name: The Colorful - Red Door
|
||||
location_name: The Colorful - Red
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- LOAF
|
||||
The Colorful (Yellow):
|
||||
@@ -2552,7 +2572,7 @@
|
||||
id: Doorway Room Doors/Door_yellow
|
||||
item_name: The Colorful - Yellow Door
|
||||
location_name: The Colorful - Yellow
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- CREAM
|
||||
The Colorful (Blue):
|
||||
@@ -2572,7 +2592,7 @@
|
||||
id: Doorway Room Doors/Door_blue
|
||||
item_name: The Colorful - Blue Door
|
||||
location_name: The Colorful - Blue
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- SUN
|
||||
The Colorful (Purple):
|
||||
@@ -2592,7 +2612,7 @@
|
||||
id: Doorway Room Doors/Door_purple
|
||||
item_name: The Colorful - Purple Door
|
||||
location_name: The Colorful - Purple
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- SPOON
|
||||
The Colorful (Orange):
|
||||
@@ -2612,7 +2632,7 @@
|
||||
id: Doorway Room Doors/Door_orange
|
||||
item_name: The Colorful - Orange Door
|
||||
location_name: The Colorful - Orange
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- LETTERS
|
||||
The Colorful (Green):
|
||||
@@ -2632,7 +2652,7 @@
|
||||
id: Doorway Room Doors/Door_green
|
||||
item_name: The Colorful - Green Door
|
||||
location_name: The Colorful - Green
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- WALLS
|
||||
The Colorful (Brown):
|
||||
@@ -2652,7 +2672,7 @@
|
||||
id: Doorway Room Doors/Door_brown
|
||||
item_name: The Colorful - Brown Door
|
||||
location_name: The Colorful - Brown
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- IRON
|
||||
The Colorful (Gray):
|
||||
@@ -2672,7 +2692,7 @@
|
||||
id: Doorway Room Doors/Door_gray
|
||||
item_name: The Colorful - Gray Door
|
||||
location_name: The Colorful - Gray
|
||||
group: Colorful Doors
|
||||
door_group: Colorful Doors
|
||||
panels:
|
||||
- OBSTACLE
|
||||
The Colorful:
|
||||
@@ -2768,7 +2788,7 @@
|
||||
doors:
|
||||
Shortcut to Starting Room:
|
||||
id: Entry Room Area Doors/Door_return_return
|
||||
group: Welcome Back Doors
|
||||
door_group: Welcome Back Doors
|
||||
include_reduce: True
|
||||
panels:
|
||||
- WELCOME BACK
|
||||
@@ -2793,7 +2813,7 @@
|
||||
doors:
|
||||
Shortcut to Hedge Maze:
|
||||
id: Maze Area Doors/Door_strays_maze
|
||||
group: Hedge Maze Doors
|
||||
door_group: Hedge Maze Doors
|
||||
panels:
|
||||
- STRAYS
|
||||
paintings:
|
||||
@@ -2916,14 +2936,14 @@
|
||||
- UNCOVER
|
||||
Blue Barrier:
|
||||
id: Color Arrow Room Doors/Door_blue_3
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
panel: BLUE
|
||||
Orange Barrier:
|
||||
id: Color Arrow Room Doors/Door_orange_3
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
@@ -2931,6 +2951,7 @@
|
||||
Initiated Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_locked_knocked
|
||||
item_name: The Initiated - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- OXEN
|
||||
# These would be more appropriate in Champion's Rest, but as currently
|
||||
@@ -2940,7 +2961,7 @@
|
||||
id: Color Arrow Room Doors/Door_green_hider_1
|
||||
location_name: Color Barriers - BLUE and YELLOW
|
||||
item_name: Color Hunt - Green Barrier
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
panels:
|
||||
- BLUE
|
||||
- room: Directional Gallery
|
||||
@@ -2952,7 +2973,7 @@
|
||||
- Color Arrow Room Doors/Door_purple_hider_3
|
||||
location_name: Color Barriers - RED and BLUE
|
||||
item_name: Color Hunt - Purple Barrier
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
panels:
|
||||
- BLUE
|
||||
- room: Orange Tower Third Floor
|
||||
@@ -2972,6 +2993,7 @@
|
||||
panel: PURPLE
|
||||
Eight Door:
|
||||
id: Red Blue Purple Room Area Doors/Door_a_strands2
|
||||
item_group: Achievement Room Entrances
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: The Incomparable
|
||||
@@ -3189,7 +3211,8 @@
|
||||
doors:
|
||||
Color Hallways Entrance:
|
||||
id: Appendix Room Area Doors/Door_hello_hi
|
||||
group: Entrance to The Traveled
|
||||
door_group: Entrance to The Traveled
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- HELLO
|
||||
Color Hallways:
|
||||
@@ -3305,17 +3328,20 @@
|
||||
Bold Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_unopened_open
|
||||
item_name: The Bold - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- UNOPEN
|
||||
Painting Shortcut:
|
||||
painting_id: pencil_painting6
|
||||
skip_location: True
|
||||
item_name: Starting Room - Pencil Painting
|
||||
item_group: Paintings
|
||||
panels:
|
||||
- UNOPEN
|
||||
Steady Entrance:
|
||||
id: Rock Room Doors/Door_2
|
||||
item_name: The Steady - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- BEGIN
|
||||
Lilac Entrance:
|
||||
@@ -3536,6 +3562,7 @@
|
||||
Undeterred Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_pen_open
|
||||
item_name: The Undeterred - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- PEN
|
||||
Painting Shortcut:
|
||||
@@ -3544,11 +3571,13 @@
|
||||
- arrows_painting3
|
||||
skip_location: True
|
||||
item_name: Starting Room - Blue Painting
|
||||
item_group: Paintings
|
||||
panels:
|
||||
- PEN
|
||||
Green Painting:
|
||||
painting_id: maze_painting_3
|
||||
skip_location: True
|
||||
item_group: Paintings
|
||||
panels:
|
||||
- FOUR
|
||||
Twos:
|
||||
@@ -3556,6 +3585,7 @@
|
||||
- Count Up Room Area Doors/Door_two_hider
|
||||
- Count Up Room Area Doors/Door_two_hider_2
|
||||
include_reduce: True
|
||||
item_group: Numbers
|
||||
panels:
|
||||
- ONE
|
||||
Threes:
|
||||
@@ -3565,6 +3595,7 @@
|
||||
- Count Up Room Area Doors/Door_three_hider_3
|
||||
location_name: Twos
|
||||
include_reduce: True
|
||||
item_group: Numbers
|
||||
panels:
|
||||
- TWO (1)
|
||||
- TWO (2)
|
||||
@@ -3583,6 +3614,7 @@
|
||||
- Count Up Room Area Doors/Door_four_hider_3
|
||||
- Count Up Room Area Doors/Door_four_hider_4
|
||||
skip_location: True
|
||||
item_group: Numbers
|
||||
panels:
|
||||
- THREE (1)
|
||||
- THREE (2)
|
||||
@@ -3594,6 +3626,7 @@
|
||||
- Count Up Room Area Doors/Door_five_hider_5
|
||||
location_name: Fours
|
||||
item_name: Number Hunt - Fives
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- FOUR
|
||||
@@ -3606,6 +3639,7 @@
|
||||
Challenge Entrance:
|
||||
id: Count Up Room Area Doors/Door_zero_unlocked
|
||||
item_name: Number Hunt - Challenge Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- ZERO
|
||||
paintings:
|
||||
@@ -3752,7 +3786,7 @@
|
||||
doors:
|
||||
Door to Directional Gallery:
|
||||
id: Count Up Room Area Doors/Door_five_unlocked
|
||||
group: Directional Gallery Doors
|
||||
door_group: Directional Gallery Doors
|
||||
skip_location: True
|
||||
panels:
|
||||
- FIVE
|
||||
@@ -3766,6 +3800,7 @@
|
||||
- Count Up Room Area Doors/Door_six_hider_6
|
||||
painting_id: pencil_painting3 # See note in Outside The Bold
|
||||
location_name: Fives
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- FIVE
|
||||
@@ -3788,6 +3823,7 @@
|
||||
- Count Up Room Area Doors/Door_seven_hider_6
|
||||
- Count Up Room Area Doors/Door_seven_hider_7
|
||||
location_name: Sixes
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- SIX
|
||||
@@ -3813,6 +3849,7 @@
|
||||
- Count Up Room Area Doors/Door_eight_hider_7
|
||||
- Count Up Room Area Doors/Door_eight_hider_8
|
||||
location_name: Sevens
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- SEVEN
|
||||
@@ -3840,6 +3877,7 @@
|
||||
- Count Up Room Area Doors/Door_nine_hider_8
|
||||
- Count Up Room Area Doors/Door_nine_hider_9
|
||||
location_name: Eights
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- EIGHT
|
||||
@@ -3862,6 +3900,7 @@
|
||||
id: Count Up Room Area Doors/Door_zero_hider_2
|
||||
location_name: Nines
|
||||
item_name: Outside The Undeterred - Zero Door
|
||||
item_group: Numbers
|
||||
include_reduce: True
|
||||
panels:
|
||||
- NINE
|
||||
@@ -4030,13 +4069,13 @@
|
||||
doors:
|
||||
Shortcut to The Undeterred:
|
||||
id: Count Up Room Area Doors/Door_return_double
|
||||
group: Directional Gallery Doors
|
||||
door_group: Directional Gallery Doors
|
||||
panels:
|
||||
- TURN
|
||||
- LEARN
|
||||
Yellow Barrier:
|
||||
id: Color Arrow Room Doors/Door_yellow_4
|
||||
group: Color Hunt Barriers
|
||||
door_group: Color Hunt Barriers
|
||||
skip_location: True
|
||||
panels:
|
||||
- room: Color Hunt
|
||||
@@ -4231,11 +4270,12 @@
|
||||
doors:
|
||||
Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_middle_middle
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- MIDDLE
|
||||
Backside Door:
|
||||
id: Red Blue Purple Room Area Doors/Door_locked_knocked2 # yeah...
|
||||
group: Backside Doors
|
||||
door_group: Backside Doors
|
||||
panels:
|
||||
- FARTHER
|
||||
East Entrance:
|
||||
@@ -4952,7 +4992,7 @@
|
||||
colors:
|
||||
- red
|
||||
- blue
|
||||
tag: mid red blue
|
||||
tag: chain mid red blue
|
||||
required_panel:
|
||||
- room: Knight Night (Right Lower Segment)
|
||||
panel: ADJUST
|
||||
@@ -5223,7 +5263,7 @@
|
||||
- Ceiling Room Doors/Door_blue
|
||||
- Ceiling Room Doors/Door_blue2
|
||||
location_name: The Artistic - Smiley and Panda
|
||||
group: Artistic Doors
|
||||
door_group: Artistic Doors
|
||||
panels:
|
||||
- FINE
|
||||
- BLADE
|
||||
@@ -5333,7 +5373,7 @@
|
||||
- Ceiling Room Doors/Door_red
|
||||
- Ceiling Room Doors/Door_red2
|
||||
location_name: The Artistic - Panda and Lattice
|
||||
group: Artistic Doors
|
||||
door_group: Artistic Doors
|
||||
panels:
|
||||
- EYE (Top)
|
||||
- EYE (Bottom)
|
||||
@@ -5444,7 +5484,7 @@
|
||||
- Ceiling Room Doors/Door_black
|
||||
- Ceiling Room Doors/Door_black2
|
||||
location_name: The Artistic - Lattice and Apple
|
||||
group: Artistic Doors
|
||||
door_group: Artistic Doors
|
||||
panels:
|
||||
- POSH
|
||||
- MALL
|
||||
@@ -5557,7 +5597,7 @@
|
||||
- Ceiling Room Doors/Door_yellow
|
||||
- Ceiling Room Doors/Door_yellow2
|
||||
location_name: The Artistic - Apple and Smiley
|
||||
group: Artistic Doors
|
||||
door_group: Artistic Doors
|
||||
panels:
|
||||
- SPRIG
|
||||
- RELEASES
|
||||
@@ -5721,7 +5761,7 @@
|
||||
doors:
|
||||
Exit:
|
||||
id: Count Up Room Area Doors/Door_near_near
|
||||
group: Crossroads Doors
|
||||
door_group: Crossroads Doors
|
||||
panels:
|
||||
- NEAR
|
||||
paintings:
|
||||
@@ -5762,6 +5802,7 @@
|
||||
Wondrous Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_wonderland
|
||||
item_name: The Wondrous - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- SHRINK
|
||||
The Wondrous (Doorknob):
|
||||
@@ -5782,6 +5823,7 @@
|
||||
- arrows_painting2
|
||||
skip_location: True
|
||||
item_name: Starting Room - Symmetry Painting
|
||||
item_group: Paintings
|
||||
panels:
|
||||
- room: Outside The Wondrous
|
||||
panel: SHRINK
|
||||
@@ -5886,6 +5928,7 @@
|
||||
doors:
|
||||
Exit:
|
||||
id: Red Blue Purple Room Area Doors/Door_wonderland_exit
|
||||
item_group: Paintings
|
||||
painting_id: arrows_painting_9
|
||||
include_reduce: True
|
||||
panels:
|
||||
@@ -5955,7 +5998,7 @@
|
||||
Exit:
|
||||
id: Red Blue Purple Room Area Doors/Door_room_3
|
||||
location_name: Hallway Room - Second Room
|
||||
group: Hallway Room Doors
|
||||
door_group: Hallway Room Doors
|
||||
panels:
|
||||
- WISE
|
||||
- CLOCK
|
||||
@@ -5992,7 +6035,7 @@
|
||||
Exit:
|
||||
id: Red Blue Purple Room Area Doors/Door_room_4
|
||||
location_name: Hallway Room - Third Room
|
||||
group: Hallway Room Doors
|
||||
door_group: Hallway Room Doors
|
||||
panels:
|
||||
- TRANCE
|
||||
- FORM
|
||||
@@ -6014,7 +6057,7 @@
|
||||
id:
|
||||
- Red Blue Purple Room Area Doors/Door_room_5
|
||||
- Red Blue Purple Room Area Doors/Door_room_6 # this is the connection to The Artistic
|
||||
group: Hallway Room Doors
|
||||
door_group: Hallway Room Doors
|
||||
location_name: Hallway Room - Fourth Room
|
||||
panels:
|
||||
- WHEEL
|
||||
@@ -6082,6 +6125,7 @@
|
||||
Wanderer Entrance:
|
||||
id: Tower Room Area Doors/Door_wanderer_entrance
|
||||
item_name: The Wanderer - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- WANDERLUST
|
||||
Tower Entrance:
|
||||
@@ -6222,6 +6266,7 @@
|
||||
id: Tower Room Area Doors/Door_painting_exit
|
||||
include_reduce: True
|
||||
item_name: Orange Tower Fifth Floor - Quadruple Intersection
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- ORDER
|
||||
paintings:
|
||||
@@ -6417,7 +6462,7 @@
|
||||
- Double Room Area Doors/Door_room_3a
|
||||
- Double Room Area Doors/Door_room_3bc
|
||||
skip_location: True
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- SCHEME
|
||||
- FANTASY
|
||||
@@ -6518,7 +6563,7 @@
|
||||
Exit:
|
||||
id: Double Room Area Doors/Door_room_exit
|
||||
location_name: Rhyme Room (Cross) - Exit Puzzles
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- PLUMP
|
||||
- BOUNCE
|
||||
@@ -6581,7 +6626,7 @@
|
||||
- Double Room Area Doors/Door_room_2b
|
||||
- Double Room Area Doors/Door_room_3b
|
||||
location_name: Rhyme Room - Circle/Smiley Wall
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- BIRD
|
||||
- LETTER
|
||||
@@ -6664,7 +6709,7 @@
|
||||
- Double Room Area Doors/Door_room_2a
|
||||
- Double Room Area Doors/Door_room_1c
|
||||
location_name: Rhyme Room - Circle/Looped Square Wall
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- WALKED
|
||||
- OBSTRUCTED
|
||||
@@ -6683,7 +6728,7 @@
|
||||
- Double Room Area Doors/Door_room_1a
|
||||
- Double Room Area Doors/Door_room_5a
|
||||
location_name: Rhyme Room - Cross/Looped Square Wall
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- SKIES
|
||||
- SWELL
|
||||
@@ -6702,7 +6747,7 @@
|
||||
- Double Room Area Doors/Door_room_1b
|
||||
- Double Room Area Doors/Door_room_4b
|
||||
location_name: Rhyme Room - Target/Looped Square Wall
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- PENNED
|
||||
- CLIMB
|
||||
@@ -6765,7 +6810,7 @@
|
||||
Door to Cross:
|
||||
id: Double Room Area Doors/Door_room_4a
|
||||
location_name: Rhyme Room (Target) - Puzzles Toward Cross
|
||||
group: Rhyme Room Doors
|
||||
door_group: Rhyme Room Doors
|
||||
panels:
|
||||
- PISTOL
|
||||
- GEM
|
||||
@@ -7016,6 +7061,7 @@
|
||||
Wise Entrance:
|
||||
id: Clock Room Area Doors/Door_time_start
|
||||
item_name: The Wise - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- KITTEN
|
||||
- CAT
|
||||
@@ -7269,6 +7315,7 @@
|
||||
Scientific Entrance:
|
||||
id: Red Blue Purple Room Area Doors/Door_chemistry_lab
|
||||
item_name: The Scientific - Entrance
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- OPEN
|
||||
The Scientific:
|
||||
@@ -7704,5 +7751,6 @@
|
||||
doors:
|
||||
Welcome Door:
|
||||
id: Entry Room Area Doors/Door_challenge_challenge
|
||||
item_group: Achievement Room Entrances
|
||||
panels:
|
||||
- WELCOME
|
||||
|
||||
Binary file not shown.
@@ -165,7 +165,7 @@ panels:
|
||||
THAT: 444525
|
||||
STRESSED: 444526
|
||||
STAR: 444527
|
||||
TAME: 444528
|
||||
TUBE: 444528
|
||||
CAT: 444529
|
||||
Hedge Maze:
|
||||
DOWN: 444530
|
||||
@@ -995,9 +995,6 @@ doors:
|
||||
Traveled Entrance:
|
||||
item: 444433
|
||||
location: 444438
|
||||
Lost Door:
|
||||
item: 444435
|
||||
location: 444440
|
||||
Pilgrim Antechamber:
|
||||
Sun Painting:
|
||||
item: 444436
|
||||
|
||||
@@ -32,9 +32,10 @@ class Door(NamedTuple):
|
||||
has_doors: bool
|
||||
painting_ids: List[str]
|
||||
event: bool
|
||||
group: Optional[str]
|
||||
door_group: Optional[str]
|
||||
include_reduce: bool
|
||||
junk_item: bool
|
||||
item_group: Optional[str]
|
||||
|
||||
|
||||
class Panel(NamedTuple):
|
||||
|
||||
@@ -42,14 +42,16 @@ class LingoItem(Item):
|
||||
|
||||
|
||||
ALL_ITEM_TABLE: Dict[str, ItemData] = {}
|
||||
ITEMS_BY_GROUP: Dict[str, List[str]] = {}
|
||||
|
||||
|
||||
def load_item_data():
|
||||
global ALL_ITEM_TABLE
|
||||
global ALL_ITEM_TABLE, ITEMS_BY_GROUP
|
||||
|
||||
for color in ["Black", "Red", "Blue", "Yellow", "Green", "Orange", "Gray", "Brown", "Purple"]:
|
||||
ALL_ITEM_TABLE[color] = ItemData(get_special_item_id(color), ItemClassification.progression,
|
||||
"colors", [], [])
|
||||
ITEMS_BY_GROUP.setdefault("Colors", []).append(color)
|
||||
|
||||
door_groups: Dict[str, List[str]] = {}
|
||||
for room_name, doors in DOORS_BY_ROOM.items():
|
||||
@@ -57,11 +59,11 @@ def load_item_data():
|
||||
if door.skip_item is True or door.event is True:
|
||||
continue
|
||||
|
||||
if door.group is None:
|
||||
if door.door_group is None:
|
||||
door_mode = "doors"
|
||||
else:
|
||||
door_mode = "complex door"
|
||||
door_groups.setdefault(door.group, [])
|
||||
door_groups.setdefault(door.door_group, [])
|
||||
|
||||
if room_name in PROGRESSION_BY_ROOM and door_name in PROGRESSION_BY_ROOM[room_name]:
|
||||
door_mode = "special"
|
||||
@@ -70,10 +72,15 @@ def load_item_data():
|
||||
ItemData(get_door_item_id(room_name, door_name),
|
||||
ItemClassification.filler if door.junk_item else ItemClassification.progression, door_mode,
|
||||
door.has_doors, door.painting_ids)
|
||||
ITEMS_BY_GROUP.setdefault("Doors", []).append(door.item_name)
|
||||
|
||||
if door.item_group is not None:
|
||||
ITEMS_BY_GROUP.setdefault(door.item_group, []).append(door.item_name)
|
||||
|
||||
for group, group_door_ids in door_groups.items():
|
||||
ALL_ITEM_TABLE[group] = ItemData(get_door_group_item_id(group),
|
||||
ItemClassification.progression, "door group", True, [])
|
||||
ITEMS_BY_GROUP.setdefault("Doors", []).append(group)
|
||||
|
||||
special_items: Dict[str, ItemClassification] = {
|
||||
":)": ItemClassification.filler,
|
||||
@@ -90,6 +97,11 @@ def load_item_data():
|
||||
ALL_ITEM_TABLE[item_name] = ItemData(get_special_item_id(item_name), classification,
|
||||
"special", False, [])
|
||||
|
||||
if classification == ItemClassification.filler:
|
||||
ITEMS_BY_GROUP.setdefault("Junk", []).append(item_name)
|
||||
elif classification == ItemClassification.trap:
|
||||
ITEMS_BY_GROUP.setdefault("Traps", []).append(item_name)
|
||||
|
||||
for item_name in PROGRESSIVE_ITEMS:
|
||||
ALL_ITEM_TABLE[item_name] = ItemData(get_progressive_item_id(item_name),
|
||||
ItemClassification.progression, "special", False, [])
|
||||
|
||||
@@ -30,10 +30,11 @@ class LingoLocation(Location):
|
||||
|
||||
|
||||
ALL_LOCATION_TABLE: Dict[str, LocationData] = {}
|
||||
LOCATIONS_BY_GROUP: Dict[str, List[str]] = {}
|
||||
|
||||
|
||||
def load_location_data():
|
||||
global ALL_LOCATION_TABLE
|
||||
global ALL_LOCATION_TABLE, LOCATIONS_BY_GROUP
|
||||
|
||||
for room_name, panels in PANELS_BY_ROOM.items():
|
||||
for panel_name, panel in panels.items():
|
||||
@@ -50,6 +51,9 @@ def load_location_data():
|
||||
LocationData(get_panel_location_id(room_name, panel_name), room_name,
|
||||
[RoomAndPanel(None, panel_name)], classification)
|
||||
|
||||
if panel.achievement:
|
||||
LOCATIONS_BY_GROUP.setdefault("Achievements", []).append(location_name)
|
||||
|
||||
for room_name, doors in DOORS_BY_ROOM.items():
|
||||
for door_name, door in doors.items():
|
||||
if door.skip_location or door.event or door.panels is None:
|
||||
|
||||
@@ -150,9 +150,9 @@ class LingoPlayerLogic:
|
||||
for room_name, room_data in DOORS_BY_ROOM.items():
|
||||
for door_name, door_data in room_data.items():
|
||||
if door_data.skip_item is False and door_data.event is False:
|
||||
if door_data.group is not None and door_shuffle == ShuffleDoors.option_simple:
|
||||
if door_data.door_group is not None and door_shuffle == ShuffleDoors.option_simple:
|
||||
# Grouped doors are handled differently if shuffle doors is on simple.
|
||||
self.set_door_item(room_name, door_name, door_data.group)
|
||||
self.set_door_item(room_name, door_name, door_data.door_group)
|
||||
else:
|
||||
self.handle_non_grouped_door(room_name, door_data, world)
|
||||
|
||||
|
||||
@@ -255,10 +255,15 @@ def process_door(room_name, door_name, door_data):
|
||||
else:
|
||||
junk_item = False
|
||||
|
||||
if "group" in door_data:
|
||||
group = door_data["group"]
|
||||
if "door_group" in door_data:
|
||||
door_group = door_data["door_group"]
|
||||
else:
|
||||
group = None
|
||||
door_group = None
|
||||
|
||||
if "item_group" in door_data:
|
||||
item_group = door_data["item_group"]
|
||||
else:
|
||||
item_group = None
|
||||
|
||||
# panels is a list of panels. Each panel can either be a simple string (the name of a panel in the current room) or
|
||||
# a dictionary specifying a panel in a different room.
|
||||
@@ -308,7 +313,7 @@ def process_door(room_name, door_name, door_data):
|
||||
painting_ids = []
|
||||
|
||||
door_obj = Door(door_name, item_name, location_name, panels, skip_location, skip_item, has_doors,
|
||||
painting_ids, event, group, include_reduce, junk_item)
|
||||
painting_ids, event, door_group, include_reduce, junk_item, item_group)
|
||||
|
||||
DOORS_BY_ROOM[room_name][door_name] = door_obj
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ door_groups = {}
|
||||
|
||||
directives = Set["entrances", "panels", "doors", "paintings", "progression"]
|
||||
panel_directives = Set["id", "required_room", "required_door", "required_panel", "colors", "check", "exclude_reduce", "tag", "link", "subtag", "achievement", "copy_to_sign", "non_counting", "hunt"]
|
||||
door_directives = Set["id", "painting_id", "panels", "item_name", "location_name", "skip_location", "skip_item", "group", "include_reduce", "junk_item", "event"]
|
||||
door_directives = Set["id", "painting_id", "panels", "item_name", "item_group", "location_name", "skip_location", "skip_item", "door_group", "include_reduce", "junk_item", "event"]
|
||||
painting_directives = Set["id", "enter_only", "exit_only", "orientation", "required_door", "required", "required_when_no_doors", "move", "req_blocked", "req_blocked_when_no_doors"]
|
||||
|
||||
non_counting = 0
|
||||
|
||||
@@ -71,6 +71,12 @@ def first_nine_ixupi_capturable(state: CollectionState, player: int) -> bool:
|
||||
and metal_capturable(state, player)
|
||||
|
||||
|
||||
def all_skull_dials_available(state: CollectionState, player: int) -> bool:
|
||||
return state.can_reach("Prehistoric", "Region", player) and state.can_reach("Tar River", "Region", player) \
|
||||
and state.can_reach("Egypt", "Region", player) and state.can_reach("Burial", "Region", player) \
|
||||
and state.can_reach("Gods Room", "Region", player) and state.can_reach("Werewolf", "Region", player)
|
||||
|
||||
|
||||
def get_rules_lookup(player: int):
|
||||
rules_lookup: Dict[str, List[Callable[[CollectionState], bool]]] = {
|
||||
"entrances": {
|
||||
@@ -116,10 +122,7 @@ def get_rules_lookup(player: int):
|
||||
"To Tar River From Lobby": lambda state: (state.has("Crawling", player) and oil_capturable(state, player) and state.can_reach("Tar River", "Region", player)),
|
||||
"To Burial From Egypt": lambda state: state.can_reach("Egypt", "Region", player),
|
||||
"To Gods Room From Anansi": lambda state: state.can_reach("Gods Room", "Region", player),
|
||||
"To Slide Room": lambda state: (
|
||||
state.can_reach("Prehistoric", "Region", player) and state.can_reach("Tar River", "Region",player) and
|
||||
state.can_reach("Egypt", "Region", player) and state.can_reach("Burial", "Region", player) and
|
||||
state.can_reach("Gods Room", "Region", player) and state.can_reach("Werewolf", "Region", player)),
|
||||
"To Slide Room": lambda state: all_skull_dials_available(state, player),
|
||||
"To Lobby From Slide Room": lambda state: (beths_body_available(state, player))
|
||||
},
|
||||
"locations_required": {
|
||||
@@ -141,6 +144,7 @@ def get_rules_lookup(player: int):
|
||||
"Final Riddle: Norse God Stone Message": lambda state: (state.can_reach("Fortune Teller", "Region", player) and state.can_reach("UFO", "Region", player)),
|
||||
"Final Riddle: Beth's Body Page 17": lambda state: beths_body_available(state, player),
|
||||
"Final Riddle: Guillotine Dropped": lambda state: beths_body_available(state, player),
|
||||
"Puzzle Solved Skull Dial Door": lambda state: all_skull_dials_available(state, player),
|
||||
},
|
||||
"locations_puzzle_hints": {
|
||||
"Puzzle Solved Clock Tower Door": lambda state: state.can_reach("Three Floor Elevator", "Region", player),
|
||||
|
||||
@@ -7,6 +7,7 @@ from .rules import set_location_rules, set_region_rules, randomize_ability_unloc
|
||||
from .er_rules import set_er_location_rules
|
||||
from .regions import tunic_regions
|
||||
from .er_scripts import create_er_regions
|
||||
from .er_data import portal_mapping
|
||||
from .options import TunicOptions
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
@@ -44,7 +45,6 @@ class TunicWorld(World):
|
||||
game = "TUNIC"
|
||||
web = TunicWeb()
|
||||
|
||||
data_version = 2
|
||||
options: TunicOptions
|
||||
options_dataclass = TunicOptions
|
||||
item_name_groups = item_name_groups
|
||||
@@ -72,6 +72,7 @@ class TunicWorld(World):
|
||||
self.options.maskless.value = passthrough["maskless"]
|
||||
self.options.hexagon_quest.value = passthrough["hexagon_quest"]
|
||||
self.options.entrance_rando.value = passthrough["entrance_rando"]
|
||||
self.options.shuffle_ladders.value = passthrough["shuffle_ladders"]
|
||||
|
||||
def create_item(self, name: str) -> TunicItem:
|
||||
item_data = item_table[name]
|
||||
@@ -119,27 +120,46 @@ class TunicWorld(World):
|
||||
items_to_create[rgb_hexagon] = 0
|
||||
items_to_create[gold_hexagon] -= 3
|
||||
|
||||
# Filler items in the item pool
|
||||
available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and
|
||||
item_table[filler].classification == ItemClassification.filler]
|
||||
|
||||
# Remove filler to make room for other items
|
||||
def remove_filler(amount: int):
|
||||
for _ in range(0, amount):
|
||||
if not available_filler:
|
||||
fill = "Fool Trap"
|
||||
else:
|
||||
fill = self.random.choice(available_filler)
|
||||
if items_to_create[fill] == 0:
|
||||
raise Exception("No filler items left to accommodate options selected. Turn down fool trap amount.")
|
||||
items_to_create[fill] -= 1
|
||||
if items_to_create[fill] == 0:
|
||||
available_filler.remove(fill)
|
||||
|
||||
if self.options.shuffle_ladders:
|
||||
ladder_count = 0
|
||||
for item_name, item_data in item_table.items():
|
||||
if item_data.item_group == "ladders":
|
||||
items_to_create[item_name] = 1
|
||||
ladder_count += 1
|
||||
remove_filler(ladder_count)
|
||||
|
||||
if hexagon_quest:
|
||||
# Calculate number of hexagons in item pool
|
||||
hexagon_goal = self.options.hexagon_goal
|
||||
extra_hexagons = self.options.extra_hexagon_percentage
|
||||
items_to_create[gold_hexagon] += int((Decimal(100 + extra_hexagons) / 100 * hexagon_goal).to_integral_value(rounding=ROUND_HALF_UP))
|
||||
|
||||
|
||||
# Replace pages and normal hexagons with filler
|
||||
for replaced_item in list(filter(lambda item: "Pages" in item or item in hexagon_locations, items_to_create)):
|
||||
items_to_create[self.get_filler_item_name()] += items_to_create[replaced_item]
|
||||
filler_name = self.get_filler_item_name()
|
||||
items_to_create[filler_name] += items_to_create[replaced_item]
|
||||
if items_to_create[filler_name] >= 1 and filler_name not in available_filler:
|
||||
available_filler.append(filler_name)
|
||||
items_to_create[replaced_item] = 0
|
||||
|
||||
# Filler items that are still in the item pool to swap out
|
||||
available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and
|
||||
item_table[filler].classification == ItemClassification.filler]
|
||||
|
||||
# Remove filler to make room for extra hexagons
|
||||
for i in range(0, items_to_create[gold_hexagon]):
|
||||
fill = self.random.choice(available_filler)
|
||||
items_to_create[fill] -= 1
|
||||
if items_to_create[fill] == 0:
|
||||
available_filler.remove(fill)
|
||||
remove_filler(items_to_create[gold_hexagon])
|
||||
|
||||
if self.options.maskless:
|
||||
mask_item = TunicItem("Scavenger Mask", ItemClassification.useful, self.item_name_to_id["Scavenger Mask"], self.player)
|
||||
@@ -147,8 +167,8 @@ class TunicWorld(World):
|
||||
items_to_create["Scavenger Mask"] = 0
|
||||
|
||||
if self.options.lanternless:
|
||||
mask_item = TunicItem("Lantern", ItemClassification.useful, self.item_name_to_id["Lantern"], self.player)
|
||||
tunic_items.append(mask_item)
|
||||
lantern_item = TunicItem("Lantern", ItemClassification.useful, self.item_name_to_id["Lantern"], self.player)
|
||||
tunic_items.append(lantern_item)
|
||||
items_to_create["Lantern"] = 0
|
||||
|
||||
for item, quantity in items_to_create.items():
|
||||
@@ -172,15 +192,16 @@ class TunicWorld(World):
|
||||
self.ability_unlocks["Pages 24-25 (Prayer)"] = passthrough["Hexagon Quest Prayer"]
|
||||
self.ability_unlocks["Pages 42-43 (Holy Cross)"] = passthrough["Hexagon Quest Holy Cross"]
|
||||
self.ability_unlocks["Pages 52-53 (Icebolt)"] = passthrough["Hexagon Quest Icebolt"]
|
||||
|
||||
if self.options.entrance_rando:
|
||||
portal_pairs, portal_hints = create_er_regions(self)
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination()
|
||||
|
||||
self.er_portal_hints = portal_hints
|
||||
|
||||
# ladder rando uses ER with vanilla connections, so that we're not managing more rules files
|
||||
if self.options.entrance_rando or self.options.shuffle_ladders:
|
||||
portal_pairs = create_er_regions(self)
|
||||
if self.options.entrance_rando:
|
||||
# these get interpreted by the game to tell it which entrances to connect
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination()
|
||||
else:
|
||||
# for non-ER, non-ladders
|
||||
for region_name in tunic_regions:
|
||||
region = Region(region_name, self.player, self.multiworld)
|
||||
self.multiworld.regions.append(region)
|
||||
@@ -201,7 +222,7 @@ class TunicWorld(World):
|
||||
victory_region.locations.append(victory_location)
|
||||
|
||||
def set_rules(self) -> None:
|
||||
if self.options.entrance_rando:
|
||||
if self.options.entrance_rando or self.options.shuffle_ladders:
|
||||
set_er_location_rules(self, self.ability_unlocks)
|
||||
else:
|
||||
set_region_rules(self, self.ability_unlocks)
|
||||
@@ -212,7 +233,31 @@ class TunicWorld(World):
|
||||
|
||||
def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]):
|
||||
if self.options.entrance_rando:
|
||||
hint_data[self.player] = self.er_portal_hints
|
||||
hint_data.update({self.player: {}})
|
||||
# all state seems to have efficient paths
|
||||
all_state = self.multiworld.get_all_state(True)
|
||||
all_state.update_reachable_regions(self.player)
|
||||
paths = all_state.path
|
||||
portal_names = [portal.name for portal in portal_mapping]
|
||||
for location in self.multiworld.get_locations(self.player):
|
||||
# skipping event locations
|
||||
if not location.address:
|
||||
continue
|
||||
path_to_loc = []
|
||||
previous_name = "placeholder"
|
||||
name, connection = paths[location.parent_region]
|
||||
while connection != ("Menu", None):
|
||||
name, connection = connection
|
||||
# for LS entrances, we just want to give the portal name
|
||||
if "(LS)" in name:
|
||||
name, _ = name.split(" (LS) ")
|
||||
# was getting some cases like Library Grave -> Library Grave -> other place
|
||||
if name in portal_names and name != previous_name:
|
||||
previous_name = name
|
||||
path_to_loc.append(name)
|
||||
hint_text = " -> ".join(reversed(path_to_loc))
|
||||
if hint_text:
|
||||
hint_data[self.player][location.address] = hint_text
|
||||
|
||||
def fill_slot_data(self) -> Dict[str, Any]:
|
||||
slot_data: Dict[str, Any] = {
|
||||
@@ -226,7 +271,8 @@ class TunicWorld(World):
|
||||
"logic_rules": self.options.logic_rules.value,
|
||||
"lanternless": self.options.lanternless.value,
|
||||
"maskless": self.options.maskless.value,
|
||||
"entrance_rando": bool(self.options.entrance_rando.value),
|
||||
"entrance_rando": int(bool(self.options.entrance_rando.value)),
|
||||
"shuffle_ladders": self.options.shuffle_ladders.value,
|
||||
"Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"],
|
||||
"Hexagon Quest Holy Cross": self.ability_unlocks["Pages 42-43 (Holy Cross)"],
|
||||
"Hexagon Quest Icebolt": self.ability_unlocks["Pages 52-53 (Icebolt)"],
|
||||
|
||||
@@ -67,7 +67,7 @@ For the Entrance Randomizer:
|
||||
Bombs, consumables (non-bomb ones), weapons, melee weapons (stick and sword), keys, hexagons, offerings, hero relics, cards, golden treasures, money, pages, and abilities (the three ability pages). There are also a few groups being used for singular items: laurels, orb, dagger, magic rod, holy cross, prayer, icebolt, and progressive sword.
|
||||
|
||||
## What location groups are there?
|
||||
Holy cross (for all holy cross checks), fairies (for the two fairy checks), well (for the coin well checks), and shop. Additionally, for checks that do not fall into the above categories, the name of the region is the name of the location group.
|
||||
Holy cross (for all holy cross checks), fairies (for the two fairy checks), well (for the coin well checks), shop, bosses (for the bosses with checks associated with them), hero relic (for the 6 hero grave checks), and ladders (for the ladder items when you have shuffle ladders enabled).
|
||||
|
||||
## Is Connection Plando supported?
|
||||
Yes. The host needs to enable it in their `host.yaml`, and the player's yaml needs to contain a plando_connections block.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
from typing import Dict, List, Set, Tuple, TYPE_CHECKING
|
||||
from BaseClasses import Region, ItemClassification, Item, Location
|
||||
from .locations import location_table
|
||||
from .er_data import Portal, tunic_er_regions, portal_mapping, hallway_helper, hallway_helper_ur, \
|
||||
from .er_data import Portal, tunic_er_regions, portal_mapping, \
|
||||
dependent_regions_restricted, dependent_regions_nmg, dependent_regions_ur
|
||||
from .er_rules import set_er_region_rules
|
||||
from worlds.generic import PlandoConnection
|
||||
@@ -19,118 +19,26 @@ class TunicERLocation(Location):
|
||||
game: str = "TUNIC"
|
||||
|
||||
|
||||
def create_er_regions(world: "TunicWorld") -> Tuple[Dict[Portal, Portal], Dict[int, str]]:
|
||||
def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||
regions: Dict[str, Region] = {}
|
||||
portal_pairs: Dict[Portal, Portal] = pair_portals(world)
|
||||
logic_rules = world.options.logic_rules
|
||||
if world.options.entrance_rando:
|
||||
portal_pairs: Dict[Portal, Portal] = pair_portals(world)
|
||||
|
||||
# output the entrances to the spoiler log here for convenience
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
world.multiworld.spoiler.set_entrance(portal1.name, portal2.name, "both", world.player)
|
||||
# output the entrances to the spoiler log here for convenience
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
world.multiworld.spoiler.set_entrance(portal1.name, portal2.name, "both", world.player)
|
||||
else:
|
||||
portal_pairs: Dict[Portal, Portal] = vanilla_portals()
|
||||
|
||||
# check if a portal leads to a hallway. if it does, update the hint text accordingly
|
||||
def hint_helper(portal: Portal, hint_string: str = "") -> str:
|
||||
# start by setting it as the name of the portal, for the case we're not using the hallway helper
|
||||
if hint_string == "":
|
||||
hint_string = portal.name
|
||||
|
||||
# unrestricted has fewer hallways, like the well rail
|
||||
if logic_rules == "unrestricted":
|
||||
hallways = hallway_helper_ur
|
||||
else:
|
||||
hallways = hallway_helper
|
||||
|
||||
if portal.scene_destination() in hallways:
|
||||
# if we have a hallway, we want the region rather than the portal name
|
||||
if hint_string == portal.name:
|
||||
hint_string = portal.region
|
||||
# library exterior is two regions, we just want to fix up the name
|
||||
if hint_string in {"Library Exterior Tree", "Library Exterior Ladder"}:
|
||||
hint_string = "Library Exterior"
|
||||
|
||||
# search through the list for the other end of the hallway
|
||||
for portala, portalb in portal_pairs.items():
|
||||
if portala.scene_destination() == hallways[portal.scene_destination()]:
|
||||
# if we find that we have a chain of hallways, do recursion
|
||||
if portalb.scene_destination() in hallways:
|
||||
hint_region = portalb.region
|
||||
if hint_region in {"Library Exterior Tree", "Library Exterior Ladder"}:
|
||||
hint_region = "Library Exterior"
|
||||
hint_string = hint_region + " then " + hint_string
|
||||
hint_string = hint_helper(portalb, hint_string)
|
||||
else:
|
||||
# if we didn't find a chain, get the portal name for the end of the chain
|
||||
hint_string = portalb.name + " then " + hint_string
|
||||
return hint_string
|
||||
# and then the same thing for the other portal, since we have to check each separately
|
||||
if portalb.scene_destination() == hallways[portal.scene_destination()]:
|
||||
if portala.scene_destination() in hallways:
|
||||
hint_region = portala.region
|
||||
if hint_region in {"Library Exterior Tree", "Library Exterior Ladder"}:
|
||||
hint_region = "Library Exterior"
|
||||
hint_string = hint_region + " then " + hint_string
|
||||
hint_string = hint_helper(portala, hint_string)
|
||||
else:
|
||||
hint_string = portala.name + " then " + hint_string
|
||||
return hint_string
|
||||
return hint_string
|
||||
|
||||
# create our regions, give them hint text if they're in a spot where it makes sense to
|
||||
# we're limiting which ones get hints so that it still gets that ER feel with a little less BS
|
||||
for region_name, region_data in tunic_er_regions.items():
|
||||
hint_text = "error"
|
||||
if region_data.hint == 1:
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
if portal1.region == region_name:
|
||||
hint_text = hint_helper(portal2)
|
||||
break
|
||||
if portal2.region == region_name:
|
||||
hint_text = hint_helper(portal1)
|
||||
break
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld, hint_text)
|
||||
elif region_data.hint == 2:
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
if portal1.scene() == tunic_er_regions[region_name].game_scene:
|
||||
hint_text = hint_helper(portal2)
|
||||
break
|
||||
if portal2.scene() == tunic_er_regions[region_name].game_scene:
|
||||
hint_text = hint_helper(portal1)
|
||||
break
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld, hint_text)
|
||||
elif region_data.hint == 3:
|
||||
# west garden portal item is at a dead end in restricted, otherwise just in west garden
|
||||
if region_name == "West Garden Portal Item":
|
||||
if world.options.logic_rules:
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
if portal1.scene() == "Archipelagos Redux":
|
||||
hint_text = hint_helper(portal2)
|
||||
break
|
||||
if portal2.scene() == "Archipelagos Redux":
|
||||
hint_text = hint_helper(portal1)
|
||||
break
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld, hint_text)
|
||||
else:
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
if portal1.region == "West Garden Portal":
|
||||
hint_text = hint_helper(portal2)
|
||||
break
|
||||
if portal2.region == "West Garden Portal":
|
||||
hint_text = hint_helper(portal1)
|
||||
break
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld, hint_text)
|
||||
else:
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld)
|
||||
regions[region_name] = Region(region_name, world.player, world.multiworld)
|
||||
|
||||
set_er_region_rules(world, world.ability_unlocks, regions, portal_pairs)
|
||||
|
||||
er_hint_data: Dict[int, str] = {}
|
||||
for location_name, location_id in world.location_name_to_id.items():
|
||||
region = regions[location_table[location_name].er_region]
|
||||
location = TunicERLocation(world.player, location_name, location_id, region)
|
||||
region.locations.append(location)
|
||||
if region.name == region.hint_text:
|
||||
continue
|
||||
er_hint_data[location.address] = region.hint_text
|
||||
|
||||
create_randomized_entrances(portal_pairs, regions)
|
||||
|
||||
@@ -145,14 +53,12 @@ def create_er_regions(world: "TunicWorld") -> Tuple[Dict[Portal, Portal], Dict[i
|
||||
world.multiworld.completion_condition[world.player] = lambda state: state.has("Victory", world.player)
|
||||
victory_region.locations.append(victory_location)
|
||||
|
||||
portals_and_hints = (portal_pairs, er_hint_data)
|
||||
|
||||
return portals_and_hints
|
||||
return portal_pairs
|
||||
|
||||
|
||||
tunic_events: Dict[str, str] = {
|
||||
"Eastern Bell": "Forest Belltower Upper",
|
||||
"Western Bell": "Overworld Belltower",
|
||||
"Western Bell": "Overworld Belltower at Bell",
|
||||
"Furnace Fuse": "Furnace Fuse",
|
||||
"South and West Fortress Exterior Fuses": "Fortress Exterior from Overworld",
|
||||
"Upper and Central Fortress Exterior Fuses": "Fortress Courtyard Upper",
|
||||
@@ -163,7 +69,7 @@ tunic_events: Dict[str, str] = {
|
||||
"Quarry Fuse": "Quarry",
|
||||
"Ziggurat Fuse": "Rooted Ziggurat Lower Back",
|
||||
"West Garden Fuse": "West Garden",
|
||||
"Library Fuse": "Library Lab",
|
||||
"Library Fuse": "Library Lab"
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +86,38 @@ def place_event_items(world: "TunicWorld", regions: Dict[str, Region]) -> None:
|
||||
region.locations.append(location)
|
||||
|
||||
|
||||
def vanilla_portals() -> Dict[Portal, Portal]:
|
||||
portal_pairs: Dict[Portal, Portal] = {}
|
||||
portal_map = portal_mapping.copy()
|
||||
shop_num = 1
|
||||
|
||||
while portal_map:
|
||||
portal1 = portal_map[0]
|
||||
portal2 = None
|
||||
# portal2 scene destination tag is portal1's destination scene tag
|
||||
portal2_sdt = portal1.destination_scene()
|
||||
|
||||
if portal2_sdt.startswith("Shop,"):
|
||||
portal2 = Portal(name=f"Shop", region="Shop",
|
||||
destination="Previous Region", tag="_")
|
||||
shop_num += 1
|
||||
|
||||
if portal2_sdt == "Purgatory, Purgatory_bottom":
|
||||
portal2_sdt = "Purgatory, Purgatory_top"
|
||||
|
||||
for portal in portal_map:
|
||||
if portal.scene_destination() == portal2_sdt:
|
||||
portal2 = portal
|
||||
break
|
||||
|
||||
portal_pairs[portal1] = portal2
|
||||
portal_map.remove(portal1)
|
||||
if not portal2_sdt.startswith("Shop,"):
|
||||
portal_map.remove(portal2)
|
||||
|
||||
return portal_pairs
|
||||
|
||||
|
||||
# pairing off portals, starting with dead ends
|
||||
def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||
# separate the portals into dead ends and non-dead ends
|
||||
@@ -290,7 +228,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||
break
|
||||
if p_exit in ["Shop Portal", "Shop"]:
|
||||
portal2 = Portal(name="Shop Portal", region=f"Shop",
|
||||
destination="Previous Region_")
|
||||
destination="Previous Region", tag="_")
|
||||
shop_count -= 1
|
||||
if shop_count < 0:
|
||||
shop_count += 2
|
||||
@@ -355,10 +293,12 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||
if portal.scene_destination() == "Overworld Redux, Windmill_":
|
||||
portal1 = portal
|
||||
break
|
||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region_")
|
||||
if not portal1:
|
||||
raise Exception(f"Failed to do Fixed Shop option. "
|
||||
f"Did {player_name} plando connection the Windmill Shop entrance?")
|
||||
|
||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region", tag="_")
|
||||
|
||||
portal_pairs[portal1] = portal2
|
||||
two_plus.remove(portal1)
|
||||
|
||||
@@ -433,7 +373,8 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||
break
|
||||
if portal1 is None:
|
||||
raise Exception("Too many shops in the pool, or something else went wrong.")
|
||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region_")
|
||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region", tag="_")
|
||||
|
||||
portal_pairs[portal1] = portal2
|
||||
|
||||
# connect dead ends to random non-dead ends
|
||||
@@ -465,10 +406,10 @@ def create_randomized_entrances(portal_pairs: Dict[Portal, Portal], regions: Dic
|
||||
for portal1, portal2 in portal_pairs.items():
|
||||
region1 = regions[portal1.region]
|
||||
region2 = regions[portal2.region]
|
||||
region1.connect(region2, f"{portal1.name} -> {portal2.name}")
|
||||
region1.connect(connecting_region=region2, name=portal1.name)
|
||||
# prevent the logic from thinking you can get to any shop-connected region from the shop
|
||||
if not portal2.name.startswith("Shop"):
|
||||
region2.connect(region1, f"{portal2.name} -> {portal1.name}")
|
||||
if portal2.name not in {"Shop", "Shop Portal"}:
|
||||
region2.connect(connecting_region=region1, name=portal2.name)
|
||||
|
||||
|
||||
# loop through the static connections, return regions you can reach from this region
|
||||
@@ -519,8 +460,8 @@ def gate_before_switch(check_portal: Portal, two_plus: List[Portal]) -> bool:
|
||||
return True
|
||||
|
||||
# fortress teleporter needs only the left fuses
|
||||
elif check_portal.scene_destination() in ["Fortress Arena, Transit_teleporter_spidertank",
|
||||
"Transit, Fortress Arena_teleporter_spidertank"]:
|
||||
elif check_portal.scene_destination() in {"Fortress Arena, Transit_teleporter_spidertank",
|
||||
"Transit, Fortress Arena_teleporter_spidertank"}:
|
||||
i = j = k = 0
|
||||
for portal in two_plus:
|
||||
if portal.scene() == "Fortress Courtyard":
|
||||
@@ -537,7 +478,8 @@ def gate_before_switch(check_portal: Portal, two_plus: List[Portal]) -> bool:
|
||||
elif check_portal.scene_destination() == "Swamp Redux 2, Cathedral Redux_main":
|
||||
i = 0
|
||||
for portal in two_plus:
|
||||
if portal.region == "Swamp":
|
||||
if portal.region in {"Swamp Front", "Swamp to Cathedral Treasure Room",
|
||||
"Swamp to Cathedral Main Entrance Region"}:
|
||||
i += 1
|
||||
if i == 4:
|
||||
return True
|
||||
@@ -553,8 +495,8 @@ def gate_before_switch(check_portal: Portal, two_plus: List[Portal]) -> bool:
|
||||
|
||||
# Quarry teleporter needs you to hit the Darkwoods fuse
|
||||
# Since it's physically in Quarry, we don't need to check for it
|
||||
elif check_portal.scene_destination() in ["Quarry Redux, Transit_teleporter_quarry teleporter",
|
||||
"Quarry Redux, ziggurat2020_0_"]:
|
||||
elif check_portal.scene_destination() in {"Quarry Redux, Transit_teleporter_quarry teleporter",
|
||||
"Quarry Redux, ziggurat2020_0_"}:
|
||||
i = 0
|
||||
for portal in two_plus:
|
||||
if portal.scene() == "Darkwoods Tunnel":
|
||||
|
||||
@@ -143,6 +143,28 @@ item_table: Dict[str, TunicItemData] = {
|
||||
"Pages 50-51": TunicItemData(ItemClassification.useful, 1, 127, "pages"),
|
||||
"Pages 52-53 (Icebolt)": TunicItemData(ItemClassification.progression, 1, 128, "pages"),
|
||||
"Pages 54-55": TunicItemData(ItemClassification.useful, 1, 129, "pages"),
|
||||
|
||||
"Ladders near Weathervane": TunicItemData(ItemClassification.progression, 0, 130, "ladders"),
|
||||
"Ladders near Overworld Checkpoint": TunicItemData(ItemClassification.progression, 0, 131, "ladders"),
|
||||
"Ladders near Patrol Cave": TunicItemData(ItemClassification.progression, 0, 132, "ladders"),
|
||||
"Ladder near Temple Rafters": TunicItemData(ItemClassification.progression, 0, 133, "ladders"),
|
||||
"Ladders near Dark Tomb": TunicItemData(ItemClassification.progression, 0, 134, "ladders"),
|
||||
"Ladder to Quarry": TunicItemData(ItemClassification.progression, 0, 135, "ladders"),
|
||||
"Ladders to West Bell": TunicItemData(ItemClassification.progression, 0, 136, "ladders"),
|
||||
"Ladders in Overworld Town": TunicItemData(ItemClassification.progression, 0, 137, "ladders"),
|
||||
"Ladder to Ruined Atoll": TunicItemData(ItemClassification.progression, 0, 138, "ladders"),
|
||||
"Ladder to Swamp": TunicItemData(ItemClassification.progression, 0, 139, "ladders"),
|
||||
"Ladders in Well": TunicItemData(ItemClassification.progression, 0, 140, "ladders"),
|
||||
"Ladder in Dark Tomb": TunicItemData(ItemClassification.progression, 0, 141, "ladders"),
|
||||
"Ladder to East Forest": TunicItemData(ItemClassification.progression, 0, 142, "ladders"),
|
||||
"Ladders to Lower Forest": TunicItemData(ItemClassification.progression, 0, 143, "ladders"),
|
||||
"Ladder to Beneath the Vault": TunicItemData(ItemClassification.progression, 0, 144, "ladders"),
|
||||
"Ladders in Hourglass Cave": TunicItemData(ItemClassification.progression, 0, 145, "ladders"),
|
||||
"Ladders in South Atoll": TunicItemData(ItemClassification.progression, 0, 146, "ladders"),
|
||||
"Ladders to Frog's Domain": TunicItemData(ItemClassification.progression, 0, 147, "ladders"),
|
||||
"Ladders in Library": TunicItemData(ItemClassification.progression, 0, 148, "ladders"),
|
||||
"Ladders in Lower Quarry": TunicItemData(ItemClassification.progression, 0, 149, "ladders"),
|
||||
"Ladders in Swamp": TunicItemData(ItemClassification.progression, 0, 150, "ladders"),
|
||||
}
|
||||
|
||||
fool_tiers: List[List[str]] = [
|
||||
@@ -209,7 +231,9 @@ extra_groups: Dict[str, Set[str]] = {
|
||||
"melee weapons": {"Stick", "Sword", "Sword Upgrade"},
|
||||
"progressive sword": {"Sword Upgrade"},
|
||||
"abilities": {"Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)", "Pages 52-53 (Icebolt)"},
|
||||
"questagons": {"Red Questagon", "Green Questagon", "Blue Questagon", "Gold Questagon"}
|
||||
"questagons": {"Red Questagon", "Green Questagon", "Blue Questagon", "Gold Questagon"},
|
||||
"ladder to atoll": {"Ladder to Ruined Atoll"}, # fuzzy matching made it hint Ladders in Well, now it won't
|
||||
"ladders to bell": {"Ladders to West Bell"},
|
||||
}
|
||||
|
||||
item_name_groups.update(extra_groups)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from typing import Dict, NamedTuple, Set
|
||||
from itertools import groupby
|
||||
from typing import Dict, NamedTuple, Set, Optional, List
|
||||
|
||||
|
||||
class TunicLocationData(NamedTuple):
|
||||
region: str
|
||||
er_region: str # entrance rando region
|
||||
location_group: str = "region"
|
||||
location_group: Optional[str] = None
|
||||
location_groups: Optional[List[str]] = None
|
||||
|
||||
|
||||
location_base_id = 509342400
|
||||
@@ -22,10 +22,10 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Beneath the Well - [Back Corridor] Right Secret": TunicLocationData("Beneath the Well", "Beneath the Well Main"),
|
||||
"Beneath the Well - [Back Corridor] Left Secret": TunicLocationData("Beneath the Well", "Beneath the Well Main"),
|
||||
"Beneath the Well - [Second Room] Obscured Behind Waterfall": TunicLocationData("Beneath the Well", "Beneath the Well Main"),
|
||||
"Beneath the Well - [Side Room] Chest By Pots": TunicLocationData("Beneath the Well", "Beneath the Well Main"),
|
||||
"Beneath the Well - [Side Room] Chest By Pots": TunicLocationData("Beneath the Well", "Beneath the Well Back"),
|
||||
"Beneath the Well - [Side Room] Chest By Phrends": TunicLocationData("Beneath the Well", "Beneath the Well Back"),
|
||||
"Beneath the Well - [Second Room] Page": TunicLocationData("Beneath the Well", "Beneath the Well Main"),
|
||||
"Dark Tomb Checkpoint - [Passage To Dark Tomb] Page Pickup": TunicLocationData("Beneath the Well", "Dark Tomb Checkpoint"),
|
||||
"Dark Tomb Checkpoint - [Passage To Dark Tomb] Page Pickup": TunicLocationData("Overworld", "Dark Tomb Checkpoint"),
|
||||
"Cathedral - [1F] Guarded By Lasers": TunicLocationData("Cathedral", "Cathedral"),
|
||||
"Cathedral - [1F] Near Spikes": TunicLocationData("Cathedral", "Cathedral"),
|
||||
"Cathedral - [2F] Bird Room": TunicLocationData("Cathedral", "Cathedral"),
|
||||
@@ -39,25 +39,25 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Dark Tomb - 2nd Laser Room": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Dark Tomb - 1st Laser Room": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Dark Tomb - Spike Maze Upper Walkway": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Dark Tomb - Skulls Chest": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Dark Tomb - Skulls Chest": TunicLocationData("Dark Tomb", "Dark Tomb Upper"),
|
||||
"Dark Tomb - Spike Maze Near Stairs": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Dark Tomb - 1st Laser Room Obscured": TunicLocationData("Dark Tomb", "Dark Tomb Main"),
|
||||
"Guardhouse 2 - Upper Floor": TunicLocationData("East Forest", "Guard House 2"),
|
||||
"Guardhouse 2 - Bottom Floor Secret": TunicLocationData("East Forest", "Guard House 2"),
|
||||
"Guardhouse 2 - Upper Floor": TunicLocationData("East Forest", "Guard House 2 Upper"),
|
||||
"Guardhouse 2 - Bottom Floor Secret": TunicLocationData("East Forest", "Guard House 2 Lower"),
|
||||
"Guardhouse 1 - Upper Floor Obscured": TunicLocationData("East Forest", "Guard House 1 East"),
|
||||
"Guardhouse 1 - Upper Floor": TunicLocationData("East Forest", "Guard House 1 East"),
|
||||
"East Forest - Dancing Fox Spirit Holy Cross": TunicLocationData("East Forest", "East Forest Dance Fox Spot", "holy cross"),
|
||||
"East Forest - Golden Obelisk Holy Cross": TunicLocationData("East Forest", "East Forest", "holy cross"),
|
||||
"East Forest - Dancing Fox Spirit Holy Cross": TunicLocationData("East Forest", "East Forest Dance Fox Spot", location_group="holy cross"),
|
||||
"East Forest - Golden Obelisk Holy Cross": TunicLocationData("East Forest", "Lower Forest", location_group="holy cross"),
|
||||
"East Forest - Ice Rod Grapple Chest": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Above Save Point": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Above Save Point Obscured": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - From Guardhouse 1 Chest": TunicLocationData("East Forest", "East Forest Dance Fox Spot"),
|
||||
"East Forest - Near Save Point": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Beneath Spider Chest": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Beneath Spider Chest": TunicLocationData("East Forest", "Lower Forest"),
|
||||
"East Forest - Near Telescope": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Spider Chest": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Lower Dash Chest": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Lower Grapple Chest": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Spider Chest": TunicLocationData("East Forest", "Lower Forest"),
|
||||
"East Forest - Lower Dash Chest": TunicLocationData("East Forest", "Lower Forest"),
|
||||
"East Forest - Lower Grapple Chest": TunicLocationData("East Forest", "Lower Forest"),
|
||||
"East Forest - Bombable Wall": TunicLocationData("East Forest", "East Forest"),
|
||||
"East Forest - Page On Teleporter": TunicLocationData("East Forest", "East Forest"),
|
||||
"Forest Belltower - Near Save Point": TunicLocationData("East Forest", "Forest Belltower Lower"),
|
||||
@@ -65,18 +65,18 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Forest Belltower - Obscured Near Bell Top Floor": TunicLocationData("East Forest", "Forest Belltower Upper"),
|
||||
"Forest Belltower - Obscured Beneath Bell Bottom Floor": TunicLocationData("East Forest", "Forest Belltower Main"),
|
||||
"Forest Belltower - Page Pickup": TunicLocationData("East Forest", "Forest Belltower Main"),
|
||||
"Forest Grave Path - Holy Cross Code by Grave": TunicLocationData("East Forest", "Forest Grave Path by Grave", "holy cross"),
|
||||
"Forest Grave Path - Holy Cross Code by Grave": TunicLocationData("East Forest", "Forest Grave Path by Grave", location_group="holy cross"),
|
||||
"Forest Grave Path - Above Gate": TunicLocationData("East Forest", "Forest Grave Path Main"),
|
||||
"Forest Grave Path - Obscured Chest": TunicLocationData("East Forest", "Forest Grave Path Main"),
|
||||
"Forest Grave Path - Upper Walkway": TunicLocationData("East Forest", "Forest Grave Path Upper"),
|
||||
"Forest Grave Path - Sword Pickup": TunicLocationData("East Forest", "Forest Grave Path by Grave"),
|
||||
"Hero's Grave - Tooth Relic": TunicLocationData("East Forest", "Hero Relic - East Forest"),
|
||||
"Hero's Grave - Tooth Relic": TunicLocationData("East Forest", "Hero Relic - East Forest", location_group="hero relic"),
|
||||
"Fortress Courtyard - From East Belltower": TunicLocationData("East Forest", "Fortress Exterior from East Forest"),
|
||||
"Fortress Leaf Piles - Secret Chest": TunicLocationData("Eastern Vault Fortress", "Fortress Leaf Piles"),
|
||||
"Fortress Arena - Hexagon Red": TunicLocationData("Eastern Vault Fortress", "Fortress Arena"),
|
||||
"Fortress Arena - Siege Engine/Vault Key Pickup": TunicLocationData("Eastern Vault Fortress", "Fortress Arena"),
|
||||
"Fortress Arena - Siege Engine/Vault Key Pickup": TunicLocationData("Eastern Vault Fortress", "Fortress Arena", location_group="bosses"),
|
||||
"Fortress East Shortcut - Chest Near Slimes": TunicLocationData("Eastern Vault Fortress", "Fortress East Shortcut Lower"),
|
||||
"Eastern Vault Fortress - [West Wing] Candles Holy Cross": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress", "holy cross"),
|
||||
"Eastern Vault Fortress - [West Wing] Candles Holy Cross": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress", location_group="holy cross"),
|
||||
"Eastern Vault Fortress - [West Wing] Dark Room Chest 1": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"),
|
||||
"Eastern Vault Fortress - [West Wing] Dark Room Chest 2": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"),
|
||||
"Eastern Vault Fortress - [East Wing] Bombable Wall": TunicLocationData("Eastern Vault Fortress", "Eastern Vault Fortress"),
|
||||
@@ -84,7 +84,7 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Fortress Grave Path - Upper Walkway": TunicLocationData("Eastern Vault Fortress", "Fortress Grave Path Upper"),
|
||||
"Fortress Grave Path - Chest Right of Grave": TunicLocationData("Eastern Vault Fortress", "Fortress Grave Path"),
|
||||
"Fortress Grave Path - Obscured Chest Left of Grave": TunicLocationData("Eastern Vault Fortress", "Fortress Grave Path"),
|
||||
"Hero's Grave - Flowers Relic": TunicLocationData("Eastern Vault Fortress", "Hero Relic - Fortress"),
|
||||
"Hero's Grave - Flowers Relic": TunicLocationData("Eastern Vault Fortress", "Hero Relic - Fortress", location_group="hero relic"),
|
||||
"Beneath the Fortress - Bridge": TunicLocationData("Beneath the Vault", "Beneath the Vault Back"),
|
||||
"Beneath the Fortress - Cell Chest 1": TunicLocationData("Beneath the Vault", "Beneath the Vault Back"),
|
||||
"Beneath the Fortress - Obscured Behind Waterfall": TunicLocationData("Beneath the Vault", "Beneath the Vault Front"),
|
||||
@@ -101,8 +101,8 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Frog's Domain - Side Room Chest": TunicLocationData("Frog's Domain", "Frog's Domain"),
|
||||
"Frog's Domain - Side Room Grapple Secret": TunicLocationData("Frog's Domain", "Frog's Domain"),
|
||||
"Frog's Domain - Magic Orb Pickup": TunicLocationData("Frog's Domain", "Frog's Domain"),
|
||||
"Librarian - Hexagon Green": TunicLocationData("Library", "Library Arena"),
|
||||
"Library Hall - Holy Cross Chest": TunicLocationData("Library", "Library Hall", "holy cross"),
|
||||
"Librarian - Hexagon Green": TunicLocationData("Library", "Library Arena", location_group="bosses"),
|
||||
"Library Hall - Holy Cross Chest": TunicLocationData("Library", "Library Hall", location_group="holy cross"),
|
||||
"Library Lab - Chest By Shrine 2": TunicLocationData("Library", "Library Lab"),
|
||||
"Library Lab - Chest By Shrine 1": TunicLocationData("Library", "Library Lab"),
|
||||
"Library Lab - Chest By Shrine 3": TunicLocationData("Library", "Library Lab"),
|
||||
@@ -110,7 +110,7 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Library Lab - Page 3": TunicLocationData("Library", "Library Lab"),
|
||||
"Library Lab - Page 1": TunicLocationData("Library", "Library Lab"),
|
||||
"Library Lab - Page 2": TunicLocationData("Library", "Library Lab"),
|
||||
"Hero's Grave - Mushroom Relic": TunicLocationData("Library", "Hero Relic - Library"),
|
||||
"Hero's Grave - Mushroom Relic": TunicLocationData("Library", "Hero Relic - Library", location_group="hero relic"),
|
||||
"Lower Mountain - Page Before Door": TunicLocationData("Overworld", "Lower Mountain"),
|
||||
"Changing Room - Normal Chest": TunicLocationData("Overworld", "Changing Room"),
|
||||
"Fortress Courtyard - Chest Near Cave": TunicLocationData("Overworld", "Fortress Exterior near cave"),
|
||||
@@ -122,42 +122,42 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Old House - Normal Chest": TunicLocationData("Overworld", "Old House Front"),
|
||||
"Old House - Shield Pickup": TunicLocationData("Overworld", "Old House Front"),
|
||||
"Overworld - [West] Obscured Behind Windmill": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [South] Beach Chest": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [South] Beach Chest": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [West] Obscured Near Well": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Central] Bombable Wall": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Near Turret": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Chest Near Pots": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Near Golden Obelisk": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Chest Near Pots": TunicLocationData("Overworld", "East Overworld"),
|
||||
"Overworld - [Northwest] Chest Near Golden Obelisk": TunicLocationData("Overworld", "Overworld above Quarry Entrance"),
|
||||
"Overworld - [Southwest] South Chest Near Guard": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] West Beach Guarded By Turret": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] West Beach Guarded By Turret": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Southwest] Chest Guarded By Turret": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Shadowy Corner Chest": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Obscured In Tunnel To Beach": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Grapple Chest Over Walkway": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Beneath Quarry Gate": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southeast] Chest Near Swamp": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] From West Garden": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Grapple Chest": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] West Beach Guarded By Turret 2": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Beach Chest Near Flowers": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Beneath Quarry Gate": TunicLocationData("Overworld", "Overworld after Envoy"),
|
||||
"Overworld - [Southeast] Chest Near Swamp": TunicLocationData("Overworld", "Overworld Swamp Lower Entry"),
|
||||
"Overworld - [Southwest] From West Garden": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [East] Grapple Chest": TunicLocationData("Overworld", "Overworld above Patrol Cave"),
|
||||
"Overworld - [Southwest] West Beach Guarded By Turret 2": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Southwest] Beach Chest Near Flowers": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Southwest] Bombable Wall Near Fountain": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [West] Chest After Bell": TunicLocationData("Overworld", "Overworld Belltower"),
|
||||
"Overworld - [Southwest] Tunnel Guarded By Turret": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Between Ladders Near Ruined Passage": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northeast] Chest Above Patrol Cave": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Beach Chest Beneath Guard": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Tunnel Guarded By Turret": TunicLocationData("Overworld", "Overworld Tunnel Turret"),
|
||||
"Overworld - [East] Between Ladders Near Ruined Passage": TunicLocationData("Overworld", "Above Ruined Passage"),
|
||||
"Overworld - [Northeast] Chest Above Patrol Cave": TunicLocationData("Overworld", "Upper Overworld"),
|
||||
"Overworld - [Southwest] Beach Chest Beneath Guard": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Central] Chest Across From Well": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Near Quarry Gate": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Chest In Trees": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Chest In Trees": TunicLocationData("Overworld", "Above Ruined Passage"),
|
||||
"Overworld - [West] Chest Behind Moss Wall": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [South] Beach Page": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [South] Beach Page": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Southeast] Page on Pillar by Swamp": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Key Pickup": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [West] Key Pickup": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Page Near Secret Shop": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [East] Page Near Secret Shop": TunicLocationData("Overworld", "East Overworld"),
|
||||
"Overworld - [Southwest] Fountain Page": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Page on Pillar by Dark Tomb": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Fire Wand Pickup": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Fire Wand Pickup": TunicLocationData("Overworld", "Upper Overworld"),
|
||||
"Overworld - [West] Page On Teleporter": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Page By Well": TunicLocationData("Overworld", "Overworld"),
|
||||
"Patrol Cave - Normal Chest": TunicLocationData("Overworld", "Patrol Cave"),
|
||||
@@ -165,49 +165,49 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Ruined Shop - Chest 2": TunicLocationData("Overworld", "Ruined Shop"),
|
||||
"Ruined Shop - Chest 3": TunicLocationData("Overworld", "Ruined Shop"),
|
||||
"Ruined Passage - Page Pickup": TunicLocationData("Overworld", "Ruined Passage"),
|
||||
"Shop - Potion 1": TunicLocationData("Overworld", "Shop", "shop"),
|
||||
"Shop - Potion 2": TunicLocationData("Overworld", "Shop", "shop"),
|
||||
"Shop - Coin 1": TunicLocationData("Overworld", "Shop", "shop"),
|
||||
"Shop - Coin 2": TunicLocationData("Overworld", "Shop", "shop"),
|
||||
"Shop - Potion 1": TunicLocationData("Overworld", "Shop", location_group="shop"),
|
||||
"Shop - Potion 2": TunicLocationData("Overworld", "Shop", location_group="shop"),
|
||||
"Shop - Coin 1": TunicLocationData("Overworld", "Shop", location_group="shop"),
|
||||
"Shop - Coin 2": TunicLocationData("Overworld", "Shop", location_group="shop"),
|
||||
"Special Shop - Secret Page Pickup": TunicLocationData("Overworld", "Special Shop"),
|
||||
"Stick House - Stick Chest": TunicLocationData("Overworld", "Stick House"),
|
||||
"Sealed Temple - Page Pickup": TunicLocationData("Overworld", "Sealed Temple"),
|
||||
"Hourglass Cave - Hourglass Chest": TunicLocationData("Overworld", "Hourglass Cave"),
|
||||
"Far Shore - Secret Chest": TunicLocationData("Overworld", "Far Shore"),
|
||||
"Far Shore - Page Pickup": TunicLocationData("Overworld", "Far Shore to Spawn"),
|
||||
"Coins in the Well - 10 Coins": TunicLocationData("Overworld", "Overworld", "well"),
|
||||
"Coins in the Well - 15 Coins": TunicLocationData("Overworld", "Overworld", "well"),
|
||||
"Coins in the Well - 3 Coins": TunicLocationData("Overworld", "Overworld", "well"),
|
||||
"Coins in the Well - 6 Coins": TunicLocationData("Overworld", "Overworld", "well"),
|
||||
"Secret Gathering Place - 20 Fairy Reward": TunicLocationData("Overworld", "Secret Gathering Place", "fairies"),
|
||||
"Secret Gathering Place - 10 Fairy Reward": TunicLocationData("Overworld", "Secret Gathering Place", "fairies"),
|
||||
"Overworld - [West] Moss Wall Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [Southwest] Flowers Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [Southwest] Fountain Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [Northeast] Flowers Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [East] Weathervane Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [West] Windmill Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [Southwest] Haiku Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [West] Windchimes Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [South] Starting Platform Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Overworld - [Northwest] Golden Obelisk Page": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", "holy cross"),
|
||||
"Old House - Holy Cross Door Page": TunicLocationData("Overworld Holy Cross", "Old House Back", "holy cross"),
|
||||
"Cube Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Cube Cave", "holy cross"),
|
||||
"Southeast Cross Door - Chest 3": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", "holy cross"),
|
||||
"Southeast Cross Door - Chest 2": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", "holy cross"),
|
||||
"Southeast Cross Door - Chest 1": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", "holy cross"),
|
||||
"Maze Cave - Maze Room Holy Cross": TunicLocationData("Overworld Holy Cross", "Maze Cave", "holy cross"),
|
||||
"Caustic Light Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Caustic Light Cave", "holy cross"),
|
||||
"Old House - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Old House Front", "holy cross"),
|
||||
"Patrol Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Patrol Cave", "holy cross"),
|
||||
"Ruined Passage - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Ruined Passage", "holy cross"),
|
||||
"Hourglass Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Hourglass Cave", "holy cross"),
|
||||
"Sealed Temple - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Sealed Temple", "holy cross"),
|
||||
"Fountain Cross Door - Page Pickup": TunicLocationData("Overworld Holy Cross", "Fountain Cross Room", "holy cross"),
|
||||
"Secret Gathering Place - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Secret Gathering Place", "holy cross"),
|
||||
"Top of the Mountain - Page At The Peak": TunicLocationData("Overworld Holy Cross", "Top of the Mountain", "holy cross"),
|
||||
"Far Shore - Page Pickup": TunicLocationData("Overworld", "Far Shore to Spawn Region"),
|
||||
"Coins in the Well - 10 Coins": TunicLocationData("Overworld", "Overworld", location_group="well"),
|
||||
"Coins in the Well - 15 Coins": TunicLocationData("Overworld", "Overworld", location_group="well"),
|
||||
"Coins in the Well - 3 Coins": TunicLocationData("Overworld", "Overworld", location_group="well"),
|
||||
"Coins in the Well - 6 Coins": TunicLocationData("Overworld", "Overworld", location_group="well"),
|
||||
"Secret Gathering Place - 20 Fairy Reward": TunicLocationData("Overworld", "Secret Gathering Place", location_group="fairies"),
|
||||
"Secret Gathering Place - 10 Fairy Reward": TunicLocationData("Overworld", "Secret Gathering Place", location_group="fairies"),
|
||||
"Overworld - [West] Moss Wall Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", location_group="holy cross"),
|
||||
"Overworld - [Southwest] Flowers Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Beach", location_group="holy cross"),
|
||||
"Overworld - [Southwest] Fountain Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", location_group="holy cross"),
|
||||
"Overworld - [Northeast] Flowers Holy Cross": TunicLocationData("Overworld Holy Cross", "East Overworld", location_group="holy cross"),
|
||||
"Overworld - [East] Weathervane Holy Cross": TunicLocationData("Overworld Holy Cross", "East Overworld", location_group="holy cross"),
|
||||
"Overworld - [West] Windmill Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", location_group="holy cross"),
|
||||
"Overworld - [Southwest] Haiku Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Beach", location_group="holy cross"),
|
||||
"Overworld - [West] Windchimes Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", location_group="holy cross"),
|
||||
"Overworld - [South] Starting Platform Holy Cross": TunicLocationData("Overworld Holy Cross", "Overworld Holy Cross", location_group="holy cross"),
|
||||
"Overworld - [Northwest] Golden Obelisk Page": TunicLocationData("Overworld Holy Cross", "Upper Overworld", location_group="holy cross"),
|
||||
"Old House - Holy Cross Door Page": TunicLocationData("Overworld Holy Cross", "Old House Back", location_group="holy cross"),
|
||||
"Cube Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Cube Cave", location_group="holy cross"),
|
||||
"Southeast Cross Door - Chest 3": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", location_group="holy cross"),
|
||||
"Southeast Cross Door - Chest 2": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", location_group="holy cross"),
|
||||
"Southeast Cross Door - Chest 1": TunicLocationData("Overworld Holy Cross", "Southeast Cross Room", location_group="holy cross"),
|
||||
"Maze Cave - Maze Room Holy Cross": TunicLocationData("Overworld Holy Cross", "Maze Cave", location_group="holy cross"),
|
||||
"Caustic Light Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Caustic Light Cave", location_group="holy cross"),
|
||||
"Old House - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Old House Front", location_group="holy cross"),
|
||||
"Patrol Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Patrol Cave", location_group="holy cross"),
|
||||
"Ruined Passage - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Ruined Passage", location_group="holy cross"),
|
||||
"Hourglass Cave - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Hourglass Cave Tower", location_group="holy cross"),
|
||||
"Sealed Temple - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Sealed Temple", location_group="holy cross"),
|
||||
"Fountain Cross Door - Page Pickup": TunicLocationData("Overworld Holy Cross", "Fountain Cross Room", location_group="holy cross"),
|
||||
"Secret Gathering Place - Holy Cross Chest": TunicLocationData("Overworld Holy Cross", "Secret Gathering Place", location_group="holy cross"),
|
||||
"Top of the Mountain - Page At The Peak": TunicLocationData("Overworld Holy Cross", "Top of the Mountain", location_group="holy cross"),
|
||||
"Monastery - Monastery Chest": TunicLocationData("Quarry", "Monastery Back"),
|
||||
"Quarry - [Back Entrance] Bushes Holy Cross": TunicLocationData("Quarry Back", "Quarry Back", "holy cross"),
|
||||
"Quarry - [Back Entrance] Bushes Holy Cross": TunicLocationData("Quarry Back", "Quarry Back", location_group="holy cross"),
|
||||
"Quarry - [Back Entrance] Chest": TunicLocationData("Quarry Back", "Quarry Back"),
|
||||
"Quarry - [Central] Near Shortcut Ladder": TunicLocationData("Quarry", "Quarry"),
|
||||
"Quarry - [East] Near Telescope": TunicLocationData("Quarry", "Quarry"),
|
||||
@@ -225,16 +225,16 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Quarry - [Central] Above Ladder Dash Chest": TunicLocationData("Quarry", "Quarry Monastery Entry"),
|
||||
"Quarry - [West] Upper Area Bombable Wall": TunicLocationData("Quarry Back", "Quarry Back"),
|
||||
"Quarry - [East] Bombable Wall": TunicLocationData("Quarry", "Quarry"),
|
||||
"Hero's Grave - Ash Relic": TunicLocationData("Quarry", "Hero Relic - Quarry"),
|
||||
"Hero's Grave - Ash Relic": TunicLocationData("Quarry", "Hero Relic - Quarry", location_group="hero relics"),
|
||||
"Quarry - [West] Shooting Range Secret Path": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [West] Near Shooting Range": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [West] Below Shooting Range": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Below Broken Ladder": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Below Broken Ladder": TunicLocationData("Lower Quarry", "Even Lower Quarry"),
|
||||
"Quarry - [West] Upper Area Near Waterfall": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Upper Walkway": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Upper Walkway": TunicLocationData("Lower Quarry", "Even Lower Quarry"),
|
||||
"Quarry - [West] Lower Area Below Bridge": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [West] Lower Area Isolated Chest": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Near Elevator": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Quarry - [Lowlands] Near Elevator": TunicLocationData("Lower Quarry", "Even Lower Quarry"),
|
||||
"Quarry - [West] Lower Area After Bridge": TunicLocationData("Lower Quarry", "Lower Quarry"),
|
||||
"Rooted Ziggurat Upper - Near Bridge Switch": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Upper Front"),
|
||||
"Rooted Ziggurat Upper - Beneath Bridge To Administrator": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Upper Back"),
|
||||
@@ -246,15 +246,15 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Rooted Ziggurat Lower - Guarded By Double Turrets": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Front"),
|
||||
"Rooted Ziggurat Lower - After 2nd Double Turret Chest": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Front"),
|
||||
"Rooted Ziggurat Lower - Guarded By Double Turrets 2": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Front"),
|
||||
"Rooted Ziggurat Lower - Hexagon Blue": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Back"),
|
||||
"Rooted Ziggurat Lower - Hexagon Blue": TunicLocationData("Rooted Ziggurat", "Rooted Ziggurat Lower Back", location_group="bosses"),
|
||||
"Ruined Atoll - [West] Near Kevin Block": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [South] Upper Floor On Power Line": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [South] Upper Floor On Power Line": TunicLocationData("Ruined Atoll", "Ruined Atoll Ladder Tops"),
|
||||
"Ruined Atoll - [South] Chest Near Big Crabs": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [North] Guarded By Bird": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Northeast] Chest Beneath Brick Walkway": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Northwest] Bombable Wall": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [North] Obscured Beneath Bridge": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [South] Upper Floor On Bricks": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [South] Upper Floor On Bricks": TunicLocationData("Ruined Atoll", "Ruined Atoll Ladder Tops"),
|
||||
"Ruined Atoll - [South] Near Birds": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Northwest] Behind Envoy": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Southwest] Obscured Behind Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
@@ -262,40 +262,40 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Ruined Atoll - [North] From Lower Overworld Entrance": TunicLocationData("Ruined Atoll", "Ruined Atoll Lower Entry Area"),
|
||||
"Ruined Atoll - [East] Locked Room Lower Chest": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Northeast] Chest On Brick Walkway": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Southeast] Chest Near Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Ruined Atoll - [Southeast] Chest Near Fuse": TunicLocationData("Ruined Atoll", "Ruined Atoll Ladder Tops"),
|
||||
"Ruined Atoll - [Northeast] Key Pickup": TunicLocationData("Ruined Atoll", "Ruined Atoll"),
|
||||
"Cathedral Gauntlet - Gauntlet Reward": TunicLocationData("Swamp", "Cathedral Gauntlet"),
|
||||
"Cathedral - Secret Legend Trophy Chest": TunicLocationData("Swamp", "Cathedral Secret Legend Room"),
|
||||
"Swamp - [Upper Graveyard] Obscured Behind Hill": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] 4 Orange Skulls": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Central] Near Ramps Up": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Upper Graveyard] Near Shield Fleemers": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Obscured Behind Ridge": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Obscured Beneath Telescope": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Upper Graveyard] Obscured Behind Hill": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] 4 Orange Skulls": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Central] Near Ramps Up": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [Upper Graveyard] Near Shield Fleemers": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] Obscured Behind Ridge": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] Obscured Beneath Telescope": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Entrance] Above Entryway": TunicLocationData("Swamp", "Back of Swamp Laurels Area"),
|
||||
"Swamp - [Central] South Secret Passage": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Upper Walkway On Pedestal": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Guarded By Tentacles": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Upper Graveyard] Near Telescope": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Outside Cathedral] Near Moonlight Bridge Door": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Entrance] Obscured Inside Watchtower": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Entrance] South Near Fence": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Guarded By Big Skeleton": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Chest Near Graves": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Entrance] North Small Island": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Central] South Secret Passage": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] Upper Walkway On Pedestal": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [South Graveyard] Guarded By Tentacles": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Upper Graveyard] Near Telescope": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [Outside Cathedral] Near Moonlight Bridge Door": TunicLocationData("Swamp", "Swamp Ledge under Cathedral Door"),
|
||||
"Swamp - [Entrance] Obscured Inside Watchtower": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Entrance] South Near Fence": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [South Graveyard] Guarded By Big Skeleton": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [South Graveyard] Chest Near Graves": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Entrance] North Small Island": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Outside Cathedral] Obscured Behind Memorial": TunicLocationData("Swamp", "Back of Swamp"),
|
||||
"Swamp - [Central] Obscured Behind Northern Mountain": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Upper Walkway Dash Chest": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [South Graveyard] Above Big Skeleton": TunicLocationData("Swamp", "Swamp"),
|
||||
"Swamp - [Central] Beneath Memorial": TunicLocationData("Swamp", "Swamp"),
|
||||
"Hero's Grave - Feathers Relic": TunicLocationData("Swamp", "Hero Relic - Swamp"),
|
||||
"Swamp - [Central] Obscured Behind Northern Mountain": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] Upper Walkway Dash Chest": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Swamp - [South Graveyard] Above Big Skeleton": TunicLocationData("Swamp", "Swamp Front"),
|
||||
"Swamp - [Central] Beneath Memorial": TunicLocationData("Swamp", "Swamp Mid"),
|
||||
"Hero's Grave - Feathers Relic": TunicLocationData("Swamp", "Hero Relic - Swamp", location_group="hero relic"),
|
||||
"West Furnace - Chest": TunicLocationData("West Garden", "Furnace Walking Path"),
|
||||
"Overworld - [West] Near West Garden Entrance": TunicLocationData("West Garden", "Overworld to West Garden from Furnace"),
|
||||
"West Garden - [Central Highlands] Holy Cross (Blue Lines)": TunicLocationData("West Garden", "West Garden", "holy cross"),
|
||||
"West Garden - [West Lowlands] Tree Holy Cross Chest": TunicLocationData("West Garden", "West Garden", "holy cross"),
|
||||
"West Garden - [Central Highlands] Holy Cross (Blue Lines)": TunicLocationData("West Garden", "West Garden", location_group="holy cross"),
|
||||
"West Garden - [West Lowlands] Tree Holy Cross Chest": TunicLocationData("West Garden", "West Garden", location_group="holy cross"),
|
||||
"West Garden - [Southeast Lowlands] Outside Cave": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [Central Lowlands] Chest Beneath Faeries": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [North] Behind Holy Cross Door": TunicLocationData("West Garden", "West Garden", "holy cross"),
|
||||
"West Garden - [North] Behind Holy Cross Door": TunicLocationData("West Garden", "West Garden", location_group="holy cross"),
|
||||
"West Garden - [Central Highlands] Top of Ladder Before Boss": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [Central Lowlands] Passage Beneath Bridge": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [North] Across From Page Pickup": TunicLocationData("West Garden", "West Garden"),
|
||||
@@ -307,12 +307,12 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"West Garden - [West Highlands] Upper Left Walkway": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [Central Lowlands] Chest Beneath Save Point": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [Central Highlands] Behind Guard Captain": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [Central Highlands] After Garden Knight": TunicLocationData("West Garden", "West Garden after Boss"),
|
||||
"West Garden - [Central Highlands] After Garden Knight": TunicLocationData("Overworld", "West Garden after Boss", location_group="bosses"),
|
||||
"West Garden - [South Highlands] Secret Chest Beneath Fuse": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden - [East Lowlands] Page Behind Ice Dagger House": TunicLocationData("West Garden", "West Garden Portal Item"),
|
||||
"West Garden - [North] Page Pickup": TunicLocationData("West Garden", "West Garden"),
|
||||
"West Garden House - [Southeast Lowlands] Ice Dagger Pickup": TunicLocationData("West Garden", "Magic Dagger House"),
|
||||
"Hero's Grave - Effigy Relic": TunicLocationData("West Garden", "Hero Relic - West Garden"),
|
||||
"Hero's Grave - Effigy Relic": TunicLocationData("West Garden", "Hero Relic - West Garden", location_group="hero relic"),
|
||||
}
|
||||
|
||||
hexagon_locations: Dict[str, str] = {
|
||||
@@ -323,15 +323,9 @@ hexagon_locations: Dict[str, str] = {
|
||||
|
||||
location_name_to_id: Dict[str, int] = {name: location_base_id + index for index, name in enumerate(location_table)}
|
||||
|
||||
|
||||
def get_loc_group(location_name: str) -> str:
|
||||
loc_group = location_table[location_name].location_group
|
||||
if loc_group == "region":
|
||||
# set loc_group as the region name. Typically, location groups are lowercase
|
||||
loc_group = location_table[location_name].region.lower()
|
||||
return loc_group
|
||||
|
||||
|
||||
location_name_groups: Dict[str, Set[str]] = {
|
||||
group: set(item_names) for group, item_names in groupby(sorted(location_table, key=get_loc_group), get_loc_group)
|
||||
}
|
||||
location_name_groups: Dict[str, Set[str]] = {}
|
||||
for loc_name, loc_data in location_table.items():
|
||||
if loc_data.location_group:
|
||||
if loc_data.location_group not in location_name_groups.keys():
|
||||
location_name_groups[loc_data.location_group] = set()
|
||||
location_name_groups[loc_data.location_group].add(loc_name)
|
||||
|
||||
@@ -4,8 +4,7 @@ from Options import DefaultOnToggle, Toggle, StartInventoryPool, Choice, Range,
|
||||
|
||||
|
||||
class SwordProgression(DefaultOnToggle):
|
||||
"""Adds four sword upgrades to the item pool that will progressively grant stronger melee weapons, including two new
|
||||
swords with increased range and attack power."""
|
||||
"""Adds four sword upgrades to the item pool that will progressively grant stronger melee weapons, including two new swords with increased range and attack power."""
|
||||
internal_name = "sword_progression"
|
||||
display_name = "Sword Progression"
|
||||
|
||||
@@ -24,25 +23,24 @@ class KeysBehindBosses(Toggle):
|
||||
|
||||
class AbilityShuffling(Toggle):
|
||||
"""Locks the usage of Prayer, Holy Cross*, and the Icebolt combo until the relevant pages of the manual have been found.
|
||||
If playing Hexagon Quest, abilities are instead randomly unlocked after obtaining 25%, 50%, and 75% of the required
|
||||
Hexagon goal amount.
|
||||
*Certain Holy Cross usages are still allowed, such as the free bomb codes, the seeking spell, and other
|
||||
player-facing codes.
|
||||
If playing Hexagon Quest, abilities are instead randomly unlocked after obtaining 25%, 50%, and 75% of the required Hexagon goal amount.
|
||||
*Certain Holy Cross usages are still allowed, such as the free bomb codes, the seeking spell, and other player-facing codes.
|
||||
"""
|
||||
internal_name = "ability_shuffling"
|
||||
display_name = "Shuffle Abilities"
|
||||
|
||||
|
||||
class LogicRules(Choice):
|
||||
"""Set which logic rules to use for your world.
|
||||
"""
|
||||
Set which logic rules to use for your world.
|
||||
Restricted: Standard logic, no glitches.
|
||||
No Major Glitches: Sneaky Laurels zips, ice grapples through doors, shooting the west bell, and boss quick kills are included in logic.
|
||||
* Ice grappling through the Ziggurat door is not in logic since you will get stuck in there without Prayer.
|
||||
Unrestricted: Logic in No Major Glitches, as well as ladder storage to get to certain places early.
|
||||
*Special Shop is not in logic without the Hero's Laurels due to soft lock potential.
|
||||
*Torch is given to the player at the start of the game due to the high softlock potential with various tricks. Using the torch is not required in logic.
|
||||
*Using Ladder Storage to get to individual chests is not in logic to avoid tedium.
|
||||
*Getting knocked out of the air by enemies during Ladder Storage to reach places is not in logic, except for in
|
||||
Rooted Ziggurat Lower. This is so you're not punished for playing with enemy rando on."""
|
||||
*Getting knocked out of the air by enemies during Ladder Storage to reach places is not in logic, except for in Rooted Ziggurat Lower. This is so you're not punished for playing with enemy rando on.
|
||||
"""
|
||||
internal_name = "logic_rules"
|
||||
display_name = "Logic Rules"
|
||||
option_restricted = 0
|
||||
@@ -68,8 +66,7 @@ class Maskless(Toggle):
|
||||
|
||||
|
||||
class FoolTraps(Choice):
|
||||
"""Replaces low-to-medium value money rewards in the item pool with fool traps, which cause random negative
|
||||
effects to the player."""
|
||||
"""Replaces low-to-medium value money rewards in the item pool with fool traps, which cause random negative effects to the player."""
|
||||
internal_name = "fool_traps"
|
||||
display_name = "Fool Traps"
|
||||
option_off = 0
|
||||
@@ -80,8 +77,7 @@ class FoolTraps(Choice):
|
||||
|
||||
|
||||
class HexagonQuest(Toggle):
|
||||
"""An alternate goal that shuffles Gold "Questagon" items into the item pool and allows the game to be completed
|
||||
after collecting the required number of them."""
|
||||
"""An alternate goal that shuffles Gold "Questagon" items into the item pool and allows the game to be completed after collecting the required number of them."""
|
||||
internal_name = "hexagon_quest"
|
||||
display_name = "Hexagon Quest"
|
||||
|
||||
@@ -105,9 +101,11 @@ class ExtraHexagonPercentage(Range):
|
||||
|
||||
|
||||
class EntranceRando(TextChoice):
|
||||
"""Randomize the connections between scenes.
|
||||
You can choose a custom seed by editing this option.
|
||||
A small, very lost fox on a big adventure."""
|
||||
"""
|
||||
Randomize the connections between scenes.
|
||||
If you set this to a value besides true or false, that value will be used as a custom seed.
|
||||
A small, very lost fox on a big adventure.
|
||||
"""
|
||||
internal_name = "entrance_rando"
|
||||
display_name = "Entrance Rando"
|
||||
alias_false = 0
|
||||
@@ -137,15 +135,24 @@ class LaurelsLocation(Choice):
|
||||
default = 0
|
||||
|
||||
|
||||
class ShuffleLadders(Toggle):
|
||||
"""Turns several ladders in the game into items that must be found before they can be climbed on.
|
||||
Adds more layers of progression to the game by blocking access to many areas early on.
|
||||
"Ladders were a mistake." —Andrew Shouldice"""
|
||||
internal_name = "shuffle_ladders"
|
||||
display_name = "Shuffle Ladders"
|
||||
|
||||
|
||||
@dataclass
|
||||
class TunicOptions(PerGameCommonOptions):
|
||||
sword_progression: SwordProgression
|
||||
start_with_sword: StartWithSword
|
||||
keys_behind_bosses: KeysBehindBosses
|
||||
ability_shuffling: AbilityShuffling
|
||||
logic_rules: LogicRules
|
||||
shuffle_ladders: ShuffleLadders
|
||||
entrance_rando: EntranceRando
|
||||
fixed_shop: FixedShop
|
||||
logic_rules: LogicRules
|
||||
fool_traps: FoolTraps
|
||||
hexagon_quest: HexagonQuest
|
||||
hexagon_goal: HexagonGoal
|
||||
|
||||
@@ -6,10 +6,10 @@ tunic_regions: Dict[str, Set[str]] = {
|
||||
"Ruined Atoll", "Eastern Vault Fortress", "Beneath the Vault", "Quarry Back", "Quarry", "Swamp",
|
||||
"Spirit Arena"},
|
||||
"Overworld Holy Cross": set(),
|
||||
"East Forest": {"Eastern Vault Fortress"},
|
||||
"East Forest": set(),
|
||||
"Dark Tomb": {"West Garden"},
|
||||
"Beneath the Well": {"Dark Tomb"},
|
||||
"West Garden": {"Overworld", "Dark Tomb"},
|
||||
"Beneath the Well": set(),
|
||||
"West Garden": set(),
|
||||
"Ruined Atoll": {"Frog's Domain", "Library"},
|
||||
"Frog's Domain": set(),
|
||||
"Library": set(),
|
||||
|
||||
@@ -103,18 +103,10 @@ def set_region_rules(world: "TunicWorld", ability_unlocks: Dict[str, int]) -> No
|
||||
multiworld.get_entrance("Overworld -> West Garden", player).access_rule = \
|
||||
lambda state: state.has(laurels, player) \
|
||||
or can_ladder_storage(state, player, options)
|
||||
multiworld.get_entrance("Beneath the Well -> Dark Tomb", player).access_rule = \
|
||||
lambda state: has_lantern(state, player, options)
|
||||
multiworld.get_entrance("West Garden -> Dark Tomb", player).access_rule = \
|
||||
lambda state: has_lantern(state, player, options)
|
||||
multiworld.get_entrance("Overworld -> Eastern Vault Fortress", player).access_rule = \
|
||||
lambda state: state.has(laurels, player) \
|
||||
or has_ice_grapple_logic(True, state, player, options, ability_unlocks) \
|
||||
or can_ladder_storage(state, player, options)
|
||||
multiworld.get_entrance("East Forest -> Eastern Vault Fortress", player).access_rule = \
|
||||
lambda state: state.has(laurels, player) \
|
||||
or has_ice_grapple_logic(True, state, player, options, ability_unlocks) \
|
||||
or can_ladder_storage(state, player, options)
|
||||
# using laurels or ls to get in is covered by the -> Eastern Vault Fortress rules
|
||||
multiworld.get_entrance("Overworld -> Beneath the Vault", player).access_rule = \
|
||||
lambda state: has_lantern(state, player, options) and \
|
||||
@@ -211,7 +203,8 @@ def set_location_rules(world: "TunicWorld", ability_unlocks: Dict[str, int]) ->
|
||||
lambda state: state.has(laurels, player))
|
||||
set_rule(multiworld.get_location("Overworld - [West] Chest After Bell", player),
|
||||
lambda state: state.has(laurels, player)
|
||||
or (has_lantern(state, player, options) and has_sword(state, player)))
|
||||
or (has_lantern(state, player, options) and has_sword(state, player))
|
||||
or can_ladder_storage(state, player, options))
|
||||
set_rule(multiworld.get_location("Overworld - [Northwest] Chest Beneath Quarry Gate", player),
|
||||
lambda state: state.has_any({grapple, laurels}, player) or options.logic_rules)
|
||||
set_rule(multiworld.get_location("Overworld - [East] Grapple Chest", player),
|
||||
@@ -228,6 +221,8 @@ def set_location_rules(world: "TunicWorld", ability_unlocks: Dict[str, int]) ->
|
||||
lambda state: state.has(laurels, player)
|
||||
or (has_lantern(state, player, options) and (has_sword(state, player) or state.has(fire_wand, player)))
|
||||
or has_ice_grapple_logic(False, state, player, options, ability_unlocks))
|
||||
set_rule(multiworld.get_location("West Furnace - Lantern Pickup", player),
|
||||
lambda state: has_stick(state, player) or state.has_any({fire_wand, laurels}, player))
|
||||
|
||||
set_rule(multiworld.get_location("Secret Gathering Place - 10 Fairy Reward", player),
|
||||
lambda state: state.has(fairies, player, 10))
|
||||
@@ -265,8 +260,8 @@ def set_location_rules(world: "TunicWorld", ability_unlocks: Dict[str, int]) ->
|
||||
set_rule(multiworld.get_location("West Garden - [Central Lowlands] Below Left Walkway", player),
|
||||
lambda state: state.has(laurels, player))
|
||||
set_rule(multiworld.get_location("West Garden - [Central Highlands] After Garden Knight", player),
|
||||
lambda state: has_sword(state, player) or state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, state, player, options, ability_unlocks)
|
||||
lambda state: state.has(laurels, player)
|
||||
or (has_lantern(state, player, options) and has_sword(state, player))
|
||||
or can_ladder_storage(state, player, options))
|
||||
|
||||
# Ruined Atoll
|
||||
@@ -325,8 +320,6 @@ def set_location_rules(world: "TunicWorld", ability_unlocks: Dict[str, int]) ->
|
||||
lambda state: state.has(laurels, player))
|
||||
set_rule(multiworld.get_location("Swamp - [South Graveyard] 4 Orange Skulls", player),
|
||||
lambda state: has_sword(state, player))
|
||||
set_rule(multiworld.get_location("Swamp - [South Graveyard] Guarded By Tentacles", player),
|
||||
lambda state: has_sword(state, player))
|
||||
|
||||
# Hero's Grave
|
||||
set_rule(multiworld.get_location("Hero's Grave - Tooth Relic", player),
|
||||
|
||||
@@ -8,19 +8,23 @@ from .static_logic import WeightedItemDefinition, ItemCategory, StaticWitnessLog
|
||||
|
||||
|
||||
class DisableNonRandomizedPuzzles(Toggle):
|
||||
"""Disables puzzles that cannot be randomized.
|
||||
"""
|
||||
Disables puzzles that cannot be randomized.
|
||||
This includes many puzzles that heavily involve the environment, such as Shadows, Monastery or Orchard.
|
||||
|
||||
The lasers for those areas will activate as you solve optional puzzles, such as Discarded Panels.
|
||||
Additionally, the panels activating Monastery Laser and Jungle Popup Wall will be on from the start."""
|
||||
Additionally, the panel activating the Jungle Popup Wall will be on from the start.
|
||||
"""
|
||||
display_name = "Disable non randomized puzzles"
|
||||
|
||||
|
||||
class EarlyCaves(Choice):
|
||||
"""Adds an item that opens the Caves Shortcuts to Swamp and Mountain,
|
||||
allowing early access to the Caves even if you are not playing a remote Door Shuffle mode.
|
||||
You can either add this item to the pool to be found on one of your randomized checks,
|
||||
or you can outright start with it and have immediate access to the Caves.
|
||||
If you choose "add_to_pool" and you are already playing a remote Door Shuffle mode, this setting will do nothing."""
|
||||
"""
|
||||
Adds an item that opens the Caves Shortcuts to Swamp and Mountain, allowing early access to the Caves even if you are not playing a remote Door Shuffle mode.
|
||||
You can either add this item to the pool to be found in the multiworld, or you can outright start with it and have immediate access to the Caves.
|
||||
|
||||
If you choose "Add To Pool" and you are already playing a remote Door Shuffle mode, this option will do nothing.
|
||||
"""
|
||||
display_name = "Early Caves"
|
||||
option_off = 0
|
||||
alias_false = 0
|
||||
@@ -31,15 +35,19 @@ class EarlyCaves(Choice):
|
||||
|
||||
|
||||
class ShuffleSymbols(DefaultOnToggle):
|
||||
"""You will need to unlock puzzle symbols as items to be able to solve the panels that contain those symbols.
|
||||
If you turn this off, there will be no progression items in the game unless you turn on door shuffle."""
|
||||
"""
|
||||
If on, you will need to unlock puzzle symbols as items to be able to solve the panels that contain those symbols.
|
||||
|
||||
Please note that there is no minimum set of progression items in this randomizer.
|
||||
If you turn this option off and don't turn on door shuffle or obelisk keys, there will be no progression items, which will disallow you from adding your yaml to a multiworld generation.
|
||||
"""
|
||||
display_name = "Shuffle Symbols"
|
||||
|
||||
|
||||
class ShuffleLasers(Choice):
|
||||
"""If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
|
||||
Note: There is a visual bug that can occur with the Desert Laser. It does not affect gameplay - The Laser can still
|
||||
be redirected as normal, for both applications of redirection."""
|
||||
"""
|
||||
If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
|
||||
"""
|
||||
display_name = "Shuffle Lasers"
|
||||
option_off = 0
|
||||
alias_false = 0
|
||||
@@ -50,10 +58,12 @@ class ShuffleLasers(Choice):
|
||||
|
||||
|
||||
class ShuffleDoors(Choice):
|
||||
"""If on, opening doors, moving bridges etc. will require a "key".
|
||||
"""
|
||||
If on, opening doors, moving bridges etc. will require a "key".
|
||||
If set to "panels", the panel on the door will be locked until receiving its corresponding key.
|
||||
If set to "doors", the door will open immediately upon receiving its key. Door panels are added as location checks.
|
||||
"Mixed" includes all doors from "doors", and all control panels (bridges, elevators etc.) from "panels"."""
|
||||
"Mixed" includes all doors from "doors", and all control panels (bridges, elevators etc.) from "panels".
|
||||
"""
|
||||
display_name = "Shuffle Doors"
|
||||
option_off = 0
|
||||
option_panels = 1
|
||||
@@ -62,38 +72,45 @@ class ShuffleDoors(Choice):
|
||||
|
||||
|
||||
class DoorGroupings(Choice):
|
||||
"""If set to "none", there will be one key for every door, resulting in up to 120 keys being added to the item pool.
|
||||
If set to "regional", all doors in the same general region will open at once with a single key,
|
||||
reducing the amount of door items and complexity."""
|
||||
"""
|
||||
If set to "none", there will be one key for each door, potentially resulting in upwards of 120 keys being added to the item pool.
|
||||
If set to "regional", all doors in the same general region will open at once with a single key, reducing the amount of door items and complexity.
|
||||
"""
|
||||
display_name = "Door Groupings"
|
||||
option_off = 0
|
||||
option_regional = 1
|
||||
|
||||
|
||||
class ShuffleBoat(DefaultOnToggle):
|
||||
"""If set, adds a "Boat" item to the item pool. Before receiving this item, you will not be able to use the boat."""
|
||||
"""
|
||||
If on, adds a "Boat" item to the item pool. Before receiving this item, you will not be able to use the boat.
|
||||
"""
|
||||
display_name = "Shuffle Boat"
|
||||
|
||||
|
||||
class ShuffleDiscardedPanels(Toggle):
|
||||
"""Add Discarded Panels into the location pool.
|
||||
Solving certain Discarded Panels may still be necessary to beat the game, even if this is off - The main example
|
||||
of this being the alternate activation triggers in disable_non_randomized."""
|
||||
"""
|
||||
Adds Discarded Panels into the location pool.
|
||||
|
||||
Even if this is off, solving certain Discarded Panels may still be necessary to beat the game - The main example of this being the alternate activation triggers in "Disable non randomized puzzles".
|
||||
"""
|
||||
display_name = "Shuffle Discarded Panels"
|
||||
|
||||
|
||||
class ShuffleVaultBoxes(Toggle):
|
||||
"""Add Vault Boxes to the location pool."""
|
||||
"""
|
||||
Adds Vault Boxes to the location pool.
|
||||
"""
|
||||
display_name = "Shuffle Vault Boxes"
|
||||
|
||||
|
||||
class ShuffleEnvironmentalPuzzles(Choice):
|
||||
"""
|
||||
Add Environmental/Obelisk Puzzles into the location pool.
|
||||
In "individual", every Environmental Puzzle sends an item.
|
||||
In "obelisk_sides", completing every puzzle on one side of an Obelisk sends an item.
|
||||
Note: In Obelisk Sides, any EPs excluded through another setting will be counted as pre-completed on their Obelisk.
|
||||
Adds Environmental/Obelisk Puzzles into the location pool.
|
||||
If set to "individual", every Environmental Puzzle sends an item.
|
||||
If set to "Obelisk Sides", completing every puzzle on one side of an Obelisk sends an item.
|
||||
|
||||
Note: In Obelisk Sides, any EPs excluded through another option will be pre-completed on their Obelisk.
|
||||
"""
|
||||
display_name = "Shuffle Environmental Puzzles"
|
||||
option_off = 0
|
||||
@@ -102,17 +119,18 @@ class ShuffleEnvironmentalPuzzles(Choice):
|
||||
|
||||
|
||||
class ShuffleDog(Toggle):
|
||||
"""Add petting the Town dog into the location pool."""
|
||||
|
||||
"""
|
||||
Adds petting the Town dog into the location pool.
|
||||
"""
|
||||
display_name = "Pet the Dog"
|
||||
|
||||
|
||||
class EnvironmentalPuzzlesDifficulty(Choice):
|
||||
"""
|
||||
When "Shuffle Environmental Puzzles" is on, this setting governs which EPs are eligible for the location pool.
|
||||
On "eclipse", every EP in the game is eligible, including the 1-hour-long "Theater Eclipse EP".
|
||||
On "tedious", Theater Eclipse EP is excluded from the location pool.
|
||||
On "normal", several other difficult or long EPs are excluded as well.
|
||||
If set to "eclipse", every EP in the game is eligible, including the 1-hour-long "Theater Eclipse EP".
|
||||
If set to "tedious", Theater Eclipse EP is excluded from the location pool.
|
||||
If set to "normal", several other difficult or long EPs are excluded as well.
|
||||
"""
|
||||
display_name = "Environmental Puzzles Difficulty"
|
||||
option_normal = 0
|
||||
@@ -123,26 +141,31 @@ class EnvironmentalPuzzlesDifficulty(Choice):
|
||||
class ObeliskKeys(DefaultOnToggle):
|
||||
"""
|
||||
Add one Obelisk Key item per Obelisk, locking you out of solving any of the associated Environmental Puzzles.
|
||||
|
||||
Does nothing if "Shuffle Environmental Puzzles" is set to "off".
|
||||
"""
|
||||
display_name = "Obelisk Keys"
|
||||
|
||||
|
||||
class ShufflePostgame(Toggle):
|
||||
"""Adds locations into the pool that are guaranteed to become accessible after or at the same time as your goal.
|
||||
Use this if you don't play with release on victory. IMPORTANT NOTE: The possibility of your second
|
||||
"Progressive Dots" showing up in the Caves is ignored, they will still be considered "postgame" in base settings."""
|
||||
"""
|
||||
Adds locations into the pool that are guaranteed to become accessible after or at the same time as your goal.
|
||||
Use this if you don't play with release on victory.
|
||||
"""
|
||||
display_name = "Shuffle Postgame"
|
||||
|
||||
|
||||
class VictoryCondition(Choice):
|
||||
"""Set the victory condition for this world.
|
||||
"""
|
||||
Set the victory condition for this world.
|
||||
Elevator: Start the elevator at the bottom of the mountain (requires Mountain Lasers).
|
||||
Challenge: Beat the secret Challenge (requires Challenge Lasers).
|
||||
Mountain Box Short: Input the short solution to the Mountaintop Box (requires Mountain Lasers).
|
||||
Mountain Box Long: Input the long solution to the Mountaintop Box (requires Challenge Lasers).
|
||||
|
||||
It is important to note that while the Mountain Box requires Desert Laser to be redirected in Town for that laser
|
||||
to count, the laser locks on the Elevator and Challenge Timer panels do not."""
|
||||
to count, the laser locks on the Elevator and Challenge Timer panels do not.
|
||||
"""
|
||||
display_name = "Victory Condition"
|
||||
option_elevator = 0
|
||||
option_challenge = 1
|
||||
@@ -151,7 +174,9 @@ class VictoryCondition(Choice):
|
||||
|
||||
|
||||
class PuzzleRandomization(Choice):
|
||||
"""Puzzles in this randomizer are randomly generated. This setting changes the difficulty/types of puzzles."""
|
||||
"""
|
||||
Puzzles in this randomizer are randomly generated. This option changes the difficulty/types of puzzles.
|
||||
"""
|
||||
display_name = "Puzzle Randomization"
|
||||
option_sigma_normal = 0
|
||||
option_sigma_expert = 1
|
||||
@@ -159,10 +184,11 @@ class PuzzleRandomization(Choice):
|
||||
|
||||
|
||||
class MountainLasers(Range):
|
||||
"""Sets the amount of lasers required to enter the Mountain.
|
||||
If set to a higher amount than 7, the mountaintop box will be slightly rotated to make it possible to solve without
|
||||
the hatch being opened.
|
||||
This change will also be applied logically to the long solution ("Challenge Lasers" setting)."""
|
||||
"""
|
||||
Sets the number of lasers required to enter the Mountain.
|
||||
If set to a higher number than 7, the mountaintop box will be slightly rotated to make it possible to solve without the hatch being opened.
|
||||
This change will also be applied logically to the long solution ("Challenge Lasers" option).
|
||||
"""
|
||||
display_name = "Required Lasers for Mountain Entry"
|
||||
range_start = 1
|
||||
range_end = 11
|
||||
@@ -170,7 +196,9 @@ class MountainLasers(Range):
|
||||
|
||||
|
||||
class ChallengeLasers(Range):
|
||||
"""Sets the amount of beams required to enter the Caves through the Mountain Bottom Floor Discard."""
|
||||
"""
|
||||
Sets the number of lasers required to enter the Caves through the Mountain Bottom Floor Discard and to unlock the Challenge Timer Panel.
|
||||
"""
|
||||
display_name = "Required Lasers for Challenge"
|
||||
range_start = 1
|
||||
range_end = 11
|
||||
@@ -178,13 +206,17 @@ class ChallengeLasers(Range):
|
||||
|
||||
|
||||
class ElevatorsComeToYou(Toggle):
|
||||
"""If true, the Quarry Elevator, Bunker Elevator and Swamp Long Bridge will "come to you" if you approach them.
|
||||
This does actually affect logic as it allows unintended backwards / early access into these areas."""
|
||||
"""
|
||||
If on, the Quarry Elevator, Bunker Elevator and Swamp Long Bridge will "come to you" if you approach them.
|
||||
This does actually affect logic as it allows unintended backwards / early access into these areas.
|
||||
"""
|
||||
display_name = "All Bridges & Elevators come to you"
|
||||
|
||||
|
||||
class TrapPercentage(Range):
|
||||
"""Replaces junk items with traps, at the specified rate."""
|
||||
"""
|
||||
Replaces junk items with traps, at the specified rate.
|
||||
"""
|
||||
display_name = "Trap Percentage"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -192,10 +224,11 @@ class TrapPercentage(Range):
|
||||
|
||||
|
||||
class TrapWeights(OptionDict):
|
||||
"""Specify the weights determining how many copies of each trap item will be in your itempool.
|
||||
"""
|
||||
Specify the weights determining how many copies of each trap item will be in your itempool.
|
||||
If you don't want a specific type of trap, you can set the weight for it to 0 (Do not delete the entry outright!).
|
||||
If you set all trap weights to 0, you will get no traps, bypassing the "Trap Percentage" option."""
|
||||
|
||||
If you set all trap weights to 0, you will get no traps, bypassing the "Trap Percentage" option.
|
||||
"""
|
||||
display_name = "Trap Weights"
|
||||
schema = Schema({
|
||||
trap_name: And(int, lambda n: n >= 0)
|
||||
@@ -210,8 +243,9 @@ class TrapWeights(OptionDict):
|
||||
|
||||
|
||||
class PuzzleSkipAmount(Range):
|
||||
"""Adds this number of Puzzle Skips into the pool, if there is room. Puzzle Skips let you skip one panel.
|
||||
Works on most panels in the game - The only big exception is The Challenge."""
|
||||
"""
|
||||
Adds this many Puzzle Skips into the pool, if there is room. Puzzle Skips let you skip one panel.
|
||||
"""
|
||||
display_name = "Puzzle Skips"
|
||||
range_start = 0
|
||||
range_end = 30
|
||||
@@ -219,8 +253,10 @@ class PuzzleSkipAmount(Range):
|
||||
|
||||
|
||||
class HintAmount(Range):
|
||||
"""Adds hints to Audio Logs. If set to a low amount, up to 2 additional duplicates of each hint will be added.
|
||||
Remaining Audio Logs will have junk hints."""
|
||||
"""
|
||||
Adds hints to Audio Logs. If set to a low amount, up to 2 additional duplicates of each hint will be added.
|
||||
Remaining Audio Logs will have junk hints.
|
||||
"""
|
||||
display_name = "Hints on Audio Logs"
|
||||
range_start = 0
|
||||
range_end = 49
|
||||
@@ -228,11 +264,12 @@ class HintAmount(Range):
|
||||
|
||||
|
||||
class AreaHintPercentage(Range):
|
||||
"""There are two types of hints for The Witness.
|
||||
"Location hints" hint one location in your world / containing an item for your world.
|
||||
"Area hints" will tell you some general info about the items you can find in one of the
|
||||
main geographic areas on the island.
|
||||
Use this option to specify how many of your hints you want to be area hints. The rest will be location hints."""
|
||||
"""
|
||||
There are two types of hints for The Witness.
|
||||
"Location hints" hint one location in your world or one location containing an item for your world.
|
||||
"Area hints" tell you some general info about the items you can find in one of the main geographic areas on the island.
|
||||
Use this option to specify how many of your hints you want to be area hints. The rest will be location hints.
|
||||
"""
|
||||
display_name = "Area Hint Percentage"
|
||||
range_start = 0
|
||||
range_end = 100
|
||||
@@ -240,20 +277,26 @@ class AreaHintPercentage(Range):
|
||||
|
||||
|
||||
class LaserHints(Toggle):
|
||||
"""If on, lasers will tell you where their items are if you walk close to them in-game.
|
||||
Only applies if laser shuffle is enabled."""
|
||||
"""
|
||||
If on, lasers will tell you where their items are if you walk close to them in-game.
|
||||
Only applies if Laser Shuffle is enabled.
|
||||
"""
|
||||
display_name = "Laser Hints"
|
||||
|
||||
|
||||
class DeathLink(Toggle):
|
||||
"""If on: Whenever you fail a puzzle (with some exceptions), everyone who is also on Death Link dies.
|
||||
The effect of a "death" in The Witness is a Bonk Trap."""
|
||||
"""
|
||||
If on, whenever you fail a puzzle (with some exceptions), you and everyone who is also on Death Link dies.
|
||||
The effect of a "death" in The Witness is a Bonk Trap.
|
||||
"""
|
||||
display_name = "Death Link"
|
||||
|
||||
|
||||
class DeathLinkAmnesty(Range):
|
||||
"""Number of panel fails to allow before sending a death through Death Link.
|
||||
0 means every panel fail will send a death, 1 means every other panel fail will send a death, etc."""
|
||||
"""
|
||||
The number of panel fails to allow before sending a death through Death Link.
|
||||
0 means every panel fail will send a death, 1 means every other panel fail will send a death, etc.
|
||||
"""
|
||||
display_name = "Death Link Amnesty"
|
||||
range_start = 0
|
||||
range_end = 5
|
||||
|
||||
Reference in New Issue
Block a user