def generate_itempool(world, player: int): if world.difficulty[player] not in difficulties: raise NotImplementedError(f"Diffulty {world.difficulty[player]}") if world.goal[player] not in {'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals'}: raise NotImplementedError(f"Goal {world.goal[player]}") if world.mode[player] not in {'open', 'standard', 'inverted'}: raise NotImplementedError(f"Mode {world.mode[player]}") if world.timer[player] not in {False, 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'}: raise NotImplementedError(f"Timer {world.mode[player]}") if world.timer[player] in ['ohko', 'timed-ohko']: world.can_take_damage[player] = False if world.goal[player] in ['pedestal', 'triforcehunt', 'localtriforcehunt']: world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False) else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) if world.goal[player] in ['triforcehunt', 'localtriforcehunt']: region = world.get_region('Light World', player) loc = Location(player, "Murahdahla", parent=region) loc.access_rule = lambda state: state.has_triforce_pieces(state.world.treasure_hunt_count[player], player) region.locations.append(loc) world.dynamic_locations.append(loc) world.clear_location_cache() world.push_item(loc, ItemFactory('Triforce', player), False) loc.event = True loc.locked = True world.get_location('Ganon', player).event = True world.get_location('Ganon', player).locked = True world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False) world.get_location('Agahnim 1', player).event = True world.get_location('Agahnim 1', player).locked = True world.push_item(world.get_location('Agahnim 2', player), ItemFactory('Beat Agahnim 2', player), False) world.get_location('Agahnim 2', player).event = True world.get_location('Agahnim 2', player).locked = True world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False) world.get_location('Dark Blacksmith Ruins', player).event = True world.get_location('Dark Blacksmith Ruins', player).locked = True world.push_item(world.get_location('Frog', player), ItemFactory('Get Frog', player), False) world.get_location('Frog', player).event = True world.get_location('Frog', player).locked = True world.push_item(world.get_location('Missing Smith', player), ItemFactory('Return Smith', player), False) world.get_location('Missing Smith', player).event = True world.get_location('Missing Smith', player).locked = True world.push_item(world.get_location('Floodgate', player), ItemFactory('Open Floodgate', player), False) world.get_location('Floodgate', player).event = True world.get_location('Floodgate', player).locked = True # set up item pool if world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = make_custom_item_pool(world, player) world.rupoor_cost = min(world.customitemarray[69], 9999) else: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = get_pool_core( world, player) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) if world.mode[player] == 'standard' and not world.state.has_melee_weapon(player): if "Link's Uncle" not in placed_items: found_sword = False found_bow = False 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': found_sword = True possible_weapons.append(item) if item in ['Progressive Bow', 'Bow'] and not found_bow: found_bow = True possible_weapons.append(item) if item in ['Hammer', 'Bombs (10)', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']: if item not in possible_weapons: possible_weapons.append(item) starting_weapon = world.random.choice(possible_weapons) placed_items["Link's Uncle"] = starting_weapon pool.remove(starting_weapon) if placed_items["Link's Uncle"] in ['Bow', 'Progressive Bow', 'Bombs (10)', 'Cane of Somaria', 'Cane of Byrna'] and world.enemy_health[player] not in ['default', 'easy']: world.escape_assist[player].append('bombs') for (location, item) in placed_items.items(): world.push_item(world.get_location(location, player), ItemFactory(item, player), False) world.get_location(location, player).event = True world.get_location(location, player).locked = True items = ItemFactory(pool, player) if clock_mode is not None: world.clock_mode[player] = clock_mode if treasure_hunt_count is not None: world.treasure_hunt_count[player] = treasure_hunt_count if treasure_hunt_icon is not None: world.treasure_hunt_icon[player] = treasure_hunt_icon world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player and ((item.smallkey and world.keyshuffle[player]) or (item.bigkey and world.bigkeyshuffle[player]) or (item.map and world.mapshuffle[player]) or (item.compass and world.compassshuffle[player]))]) # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and world.customitemarray[30] == 0): [item for item in items if item.name == 'Boss Heart Container'][0].advancement = True elif world.difficulty[player] in ['expert'] and not (world.custom and world.customitemarray[29] < 4): adv_heart_pieces = [item for item in items if item.name == 'Piece of Heart'][0:4] for hp in adv_heart_pieces: hp.advancement = True beeweights = {0: {None: 100}, 1: {None: 75, 'trap': 25}, 2: {None: 40, 'trap': 40, 'bee': 20}, 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: choice = world.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 progressionitems = [item for item in items if item.advancement or item.priority or item.type] nonprogressionitems = [beemizer(item) for item in items if not item.advancement and not item.priority and not item.type] world.random.shuffle(nonprogressionitems) triforce_pieces = world.triforce_pieces_available[player] if 'triforcehunt' in world.goal[player] and triforce_pieces > 30: progressionitems += [ItemFactory("Triforce Piece", player)] * (triforce_pieces - 30) nonprogressionitems = nonprogressionitems[(triforce_pieces - 30):] world.itempool += progressionitems + nonprogressionitems # shuffle medallions mm_medallion = ['Ether', 'Quake', 'Bombos'][world.random.randint(0, 2)] tr_medallion = ['Ether', 'Quake', 'Bombos'][world.random.randint(0, 2)] world.required_medallions[player] = (mm_medallion, tr_medallion) place_bosses(world, player) set_up_shops(world, player) if world.retro[player]: set_up_take_anys(world, player) create_dynamic_shop_locations(world, player)
def generate_itempool(world): if (world.difficulty not in ['easy', 'normal', 'hard', 'expert', 'insane'] or world.goal not in [ 'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals' ] or world.mode not in ['open', 'standard', 'swordless'] or world.timer not in [ 'none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown' ] or world.progressive not in ['on', 'off', 'random']): raise NotImplementedError('Not supported yet') if world.timer in ['ohko', 'timed-ohko']: world.can_take_damage = False world.push_item('Ganon', ItemFactory('Triforce'), False) world.get_location('Ganon').event = True world.push_item('Agahnim 1', ItemFactory('Beat Agahnim 1'), False) world.get_location('Agahnim 1').event = True world.push_item('Agahnim 2', ItemFactory('Beat Agahnim 2'), False) world.get_location('Agahnim 2').event = True world.push_item('Dark Blacksmith Ruins', ItemFactory('Pick Up Purple Chest'), False) world.get_location('Dark Blacksmith Ruins').event = True world.push_item('Frog', ItemFactory('Get Frog'), False) world.get_location('Frog').event = True world.push_item('Missing Smith', ItemFactory('Return Smith'), False) world.get_location('Missing Smith').event = True world.push_item('Floodgate', ItemFactory('Open Floodgate'), False) world.get_location('Floodgate').event = True # set up item pool if world.custom: (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool( world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.retro, world.customitemarray) world.rupoor_cost = min(world.customitemarray[67], 9999) else: (pool, placed_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core( world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.retro) world.itempool = ItemFactory(pool) for (location, item) in placed_items: world.push_item(location, ItemFactory(item), False) world.get_location(location).event = True world.lamps_needed_for_dark_rooms = lamps_needed_for_dark_rooms if clock_mode is not None: world.clock_mode = clock_mode if treasure_hunt_count is not None: world.treasure_hunt_count = treasure_hunt_count if treasure_hunt_icon is not None: world.treasure_hunt_icon = treasure_hunt_icon if world.keysanity: world.itempool.extend(get_dungeon_item_pool(world)) # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.difficulty in [ 'easy', 'normal', 'hard' ] and not (world.custom and world.customitemarray[30] == 0): [ item for item in world.itempool if item.name == 'Boss Heart Container' ][0].advancement = True elif world.difficulty in [ 'expert' ] and not (world.custom and world.customitemarray[29] < 4): adv_heart_pieces = [ item for item in world.itempool if item.name == 'Piece of Heart' ][0:4] for hp in adv_heart_pieces: hp.advancement = True # shuffle medallions mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] world.required_medallions = (mm_medallion, tr_medallion) place_bosses(world) set_up_shops(world) if world.retro: set_up_take_anys(world) create_dynamic_shop_locations(world)
def generate_itempool(world, player: int): if world.difficulty[player] not in difficulties: raise NotImplementedError(f"Diffulty {world.difficulty[player]}") if world.goal[player] not in { 'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'localtriforcehunt', 'icerodhunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals', 'ganonpedestal' }: raise NotImplementedError(f"Goal {world.goal[player]}") if world.mode[player] not in {'open', 'standard', 'inverted'}: raise NotImplementedError(f"Mode {world.mode[player]}") if world.timer[player] not in { False, 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown' }: raise NotImplementedError(f"Timer {world.mode[player]}") if world.timer[player] in ['ohko', 'timed-ohko']: world.can_take_damage[player] = False if world.goal[player] in [ 'pedestal', 'triforcehunt', 'localtriforcehunt', 'icerodhunt' ]: world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False) else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) if world.goal[player] in ['triforcehunt', 'localtriforcehunt']: region = world.get_region('Light World', player) loc = Location(player, "Murahdahla", parent=region) loc.access_rule = lambda state: state.has_triforce_pieces( state.world.treasure_hunt_count[player], player) region.locations.append(loc) world.dynamic_locations.append(loc) world.clear_location_cache() world.push_item(loc, ItemFactory('Triforce', player), False) loc.event = True loc.locked = True if world.goal[player] == 'icerodhunt': world.progression_balancing[player] = False loc = world.get_location('Turtle Rock - Boss', player) world.push_item(loc, ItemFactory('Triforce', player), False) if world.boss_shuffle[player] != 'none': if 'turtle rock-' not in world.boss_shuffle[player]: world.boss_shuffle[ player] = f'Turtle Rock-Trinexx;{world.boss_shuffle[player]}' else: logging.warning( f'Cannot guarantee that Trinexx is the boss of Turtle Rock for player {player}' ) loc.event = True loc.locked = True forbid_items_for_player( loc, { 'Red Pendant', 'Green Pendant', 'Blue Pendant', 'Crystal 5', 'Crystal 6' }, player) itemdiff = difficulties[world.difficulty[player]] itempool = [] itempool.extend(itemdiff.alwaysitems) itempool.remove('Ice Rod') itempool.extend(['Single Arrow', 'Sanctuary Heart Container']) itempool.extend(['Boss Heart Container'] * itemdiff.boss_heart_container_limit) itempool.extend(['Piece of Heart'] * itemdiff.heart_piece_limit) itempool.extend(itemdiff.bottles) itempool.extend(itemdiff.basicbow) itempool.extend(itemdiff.basicarmor) if world.swords[player] != 'swordless': itempool.extend(itemdiff.basicsword) itempool.extend(itemdiff.basicmagic) itempool.extend(itemdiff.basicglove) itempool.extend(itemdiff.basicshield) itempool.extend(itemdiff.legacyinsanity) itempool.extend(['Rupees (300)'] * 34) itempool.extend(['Bombs (10)'] * 5) itempool.extend(['Arrows (10)'] * 7) if world.keyshuffle[player] == 'universal': itempool.extend(itemdiff.universal_keys) itempool.append('Small Key (Universal)') for item in itempool: world.push_precollected(ItemFactory(item, player)) world.get_location('Ganon', player).event = True world.get_location('Ganon', player).locked = True event_pairs = [('Agahnim 1', 'Beat Agahnim 1'), ('Agahnim 2', 'Beat Agahnim 2'), ('Dark Blacksmith Ruins', 'Pick Up Purple Chest'), ('Frog', 'Get Frog'), ('Missing Smith', 'Return Smith'), ('Floodgate', 'Open Floodgate'), ('Agahnim 1', 'Beat Agahnim 1'), ('Flute Activation Spot', 'Activated Flute')] for location_name, event_name in event_pairs: location = world.get_location(location_name, player) event = ItemFactory(event_name, player) world.push_item(location, event, False) location.event = location.locked = True # set up item pool additional_triforce_pieces = 0 if world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon) = make_custom_item_pool(world, player) world.rupoor_cost = min(world.customitemarray[67], 9999) else: pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, \ treasure_hunt_icon, additional_triforce_pieces = get_pool_core(world, player) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) if world.mode[player] == 'standard' and not world.state.has_melee_weapon( player): if "Link's Uncle" not in placed_items: found_sword = False found_bow = False 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': found_sword = True possible_weapons.append(item) if item in ['Progressive Bow', 'Bow'] and not found_bow: found_bow = True possible_weapons.append(item) if item in [ 'Hammer', 'Bombs (10)', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna' ]: if item not in possible_weapons: possible_weapons.append(item) starting_weapon = world.random.choice(possible_weapons) placed_items["Link's Uncle"] = starting_weapon pool.remove(starting_weapon) if placed_items["Link's Uncle"] in [ 'Bow', 'Progressive Bow', 'Bombs (10)', 'Cane of Somaria', 'Cane of Byrna' ] and world.enemy_health[player] not in ['default', 'easy']: world.escape_assist[player].append('bombs') for (location, item) in placed_items.items(): world.push_item(world.get_location(location, player), ItemFactory(item, player), False) world.get_location(location, player).event = True world.get_location(location, player).locked = True items = ItemFactory(pool, player) if clock_mode is not None: world.clock_mode[player] = clock_mode if treasure_hunt_count is not None: world.treasure_hunt_count[player] = treasure_hunt_count % 999 if treasure_hunt_icon is not None: world.treasure_hunt_icon[player] = treasure_hunt_icon dungeon_items = [ item for item in get_dungeon_item_pool(world) if item.player == player and ( (item.smallkey and world.keyshuffle[player]) or (item.bigkey and world.bigkeyshuffle[player]) or (item.map and world.mapshuffle[player]) or (item.compass and world.compassshuffle[player]) or world.goal[player] == 'icerodhunt') ] if world.goal[player] == 'icerodhunt': for item in dungeon_items: world.itempool.append( ItemFactory(GetBeemizerItem(world, player, 'Nothing'), player)) world.push_precollected(item) else: world.itempool.extend([item for item in dungeon_items]) # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.goal[player] != 'icerodhunt' and world.difficulty[player] in [ 'easy', 'normal', 'hard' ] and not (world.custom and world.customitemarray[30] == 0): next(item for item in items if item.name == 'Boss Heart Container').advancement = True elif world.goal[player] != 'icerodhunt' and world.difficulty[player] in [ 'expert' ] and not (world.custom and world.customitemarray[29] < 4): adv_heart_pieces = (item for item in items if item.name == 'Piece of Heart') for i in range(4): next(adv_heart_pieces).advancement = True progressionitems = [] nonprogressionitems = [] for item in items: if item.advancement or item.type: progressionitems.append(item) else: nonprogressionitems.append( GetBeemizerItem(world, item.player, item)) world.random.shuffle(nonprogressionitems) if additional_triforce_pieces: if additional_triforce_pieces > len(nonprogressionitems): raise FillError( f"Not enough non-progression items to replace with Triforce pieces found for player " f"{world.get_player_names(player)}.") progressionitems += [ItemFactory("Triforce Piece", player) ] * additional_triforce_pieces nonprogressionitems.sort(key=lambda item: int("Heart" in item.name) ) # try to keep hearts in the pool nonprogressionitems = nonprogressionitems[additional_triforce_pieces:] world.random.shuffle(nonprogressionitems) # shuffle medallions if world.required_medallions[player][0] == "random": mm_medallion = world.random.choice(['Ether', 'Quake', 'Bombos']) else: mm_medallion = world.required_medallions[player][0] if world.required_medallions[player][1] == "random": tr_medallion = world.random.choice(['Ether', 'Quake', 'Bombos']) else: tr_medallion = world.required_medallions[player][1] world.required_medallions[player] = (mm_medallion, tr_medallion) place_bosses(world, player) set_up_shops(world, player) if world.shop_shuffle[player]: shuffle_shops(world, nonprogressionitems, player) create_dynamic_shop_locations(world, player) world.itempool += progressionitems + nonprogressionitems if world.retro[player]: set_up_take_anys(world, player) # depends on world.itempool to be set
def generate_itempool(world, player): if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in [ 'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals' ] or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in [ 'none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown' ] or world.progressive not in ['on', 'off', 'random']): raise NotImplementedError('Not supported yet') if world.timer in ['ohko', 'timed-ohko']: world.can_take_damage = False if world.goal[player] in ['pedestal', 'triforcehunt']: world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False) else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) if world.goal[player] in ['triforcehunt']: region = world.get_region('Light World', player) loc = Location(player, "Murahdahla", parent=region) loc.access_rule = lambda state: state.item_count( 'Triforce Piece', player) + state.item_count( 'Power Star', player) > state.world.treasure_hunt_count[player] region.locations.append(loc) world.dynamic_locations.append(loc) world.clear_location_cache() world.push_item(loc, ItemFactory('Triforce', player), False) loc.event = True loc.locked = True world.get_location('Ganon', player).event = True world.get_location('Ganon', player).locked = True world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False) world.get_location('Agahnim 1', player).event = True world.get_location('Agahnim 1', player).locked = True world.push_item(world.get_location('Agahnim 2', player), ItemFactory('Beat Agahnim 2', player), False) world.get_location('Agahnim 2', player).event = True world.get_location('Agahnim 2', player).locked = True world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False) world.get_location('Dark Blacksmith Ruins', player).event = True world.get_location('Dark Blacksmith Ruins', player).locked = True world.push_item(world.get_location('Frog', player), ItemFactory('Get Frog', player), False) world.get_location('Frog', player).event = True world.get_location('Frog', player).locked = True world.push_item(world.get_location('Missing Smith', player), ItemFactory('Return Smith', player), False) world.get_location('Missing Smith', player).event = True world.get_location('Missing Smith', player).locked = True world.push_item(world.get_location('Floodgate', player), ItemFactory('Open Floodgate', player), False) world.get_location('Floodgate', player).event = True world.get_location('Floodgate', player).locked = True world.push_item(world.get_location('Trench 1 Switch', player), ItemFactory('Trench 1 Filled', player), False) world.get_location('Trench 1 Switch', player).event = True world.get_location('Trench 1 Switch', player).locked = True world.push_item(world.get_location('Trench 2 Switch', player), ItemFactory('Trench 2 Filled', player), False) world.get_location('Trench 2 Switch', player).event = True world.get_location('Trench 2 Switch', player).locked = True world.push_item(world.get_location('Swamp Drain', player), ItemFactory('Drained Swamp', player), False) world.get_location('Swamp Drain', player).event = True world.get_location('Swamp Drain', player).locked = True world.push_item(world.get_location('Attic Cracked Floor', player), ItemFactory('Shining Light', player), False) world.get_location('Attic Cracked Floor', player).event = True world.get_location('Attic Cracked Floor', player).locked = True world.push_item(world.get_location('Suspicious Maiden', player), ItemFactory('Maiden Rescued', player), False) world.get_location('Suspicious Maiden', player).event = True world.get_location('Suspicious Maiden', player).locked = True world.push_item(world.get_location('Revealing Light', player), ItemFactory('Maiden Unmasked', player), False) world.get_location('Revealing Light', player).event = True world.get_location('Revealing Light', player).locked = True world.push_item(world.get_location('Ice Block Drop', player), ItemFactory('Convenient Block', player), False) world.get_location('Ice Block Drop', player).event = True world.get_location('Ice Block Drop', player).locked = True if world.mode[player] == 'standard': world.push_item(world.get_location('Zelda Pickup', player), ItemFactory('Zelda Herself', player), False) world.get_location('Zelda Pickup', player).event = True world.get_location('Zelda Pickup', player).locked = True world.push_item(world.get_location('Zelda Drop Off', player), ItemFactory('Zelda Delivered', player), False) world.get_location('Zelda Drop Off', player).event = True world.get_location('Zelda Drop Off', player).locked = True # set up item pool if world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool( world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray["rupoorcost"], 9999) else: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core( world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.doorShuffle[player]) if player in world.pool_adjustment.keys(): amt = world.pool_adjustment[player] if amt < 0: for i in range(0, amt): pool.remove('Rupees (20)') elif amt > 0: for i in range(0, amt): pool.append('Rupees (20)') for item in precollected_items: world.push_precollected(ItemFactory(item, player)) if world.mode[player] == 'standard' and not world.state.has_blunt_weapon( player): if "Link's Uncle" not in placed_items: found_sword = False found_bow = False 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': found_sword = True possible_weapons.append(item) if item in ['Progressive Bow', 'Bow'] and not found_bow: found_bow = True possible_weapons.append(item) if item in [ 'Hammer', 'Bombs (10)', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna' ]: if item not in possible_weapons: possible_weapons.append(item) starting_weapon = random.choice(possible_weapons) placed_items["Link's Uncle"] = starting_weapon pool.remove(starting_weapon) if placed_items["Link's Uncle"] in [ 'Bow', 'Progressive Bow', 'Bombs (10)', 'Cane of Somaria', 'Cane of Byrna' ] and world.enemy_health[player] not in ['default', 'easy']: world.escape_assist[player].append('bombs') for (location, item) in placed_items.items(): world.push_item(world.get_location(location, player), ItemFactory(item, player), False) world.get_location(location, player).event = True world.get_location(location, player).locked = True items = ItemFactory(pool, player) world.lamps_needed_for_dark_rooms = lamps_needed_for_dark_rooms if clock_mode is not None: world.clock_mode = clock_mode if treasure_hunt_count is not None: world.treasure_hunt_count[player] = treasure_hunt_count if treasure_hunt_icon is not None: world.treasure_hunt_icon[player] = treasure_hunt_icon world.itempool.extend([ item for item in get_dungeon_item_pool(world) if item.player == player and ( (item.smallkey and world.keyshuffle[player]) or (item.bigkey and world.bigkeyshuffle[player]) or (item.map and world.mapshuffle[player]) or (item.compass and world.compassshuffle[player])) ]) # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.difficulty[player] in [ 'normal', 'hard' ] and not (world.custom and world.customitemarray["heartcontainer"] == 0): [item for item in items if item.name == 'Boss Heart Container'][0].advancement = True elif world.difficulty[player] in [ 'expert' ] and not (world.custom and world.customitemarray["heartpiece"] < 4): adv_heart_pieces = [ item for item in items if item.name == 'Piece of Heart' ][0:4] for hp in adv_heart_pieces: hp.advancement = True beeweights = { 0: { None: 100 }, 1: { None: 75, 'trap': 25 }, 2: { None: 40, 'trap': 40, 'bee': 20 }, 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: 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 world.itempool += [beemizer(item) for item in items] # shuffle medallions mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] world.required_medallions[player] = (mm_medallion, tr_medallion) place_bosses(world, player) set_up_shops(world, player) if world.retro[player]: set_up_take_anys(world, player) create_dynamic_shop_locations(world, player)
def generate_itempool(world, player): if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal not in [ 'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals' ] or world.mode not in ['open', 'standard', 'inverted'] or world.timer not in [ 'none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown' ] or world.progressive not in ['on', 'off', 'random']): raise NotImplementedError('Not supported yet') if world.timer in ['ohko', 'timed-ohko']: world.can_take_damage = False if world.goal in ['pedestal', 'triforcehunt']: world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False) else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) if world.goal in ['triforcehunt']: if world.mode == 'inverted': region = world.get_region('Light World', player) else: region = world.get_region('Hyrule Castle Courtyard', player) loc = Location(player, "Murahdahla", parent=region) loc.access_rule = lambda state: state.item_count( 'Triforce Piece', player) + state.item_count( 'Power Star', player) > state.world.treasure_hunt_count region.locations.append(loc) world.dynamic_locations.append(loc) world.clear_location_cache() world.push_item(loc, ItemFactory('Triforce', player), False) loc.event = True loc.locked = True world.get_location('Ganon', player).event = True world.get_location('Ganon', player).locked = True world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False) world.get_location('Agahnim 1', player).event = True world.get_location('Agahnim 1', player).locked = True world.push_item(world.get_location('Agahnim 2', player), ItemFactory('Beat Agahnim 2', player), False) world.get_location('Agahnim 2', player).event = True world.get_location('Agahnim 2', player).locked = True world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False) world.get_location('Dark Blacksmith Ruins', player).event = True world.get_location('Dark Blacksmith Ruins', player).locked = True world.push_item(world.get_location('Frog', player), ItemFactory('Get Frog', player), False) world.get_location('Frog', player).event = True world.get_location('Frog', player).locked = True world.push_item(world.get_location('Missing Smith', player), ItemFactory('Return Smith', player), False) world.get_location('Missing Smith', player).event = True world.get_location('Missing Smith', player).locked = True world.push_item(world.get_location('Floodgate', player), ItemFactory('Open Floodgate', player), False) world.get_location('Floodgate', player).event = True world.get_location('Floodgate', player).locked = True # set up item pool if world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool( world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.swords, world.retro, world.customitemarray) world.rupoor_cost = min(world.customitemarray[67], 9999) else: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core( world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.swords, world.retro) world.itempool += ItemFactory(pool, player) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) for (location, item) in placed_items: world.push_item(world.get_location(location, player), ItemFactory(item, player), False) world.get_location(location, player).event = True world.get_location(location, player).locked = True world.lamps_needed_for_dark_rooms = lamps_needed_for_dark_rooms if clock_mode is not None: world.clock_mode = clock_mode if treasure_hunt_count is not None: world.treasure_hunt_count = treasure_hunt_count if treasure_hunt_icon is not None: world.treasure_hunt_icon = treasure_hunt_icon if world.keysanity: world.itempool.extend([ item for item in get_dungeon_item_pool(world) if item.player == player ]) # logic has some branches where having 4 hearts is one possible requirement (of several alternatives) # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.difficulty in [ 'normal', 'hard' ] and not (world.custom and world.customitemarray[30] == 0): [ item for item in world.itempool if item.name == 'Boss Heart Container' and item.player == player ][0].advancement = True elif world.difficulty in [ 'expert' ] and not (world.custom and world.customitemarray[29] < 4): adv_heart_pieces = [ item for item in world.itempool if item.name == 'Piece of Heart' and item.player == player ][0:4] for hp in adv_heart_pieces: hp.advancement = True # shuffle medallions mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] world.required_medallions[player] = (mm_medallion, tr_medallion) place_bosses(world, player) set_up_shops(world, player) if world.retro: set_up_take_anys(world, player) create_dynamic_shop_locations(world, player)