Hylics 2: Implement new game (#1058)

This commit is contained in:
Trevor L 2022-10-12 23:51:25 -06:00 committed by GitHub
parent 30a4bcbbbe
commit b014ce082b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1492 additions and 0 deletions

94
worlds/hylics2/Exits.py Normal file
View File

@ -0,0 +1,94 @@
from typing import List, Dict
region_exit_table: Dict[int, List[str]] = {
0: ["New Game"],
1: ["To Waynehouse",
"To New Muldul",
"To Viewax",
"To TV Island",
"To Shield Facility",
"To Worm Pod",
"To Foglast",
"To Sage Labyrinth",
"To Hylemxylem"],
2: ["To World",
"To Afterlife",],
3: ["To Airship",
"To Waynehouse",
"To New Muldul",
"To Drill Castle",
"To Viewax",
"To Arcade Island",
"To TV Island",
"To Juice Ranch",
"To Shield Facility",
"To Worm Pod",
"To Foglast",
"To Sage Airship",
"To Hylemxylem"],
4: ["To World",
"To Afterlife",
"To New Muldul Vault"],
5: ["To New Muldul"],
6: ["To World",
"To Afterlife"],
7: ["To World"],
8: ["To World"],
9: ["To World",
"To Afterlife"],
10: ["To World"],
11: ["To World",
"To Afterlife",
"To Worm Pod"],
12: ["To Shield Facility",
"To Afterlife"],
13: ["To World",
"To Afterlife"],
14: ["To World",
"To Sage Labyrinth"],
15: ["To Drill Castle",
"To Afterlife"],
16: ["To World"],
17: ["To World",
"To Afterlife"]
}
exit_lookup_table: Dict[str, int] = {
"New Game": 2,
"To Waynehouse": 2,
"To Afterlife": 1,
"To World": 3,
"To New Muldul": 4,
"To New Muldul Vault": 5,
"To Viewax": 6,
"To Airship": 7,
"To Arcade Island": 8,
"To TV Island": 9,
"To Juice Ranch": 10,
"To Shield Facility": 11,
"To Worm Pod": 12,
"To Foglast": 13,
"To Drill Castle": 14,
"To Sage Labyrinth": 15,
"To Sage Airship": 16,
"To Hylemxylem": 17
}

243
worlds/hylics2/Items.py Normal file
View File

@ -0,0 +1,243 @@
from BaseClasses import ItemClassification
from typing import TypedDict, Dict
class ItemDict(TypedDict):
classification: ItemClassification
count: int
name: str
item_table: Dict[int, ItemDict] = {
# Things
200622: {'classification': ItemClassification.filler,
'count': 1,
'name': 'DUBIOUS BERRY'},
200623: {'classification': ItemClassification.filler,
'count': 11,
'name': 'BURRITO'},
200624: {'classification': ItemClassification.filler,
'count': 1,
'name': 'COFFEE'},
200625: {'classification': ItemClassification.filler,
'count': 6,
'name': 'SOUL SPONGE'},
200626: {'classification': ItemClassification.useful,
'count': 6,
'name': 'MUSCLE APPLIQUE'},
200627: {'classification': ItemClassification.filler,
'count': 1,
'name': 'POOLWINE'},
200628: {'classification': ItemClassification.filler,
'count': 3,
'name': 'CUPCAKE'},
200629: {'classification': ItemClassification.filler,
'count': 3,
'name': 'COOKIE'},
200630: {'classification': ItemClassification.progression,
'count': 1,
'name': 'HOUSE KEY'},
200631: {'classification': ItemClassification.filler,
'count': 2,
'name': 'MEAT'},
200632: {'classification': ItemClassification.progression,
'count': 1,
'name': 'PNEUMATOPHORE'},
200633: {'classification': ItemClassification.progression,
'count': 1,
'name': 'CAVE KEY'},
200634: {'classification': ItemClassification.filler,
'count': 6,
'name': 'JUICE'},
200635: {'classification': ItemClassification.progression,
'count': 1,
'name': 'DOCK KEY'},
200636: {'classification': ItemClassification.filler,
'count': 14,
'name': 'BANANA'},
200637: {'classification': ItemClassification.progression,
'count': 3,
'name': 'PAPER CUP'},
200638: {'classification': ItemClassification.progression,
'count': 1,
'name': 'JAIL KEY'},
200639: {'classification': ItemClassification.progression,
'count': 1,
'name': 'PADDLE'},
200640: {'classification': ItemClassification.progression,
'count': 1,
'name': 'WORM ROOM KEY'},
200641: {'classification': ItemClassification.progression,
'count': 1,
'name': 'BRIDGE KEY'},
200642: {'classification': ItemClassification.filler,
'count': 2,
'name': 'STEM CELL'},
200643: {'classification': ItemClassification.progression,
'count': 1,
'name': 'UPPER CHAMBER KEY'},
200644: {'classification': ItemClassification.progression,
'count': 1,
'name': 'VESSEL ROOM KEY'},
200645: {'classification': ItemClassification.filler,
'count': 3,
'name': 'CLOUD GERM'},
200646: {'classification': ItemClassification.progression,
'count': 1,
'name': 'SKULL BOMB'},
200647: {'classification': ItemClassification.progression,
'count': 1,
'name': 'TOWER KEY'},
200648: {'classification': ItemClassification.progression,
'count': 1,
'name': 'DEEP KEY'},
200649: {'classification': ItemClassification.filler,
'count': 1,
'name': 'MULTI-COFFEE'},
200650: {'classification': ItemClassification.filler,
'count': 4,
'name': 'MULTI-JUICE'},
200651: {'classification': ItemClassification.filler,
'count': 1,
'name': 'MULTI STEM CELL'},
200652: {'classification': ItemClassification.filler,
'count': 6,
'name': 'MULTI SOUL SPONGE'},
#200653: {'classification': ItemClassification.filler,
# 'count': 1,
# 'name': 'ANTENNA'},
200654: {'classification': ItemClassification.progression,
'count': 1,
'name': 'UPPER HOUSE KEY'},
200655: {'classification': ItemClassification.useful,
'count': 1,
'name': 'BOTTOMLESS JUICE'},
200656: {'classification': ItemClassification.progression,
'count': 3,
'name': 'SAGE TOKEN'},
200657: {'classification': ItemClassification.progression,
'count': 1,
'name': 'CLICKER'},
# Garbs > Gloves
200658: {'classification': ItemClassification.useful,
'count': 1,
'name': 'CURSED GLOVES'},
200659: {'classification': ItemClassification.useful,
'count': 5,
'name': 'LONG GLOVES'},
200660: {'classification': ItemClassification.useful,
'count': 1,
'name': 'BRAIN DIGITS'},
200661: {'classification': ItemClassification.useful,
'count': 1,
'name': 'MATERIEL MITTS'},
200662: {'classification': ItemClassification.useful,
'count': 1,
'name': 'PLEATHER GAGE'},
200663: {'classification': ItemClassification.useful,
'count': 1,
'name': 'PEPTIDE BODKINS'},
200664: {'classification': ItemClassification.useful,
'count': 1,
'name': 'TELESCOPIC SLEEVE'},
200665: {'classification': ItemClassification.useful,
'count': 1,
'name': 'TENDRIL HAND'},
200666: {'classification': ItemClassification.useful,
'count': 1,
'name': 'PSYCHIC KNUCKLE'},
200667: {'classification': ItemClassification.useful,
'count': 1,
'name': 'SINGLE GLOVE'},
# Garbs > Accessories
200668: {'classification': ItemClassification.useful,
'count': 1,
'name': 'FADED PONCHO'},
200669: {'classification': ItemClassification.useful,
'count': 1,
'name': 'JUMPSUIT'},
200670: {'classification': ItemClassification.useful,
'count': 1,
'name': 'BOOTS'},
200671: {'classification': ItemClassification.useful,
'count': 1,
'name': 'CONVERTER WORM'},
200672: {'classification': ItemClassification.useful,
'count': 1,
'name': 'COFFEE CHIP'},
200673: {'classification': ItemClassification.useful,
'count': 1,
'name': 'RANCHER PONCHO'},
200674: {'classification': ItemClassification.useful,
'count': 1,
'name': 'ORGAN FORT'},
200675: {'classification': ItemClassification.useful,
'count': 2,
'name': 'LOOPED DOME'},
200676: {'classification': ItemClassification.useful,
'count': 1,
'name': 'DUCTILE HABIT'},
200677: {'classification': ItemClassification.useful,
'count': 2,
'name': 'TARP'},
# Bones
200686: {'classification': ItemClassification.filler,
'count': 1,
'name': '100 Bones'},
200687: {'classification': ItemClassification.filler,
'count': 1,
'name': '50 Bones'}
}
gesture_item_table: Dict[int, ItemDict] = {
200678: {'classification': ItemClassification.useful,
'count': 1,
'name': 'POROMER BLEB'},
200679: {'classification': ItemClassification.useful,
'count': 1,
'name': 'SOUL CRISPER'},
200680: {'classification': ItemClassification.useful,
'count': 1,
'name': 'TIME SIGIL'},
200681: {'classification': ItemClassification.progression,
'count': 1,
'name': 'CHARGE UP'},
200682: {'classification': ItemClassification.useful,
'count': 1,
'name': 'FATE SANDBOX'},
200683: {'classification': ItemClassification.useful,
'count': 1,
'name': 'TELEDENUDATE'},
200684: {'classification': ItemClassification.useful,
'count': 1,
'name': 'LINK MOLLUSC'},
200685: {'classification': ItemClassification.useful,
'count': 1,
'name': 'BOMBO - GENESIS'},
200688: {'classification': ItemClassification.useful,
'count': 1,
'name': 'NEMATODE INTERFACE'},
}
party_item_table: Dict[int, ItemDict] = {
200689: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Pongorma'},
200690: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Dedusmuln'},
200691: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Somsnosa'}
}
medallion_item_table: Dict[int, ItemDict] = {
200692: {'classification': ItemClassification.filler,
'count': 30,
'name': '10 Bones'}
}

383
worlds/hylics2/Locations.py Normal file
View File

@ -0,0 +1,383 @@
from typing import Dict, TypedDict
class LocationDict(TypedDict, total=False):
name: str
region: int
location_table: Dict[int, LocationDict] = {
# Waynehouse
200622: {'name': "Waynehouse: Toilet",
'region': 2},
200623: {'name': "Waynehouse: Basement Pot 1",
'region': 2},
200624: {'name': "Waynehouse: Basement Pot 2",
'region': 2},
200625: {'name': "Waynehouse: Basement Pot 3",
'region': 2},
200626: {'name': "Waynehouse: Sarcophagus",
'region': 2},
# Afterlife
200628: {'name': "Afterlife: Mangled Wayne",
'region': 1},
200629: {'name': "Afterlife: Jar near Mangled Wayne",
'region': 1},
200630: {'name': "Afterlife: Jar under Pool",
'region': 1},
# New Muldul
200632: {'name': "New Muldul: Shop Ceiling Pot 1",
'region': 4},
200633: {'name': "New Muldul: Shop Ceiling Pot 2",
'region': 4},
200634: {'name': "New Muldul: Flag Banana",
'region': 4},
200635: {'name': "New Muldul: Pot near Vault",
'region': 4},
200636: {'name': "New Muldul: Underground Pot",
'region': 4},
200637: {'name': "New Muldul: Underground Chest",
'region': 4},
200638: {'name': "New Muldul: Juice Trade",
'region': 4},
200639: {'name': "New Muldul: Basement Suitcase",
'region': 4},
200640: {'name': "New Muldul: Upper House Chest 1",
'region': 4},
200641: {'name': "New Muldul: Upper House Chest 2",
'region': 4},
# New Muldul Vault
200643: {'name': "New Muldul: Talk to Pongorma",
'region': 4},
200645: {'name': "New Muldul: Rescued Blerol 1",
'region': 4},
200646: {'name': "New Muldul: Rescued Blerol 2",
'region': 4},
200647: {'name': "New Muldul: Vault Left Chest",
'region': 5},
200648: {'name': "New Muldul: Vault Right Chest",
'region': 5},
200649: {'name': "New Muldul: Vault Bomb",
'region': 5},
# Viewax's Edifice
200650: {'name': "Viewax's Edifice: Fountain Banana",
'region': 6},
200651: {'name': "Viewax's Edifice: Dedusmuln's Suitcase",
'region': 6},
200652: {'name': "Viewax's Edifice: Dedusmuln's Campfire",
'region': 6},
200653: {'name': "Viewax's Edifice: Talk to Dedusmuln",
'region': 6},
200655: {'name': "Viewax's Edifice: Canopic Jar",
'region': 6},
200656: {'name': "Viewax's Edifice: Cave Sarcophagus",
'region': 6},
200657: {'name': "Viewax's Edifice: Shielded Key",
'region': 6},
200658: {'name': "Viewax's Edifice: Tower Pot",
'region': 6},
200659: {'name': "Viewax's Edifice: Tower Jar",
'region': 6},
200660: {'name': "Viewax's Edifice: Tower Chest",
'region': 6},
200661: {'name': "Viewax's Edifice: Sage Fridge",
'region': 6},
200662: {'name': "Viewax's Edifice: Sage Item 1",
'region': 6},
200663: {'name': "Viewax's Edifice: Sage Item 2",
'region': 6},
200664: {'name': "Viewax's Edifice: Viewax Pot",
'region': 6},
200665: {'name': "Viewax's Edifice: Defeat Viewax",
'region': 6},
# Viewax Arcade Minigame
200667: {'name': "Arcade 1: Key",
'region': 6},
200668: {'name': "Arcade 1: Coin Dash",
'region': 6},
200669: {'name': "Arcade 1: Burrito Alcove 1",
'region': 6},
200670: {'name': "Arcade 1: Burrito Alcove 2",
'region': 6},
200671: {'name': "Arcade 1: Behind Spikes Banana",
'region': 6},
200672: {'name': "Arcade 1: Pyramid Banana",
'region': 6},
200673: {'name': "Arcade 1: Moving Platforms Muscle Applique",
'region': 6},
200674: {'name': "Arcade 1: Bed Banana",
'region': 6},
# Airship
200675: {'name': "Airship: Talk to Somsnosa",
'region': 7},
# Arcade Island
200676: {'name': "Arcade Island: Shielded Key",
'region': 8},
200677: {'name': "Arcade 2: Flying Machine Banana",
'region': 8},
200678: {'name': "Arcade 2: Paper Cup Detour",
'region': 8},
200679: {'name': "Arcade 2: Peak Muscle Applique",
'region': 8},
200680: {'name': "Arcade 2: Double Banana 1",
'region': 8},
200681: {'name': "Arcade 2: Double Banana 2",
'region': 8},
200682: {'name': "Arcade 2: Cave Burrito",
'region': 8},
# Juice Ranch
200684: {'name': "Juice Ranch: Juice 1",
'region': 10},
200685: {'name': "Juice Ranch: Juice 2",
'region': 10},
200686: {'name': "Juice Ranch: Juice 3",
'region': 10},
200687: {'name': "Juice Ranch: Ledge Rancher",
'region': 10},
200688: {'name': "Juice Ranch: Battle with Somsnosa",
'region': 10},
200690: {'name': "Juice Ranch: Fridge",
'region': 10},
# Worm Pod
200692: {'name': "Worm Pod: Key",
'region': 12},
# Foglast
200693: {'name': "Foglast: West Sarcophagus",
'region': 13},
200694: {'name': "Foglast: Underground Sarcophagus",
'region': 13},
200695: {'name': "Foglast: Shielded Key",
'region': 13},
200696: {'name': "Foglast: Buy Clicker",
'region': 13},
200698: {'name': "Foglast: Shielded Chest",
'region': 13},
200699: {'name': "Foglast: Cave Fridge",
'region': 13},
200700: {'name': "Foglast: Roof Sarcophagus",
'region': 13},
200701: {'name': "Foglast: Under Lair Sarcophagus 1",
'region': 13},
200702: {'name': "Foglast: Under Lair Sarcophagus 2",
'region': 13},
200703: {'name': "Foglast: Under Lair Sarcophagus 3",
'region': 13},
200704: {'name': "Foglast: Sage Sarcophagus",
'region': 13},
200705: {'name': "Foglast: Sage Item 1",
'region': 13},
200706: {'name': "Foglast: Sage Item 2",
'region': 13},
# Drill Castle
200707: {'name': "Drill Castle: Ledge Banana",
'region': 14},
200708: {'name': "Drill Castle: Island Banana",
'region': 14},
200709: {'name': "Drill Castle: Island Pot",
'region': 14},
200710: {'name': "Drill Castle: Cave Sarcophagus",
'region': 14},
200711: {'name': "Drill Castle: Roof Banana",
'region': 14},
# Sage Labyrinth
200713: {'name': "Sage Labyrinth: 1F Chest Near Fountain",
'region': 15},
200714: {'name': "Sage Labyrinth: 1F Hidden Sarcophagus",
'region': 15},
200715: {'name': "Sage Labyrinth: 1F Four Statues Chest 1",
'region': 15},
200716: {'name': "Sage Labyrinth: 1F Four Statues Chest 2",
'region': 15},
200717: {'name': "Sage Labyrinth: B1 Double Chest 1",
'region': 15},
200718: {'name': "Sage Labyrinth: B1 Double Chest 2",
'region': 15},
200719: {'name': "Sage Labyrinth: B1 Single Chest",
'region': 15},
200720: {'name': "Sage Labyrinth: B1 Enemy Chest",
'region': 15},
200721: {'name': "Sage Labyrinth: B1 Hidden Sarcophagus",
'region': 15},
200722: {'name': "Sage Labyrinth: B1 Hole Chest",
'region': 15},
200723: {'name': "Sage Labyrinth: B2 Hidden Sarcophagus 1",
'region': 15},
200724: {'name': "Sage Labyrinth: B2 Hidden Sarcophagus 2",
'region': 15},
200754: {'name': "Sage Labyrinth: 2F Sarcophagus",
'region': 15},
200725: {'name': "Sage Labyrinth: Motor Hunter Sarcophagus",
'region': 15},
200726: {'name': "Sage Labyrinth: Sage Item 1",
'region': 15},
200727: {'name': "Sage Labyrinth: Sage Item 2",
'region': 15},
200728: {'name': "Sage Labyrinth: Sage Left Arm",
'region': 15},
200729: {'name': "Sage Labyrinth: Sage Right Arm",
'region': 15},
200730: {'name': "Sage Labyrinth: Sage Left Leg",
'region': 15},
200731: {'name': "Sage Labyrinth: Sage Right Leg",
'region': 15},
# Sage Airship
200732: {'name': "Sage Airship: Bottom Level Pot",
'region': 16},
200733: {'name': "Sage Airship: Flesh Pot",
'region': 16},
200734: {'name': "Sage Airship: Top Jar",
'region': 16},
# Hylemxylem
200736: {'name': "Hylemxylem: Jar",
'region': 17},
200737: {'name': "Hylemxylem: Lower Reservoir Key",
'region': 17},
200738: {'name': "Hylemxylem: Fountain Banana",
'region': 17},
200739: {'name': "Hylemxylem: East Island Banana",
'region': 17},
200740: {'name': "Hylemxylem: East Island Chest",
'region': 17},
200741: {'name': "Hylemxylem: Upper Chamber Banana",
'region': 17},
200742: {'name': "Hylemxylem: Across Upper Reservoir Chest",
'region': 17},
200743: {'name': "Hylemxylem: Drained Lower Reservoir Chest",
'region': 17},
200744: {'name': "Hylemxylem: Drained Lower Reservoir Burrito 1",
'region': 17},
200745: {'name': "Hylemxylem: Drained Lower Reservoir Burrito 2",
'region': 17},
200746: {'name': "Hylemxylem: Lower Reservoir Hole Pot 1",
'region': 17},
200747: {'name': "Hylemxylem: Lower Reservoir Hole Pot 2",
'region': 17},
200748: {'name': "Hylemxylem: Lower Reservoir Hole Pot 3",
'region': 17},
200749: {'name': "Hylemxylem: Lower Reservoir Hole Sarcophagus",
'region': 17},
200750: {'name': "Hylemxylem: Drained Upper Reservoir Burrito 1",
'region': 17},
200751: {'name': "Hylemxylem: Drained Upper Reservoir Burrito 2",
'region': 17},
200752: {'name': "Hylemxylem: Drained Upper Reservoir Burrito 3",
'region': 17},
200753: {'name': "Hylemxylem: Upper Reservoir Hole Key",
'region': 17}
}
tv_location_table: Dict[int, LocationDict] = {
200627: {'name': "Waynehouse: TV",
'region': 2},
200631: {'name': "Afterlife: TV",
'region': 1},
200642: {'name': "New Muldul: TV",
'region': 4},
200666: {'name': "Viewax's Edifice: TV",
'region': 6},
200683: {'name': "TV Island: TV",
'region': 9},
200691: {'name': "Juice Ranch: TV",
'region': 10},
200697: {'name': "Foglast: TV",
'region': 13},
200712: {'name': "Drill Castle: TV",
'region': 14},
200735: {'name': "Sage Airship: TV",
'region': 16}
}
party_location_table: Dict[int, LocationDict] = {
200644: {'name': "New Muldul: Pongorma Joins",
'region': 4},
200654: {'name': "Viewax's Edifice: Dedusmuln Joins",
'region': 6},
200689: {'name': "Juice Ranch: Somsnosa Joins",
'region': 10}
}
medallion_location_table: Dict[int, LocationDict] = {
200755: {'name': "New Muldul: Upper House Medallion",
'region': 4},
200756: {'name': "New Muldul: Vault Rear Left Medallion",
'region': 5},
200757: {'name': "New Muldul: Vault Rear Right Medallion",
'region': 5},
200758: {'name': "New Muldul: Vault Center Medallion",
'region': 5},
200759: {'name': "New Muldul: Vault Front Left Medallion",
'region': 5},
200760: {'name': "New Muldul: Vault Front Right Medallion",
'region': 5},
200761: {'name': "Viewax's Edifice: Fort Wall Medallion",
'region': 6},
200762: {'name': "Viewax's Edifice: Jar Medallion",
'region': 6},
200763: {'name': "Viewax's Edifice: Sage Chair Medallion",
'region': 6},
200764: {'name': "Arcade 1: Lonely Medallion",
'region': 6},
200765: {'name': "Arcade 1: Alcove Medallion",
'region': 6},
200766: {'name': "Arcade 1: Lava Medallion",
'region': 6},
200767: {'name': "Arcade 2: Flying Machine Medallion",
'region': 8},
200768: {'name': "Arcade 2: Guarded Medallion",
'region': 8},
200769: {'name': "Arcade 2: Spinning Medallion",
'region': 8},
200770: {'name': "Arcade 2: Hook Medallion",
'region': 8},
200771: {'name': "Arcade 2: Flag Medallion",
'region': 8},
200772: {'name': "Foglast: Under Lair Medallion",
'region': 13},
200773: {'name': "Foglast: Mid-Air Medallion",
'region': 13},
200774: {'name': "Foglast: Top of Tower Medallion",
'region': 13},
200775: {'name': "Sage Airship: Walkway Medallion",
'region': 16},
200776: {'name': "Sage Airship: Flesh Medallion",
'region': 16},
200777: {'name': "Sage Airship: Top of Ship Medallion",
'region': 16},
200778: {'name': "Sage Airship: Hidden Medallion 1",
'region': 16},
200779: {'name': "Sage Airship: Hidden Medallion 2",
'region': 16},
200780: {'name': "Sage Airship: Hidden Medallion 3",
'region': 16},
200781: {'name': "Hylemxylem: Lower Reservoir Medallion",
'region': 17},
200782: {'name': "Hylemxylem: Lower Reservoir Hole Medallion",
'region': 17},
200783: {'name': "Hylemxylem: Drain Switch Medallion",
'region': 17},
200784: {'name': "Hylemxylem: Warpo Medallion",
'region': 17}
}

41
worlds/hylics2/Options.py Normal file
View File

@ -0,0 +1,41 @@
from Options import Choice, Toggle, DefaultOnToggle, DeathLink
class PartyShuffle(Toggle):
"""Shuffles party members into the pool.
Note that enabling this can potentially increase both the difficulty and length of a run."""
display_name = "Shuffle Party Members"
class GestureShuffle(Choice):
"""Choose where gestures will appear in the item pool."""
display_name = "Shuffle Gestures"
option_anywhere = 0
option_tvs_only = 1
option_default_locations = 2
default = 0
class MedallionShuffle(Toggle):
"""Shuffles red medallions into the pool."""
display_name = "Shuffle Red Medallions"
class RandomStart(Toggle):
"""Start the randomizer in 1 of 4 positions.
(Waynehouse, Viewax's Edifice, TV Island, Shield Facility)"""
display_name = "Randomize Start Location"
class ExtraLogic(DefaultOnToggle):
"""Include some extra items in logic (CHARGE UP, 1x PAPER CUP) to prevent the game from becoming too difficult."""
display_name = "Extra Items in Logic"
class Hylics2DeathLink(DeathLink):
"""When you die, everyone dies. The reverse is also true.
Note that this also includes death by using the PERISH gesture.
Can be toggled via in-game console command "/deathlink"."""
hylics2_options = {
"party_shuffle": PartyShuffle,
"gesture_shuffle" : GestureShuffle,
"medallion_shuffle" : MedallionShuffle,
"random_start" : RandomStart,
"extra_items_in_logic": ExtraLogic,
"death_link": Hylics2DeathLink
}

433
worlds/hylics2/Rules.py Normal file
View File

@ -0,0 +1,433 @@
from worlds.generic.Rules import add_rule
from ..AutoWorld import LogicMixin
class Hylics2Logic(LogicMixin):
def _hylics2_can_air_dash(self, player):
return self.has("PNEUMATOPHORE", player)
def _hylics2_has_airship(self, player):
return self.has("DOCK KEY", player)
def _hylics2_has_jail_key(self, player):
return self.has("JAIL KEY", player)
def _hylics2_has_paddle(self, player):
return self.has("PADDLE", player)
def _hylics2_has_worm_room_key(self, player):
return self.has("WORM ROOM KEY", player)
def _hylics2_has_bridge_key(self, player):
return self.has("BRIDGE KEY", player)
def _hylics2_has_upper_chamber_key(self, player):
return self.has("UPPER CHAMBER KEY", player)
def _hylics2_has_vessel_room_key(self, player):
return self.has("VESSEL ROOM KEY", player)
def _hylics2_has_house_key(self, player):
return self.has("HOUSE KEY", player)
def _hylics2_has_cave_key(self, player):
return self.has("CAVE KEY", player)
def _hylics2_has_skull_bomb(self, player):
return self.has("SKULL BOMB", player)
def _hylics2_has_tower_key(self, player):
return self.has("TOWER KEY", player)
def _hylics2_has_deep_key(self, player):
return self.has("DEEP KEY", player)
def _hylics2_has_upper_house_key(self, player):
return self.has("UPPER HOUSE KEY", player)
def _hylics2_has_clicker(self, player):
return self.has("CLICKER", player)
def _hylics2_has_tokens(self, player):
return self.has("SAGE TOKEN", player, 3)
def _hylics2_has_charge_up(self, player):
return self.has("CHARGE UP", player)
def _hylics2_has_cup(self, player):
return self.has("PAPER CUP", player, 1)
def _hylics2_has_1_member(self, player):
return self.has("Pongorma", player) or self.has("Dedusmuln", player) or self.has("Somsnosa", player)
def _hylics2_has_2_members(self, player):
return (self.has("Pongorma", player) and self.has("Dedusmuln", player)) or\
(self.has("Pongorma", player) and self.has("Somsnosa", player)) or\
(self.has("Dedusmuln", player) and self.has("Somsnosa", player))
def _hylics2_has_3_members(self, player):
return self.has("Pongorma", player) and self.has("Dedusmuln", player) and self.has("Somsnosa", player)
def _hylics2_enter_arcade2(self, player):
return self._hylics2_can_air_dash(player) and self._hylics2_has_airship(player)
def _hylics2_enter_wormpod(self, player):
return self._hylics2_has_airship(player) and self._hylics2_has_worm_room_key(player) and\
self._hylics2_has_paddle(player)
def _hylics2_enter_sageship(self, player):
return self._hylics2_has_skull_bomb(player) and self._hylics2_has_airship(player) and\
self._hylics2_has_paddle(player)
def _hylics2_enter_foglast(self, player):
return self._hylics2_enter_wormpod(player)
def _hylics2_enter_hylemxylem(self, player):
return self._hylics2_can_air_dash(player) and self._hylics2_enter_wormpod(player) and\
self._hylics2_has_bridge_key(player)
def set_rules(hylics2world):
world = hylics2world.world
player = hylics2world.player
# Afterlife
add_rule(world.get_location("Afterlife: TV", player),
lambda state: state._hylics2_has_cave_key(player))
# New Muldul
add_rule(world.get_location("New Muldul: Underground Chest", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("New Muldul: TV", player),
lambda state: state._hylics2_has_house_key(player))
add_rule(world.get_location("New Muldul: Upper House Chest 1", player),
lambda state: state._hylics2_has_upper_house_key(player))
add_rule(world.get_location("New Muldul: Upper House Chest 2", player),
lambda state: state._hylics2_has_upper_house_key(player))
# New Muldul Vault
add_rule(world.get_location("New Muldul: Rescued Blerol 1", player),
lambda state: (state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player)) and\
((state._hylics2_has_jail_key(player) and state._hylics2_has_paddle(player)) or\
(state._hylics2_has_bridge_key(player) and state._hylics2_has_worm_room_key(player))))
add_rule(world.get_location("New Muldul: Rescued Blerol 2", player),
lambda state: (state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player)) and\
((state._hylics2_has_jail_key(player) and state._hylics2_has_paddle(player)) or\
(state._hylics2_has_bridge_key(player) and state._hylics2_has_worm_room_key(player))))
add_rule(world.get_location("New Muldul: Vault Left Chest", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Right Chest", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Bomb", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
# Viewax's Edifice
add_rule(world.get_location("Viewax's Edifice: Canopic Jar", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Cave Sarcophagus", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Shielded Key", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Shielded Key", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Tower Pot", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Tower Jar", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Tower Chest", player),
lambda state: state._hylics2_has_paddle(player) and state._hylics2_has_tower_key(player))
add_rule(world.get_location("Viewax's Edifice: Viewax Pot", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Defeat Viewax", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: TV", player),
lambda state: state._hylics2_has_paddle(player) and state._hylics2_has_jail_key(player))
add_rule(world.get_location("Viewax's Edifice: Sage Fridge", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Viewax's Edifice: Sage Item 1", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Viewax's Edifice: Sage Item 2", player),
lambda state: state._hylics2_can_air_dash(player))
# Arcade 1
add_rule(world.get_location("Arcade 1: Key", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Coin Dash", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Burrito Alcove 1", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Burrito Alcove 2", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Behind Spikes Banana", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Pyramid Banana", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Moving Platforms Muscle Applique", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Bed Banana", player),
lambda state: state._hylics2_has_paddle(player))
# Airship
add_rule(world.get_location("Airship: Talk to Somsnosa", player),
lambda state: state._hylics2_has_worm_room_key(player))
# Foglast
add_rule(world.get_location("Foglast: Underground Sarcophagus", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: Shielded Key", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: TV", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_clicker(player))
add_rule(world.get_location("Foglast: Buy Clicker", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: Shielded Chest", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: Cave Fridge", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: Roof Sarcophagus", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Under Lair Sarcophagus 1", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Under Lair Sarcophagus 2", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Under Lair Sarcophagus 3", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Sage Sarcophagus", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Sage Item 1", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Sage Item 2", player),
lambda state: state._hylics2_can_air_dash(player) and state._hylics2_has_bridge_key(player))
# Drill Castle
add_rule(world.get_location("Drill Castle: Island Banana", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Drill Castle: Island Pot", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Drill Castle: Cave Sarcophagus", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Drill Castle: TV", player),
lambda state: state._hylics2_can_air_dash(player))
# Sage Labyrinth
add_rule(world.get_location("Sage Labyrinth: Sage Item 1", player),
lambda state: state._hylics2_has_deep_key(player))
add_rule(world.get_location("Sage Labyrinth: Sage Item 2", player),
lambda state: state._hylics2_has_deep_key(player))
add_rule(world.get_location("Sage Labyrinth: Sage Left Arm", player),
lambda state: state._hylics2_has_deep_key(player))
add_rule(world.get_location("Sage Labyrinth: Sage Right Arm", player),
lambda state: state._hylics2_has_deep_key(player))
add_rule(world.get_location("Sage Labyrinth: Sage Left Leg", player),
lambda state: state._hylics2_has_deep_key(player))
add_rule(world.get_location("Sage Labyrinth: Sage Right Leg", player),
lambda state: state._hylics2_has_deep_key(player))
# Sage Airship
add_rule(world.get_location("Sage Airship: TV", player),
lambda state: state._hylics2_has_tokens(player))
# Hylemxylem
add_rule(world.get_location("Hylemxylem: Upper Chamber Banana", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Across Upper Reservoir Chest", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Lower Reservoir Chest", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Lower Reservoir Burrito 1", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Lower Reservoir Burrito 2", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Lower Reservoir Hole Pot 1", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Lower Reservoir Hole Pot 2", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Lower Reservoir Hole Pot 3", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Lower Reservoir Hole Sarcophagus", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Upper Reservoir Burrito 1", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Upper Reservoir Burrito 2", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Drained Upper Reservoir Burrito 3", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
add_rule(world.get_location("Hylemxylem: Upper Reservoir Hole Key", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
# extra rules if Extra Items in Logic is enabled
if world.extra_items_in_logic[player]:
for i in world.get_region("Foglast", player).entrances:
add_rule(i, lambda state: state._hylics2_has_charge_up(player))
for i in world.get_region("Sage Airship", player).entrances:
add_rule(i, lambda state: state._hylics2_has_charge_up(player) and state._hylics2_has_cup(player) and\
state._hylics2_has_worm_room_key(player))
for i in world.get_region("Hylemxylem", player).entrances:
add_rule(i, lambda state: state._hylics2_has_charge_up(player) and state._hylics2_has_cup(player))
add_rule(world.get_location("Sage Labyrinth: Motor Hunter Sarcophagus", player),
lambda state: state._hylics2_has_charge_up(player) and state._hylics2_has_cup(player))
# extra rules if Shuffle Party Members is enabled
if world.party_shuffle[player]:
for i in world.get_region("Arcade Island", player).entrances:
add_rule(i, lambda state: state._hylics2_has_3_members(player))
for i in world.get_region("Foglast", player).entrances:
add_rule(i, lambda state: state._hylics2_has_3_members(player) or\
(state._hylics2_has_2_members(player) and state._hylics2_has_jail_key(player)))
for i in world.get_region("Sage Airship", player).entrances:
add_rule(i, lambda state: state._hylics2_has_3_members(player))
for i in world.get_region("Hylemxylem", player).entrances:
add_rule(i, lambda state: state._hylics2_has_3_members(player))
add_rule(world.get_location("Viewax's Edifice: Defeat Viewax", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("New Muldul: Rescued Blerol 1", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("New Muldul: Rescued Blerol 2", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("New Muldul: Vault Left Chest", player),
lambda state: state._hylics2_has_3_members(player))
add_rule(world.get_location("New Muldul: Vault Right Chest", player),
lambda state: state._hylics2_has_3_members(player))
add_rule(world.get_location("New Muldul: Vault Bomb", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("Juice Ranch: Battle with Somsnosa", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("Juice Ranch: Somsnosa Joins", player),
lambda state: state._hylics2_has_2_members(player))
add_rule(world.get_location("Airship: Talk to Somsnosa", player),
lambda state: state._hylics2_has_3_members(player))
add_rule(world.get_location("Sage Labyrinth: Motor Hunter Sarcophagus", player),
lambda state: state._hylics2_has_3_members(player))
# extra rules if Shuffle Red Medallions is enabled
if world.medallion_shuffle[player]:
add_rule(world.get_location("New Muldul: Upper House Medallion", player),
lambda state: state._hylics2_has_upper_house_key(player))
add_rule(world.get_location("New Muldul: Vault Rear Left Medallion", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Rear Right Medallion", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Center Medallion", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Front Left Medallion", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("New Muldul: Vault Front Right Medallion", player),
lambda state: state._hylics2_enter_foglast(player) and state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Viewax's Edifice: Fort Wall Medallion", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Jar Medallion", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Viewax's Edifice: Sage Chair Medallion", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Arcade 1: Lonely Medallion", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Arcade 1: Alcove Medallion", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Foglast: Under Lair Medallion", player),
lambda state: state._hylics2_has_bridge_key(player))
add_rule(world.get_location("Foglast: Mid-Air Medallion", player),
lambda state: state._hylics2_can_air_dash(player))
add_rule(world.get_location("Foglast: Top of Tower Medallion", player),
lambda state: state._hylics2_has_paddle(player))
add_rule(world.get_location("Hylemxylem: Lower Reservoir Hole Medallion", player),
lambda state: state._hylics2_has_upper_chamber_key(player))
# extra rules is Shuffle Red Medallions and Party Shuffle are enabled
if world.party_shuffle[player] and world.medallion_shuffle[player]:
add_rule(world.get_location("New Muldul: Vault Rear Left Medallion", player),
lambda state: state._hylics2_has_jail_key(player))
add_rule(world.get_location("New Muldul: Vault Rear Right Medallion", player),
lambda state: state._hylics2_has_jail_key(player))
add_rule(world.get_location("New Muldul: Vault Center Medallion", player),
lambda state: state._hylics2_has_jail_key(player))
add_rule(world.get_location("New Muldul: Vault Front Left Medallion", player),
lambda state: state._hylics2_has_jail_key(player))
add_rule(world.get_location("New Muldul: Vault Front Right Medallion", player),
lambda state: state._hylics2_has_jail_key(player))
# entrances
for i in world.get_region("Airship", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Arcade Island", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player) and state._hylics2_can_air_dash(player))
for i in world.get_region("Worm Pod", player).entrances:
add_rule(i, lambda state: state._hylics2_enter_wormpod(player))
for i in world.get_region("Foglast", player).entrances:
add_rule(i, lambda state: state._hylics2_enter_foglast(player))
for i in world.get_region("Sage Labyrinth", player).entrances:
add_rule(i, lambda state: state._hylics2_has_skull_bomb(player))
for i in world.get_region("Sage Airship", player).entrances:
add_rule(i, lambda state: state._hylics2_enter_sageship(player))
for i in world.get_region("Hylemxylem", player).entrances:
add_rule(i, lambda state: state._hylics2_enter_hylemxylem(player))
# random start logic (default)
if ((not world.random_start[player]) or \
(world.random_start[player] and hylics2world.start_location == "Waynehouse")):
# entrances
for i in world.get_region("Viewax", player).entrances:
add_rule(i, lambda state: state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player))
for i in world.get_region("TV Island", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Shield Facility", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Juice Ranch", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
# random start logic (Viewax's Edifice)
elif (world.random_start[player] and hylics2world.start_location == "Viewax's Edifice"):
for i in world.get_region("Waynehouse", player).entrances:
add_rule(i, lambda state: state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player))
for i in world.get_region("New Muldul", player).entrances:
add_rule(i, lambda state: state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player))
for i in world.get_region("New Muldul Vault", player).entrances:
add_rule(i, lambda state: state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player))
for i in world.get_region("Drill Castle", player).entrances:
add_rule(i, lambda state: state._hylics2_can_air_dash(player) or state._hylics2_has_airship(player))
for i in world.get_region("TV Island", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Shield Facility", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Juice Ranch", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Sage Labyrinth", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
# random start logic (TV Island)
elif (world.random_start[player] and hylics2world.start_location == "TV Island"):
for i in world.get_region("Waynehouse", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("New Muldul", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("New Muldul Vault", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Drill Castle", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Viewax", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Shield Facility", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Juice Ranch", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Sage Labyrinth", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
# random start logic (Shield Facility)
elif (world.random_start[player] and hylics2world.start_location == "Shield Facility"):
for i in world.get_region("Waynehouse", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("New Muldul", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("New Muldul Vault", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Drill Castle", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Viewax", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("TV Island", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))
for i in world.get_region("Sage Labyrinth", player).entrances:
add_rule(i, lambda state: state._hylics2_has_airship(player))

246
worlds/hylics2/__init__.py Normal file
View File

@ -0,0 +1,246 @@
import random
from typing import Dict, Any
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, RegionType
from worlds.generic.Rules import set_rule
from ..AutoWorld import World, WebWorld
from . import Items, Locations, Options, Rules, Exits
class Hylics2Web(WebWorld):
theme = "ocean"
tutorials = [Tutorial(
"Multiworld Setup Guide",
"A guide to settings up the Hylics 2 randomizer connected to an Archipelago Multiworld",
"English",
"setup_en.md",
"setup/en",
["TRPG"]
)]
class Hylics2World(World):
"""
Hylics 2 is a surreal and unusual RPG, with a bizarre yet unique visual style. Play as Wayne,
travel the world, and gather your allies to defeat the nefarious Gibby in his Hylemxylem!
"""
game: str = "Hylics 2"
web = Hylics2Web()
all_items = {**Items.item_table, **Items.gesture_item_table, **Items.party_item_table,
**Items.medallion_item_table}
all_locations = {**Locations.location_table, **Locations.tv_location_table, **Locations.party_location_table,
**Locations.medallion_location_table}
item_name_to_id = {data["name"]: item_id for item_id, data in all_items.items()}
location_name_to_id = {data["name"]: loc_id for loc_id, data in all_locations.items()}
option_definitions = Options.hylics2_options
topology_present: bool = True
remote_items: bool = True
remote_start_inventory: bool = True
data_version: 1
start_location = "Waynehouse"
def set_rules(self):
Rules.set_rules(self)
def create_item(self, name: str) -> "Hylics2Item":
item_id: int = self.item_name_to_id[name]
return Hylics2Item(name, self.all_items[item_id]["classification"], item_id, player=self.player)
def add_item(self, name: str, classification: ItemClassification, code: int) -> "Item":
return Hylics2Item(name, classification, code, self.player)
def create_event(self, event: str):
return Hylics2Item(event, ItemClassification.progression_skip_balancing, None, self.player)
# set random starting location if option is enabled
def generate_early(self):
if self.world.random_start[self.player]:
i = self.world.random.randint(0, 3)
if i == 0:
self.start_location = "Waynehouse"
elif i == 1:
self.start_location = "Viewax's Edifice"
elif i == 2:
self.start_location = "TV Island"
elif i == 3:
self.start_location = "Shield Facility"
def generate_basic(self):
# create location for beating the game and place Victory event there
loc = Location(self.player, "Defeat Gibby", None, self.world.get_region("Hylemxylem", self.player))
loc.place_locked_item(self.create_event("Victory"))
set_rule(loc, lambda state: state._hylics2_has_upper_chamber_key(self.player)
and state._hylics2_has_vessel_room_key(self.player))
self.world.get_region("Hylemxylem", self.player).locations.append(loc)
self.world.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
# create item pool
pool = []
# add regular items
for i, data in Items.item_table.items():
if data["count"] > 0:
for j in range(data["count"]):
pool.append(self.add_item(data["name"], data["classification"], i))
# add party members if option is enabled
if self.world.party_shuffle[self.player]:
for i, data in Items.party_item_table.items():
pool.append(self.add_item(data["name"], data["classification"], i))
# handle gesture shuffle options
if self.world.gesture_shuffle[self.player] == 2: # vanilla locations
gestures = Items.gesture_item_table
self.world.get_location("Waynehouse: TV", self.player)\
.place_locked_item(self.add_item(gestures[200678]["name"], gestures[200678]["classification"], 200678))
self.world.get_location("Afterlife: TV", self.player)\
.place_locked_item(self.add_item(gestures[200683]["name"], gestures[200683]["classification"], 200683))
self.world.get_location("New Muldul: TV", self.player)\
.place_locked_item(self.add_item(gestures[200679]["name"], gestures[200679]["classification"], 200679))
self.world.get_location("Viewax's Edifice: TV", self.player)\
.place_locked_item(self.add_item(gestures[200680]["name"], gestures[200680]["classification"], 200680))
self.world.get_location("TV Island: TV", self.player)\
.place_locked_item(self.add_item(gestures[200681]["name"], gestures[200681]["classification"], 200681))
self.world.get_location("Juice Ranch: TV", self.player)\
.place_locked_item(self.add_item(gestures[200682]["name"], gestures[200682]["classification"], 200682))
self.world.get_location("Foglast: TV", self.player)\
.place_locked_item(self.add_item(gestures[200684]["name"], gestures[200684]["classification"], 200684))
self.world.get_location("Drill Castle: TV", self.player)\
.place_locked_item(self.add_item(gestures[200688]["name"], gestures[200688]["classification"], 200688))
self.world.get_location("Sage Airship: TV", self.player)\
.place_locked_item(self.add_item(gestures[200685]["name"], gestures[200685]["classification"], 200685))
elif self.world.gesture_shuffle[self.player] == 1: # TVs only
gestures = list(Items.gesture_item_table.items())
tvs = list(Locations.tv_location_table.items())
# if Extra Items in Logic is enabled place CHARGE UP first and make sure it doesn't get
# placed at Sage Airship: TV
if self.world.extra_items_in_logic[self.player]:
tv = self.world.random.choice(tvs)
gest = gestures.index((200681, Items.gesture_item_table[200681]))
while tv[1]["name"] == "Sage Airship: TV":
tv = self.world.random.choice(tvs)
self.world.get_location(tv[1]["name"], self.player)\
.place_locked_item(self.add_item(gestures[gest][1]["name"], gestures[gest][1]["classification"],
gestures[gest]))
gestures.remove(gestures[gest])
tvs.remove(tv)
for i in range(len(gestures)):
gest = self.world.random.choice(gestures)
tv = self.world.random.choice(tvs)
self.world.get_location(tv[1]["name"], self.player)\
.place_locked_item(self.add_item(gest[1]["name"], gest[1]["classification"], gest[1]))
gestures.remove(gest)
tvs.remove(tv)
else: # add gestures to pool like normal
for i, data in Items.gesture_item_table.items():
pool.append(self.add_item(data["name"], data["classification"], i))
# add '10 Bones' items if medallion shuffle is enabled
if self.world.medallion_shuffle[self.player]:
for i, data in Items.medallion_item_table.items():
for j in range(data["count"]):
pool.append(self.add_item(data["name"], data["classification"], i))
# add to world's pool
self.world.itempool += pool
def fill_slot_data(self) -> Dict[str, Any]:
slot_data: Dict[str, Any] = {
"party_shuffle": self.world.party_shuffle[self.player].value,
"medallion_shuffle": self.world.medallion_shuffle[self.player].value,
"random_start" : self.world.random_start[self.player].value,
"start_location" : self.start_location,
"death_link": self.world.death_link[self.player].value
}
return slot_data
def create_regions(self) -> None:
region_table: Dict[int, Region] = {
0: Region("Menu", RegionType.Generic, "Menu", self.player, self.world),
1: Region("Afterlife", RegionType.Generic, "Afterlife", self.player, self.world),
2: Region("Waynehouse", RegionType.Generic, "Waynehouse", self.player, self.world),
3: Region("World", RegionType.Generic, "World", self.player, self.world),
4: Region("New Muldul", RegionType.Generic, "New Muldul", self.player, self.world),
5: Region("New Muldul Vault", RegionType.Generic, "New Muldul Vault", self.player, self.world),
6: Region("Viewax", RegionType.Generic, "Viewax's Edifice", self.player, self.world),
7: Region("Airship", RegionType.Generic, "Airship", self.player, self.world),
8: Region("Arcade Island", RegionType.Generic, "Arcade Island", self.player, self.world),
9: Region("TV Island", RegionType.Generic, "TV Island", self.player, self.world),
10: Region("Juice Ranch", RegionType.Generic, "Juice Ranch", self.player, self.world),
11: Region("Shield Facility", RegionType.Generic, "Shield Facility", self.player, self.world),
12: Region("Worm Pod", RegionType.Generic, "Worm Pod", self.player, self.world),
13: Region("Foglast", RegionType.Generic, "Foglast", self.player, self.world),
14: Region("Drill Castle", RegionType.Generic, "Drill Castle", self.player, self.world),
15: Region("Sage Labyrinth", RegionType.Generic, "Sage Labyrinth", self.player, self.world),
16: Region("Sage Airship", RegionType.Generic, "Sage Airship", self.player, self.world),
17: Region("Hylemxylem", RegionType.Generic, "Hylemxylem", self.player, self.world)
}
# create regions from table
for i, reg in region_table.items():
self.world.regions.append(reg)
# get all exits per region
for j, exits in Exits.region_exit_table.items():
if j == i:
for k in exits:
# create entrance and connect it to parent and destination regions
ent = Entrance(self.player, k, reg)
reg.exits.append(ent)
if k == "New Game" and self.world.random_start[self.player]:
if self.start_location == "Waynehouse":
ent.connect(region_table[2])
elif self.start_location == "Viewax's Edifice":
ent.connect(region_table[6])
elif self.start_location == "TV Island":
ent.connect(region_table[9])
elif self.start_location == "Shield Facility":
ent.connect(region_table[11])
else:
for name, num in Exits.exit_lookup_table.items():
if k == name:
ent.connect(region_table[num])
# add regular locations
for i, data in Locations.location_table.items():
region_table[data["region"]].locations\
.append(Hylics2Location(self.player, data["name"], i, region_table[data["region"]]))
for i, data in Locations.tv_location_table.items():
region_table[data["region"]].locations\
.append(Hylics2Location(self.player, data["name"], i, region_table[data["region"]]))
# add party member locations if option is enabled
if self.world.party_shuffle[self.player]:
for i, data in Locations.party_location_table.items():
region_table[data["region"]].locations\
.append(Hylics2Location(self.player, data["name"], i, region_table[data["region"]]))
# add medallion locations if option is enabled
if self.world.medallion_shuffle[self.player]:
for i, data in Locations.medallion_location_table.items():
region_table[data["region"]].locations\
.append(Hylics2Location(self.player, data["name"], i, region_table[data["region"]]))
class Hylics2Location(Location):
game: str = "Hylics 2"
class Hylics2Item(Item):
game: str = "Hylics 2"

View File

@ -0,0 +1,17 @@
# Hylics 2
## Where is the settings page?
The [player settings page for this game](../player-settings) contains all the options you need to configure and export a config file.
## What does randomization do to this game?
In Hylics 2, all unique items, equipment and skills are randomized. This includes items in chests, items that are freely standing in the world, items recieved from talking to certain characters, gestures learned from TVs, and so on. Items recieved from completing battles are not randomized, with the exception of the Jail Key recieved from defeating Viewax.
## What Hylics 2 items can appear in other players' worlds?
Consumable items, key items, gloves, accessories, and gestures can appear in other players' worlds.
## What does another world's item look like in Hylics 2?
All items retain their original appearance. You won't know if an item belongs to another player until you collect it.

View File

@ -0,0 +1,35 @@
# Hylics 2 Randomizer Setup Guide
## Required Software
- Hylics 2 from: [Steam](https://store.steampowered.com/app/1286710/Hylics_2/) or [itch.io](https://mason-lindroth.itch.io/hylics-2)
- BepInEx from: [GitHub](https://github.com/BepInEx/BepInEx/releases)
- Archipelago Mod for Hylics 2 from: [GitHub](https://github.com/TRPG0/ArchipelagoHylics2)
## Instructions (Windows)
1. Download and install BepInEx 5 (32-bit, version 5.4.20 or newer) to your Hylics 2 root folder. *Do not use any pre-release versions of BepInEx 6.*
2. Start Hylics 2 once so that BepInEx can create its required configuration files.
3. Download the latest version of ArchipelagoHylics2 from the [Releases](https://github.com/TRPG0/ArchipelagoHylics2/releases) page and extract the contents of the zip file into `BepInEx\plugins`.
4. Start Hylics 2 again. To verify that the mod is working, begin a new game or load a save file.
## Connecting
To connect to an Archipelago server, open the in-game console (default key: `/`) and use the command `/connect [address:port] [name] [password]`. The port and password are both optional - if no port is provided then the default port of 38281 is used.
**Make sure that you have connected to a server at least once before attempting to check any locations.**
## Other Commands
There are a few additional commands that can be used while playing Hylics 2 randomizer:
- `/disconnect` - Disconnect from an Archipelago server.
- `/popups` - Enables or disables in-game messages when an item is found or recieved.
- `/airship` - Resummons the airship at the dock above New Muldul and teleports Wayne to it, in case the player gets stuck. Player must have the DOCK KEY to use this command.
- `/respawn` - Moves Wayne back to the spawn position of the current area in case you get stuck. `/respawn home` will teleport Wayne back to his original starting position.
- `/checked [region]` - States how many locations have been checked in a given region. If no region is given, then the player's location will be used.
- `/deathlink` - Enables or disables DeathLink.
- `/help [command]` - Lists a command, it's description, and it's required arguments (if any). If no command is given, all commands will be displayed.
- `![command]` - Entering any command with an `!` at the beginning allows for remotely sending commands to the server.