Example #1
0
 def setUp(self):
     self.world = MultiWorld(1)
     args = Namespace()
     for name, option in AutoWorld.AutoWorldRegister.world_types[
             "A Link to the Past"].options.items():
         setattr(args, name, {1: option.from_any(option.default)})
     self.world.set_options(args)
     self.world.set_default_common_options()
     self.starting_regions = []  # Where to start exploring
     self.remove_exits = []  # Block dungeon exits
     self.world.difficulty_requirements[1] = difficulties['normal']
     create_regions(self.world, 1)
     create_dungeons(self.world, 1)
     create_shops(self.world, 1)
     for exitname, regionname in mandatory_connections:
         connect_simple(self.world, exitname, regionname, 1)
     connect_simple(self.world, 'Big Bomb Shop', 'Big Bomb Shop', 1)
     self.world.get_region('Menu', 1).exits = []
     self.world.swamp_patch_required[1] = True
     self.world.worlds[1].set_rules()
     self.world.worlds[1].create_items()
     self.world.itempool.extend(get_dungeon_item_pool(self.world))
     self.world.itempool.extend(
         ItemFactory([
             'Green Pendant', 'Red Pendant', 'Blue Pendant',
             'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2',
             'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'
         ], 1))
Example #2
0
 def setUp(self):
     self.world = MultiWorld(1)
     args = Namespace()
     for name, option in AutoWorld.AutoWorldRegister.world_types[
             "A Link to the Past"].options.items():
         setattr(args, name, {1: option.from_any(option.default)})
     self.world.set_options(args)
     self.world.set_default_common_options()
     self.world.logic[1] = "owglitches"
     self.world.mode[1] = "inverted"
     self.world.difficulty_requirements[1] = difficulties['normal']
     create_inverted_regions(self.world, 1)
     create_dungeons(self.world, 1)
     create_shops(self.world, 1)
     link_inverted_entrances(self.world, 1)
     self.world.worlds[1].create_items()
     self.world.required_medallions[1] = ['Ether', 'Quake']
     self.world.itempool.extend(get_dungeon_item_pool(self.world))
     self.world.itempool.extend(
         ItemFactory([
             'Green Pendant', 'Red Pendant', 'Blue Pendant',
             'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2',
             'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'
         ], 1))
     self.world.get_location('Agahnim 1', 1).item = None
     self.world.get_location('Agahnim 2', 1).item = None
     self.world.precollected_items[1].clear()
     self.world.itempool.append(ItemFactory('Pegasus Boots', 1))
     mark_light_world_regions(self.world, 1)
     self.world.worlds[1].set_rules()
Example #3
0
 def setUp(self):
     self.world = MultiWorld(1)
     self.starting_regions = []  # Where to start exploring
     self.remove_exits = []      # Block dungeon exits
     self.world.difficulty_requirements[1] = difficulties['normal']
     create_regions(self.world, 1)
     create_dungeons(self.world, 1)
     create_shops(self.world, 1)
     for exitname, regionname in mandatory_connections:
         connect_simple(self.world, exitname, regionname, 1)
     connect_simple(self.world, 'Big Bomb Shop', 'Big Bomb Shop', 1)
     self.world.get_region('Menu', 1).exits = []
     self.world.swamp_patch_required[1] = True
     set_rules(self.world, 1)
     generate_itempool(self.world, 1)
     self.world.itempool.extend(get_dungeon_item_pool(self.world))
     self.world.itempool.extend(ItemFactory(['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'], 1))
Example #4
0
 def setUp(self):
     self.world = MultiWorld(1)
     self.world.difficulty_requirements[1] = difficulties['normal']
     self.world.logic[1] = "owglitches"
     create_regions(self.world, 1)
     create_dungeons(self.world, 1)
     create_shops(self.world, 1)
     link_entrances(self.world, 1)
     generate_itempool(self.world, 1)
     self.world.required_medallions[1] = ['Ether', 'Quake']
     self.world.itempool.extend(get_dungeon_item_pool(self.world))
     self.world.itempool.extend(ItemFactory(['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'], 1))
     self.world.get_location('Agahnim 1', 1).item = None
     self.world.get_location('Agahnim 2', 1).item = None
     self.world.precollected_items.clear()
     self.world.itempool.append(ItemFactory('Pegasus Boots', 1))
     mark_dark_world_regions(self.world, 1)
     set_rules(self.world, 1)
Example #5
0
 def setUp(self):
     self.world = MultiWorld(1)
     self.world.difficulty_requirements[1] = difficulties['normal']
     self.world.mode[1] = "inverted"
     create_inverted_regions(self.world, 1)
     create_dungeons(self.world, 1)
     create_shops(self.world, 1)
     link_inverted_entrances(self.world, 1)
     generate_itempool(self.world, 1)
     self.world.required_medallions[1] = ['Ether', 'Quake']
     self.world.itempool.extend(get_dungeon_item_pool(self.world))
     self.world.itempool.extend(
         ItemFactory([
             'Green Pendant', 'Red Pendant', 'Blue Pendant',
             'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2',
             'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'
         ], 1))
     self.world.get_location('Agahnim 1', 1).item = None
     self.world.get_location('Agahnim 2', 1).item = None
     mark_light_world_regions(self.world, 1)
     set_rules(self.world, 1)
Example #6
0
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', 'bosses', 'triforcehunt', 'localtriforcehunt',
            'icerodhunt', 'ganontriforcehunt', 'localganontriforcehunt',
            'crystals', 'ganonpedestal'
    }:
        raise NotImplementedError(
            f"Goal {world.goal[player]} for player {player}")
    if world.mode[player] not in {'open', 'standard', 'inverted'}:
        raise NotImplementedError(
            f"Mode {world.mode[player]} for player {player}")
    if world.timer[player] not in {
            False, 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'
    }:
        raise NotImplementedError(
            f"Timer {world.mode[player]} for player {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 = ALttPLocation(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 not world.swordless[player]:
            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:
                        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