| 
									
										
										
										
											2023-03-22 10:21:41 -04:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | from typing import List | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | from BaseClasses import Tutorial, ItemClassification | 
					
						
							|  |  |  | from Fill import fill_restrictive | 
					
						
							|  |  |  | from worlds.LauncherComponents import Component, components, Type, launch_subprocess | 
					
						
							|  |  |  | from worlds.AutoWorld import World, WebWorld | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | from .Items import * | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | from .Locations import * | 
					
						
							|  |  |  | from .Names import ItemName, LocationName, RegionName | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | from .OpenKH import patch_kh2 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | from .Options import KingdomHearts2Options | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | from .Regions import create_regions, connect_regions | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | from .Rules import * | 
					
						
							| 
									
										
										
										
											2024-01-16 07:12:33 -05:00
										 |  |  | from .Subclasses import KH2Item | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def launch_client(): | 
					
						
							|  |  |  |     from .Client import launch | 
					
						
							|  |  |  |     launch_subprocess(launch, name="KH2Client") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | components.append(Component("KH2 Client", "KH2Client", func=launch_client, component_type=Type.CLIENT)) | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class KingdomHearts2Web(WebWorld): | 
					
						
							|  |  |  |     tutorials = [Tutorial( | 
					
						
							|  |  |  |             "Multiworld Setup Guide", | 
					
						
							|  |  |  |             "A guide to playing Kingdom Hearts 2 Final Mix with Archipelago.", | 
					
						
							|  |  |  |             "English", | 
					
						
							|  |  |  |             "setup_en.md", | 
					
						
							|  |  |  |             "setup/en", | 
					
						
							|  |  |  |             ["JaredWeakStrike"] | 
					
						
							|  |  |  |     )] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class KH2World(World): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Kingdom Hearts II is an action role-playing game developed and published by Square Enix and released in 2005. | 
					
						
							|  |  |  |     It is the sequel to Kingdom Hearts and Kingdom Hearts: Chain of Memories, and like the two previous games, | 
					
						
							|  |  |  |     focuses on Sora and his friends' continued battle against the Darkness. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |     game = "Kingdom Hearts 2" | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |     web = KingdomHearts2Web() | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     required_client_version = (0, 4, 4) | 
					
						
							|  |  |  |     options_dataclass = KingdomHearts2Options | 
					
						
							|  |  |  |     options: KingdomHearts2Options | 
					
						
							|  |  |  |     item_name_to_id = {item: item_id | 
					
						
							|  |  |  |                        for item_id, item in enumerate(item_dictionary_table.keys(), 0x130000)} | 
					
						
							|  |  |  |     location_name_to_id = {item: location | 
					
						
							|  |  |  |                            for location, item in enumerate(all_locations.keys(), 0x130000)} | 
					
						
							| 
									
										
										
										
											2024-01-16 07:12:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |     item_name_groups = item_groups | 
					
						
							| 
									
										
										
										
											2024-01-16 07:12:33 -05:00
										 |  |  |     location_name_groups = location_groups | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |     visitlocking_dict: Dict[str, int] | 
					
						
							|  |  |  |     plando_locations: Dict[str, str] | 
					
						
							|  |  |  |     lucky_emblem_amount: int | 
					
						
							|  |  |  |     lucky_emblem_required: int | 
					
						
							|  |  |  |     bounties_required: int | 
					
						
							|  |  |  |     bounties_amount: int | 
					
						
							|  |  |  |     filler_items: List[str] | 
					
						
							|  |  |  |     item_quantity_dict: Dict[str, int] | 
					
						
							|  |  |  |     local_items: Dict[int, int] | 
					
						
							|  |  |  |     sora_ability_dict: Dict[str, int] | 
					
						
							|  |  |  |     goofy_ability_dict: Dict[str, int] | 
					
						
							|  |  |  |     donald_ability_dict: Dict[str, int] | 
					
						
							|  |  |  |     total_locations: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # growth_list: list[str] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |     def __init__(self, multiworld: "MultiWorld", player: int): | 
					
						
							|  |  |  |         super().__init__(multiworld, player) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         # random_super_boss_list List[str] | 
					
						
							|  |  |  |         # has to be in __init__ or else other players affect each other's bounties | 
					
						
							|  |  |  |         self.random_super_boss_list = list() | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |         self.growth_list = list() | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         # lists of KH2Item | 
					
						
							|  |  |  |         self.keyblade_ability_pool = list() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.goofy_get_bonus_abilities = list() | 
					
						
							|  |  |  |         self.goofy_weapon_abilities = list() | 
					
						
							|  |  |  |         self.donald_get_bonus_abilities = list() | 
					
						
							|  |  |  |         self.donald_weapon_abilities = list() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.slot_data_goofy_weapon = dict() | 
					
						
							|  |  |  |         self.slot_data_sora_weapon = dict() | 
					
						
							|  |  |  |         self.slot_data_donald_weapon = dict() | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> dict: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         for ability in self.slot_data_sora_weapon: | 
					
						
							|  |  |  |             if ability in self.sora_ability_dict and self.sora_ability_dict[ability] >= 1: | 
					
						
							|  |  |  |                 self.sora_ability_dict[ability] -= 1 | 
					
						
							|  |  |  |         self.donald_ability_dict = {k: v.quantity for k, v in DonaldAbility_Table.items()} | 
					
						
							|  |  |  |         for ability in self.slot_data_donald_weapon: | 
					
						
							|  |  |  |             if ability in self.donald_ability_dict and self.donald_ability_dict[ability] >= 1: | 
					
						
							|  |  |  |                 self.donald_ability_dict[ability] -= 1 | 
					
						
							|  |  |  |         self.goofy_ability_dict = {k: v.quantity for k, v in GoofyAbility_Table.items()} | 
					
						
							|  |  |  |         for ability in self.slot_data_goofy_weapon: | 
					
						
							|  |  |  |             if ability in self.goofy_ability_dict and self.goofy_ability_dict[ability] >= 1: | 
					
						
							|  |  |  |                 self.goofy_ability_dict[ability] -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         slot_data = self.options.as_dict("Goal", "FinalXemnas", "LuckyEmblemsRequired", "BountyRequired") | 
					
						
							|  |  |  |         slot_data.update({ | 
					
						
							|  |  |  |             "hitlist":                [],  # remove this after next update | 
					
						
							|  |  |  |             "PoptrackerVersionCheck": 4.3, | 
					
						
							|  |  |  |             "KeybladeAbilities":      self.sora_ability_dict, | 
					
						
							|  |  |  |             "StaffAbilities":         self.donald_ability_dict, | 
					
						
							|  |  |  |             "ShieldAbilities":        self.goofy_ability_dict, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str) -> Item: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Returns created KH2Item | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # data = item_dictionary_table[name] | 
					
						
							|  |  |  |         if name in progression_set: | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |             item_classification = ItemClassification.progression | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         elif name in useful_set: | 
					
						
							|  |  |  |             item_classification = ItemClassification.useful | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |         else: | 
					
						
							|  |  |  |             item_classification = ItemClassification.filler | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         created_item = KH2Item(name, item_classification, self.item_name_to_id[name], self.player) | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return created_item | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-08 16:39:24 -05:00
										 |  |  |     def create_event_item(self, name: str) -> Item: | 
					
						
							|  |  |  |         item_classification = ItemClassification.progression | 
					
						
							|  |  |  |         created_item = KH2Item(name, item_classification, None, self.player) | 
					
						
							|  |  |  |         return created_item | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |     def create_items(self) -> None: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Fills ItemPool and manages schmovement, random growth, visit locking and random starting visit locking. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.visitlocking_dict = visit_locking_dict["AllVisitLocking"].copy() | 
					
						
							|  |  |  |         if self.options.Schmovement != "level_0": | 
					
						
							|  |  |  |             for _ in range(self.options.Schmovement.value): | 
					
						
							|  |  |  |                 for name in Movement_Table.keys(): | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                     self.item_quantity_dict[name] -= 1 | 
					
						
							|  |  |  |                     self.growth_list.remove(name) | 
					
						
							|  |  |  |                     self.multiworld.push_precollected(self.create_item(name)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.RandomGrowth: | 
					
						
							|  |  |  |             max_growth = min(self.options.RandomGrowth.value, len(self.growth_list)) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             for _ in range(max_growth): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |                 random_growth = self.random.choice(self.growth_list) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                 self.item_quantity_dict[random_growth] -= 1 | 
					
						
							|  |  |  |                 self.growth_list.remove(random_growth) | 
					
						
							|  |  |  |                 self.multiworld.push_precollected(self.create_item(random_growth)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.Visitlocking == "no_visit_locking": | 
					
						
							|  |  |  |             for item, amount in visit_locking_dict["AllVisitLocking"].items(): | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                 for _ in range(amount): | 
					
						
							|  |  |  |                     self.multiworld.push_precollected(self.create_item(item)) | 
					
						
							|  |  |  |                     self.item_quantity_dict[item] -= 1 | 
					
						
							|  |  |  |                     self.visitlocking_dict[item] -= 1 | 
					
						
							|  |  |  |                     if self.visitlocking_dict[item] == 0: | 
					
						
							|  |  |  |                         self.visitlocking_dict.pop(item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         elif self.options.Visitlocking == "second_visit_locking": | 
					
						
							|  |  |  |             for item in visit_locking_dict["2VisitLocking"]: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                 self.item_quantity_dict[item] -= 1 | 
					
						
							|  |  |  |                 self.visitlocking_dict[item] -= 1 | 
					
						
							|  |  |  |                 if self.visitlocking_dict[item] == 0: | 
					
						
							|  |  |  |                     self.visitlocking_dict.pop(item) | 
					
						
							|  |  |  |                 self.multiworld.push_precollected(self.create_item(item)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         for _ in range(self.options.RandomVisitLockingItem.value): | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             if sum(self.visitlocking_dict.values()) <= 0: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             visitlocking_set = list(self.visitlocking_dict.keys()) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             item = self.random.choice(visitlocking_set) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             self.item_quantity_dict[item] -= 1 | 
					
						
							|  |  |  |             self.visitlocking_dict[item] -= 1 | 
					
						
							|  |  |  |             if self.visitlocking_dict[item] == 0: | 
					
						
							|  |  |  |                 self.visitlocking_dict.pop(item) | 
					
						
							|  |  |  |             self.multiworld.push_precollected(self.create_item(item)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-15 15:17:23 -04:00
										 |  |  |         itempool = [self.create_item(item) for item, data in self.item_quantity_dict.items() for _ in range(data)] | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Creating filler for unfilled locations | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         itempool += [self.create_filler() for _ in range(self.total_locations - len(itempool))] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         self.multiworld.itempool += itempool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |     def generate_early(self) -> None: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Determines the quantity of items and maps plando locations to items. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # Item: Quantity Map | 
					
						
							|  |  |  |         # Example. Quick Run: 4 | 
					
						
							|  |  |  |         self.total_locations = len(all_locations.keys()) | 
					
						
							|  |  |  |         for x in range(4): | 
					
						
							|  |  |  |             self.growth_list.extend(Movement_Table.keys()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-15 15:17:23 -04:00
										 |  |  |         self.item_quantity_dict = {item: data.quantity for item, data in item_dictionary_table.items()} | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         self.sora_ability_dict = {k: v.quantity for dic in [SupportAbility_Table, ActionAbility_Table] for k, v in | 
					
						
							|  |  |  |                                   dic.items()} | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         # Dictionary to mark locations with their plandoed item | 
					
						
							|  |  |  |         # Example. Final Xemnas: Victory | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         # 3 random support abilities because there are left over slots | 
					
						
							|  |  |  |         support_abilities = list(SupportAbility_Table.keys()) | 
					
						
							|  |  |  |         for _ in range(6): | 
					
						
							|  |  |  |             random_support_ability = self.random.choice(support_abilities) | 
					
						
							|  |  |  |             self.item_quantity_dict[random_support_ability] += 1 | 
					
						
							|  |  |  |             self.sora_ability_dict[random_support_ability] += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         self.plando_locations = dict() | 
					
						
							|  |  |  |         self.starting_invo_verify() | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for k, v in self.options.CustomItemPoolQuantity.value.items(): | 
					
						
							|  |  |  |             # kh2's items cannot hold more than a byte | 
					
						
							|  |  |  |             if 255 > v > self.item_quantity_dict[k] and k in default_itempool_option.keys(): | 
					
						
							|  |  |  |                 self.item_quantity_dict[k] = v | 
					
						
							|  |  |  |             elif 255 <= v: | 
					
						
							|  |  |  |                 logging.warning( | 
					
						
							|  |  |  |                         f"{self.player} has too many {k} in their CustomItemPool setting. Setting to default quantity") | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |         # Option to turn off Promise Charm Item | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if not self.options.Promise_Charm: | 
					
						
							|  |  |  |             del self.item_quantity_dict[ItemName.PromiseCharm] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.options.AntiForm: | 
					
						
							|  |  |  |             del self.item_quantity_dict[ItemName.AntiForm] | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         self.set_excluded_locations() | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.Goal not in ["hitlist", "three_proofs"]: | 
					
						
							|  |  |  |             self.lucky_emblem_amount = self.options.LuckyEmblemsAmount.value | 
					
						
							|  |  |  |             self.lucky_emblem_required = self.options.LuckyEmblemsRequired.value | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             self.emblem_verify() | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # hitlist | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.Goal not in ["lucky_emblem_hunt", "three_proofs"]: | 
					
						
							|  |  |  |             self.random_super_boss_list.extend(exclusion_table["Hitlist"]) | 
					
						
							|  |  |  |             self.bounties_amount = self.options.BountyAmount.value | 
					
						
							|  |  |  |             self.bounties_required = self.options.BountyRequired.value | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             self.hitlist_verify() | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |             prio_hitlist = [location for location in self.options.priority_locations.value if | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |                             location in self.random_super_boss_list] | 
					
						
							|  |  |  |             for bounty in range(self.options.BountyAmount.value): | 
					
						
							|  |  |  |                 if prio_hitlist: | 
					
						
							|  |  |  |                     random_boss = self.random.choice(prio_hitlist) | 
					
						
							|  |  |  |                     prio_hitlist.remove(random_boss) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     random_boss = self.random.choice(self.random_super_boss_list) | 
					
						
							|  |  |  |                 self.plando_locations[random_boss] = ItemName.Bounty | 
					
						
							|  |  |  |                 self.random_super_boss_list.remove(random_boss) | 
					
						
							|  |  |  |                 self.total_locations -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.donald_gen_early() | 
					
						
							|  |  |  |         self.goofy_gen_early() | 
					
						
							|  |  |  |         self.keyblade_gen_early() | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-16 07:12:33 -05:00
										 |  |  |         # final xemnas isn't a location anymore | 
					
						
							|  |  |  |         # self.total_locations -= 1 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.WeaponSlotStartHint: | 
					
						
							|  |  |  |             for location in all_weapon_slot: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |                 self.options.start_location_hints.value.add(location) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.options.FillerItemsLocal: | 
					
						
							|  |  |  |             for item in filler_items: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |                 self.options.local_items.value.add(item) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         # By imitating remote this doesn't have to be plandoded filler anymore | 
					
						
							|  |  |  |         #  for location in {LocationName.JunkMedal, LocationName.JunkMedal}: | 
					
						
							|  |  |  |         #    self.plando_locations[location] = random_stt_item | 
					
						
							|  |  |  |         if not self.options.SummonLevelLocationToggle: | 
					
						
							|  |  |  |             self.total_locations -= 6 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.total_locations -= self.level_subtraction() | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def pre_fill(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Plandoing Events and Fill_Restrictive for donald,goofy and sora | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.donald_pre_fill() | 
					
						
							|  |  |  |         self.goofy_pre_fill() | 
					
						
							|  |  |  |         self.keyblade_pre_fill() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         for location, item in self.plando_locations.items(): | 
					
						
							|  |  |  |             self.multiworld.get_location(location, self.player).place_locked_item( | 
					
						
							|  |  |  |                     self.create_item(item)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Creates the Regions and Connects them. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         create_regions(self) | 
					
						
							|  |  |  |         connect_regions(self) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Sets the Logic for the Regions and Locations. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         universal_logic = Rules.KH2WorldRules(self) | 
					
						
							|  |  |  |         form_logic = Rules.KH2FormRules(self) | 
					
						
							|  |  |  |         fight_rules = Rules.KH2FightRules(self) | 
					
						
							|  |  |  |         fight_rules.set_kh2_fight_rules() | 
					
						
							|  |  |  |         universal_logic.set_kh2_rules() | 
					
						
							|  |  |  |         form_logic.set_kh2_form_rules() | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def generate_output(self, output_directory: str): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Generates the .zip for OpenKH (The KH Mod Manager) | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         patch_kh2(self, output_directory) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |     def donald_gen_early(self): | 
					
						
							|  |  |  |         random_prog_ability = self.random.choice([ItemName.Fantasia, ItemName.FlareForce]) | 
					
						
							|  |  |  |         donald_master_ability = [donald_ability for donald_ability in DonaldAbility_Table.keys() for _ in | 
					
						
							|  |  |  |                                  range(self.item_quantity_dict[donald_ability]) if | 
					
						
							|  |  |  |                                  donald_ability != random_prog_ability] | 
					
						
							|  |  |  |         self.donald_weapon_abilities = [] | 
					
						
							|  |  |  |         self.donald_get_bonus_abilities = [] | 
					
						
							|  |  |  |         # fill goofy weapons first | 
					
						
							|  |  |  |         for _ in range(15): | 
					
						
							|  |  |  |             random_ability = self.random.choice(donald_master_ability) | 
					
						
							|  |  |  |             donald_master_ability.remove(random_ability) | 
					
						
							|  |  |  |             self.donald_weapon_abilities += [self.create_item(random_ability)] | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |             self.item_quantity_dict[random_ability] -= 1 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             self.total_locations -= 1 | 
					
						
							|  |  |  |         self.slot_data_donald_weapon = [item_name.name for item_name in self.donald_weapon_abilities] | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |         if not self.options.DonaldGoofyStatsanity: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             # pre plando donald get bonuses | 
					
						
							|  |  |  |             self.donald_get_bonus_abilities += [self.create_item(random_prog_ability)] | 
					
						
							|  |  |  |             self.total_locations -= 1 | 
					
						
							|  |  |  |             for item_name in donald_master_ability: | 
					
						
							|  |  |  |                 self.donald_get_bonus_abilities += [self.create_item(item_name)] | 
					
						
							|  |  |  |                 self.item_quantity_dict[item_name] -= 1 | 
					
						
							|  |  |  |                 self.total_locations -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def goofy_gen_early(self): | 
					
						
							|  |  |  |         random_prog_ability = self.random.choice([ItemName.Teamwork, ItemName.TornadoFusion]) | 
					
						
							|  |  |  |         goofy_master_ability = [goofy_ability for goofy_ability in GoofyAbility_Table.keys() for _ in | 
					
						
							|  |  |  |                                 range(self.item_quantity_dict[goofy_ability]) if goofy_ability != random_prog_ability] | 
					
						
							|  |  |  |         self.goofy_weapon_abilities = [] | 
					
						
							|  |  |  |         self.goofy_get_bonus_abilities = [] | 
					
						
							|  |  |  |         # fill goofy weapons first | 
					
						
							|  |  |  |         for _ in range(15): | 
					
						
							|  |  |  |             random_ability = self.random.choice(goofy_master_ability) | 
					
						
							|  |  |  |             goofy_master_ability.remove(random_ability) | 
					
						
							|  |  |  |             self.goofy_weapon_abilities += [self.create_item(random_ability)] | 
					
						
							|  |  |  |             self.item_quantity_dict[random_ability] -= 1 | 
					
						
							|  |  |  |             self.total_locations -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.slot_data_goofy_weapon = [item_name.name for item_name in self.goofy_weapon_abilities] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.options.DonaldGoofyStatsanity: | 
					
						
							|  |  |  |             # pre plando goofy get bonuses | 
					
						
							|  |  |  |             self.goofy_get_bonus_abilities += [self.create_item(random_prog_ability)] | 
					
						
							|  |  |  |             self.total_locations -= 1 | 
					
						
							|  |  |  |             for item_name in goofy_master_ability: | 
					
						
							|  |  |  |                 self.goofy_get_bonus_abilities += [self.create_item(item_name)] | 
					
						
							|  |  |  |                 self.item_quantity_dict[item_name] -= 1 | 
					
						
							|  |  |  |                 self.total_locations -= 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def keyblade_gen_early(self): | 
					
						
							|  |  |  |         keyblade_master_ability = [ability for ability in SupportAbility_Table.keys() if ability not in progression_set | 
					
						
							|  |  |  |                                    for _ in range(self.item_quantity_dict[ability])] | 
					
						
							|  |  |  |         self.keyblade_ability_pool = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for _ in range(len(Keyblade_Slots)): | 
					
						
							|  |  |  |             random_ability = self.random.choice(keyblade_master_ability) | 
					
						
							|  |  |  |             keyblade_master_ability.remove(random_ability) | 
					
						
							|  |  |  |             self.keyblade_ability_pool += [self.create_item(random_ability)] | 
					
						
							|  |  |  |             self.item_quantity_dict[random_ability] -= 1 | 
					
						
							|  |  |  |             self.total_locations -= 1 | 
					
						
							|  |  |  |         self.slot_data_sora_weapon = [item_name.name for item_name in self.keyblade_ability_pool] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def goofy_pre_fill(self): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Removes donald locations from the location pool maps random donald items to be plandoded. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         goofy_weapon_location_list = [self.multiworld.get_location(location, self.player) for location in | 
					
						
							|  |  |  |                                       Goofy_Checks.keys() if Goofy_Checks[location].yml == "Keyblade"] | 
					
						
							|  |  |  |         # take one of the 2 out | 
					
						
							|  |  |  |         # randomize the list with only | 
					
						
							|  |  |  |         for location in goofy_weapon_location_list: | 
					
						
							|  |  |  |             random_ability = self.random.choice(self.goofy_weapon_abilities) | 
					
						
							|  |  |  |             location.place_locked_item(random_ability) | 
					
						
							|  |  |  |             self.goofy_weapon_abilities.remove(random_ability) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |         if not self.options.DonaldGoofyStatsanity: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             # plando goofy get bonuses | 
					
						
							|  |  |  |             goofy_get_bonus_location_pool = [self.multiworld.get_location(location, self.player) for location in | 
					
						
							|  |  |  |                                              Goofy_Checks.keys() if Goofy_Checks[location].yml != "Keyblade"] | 
					
						
							|  |  |  |             for location in goofy_get_bonus_location_pool: | 
					
						
							|  |  |  |                 self.random.choice(self.goofy_get_bonus_abilities) | 
					
						
							|  |  |  |                 random_ability = self.random.choice(self.goofy_get_bonus_abilities) | 
					
						
							|  |  |  |                 location.place_locked_item(random_ability) | 
					
						
							|  |  |  |                 self.goofy_get_bonus_abilities.remove(random_ability) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def donald_pre_fill(self): | 
					
						
							|  |  |  |         donald_weapon_location_list = [self.multiworld.get_location(location, self.player) for location in | 
					
						
							|  |  |  |                                        Donald_Checks.keys() if Donald_Checks[location].yml == "Keyblade"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # take one of the 2 out | 
					
						
							|  |  |  |         # randomize the list with only | 
					
						
							|  |  |  |         for location in donald_weapon_location_list: | 
					
						
							|  |  |  |             random_ability = self.random.choice(self.donald_weapon_abilities) | 
					
						
							|  |  |  |             location.place_locked_item(random_ability) | 
					
						
							|  |  |  |             self.donald_weapon_abilities.remove(random_ability) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |         if not self.options.DonaldGoofyStatsanity: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             # plando goofy get bonuses | 
					
						
							|  |  |  |             donald_get_bonus_location_pool = [self.multiworld.get_location(location, self.player) for location in | 
					
						
							|  |  |  |                                               Donald_Checks.keys() if Donald_Checks[location].yml != "Keyblade"] | 
					
						
							|  |  |  |             for location in donald_get_bonus_location_pool: | 
					
						
							|  |  |  |                 random_ability = self.random.choice(self.donald_get_bonus_abilities) | 
					
						
							|  |  |  |                 location.place_locked_item(random_ability) | 
					
						
							|  |  |  |                 self.donald_get_bonus_abilities.remove(random_ability) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def keyblade_pre_fill(self): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Fills keyblade slots with abilities determined on player's setting | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         keyblade_locations = [self.multiworld.get_location(location, self.player) for location in Keyblade_Slots.keys()] | 
					
						
							|  |  |  |         state = self.multiworld.get_all_state(False) | 
					
						
							|  |  |  |         keyblade_ability_pool_copy = self.keyblade_ability_pool.copy() | 
					
						
							| 
									
										
										
										
											2024-04-18 12:55:27 -04:00
										 |  |  |         fill_restrictive(self.multiworld, state, keyblade_locations, keyblade_ability_pool_copy, True, True, allow_excluded=True) | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |     def starting_invo_verify(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Making sure the player doesn't put too many abilities in their starting inventory. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |         for item, value in self.options.start_inventory.value.items(): | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             if item in ActionAbility_Table \ | 
					
						
							| 
									
										
										
										
											2024-06-04 15:20:37 -04:00
										 |  |  |                     or item in SupportAbility_Table or item in exclusion_item_table["StatUps"] \ | 
					
						
							| 
									
										
										
										
											2023-04-15 15:17:23 -04:00
										 |  |  |                     or item in DonaldAbility_Table or item in GoofyAbility_Table: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                 # cannot have more than the quantity for abilties | 
					
						
							|  |  |  |                 if value > item_dictionary_table[item].quantity: | 
					
						
							|  |  |  |                     logging.info( | 
					
						
							| 
									
										
										
										
											2024-06-04 15:20:37 -04:00
										 |  |  |                             f"{self.multiworld.get_file_safe_player_name(self.player)} cannot have more than {item_dictionary_table[item].quantity} of {item}." | 
					
						
							|  |  |  |                             f" Changing the amount to the max amount") | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |                     value = item_dictionary_table[item].quantity | 
					
						
							|  |  |  |                 self.item_quantity_dict[item] -= value | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |     def emblem_verify(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Making sure lucky emblems have amount>=required. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if self.lucky_emblem_amount < self.lucky_emblem_required: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             logging.info( | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |                     f"Lucky Emblem Amount {self.options.LuckyEmblemsAmount.value} is less than required " | 
					
						
							|  |  |  |                     f"{self.options.LuckyEmblemsRequired.value} for player {self.multiworld.get_file_safe_player_name(self.player)}." | 
					
						
							|  |  |  |                     f" Setting amount to {self.options.LuckyEmblemsRequired.value}") | 
					
						
							|  |  |  |             luckyemblemamount = max(self.lucky_emblem_amount, self.lucky_emblem_required) | 
					
						
							|  |  |  |             self.options.LuckyEmblemsAmount.value = luckyemblemamount | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         self.item_quantity_dict[ItemName.LuckyEmblem] = self.options.LuckyEmblemsAmount.value | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         # give this proof to unlock the final door once the player has the amount of lucky emblem required | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if ItemName.ProofofNonexistence in self.item_quantity_dict: | 
					
						
							|  |  |  |             del self.item_quantity_dict[ItemName.ProofofNonexistence] | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def hitlist_verify(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Making sure hitlist have amount>=required. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |         for location in self.options.exclude_locations.value: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             if location in self.random_super_boss_list: | 
					
						
							|  |  |  |                 self.random_super_boss_list.remove(location) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-10 12:58:52 -05:00
										 |  |  |         if not self.options.SummonLevelLocationToggle and LocationName.Summonlvl7 in self.random_super_boss_list: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             self.random_super_boss_list.remove(LocationName.Summonlvl7) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #  Testing if the player has the right amount of Bounties for Completion. | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if len(self.random_super_boss_list) < self.bounties_amount: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             logging.info( | 
					
						
							|  |  |  |                     f"{self.multiworld.get_file_safe_player_name(self.player)} has more bounties than bosses." | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |                     f" Setting total bounties to {len(self.random_super_boss_list)}") | 
					
						
							|  |  |  |             self.bounties_amount = len(self.random_super_boss_list) | 
					
						
							|  |  |  |             self.options.BountyAmount.value = self.bounties_amount | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if len(self.random_super_boss_list) < self.bounties_required: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             logging.info(f"{self.multiworld.get_file_safe_player_name(self.player)} has too many required bounties." | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |                          f" Setting required bounties to {len(self.random_super_boss_list)}") | 
					
						
							|  |  |  |             self.bounties_required = len(self.random_super_boss_list) | 
					
						
							|  |  |  |             self.options.BountyRequired.value = self.bounties_required | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.bounties_amount < self.bounties_required: | 
					
						
							|  |  |  |             logging.info( | 
					
						
							|  |  |  |                     f"Bounties Amount is less than required for player {self.multiworld.get_file_safe_player_name(self.player)}." | 
					
						
							|  |  |  |                     f" Swapping Amount and Required") | 
					
						
							|  |  |  |             temp = self.options.BountyRequired.value | 
					
						
							|  |  |  |             self.options.BountyRequired.value = self.options.BountyAmount.value | 
					
						
							|  |  |  |             self.options.BountyAmount.value = temp | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.BountyStartingHintToggle: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |             self.options.start_hints.value.add(ItemName.Bounty) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ItemName.ProofofNonexistence in self.item_quantity_dict: | 
					
						
							|  |  |  |             del self.item_quantity_dict[ItemName.ProofofNonexistence] | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def set_excluded_locations(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Fills excluded_locations from player's settings. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         # Option to turn off all superbosses. Can do this individually but its like 20+ checks | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if not self.options.SuperBosses: | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             for superboss in exclusion_table["SuperBosses"]: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |                 self.options.exclude_locations.value.add(superboss) | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         # Option to turn off Olympus Colosseum Cups. | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if self.options.Cups == "no_cups": | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |             for cup in exclusion_table["Cups"]: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |                 self.options.exclude_locations.value.add(cup) | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |         # exclude only hades paradox. If cups and hades paradox then nothing is excluded | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         elif self.options.Cups == "cups": | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |             self.options.exclude_locations.value.add(LocationName.HadesCupTrophyParadoxCups) | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         if not self.options.AtlanticaToggle: | 
					
						
							|  |  |  |             for loc in exclusion_table["Atlantica"]: | 
					
						
							| 
									
										
										
										
											2024-03-11 19:52:16 -04:00
										 |  |  |                 self.options.exclude_locations.value.add(loc) | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |     def level_subtraction(self): | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |        Determine how many locations are on sora's levels. | 
					
						
							|  |  |  |        """
 | 
					
						
							|  |  |  |         if self.options.LevelDepth == "level_50_sanity": | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |             # level 50 sanity | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             return 49 | 
					
						
							|  |  |  |         elif self.options.LevelDepth == "level_1": | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |             # level 1. No checks on levels | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             return 98 | 
					
						
							|  |  |  |         elif self.options.LevelDepth in ["level_50", "level_99"]: | 
					
						
							|  |  |  |             # could be if leveldepth!= 99 sanity but this reads better imo | 
					
						
							|  |  |  |             return 75 | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2023-03-20 12:19:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-09 22:12:23 -04:00
										 |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							| 
									
										
										
										
											2023-11-25 09:46:00 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Returns random filler item name. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         return self.random.choice(filler_items) |