turn weapons into boolean swordless

This commit is contained in:
Fabian Dill 2021-04-09 20:40:45 +02:00
parent 4461cb67f0
commit c4d6ac50be
8 changed files with 29 additions and 58 deletions

View File

@ -64,7 +64,7 @@ class MultiWorld():
set_player_attr('shuffle', "vanilla") set_player_attr('shuffle', "vanilla")
set_player_attr('logic', "noglitches") set_player_attr('logic', "noglitches")
set_player_attr('mode', 'open') set_player_attr('mode', 'open')
set_player_attr('swords', 'random') set_player_attr('swordless', False)
set_player_attr('difficulty', 'normal') set_player_attr('difficulty', 'normal')
set_player_attr('item_functionality', 'normal') set_player_attr('item_functionality', 'normal')
set_player_attr('timer', False) set_player_attr('timer', False)
@ -726,7 +726,7 @@ class CollectionState(object):
def can_retrieve_tablet(self, player:int) -> bool: def can_retrieve_tablet(self, player:int) -> bool:
return self.has('Book of Mudora', player) and (self.has_beam_sword(player) or return self.has('Book of Mudora', player) and (self.has_beam_sword(player) or
(self.world.swords[player] == "swordless" and (self.world.swordless[player] and
self.has("Hammer", player))) self.has("Hammer", player)))
def has_sword(self, player: int) -> bool: def has_sword(self, player: int) -> bool:
@ -747,7 +747,7 @@ class CollectionState(object):
def can_melt_things(self, player: int) -> bool: def can_melt_things(self, player: int) -> bool:
return self.has('Fire Rod', player) or \ return self.has('Fire Rod', player) or \
(self.has('Bombos', player) and (self.has('Bombos', player) and
(self.world.swords[player] == "swordless" or (self.world.swordless[player] or
self.has_sword(player))) self.has_sword(player)))
def can_avoid_lasers(self, player: int) -> bool: def can_avoid_lasers(self, player: int) -> bool:
@ -1313,7 +1313,7 @@ class Spoiler(object):
'dark_room_logic': self.world.dark_room_logic, 'dark_room_logic': self.world.dark_room_logic,
'mode': self.world.mode, 'mode': self.world.mode,
'retro': self.world.retro, 'retro': self.world.retro,
'weapons': self.world.swords, 'swordless': self.world.swordless,
'goal': self.world.goal, 'goal': self.world.goal,
'shuffle': self.world.shuffle, 'shuffle': self.world.shuffle,
'item_pool': self.world.difficulty, 'item_pool': self.world.difficulty,
@ -1412,7 +1412,7 @@ class Spoiler(object):
outfile.write('Mode: %s\n' % self.metadata['mode'][player]) outfile.write('Mode: %s\n' % self.metadata['mode'][player])
outfile.write('Retro: %s\n' % outfile.write('Retro: %s\n' %
('Yes' if self.metadata['retro'][player] else 'No')) ('Yes' if self.metadata['retro'][player] else 'No'))
outfile.write('Swords: %s\n' % self.metadata['weapons'][player]) outfile.write('Swordless: %s\n' % ('Yes' if self.metadata['swordless'][player] else 'No'))
outfile.write('Goal: %s\n' % self.metadata['goal'][player]) outfile.write('Goal: %s\n' % self.metadata['goal'][player])
if "triforce" in self.metadata["goal"][player]: # triforce hunt if "triforce" in self.metadata["goal"][player]: # triforce hunt
outfile.write("Pieces available for Triforce: %s\n" % outfile.write("Pieces available for Triforce: %s\n" %

View File

@ -69,7 +69,7 @@ def main(args, seed=None):
world.shuffle = args.shuffle.copy() world.shuffle = args.shuffle.copy()
world.logic = args.logic.copy() world.logic = args.logic.copy()
world.mode = args.mode.copy() world.mode = args.mode.copy()
world.swords = args.swords.copy() world.swordless = args.swordless.copy()
world.difficulty = args.difficulty.copy() world.difficulty = args.difficulty.copy()
world.item_functionality = args.item_functionality.copy() world.item_functionality = args.item_functionality.copy()
world.timer = args.timer.copy() world.timer = args.timer.copy()

View File

@ -632,11 +632,7 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options):
ret.hints = get_choice('hints', weights) ret.hints = get_choice('hints', weights)
ret.swords = {'randomized': 'random', ret.swordless = get_choice('swordless', weights, False)
'assured': 'assured',
'vanilla': 'vanilla',
'swordless': 'swordless'
}[get_choice('weapons', weights, 'assured')]
ret.difficulty = get_choice('item_pool', weights) ret.difficulty = get_choice('item_pool', weights)

View File

@ -80,7 +80,7 @@ def KholdstareDefeatRule(state, player: int):
state.has('Fire Rod', player) or state.has('Fire Rod', player) or
( (
state.has('Bombos', player) and state.has('Bombos', player) and
(state.has_sword(player) or state.world.swords[player] == 'swordless') (state.has_sword(player) or state.world.swordless[player])
) )
) and ) and
( (
@ -89,7 +89,7 @@ def KholdstareDefeatRule(state, player: int):
( (
state.has('Fire Rod', player) and state.has('Fire Rod', player) and
state.has('Bombos', player) and state.has('Bombos', player) and
state.world.swords[player] == 'swordless' and state.world.swordless[player] and
state.can_extend_magic(player, 16) state.can_extend_magic(player, 16)
) )
) )
@ -113,7 +113,7 @@ def AgahnimDefeatRule(state, player: int):
def GanonDefeatRule(state, player: int): def GanonDefeatRule(state, player: int):
if state.world.swords[player] == "swordless": if state.world.swordless[player]:
return state.has('Hammer', player) and \ return state.has('Hammer', player) and \
state.has_fire_source(player) and \ state.has_fire_source(player) and \
state.has('Silver Bow', player) and \ state.has('Silver Bow', player) and \

