Damage Challenge modes: OHKO and Gloom
This commit is contained in:
@@ -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']))
|
||||
|
||||
3
CLI.py
3
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",
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
3
Main.py
3
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()
|
||||
|
||||
18
Rom.py
18
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
|
||||
|
||||
26
Rules.py
26
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:
|
||||
|
||||
Binary file not shown.
@@ -571,6 +571,13 @@
|
||||
"always_in_logic"
|
||||
]
|
||||
},
|
||||
"damage_challenge": {
|
||||
"choices": [
|
||||
"normal",
|
||||
"ohko",
|
||||
"gloom"
|
||||
]
|
||||
},
|
||||
"crystal_book": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
|
||||
Reference in New Issue
Block a user