diff --git a/BaseClasses.py b/BaseClasses.py index 138f8bae..f0f48418 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -71,6 +71,7 @@ class World(object): self.fix_palaceofdarkness_exit = {} self.fix_trock_exit = {} self.shuffle_ganon = shuffle_ganon + self.dark_rooms = {} self.custom = custom self.customitemarray = customitemarray self.can_take_damage = True @@ -169,6 +170,7 @@ class World(object): set_player_attr('pot_contents', None) set_player_attr('pseudoboots', False) set_player_attr('mirrorscroll', False) + set_player_attr('dark_rooms', 'require_lamp') set_player_attr('collection_rate', False) set_player_attr('colorizepots', True) set_player_attr('pot_pool', {}) @@ -3062,6 +3064,7 @@ class Spoiler(object): 'shopsanity': self.world.shopsanity, 'pseudoboots': self.world.pseudoboots, 'mirrorscroll': self.world.mirrorscroll, + 'dark_rooms': self.world.dark_rooms, 'triforcegoal': self.world.treasure_hunt_count, 'triforcepool': self.world.treasure_hunt_total, 'race': self.world.settings.world_rep['meta']['race'], @@ -3311,6 +3314,7 @@ class Spoiler(object): outfile.write('\n') 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('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 8fc7263e..07e499e0 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', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', + 'pseudoboots', 'mirrorscroll', "dark_rooms", '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', @@ -210,6 +210,7 @@ def parse_settings(): "take_any": "none", "pseudoboots": False, "mirrorscroll": False, + "dark_rooms": "require_lamp", "shuffleenemies": "none", "shufflebosses": "none", diff --git a/ItemList.py b/ItemList.py index 08be1d62..ec2be0e7 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1081,7 +1081,10 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt else: pool.extend(basicgloves) - lamps_needed_for_dark_rooms = 1 + if world.dark_rooms[player] in ['lamp_required']: + lamps_needed_for_dark_rooms = 1 + else: + lamps_needed_for_dark_rooms = 0 # old insanity shuffle didn't have fake LW/DW logic so this used to be conditional pool.extend(['Magic Mirror', 'Moon Pearl']) @@ -1260,7 +1263,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, customitemarray): +def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, dark_rooms, customitemarray): pool = [] placed_items = {} precollected_items = [] @@ -1299,7 +1302,10 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer diff = difficulties[difficulty] - lamps_needed_for_dark_rooms = 1 + if world.dark_rooms[player] in ['lamp_required']: + lamps_needed_for_dark_rooms = 1 + else: + lamps_needed_for_dark_rooms = 0 # expert+ difficulties produce the same contents for # all bottles, since only one bottle is available @@ -1505,7 +1511,12 @@ def make_customizer_pool(world, player): pool.remove('Fighter Sword') pool.append('Rupees (50)') - return pool, placed_items, precollected_items, clock_mode, 1 + if world.dark_rooms[player] in ['lamp_required']: + lamps_needed_for_dark_rooms = 1 + else: + lamps_needed_for_dark_rooms = 0 + + return pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms filler_items = { diff --git a/Main.py b/Main.py index 1928a654..f908e702 100644 --- a/Main.py +++ b/Main.py @@ -508,6 +508,7 @@ def init_world(args, fish): world.linked_drops = args.linked_drops.copy() world.pseudoboots = args.pseudoboots.copy() world.mirrorscroll = args.mirrorscroll.copy() + world.dark_rooms = args.dark_rooms.copy() world.overworld_map = args.overworld_map.copy() world.take_any = args.take_any.copy() world.restrict_boss_items = args.restrict_boss_items.copy() @@ -603,6 +604,7 @@ def copy_world(world): ret.linked_drops = world.linked_drops.copy() ret.pseudoboots = world.pseudoboots.copy() ret.mirrorscroll = world.mirrorscroll.copy() + ret.dark_rooms = world.dark_rooms.copy() ret.overworld_map = world.overworld_map.copy() ret.take_any = world.take_any.copy() ret.boss_shuffle = world.boss_shuffle.copy() @@ -823,6 +825,7 @@ def copy_world_premature(world, player): ret.linked_drops = world.linked_drops.copy() ret.pseudoboots = world.pseudoboots.copy() ret.mirrorscroll = world.mirrorscroll.copy() + ret.dark_rooms = world.dark_rooms.copy() ret.overworld_map = world.overworld_map.copy() ret.take_any = world.take_any.copy() ret.boss_shuffle = world.boss_shuffle.copy() diff --git a/Rom.py b/Rom.py index 03f8b3af..1542420f 100644 --- a/Rom.py +++ b/Rom.py @@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '80e0a4f8bd5cc6f83ac9f7f46c01bf4f' +RANDOMIZERBASEHASH = '9cdc4e5b97fc03af357b4f35ea8802fd' class JsonRom(object): @@ -956,7 +956,15 @@ def patch_rom(world, rom, player, team, is_mystery=False): rom.write_bytes(0x6D323, [0x00, 0x00, 0xe4, 0xff, 0x08, 0x0E]) # set light cones - rom.write_byte(0x180038, 0x01 if world.sewer_light_cone[player] else 0x00) + if world.dark_rooms[player] == 'no_dark_rooms': + light_cone = 0x20 + elif world.dark_rooms[player] == 'always_light_cone': + light_cone = 0x10 + elif world.sewer_light_cone[player]: + light_cone = 0x01 + else: + light_cone = 0x00 + rom.write_byte(0x180038, light_cone) GREEN_TWENTY_RUPEES = 0x47 TRIFORCE_PIECE = ItemFactory('Triforce Piece', player).code diff --git a/Utils.py b/Utils.py index b0f64517..6f1a38be 100644 --- a/Utils.py +++ b/Utils.py @@ -792,10 +792,10 @@ def hex_representer(dumper, data): if __name__ == '__main__': - # make_new_base2current() + print(make_new_base2current()) # read_entrance_data(old_rom=sys.argv[1]) # room_palette_data(old_rom=sys.argv[1]) # extract_data_from_us_rom(sys.argv[1]) # extract_data_from_jp_rom(sys.argv[1]) # check_pots() - find_and_replace() + # find_and_replace() diff --git a/data/base2current.bps b/data/base2current.bps index db46c22a..0986c290 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 62159299..e58cb67b 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -558,6 +558,14 @@ "action": "store_true", "type": "bool" }, + "dark_rooms": { + "choices": [ + "require_lamp", + "always_light_cone", + "no_dark_rooms", + "always_in_logic" + ] + }, "calc_playthrough": { "action": "store_false", "type": "bool" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 2bf10795..2e39e4e4 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -395,6 +395,12 @@ "collection_rate": [ "Display collection rate (default: %(default)s)" ], "pseudoboots": [ " Start with pseudo boots that allow dashing but no item checks (default: %(default)s)"], "mirrorscroll": [ " Players starts with mirror scroll that allows mirror in dungeons but not overworld (default: %(default)s"], + "dark_rooms": [ "Controls how dark rooms are treated in the game and logic:", + "RequireLamp: Lamp is always required for dark rooms to be in logic", + "AlwaysLightCone: Player gets a light cone even without the lamp, and dark rooms are always in logic", + "NoDarkRooms: Dark rooms are changed to no longer be dark, and are always in logic", + "AlwaysInLogic: Dark rooms are always considered to be in logic, even if the player cannot see" + ], "bombbag": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (default: %(default)s)" ], "any_enemy_logic": [ "How to handle potential traversal between dungeon in Crossed door shuffle",