Add --require_ganon_item option

This commit is contained in:
2026-06-08 23:27:18 -05:00
parent 2039159d36
commit 0bc1a5c2ad
6 changed files with 26 additions and 7 deletions

View File

@@ -85,6 +85,7 @@ class World(object):
self.bosses_ganon = {} self.bosses_ganon = {}
self.bosshunt_include_agas = {} self.bosshunt_include_agas = {}
self.ganon_item = {} self.ganon_item = {}
self.require_ganon_item = {}
self.ganon_item_orig = {} self.ganon_item_orig = {}
self.custom = custom self.custom = custom
self.customitemarray = customitemarray self.customitemarray = customitemarray
@@ -186,6 +187,7 @@ class World(object):
set_player_attr('bosses_ganon', 8) set_player_attr('bosses_ganon', 8)
set_player_attr('bosshunt_include_agas', False) set_player_attr('bosshunt_include_agas', False)
set_player_attr('ganon_item', 'silver') set_player_attr('ganon_item', 'silver')
set_player_attr('require_ganon_item', False)
set_player_attr('crystals_ganon_orig', {}) set_player_attr('crystals_ganon_orig', {})
set_player_attr('crystals_gt_orig', {}) set_player_attr('crystals_gt_orig', {})
set_player_attr('ganon_item_orig', 'silver') set_player_attr('ganon_item_orig', 'silver')
@@ -3154,6 +3156,7 @@ class Spoiler(object):
'ganon_bosses': self.world.bosses_ganon, 'ganon_bosses': self.world.bosses_ganon,
'bosshunt_include_agas': self.world.bosshunt_include_agas, 'bosshunt_include_agas': self.world.bosshunt_include_agas,
'ganon_item': self.world.ganon_item, 'ganon_item': self.world.ganon_item,
'require_ganon_item': self.world.require_ganon_item,
'open_pyramid': self.world.open_pyramid, 'open_pyramid': self.world.open_pyramid,
'accessibility': self.world.accessibility, 'accessibility': self.world.accessibility,
'restricted_boss_items': self.world.restrict_boss_items, 'restricted_boss_items': self.world.restrict_boss_items,
@@ -3391,7 +3394,8 @@ class Spoiler(object):
if custom['murahgoal'] and 'requirements' in custom['murahgoal']: if custom['murahgoal'] and 'requirements' in custom['murahgoal']:
outfile.write('Murahdahla Requirement:'.ljust(line_width) + 'custom\n') outfile.write('Murahdahla Requirement:'.ljust(line_width) + 'custom\n')
outfile.write(' %s\n' % custom['murahgoal']['goaltext']) 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('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player])
outfile.write('\n') outfile.write('\n')
outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player]) outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player])

4
CLI.py
View File

@@ -159,7 +159,8 @@ def parse_cli(argv, no_defaults=False):
'take_any', 'boots_hint', 'shuffle_followers', 'take_any', 'boots_hint', 'shuffle_followers',
'shuffle', 'door_shuffle', 'intensity', 'shuffle', 'door_shuffle', 'intensity',
'crystals_ganon', 'crystals_gt', 'bosses_ganon', 'crystals_ganon', 'crystals_gt', 'bosses_ganon',
'bosshunt_include_agas', 'ganon_item', 'openpyramid', 'bosshunt_include_agas', 'ganon_item',
'require_ganon_item', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle', 'mapshuffle', 'compassshuffle', 'keyshuffle',
'bigkeyshuffle', 'prizeshuffle', 'showloot', 'loothud', 'bigkeyshuffle', 'prizeshuffle', 'showloot', 'loothud',
'showmap', 'startinventory', 'usestartinventory', 'showmap', 'startinventory', 'usestartinventory',
@@ -220,6 +221,7 @@ def parse_settings():
"bosses_ganon": "8", "bosses_ganon": "8",
"bosshunt_include_agas": False, "bosshunt_include_agas": False,
"ganon_item": "silver", "ganon_item": "silver",
"require_ganon_item": False,
"swords": "random", "swords": "random",
"flute_mode": "normal", "flute_mode": "normal",
"bow_mode": "progressive", "bow_mode": "progressive",

View File

@@ -546,6 +546,7 @@ def init_world(args, fish):
world.crystals_ganon_orig = args.crystals_ganon.copy() world.crystals_ganon_orig = args.crystals_ganon.copy()
world.crystals_gt_orig = args.crystals_gt.copy() world.crystals_gt_orig = args.crystals_gt.copy()
world.ganon_item_orig = args.ganon_item.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.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.bosshunt_include_agas = args.bosshunt_include_agas.copy()
world.owTerrain = args.ow_terrain.copy() world.owTerrain = args.ow_terrain.copy()
@@ -871,6 +872,7 @@ def copy_world(world):
ret.bosses_ganon = world.bosses_ganon.copy() ret.bosses_ganon = world.bosses_ganon.copy()
ret.bosshunt_include_agas = world.bosshunt_include_agas.copy() ret.bosshunt_include_agas = world.bosshunt_include_agas.copy()
ret.ganon_item = world.ganon_item.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_ganon_orig = world.crystals_ganon_orig.copy()
ret.crystals_gt_orig = world.crystals_gt_orig.copy() ret.crystals_gt_orig = world.crystals_gt_orig.copy()
ret.ganon_item_orig = world.ganon_item_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.bosses_ganon = world.bosses_ganon.copy()
ret.bosshunt_include_agas = world.bosshunt_include_agas.copy() ret.bosshunt_include_agas = world.bosshunt_include_agas.copy()
ret.ganon_item = world.ganon_item.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_ganon_orig = world.crystals_ganon_orig.copy()
ret.crystals_gt_orig = world.crystals_gt_orig.copy() ret.crystals_gt_orig = world.crystals_gt_orig.copy()
ret.ganon_item_orig = world.ganon_item_orig.copy() ret.ganon_item_orig = world.ganon_item_orig.copy()

7
Rom.py
View File

@@ -1452,7 +1452,12 @@ def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None):
"byrna": 0x12, "byrna": 0x12,
"none": 0x7F, "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 # 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' prevent_rain = world.mode[player] == 'standard' and world.shuffle[player] != 'vanilla' and world.logic[player] != 'nologic'

View File

@@ -1026,10 +1026,11 @@ def global_rules(world, player):
world.get_location('Ganon', player), world.get_location('Ganon', player),
lambda state: state.has_beam_sword(player) lambda state: state.has_beam_sword(player)
and state.has_fire_source(player) and state.has_fire_source(player)
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) and (state.can_hit_stunned_ganon(player) or (
or state.can_hit_stunned_ganon(player) not world.require_ganon_item[player] and (
or state.has('Lamp', player) state.has('Tempered Sword', player) or state.has('Golden Sword', player)
or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times 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 set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop

View File

@@ -378,6 +378,10 @@
"none" "none"
] ]
}, },
"require_ganon_item": {
"action": "store_true",
"type": "bool"
},
"beemizer": { "beemizer": {
"choices": [ "choices": [
"4", "3", "2", "1", "0" "4", "3", "2", "1", "0"