| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  | from typing import Dict, List, Set, Any | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | from collections import Counter | 
					
						
							|  |  |  | from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  | from worlds.AutoWorld import World, WebWorld | 
					
						
							|  |  |  | from .Items import base_id, item_table, group_table, tears_set, reliquary_set, event_table | 
					
						
							|  |  |  | from .Locations import location_table | 
					
						
							|  |  |  | from .Rooms import room_table, door_table | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | from .Rules import rules | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  | from worlds.generic.Rules import set_rule, add_rule | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | from .Options import blasphemous_options | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  | from .Vanilla import unrandomized_dict, junk_locations, thorn_set, skill_dict | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BlasphemousWeb(WebWorld): | 
					
						
							|  |  |  |     theme = "stone" | 
					
						
							|  |  |  |     tutorials = [Tutorial( | 
					
						
							|  |  |  |         "Multiworld Setup Guide", | 
					
						
							|  |  |  |         "A guide to setting up the Blasphemous randomizer connected to an Archipelago Multiworld", | 
					
						
							|  |  |  |         "English", | 
					
						
							|  |  |  |         "setup_en.md", | 
					
						
							|  |  |  |         "setup/en", | 
					
						
							|  |  |  |         ["TRPG"] | 
					
						
							|  |  |  |     )] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BlasphemousWorld(World): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Blasphemous is a challenging Metroidvania set in the cursed land of Cvstodia. Play as the Penitent One, trapped | 
					
						
							|  |  |  |     in an endless cycle of death and rebirth, and free the world from it's terrible fate in your quest to break | 
					
						
							|  |  |  |     your eternal damnation! | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     game: str = "Blasphemous" | 
					
						
							|  |  |  |     web = BlasphemousWeb() | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     data_version = 2 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     item_name_to_id = {item["name"]: (base_id + index) for index, item in enumerate(item_table)} | 
					
						
							|  |  |  |     location_name_to_id = {loc["name"]: (base_id + index) for index, loc in enumerate(location_table)} | 
					
						
							|  |  |  |     location_name_to_game_id = {loc["name"]: loc["game_id"] for loc in location_table} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_groups = group_table | 
					
						
							|  |  |  |     option_definitions = blasphemous_options | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     required_client_version = (0, 4, 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, multiworld, player): | 
					
						
							|  |  |  |         super(BlasphemousWorld, self).__init__(multiworld, player) | 
					
						
							|  |  |  |         self.start_room: str = "D17Z01S01" | 
					
						
							|  |  |  |         self.door_connections: Dict[str, str] = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self): | 
					
						
							|  |  |  |         rules(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str) -> "BlasphemousItem": | 
					
						
							|  |  |  |         item_id: int = self.item_name_to_id[name] | 
					
						
							|  |  |  |         id = item_id - base_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return BlasphemousItem(name, item_table[id]["classification"], item_id, player=self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_event(self, event: str): | 
					
						
							|  |  |  |         return BlasphemousItem(event, ItemClassification.progression_skip_balancing, None, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							|  |  |  |         return self.multiworld.random.choice(tears_set) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     def generate_early(self): | 
					
						
							|  |  |  |         world = self.multiworld | 
					
						
							|  |  |  |         player = self.player | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.starting_location[player].randomized: | 
					
						
							|  |  |  |             if world.starting_location[player].value == 6 and world.difficulty[player].value < 2: | 
					
						
							|  |  |  |                 raise Exception(f"[Blasphemous - '{world.get_player_name(player)}'] {world.starting_location[player]}" | 
					
						
							|  |  |  |                                 " cannot be chosen if Difficulty is lower than Hard.") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             if (world.starting_location[player].value == 0 or world.starting_location[player].value == 6) \ | 
					
						
							|  |  |  |                 and world.dash_shuffle[player]: | 
					
						
							|  |  |  |                     raise Exception(f"[Blasphemous - '{world.get_player_name(player)}'] {world.starting_location[player]}" | 
					
						
							|  |  |  |                                     " cannot be chosen if Shuffle Dash is enabled.") | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if world.starting_location[player].value == 3 and world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |                 raise Exception(f"[Blasphemous - '{world.get_player_name(player)}'] {world.starting_location[player]}" | 
					
						
							|  |  |  |                                 " cannot be chosen if Shuffle Wall Climb is enabled.") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             locations: List[int] = [ 0, 1, 2, 3, 4, 5, 6 ] | 
					
						
							|  |  |  |             invalid: bool = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if world.difficulty[player].value < 2: | 
					
						
							|  |  |  |                 locations.remove(6) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if world.dash_shuffle[player]: | 
					
						
							|  |  |  |                 locations.remove(0) | 
					
						
							|  |  |  |                 if 6 in locations: | 
					
						
							|  |  |  |                     locations.remove(6) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |                 locations.remove(3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if world.starting_location[player].value == 6 and world.difficulty[player].value < 2: | 
					
						
							|  |  |  |                 invalid = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (world.starting_location[player].value == 0 or world.starting_location[player].value == 6) \ | 
					
						
							|  |  |  |                 and world.dash_shuffle[player]: | 
					
						
							|  |  |  |                     invalid = True | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if world.starting_location[player].value == 3 and world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |                 invalid = True | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             if invalid: | 
					
						
							|  |  |  |                 world.starting_location[player].value = world.random.choice(locations) | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.dash_shuffle[player]: | 
					
						
							|  |  |  |             world.push_precollected(self.create_item("Dash Ability")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |             world.push_precollected(self.create_item("Wall Climb Ability")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if world.skip_long_quests[player]: | 
					
						
							|  |  |  |             for loc in junk_locations: | 
					
						
							|  |  |  |                 world.exclude_locations[player].value.add(loc) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         start_rooms: Dict[int, str] = { | 
					
						
							|  |  |  |             0: "D17Z01S01", | 
					
						
							|  |  |  |             1: "D01Z02S01", | 
					
						
							|  |  |  |             2: "D02Z03S09", | 
					
						
							|  |  |  |             3: "D03Z03S11", | 
					
						
							|  |  |  |             4: "D04Z03S01", | 
					
						
							|  |  |  |             5: "D06Z01S09", | 
					
						
							|  |  |  |             6: "D20Z02S09" | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         self.start_room = start_rooms[world.starting_location[player].value] | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     def create_items(self): | 
					
						
							|  |  |  |         world = self.multiworld | 
					
						
							|  |  |  |         player = self.player | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         removed: int = 0 | 
					
						
							|  |  |  |         to_remove: List[str] = [ | 
					
						
							|  |  |  |             "Tears of Atonement (250)", | 
					
						
							|  |  |  |             "Tears of Atonement (300)", | 
					
						
							|  |  |  |             "Tears of Atonement (500)", | 
					
						
							|  |  |  |             "Tears of Atonement (500)", | 
					
						
							|  |  |  |             "Tears of Atonement (500)" | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         skipped_items = [] | 
					
						
							|  |  |  |         junk: int = 0 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         for item, count in world.start_inventory[player].value.items(): | 
					
						
							|  |  |  |             for _ in range(count): | 
					
						
							|  |  |  |                 skipped_items.append(item) | 
					
						
							|  |  |  |                 junk += 1 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         skipped_items.extend(unrandomized_dict.values()) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.thorn_shuffle[player] == 2: | 
					
						
							|  |  |  |             for i in range(8): | 
					
						
							|  |  |  |                 skipped_items.append("Thorn Upgrade") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.dash_shuffle[player]: | 
					
						
							|  |  |  |             skipped_items.append(to_remove[removed]) | 
					
						
							|  |  |  |             removed += 1 | 
					
						
							|  |  |  |         elif not world.dash_shuffle[player]: | 
					
						
							|  |  |  |             skipped_items.append("Dash Ability") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |             skipped_items.append(to_remove[removed]) | 
					
						
							|  |  |  |             removed += 1 | 
					
						
							|  |  |  |         elif not world.wall_climb_shuffle[player]: | 
					
						
							|  |  |  |             skipped_items.append("Wall Climb Ability") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.reliquary_shuffle[player]: | 
					
						
							|  |  |  |             skipped_items.extend(reliquary_set) | 
					
						
							|  |  |  |         elif world.reliquary_shuffle[player]: | 
					
						
							|  |  |  |             for i in range(3): | 
					
						
							|  |  |  |                 skipped_items.append(to_remove[removed]) | 
					
						
							|  |  |  |                 removed += 1 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.boots_of_pleading[player]: | 
					
						
							|  |  |  |             skipped_items.append("Boots of Pleading") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.purified_hand[player]: | 
					
						
							|  |  |  |             skipped_items.append("Purified Hand of the Nun") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.start_wheel[player]: | 
					
						
							|  |  |  |             skipped_items.append("The Young Mason's Wheel") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.skill_randomizer[player]: | 
					
						
							|  |  |  |             skipped_items.extend(skill_dict.values()) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         counter = Counter(skipped_items) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         pool = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for item in item_table: | 
					
						
							|  |  |  |             count = item["count"] - counter[item["name"]] | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if count <= 0: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 for i in range(count): | 
					
						
							|  |  |  |                     pool.append(self.create_item(item["name"])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         for _ in range(junk): | 
					
						
							|  |  |  |             pool.append(self.create_item(self.get_filler_item_name())) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         world.itempool += pool | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     def pre_fill(self): | 
					
						
							|  |  |  |         world = self.multiworld | 
					
						
							|  |  |  |         player = self.player | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         self.place_items_from_dict(unrandomized_dict) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.thorn_shuffle[player] == 2: | 
					
						
							|  |  |  |             self.place_items_from_set(thorn_set, "Thorn Upgrade") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.start_wheel[player]: | 
					
						
							|  |  |  |             world.get_location("Beginning gift", player)\ | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |                 .place_locked_item(self.create_item("The Young Mason's Wheel")) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if not world.skill_randomizer[player]: | 
					
						
							|  |  |  |             self.place_items_from_dict(skill_dict) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.thorn_shuffle[player] == 1: | 
					
						
							|  |  |  |             world.local_items[player].value.add("Thorn Upgrade") | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |          | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def place_items_from_set(self, location_set: Set[str], name: str): | 
					
						
							|  |  |  |         for loc in location_set: | 
					
						
							|  |  |  |             self.multiworld.get_location(loc, self.player)\ | 
					
						
							|  |  |  |                 .place_locked_item(self.create_item(name)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def place_items_from_dict(self, option_dict: Dict[str, str]): | 
					
						
							|  |  |  |         for loc, item in option_dict.items(): | 
					
						
							|  |  |  |             self.multiworld.get_location(loc, self.player)\ | 
					
						
							|  |  |  |                 .place_locked_item(self.create_item(item)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self) -> None: | 
					
						
							|  |  |  |         player = self.player | 
					
						
							|  |  |  |         world = self.multiworld | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |          | 
					
						
							|  |  |  |         menu_region = Region("Menu", player, world) | 
					
						
							|  |  |  |         misc_region = Region("Misc", player, world) | 
					
						
							|  |  |  |         world.regions += [menu_region, misc_region] | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         for room in room_table: | 
					
						
							|  |  |  |             region = Region(room, player, world) | 
					
						
							|  |  |  |             world.regions.append(region) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         menu_region.add_exits({self.start_room: "New Game"}) | 
					
						
							|  |  |  |         world.get_region(self.start_room, player).add_exits({"Misc": "Misc"}) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         for door in door_table: | 
					
						
							|  |  |  |             if door.get("OriginalDoor") is None: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 if not door["Id"] in self.door_connections.keys(): | 
					
						
							|  |  |  |                     self.door_connections[door["Id"]] = door["OriginalDoor"] | 
					
						
							|  |  |  |                     self.door_connections[door["OriginalDoor"]] = door["Id"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 parent_region: Region = self.get_room_from_door(door["Id"]) | 
					
						
							|  |  |  |                 target_region: Region = self.get_room_from_door(door["OriginalDoor"]) | 
					
						
							|  |  |  |                 parent_region.add_exits({ | 
					
						
							|  |  |  |                     target_region.name: door["Id"] | 
					
						
							|  |  |  |                 }, { | 
					
						
							|  |  |  |                     target_region.name: lambda x: door.get("VisibilityFlags") != 1 | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for index, loc in enumerate(location_table): | 
					
						
							|  |  |  |             if not world.boots_of_pleading[player] and loc["name"] == "BotSS: 2nd meeting with Redento": | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if not world.purified_hand[player] and loc["name"] == "MoM: Western room ledge": | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             region: Region = world.get_region(loc["room"], player) | 
					
						
							|  |  |  |             region.add_locations({loc["name"]: base_id + index}) | 
					
						
							|  |  |  |             #id = base_id + location_table.index(loc) | 
					
						
							|  |  |  |             #reg.locations.append(BlasphemousLocation(player, loc["name"], id, reg)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for e, r in event_table.items(): | 
					
						
							|  |  |  |             region: Region = world.get_region(r, player) | 
					
						
							|  |  |  |             event = BlasphemousLocation(player, e, None, region) | 
					
						
							|  |  |  |             event.show_in_spoiler = False | 
					
						
							|  |  |  |             event.place_locked_item(self.create_event(e)) | 
					
						
							|  |  |  |             region.locations.append(event) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for door in door_table: | 
					
						
							|  |  |  |             region: Region = self.get_room_from_door(self.door_connections[door["Id"]]) | 
					
						
							|  |  |  |             event = BlasphemousLocation(player, door["Id"], None, region) | 
					
						
							|  |  |  |             event.show_in_spoiler = False | 
					
						
							|  |  |  |             event.place_locked_item(self.create_event(door["Id"])) | 
					
						
							|  |  |  |             add_rule(event, lambda state: state.can_reach(self.get_connected_door(door["Id"])), player) | 
					
						
							|  |  |  |             region.locations.append(event) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         victory = Location(player, "His Holiness Escribar", None, world.get_region("D07Z01S03", player)) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |         victory.place_locked_item(self.create_event("Victory")) | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         world.get_region("D07Z01S03", player).locations.append(victory) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         if world.ending[self.player].value == 1: | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |             set_rule(victory, lambda state: state.has("Thorn Upgrade", player, 8)) | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         elif world.ending[self.player].value == 2: | 
					
						
							|  |  |  |             set_rule(victory, lambda state: state.has("Thorn Upgrade", player, 8) and | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |                 state.has("Holy Wound of Abnegation", player)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         world.completion_condition[self.player] = lambda state: state.has("Victory", player) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_room_from_door(self, door: str) -> Region: | 
					
						
							|  |  |  |         return self.multiworld.get_region(door.split("[")[0], self.player) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |     def get_connected_door(self, door: str) -> Entrance: | 
					
						
							|  |  |  |         return self.multiworld.get_entrance(self.door_connections[door], self.player) | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |     def fill_slot_data(self) -> Dict[str, Any]: | 
					
						
							|  |  |  |         slot_data: Dict[str, Any] = {} | 
					
						
							|  |  |  |         locations = [] | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         doors: Dict[str, str] = {} | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |         world = self.multiworld | 
					
						
							|  |  |  |         player = self.player | 
					
						
							|  |  |  |         thorns: bool = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if world.thorn_shuffle[player].value == 2: | 
					
						
							|  |  |  |             thorns = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for loc in world.get_filled_locations(player): | 
					
						
							|  |  |  |             if loc.item.code == None: | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 data = { | 
					
						
							|  |  |  |                     "id": self.location_name_to_game_id[loc.name], | 
					
						
							|  |  |  |                     "ap_id": loc.address, | 
					
						
							|  |  |  |                     "name": loc.item.name, | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |                     "player_name": world.player_name[loc.item.player], | 
					
						
							|  |  |  |                     "type": int(loc.item.classification) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 locations.append(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         config = { | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             "LogicDifficulty": world.difficulty[player].value, | 
					
						
							|  |  |  |             "StartingLocation": world.starting_location[player].value, | 
					
						
							|  |  |  |             "VersionCreated": "AP", | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             "UnlockTeleportation": bool(world.prie_dieu_warp[player].value), | 
					
						
							|  |  |  |             "AllowHints": bool(world.corpse_hints[player].value), | 
					
						
							|  |  |  |             "AllowPenitence": bool(world.penitence[player].value), | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             "ShuffleReliquaries": bool(world.reliquary_shuffle[player].value), | 
					
						
							|  |  |  |             "ShuffleBootsOfPleading": bool(world.boots_of_pleading[player].value), | 
					
						
							|  |  |  |             "ShufflePurifiedHand": bool(world.purified_hand[player].value), | 
					
						
							|  |  |  |             "ShuffleDash": bool(world.dash_shuffle[player].value), | 
					
						
							|  |  |  |             "ShuffleWallClimb": bool(world.wall_climb_shuffle[player].value), | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             "ShuffleSwordSkills": bool(world.skill_randomizer[player].value), | 
					
						
							|  |  |  |             "ShuffleThorns": thorns, | 
					
						
							|  |  |  |             "JunkLongQuests": bool(world.skip_long_quests[player].value), | 
					
						
							|  |  |  |             "StartWithWheel": bool(world.start_wheel[player].value), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             "EnemyShuffleType": world.enemy_randomizer[player].value, | 
					
						
							|  |  |  |             "MaintainClass": bool(world.enemy_groups[player].value), | 
					
						
							|  |  |  |             "AreaScaling": bool(world.enemy_scaling[player].value), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             "BossShuffleType": 0, | 
					
						
							|  |  |  |             "DoorShuffleType": 0 | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |         slot_data = { | 
					
						
							|  |  |  |             "locations": locations, | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             "doors": doors, | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |             "cfg": config, | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:26 -06:00
										 |  |  |             "ending": world.ending[self.player].value, | 
					
						
							|  |  |  |             "death_link": bool(world.death_link[self.player].value) | 
					
						
							| 
									
										
										
										
											2023-02-23 23:33:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BlasphemousItem(Item): | 
					
						
							|  |  |  |     game: str = "Blasphemous" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BlasphemousLocation(Location): | 
					
						
							|  |  |  |     game: str = "Blasphemous" |