| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  | import os | 
					
						
							|  |  |  | import pkgutil | 
					
						
							|  |  |  | from typing import Any, ClassVar, Dict, List | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import settings | 
					
						
							|  |  |  | from BaseClasses import Entrance, Item, ItemClassification, Location, MultiWorld, Region, Tutorial | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import Utils | 
					
						
							|  |  |  | from worlds.AutoWorld import WebWorld, World | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .boosterpacks import booster_contents as booster_contents | 
					
						
							|  |  |  | from .boosterpacks import get_booster_locations | 
					
						
							|  |  |  | from .items import ( | 
					
						
							|  |  |  |     Banlist_Items, | 
					
						
							|  |  |  |     booster_packs, | 
					
						
							|  |  |  |     draft_boosters, | 
					
						
							|  |  |  |     draft_opponents, | 
					
						
							|  |  |  |     excluded_items, | 
					
						
							|  |  |  |     item_to_index, | 
					
						
							|  |  |  |     tier_1_opponents, | 
					
						
							|  |  |  |     useful, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | from .items import ( | 
					
						
							|  |  |  |     challenges as challenges, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | from .locations import ( | 
					
						
							|  |  |  |     Bonuses, | 
					
						
							|  |  |  |     Campaign_Opponents, | 
					
						
							|  |  |  |     Limited_Duels, | 
					
						
							|  |  |  |     Required_Cards, | 
					
						
							|  |  |  |     Theme_Duels, | 
					
						
							|  |  |  |     collection_events, | 
					
						
							|  |  |  |     get_beat_challenge_events, | 
					
						
							|  |  |  |     special, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | from .logic import core_booster, yugioh06_difficulty | 
					
						
							|  |  |  | from .opponents import OpponentData, get_opponent_condition, get_opponent_locations, get_opponents | 
					
						
							|  |  |  | from .opponents import challenge_opponents as challenge_opponents | 
					
						
							|  |  |  | from .options import Yugioh06Options | 
					
						
							|  |  |  | from .rom import MD5America, MD5Europe, YGO06ProcedurePatch, write_tokens | 
					
						
							|  |  |  | from .rom import get_base_rom_path as get_base_rom_path | 
					
						
							|  |  |  | from .rom_values import banlist_ids as banlist_ids | 
					
						
							|  |  |  | from .rom_values import function_addresses as function_addresses | 
					
						
							|  |  |  | from .rom_values import structure_deck_selection as structure_deck_selection | 
					
						
							|  |  |  | from .rules import set_rules | 
					
						
							|  |  |  | from .structure_deck import get_deck_content_locations | 
					
						
							|  |  |  | from .client_bh import YuGiOh2006Client | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Yugioh06Web(WebWorld): | 
					
						
							|  |  |  |     theme = "stone" | 
					
						
							|  |  |  |     setup = Tutorial( | 
					
						
							|  |  |  |         "Multiworld Setup Tutorial", | 
					
						
							|  |  |  |         "A guide to setting up Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 " | 
					
						
							|  |  |  |         "for Archipelago on your computer.", | 
					
						
							|  |  |  |         "English", | 
					
						
							|  |  |  |         "docs/setup_en.md", | 
					
						
							|  |  |  |         "setup/en", | 
					
						
							|  |  |  |         ["Rensen"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     tutorials = [setup] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Yugioh2006Setting(settings.Group): | 
					
						
							|  |  |  |     class Yugioh2006RomFile(settings.UserFilePath): | 
					
						
							|  |  |  |         """File name of your Yu-Gi-Oh 2006 ROM""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         description = "Yu-Gi-Oh 2006 ROM File" | 
					
						
							|  |  |  |         copy_to = "YuGiOh06.gba" | 
					
						
							|  |  |  |         md5s = [MD5Europe, MD5America] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rom_file: Yugioh2006RomFile = Yugioh2006RomFile(Yugioh2006RomFile.copy_to) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Yugioh06World(World): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Yu-Gi-Oh! Ultimate Masters: World Championship Tournament 2006 is the definitive Yu-Gi-Oh | 
					
						
							|  |  |  |     simulator on the GBA. Featuring over 2000 cards and over 90 Challenges. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     game = "Yu-Gi-Oh! 2006" | 
					
						
							|  |  |  |     web = Yugioh06Web() | 
					
						
							|  |  |  |     options: Yugioh06Options | 
					
						
							|  |  |  |     options_dataclass = Yugioh06Options | 
					
						
							|  |  |  |     settings_key = "yugioh06_settings" | 
					
						
							|  |  |  |     settings: ClassVar[Yugioh2006Setting] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_to_id = {} | 
					
						
							|  |  |  |     start_id = 5730000 | 
					
						
							|  |  |  |     for k, v in item_to_index.items(): | 
					
						
							|  |  |  |         item_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     location_name_to_id = {} | 
					
						
							|  |  |  |     for k, v in Bonuses.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for k, v in Limited_Duels.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for k, v in Theme_Duels.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for k, v in Campaign_Opponents.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for k, v in special.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for k, v in Required_Cards.items(): | 
					
						
							|  |  |  |         location_name_to_id[k] = v + start_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_groups = { | 
					
						
							|  |  |  |         "Core Booster": core_booster, | 
					
						
							|  |  |  |         "Campaign Boss Beaten": ["Tier 1 Beaten", "Tier 2 Beaten", "Tier 3 Beaten", "Tier 4 Beaten", "Tier 5 Beaten"], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     removed_challenges: List[str] | 
					
						
							|  |  |  |     starting_booster: str | 
					
						
							|  |  |  |     starting_opponent: str | 
					
						
							|  |  |  |     campaign_opponents: List[OpponentData] | 
					
						
							|  |  |  |     is_draft_mode: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, world: MultiWorld, player: int): | 
					
						
							|  |  |  |         super().__init__(world, player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_early(self): | 
					
						
							|  |  |  |         self.starting_opponent = "" | 
					
						
							|  |  |  |         self.starting_booster = "" | 
					
						
							|  |  |  |         self.removed_challenges = [] | 
					
						
							|  |  |  |         # Universal tracker stuff, shouldn't do anything in standard gen | 
					
						
							|  |  |  |         if hasattr(self.multiworld, "re_gen_passthrough"): | 
					
						
							|  |  |  |             if "Yu-Gi-Oh! 2006" in self.multiworld.re_gen_passthrough: | 
					
						
							|  |  |  |                 # bypassing random yaml settings | 
					
						
							|  |  |  |                 slot_data = self.multiworld.re_gen_passthrough["Yu-Gi-Oh! 2006"] | 
					
						
							|  |  |  |                 self.options.structure_deck.value = slot_data["structure_deck"] | 
					
						
							|  |  |  |                 self.options.banlist.value = slot_data["banlist"] | 
					
						
							|  |  |  |                 self.options.final_campaign_boss_unlock_condition.value = slot_data[ | 
					
						
							|  |  |  |                     "final_campaign_boss_unlock_condition" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_unlock_condition.value = slot_data[ | 
					
						
							|  |  |  |                     "fourth_tier_5_campaign_boss_unlock_condition" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_unlock_condition.value = slot_data[ | 
					
						
							|  |  |  |                     "third_tier_5_campaign_boss_unlock_condition" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.final_campaign_boss_challenges.value = slot_data["final_campaign_boss_challenges"] | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_challenges.value = slot_data[ | 
					
						
							|  |  |  |                     "fourth_tier_5_campaign_boss_challenges" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_challenges.value = slot_data[ | 
					
						
							|  |  |  |                     "third_tier_5_campaign_boss_challenges" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.final_campaign_boss_campaign_opponents.value = slot_data[ | 
					
						
							|  |  |  |                     "final_campaign_boss_campaign_opponents" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_campaign_opponents.value = slot_data[ | 
					
						
							|  |  |  |                     "fourth_tier_5_campaign_boss_campaign_opponents" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_campaign_opponents.value = slot_data[ | 
					
						
							|  |  |  |                     "third_tier_5_campaign_boss_campaign_opponents" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |                 self.options.number_of_challenges.value = slot_data["number_of_challenges"] | 
					
						
							|  |  |  |                 self.removed_challenges = slot_data["removed challenges"] | 
					
						
							|  |  |  |                 self.starting_booster = slot_data["starting_booster"] | 
					
						
							|  |  |  |                 self.starting_opponent = slot_data["starting_opponent"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.options.structure_deck.current_key == "none": | 
					
						
							|  |  |  |             self.is_draft_mode = True | 
					
						
							|  |  |  |             boosters = draft_boosters | 
					
						
							|  |  |  |             if self.options.campaign_opponents_shuffle.value: | 
					
						
							|  |  |  |                 opponents = tier_1_opponents | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 opponents = draft_opponents | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.is_draft_mode = False | 
					
						
							|  |  |  |             boosters = booster_packs | 
					
						
							|  |  |  |             opponents = tier_1_opponents | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.options.structure_deck.current_key == "random_deck": | 
					
						
							|  |  |  |             self.options.structure_deck.value = self.random.randint(0, 5) | 
					
						
							|  |  |  |         for item in self.options.start_inventory: | 
					
						
							|  |  |  |             if item in opponents: | 
					
						
							|  |  |  |                 self.starting_opponent = item | 
					
						
							|  |  |  |             if item in boosters: | 
					
						
							|  |  |  |                 self.starting_booster = item | 
					
						
							|  |  |  |         if not self.starting_opponent: | 
					
						
							|  |  |  |             self.starting_opponent = self.random.choice(opponents) | 
					
						
							|  |  |  |             self.multiworld.push_precollected(self.create_item(self.starting_opponent)) | 
					
						
							|  |  |  |         if not self.starting_booster: | 
					
						
							|  |  |  |             self.starting_booster = self.random.choice(boosters) | 
					
						
							|  |  |  |             self.multiworld.push_precollected(self.create_item(self.starting_booster)) | 
					
						
							|  |  |  |         banlist = self.options.banlist.value | 
					
						
							|  |  |  |         self.multiworld.push_precollected(self.create_item(Banlist_Items[banlist])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.removed_challenges: | 
					
						
							| 
									
										
										
										
											2024-05-18 13:53:17 +02:00
										 |  |  |             challenge = list(({**Limited_Duels, **Theme_Duels}).keys()) | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             noc = len(challenge) - max( | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_challenges.value | 
					
						
							|  |  |  |                 if self.options.third_tier_5_campaign_boss_unlock_condition == "challenges" | 
					
						
							|  |  |  |                 else 0, | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_challenges.value | 
					
						
							|  |  |  |                 if self.options.fourth_tier_5_campaign_boss_unlock_condition == "challenges" | 
					
						
							|  |  |  |                 else 0, | 
					
						
							|  |  |  |                 self.options.final_campaign_boss_challenges.value | 
					
						
							|  |  |  |                 if self.options.final_campaign_boss_unlock_condition == "challenges" | 
					
						
							|  |  |  |                 else 0, | 
					
						
							|  |  |  |                 self.options.number_of_challenges.value, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.random.shuffle(challenge) | 
					
						
							|  |  |  |             excluded = self.options.exclude_locations.value.intersection(challenge) | 
					
						
							|  |  |  |             prio = self.options.priority_locations.value.intersection(challenge) | 
					
						
							|  |  |  |             normal = [e for e in challenge if e not in excluded and e not in prio] | 
					
						
							|  |  |  |             total = list(excluded) + normal + list(prio) | 
					
						
							|  |  |  |             self.removed_challenges = total[:noc] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.campaign_opponents = get_opponents( | 
					
						
							|  |  |  |             self.multiworld, self.player, self.options.campaign_opponents_shuffle.value | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_region(self, name: str, locations=None, exits=None): | 
					
						
							|  |  |  |         region = Region(name, self.player, self.multiworld) | 
					
						
							|  |  |  |         if locations: | 
					
						
							|  |  |  |             for location_name, lid in locations.items(): | 
					
						
							|  |  |  |                 if lid is not None and isinstance(lid, int): | 
					
						
							|  |  |  |                     lid = self.location_name_to_id[location_name] | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     lid = None | 
					
						
							|  |  |  |                 location = Yugioh2006Location(self.player, location_name, lid, region) | 
					
						
							|  |  |  |                 region.locations.append(location) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if exits: | 
					
						
							|  |  |  |             for _exit in exits: | 
					
						
							|  |  |  |                 region.exits.append(Entrance(self.player, _exit, region)) | 
					
						
							|  |  |  |         return region | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self): | 
					
						
							|  |  |  |         structure_deck = self.options.structure_deck.current_key | 
					
						
							|  |  |  |         self.multiworld.regions += [ | 
					
						
							|  |  |  |             self.create_region("Menu", None, ["to Deck Edit", "to Campaign", "to Challenges", "to Card Shop"]), | 
					
						
							| 
									
										
										
										
											2024-05-18 13:53:17 +02:00
										 |  |  |             self.create_region("Campaign", {**Bonuses,  **Campaign_Opponents}), | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             self.create_region("Challenges"), | 
					
						
							| 
									
										
										
										
											2024-05-18 13:53:17 +02:00
										 |  |  |             self.create_region("Card Shop", {**Required_Cards, **collection_events}), | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             self.create_region("Structure Deck", get_deck_content_locations(structure_deck)), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.get_entrance("to Campaign").connect(self.get_region("Campaign")) | 
					
						
							|  |  |  |         self.get_entrance("to Challenges").connect(self.get_region("Challenges")) | 
					
						
							|  |  |  |         self.get_entrance("to Card Shop").connect(self.get_region("Card Shop")) | 
					
						
							|  |  |  |         self.get_entrance("to Deck Edit").connect(self.get_region("Structure Deck")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         campaign = self.get_region("Campaign") | 
					
						
							|  |  |  |         # Campaign Opponents | 
					
						
							|  |  |  |         for opponent in self.campaign_opponents: | 
					
						
							|  |  |  |             unlock_item = "Campaign Tier " + str(opponent.tier) + " Column " + str(opponent.column) | 
					
						
							|  |  |  |             region = self.create_region(opponent.name, get_opponent_locations(opponent)) | 
					
						
							|  |  |  |             entrance = Entrance(self.player, unlock_item, campaign) | 
					
						
							|  |  |  |             if opponent.tier == 5 and opponent.column > 2: | 
					
						
							|  |  |  |                 unlock_amount = 0 | 
					
						
							|  |  |  |                 is_challenge = True | 
					
						
							|  |  |  |                 if opponent.column == 3: | 
					
						
							|  |  |  |                     if self.options.third_tier_5_campaign_boss_unlock_condition.value == 1: | 
					
						
							|  |  |  |                         unlock_item = "Challenge Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.third_tier_5_campaign_boss_challenges.value | 
					
						
							|  |  |  |                         is_challenge = True | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         unlock_item = "Campaign Boss Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.third_tier_5_campaign_boss_campaign_opponents.value | 
					
						
							|  |  |  |                         is_challenge = False | 
					
						
							|  |  |  |                 if opponent.column == 4: | 
					
						
							|  |  |  |                     if self.options.fourth_tier_5_campaign_boss_unlock_condition.value == 1: | 
					
						
							|  |  |  |                         unlock_item = "Challenge Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.fourth_tier_5_campaign_boss_challenges.value | 
					
						
							|  |  |  |                         is_challenge = True | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         unlock_item = "Campaign Boss Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.fourth_tier_5_campaign_boss_campaign_opponents.value | 
					
						
							|  |  |  |                         is_challenge = False | 
					
						
							|  |  |  |                 if opponent.column == 5: | 
					
						
							|  |  |  |                     if self.options.final_campaign_boss_unlock_condition.value == 1: | 
					
						
							|  |  |  |                         unlock_item = "Challenge Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.final_campaign_boss_challenges.value | 
					
						
							|  |  |  |                         is_challenge = True | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         unlock_item = "Campaign Boss Beaten" | 
					
						
							|  |  |  |                         unlock_amount = self.options.final_campaign_boss_campaign_opponents.value | 
					
						
							|  |  |  |                         is_challenge = False | 
					
						
							|  |  |  |                 entrance.access_rule = get_opponent_condition( | 
					
						
							|  |  |  |                     opponent, unlock_item, unlock_amount, self.player, is_challenge | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 entrance.access_rule = lambda state, unlock=unlock_item, opp=opponent: state.has( | 
					
						
							|  |  |  |                     unlock, self.player | 
					
						
							|  |  |  |                 ) and yugioh06_difficulty(state, self.player, opp.difficulty) | 
					
						
							|  |  |  |             campaign.exits.append(entrance) | 
					
						
							|  |  |  |             entrance.connect(region) | 
					
						
							|  |  |  |             self.multiworld.regions.append(region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         card_shop = self.get_region("Card Shop") | 
					
						
							|  |  |  |         # Booster Contents | 
					
						
							|  |  |  |         for booster in booster_packs: | 
					
						
							|  |  |  |             region = self.create_region(booster, get_booster_locations(booster)) | 
					
						
							|  |  |  |             entrance = Entrance(self.player, booster, card_shop) | 
					
						
							|  |  |  |             entrance.access_rule = lambda state, unlock=booster: state.has(unlock, self.player) | 
					
						
							|  |  |  |             card_shop.exits.append(entrance) | 
					
						
							|  |  |  |             entrance.connect(region) | 
					
						
							|  |  |  |             self.multiworld.regions.append(region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         challenge_region = self.get_region("Challenges") | 
					
						
							|  |  |  |         # Challenges | 
					
						
							| 
									
										
										
										
											2024-05-18 13:53:17 +02:00
										 |  |  |         for challenge, lid in ({**Limited_Duels, **Theme_Duels}).items(): | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             if challenge in self.removed_challenges: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             region = self.create_region(challenge, {challenge: lid, challenge + " Complete": None}) | 
					
						
							|  |  |  |             entrance = Entrance(self.player, challenge, challenge_region) | 
					
						
							|  |  |  |             entrance.access_rule = lambda state, unlock=challenge: state.has(unlock + " Unlock", self.player) | 
					
						
							|  |  |  |             challenge_region.exits.append(entrance) | 
					
						
							|  |  |  |             entrance.connect(region) | 
					
						
							|  |  |  |             self.multiworld.regions.append(region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str) -> Item: | 
					
						
							|  |  |  |         classification: ItemClassification = ItemClassification.progression | 
					
						
							|  |  |  |         if name == "5000DP": | 
					
						
							|  |  |  |             classification = ItemClassification.filler | 
					
						
							|  |  |  |         if name in useful: | 
					
						
							|  |  |  |             classification = ItemClassification.useful | 
					
						
							|  |  |  |         return Item(name, classification, self.item_name_to_id[name], self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_filler(self) -> Item: | 
					
						
							|  |  |  |         return self.create_item("5000DP") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							|  |  |  |         return "5000DP" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_items(self): | 
					
						
							|  |  |  |         start_inventory = self.options.start_inventory.value.copy() | 
					
						
							|  |  |  |         item_pool = [] | 
					
						
							|  |  |  |         items = item_to_index.copy() | 
					
						
							|  |  |  |         starting_list = Banlist_Items[self.options.banlist.value] | 
					
						
							|  |  |  |         if not self.options.add_empty_banlist.value and starting_list != "No Banlist": | 
					
						
							|  |  |  |             items.pop("No Banlist") | 
					
						
							|  |  |  |         for rc in self.removed_challenges: | 
					
						
							|  |  |  |             items.pop(rc + " Unlock") | 
					
						
							|  |  |  |         items.pop(self.starting_opponent) | 
					
						
							|  |  |  |         items.pop(self.starting_booster) | 
					
						
							|  |  |  |         items.pop(starting_list) | 
					
						
							|  |  |  |         for name in items: | 
					
						
							|  |  |  |             if name in excluded_items or name in start_inventory: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             item = self.create_item(name) | 
					
						
							|  |  |  |             item_pool.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         needed_item_pool_size = sum(loc not in self.removed_challenges for loc in self.location_name_to_id) | 
					
						
							|  |  |  |         needed_filler_amount = needed_item_pool_size - len(item_pool) | 
					
						
							|  |  |  |         item_pool += [self.create_item("5000DP") for _ in range(needed_filler_amount)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.itempool += item_pool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for challenge in get_beat_challenge_events(self): | 
					
						
							|  |  |  |             item = Yugioh2006Item("Challenge Beaten", ItemClassification.progression, None, self.player) | 
					
						
							|  |  |  |             location = self.multiworld.get_location(challenge, self.player) | 
					
						
							|  |  |  |             location.place_locked_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for opponent in self.campaign_opponents: | 
					
						
							|  |  |  |             for location_name, event in get_opponent_locations(opponent).items(): | 
					
						
							|  |  |  |                 if event is not None and not isinstance(event, int): | 
					
						
							|  |  |  |                     item = Yugioh2006Item(event, ItemClassification.progression, None, self.player) | 
					
						
							|  |  |  |                     location = self.multiworld.get_location(location_name, self.player) | 
					
						
							|  |  |  |                     location.place_locked_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for booster in booster_packs: | 
					
						
							|  |  |  |             for location_name, content in get_booster_locations(booster).items(): | 
					
						
							|  |  |  |                 item = Yugioh2006Item(content, ItemClassification.progression, None, self.player) | 
					
						
							|  |  |  |                 location = self.multiworld.get_location(location_name, self.player) | 
					
						
							|  |  |  |                 location.place_locked_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         structure_deck = self.options.structure_deck.current_key | 
					
						
							|  |  |  |         for location_name, content in get_deck_content_locations(structure_deck).items(): | 
					
						
							|  |  |  |             item = Yugioh2006Item(content, ItemClassification.progression, None, self.player) | 
					
						
							|  |  |  |             location = self.multiworld.get_location(location_name, self.player) | 
					
						
							|  |  |  |             location.place_locked_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for event in collection_events: | 
					
						
							|  |  |  |             item = Yugioh2006Item(event, ItemClassification.progression, None, self.player) | 
					
						
							|  |  |  |             location = self.multiworld.get_location(event, self.player) | 
					
						
							|  |  |  |             location.place_locked_item(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self): | 
					
						
							|  |  |  |         set_rules(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_output(self, output_directory: str): | 
					
						
							|  |  |  |         outfilepname = f"_P{self.player}" | 
					
						
							|  |  |  |         outfilepname += f"_{self.multiworld.get_file_safe_player_name(self.player).replace(' ', '_')}" | 
					
						
							|  |  |  |         self.rom_name_text = f'YGO06{Utils.__version__.replace(".", "")[0:3]}_{self.player}_{self.multiworld.seed:11}\0' | 
					
						
							|  |  |  |         self.romName = bytearray(self.rom_name_text, "utf8")[:0x20] | 
					
						
							|  |  |  |         self.romName.extend([0] * (0x20 - len(self.romName))) | 
					
						
							|  |  |  |         self.rom_name = self.romName | 
					
						
							|  |  |  |         self.playerName = bytearray(self.multiworld.player_name[self.player], "utf8")[:0x20] | 
					
						
							|  |  |  |         self.playerName.extend([0] * (0x20 - len(self.playerName))) | 
					
						
							|  |  |  |         patch = YGO06ProcedurePatch(player=self.player, player_name=self.multiworld.player_name[self.player]) | 
					
						
							|  |  |  |         patch.write_file("base_patch.bsdiff4", pkgutil.get_data(__name__, "patch.bsdiff4")) | 
					
						
							| 
									
										
										
										
											2024-06-01 13:10:02 +02:00
										 |  |  |         procedure = [("apply_bsdiff4", ["base_patch.bsdiff4"]), ("apply_tokens", ["token_data.bin"])] | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |         if self.is_draft_mode: | 
					
						
							| 
									
										
										
										
											2024-06-01 13:10:02 +02:00
										 |  |  |             procedure.insert(1, ("apply_bsdiff4", ["draft_patch.bsdiff4"])) | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             patch.write_file("draft_patch.bsdiff4", pkgutil.get_data(__name__, "patches/draft.bsdiff4")) | 
					
						
							|  |  |  |         if self.options.ocg_arts: | 
					
						
							| 
									
										
										
										
											2024-06-01 13:10:02 +02:00
										 |  |  |             procedure.insert(1, ("apply_bsdiff4", ["ocg_patch.bsdiff4"])) | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             patch.write_file("ocg_patch.bsdiff4", pkgutil.get_data(__name__, "patches/ocg.bsdiff4")) | 
					
						
							| 
									
										
										
										
											2024-06-01 13:10:02 +02:00
										 |  |  |         patch.procedure = procedure | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |         write_tokens(self, patch) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Write Output | 
					
						
							|  |  |  |         out_file_name = self.multiworld.get_out_file_name_base(self.player) | 
					
						
							|  |  |  |         patch.write(os.path.join(output_directory, f"{out_file_name}{patch.patch_file_ending}")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> Dict[str, Any]: | 
					
						
							|  |  |  |         slot_data: Dict[str, Any] = { | 
					
						
							|  |  |  |             "structure_deck": self.options.structure_deck.value, | 
					
						
							|  |  |  |             "banlist": self.options.banlist.value, | 
					
						
							|  |  |  |             "final_campaign_boss_unlock_condition": self.options.final_campaign_boss_unlock_condition.value, | 
					
						
							|  |  |  |             "fourth_tier_5_campaign_boss_unlock_condition": | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_unlock_condition.value, | 
					
						
							|  |  |  |             "third_tier_5_campaign_boss_unlock_condition": | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_unlock_condition.value, | 
					
						
							|  |  |  |             "final_campaign_boss_challenges": self.options.final_campaign_boss_challenges.value, | 
					
						
							|  |  |  |             "fourth_tier_5_campaign_boss_challenges": | 
					
						
							|  |  |  |                 self.options.fourth_tier_5_campaign_boss_challenges.value, | 
					
						
							|  |  |  |             "third_tier_5_campaign_boss_challenges": | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_campaign_opponents.value, | 
					
						
							|  |  |  |             "final_campaign_boss_campaign_opponents": | 
					
						
							|  |  |  |                 self.options.final_campaign_boss_campaign_opponents.value, | 
					
						
							|  |  |  |             "fourth_tier_5_campaign_boss_campaign_opponents": | 
					
						
							| 
									
										
										
										
											2024-09-17 15:13:19 +02:00
										 |  |  |                 self.options.fourth_tier_5_campaign_boss_campaign_opponents.value, | 
					
						
							| 
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 |  |  |             "third_tier_5_campaign_boss_campaign_opponents": | 
					
						
							|  |  |  |                 self.options.third_tier_5_campaign_boss_campaign_opponents.value, | 
					
						
							|  |  |  |             "number_of_challenges": self.options.number_of_challenges.value, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         slot_data["removed challenges"] = self.removed_challenges | 
					
						
							|  |  |  |         slot_data["starting_booster"] = self.starting_booster | 
					
						
							|  |  |  |         slot_data["starting_opponent"] = self.starting_opponent | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # for the universal tracker, doesn't get called in standard gen | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]: | 
					
						
							|  |  |  |         # returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Yugioh2006Item(Item): | 
					
						
							|  |  |  |     game: str = "Yu-Gi-Oh! 2006" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Yugioh2006Location(Location): | 
					
						
							|  |  |  |     game: str = "Yu-Gi-Oh! 2006" |