diff --git a/BaseClasses.py b/BaseClasses.py index 8bfdc544..8869ed53 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -154,7 +154,7 @@ class World(object): set_player_attr('enemy_health', 'default') set_player_attr('enemy_damage', 'default') set_player_attr('any_enemy_logic', 'allow_all') - set_player_attr('beemizer', 0) + set_player_attr('beemizer', '0') set_player_attr('escape_assist', []) set_player_attr('crystals_needed_for_ganon', 7) set_player_attr('crystals_needed_for_gt', 7) @@ -2826,7 +2826,7 @@ class Item(object): def __eq__(self, other): if type(other) is str: return self.name == other - return self.name == other.name and self.player == other.player + return other is not None and self.name == other.name and self.player == other.player # have 6 address that need to be filled diff --git a/CLI.py b/CLI.py index 70fae6e2..958a8da4 100644 --- a/CLI.py +++ b/CLI.py @@ -137,7 +137,7 @@ def parse_cli(argv, no_defaults=False): 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'prizeshuffle', 'startinventory', 'usestartinventory', 'bombbag', 'shuffleganon', 'overworld_map', 'restrict_boss_items', - 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', 'triforce_max_difference', + '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', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', @@ -285,7 +285,7 @@ def parse_settings(): "seed": "", "count": 1, "startinventory": "", - "beemizer": 0, + 'beemizer': '0', "remote_items": False, "race": False, "customitemarray": { diff --git a/DoorShuffle.py b/DoorShuffle.py index 02ce9226..05dfcb55 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -2322,7 +2322,7 @@ def validate_trap_layout(proposal, builder, start_regions, paths, world, player) if bk_special_loc: if not state.found_forced_bk(): return False - if world.accessibility[player] != 'beatable': + if world.accessibility[player] != 'none': all_locations = [l for r in builder.master_sector.region_set() for l in world.get_region(r, player).locations] if any(l not in state.found_locations for l in all_locations): return False diff --git a/ItemList.py b/ItemList.py index 35ff2d0a..6f3b7d73 100644 --- a/ItemList.py +++ b/ItemList.py @@ -462,7 +462,7 @@ def generate_itempool(world, player): '3': {'trap': 50, 'bee': 50}, '4': {'trap': 100}} def beemizer(item): - if world.beemizer[item.player] and not item.advancement and not item.priority and not item.type: + if world.beemizer[item.player] != '0' and not item.advancement and not item.priority and not item.type: choice = random.choices(list(beeweights[world.beemizer[item.player]].keys()), weights=list(beeweights[world.beemizer[item.player]].values()))[0] return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee", player) return item @@ -1439,7 +1439,7 @@ def make_customizer_pool(world, player): or (d_item.map and not world.mapshuffle[player])): d_name = d_item.dungeon dungeon = world.get_dungeon(d_name, player) - current_amount = 1 if d_item == dungeon.big_key or d_item in dungeon.dungeon_items else 0 + current_amount = 1 if dungeon.big_key and (d_item == dungeon.big_key or d_item in dungeon.dungeon_items) else 0 additional_amount = amount - current_amount possible_fit = min(additional_amount, len(dungeon_locations[d_name])-dungeon_count[d_name]) if possible_fit > 0: @@ -1450,7 +1450,7 @@ def make_customizer_pool(world, player): pool.extend([item_name] * amount) else: dungeon = world.get_dungeon(d_item.dungeon, player) - current_amount = 1 if d_item == dungeon.big_key or d_item in dungeon.dungeon_items else 0 + current_amount = 1 if dungeon.big_key and (d_item == dungeon.big_key or d_item in dungeon.dungeon_items) else 0 additional_amount = amount - current_amount dungeon.dungeon_items.extend([d_item] * additional_amount) else: diff --git a/Main.py b/Main.py index b5250228..122ca5ba 100644 --- a/Main.py +++ b/Main.py @@ -28,7 +28,7 @@ from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dunge from Fill import dungeon_tracking from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations, set_prize_drops from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items, create_farm_locations -from UnderworldGlitchRules import create_hybridmajor_connections, get_hybridmajor_connection_entrances +from UnderworldGlitchRules import connect_hmg_entrances_regions, create_hmg_entrances_regions from Utils import output_path, parse_player_names from source.item.District import init_districts @@ -40,7 +40,7 @@ from source.enemizer.DamageTables import DamageTable from source.enemizer.Enemizer import randomize_enemies from source.rom.DataTables import init_data_tables -version_number = '1.4.6' +version_number = '1.4.7.2' version_branch = '-u' __version__ = f'{version_number}{version_branch}' @@ -224,7 +224,8 @@ def main(args, seed=None, fish=None): for player in range(1, world.players + 1): if world.logic[player] in ('nologic', 'hybridglitches'): - create_hybridmajor_connections(world, player) + create_hmg_entrances_regions(world, player) + connect_hmg_entrances_regions(world, player) generate_itempool(world, player) verify_item_pool_config(world) @@ -479,7 +480,7 @@ def init_world(args, fish): world.enemy_health = args.enemy_health.copy() world.enemy_damage = args.enemy_damage.copy() world.any_enemy_logic = args.any_enemy_logic.copy() - world.beemizer = args.beemizer.copy() + world.beemizer = {player: str(args.beemizer[player]) for player in range(1, world.players + 1)} world.intensity = {player: 'random' if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} world.door_type_mode = args.door_type_mode.copy() world.trap_door_mode = args.trap_door_mode.copy() @@ -643,6 +644,10 @@ def copy_world(world): connection = Entrance(player, 'Uncle S&Q', parent) parent.exits.append(connection) connection.connect(target) + # This makes the regions for HMG only + # we'll connect them later after all other connections are made (OW <=> UW, Portals) + if world.logic[player] in ('nologic', 'hybridglitches'): + create_hmg_entrances_regions(ret, player) # copy bosses for dungeon in world.dungeons: @@ -659,7 +664,6 @@ def copy_world(world): # We have to skip these for now. They require both the rest of the entrances _and_ the dungeon portals to be copied first # We will connect them later - hmg_entrances = get_hybridmajor_connection_entrances() for region in world.regions: copied_region = ret.get_region(region.name, region.player) @@ -670,8 +674,6 @@ def copy_world(world): for location in copied_region.locations: location.parent_region = copied_region for entrance in region.entrances: - if entrance.name in hmg_entrances: - continue ret.get_entrance(entrance.name, entrance.player).connect(copied_region) for exit in region.exits: if exit.connected_region: @@ -739,16 +741,16 @@ def copy_world(world): categorize_world_regions(ret, player) create_farm_locations(ret, player) if world.logic[player] in ('nologic', 'hybridglitches'): - create_hybridmajor_connections(ret, player) - - for region in world.regions: + connect_hmg_entrances_regions(ret, player) + + for region in world.regions: copied_region = ret.get_region(region.name, region.player) for entrance in region.entrances: - if entrance.name not in hmg_entrances: - continue - ret.get_entrance(entrance.name, entrance.player).connect(copied_region) + ent = ret.get_entrance(entrance.name, entrance.player) + if (ent.connected_region != copied_region): + ent.connect(copied_region) - for player in range(1, world.players + 1): + for player in range(1, world.players + 1): set_rules(ret, player) return ret @@ -899,9 +901,6 @@ def copy_world_premature(world, player): for portal in world.dungeon_portals[player]: connect_portal(portal, ret, player) - if world.logic[player] in ('nologic', 'hybridglitches'): - create_hybridmajor_connections(ret, player) - set_rules(ret, player) return ret diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 09760368..de9fe6f6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -141,12 +141,20 @@ These are now independent of retro mode and have three options: None, Random, an # Patch Notes -1.4.6 - -- Restores original Sanc & Quit behavior, if Aga1 is not dead, then no quick pyramid warp -- Fixed problem with Lite/Lean shuffling some fairy caves unnecessarily -- The 300 Rupees item is now marked as priority, so it will not be used as GT junk fill (this matches a change in the VT randomizer) -- Murahdahla is now logically accessible in inverted mode as a bunny. May affect some beatable-only TFH seeds by allowing Moon Pearl to be inaccessible. -- Fixed an issue around PreferredLocationGroups in customizer which would not work with pre-activated Ocraina or priority items. -- Minor fix on triforce text -- Enemy bans for poor placements +* 1.4.7.2 + - Fixed an issue with shuffle_ganon/fix_gtower_exit causing a generation failure + - More HMG fixes by Muffins +* 1.4.7.1 + - Fixed an issue with the repaired "beemizer" setting not being backwards compatible +* 1.4.7 + - Fixed generation error with Big Key in starting inventory (thanks Cody!) + - HMG/NL logic fixes by Muffins + - Enemizer: Disabled Walking Zora in the UW due to crash with Swamola (they ignore a lot of collison anyway) + - Enemizer: Fixed an issue with enemizer bush sprites + - Enemizer: Banned new Mimics from being the randomized bush sprite due to crash + - "Beatable" or "accessibility: none" can now use randomized trap doors to seal off entire parts of dungeons (was intended, bug prevented the logic skip) + - Logic error with enemizer and standard should use new enemy logic rules + - Fixed a bug with the inconsistent treatment of the beemizer setting + - Fixed an issue with returning Blacksmith in Simple shuffle (when blacksmith is at Link's House) + - Fixed an issue with dark sanctuary spawn at tavern north door (thanks Codemann!) + - Various enemy bans for the last few months diff --git a/Rom.py b/Rom.py index a19590e8..ff3a316d 100644 --- a/Rom.py +++ b/Rom.py @@ -1528,7 +1528,7 @@ def patch_rom(world, rom, player, team, is_mystery=False): # rom.write_byte(snes_to_pc(0x0DB730), 0x08) # allows chickens to travel across water # allow smith into multi-entrance caves in appropriate shuffles - if world.shuffle[player] in ['restricted', 'full', 'lite', 'lean', 'district', 'swapped', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'): + if world.shuffle[player] in ['restricted', 'simple', 'full', 'lite', 'lean', 'district', 'swapped', 'crossed', 'insanity']: rom.write_byte(0x18004C, 0x01) # set correct flag for hera basement item diff --git a/Rules.py b/Rules.py index 896b3c12..b75a80c3 100644 --- a/Rules.py +++ b/Rules.py @@ -1614,16 +1614,28 @@ def standard_rules(world, player): add_rule(world.get_location('Secret Passage', player), lambda state: standard_escape_rule(state)) escape_builder = world.dungeon_layouts[player]['Hyrule Castle'] + room_map = world.data_tables[player].uw_enemy_table.room_map + stats = world.data_tables[player].enemy_stats for region in escape_builder.master_sector.regions: - for loc in region.locations: - add_rule(loc, lambda state: standard_escape_rule(state)) if region.name in std_kill_rooms: - for ent in std_kill_rooms[region.name][0]: - add_rule(world.get_entrance(ent, player), lambda state: standard_escape_rule(state)) - for ent in std_kill_rooms[region.name][1]: + entrances, trap_ables, room_id, enemy_list = std_kill_rooms[region.name] + rule = get_challenge_rule(world, player, room_map, stats, room_id, enemy_list, region) + for ent in entrances: entrance = world.get_entrance(ent, player) - if entrance.door.trapped: - add_rule(entrance, lambda state: standard_escape_rule(state)) + if not entrance.door or not entrance.door.entranceFlag: + add_rule_new(entrance, rule) + for ent in trap_ables: + entrance = world.get_entrance(ent, player) + if entrance.door.trapped and not entrance.door.entranceFlag: + add_rule_new(entrance, rule) + else: + for loc in region.locations: + if loc.name in kill_chests: + locations, room_id, enemy_list = kill_chests[loc.name] + rule = get_challenge_rule(world, player, room_map, stats, room_id, enemy_list, region) + add_rule_new(world.get_location(loc, player), rule) + else: + add_rule(loc, lambda state: standard_escape_rule(state)) set_rule(world.get_location('Zelda Pickup', player), lambda state: state.has('Big Key (Escape)', player)) set_rule(world.get_entrance('Hyrule Castle Tapestry Backwards', player), lambda state: state.has('Zelda Herself', player)) diff --git a/UnderworldGlitchRules.py b/UnderworldGlitchRules.py index 330c915a..c1d046bb 100644 --- a/UnderworldGlitchRules.py +++ b/UnderworldGlitchRules.py @@ -1,9 +1,7 @@ import functools -from BaseClasses import Entrance, DoorType +from BaseClasses import Entrance, DoorType, Door from DoorShuffle import connect_simple_door import Rules -from OverworldGlitchRules import create_no_logic_connections -from Doors import create_door kikiskip_spots = [ ("Kiki Skip", "Spectacle Rock Cave (Bottom)", "Palace of Darkness Portal") @@ -13,7 +11,7 @@ mirehera_spots = [("Mire to Hera Clip", "Mire Torches Top", "Hera Portal")] heraswamp_spots = [("Hera to Swamp Clip", "Mire Torches Top", "Swamp Portal")] -icepalace_spots = [("Ice Lobby Clip", "Ice Portal", "Ice Bomb Drop - Top")] +icepalace_spots = [("Ice Lobby Clip", "Ice Lobby", "Ice Bomb Drop - Top")] thievesdesert_spots = [ ("Thieves to Desert West Clip", "Thieves Attic", "Desert West Portal"), @@ -29,10 +27,7 @@ paradox_spots = [ ("Paradox Front Teleport", "Paradox Cave Front", "Paradox Cave Chest Area") ] -# Create connections between dungeons/locations -def create_hybridmajor_connections(world, player): - fix_fake_worlds = world.fix_fake_world[player] - +def create_hmg_entrances_regions(world, player): for spots in [ kikiskip_spots, mirehera_spots, @@ -42,35 +37,43 @@ def create_hybridmajor_connections(world, player): specrock_spots, paradox_spots, ]: - create_no_logic_connections(player, world, spots, connect_external=fix_fake_worlds) + for entrance, parent_region, _, *_ in spots: + parent = world.get_region(parent_region, player) + connection = Entrance(player, entrance, parent) + connection.spot_type = 'HMG' + if connection not in parent.exits: + parent.exits.append(connection) + + ip_bomb_top_reg = world.get_region("Ice Bomb Drop - Top", player) + ip_clip_entrance = Entrance(player, "Ice Bomb Drop Clip", ip_bomb_top_reg) + ip_bomb_top_reg.exits.append(ip_clip_entrance) + +def connect_hmg_entrances_regions(world, player): + for spots in [ + kikiskip_spots, + mirehera_spots, + heraswamp_spots, + icepalace_spots, + thievesdesert_spots, + specrock_spots, + paradox_spots, + ]: + for entrance, _, target_region, *_ in spots: + connection = world.get_entrance(entrance, player) + if world.fix_fake_world[player] and target_region.endswith(" Portal"): + target = world.get_portal(target_region[:-7], player).find_portal_entrance().parent_region + else: + target = world.get_region(target_region, player) + connection.connect(target) # Add the new Ice path (back of bomb drop to front) to the world and model it properly - clip_door = create_door(player, "Ice Bomb Drop Clip", DoorType.Logical) + ip_clip_entrance = world.get_entrance('Ice Bomb Drop Clip', 1) + clip_door = Door(player, "Ice Bomb Drop Clip", DoorType.Logical, ip_clip_entrance) world.doors += [clip_door] world.initialize_doors([clip_door]) - ice_bomb_top_reg = world.get_region("Ice Bomb Drop - Top", player) - ice_bomb_top_reg.exits.append( - Entrance(player, "Ice Bomb Drop Clip", ice_bomb_top_reg) - ) connect_simple_door(world, "Ice Bomb Drop Clip", "Ice Bomb Drop", player) -def get_hybridmajor_connection_entrances(): - connections = [] - for connector in ( - kikiskip_spots - + mirehera_spots - + heraswamp_spots - + icepalace_spots - + thievesdesert_spots - + specrock_spots - + paradox_spots - ): - connections.append(connector[0]) - connections.append('Ice Bomb Drop Clip') - return set(connections) - - # For some entrances, we need to fake having pearl, because we're in fake DW/LW. # This creates a copy of the input state that has Moon Pearl. def fake_pearl_state(state, player): diff --git a/docs/avianart/pots_n_bones.yaml b/docs/avianart/pots_n_bones.yaml new file mode 100644 index 00000000..e4e80a02 --- /dev/null +++ b/docs/avianart/pots_n_bones.yaml @@ -0,0 +1,24 @@ +meta: + bps: on + user_notes: An attempt to replicate the Avianart Pots and Bones settings +settings: + 1: + goal: triforcehunt + mode: standard + swords: assured + hints: on + shuffle: crossed + keysanity: on + + pottery: lottery + dropshuffle: underworld + + triforce_goal: 216 + triforce_pool: 469 + + beemizer: 0 +start_inventory: + 1: + - Pegasus Boots + - Lamp + - Red Boomerang diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 51c852d7..fb5674e3 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -65,6 +65,8 @@ class CustomSettings(object): args.outputname = get_setting(meta['name'], args.outputname) args.bps = get_setting(meta['bps'], args.bps) args.suppress_rom = get_setting(meta['suppress_rom'], args.suppress_rom) + args.skip_playthrough = get_setting(meta['skip_playthrough'], args.skip_playthrough) + args.spoiler = get_setting(meta['spoiler'], args.spoiler) args.names = get_setting(meta['names'], args.names) args.race = get_setting(meta['race'], args.race) args.notes = get_setting(meta['user_notes'], args.notes) diff --git a/source/enemizer/Enemizer.py b/source/enemizer/Enemizer.py index 021b7f03..90c7ef34 100644 --- a/source/enemizer/Enemizer.py +++ b/source/enemizer/Enemizer.py @@ -408,8 +408,9 @@ def randomize_overworld_enemies(data_tables, custom_ow): chosen = random.choices(candidate_sprites, weight, k=1)[0] sprite.kind = chosen.sprite # randomize the bush sprite per area - weight = [data_tables.ow_weights[r.sprite] for r in candidate_sprites] - bush_sprite_choice = random.choices(candidate_sprites, weight, k=1)[0] + bush_candidates = [x for x in candidate_sprites if x.bush_valid] + weight = [data_tables.ow_weights[r.sprite] for r in bush_candidates] + bush_sprite_choice = random.choices(bush_candidates, weight, k=1)[0] data_tables.bush_sprite_table[area_id] = bush_sprite_choice @@ -532,5 +533,5 @@ def write_enemy_shuffle_settings(world, player, rom): for idx, pair in enumerate(tile_pattern): rom.write_byte(snes_to_pc(0x09BA2A + idx), (pair[0] + 3) * 16) rom.write_byte(snes_to_pc(0x09BA40 + idx), (pair[1] + 4) * 16) - if world.enemy_shuffle[player] == 'random': + if world.enemy_shuffle[player] == 'shuffled': rom.write_byte(snes_to_pc(0x368100), 1) # randomize bushes diff --git a/source/enemizer/SpriteSheets.py b/source/enemizer/SpriteSheets.py index 4d89a29e..bb021088 100644 --- a/source/enemizer/SpriteSheets.py +++ b/source/enemizer/SpriteSheets.py @@ -21,6 +21,7 @@ class SpriteRequirement: self.uw_valid = True self.can_randomize = True self.water_phobic = False + self.bush_valid = True self.groups = [] self.sub_groups = defaultdict(list) @@ -94,6 +95,10 @@ class SpriteRequirement: self.uw_valid = False return self + def no_bush(self): + self.bush_valid = False + return self + def good_for_uw_water(self): return self.water_only and not self.static and not self.dont_use and self.uw_valid @@ -237,7 +242,7 @@ def init_sprite_requirements(): SpriteRequirement(EnemySprite.ArmosKnight).exalt().sub_group(3, 0x1d), SpriteRequirement(EnemySprite.Lanmolas).exalt().sub_group(3, 0x31), SpriteRequirement(EnemySprite.FireballZora).immerse().no_drop().sub_group(2, [0xc, 0x18]), # .uw_skip() test - SpriteRequirement(EnemySprite.Zora).sub_group(2, 0xc).sub_group(3, 0x44), # .uw_skip() test + SpriteRequirement(EnemySprite.Zora).sub_group(2, 0xc).sub_group(3, 0x44).uw_skip(), SpriteRequirement(EnemySprite.DesertStatue).affix().sub_group(2, 0x12), SpriteRequirement(EnemySprite.Crab).sub_group(2, 0xc), SpriteRequirement(EnemySprite.LostWoodsBird).affix().sub_group(2, 0x37).sub_group(3, 0x36), @@ -366,8 +371,8 @@ def init_sprite_requirements(): SpriteRequirement(EnemySprite.MagicShopAssistant).affix().sub_group(0, 0x4b).sub_group(3, 0x5a), SpriteRequirement(EnemySprite.SomariaPlatform).affix().sub_group(2, 0x27), SpriteRequirement(EnemySprite.CastleMantle).affix().sub_group(0, 0x5d), - SpriteRequirement(EnemySprite.GreenMimic).sub_group(1, 0x2c), - SpriteRequirement(EnemySprite.RedMimic).sub_group(1, 0x2c), + SpriteRequirement(EnemySprite.GreenMimic).sub_group(1, 0x2c).no_bush(), + SpriteRequirement(EnemySprite.RedMimic).sub_group(1, 0x2c).no_bush(), SpriteRequirement(EnemySprite.MedallionTablet).affix().sub_group(2, 0x12), # overlord requirements - encapsulated mostly in the required sheets diff --git a/source/enemizer/enemy_deny.yaml b/source/enemizer/enemy_deny.yaml index bf916dc3..b5ef799b 100644 --- a/source/enemizer/enemy_deny.yaml +++ b/source/enemizer/enemy_deny.yaml @@ -17,9 +17,9 @@ UwGeneralDeny: - [ 0x000e, 0, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Entrance - Freezor" - [ 0x000e, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari Key - Top Bari" - [ 0x000e, 2, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari Key - Middle Bari" - - [ 0x0016, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit"] ] #"Swamp Palace - Pool - Zol 1" - - [ 0x0016, 1, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit" ] ] #"Swamp Palace - Pool - Zol 2" - - [ 0x0016, 2, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit" ] ] #"Swamp Palace - Pool - Blue Bari" + - [ 0x0016, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit", "Deadrock"] ] #"Swamp Palace - Pool - Zol 1" + - [ 0x0016, 1, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit", "Deadrock" ] ] #"Swamp Palace - Pool - Zol 2" + - [ 0x0016, 2, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "GreenMimic", "RedMimic", "Pikit", "Deadrock" ] ] #"Swamp Palace - Pool - Blue Bari" - [ 0x0016, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Pool - Zol 3" - [ 0x0017, 5, [ "Beamos", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower of Hera - Bumper Room - Fire Bar (Clockwise)" - [ 0x0019, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Dark Maze - Kodongo 1" @@ -43,7 +43,7 @@ UwGeneralDeny: - [ 0x0024, 6, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots - [ 0x0026, 1, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "Statue" ] ] #"Swamp Palace - Big Spoon - Red Bari 1" - [ 0x0026, 8, [ "AntiFairyCircle", "Bumper", "Statue" ] ] #"Swamp Palace - Big Spoon - Red Bari 3" - - [ 0x0026, 9, [ "RollerHorizontalRight", "Statue" ] ] #"Swamp Palace - Big Spoon - Kyameron" + - [0x0026, 9, ["RollerHorizontalRight", "Statue", "BigSpike"]] #"Swamp Palace - Big Spoon - Kyameron" - [ 0x0026, 10, [ "Statue" ] ] # multiple push statues in this room can cause issues - [ 0x0026, 11, [ "Statue" ] ] # multiple push statues in this room can cause issues - [ 0x0027, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalLeft", "FirebarCW" ] ] #"Tower of Hera - Petting Zoo - Mini Moldorm 1" @@ -84,6 +84,7 @@ UwGeneralDeny: - [ 0x0039, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 1" - [0x0039, 5, ["RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Bumper"]] #"Skull Woods - Play Pen - Hardhat Beetle" - [ 0x0039, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 2" + - [0x003a, 1, ["RollerVerticalUp"]] - [ 0x003b, 1, [ "Bumper" ]] - [ 0x003b, 4, ["RollerVerticalUp", "RollerVerticalDown"]] - [ 0x003c, 0, ["BigSpike"]] @@ -92,7 +93,7 @@ UwGeneralDeny: - [ 0x003d, 9, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Spark (Counterclockwise)" - [ 0x003d, 10, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Spark (Clockwise) 1" - [ 0x003d, 12, [ "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Bunny Beam" - - [ 0x003d, 13, [ "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Antifairy" + - [0x003d, 13, ["AntiFairyCircle", "Bumper", "RollerHorizontalLeft", "RollerHorizontalRight"]] #"Ganon's Tower - Torches 2 - Antifairy" - [0x003e, 8, ["Wizzrobe"]] - [0x003e, 9, ["Wizzrobe", "GreenMimic", "RedMimic", "RedEyegoreMimic", "GreenEyegoreMimic"]] # drops a key by default - [0x003e, 10, ["Wizzrobe"]] @@ -171,7 +172,7 @@ UwGeneralDeny: - [0x0059, 5, ["RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]] - [ 0x0059, 9, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Gibdo 1" - [ 0x005e, 3, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Pit Trap - Big Spike Trap" - - [ 0x005e, 4, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Ice Palace - Pit Trap - Fire Bar (Clockwise)" + - [0x005e, 4, ["RollerVerticalUp", "RollerVerticalDown", "SpikeBlock"]] #"Ice Palace - Pit Trap - Fire Bar (Clockwise)" - [ 0x005f, 0, [ "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari University - Blue Bari 1" - [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2" - [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper", "Beamos", "SpikeBlock" ] ] #"Hyrule Castle - West - Blue Guard" @@ -198,6 +199,7 @@ UwGeneralDeny: - [ 0x006a, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Dark Alley - Terrorpin 4" - [ 0x006b, 7, [ "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Mimics 1 - Spike Trap 1" - [ 0x0071, 0, [ "RollerHorizontalLeft" ] ] #"Hyrule Castle - Basement Trap - Green Guard" + - [0x0072, 1, ["RollerHorizontalLeft", "RollerHorizontalRight"]] - [ 0x0074, 0, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - North Hallway - Red Devalant 1" - [ 0x0074, 1, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - North Hallway - Red Devalant 2" - [ 0x0074, 4, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - North Hallway - Leever 1" @@ -275,6 +277,7 @@ UwGeneralDeny: - [ 0x009c, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 3" - [ 0x009c, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 4" - [ 0x009c, 5, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 5" + - [0x009c, 6, ["AntiFairyCircle", "Bumper"]] - [0x009d, 2, ["AntiFairyCircle"]] - [ 0x009d, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Compass Room - Gibdo 2" - [ 0x009d, 6, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Ganon's Tower - Compass Room - Blue Bari 1" @@ -414,13 +417,17 @@ UwGeneralDeny: - [ 0x00f1, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 5" - [ 0x00f1, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 6" - [0x00fd, 0, ["Bumper", "AntiFairyCircle"]] - - [ 0x0107, 1, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] - - [ 0x0107, 2, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] + - [0x0107, 1, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] + - [0x0107, 2, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] - [0x010b, 6, ["RollerHorizontalRight"]] - [0x010c, 4, ["AntiFairyCircle"]] - [0x010c, 5, ["AntiFairyCircle"]] - [0x010c, 6, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]] - [0x010c, 7, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]] + - [0x011e, 0, ["RollerVerticalDown"]] + - [0x011e, 1, ["RollerVerticalDown"]] + - [0x011e, 2, ["RollerVerticalDown"]] + - [0x011e, 3, ["RollerVerticalDown"]] OwGeneralDeny: - [0x03, 2, ["Gibo"]] # OldMan eating Gibo - [0x03, 4, ["Gibo"]] # OldMan eating Gibo @@ -428,12 +435,14 @@ OwGeneralDeny: - [0x03, 6, ["Gibo"]] # OldMan eating Gibo - [0x03, 8, ["Gibo"]] # OldMan eating Gibo - [0x03, 9, ["Gibo"]] # OldMan eating Gibo - - [0x03, 10, ["Gibo"]] # OldMan eating Gibo + - [0x03, 10, ["Gibo", "Beamos"]] # OldMan eating Gibo - [0x05, 10, ["Bumper", "AntiFairyCircle"]] # Blocks path - [0x05, 11, ["Bumper", "AntiFairyCircle"]] # Blocks path to portal - - [0x07, 3, ["Bumper", "AntiFairyCircle"]] # Blocks path to ladder + - [0x07, 3, ["Bumper", "AntiFairyCircle", "RollerHorizontalRight", "RollerHorizontalLeft"]] # Blocks path to ladder + - [0x07, 4, ["RollerHorizontalLeft"]] # Blocks path to ladder - [0x1e, 3, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] # forbid a beamos here - [0x35, 8, ["RollerVerticalUp", "RollerVerticalDown"]] # blocks the dock + - [0x37, 5, ["RollerVerticalUp"]] # combines with a roller above to make the way impassable - [0x40, 0, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]] - [0x40, 7, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]] - [0x40, 13, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]]