diff --git a/BaseClasses.py b/BaseClasses.py index f88a48ac..fe0f9c06 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -64,7 +64,7 @@ class MultiWorld(): set_player_attr('shuffle', "vanilla") set_player_attr('logic', "noglitches") set_player_attr('mode', 'open') - set_player_attr('swords', 'random') + set_player_attr('swordless', False) set_player_attr('difficulty', 'normal') set_player_attr('item_functionality', 'normal') set_player_attr('timer', False) @@ -726,7 +726,7 @@ class CollectionState(object): def can_retrieve_tablet(self, player:int) -> bool: 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))) def has_sword(self, player: int) -> bool: @@ -747,7 +747,7 @@ class CollectionState(object): def can_melt_things(self, player: int) -> bool: return self.has('Fire Rod', player) or \ (self.has('Bombos', player) and - (self.world.swords[player] == "swordless" or + (self.world.swordless[player] or self.has_sword(player))) def can_avoid_lasers(self, player: int) -> bool: @@ -1313,7 +1313,7 @@ class Spoiler(object): 'dark_room_logic': self.world.dark_room_logic, 'mode': self.world.mode, 'retro': self.world.retro, - 'weapons': self.world.swords, + 'swordless': self.world.swordless, 'goal': self.world.goal, 'shuffle': self.world.shuffle, 'item_pool': self.world.difficulty, @@ -1412,7 +1412,7 @@ class Spoiler(object): outfile.write('Mode: %s\n' % self.metadata['mode'][player]) outfile.write('Retro: %s\n' % ('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]) if "triforce" in self.metadata["goal"][player]: # triforce hunt outfile.write("Pieces available for Triforce: %s\n" % diff --git a/Main.py b/Main.py index c3a9c2ed..4ab59357 100644 --- a/Main.py +++ b/Main.py @@ -69,7 +69,7 @@ def main(args, seed=None): world.shuffle = args.shuffle.copy() world.logic = args.logic.copy() world.mode = args.mode.copy() - world.swords = args.swords.copy() + world.swordless = args.swordless.copy() world.difficulty = args.difficulty.copy() world.item_functionality = args.item_functionality.copy() world.timer = args.timer.copy() diff --git a/Mystery.py b/Mystery.py index ddd4a1c3..8a0e0b1b 100644 --- a/Mystery.py +++ b/Mystery.py @@ -632,11 +632,7 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): ret.hints = get_choice('hints', weights) - ret.swords = {'randomized': 'random', - 'assured': 'assured', - 'vanilla': 'vanilla', - 'swordless': 'swordless' - }[get_choice('weapons', weights, 'assured')] + ret.swordless = get_choice('swordless', weights, False) ret.difficulty = get_choice('item_pool', weights) diff --git a/worlds/alttp/Bosses.py b/worlds/alttp/Bosses.py index 5c261365..3e462a54 100644 --- a/worlds/alttp/Bosses.py +++ b/worlds/alttp/Bosses.py @@ -80,7 +80,7 @@ def KholdstareDefeatRule(state, player: int): state.has('Fire Rod', player) or ( 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 ( @@ -89,7 +89,7 @@ def KholdstareDefeatRule(state, player: int): ( state.has('Fire Rod', player) and state.has('Bombos', player) and - state.world.swords[player] == 'swordless' and + state.world.swordless[player] and state.can_extend_magic(player, 16) ) ) @@ -113,7 +113,7 @@ def AgahnimDefeatRule(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 \ state.has_fire_source(player) and \ state.has('Silver Bow', player) and \ diff --git a/worlds/alttp/EntranceRandomizer.py b/worlds/alttp/EntranceRandomizer.py index 305f06de..1801a8c0 100644 --- a/worlds/alttp/EntranceRandomizer.py +++ b/worlds/alttp/EntranceRandomizer.py @@ -45,11 +45,9 @@ def parse_arguments(argv, no_defaults=False): Requires the moon pearl to be Link in the Light World 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='''\ - Select sword placement. (default: %(default)s) - Random: All swords placed randomly. - Assured: Start game with a sword already. + Toggles Swordless Mode Swordless: No swords. Curtains in Skull Woods and Agahnim\'s Tower are removed, Agahnim\'s Tower barrier can be 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 (and Book). Bombos pads have been added in Ice Palace, to allow for an alternative to firerod. - Vanilla: Swords are in vanilla locations. ''') parser.add_argument('--goal', default=defval('ganon'), const='ganon', nargs='?', 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): 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', 'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index 3776bcd4..0b83bb91 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -279,7 +279,7 @@ def generate_itempool(world, player: int): itempool.extend(itemdiff.bottles) itempool.extend(itemdiff.basicbow) itempool.extend(itemdiff.basicarmor) - if world.swords[player] != 'swordless': + if not world.swordless[player]: itempool.extend(itemdiff.basicsword) itempool.extend(itemdiff.basicmagic) itempool.extend(itemdiff.basicglove) @@ -335,7 +335,7 @@ def generate_itempool(world, player: int): possible_weapons = [] for item in pool: 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 possible_weapons.append(item) 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] goal = world.goal[player] mode = world.mode[player] - swords = world.swords[player] + swordless = world.swordless[player] retro = world.retro[player] logic = world.logic[player] @@ -619,7 +619,7 @@ def get_pool_core(world, player: int): if want_progressives(): 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'] if difficulty == "easy": swordless_bows *= 2 @@ -627,33 +627,11 @@ def get_pool_core(world, player: int): else: pool.extend(diff.basicbow) - if swords == 'swordless': + if 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: progressive_swords = want_progressives() 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) @@ -684,7 +662,7 @@ def get_pool_core(world, player: int): else: break - if goal == 'pedestal' and swords != 'vanilla': + if goal == 'pedestal': place_item('Master Sword Pedestal', 'Triforce') pool.remove("Rupees (20)") diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index 8ffa3d18..0e94e132 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -961,7 +961,7 @@ def patch_rom(world, rom, player, team, enemized): # Set overflow items for progressive equipment 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, difficulty.progressive_shield_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]) 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_byte(0x180181, 0x01) # Make silver arrows work only on ganon 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 # set swordless mode settings - rom.write_byte(0x18003F, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer can harm ganon - rom.write_byte(0x180040, 0x01 if world.swords[player] == 'swordless' else 0x00) # open curtains - rom.write_byte(0x180041, 0x01 if world.swords[player] == 'swordless' else 0x00) # swordless medallions - rom.write_byte(0x180043, 0xFF if world.swords[player] == 'swordless' else 0x00) # starting sword for link - rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets + rom.write_byte(0x18003F, 0x01 if world.swordless[player] else 0x00) # hammer can harm ganon + rom.write_byte(0x180040, 0x01 if world.swordless[player] else 0x00) # open curtains + rom.write_byte(0x180041, 0x01 if world.swordless[player] else 0x00) # swordless medallions + rom.write_byte(0x180043, 0xFF if world.swordless[player] else 0x00) # starting sword for link + rom.write_byte(0x180044, 0x01 if world.swordless[player] else 0x00) # hammer activates tablets if world.item_functionality[player] == 'easy': 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) 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 ( - world.swords[player] == 'swordless' or world.logic[player] == 'noglitches') + world.swordless[player] or world.logic[player] == 'noglitches') if distinguished_prog_bow_loc: prog_bow_locs.remove(distinguished_prog_bow_loc) silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 5bc61dc6..897083de 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -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]) - if world.swords[player] == 'swordless': + if world.swordless[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]) - if world.swords[player] == 'swordless': + if world.swordless[player]: swordless_rules(world, player) def no_glitches_rules(world, player):