View File

@ -45,11 +45,9 @@ def parse_arguments(argv, no_defaults=False):
Requires the moon pearl to be Link in the Light World Requires the moon pearl to be Link in the Light World
instead of a bunny. instead of a bunny.
''') ''')
parser.add_argument('--swords', default=defval('random'), const='random', nargs='?', choices= ['random', 'assured', 'swordless', 'vanilla'], parser.add_argument('--swordless', action='store_true',
help='''\ help='''\
Select sword placement. (default: %(default)s) Toggles Swordless Mode
Random: All swords placed randomly.
Assured: Start game with a sword already.
Swordless: No swords. Curtains in Skull Woods and Agahnim\'s Swordless: No swords. Curtains in Skull Woods and Agahnim\'s
Tower are removed, Agahnim\'s Tower barrier can be Tower are removed, Agahnim\'s Tower barrier can be
destroyed with hammer. Misery Mire and Turtle Rock destroyed with hammer. Misery Mire and Turtle Rock
@ -57,7 +55,6 @@ def parse_arguments(argv, no_defaults=False):
Ether and Bombos Tablet can be activated with Hammer Ether and Bombos Tablet can be activated with Hammer
(and Book). Bombos pads have been added in Ice (and Book). Bombos pads have been added in Ice
Palace, to allow for an alternative to firerod. Palace, to allow for an alternative to firerod.
Vanilla: Swords are in vanilla locations.
''') ''')
parser.add_argument('--goal', default=defval('ganon'), const='ganon', nargs='?', parser.add_argument('--goal', default=defval('ganon'), const='ganon', nargs='?',
choices=['ganon', 'pedestal', 'bosses', 'triforcehunt', 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals', 'ganonpedestal'], choices=['ganon', 'pedestal', 'bosses', 'triforcehunt', 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals', 'ganonpedestal'],
@ -401,7 +398,7 @@ def parse_arguments(argv, no_defaults=False):
for player in range(1, multiargs.multi + 1): for player in range(1, multiargs.multi + 1):
playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True) playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True)
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', for name in ['logic', 'mode', 'swordless', 'goal', 'difficulty', 'item_functionality',
'shuffle', 'crystals_ganon', 'crystals_gt', 'open_pyramid', 'timer', 'shuffle', 'crystals_ganon', 'crystals_gt', 'open_pyramid', 'timer',
'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time', 'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time',
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',

View File

@ -279,7 +279,7 @@ def generate_itempool(world, player: int):
itempool.extend(itemdiff.bottles) itempool.extend(itemdiff.bottles)
itempool.extend(itemdiff.basicbow) itempool.extend(itemdiff.basicbow)
itempool.extend(itemdiff.basicarmor) itempool.extend(itemdiff.basicarmor)
if world.swords[player] != 'swordless': if not world.swordless[player]:
itempool.extend(itemdiff.basicsword) itempool.extend(itemdiff.basicsword)
itempool.extend(itemdiff.basicmagic) itempool.extend(itemdiff.basicmagic)
itempool.extend(itemdiff.basicglove) itempool.extend(itemdiff.basicglove)
@ -335,7 +335,7 @@ def generate_itempool(world, player: int):
possible_weapons = [] possible_weapons = []
for item in pool: for item in pool:
if item in ['Progressive Sword', 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword']: if item in ['Progressive Sword', 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword']:
if not found_sword and world.swords[player] != 'swordless': if not found_sword:
found_sword = True found_sword = True
possible_weapons.append(item) possible_weapons.append(item)
if item in ['Progressive Bow', 'Bow'] and not found_bow: if item in ['Progressive Bow', 'Bow'] and not found_bow:
@ -548,7 +548,7 @@ def get_pool_core(world, player: int):
timer = world.timer[player] timer = world.timer[player]
goal = world.goal[player] goal = world.goal[player]
mode = world.mode[player] mode = world.mode[player]
swords = world.swords[player] swordless = world.swordless[player]
retro = world.retro[player] retro = world.retro[player]
logic = world.logic[player] logic = world.logic[player]
@ -619,7 +619,7 @@ def get_pool_core(world, player: int):
if want_progressives(): if want_progressives():
pool.extend(diff.progressivebow) pool.extend(diff.progressivebow)
elif (swords == 'swordless' or logic == 'noglitches') and goal != 'icerodhunt': elif (swordless or logic == 'noglitches') and goal != 'icerodhunt':
swordless_bows = ['Bow', 'Silver Bow'] swordless_bows = ['Bow', 'Silver Bow']
if difficulty == "easy": if difficulty == "easy":
swordless_bows *= 2 swordless_bows *= 2
@ -627,33 +627,11 @@ def get_pool_core(world, player: int):
else: else:
pool.extend(diff.basicbow) pool.extend(diff.basicbow)
if swords == 'swordless': if swordless:
pool.extend(diff.swordless) pool.extend(diff.swordless)
elif swords == 'vanilla':
swords_to_use = diff.progressivesword.copy() if want_progressives() else diff.basicsword.copy()
world.random.shuffle(swords_to_use)
place_item('Link\'s Uncle', swords_to_use.pop())
place_item('Blacksmith', swords_to_use.pop())
place_item('Pyramid Fairy - Left', swords_to_use.pop())
if goal != 'pedestal':
place_item('Master Sword Pedestal', swords_to_use.pop())
else:
swords_to_use.pop()
place_item('Master Sword Pedestal', 'Triforce')
if swords_to_use:
pool.extend(swords_to_use)
else: else:
progressive_swords = want_progressives() progressive_swords = want_progressives()
pool.extend(diff.progressivesword if progressive_swords else diff.basicsword) pool.extend(diff.progressivesword if progressive_swords else diff.basicsword)
if swords == 'assured' and goal != 'icerodhunt':
if progressive_swords:
precollected_items.append('Progressive Sword')
pool.remove('Progressive Sword')
else:
precollected_items.append('Fighter Sword')
pool.remove('Fighter Sword')
pool.extend(['Rupees (50)'])
extraitems = total_items_to_place - len(pool) - len(placed_items) extraitems = total_items_to_place - len(pool) - len(placed_items)
@ -684,7 +662,7 @@ def get_pool_core(world, player: int):
else: else:
break break
if goal == 'pedestal' and swords != 'vanilla': if goal == 'pedestal':
place_item('Master Sword Pedestal', 'Triforce') place_item('Master Sword Pedestal', 'Triforce')
pool.remove("Rupees (20)") pool.remove("Rupees (20)")

View File

@ -961,7 +961,7 @@ def patch_rom(world, rom, player, team, enemized):
# Set overflow items for progressive equipment # Set overflow items for progressive equipment
rom.write_bytes(0x180090, rom.write_bytes(0x180090,
[difficulty.progressive_sword_limit if world.swords[player] != 'swordless' else 0, [difficulty.progressive_sword_limit if not world.swordless[player] else 0,
overflow_replacement, overflow_replacement,
difficulty.progressive_shield_limit, overflow_replacement, difficulty.progressive_shield_limit, overflow_replacement,
difficulty.progressive_armor_limit, overflow_replacement, difficulty.progressive_armor_limit, overflow_replacement,
@ -971,7 +971,7 @@ def patch_rom(world, rom, player, team, enemized):
rom.write_bytes(0x180098, [difficulty.progressive_bow_limit, overflow_replacement]) rom.write_bytes(0x180098, [difficulty.progressive_bow_limit, overflow_replacement])
if difficulty.progressive_bow_limit < 2 and ( if difficulty.progressive_bow_limit < 2 and (
world.swords[player] == 'swordless' or world.logic[player] == 'noglitches'): world.swordless[player] or world.logic[player] == 'noglitches'):
rom.write_bytes(0x180098, [2, overflow_replacement]) rom.write_bytes(0x180098, [2, overflow_replacement])
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
@ -1123,11 +1123,11 @@ def patch_rom(world, rom, player, team, enemized):
rom.write_byte(0x180029, 0x01) # Smithy quick item give rom.write_byte(0x180029, 0x01) # Smithy quick item give
# set swordless mode settings # set swordless mode settings
rom.write_byte(0x18003F, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer can harm ganon rom.write_byte(0x18003F, 0x01 if world.swordless[player] else 0x00) # hammer can harm ganon
rom.write_byte(0x180040, 0x01 if world.swords[player] == 'swordless' else 0x00) # open curtains rom.write_byte(0x180040, 0x01 if world.swordless[player] else 0x00) # open curtains
rom.write_byte(0x180041, 0x01 if world.swords[player] == 'swordless' else 0x00) # swordless medallions rom.write_byte(0x180041, 0x01 if world.swordless[player] else 0x00) # swordless medallions
rom.write_byte(0x180043, 0xFF if world.swords[player] == 'swordless' else 0x00) # starting sword for link rom.write_byte(0x180043, 0xFF if world.swordless[player] else 0x00) # starting sword for link
rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets rom.write_byte(0x180044, 0x01 if world.swordless[player] else 0x00) # hammer activates tablets
if world.item_functionality[player] == 'easy': if world.item_functionality[player] == 'easy':
rom.write_byte(0x18003F, 0x01) # hammer can harm ganon rom.write_byte(0x18003F, 0x01) # hammer can harm ganon
@ -2218,7 +2218,7 @@ def write_strings(rom, world, player, team):
prog_bow_locs = world.find_items('Progressive Bow', player) prog_bow_locs = world.find_items('Progressive Bow', player)
distinguished_prog_bow_loc = next((location for location in prog_bow_locs if location.item.code == 0x65), None) distinguished_prog_bow_loc = next((location for location in prog_bow_locs if location.item.code == 0x65), None)
progressive_silvers = world.difficulty_requirements[player].progressive_bow_limit >= 2 or ( progressive_silvers = world.difficulty_requirements[player].progressive_bow_limit >= 2 or (
world.swords[player] == 'swordless' or world.logic[player] == 'noglitches') world.swordless[player] or world.logic[player] == 'noglitches')
if distinguished_prog_bow_loc: if distinguished_prog_bow_loc:
prog_bow_locs.remove(distinguished_prog_bow_loc) prog_bow_locs.remove(distinguished_prog_bow_loc)
silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s',

View File

@ -505,7 +505,7 @@ def default_rules(world, player):
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
if world.swords[player] == 'swordless': if world.swordless[player]:
swordless_rules(world, player) swordless_rules(world, player)
@ -657,7 +657,7 @@ def inverted_rules(world, player):
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
if world.swords[player] == 'swordless': if world.swordless[player]:
swordless_rules(world, player) swordless_rules(world, player)
def no_glitches_rules(world, player): def no_glitches_rules(world, player):