diff --git a/Doors.py b/Doors.py index 32ffd9ae..6627a345 100644 --- a/Doors.py +++ b/Doors.py @@ -775,7 +775,7 @@ def create_doors(world, player): create_door(player, 'Ice Freezors Hole', Hole), create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot create_door(player, 'Ice Freezors Ledge Hole', Hole), - create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(2), + create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint WS', Intr).dir(We, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint EN', Nrml).dir(Ea, 0x7e, Top, High).pos(2), create_door(player, 'Ice Tall Hint SE', Nrml).dir(So, 0x7e, Right, High).small_key().pos(0).portal(X, 0x02), diff --git a/ItemList.py b/ItemList.py index dd15a1ad..e7a21160 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1123,9 +1123,26 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt pool.extend(['Small Key (Universal)']) else: pool.extend(['Small Key (Universal)']) + modify_pool_for_start_inventory(pool, world, player) return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) +def modify_pool_for_start_inventory(pool, world, player): + for item in world.precollected_items: + if item.player == player: + pool.remove(item.name) + if item.dungeon: + d = world.get_dungeon(item.dungeon, item.player) + match = next((i for i in d.all_items if i.name == item.name), None) + if match: + if match.map or match.compass: + d.dungeon_items.remove(match) + elif match.smallkey: + d.small_keys.remove(match) + elif match.bigkey: + d.big_key.remove(match) + + def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, customitemarray): pool = [] placed_items = {} diff --git a/Main.py b/Main.py index 73502cf4..f584b791 100644 --- a/Main.py +++ b/Main.py @@ -35,7 +35,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.2-u' +__version__ = '1.2.0.3-u' from source.classes.BabelFish import BabelFish @@ -160,7 +160,7 @@ def main(args, seed=None, fish=None): world.player_names[player].append(name) logger.info('') world.settings = CustomSettings() - world.settings.create_from_world(world) + world.settings.create_from_world(world, args.race) outfilebase = f'OR_{args.outputname if args.outputname else world.seed}' @@ -202,16 +202,6 @@ def main(args, seed=None, fish=None): item = ItemFactory(inv_item.strip(), p) if item: world.push_precollected(item) - if item.dungeon: - d = world.get_dungeon(item.dungeon, item.player) - match = next((i for i in d.all_items if i.name == item.name), None) - if match: - if match.map or match.compass: - d.dungeon_items.remove(match) - elif match.smallkey: - d.small_keys.remove(match) - elif match.bigkey: - d.big_key.remove(match) if args.print_custom_yaml: world.settings.record_info(world) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 794af2d6..21f4a884 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,6 +109,14 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.2.0.3-u + * Starting inventory taken into account with default item pool. (Custom pools must do this themselves) + * Fast ROM update + * Fix for restricted boss item counting maps & compasses as vital + * Bug fix for vanilla ER + inverted + experimental +* 1.2.0.2-u + * Fixed a bug with certain trap doors missing + * Added a hint reference for district hints * 1.2.0.1-u * Added new ganonhunt and completionist goals * Fixed the issue when defeating Agahnim and standing in the doorway can cause door state to linger. @@ -116,9 +124,6 @@ These are now independent of retro mode and have three options: None, Random, an * Fix for vanilla Doors + Standard + ER * Added a limit per dungeon on small key doors to ensure reasonable generation * Fixed many small bugs -* 1.2.0.2-u - * Fixed a bug with certain trap doors missing - * Added a hint reference for district hints # Known Issues diff --git a/Rom.py b/Rom.py index fdb2f0c1..cf54c71d 100644 --- a/Rom.py +++ b/Rom.py @@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '1cdb34399467efa346b713db54d6cb02' +RANDOMIZERBASEHASH = '45aa34e724750862234f9a4b09caa3d6' class JsonRom(object): @@ -2343,7 +2343,7 @@ def write_strings(rom, world, player, team): for loc_name in district.locations: location_item = world.get_location(loc_name, player).item if location_item.advancement: - if 'Heart Container' in location_item.name: + if 'Heart Container' in location_item.name or location_item.compass or location_item.map: continue itm_type = 'useful' if useful_item_for_hint(location_item, world) else 'vital' hint_type = 'path' diff --git a/data/base2current.bps b/data/base2current.bps index ee0b630f..7daea3d4 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/docs/presets/async_doors_league/S3_BombBag.yaml b/docs/presets/async_doors_league/S3_BombBag.yaml new file mode 100644 index 00000000..e1f831f6 --- /dev/null +++ b/docs/presets/async_doors_league/S3_BombBag.yaml @@ -0,0 +1,23 @@ +meta: + players: 1 + race: true +settings: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + bombbag: true + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/docs/presets/async_doors_league/S3_Main.yaml b/docs/presets/async_doors_league/S3_Main.yaml new file mode 100644 index 00000000..e8d8f282 --- /dev/null +++ b/docs/presets/async_doors_league/S3_Main.yaml @@ -0,0 +1,22 @@ +meta: + players: 1 + race: true +settings: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/docs/presets/async_doors_league/S3_PotteryLottery.yaml b/docs/presets/async_doors_league/S3_PotteryLottery.yaml new file mode 100644 index 00000000..d65e2387 --- /dev/null +++ b/docs/presets/async_doors_league/S3_PotteryLottery.yaml @@ -0,0 +1,22 @@ +meta: + players: 1 + race: true +settings: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: lottery + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/docs/presets/async_doors_league/S3_Standard.yaml b/docs/presets/async_doors_league/S3_Standard.yaml new file mode 100644 index 00000000..050db332 --- /dev/null +++ b/docs/presets/async_doors_league/S3_Standard.yaml @@ -0,0 +1,25 @@ +meta: + players: 1 + race: true +settings: + 1: + shopsanity: true + pseudoboots: true + mode: standard + swords: assured + goal: crystals + crystals_gt: random + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true \ No newline at end of file diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 939adf8c..c6bc21b6 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -244,6 +244,7 @@ "randomizer.generation.print_custom_yaml": "Print Customizer File", "randomizer.generation.usestartinventory": "Use Starting Inventory", "randomizer.generation.usecustompool": "Use Custom Item Pool", + "randomizer.generation.race": "Generate \"Race\" ROM", "randomizer.generation.saveonexit": "Save Settings on Exit", "randomizer.generation.saveonexit.ask": "Ask Me", diff --git a/resources/app/gui/randomize/generation/checkboxes.json b/resources/app/gui/randomize/generation/checkboxes.json index 9c196402..b1ee4c84 100644 --- a/resources/app/gui/randomize/generation/checkboxes.json +++ b/resources/app/gui/randomize/generation/checkboxes.json @@ -6,6 +6,7 @@ "calcplaythrough": { "type": "checkbox" }, "print_custom_yaml": { "type": "checkbox" }, "usestartinventory": { "type": "checkbox" }, - "usecustompool": { "type": "checkbox" } + "usecustompool": { "type": "checkbox" }, + "race": { "type": "checkbox" } } } diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index f8269b2a..af6e47ff 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -61,6 +61,7 @@ class CustomSettings(object): args.bps = get_setting(meta['bps'], args.bps) args.suppress_rom = get_setting(meta['suppress_rom'], args.suppress_rom) args.names = get_setting(meta['names'], args.names) + args.race = get_setting(meta['race'], args.race) self.player_range = range(1, args.multi + 1) if 'settings' in self.file_source: for p in self.player_range: @@ -156,6 +157,7 @@ class CustomSettings(object): args.ow_palettes[p] = get_setting(settings['ow_palettes'], args.ow_palettes[p]) args.uw_palettes[p] = get_setting(settings['uw_palettes'], args.uw_palettes[p]) args.shuffle_sfx[p] = get_setting(settings['shuffle_sfx'], args.shuffle_sfx[p]) + args.msu_resume[p] = get_setting(settings['msu_resume'], args.msu_resume[p]) def get_item_pool(self): if 'item_pool' in self.file_source: @@ -202,13 +204,14 @@ class CustomSettings(object): return self.file_source['drops'] return None - def create_from_world(self, world): + def create_from_world(self, world, race): self.player_range = range(1, world.players + 1) settings_dict, meta_dict = {}, {} self.world_rep['meta'] = meta_dict meta_dict['players'] = world.players meta_dict['algorithm'] = world.algorithm meta_dict['seed'] = world.seed + meta_dict['race'] = race self.world_rep['settings'] = settings_dict for p in self.player_range: settings_dict[p] = {} diff --git a/source/classes/constants.py b/source/classes/constants.py index 0022e79d..b6a05d77 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -141,6 +141,7 @@ SETTINGSTOPROCESS = { "print_custom_yaml": "print_custom_yaml", "usestartinventory": "usestartinventory", "usecustompool": "custom", + "race": "race", "saveonexit": "saveonexit" } }, diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 1be0c5a4..8fc505e1 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -66,6 +66,8 @@ def link_entrances_new(world, player): default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' del default_map['Bumper Cave (Top)'] + del one_way_map['Big Bomb Shop'] + one_way_map['Inverted Big Bomb Shop'] = 'Inverted Big Bomb Shop' avail_pool.default_map = default_map avail_pool.one_way_map = one_way_map @@ -273,7 +275,7 @@ def do_main_shuffle(entrances, exits, avail, mode_def): # OM Cave entrance in lw/dw if cross_world off if 'Old Man Cave Exit (West)' in rem_exits: world_limiter = DW_Entrances if avail.inverted else LW_Entrances - om_cave_options = [x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)] + om_cave_options = sorted([x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)]) om_cave_choice = random.choice(om_cave_options) if not avail.coupled: connect_exit('Old Man Cave Exit (West)', om_cave_choice, avail)