diff --git a/worlds/ffx/__init__.py b/worlds/ffx/__init__.py index 7aea677b1582..57b406e4dbdc 100644 --- a/worlds/ffx/__init__.py +++ b/worlds/ffx/__init__.py @@ -196,7 +196,12 @@ def fill_slot_data(self) -> dict[str, Any]: "required_party_members": self.options.required_party_members.value, "required_primers": self.options.required_primers.value, "sphere_grid_randomization": self.options.sphere_grid_randomization.value, - "mini_games": self.options.mini_games.value, + "mini_game_blitzball": self.options.mini_game_blitzball.value, + "mini_game_butterflies": self.options.mini_game_butterflies.value, + "mini_game_lightning_dodging": self.options.mini_game_lightning_dodging.value, + "mini_game_cactuar_village": self.options.mini_game_cactuar_village.value, + "mini_game_chocobo_training": self.options.mini_game_chocobo_training.value, + "mini_game_chocobo_race": self.options.mini_game_chocobo_race.value, "recruit_sanity": self.options.recruit_sanity.value, "capture_sanity": self.options.capture_sanity.value, "creation_rewards": self.options.creation_rewards.value, @@ -213,4 +218,4 @@ def generate_output(self, output_directory: str) -> None: # Visualize regions #visualize_regions(self.multiworld.get_region("Menu", self.player), f"ffx {self.player}.puml", show_entrance_names=True) - generate_output(self, self.player, output_directory) \ No newline at end of file + generate_output(self, self.player, output_directory) diff --git a/worlds/ffx/locations.py b/worlds/ffx/locations.py index 24d90605c08e..4e54d1a6f845 100644 --- a/worlds/ffx/locations.py +++ b/worlds/ffx/locations.py @@ -615,8 +615,8 @@ def get_location_type(location_id: int): ("MCWO: Finish Butterfly Minigame (Event)", 277, False), # Key Item: Saturn Sigil [A02Bh] ("THPL: Lightning Dodger - 200 Consecutive Dodges (Event)", 278, False), # Key Item: Venus Sigil [A02Fh] ("BIKA: Desert - Complete Cactuar Village Quest (Event)", 279, False), # Key Item: Mercury Sigil [A031h] - ("MCLA: Megalixir x2 (Butterfly Game after defeating Spherimorph)", 280, False), # Item: 2x Megalixir [2009h] - ("MCLA: Elixir x2 (Butterfly Game after defeating Spherimorph)", 281, False), # Item: 2x Elixir [2008h] + ("MCWO: Megalixir x2 (Butterfly Game after defeating Spherimorph)", 280, False), # Item: 2x Megalixir [2009h] + ("MCWO: Elixir x2 (Butterfly Game after defeating Spherimorph)", 281, False), # Item: 2x Elixir [2008h] ("BSIL: Beach - Datto (NPC)", 282, False), # Item: 1x Hi-Potion [2001h] ("BSIL: Beach - Jassu (NPC)", 283, False), # Item: 3x Potion [2000h] ("BSIL: Beach - Botta (NPC)", 284, False), # Item: 2x Potion [2000h] @@ -729,7 +729,7 @@ def get_location_type(location_id: int): ("REMI: Anima Post First Fight (Boss)", 391, False), # Item: 10x Mana Sphere [2047h] ("REMI: Defeat Magus Sisters (Boss)", 392, False), # Item: 40x Shining Gem [202Ah] ("REMI: Magus Sisters Post First Fight (Boss)", 393, False), # Item: 12x Power Sphere [2046h] - ("MCLA: Teleport Sphere x1 (Butterfly Game after Airship)", 394, False), # Item: 1x Teleport Sphere [2062h] + ("MCWO: Teleport Sphere x1 (Butterfly Game after Airship)", 394, False), # Item: 1x Teleport Sphere [2062h] ("HOME: Living Quarters, East of Main Corridor - Quiz (Chest)", 395, False), # Item: 1x Skill Sphere [204Dh] ("HOME: Living Quarters, East of Main Corridor - Password (Chest)", 396, False), # Item: 1x Special Sphere [204Ch] ("HOME: Living Quarters, South of Main Corridor - Vocabulary Test (Chest)", 397, False), # Item: 1x Friend Sphere [2061h] diff --git a/worlds/ffx/options.py b/worlds/ffx/options.py index 3d303f9c6521..75513db545df 100644 --- a/worlds/ffx/options.py +++ b/worlds/ffx/options.py @@ -55,20 +55,81 @@ class APMultiplier(Range): range_end = 10 -class MiniGames(Toggle): +class MiniGameBlitzball(Toggle): """ - Sets whether minigames are included or not. If off they will only have filler items. - Minigames include; - - Blitzball (World Champion & Jupiter Sigil) + Sets whether Blitzball is included. + If off it will only have filler items. + This includes: - Luca Story Blitzball win - - Macalania Butterflies (Saturn Sigil) - - Thunder Plains Lightning Dodging (including Venus Sigil) - - Bikanel Cactuar Village (Mercury Sigil) - - Calm Lands Chocobo Training (Dodger, Hyper Dodger, Catcher, Caladbolg & Sun Sigil) - - Remiem Temple Chocobo Race (Cloudy Mirror) - Default is off. + - World Champion + - Jupiter Sigil + """ + display_name = "Blitzball" + default = 0 + option_off = 0 + option_on = 1 + + +class MiniGameButterflies(Toggle): + """ + Sets whether the Macalania Butterflies are included. + If off they will only have filler items. + """ + display_name = "Macalania Butterflies" + default = 0 + option_off = 0 + option_on = 1 + + +class MiniGameLightningDodging(Choice): + """ + Sets whether the Thunder Plains Lightning Dodging is included. + If off it will only have filler items. + """ + display_name = "Lightning Dodging" + default = 0 + option_off = 0 + option_up_to_5 = 1 + option_up_to_10 = 2 + option_up_to_20 = 3 + option_up_to_50 = 4 + option_up_to_100 = 5 + option_up_to_150 = 6 + option_up_to_200 = 7 + + +class MiniGameCactuarVillage(Toggle): + """ + Sets whether the Bikanel Cactuar Village sidequest is included. + If off it will only have filler items. + """ + display_name = "Cactuar Village" + default = 0 + option_off = 0 + option_on = 1 + + +class MiniGameChocoboTraining(Choice): + """ + Sets whether the Calm Lands Chocobo Training minigames are included. + If off they will only have filler items. + """ + display_name = "Chocobo Training" + default = 0 + option_off = 0 + option_up_to_wobbly = 1 + option_up_to_dodger = 2 + option_up_to_hyper_dodger = 3 + option_up_to_catcher = 4 + option_up_to_sigil = 5 + + +class MiniGameChocoboRace(Toggle): + """ + Sets whether the Remiem Temple Chocobo Race minigames are included. + If off they will only have filler items. """ - display_name = "Minigames" + display_name = "Remiem Chocobo Race" default = 0 option_off = 0 option_on = 1 @@ -275,7 +336,12 @@ class FFXOptions(PerGameCommonOptions): required_party_members: RequiredPartyMembers required_primers: RequiredPrimers ap_multiplier: APMultiplier - mini_games: MiniGames + mini_game_blitzball: MiniGameBlitzball + mini_game_butterflies: MiniGameButterflies + mini_game_lightning_dodging: MiniGameLightningDodging + mini_game_cactuar_village: MiniGameCactuarVillage + mini_game_chocobo_training: MiniGameChocoboTraining + mini_game_chocobo_race: MiniGameChocoboRace recruit_sanity: RecruitSanity capture_sanity: CaptureSanity arena_access: MonsterArenaAccess diff --git a/worlds/ffx/regions.py b/worlds/ffx/regions.py index c2f1d6e7d2db..760805197240 100644 --- a/worlds/ffx/regions.py +++ b/worlds/ffx/regions.py @@ -323,41 +323,136 @@ def primer_requirement_rule(state): # continue # world.multiworld.register_indirect_condition(this_region, menu_entrance) - if not world.options.mini_games.value: - mini_game_location_ids = [ - 337, # "Calm Lands: Wobbly Chocobo Minigame (Event)" - 338, # "Calm Lands: Dodger Chocobo Minigame (Event)" - 339, # "Calm Lands: Hyper Dodger Chocobo Minigame (Event)" - 340, # "Calm Lands: Catcher Chocobo Minigame (Event)" - 417, # "Calm Lands: Elixir x1 (Chocobo Race Reward)" - 418, # "Calm Lands: Megalixir x1 (Chocobo Race Reward)" - 419, # "Calm Lands: Three Stars x60 (Chocobo Race Reward)" - 420, # "Calm Lands: Pendulum x30 (Chocobo Race Reward)" - 421, # "Calm Lands: Wings to Discovery x30 (Chocobo Race Reward)" - 189, # "Thunder Plains: Megalixir x4 (Dodging Minigame Reward)", - 190, # "Thunder Plains: HP Sphere x3 (Dodging Minigame Reward)", - 191, # "Thunder Plains: Strength Sphere x3 (Dodging Minigame Reward)", - 192, # "Thunder Plains: MP Sphere x2 (Dodging Minigame Reward)", - 193, # "Thunder Plains: Mega-Potion x2 (Dodging Minigame Reward)", - 194, # "Thunder Plains: X-Potion x2 (Dodging Minigame Reward)", - 497, # "Story Win vs. Luca Goers Reward", - 274, # "Sun Sigil", - 278, # "Venus Sigil", - 277, # "Saturn Sigil", - 279, # "Mercury Sigil", - 244, # "Jupiter Sigil", - 114, # "Caladbolg", - 93, # "World Champion", - 176, # "Cloudy Mirror", + if not world.options.mini_game_blitzball: + blitzball_location_ids = [ + 497, # "LUCA: Win the Story Blitzball Tournament (Event)", + 244, # "Blitzball: Obtain The Jupiter Sigil League Prize (Event)", + 93, # "LUCA: Cafe - Talk to Owner After Placing at Least Third in a Tournament (Chest)" (World Champion), ] - for id in mini_game_location_ids: + + for id in blitzball_location_ids: + location_name = world.location_id_to_name[id | TreasureOffset] + world.options.exclude_locations.value.add(location_name) + + if not world.options.mini_game_butterflies: + butterfly_location_ids = [ + 71, # "MCWO: MP Sphere x1 (Butterfly Minigame Reward before Spherimorph)", + 72, # "MCWO: Ether x1 (Butterfly Minigame Reward before Spherimorph)", + 280, # "MCWO: Megalixir x2 (Butterfly Game after defeating Spherimorph)", + 281, # "MCWO: Elixir x2 (Butterfly Game after defeating Spherimorph)", + 394, # "MCWO: Teleport Sphere x1 (Butterfly Game after Airship)", + 277, # "MCWO: Finish Butterfly Minigame (Event)" (Saturn Sigil), + ] + + for id in butterfly_location_ids: + location_name = world.location_id_to_name[id | TreasureOffset] + world.options.exclude_locations.value.add(location_name) + + if not world.options.mini_game_lightning_dodging is world.options.mini_game_lightning_dodging.option_up_to_200: + lightning_dodging_location_ids = [] + + up_to = world.options.mini_game_lightning_dodging + up_to_200 = world.options.mini_game_lightning_dodging.option_up_to_200 + up_to_150 = world.options.mini_game_lightning_dodging.option_up_to_150 + up_to_100 = world.options.mini_game_lightning_dodging.option_up_to_100 + up_to_50 = world.options.mini_game_lightning_dodging.option_up_to_50 + up_to_20 = world.options.mini_game_lightning_dodging.option_up_to_20 + up_to_10 = world.options.mini_game_lightning_dodging.option_up_to_10 + up_to_5 = world.options.mini_game_lightning_dodging.option_up_to_5 + + if up_to < up_to_200: + lightning_dodging_location_ids.append(278) # "THPL: Lightning Dodger - 200 Consecutive Dodges (Event)", + + if up_to < up_to_150: + lightning_dodging_location_ids.append(194) # "THPL: Lightning Dodger - 150 Consecutive Dodges (Event)", + + if up_to < up_to_100: + lightning_dodging_location_ids.append(193) # "THPL: Lightning Dodger - 100 Consecutive Dodges (Event)", + + if up_to < up_to_50: + lightning_dodging_location_ids.append(192) # "THPL: Lightning Dodger - 50 Consecutive Dodges (Event)", + + if up_to < up_to_20: + lightning_dodging_location_ids.append(191) # "THPL: Lightning Dodger - 20 Consecutive Dodges (Event)", + + if up_to < up_to_10: + lightning_dodging_location_ids.append(190) # "THPL: Lightning Dodger - 10 Consecutive Dodges (Event)", + + if up_to < up_to_5: + lightning_dodging_location_ids.append(189) # "THPL: Lightning Dodger - 5 Consecutive Dodges (Event)", + + for id in lightning_dodging_location_ids: + location_name = world.location_id_to_name[id | TreasureOffset] + world.options.exclude_locations.value.add(location_name) + + if not world.options.mini_game_cactuar_village: + cactuar_village_location_ids = [ + 469, # "BIKA: Shadow Gem x2 (Robeya Minigame Chest)", + 470, # "BIKA: Shining Gem x1 (Robeya Minigame Chest)", + 471, # "BIKA: Blessed Gem x1 (Robeya Minigame Chest)", + 472, # "BIKA: Potion x1 (Cactuar Sidequest Prize)", + 473, # "BIKA: Elixir x1 (Cactuar Sidequest Prize)", + 474, # "BIKA: Megalixir x1 (Cactuar Sidequest Prize)", + 475, # "BIKA: Friend Sphere x1 (Cactuar Sidequest Prize)", + 279, # "BIKA: Desert - Complete Cactuar Village Quest (Event)", (Mercury Sigil) + ] + + for id in cactuar_village_location_ids: + location_name = world.location_id_to_name[id | TreasureOffset] + world.options.exclude_locations.value.add(location_name) + + if not world.options.mini_game_chocobo_training is world.options.mini_game_chocobo_training.option_up_to_sigil: + chocobo_training_location_ids = [] + + up_to = world.options.mini_game_chocobo_training + up_to_sigil = world.options.mini_game_chocobo_training.option_up_to_sigil + up_to_catcher = world.options.mini_game_chocobo_training.option_up_to_catcher + up_to_hyper_dodger = world.options.mini_game_chocobo_training.option_up_to_hyper_dodger + up_to_dodger = world.options.mini_game_chocobo_training.option_up_to_dodger + up_to_wobbly = world.options.mini_game_chocobo_training.option_up_to_wobbly + + if up_to < up_to_sigil: + chocobo_training_location_ids.append(274) # "CALM: Catcher chocobo Minigame, Time Under 0.00 (Event)", + + if up_to < up_to_catcher: + chocobo_training_location_ids.extend([ + 340, # "CALM: Catcher Chocobo Minigame (Event)", + 114, # "CALM: North - NW Corner, Blocked Until Winning Catcher Chocobo (Event)" (Caladbolg), + ]) + + if up_to < up_to_hyper_dodger: + chocobo_training_location_ids.append(339) # "CALM: Hyper Dodger Chocobo Minigame (Event)", + + if up_to < up_to_dodger: + chocobo_training_location_ids.append(338) # "CALM: Dodger Chocobo Minigame (Event)", + + if up_to < up_to_wobbly: + chocobo_training_location_ids.append(337) # "CALM: Wobbly Chocobo Minigame (Event)", + + # Change Remiem access from Wobbly Chocobo to Post-Defender X + calm_lands_to_remiem = world.get_region("Remiem Temple").entrances[0] + new_parent = world.get_region("Calm Lands 1st visit: Post-Defender X") + calm_lands_to_remiem.parent_region.exits.remove(calm_lands_to_remiem) + calm_lands_to_remiem.parent_region = new_parent + new_parent.exits.append(calm_lands_to_remiem) + + for id in chocobo_training_location_ids: + location_name = world.location_id_to_name[id | TreasureOffset] + world.options.exclude_locations.value.add(location_name) + + if not world.options.mini_game_chocobo_race: + chocobo_race_location_ids = [ + 176, # "REMI: Win Chocobo Race (Event)" (Cloudy Mirror) + 417, # "REMI: 1st Chest in Chocobo Race", + 418, # "REMI: 2nd Chest in Chocobo Race", + 419, # "REMI: 3rd Chest in Chocobo Race", + 420, # "REMI: 4th Chest in Chocobo Race", + 421, # "REMI: 5th Chest in Chocobo Race", + ] + + for id in chocobo_race_location_ids: location_name = world.location_id_to_name[id | TreasureOffset] world.options.exclude_locations.value.add(location_name) - calm_lands_to_remiem = world.get_region("Remiem Temple").entrances[0] - new_parent = world.get_region("Calm Lands 1st visit: Post-Defender X") - calm_lands_to_remiem.parent_region.exits.remove(calm_lands_to_remiem) - calm_lands_to_remiem.parent_region = new_parent - new_parent.exits.append(calm_lands_to_remiem) if not world.options.recruit_sanity.value: recruit_location_ids = [] diff --git a/worlds/ffx/ut.py b/worlds/ffx/ut.py index d710dde787c0..fb1e2c893a84 100644 --- a/worlds/ffx/ut.py +++ b/worlds/ffx/ut.py @@ -11,19 +11,24 @@ def setup_options_from_slot_data(world: FFXWorld) -> None: world.using_ut = True world.passthrough = world.multiworld.re_gen_passthrough["Final Fantasy X"] - world.options.goal_requirement.value = world.passthrough["goal_requirement"] - world.options.required_party_members.value = world.passthrough["required_party_members"] - world.options.required_primers.value = world.passthrough["required_primers"] - world.options.sphere_grid_randomization.value = world.passthrough["sphere_grid_randomization"] - world.options.mini_games.value = world.passthrough["mini_games"] - world.options.recruit_sanity.value = world.passthrough["recruit_sanity"] - world.options.capture_sanity.value = world.passthrough["capture_sanity"] - world.options.creation_rewards.value = world.passthrough["creation_rewards"] - world.options.arena_bosses.value = world.passthrough["arena_bosses"] - world.options.super_bosses.value = world.passthrough["super_bosses"] - world.options.jecht_spheres.value = world.passthrough["jecht_spheres"] - world.options.always_capture.value = world.passthrough["always_capture"] - world.options.logic_difficulty.value = world.passthrough["logic_difficulty"] + world.options.goal_requirement.value = world.passthrough["goal_requirement"] + world.options.required_party_members.value = world.passthrough["required_party_members"] + world.options.required_primers.value = world.passthrough["required_primers"] + world.options.sphere_grid_randomization.value = world.passthrough["sphere_grid_randomization"] + world.options.mini_game_blitzball.value = world.passthrough["mini_game_blitzball"] + world.options.mini_game_butterflies.value = world.passthrough["mini_game_butterflies"] + world.options.mini_game_lightning_dodging.value = world.passthrough["mini_game_lightning_dodging"] + world.options.mini_game_cactuar_village.value = world.passthrough["mini_game_cactuar_village"] + world.options.mini_game_chocobo_training.value = world.passthrough["mini_game_chocobo_training"] + world.options.mini_game_chocobo_race.value = world.passthrough["mini_game_chocobo_race"] + world.options.recruit_sanity.value = world.passthrough["recruit_sanity"] + world.options.capture_sanity.value = world.passthrough["capture_sanity"] + world.options.creation_rewards.value = world.passthrough["creation_rewards"] + world.options.arena_bosses.value = world.passthrough["arena_bosses"] + world.options.super_bosses.value = world.passthrough["super_bosses"] + world.options.jecht_spheres.value = world.passthrough["jecht_spheres"] + world.options.always_capture.value = world.passthrough["always_capture"] + world.options.logic_difficulty.value = world.passthrough["logic_difficulty"]