From 53be043af4ad1a605d7a2b5dcfb1ca0738a0d307 Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Sun, 18 May 2025 01:00:09 -0500 Subject: [PATCH] Damage Challenge modes: OHKO and Gloom --- BaseClasses.py | 8 +++++++- CLI.py | 3 ++- ItemList.py | 7 +++++-- Main.py | 3 +++ Rom.py | 18 +++++++++++++++++- Rules.py | 26 +++++++++++++------------- data/base2current.bps | Bin 136684 -> 136729 bytes resources/app/cli/args.json | 7 +++++++ 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 8b558fad..101e06cd 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -72,9 +72,10 @@ class World(object): self.fix_trock_exit = {} self.shuffle_ganon = shuffle_ganon self.dark_rooms = {} + self.damage_challenge = {} self.custom = custom self.customitemarray = customitemarray - self.can_take_damage = True + self.can_take_damage = {} self.hints = hints.copy() self.prizes = {} self.dynamic_regions = [] @@ -170,7 +171,9 @@ class World(object): set_player_attr('pot_contents', None) set_player_attr('pseudoboots', False) set_player_attr('mirrorscroll', False) + set_player_attr('can_take_damage', True) set_player_attr('dark_rooms', 'require_lamp') + set_player_attr('damage_challenge', 'normal') set_player_attr('crystal_book', False) set_player_attr('collection_rate', False) set_player_attr('colorizepots', True) @@ -3069,7 +3072,9 @@ class Spoiler(object): 'shopsanity': self.world.shopsanity, 'pseudoboots': self.world.pseudoboots, 'mirrorscroll': self.world.mirrorscroll, + 'can_take_damage': self.world.can_take_damage, 'dark_rooms': self.world.dark_rooms, + 'damage_challenge': self.world.damage_challenge, 'crystal_book': self.world.crystal_book, 'triforcegoal': self.world.treasure_hunt_count, 'triforcepool': self.world.treasure_hunt_total, @@ -3322,6 +3327,7 @@ class Spoiler(object): outfile.write('Pseudoboots:'.ljust(line_width) + '%s\n' % yn(self.metadata['pseudoboots'][player])) outfile.write('Mirror Scroll:'.ljust(line_width) + '%s\n' % yn(self.metadata['mirrorscroll'][player])) outfile.write('Dark Rooms:'.ljust(line_width) + '%s\n' % self.metadata['dark_rooms'][player]) + outfile.write('Damage Challenge:'.ljust(line_width) + '%s\n' % self.metadata['damage_challenge'][player]) outfile.write('Crystal Book:'.ljust(line_width) + '%s\n' % yn(self.metadata['crystal_book'][player])) outfile.write('Hints:'.ljust(line_width) + '%s\n' % yn(self.metadata['hints'][player])) outfile.write('Race:'.ljust(line_width) + '%s\n' % yn(self.world.settings.world_rep['meta']['race'])) diff --git a/CLI.py b/CLI.py index cb3bca05..abf5245d 100644 --- a/CLI.py +++ b/CLI.py @@ -139,7 +139,7 @@ def parse_cli(argv, no_defaults=False): 'triforce_max_difference', 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'shuffletavern', 'skullwoods', 'linked_drops', - 'pseudoboots', 'mirrorscroll', 'dark_rooms', 'crystal_book', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', + 'pseudoboots', 'mirrorscroll', 'dark_rooms', 'damage_challenge', 'crystal_book', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', @@ -212,6 +212,7 @@ def parse_settings(): "pseudoboots": False, "mirrorscroll": False, "dark_rooms": "require_lamp", + "damage_challenge": "normal", "crystal_book": False, "shuffleenemies": "none", diff --git a/ItemList.py b/ItemList.py index 4befd714..693fa96d 100644 --- a/ItemList.py +++ b/ItemList.py @@ -226,7 +226,10 @@ def generate_itempool(world, player): raise NotImplementedError('Not supported yet') if world.timer in ['ohko', 'timed-ohko']: - world.can_take_damage = False + world.can_take_damage[player] = False + + if world.damage_challenge[player] in ['ohko', 'gloom']: + world.can_take_damage[player] = False if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']: set_event_item(world, player, 'Ganon', 'Nothing') @@ -1287,7 +1290,7 @@ def modify_pool_for_start_inventory(start_inventory, world, player): d.big_key = None -def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, dark_rooms, customitemarray): +def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, customitemarray): pool = [] placed_items = {} precollected_items = [] diff --git a/Main.py b/Main.py index 75d0c174..bb7a4cdf 100644 --- a/Main.py +++ b/Main.py @@ -514,6 +514,7 @@ def init_world(args, fish): world.pseudoboots = args.pseudoboots.copy() world.mirrorscroll = args.mirrorscroll.copy() world.dark_rooms = args.dark_rooms.copy() + world.damage_challenge = args.damage_challenge.copy() world.crystal_book = args.crystal_book.copy() world.overworld_map = args.overworld_map.copy() world.take_any = args.take_any.copy() @@ -619,6 +620,7 @@ def copy_world(world): ret.pseudoboots = world.pseudoboots.copy() ret.mirrorscroll = world.mirrorscroll.copy() ret.dark_rooms = world.dark_rooms.copy() + ret.damage_challenge = world.damage_challenge.copy() ret.crystal_book = world.crystal_book.copy() ret.overworld_map = world.overworld_map.copy() ret.take_any = world.take_any.copy() @@ -842,6 +844,7 @@ def copy_world_premature(world, player): ret.pseudoboots = world.pseudoboots.copy() ret.mirrorscroll = world.mirrorscroll.copy() ret.dark_rooms = world.dark_rooms.copy() + ret.damage_challenge = world.damage_challenge.copy() ret.crystal_book = world.crystal_book.copy() ret.overworld_map = world.overworld_map.copy() ret.take_any = world.take_any.copy() diff --git a/Rom.py b/Rom.py index aa162e02..2028d274 100644 --- a/Rom.py +++ b/Rom.py @@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'f68e3c6169462af6e95c56b65b40701b' +RANDOMIZERBASEHASH = 'a23774f12c16a50834097fc0a661f6c1' class JsonRom(object): @@ -1141,6 +1141,22 @@ def patch_rom(world, rom, player, team, is_mystery=False): if world.swords[player] == 'swordless': rom.initial_sram.set_swordless_curtains() # open curtains + # set up challenge modes + challenge = 0x00; + if world.damage_challenge[player] == 'ohko': + challenge |= 0x01 + rom.write_byte(0x39C6B, 0x80) # never spawn sword beams + elif world.damage_challenge[player] == 'gloom': + challenge |= 0x02 + rom.write_bytes(0x4F4AC, [0x08, + 0x08, 0x10, 0x18, 0x20, 0x28, + 0x30, 0x38, 0x40, 0x48, 0x50, + 0x58, 0x60, 0x68, 0x70, 0x78, + 0x80, 0x88, 0x90, 0x98, 0xA0]) # spawn with full health + rom.write_byte(0x39C6B, 0x80) # never spawn sword beams + rom.write_bytes(0x187033, [0x28, 0x20, 0x28, 0x20]) # heart icon + rom.write_byte(0x18002D, challenge) + # set up clocks for timed modes if world.shuffle[player] == 'vanilla': ERtimeincrease = 0 diff --git a/Rules.py b/Rules.py index b4c9ab71..6fcfbbf6 100644 --- a/Rules.py +++ b/Rules.py @@ -287,7 +287,7 @@ def global_rules(world, player): ((state.has('Cape', player) and state.can_extend_magic(player, 16, True)) or (state.has('Cane of Byrna', player) and (state.can_extend_magic(player, 12, True) or - (state.world.can_take_damage and (state.has_Boots(player) or state.has_hearts(player, 4)))))) + (state.world.can_take_damage[player] and (state.has_Boots(player) or state.has_hearts(player, 4)))))) ) # underworld rules @@ -539,10 +539,10 @@ def global_rules(world, player): set_rule(world.get_location('Ice Palace - Map Chest', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player)) set_rule(world.get_entrance('Ice Antechamber Hole', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player)) # todo: ohko rules for spike room - could split into two regions instead of these, but can_take_damage is usually true - set_rule(world.get_entrance('Ice Spike Room WS', player), lambda state: state.world.can_take_damage or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) - set_rule(world.get_entrance('Ice Spike Room Up Stairs', player), lambda state: state.world.can_take_damage or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) - set_rule(world.get_entrance('Ice Spike Room Down Stairs', player), lambda state: state.world.can_take_damage or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) - set_rule(world.get_location('Ice Palace - Spike Room', player), lambda state: state.world.can_take_damage or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_entrance('Ice Spike Room WS', player), lambda state: state.world.can_take_damage[player] or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_entrance('Ice Spike Room Up Stairs', player), lambda state: state.world.can_take_damage[player] or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_entrance('Ice Spike Room Down Stairs', player), lambda state: state.world.can_take_damage[player] or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_location('Ice Palace - Spike Room', player), lambda state: state.world.can_take_damage[player] or state.has('Hookshot', player) or state.has('Cape', player) or state.has('Cane of Byrna', player)) set_rule(world.get_location('Ice Palace - Freezor Chest', player), lambda state: state.can_melt_things(player)) set_rule(world.get_entrance('Ice Hookshot Ledge Path', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_entrance('Ice Hookshot Balcony Path', player), lambda state: state.has('Hookshot', player)) @@ -566,11 +566,11 @@ def global_rules(world, player): # (state.has('Ice Rod', player) and state.can_use_bombs(player)) or # freeze popo and throw, bomb to finish # state.has('Hammer', player) or state.has('Cane of Somaria', player) or state.can_shoot_arrows(player)) # need to defeat wizzrobes, bombs don't work ... # byrna could work with sufficient magic - set_rule(world.get_location('Misery Mire - Spike Chest', player), lambda state: (state.world.can_take_damage and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player)) + set_rule(world.get_location('Misery Mire - Spike Chest', player), lambda state: (state.world.can_take_damage[player] and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player)) loc = world.get_location('Misery Mire - Spikes Pot Key', player) if loc.pot: if loc.pot.x == 48 and loc.pot.y == 28: # pot shuffled to spike area - set_rule(loc, lambda state: (state.world.can_take_damage and state.has_hearts(player, 4)) + set_rule(loc, lambda state: (state.world.can_take_damage[player] and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player)) set_rule(world.get_entrance('Mire Left Bridge Hook Path', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_entrance('Mire Tile Room NW', player), lambda state: state.has_fire_source(player)) @@ -734,8 +734,8 @@ def global_rules(world, player): set_rule(world.get_entrance('Swamp Crystal Switch Inner to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('Swamp Crystal Switch Outer to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_beam_sword(player) or (state.has('Hookshot', player) and state.can_reach_blue(world.get_region('Swamp Crystal Switch Outer', player), player))) # It is the length of the sword, not the beam itself that allows this - set_rule(world.get_entrance('Swamp Crystal Switch Outer to Inner Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) - set_rule(world.get_entrance('Swamp Crystal Switch Inner to Outer Bypass', player), lambda state: state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_entrance('Swamp Crystal Switch Outer to Inner Bypass', player), lambda state: state.world.can_take_damage[player] or state.has('Cape', player) or state.has('Cane of Byrna', player)) + set_rule(world.get_entrance('Swamp Crystal Switch Inner to Outer Bypass', player), lambda state: state.world.can_take_damage[player] or state.has('Cape', player) or state.has('Cane of Byrna', player)) set_rule(world.get_entrance('Thieves Hellway Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Thieves Hellway', player), player)) set_rule(world.get_entrance('Thieves Hellway Orange Barrier', player), lambda state: state.can_reach_orange(world.get_region('Thieves Hellway', player), player)) @@ -778,7 +778,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Mire Conveyor to Crystal', player), lambda state: state.can_hit_crystal(player)) set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: True) # Can always throw pots - set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic? + set_rule(world.get_entrance('Mire Fishbone Blue Barrier Bypass', player), lambda state: False) # (state.world.can_take_damage[player] or state.has('Cape', player) or state.has('Cane of Byrna', player)) and state.can_tastate.can_use_bombs(player) // Easy to do but obscure. Should it be in logic? set_rule(world.get_location('Turtle Rock - Chain Chomps', player), lambda state: state.can_reach('TR Chain Chomps Top', 'Region', player) and state.can_hit_crystal_through_barrier(player)) set_rule(world.get_entrance('TR Chain Chomps Top to Bottom Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('TR Chain Chomps Top', player), player)) @@ -998,7 +998,7 @@ def pot_rules(world, player): ((state.has('Cape', player) and state.can_extend_magic(player, 16, True)) or (state.has('Cane of Byrna', player) and (state.can_extend_magic(player, 12, True) or - (state.world.can_take_damage and (state.has_Boots(player) or state.has_hearts(player, 4))))))) + (state.world.can_take_damage[player] and (state.has_Boots(player) or state.has_hearts(player, 4))))))) for l in world.get_region('Mire Hint', player).locations: if l.type == LocationType.Pot: add_rule(l, lambda state: state.can_use_bombs(player)) @@ -1008,7 +1008,7 @@ def pot_rules(world, player): for number in ['1', '2']: loc = world.get_location_unsafe(f'Dark Lake Hylia Ledge Spike Cave Pot #{number}', player) if loc and loc.type == LocationType.Pot: - add_rule(loc, lambda state: state.world.can_take_damage or state.has('Hookshot', player) + add_rule(loc, lambda state: state.world.can_take_damage[player] or state.has('Hookshot', player) or state.has('Cape', player) or (state.has('Cane of Byrna', player) and state.world.difficulty_adjustments[player] == 'normal')) @@ -1021,7 +1021,7 @@ def pot_rules(world, player): set_rule(loc, lambda state: state.has('Hammer', player) and state.can_lift_rocks(player)) loc = world.get_location_unsafe('Mire Spikes Pot #3', player) if loc: - set_rule(loc, lambda state: (state.world.can_take_damage and state.has_hearts(player, 4)) + set_rule(loc, lambda state: (state.world.can_take_damage[player] and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player)) for l in world.get_region('Ice Refill', player).locations: if l.type == LocationType.Pot: diff --git a/data/base2current.bps b/data/base2current.bps index a695e8e3fe3b72534ce3a26eb03e1d6288bf2c4f..a20ee0f3a24bcd9941e389d903b4161b8f65b357 100644 GIT binary patch delta 9646 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 delta 9795 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 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 27e128eb..bc5a989b 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -571,6 +571,13 @@ "always_in_logic" ] }, + "damage_challenge": { + "choices": [ + "normal", + "ohko", + "gloom" + ] + }, "crystal_book": { "action": "store_true", "type": "bool"