From 0bc1a5c2ad80b7490306793aa86167f5ff910ebf Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Mon, 8 Jun 2026 23:27:18 -0500 Subject: [PATCH] Add --require_ganon_item option --- BaseClasses.py | 6 +++++- CLI.py | 4 +++- Main.py | 3 +++ Rom.py | 7 ++++++- Rules.py | 9 +++++---- resources/app/cli/args.json | 4 ++++ 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 9f1b3706..d8fb6307 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -85,6 +85,7 @@ class World(object): self.bosses_ganon = {} self.bosshunt_include_agas = {} self.ganon_item = {} + self.require_ganon_item = {} self.ganon_item_orig = {} self.custom = custom self.customitemarray = customitemarray @@ -186,6 +187,7 @@ class World(object): set_player_attr('bosses_ganon', 8) set_player_attr('bosshunt_include_agas', False) set_player_attr('ganon_item', 'silver') + set_player_attr('require_ganon_item', False) set_player_attr('crystals_ganon_orig', {}) set_player_attr('crystals_gt_orig', {}) set_player_attr('ganon_item_orig', 'silver') @@ -3154,6 +3156,7 @@ class Spoiler(object): 'ganon_bosses': self.world.bosses_ganon, 'bosshunt_include_agas': self.world.bosshunt_include_agas, 'ganon_item': self.world.ganon_item, + 'require_ganon_item': self.world.require_ganon_item, 'open_pyramid': self.world.open_pyramid, 'accessibility': self.world.accessibility, 'restricted_boss_items': self.world.restrict_boss_items, @@ -3391,7 +3394,8 @@ class Spoiler(object): if custom['murahgoal'] and 'requirements' in custom['murahgoal']: outfile.write('Murahdahla Requirement:'.ljust(line_width) + 'custom\n') outfile.write(' %s\n' % custom['murahgoal']['goaltext']) - outfile.write('Item Required for Ganon:'.ljust(line_width) + '%s\n' % str(self.world.ganon_item_orig[player])) + outfile.write('Item to Hurt Stunned Ganon:'.ljust(line_width) + '%s\n' % str(self.world.ganon_item_orig[player])) + outfile.write('Item Required for Ganon:'.ljust(line_width) + '%s\n' % yn(self.world.require_ganon_item[player])) outfile.write('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player]) outfile.write('\n') outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player]) diff --git a/CLI.py b/CLI.py index 889ca73d..477684a4 100644 --- a/CLI.py +++ b/CLI.py @@ -159,7 +159,8 @@ def parse_cli(argv, no_defaults=False): 'take_any', 'boots_hint', 'shuffle_followers', 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'bosses_ganon', - 'bosshunt_include_agas', 'ganon_item', 'openpyramid', + 'bosshunt_include_agas', 'ganon_item', + 'require_ganon_item', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'prizeshuffle', 'showloot', 'loothud', 'showmap', 'startinventory', 'usestartinventory', @@ -220,6 +221,7 @@ def parse_settings(): "bosses_ganon": "8", "bosshunt_include_agas": False, "ganon_item": "silver", + "require_ganon_item": False, "swords": "random", "flute_mode": "normal", "bow_mode": "progressive", diff --git a/Main.py b/Main.py index fd086076..851c451c 100644 --- a/Main.py +++ b/Main.py @@ -546,6 +546,7 @@ def init_world(args, fish): world.crystals_ganon_orig = args.crystals_ganon.copy() world.crystals_gt_orig = args.crystals_gt.copy() world.ganon_item_orig = args.ganon_item.copy() + world.require_ganon_item = args.require_ganon_item.copy() world.bosses_ganon = {player: int(args.bosses_ganon[player]) for player in range(1, world.players + 1)} world.bosshunt_include_agas = args.bosshunt_include_agas.copy() world.owTerrain = args.ow_terrain.copy() @@ -871,6 +872,7 @@ def copy_world(world): ret.bosses_ganon = world.bosses_ganon.copy() ret.bosshunt_include_agas = world.bosshunt_include_agas.copy() ret.ganon_item = world.ganon_item.copy() + ret.require_ganon_item = world.require_ganon_item.copy() ret.crystals_ganon_orig = world.crystals_ganon_orig.copy() ret.crystals_gt_orig = world.crystals_gt_orig.copy() ret.ganon_item_orig = world.ganon_item_orig.copy() @@ -1105,6 +1107,7 @@ def copy_world_premature(world, player, create_flute_exits=True): ret.bosses_ganon = world.bosses_ganon.copy() ret.bosshunt_include_agas = world.bosshunt_include_agas.copy() ret.ganon_item = world.ganon_item.copy() + ret.require_ganon_item = world.require_ganon_item.copy() ret.crystals_ganon_orig = world.crystals_ganon_orig.copy() ret.crystals_gt_orig = world.crystals_gt_orig.copy() ret.ganon_item_orig = world.ganon_item_orig.copy() diff --git a/Rom.py b/Rom.py index 02335767..4b620e9a 100644 --- a/Rom.py +++ b/Rom.py @@ -1452,7 +1452,12 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None): "byrna": 0x12, "none": 0x7F, } - rom.write_byte(0x18002E, ganon_item_byte[world.ganon_item[player]]) + ganon_item_value = ganon_item_byte[world.ganon_item[player]] + if world.require_ganon_item[player] and world.ganon_item[player] != "none": + if world.swords[player] != "swordless" or world.ganon_item[player] not in ["bombos", "ether", "quake"]: + ganon_item_value |= 0x80 + + rom.write_byte(0x18002E, ganon_item_value) # block HC upstairs doors in rain state in standard mode prevent_rain = world.mode[player] == 'standard' and world.shuffle[player] != 'vanilla' and world.logic[player] != 'nologic' diff --git a/Rules.py b/Rules.py index 32802638..9f8457b7 100644 --- a/Rules.py +++ b/Rules.py @@ -1026,10 +1026,11 @@ def global_rules(world, player): world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player) - and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) - or state.can_hit_stunned_ganon(player) - or state.has('Lamp', player) - or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times + and (state.can_hit_stunned_ganon(player) or ( + not world.require_ganon_item[player] and ( + state.has('Tempered Sword', player) or state.has('Golden Sword', player) + or state.has('Lamp', player) + or state.can_extend_magic(player, 12))))) # need to light torch a sufficient amount of times set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 4df2a18f..ab174c5b 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -378,6 +378,10 @@ "none" ] }, + "require_ganon_item": { + "action": "store_true", + "type": "bool" + }, "beemizer": { "choices": [ "4", "3", "2", "1", "0"