| 
									
										
										
										
											2023-04-07 12:01:26 -06:00
										 |  |  | from typing import Dict, List, Any | 
					
						
							| 
									
										
										
										
											2023-02-13 18:06:43 -06:00
										 |  |  | from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | from worlds.generic.Rules import set_rule | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  | from . import Exits, Items, Locations, Rules | 
					
						
							|  |  |  | from .Options import Hylics2Options | 
					
						
							| 
									
										
										
										
											2023-11-14 23:03:40 -07:00
										 |  |  | from worlds.AutoWorld import WebWorld, World | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  |     Hylics 2 is a surreal and unusual RPG, with a bizarre yet unique visual style. Play as Wayne, | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |     travel the world, and gather your allies to defeat the nefarious Gibby in his Hylemxylem! | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     game: str = "Hylics 2" | 
					
						
							|  |  |  |     web = Hylics2Web() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  |     all_items = {**Items.item_table, **Items.gesture_item_table, **Items.party_item_table, | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         **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()} | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     options_dataclass = Hylics2Options | 
					
						
							|  |  |  |     options: Hylics2Options | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 00:08:40 -06:00
										 |  |  |     data_version = 3 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 create_event(self, event: str): | 
					
						
							|  |  |  |         return Hylics2Item(event, ItemClassification.progression_skip_balancing, None, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |     # set random starting location if option is enabled | 
					
						
							|  |  |  |     def generate_early(self): | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.random_start: | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             i = self.random.randint(0, 3) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             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" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 12:01:26 -06:00
										 |  |  |     def create_items(self): | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         # create item pool | 
					
						
							|  |  |  |         pool = [] | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         # add regular items | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |         for item in Items.item_table.values(): | 
					
						
							|  |  |  |             if item["count"] > 0: | 
					
						
							|  |  |  |                 for _ in range(item["count"]): | 
					
						
							|  |  |  |                     pool.append(self.create_item(item["name"])) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # add party members if option is enabled | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.party_shuffle: | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             for item in Items.party_item_table.values(): | 
					
						
							|  |  |  |                 pool.append(self.create_item(item["name"])) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 12:01:26 -06:00
										 |  |  |         # handle gesture shuffle | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if not self.options.gesture_shuffle: # add gestures to pool like normal | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             for item in Items.gesture_item_table.values(): | 
					
						
							|  |  |  |                 pool.append(self.create_item(item["name"])) | 
					
						
							| 
									
										
										
										
											2023-04-07 12:01:26 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # add '10 Bones' items if medallion shuffle is enabled | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.medallion_shuffle: | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             for item in Items.medallion_item_table.values(): | 
					
						
							|  |  |  |                 for _ in range(item["count"]): | 
					
						
							|  |  |  |                     pool.append(self.create_item(item["name"])) | 
					
						
							| 
									
										
										
										
											2023-04-07 12:01:26 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # add to world's pool | 
					
						
							|  |  |  |         self.multiworld.itempool += pool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pre_fill(self): | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         # handle gesture shuffle options | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.gesture_shuffle == 2: # vanilla locations | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             gestures = Items.gesture_item_table | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Waynehouse: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("POROMER BLEB")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Afterlife: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("TELEDENUDATE")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("New Muldul: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("SOUL CRISPER")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Viewax's Edifice: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("TIME SIGIL")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("TV Island: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("CHARGE UP")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Juice Ranch: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("FATE SANDBOX")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Foglast: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("LINK MOLLUSC")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Drill Castle: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("NEMATODE INTERFACE")) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location("Sage Airship: TV", self.player)\ | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 .place_locked_item(self.create_item("BOMBO - GENESIS")) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         elif self.options.gesture_shuffle == 1: # TVs only | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             gestures = [gesture["name"] for gesture in Items.gesture_item_table.values()] | 
					
						
							|  |  |  |             tvs = [tv["name"] for tv in Locations.tv_location_table.values()] | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  |             # if Extra Items in Logic is enabled place CHARGE UP first and make sure it doesn't get | 
					
						
							| 
									
										
										
										
											2023-10-18 13:50:57 -06:00
										 |  |  |             # placed at Sage Airship: TV or Foglast: TV | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |             if self.options.extra_items_in_logic: | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |                 tv = self.random.choice(tvs) | 
					
						
							|  |  |  |                 while tv == "Sage Airship: TV" or tv == "Foglast: TV": | 
					
						
							|  |  |  |                     tv = self.random.choice(tvs) | 
					
						
							|  |  |  |                 self.multiworld.get_location(tv, self.player)\ | 
					
						
							|  |  |  |                     .place_locked_item(self.create_item("CHARGE UP")) | 
					
						
							|  |  |  |                 gestures.remove("CHARGE UP") | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |                 tvs.remove(tv) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 18:26:58 -06:00
										 |  |  |             self.random.shuffle(gestures) | 
					
						
							|  |  |  |             self.random.shuffle(tvs) | 
					
						
							|  |  |  |             while gestures: | 
					
						
							|  |  |  |                 gesture = gestures.pop() | 
					
						
							|  |  |  |                 tv = tvs.pop() | 
					
						
							|  |  |  |                 self.get_location(tv).place_locked_item(self.create_item(gesture)) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> Dict[str, Any]: | 
					
						
							|  |  |  |         slot_data: Dict[str, Any] = { | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |             "party_shuffle": self.options.party_shuffle.value, | 
					
						
							|  |  |  |             "medallion_shuffle": self.options.medallion_shuffle.value, | 
					
						
							|  |  |  |             "random_start" : self.options.random_start.value, | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             "start_location" : self.start_location, | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |             "death_link": self.options.death_link.value | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         } | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self) -> None: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         region_table: Dict[int, Region] = { | 
					
						
							| 
									
										
										
										
											2023-02-13 18:06:43 -06:00
										 |  |  |             0: Region("Menu", self.player, self.multiworld), | 
					
						
							|  |  |  |             1: Region("Afterlife", self.player, self.multiworld), | 
					
						
							|  |  |  |             2: Region("Waynehouse", self.player, self.multiworld), | 
					
						
							|  |  |  |             3: Region("World", self.player, self.multiworld), | 
					
						
							|  |  |  |             4: Region("New Muldul", self.player, self.multiworld), | 
					
						
							|  |  |  |             5: Region("New Muldul Vault", self.player, self.multiworld), | 
					
						
							|  |  |  |             6: Region("Viewax", self.player, self.multiworld, "Viewax's Edifice"), | 
					
						
							|  |  |  |             7: Region("Airship", self.player, self.multiworld), | 
					
						
							|  |  |  |             8: Region("Arcade Island", self.player, self.multiworld), | 
					
						
							|  |  |  |             9: Region("TV Island", self.player, self.multiworld), | 
					
						
							|  |  |  |             10: Region("Juice Ranch", self.player, self.multiworld), | 
					
						
							|  |  |  |             11: Region("Shield Facility", self.player, self.multiworld), | 
					
						
							|  |  |  |             12: Region("Worm Pod", self.player, self.multiworld), | 
					
						
							|  |  |  |             13: Region("Foglast", self.player, self.multiworld), | 
					
						
							|  |  |  |             14: Region("Drill Castle", self.player, self.multiworld), | 
					
						
							|  |  |  |             15: Region("Sage Labyrinth", self.player, self.multiworld), | 
					
						
							|  |  |  |             16: Region("Sage Airship", self.player, self.multiworld), | 
					
						
							|  |  |  |             17: Region("Hylemxylem", self.player, self.multiworld) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         # create regions from table | 
					
						
							|  |  |  |         for i, reg in region_table.items(): | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.regions.append(reg) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             # 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 | 
					
						
							| 
									
										
										
										
											2023-11-14 23:03:40 -07:00
										 |  |  |                         ent = Entrance(self.player, f"{reg.name} {k}", reg) | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |                         reg.exits.append(ent) | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |                         if k == "New Game" and self.options.random_start: | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |                             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"]])) | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |         # add party member locations if option is enabled | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.party_shuffle: | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             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 | 
					
						
							| 
									
										
										
										
											2024-04-18 10:40:53 -06:00
										 |  |  |         if self.options.medallion_shuffle: | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  |             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"]])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 21:04:01 -06:00
										 |  |  |         # create location for beating the game and place Victory event there | 
					
						
							|  |  |  |         loc = Location(self.player, "Defeat Gibby", None, self.multiworld.get_region("Hylemxylem", self.player)) | 
					
						
							|  |  |  |         loc.place_locked_item(self.create_event("Victory")) | 
					
						
							| 
									
										
										
										
											2023-10-18 13:50:57 -06:00
										 |  |  |         set_rule(loc, lambda state: ( | 
					
						
							|  |  |  |                 state.has("UPPER CHAMBER KEY", self.player) | 
					
						
							|  |  |  |                 and state.has("VESSEL ROOM KEY", self.player) | 
					
						
							|  |  |  |             )) | 
					
						
							| 
									
										
										
										
											2022-12-04 21:04:01 -06:00
										 |  |  |         self.multiworld.get_region("Hylemxylem", self.player).locations.append(loc) | 
					
						
							|  |  |  |         self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-12 23:51:25 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Hylics2Location(Location): | 
					
						
							|  |  |  |     game: str = "Hylics 2" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Hylics2Item(Item): | 
					
						
							| 
									
										
										
										
											2023-03-20 11:01:08 -05:00
										 |  |  |     game: str = "Hylics 2" |