Add support for swordless mode.
This commit is contained in:
parent
acd54cbbff
commit
7bef9f6aaa
|
@ -195,14 +195,14 @@ class World(object):
|
|||
@property
|
||||
def option_identifier(self):
|
||||
logic = 0 if self.logic == 'noglitches' else 1
|
||||
mode = 0 if self.mode == 'open' else 1
|
||||
mode = ['standard', 'open', 'swordless'].index(self.mode)
|
||||
dungeonitems = 0 if self.place_dungeon_items else 1
|
||||
goal = ['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'].index(self.goal)
|
||||
shuffle = ['vanilla', 'simple', 'restricted', 'full', 'madness', 'insanity', 'dungeonsfull', 'dungeonssimple'].index(self.shuffle)
|
||||
difficulty = ['normal', 'timed', 'timed-ohko', 'timed-countdown'].index(self.difficulty)
|
||||
algorithm = ['freshness', 'flood', 'vt21', 'vt22', 'restrictive'].index(self.algorithm)
|
||||
beatableonly = 1 if self.check_beatable_only else 0
|
||||
return logic | (mode << 1) | (dungeonitems << 2) | (goal << 3) | (shuffle << 6) | (difficulty << 10) | (algorithm << 12) | (beatableonly << 15)
|
||||
return logic | (beatableonly << 1) | (dungeonitems << 2) | (goal << 3) | (shuffle << 6) | (difficulty << 10) | (algorithm << 12) | (mode << 15)
|
||||
|
||||
|
||||
class CollectionState(object):
|
||||
|
|
23
Main.py
23
Main.py
|
@ -400,7 +400,7 @@ def flood_items(world):
|
|||
|
||||
|
||||
def generate_itempool(world):
|
||||
if world.difficulty not in ['normal', 'timed', 'timed-ohko', 'timed-countdown'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'] or world.mode not in ['open', 'standard']:
|
||||
if world.difficulty not in ['normal', 'timed', 'timed-ohko', 'timed-countdown'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'] or world.mode not in ['open', 'standard', 'swordless']:
|
||||
raise NotImplementedError('Not supported yet')
|
||||
|
||||
world.push_item('Ganon', ItemFactory('Triforce'), False)
|
||||
|
@ -412,7 +412,7 @@ def generate_itempool(world):
|
|||
# set up item pool
|
||||
if world.difficulty in ['timed', 'timed-countdown']:
|
||||
world.itempool = ItemFactory(['Arrow Upgrade (+5)'] * 2 + ['Bomb Upgrade (+5)'] * 2 + ['Arrow Upgrade (+10)'] * 3 + ['Bomb Upgrade (+10)'] * 3 +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Sword'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Bottle'] * 4 +
|
||||
['Bombos', 'Book of Mudora', 'Blue Boomerang', 'Bow', 'Bug Catching Net', 'Cane of Byrna', 'Cane of Somaria',
|
||||
'Ether', 'Fire Rod', 'Flippers', 'Ocarina', 'Hammer', 'Hookshot', 'Ice Rod', 'Lamp', 'Cape', 'Magic Powder',
|
||||
|
@ -423,7 +423,7 @@ def generate_itempool(world):
|
|||
world.clock_mode = 'stopwatch' if world.difficulty == 'timed' else 'countdown'
|
||||
elif world.difficulty == 'timed-ohko':
|
||||
world.itempool = ItemFactory(['Arrow Upgrade (+5)'] * 6 + ['Bomb Upgrade (+5)'] * 6 + ['Arrow Upgrade (+10)', 'Bomb Upgrade (+10)'] +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Sword'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Bottle'] * 4 +
|
||||
['Bombos', 'Book of Mudora', 'Blue Boomerang', 'Bow', 'Bug Catching Net', 'Cane of Byrna', 'Cane of Somaria',
|
||||
'Ether', 'Fire Rod', 'Flippers', 'Ocarina', 'Hammer', 'Hookshot', 'Ice Rod', 'Lamp', 'Cape', 'Magic Powder',
|
||||
|
@ -434,7 +434,7 @@ def generate_itempool(world):
|
|||
world.clock_mode = 'ohko'
|
||||
else:
|
||||
world.itempool = ItemFactory(['Arrow Upgrade (+5)'] * 6 + ['Bomb Upgrade (+5)'] * 6 + ['Arrow Upgrade (+10)', 'Bomb Upgrade (+10)'] +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Sword'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Progressive Armor'] * 2 + ['Progressive Shield'] * 3 + ['Progressive Glove'] * 2 +
|
||||
['Bottle'] * 4 +
|
||||
['Bombos', 'Book of Mudora', 'Blue Boomerang', 'Bow', 'Bug Catching Net', 'Cane of Byrna', 'Cane of Somaria',
|
||||
'Ether', 'Fire Rod', 'Flippers', 'Ocarina', 'Hammer', 'Hookshot', 'Ice Rod', 'Lamp', 'Cape', 'Magic Powder',
|
||||
|
@ -443,11 +443,16 @@ def generate_itempool(world):
|
|||
['Rupees (50)'] * 7 + ['Rupees (5)'] * 4 + ['Rupee (1)'] * 2 + ['Rupees (300)'] * 4 + ['Rupees (20)'] * 28 +
|
||||
['Arrows (10)'] * 4 + ['Bombs (3)'] * 10)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode == 'swordless':
|
||||
world.push_item('Ether Tablet', ItemFactory('Rupees (20)'), False)
|
||||
world.push_item('Bombos Tablet', ItemFactory('Rupees (20)'), False)
|
||||
world.itempool.extend(ItemFactory(['Rupees (20)', 'Rupees (20)']))
|
||||
elif world.mode == 'standard':
|
||||
world.push_item('Uncle', ItemFactory('Progressive Sword'), False)
|
||||
world.get_location('Uncle').event = True
|
||||
world.itempool.extend(ItemFactory(['Progressive Sword'] * 3))
|
||||
else:
|
||||
world.itempool.append(ItemFactory('Progressive Sword'))
|
||||
world.itempool.extend(ItemFactory(['Progressive Sword'] * 4))
|
||||
|
||||
# provide mirror and pearl so you can avoid fake DW/LW and do dark world exploration as intended by algorithm, for now
|
||||
if world.shuffle == 'insanity':
|
||||
|
@ -614,8 +619,10 @@ if __name__ == '__main__':
|
|||
parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true')
|
||||
parser.add_argument('--logic', default='noglitches', const='noglitches', nargs='?', choices=['noglitches', 'minorglitches'],
|
||||
help='Select Enforcement of Item Requirements. Minor Glitches may require Fake Flippers, Bunny Revival and Dark Room Navigation.')
|
||||
parser.add_argument('--mode', default='open', const='open', nargs='?', choices=['standard', 'open'],
|
||||
help='Select game mode. Standard fixes Hyrule Castle Secret Entrance and Front Door, but may lead to weird rain state issues if you exit through the Hyrule Castle side exits before rescuing Zelda in a full shuffle.')
|
||||
parser.add_argument('--mode', default='open', const='open', nargs='?', choices=['standard', 'open', 'swordless'],
|
||||
help='Select game mode. Standard fixes Hyrule Castle Secret Entrance and Front Door, but may lead to weird rain state issues if you exit through the Hyrule Castle side exits before rescuing Zelda in a full shuffle.\n'
|
||||
'Swordless mode is like open, but with no swords. Curtains in Skull Woods and Agahnims Tower are removed, Agahnims Tower barrier can be destroyed with hammer. Misery Mire and Turtle Rock can be opened without a sword.\n'
|
||||
'Hammer damages Ganon. Ether and Bombos Tablet are unreachable but contain trash items always.')
|
||||
parser.add_argument('--goal', default='ganon', const='ganon', nargs='?', choices=['ganon', 'pedestal', 'dungeons', 'starhunt', 'triforcehunt'],
|
||||
help='Select completion goal. Pedestal places the Triforce at the Master Sword Pedestal. All dungeons is not enforced ingame but considered in the playthrough. \n'
|
||||
'Star Hunt places 15 Power Stars pieces in the world, collect 10 of them to beat the game.\n'
|
||||
|
|
2
Rom.py
2
Rom.py
|
@ -74,7 +74,7 @@ def patch_rom(world, rom, hashtable, quickswap=False, beep='normal', sprite=None
|
|||
write_byte(rom, 0x51DE, 0x00)
|
||||
|
||||
# set open mode:
|
||||
if world.mode == 'open':
|
||||
if world.mode in ['open', 'swordless']:
|
||||
write_byte(rom, 0x180032, 0x01) # open mode
|
||||
|
||||
# disable sword sprite from uncle
|
||||
|
|
21
Rules.py
21
Rules.py
|
@ -15,12 +15,14 @@ def set_rules(world):
|
|||
open_rules(world)
|
||||
elif world.mode == 'standard':
|
||||
standard_rules(world)
|
||||
elif world.mode == 'swordless':
|
||||
swordless_rules(world)
|
||||
else:
|
||||
raise NotImplementedError('Not implemented yet')
|
||||
|
||||
if world.goal == 'dungeons':
|
||||
# require altar for ganon to enforce getting everything
|
||||
add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Altar', 'Location'))
|
||||
add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Altar', 'Location') and state.has('Beat Agahnim 1'))
|
||||
|
||||
set_big_bomb_rules(world)
|
||||
|
||||
|
@ -97,10 +99,10 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Checkerboard Cave'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_location('Altar'), lambda state: state.has('Red Pendant') and state.has('Blue Pendant') and state.has('Green Pendant'))
|
||||
set_rule(world.get_location('Sahasrahla'), lambda state: state.has('Green Pendant'))
|
||||
set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has_beam_sword() or state.can_reach('Agahnim 1')) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||
set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has_beam_sword() or state.has('Beat Agahnim 1')) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||
set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has_sword())
|
||||
set_rule(world.get_entrance('Top of Pyramid'), lambda state: state.has('Beat Agahnim 1'))
|
||||
set_rule(world.get_entrance('Old Man Cave Exit (West)'), lambda state: False) # drop cannott be climbed up
|
||||
set_rule(world.get_entrance('Old Man Cave Exit (West)'), lambda state: False) # drop cannot be climbed up
|
||||
set_rule(world.get_entrance('Broken Bridge (West)'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Broken Bridge (East)'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('East Death Mountain Teleporter'), lambda state: state.can_lift_heavy_rocks())
|
||||
|
@ -366,6 +368,19 @@ def open_rules(world):
|
|||
pass
|
||||
|
||||
|
||||
def swordless_rules(world):
|
||||
set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has('Hammer') or state.has('Beat Agahnim 1')) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||
set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has('Hammer') or state.has('Bug Catching Net'))
|
||||
set_rule(world.get_location('Ether Tablet'), lambda state: True) # will have fixed rupee drop, unobtainable
|
||||
set_rule(world.get_location('Bombos Tablet'), lambda state: True) # will have fixed rupee drop, unobtainable
|
||||
set_rule(world.get_entrance('Misery Mire'), lambda state: state.has_Pearl() and state.has_misery_mire_medallion()) # sword not required to use medallion for opening in swordless (!)
|
||||
set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_turtle_rock_medallion() and state.can_reach('Turtle Rock (Top)', 'Region')) # sword not required to use medallion for opening in swordless (!)
|
||||
set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.has('Small Key (Skull Woods)', 3) and state.has('Fire Rod')) # no curtain
|
||||
set_rule(world.get_location('Agahnim 2'), lambda state: state.has('Hammer') or state.has('Bug Catching Net'))
|
||||
set_rule(world.get_location('Ganon'), lambda state: state.has('Hammer') and state.has_fire_source() and state.has('Silver Arrows') and state.has('Bow'))
|
||||
set_rule(world.get_entrance('Ganon Drop'), lambda state: state.has('Hammer')) # need to damage ganon to get tiles to drop
|
||||
|
||||
|
||||
def standard_rules(world):
|
||||
# easiest way to enforce key placement not relevant for open
|
||||
forbid_item(world.get_location('[dungeon-C-B1] Escape - Final Basement Room [left chest]'), 'Small Key (Escape)')
|
||||
|
|
Loading…
Reference in New Issue