152 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
from BaseClasses import ItemClassification
 | 
						|
from .Locations import level_locations, all_level_locations, standard_level_locations, shop_locations
 | 
						|
from .Options import TriforceLocations, StartingPosition
 | 
						|
 | 
						|
# Swords are in starting_weapons
 | 
						|
overworld_items = {
 | 
						|
    "Letter": 1,
 | 
						|
    "Power Bracelet": 1,
 | 
						|
    "Heart Container": 1,
 | 
						|
    "Sword": 1
 | 
						|
}
 | 
						|
 | 
						|
# Bomb, Arrow, 1 Small Key and Red Water of Life are in guaranteed_shop_items
 | 
						|
shop_items = {
 | 
						|
    "Magical Shield": 3,
 | 
						|
    "Food": 2,
 | 
						|
    "Small Key": 1,
 | 
						|
    "Candle": 1,
 | 
						|
    "Recovery Heart": 1,
 | 
						|
    "Blue Ring": 1,
 | 
						|
    "Water of Life (Blue)": 1
 | 
						|
}
 | 
						|
 | 
						|
# Magical Rod and Red Candle are in starting_weapons, Triforce Fragments are added in its section of get_pool_core
 | 
						|
major_dungeon_items = {
 | 
						|
    "Heart Container": 8,
 | 
						|
    "Bow": 1,
 | 
						|
    "Boomerang": 1,
 | 
						|
    "Magical Boomerang": 1,
 | 
						|
    "Raft": 1,
 | 
						|
    "Stepladder": 1,
 | 
						|
    "Recorder": 1,
 | 
						|
    "Magical Key": 1,
 | 
						|
    "Book of Magic": 1,
 | 
						|
    "Silver Arrow": 1,
 | 
						|
    "Red Ring": 1
 | 
						|
}
 | 
						|
 | 
						|
minor_dungeon_items = {
 | 
						|
    "Bomb": 23,
 | 
						|
    "Small Key": 45,
 | 
						|
    "Five Rupees": 17
 | 
						|
}
 | 
						|
 | 
						|
take_any_items = {
 | 
						|
    "Heart Container": 4
 | 
						|
}
 | 
						|
 | 
						|
# Map/Compasses: 18
 | 
						|
# Reasoning: Adding some variety to the vanilla game.
 | 
						|
 | 
						|
map_compass_replacements = {
 | 
						|
    "Fairy": 6,
 | 
						|
    "Clock": 3,
 | 
						|
    "Water of Life (Red)": 1,
 | 
						|
    "Water of Life (Blue)": 2,
 | 
						|
    "Bomb": 2,
 | 
						|
    "Small Key": 2,
 | 
						|
    "Five Rupees": 2
 | 
						|
}
 | 
						|
basic_pool = {
 | 
						|
    item: overworld_items.get(item, 0) + shop_items.get(item, 0)
 | 
						|
    + major_dungeon_items.get(item, 0) + map_compass_replacements.get(item, 0)
 | 
						|
    for item in set(overworld_items) | set(shop_items) | set(major_dungeon_items) | set(map_compass_replacements)
 | 
						|
}
 | 
						|
 | 
						|
starting_weapons = ["Sword", "White Sword", "Magical Sword", "Magical Rod", "Red Candle"]
 | 
						|
guaranteed_shop_items = ["Small Key", "Bomb", "Water of Life (Red)", "Arrow"]
 | 
						|
starting_weapon_locations = ["Starting Sword Cave", "Letter Cave", "Armos Knights"]
 | 
						|
dangerous_weapon_locations = [
 | 
						|
    "Level 1 Compass", "Level 2 Bomb Drop (Keese)", "Level 3 Key Drop (Zols Entrance)", "Level 3 Compass"]
 | 
						|
 | 
						|
def generate_itempool(tlozworld):
 | 
						|
    (pool, placed_items) = get_pool_core(tlozworld)
 | 
						|
    tlozworld.multiworld.itempool.extend([tlozworld.multiworld.create_item(item, tlozworld.player) for item in pool])
 | 
						|
    for (location_name, item) in placed_items.items():
 | 
						|
        location = tlozworld.multiworld.get_location(location_name, tlozworld.player)
 | 
						|
        location.place_locked_item(tlozworld.multiworld.create_item(item, tlozworld.player))
 | 
						|
        if item == "Bomb":
 | 
						|
            location.item.classification = ItemClassification.progression
 | 
						|
 | 
						|
def get_pool_core(world):
 | 
						|
    random = world.multiworld.random
 | 
						|
 | 
						|
    pool = []
 | 
						|
    placed_items = {}
 | 
						|
    minor_items = dict(minor_dungeon_items)
 | 
						|
 | 
						|
    # Guaranteed Shop Items
 | 
						|
    reserved_store_slots = random.sample(shop_locations[0:9], 4)
 | 
						|
    for location, item in zip(reserved_store_slots, guaranteed_shop_items):
 | 
						|
        placed_items[location] = item
 | 
						|
 | 
						|
    # Starting Weapon
 | 
						|
    start_weapon_locations = starting_weapon_locations.copy()
 | 
						|
    starting_weapon = random.choice(starting_weapons)
 | 
						|
    if world.multiworld.StartingPosition[world.player] == StartingPosition.option_safe:
 | 
						|
        placed_items[start_weapon_locations[0]] = starting_weapon
 | 
						|
    elif world.multiworld.StartingPosition[world.player] in \
 | 
						|
            [StartingPosition.option_unsafe, StartingPosition.option_dangerous]:
 | 
						|
        if world.multiworld.StartingPosition[world.player] == StartingPosition.option_dangerous:
 | 
						|
            for location in dangerous_weapon_locations:
 | 
						|
                if world.multiworld.ExpandedPool[world.player] or "Drop" not in location:
 | 
						|
                    start_weapon_locations.append(location)
 | 
						|
        placed_items[random.choice(start_weapon_locations)] = starting_weapon
 | 
						|
    else:
 | 
						|
        pool.append(starting_weapon)
 | 
						|
    for other_weapons in starting_weapons:
 | 
						|
        if other_weapons != starting_weapon:
 | 
						|
            pool.append(other_weapons)
 | 
						|
 | 
						|
    # Triforce Fragments
 | 
						|
    fragment = "Triforce Fragment"
 | 
						|
    if world.multiworld.ExpandedPool[world.player]:
 | 
						|
        possible_level_locations = [location for location in all_level_locations
 | 
						|
                                    if location not in level_locations[8]]
 | 
						|
    else:
 | 
						|
        possible_level_locations = [location for location in standard_level_locations
 | 
						|
                                    if location not in level_locations[8]]
 | 
						|
    for location in placed_items.keys():
 | 
						|
        if location in possible_level_locations:
 | 
						|
            possible_level_locations.remove(location)
 | 
						|
    for level in range(1, 9):
 | 
						|
        if world.multiworld.TriforceLocations[world.player] == TriforceLocations.option_vanilla:
 | 
						|
            placed_items[f"Level {level} Triforce"] = fragment
 | 
						|
        elif world.multiworld.TriforceLocations[world.player] == TriforceLocations.option_dungeons:
 | 
						|
            placed_items[possible_level_locations.pop(random.randint(0, len(possible_level_locations) - 1))] = fragment
 | 
						|
        else:
 | 
						|
            pool.append(fragment)
 | 
						|
 | 
						|
    # Level 9 junk fill
 | 
						|
    if world.multiworld.ExpandedPool[world.player] > 0:
 | 
						|
        spots = random.sample(level_locations[8], len(level_locations[8]) // 2)
 | 
						|
        for spot in spots:
 | 
						|
            junk = random.choice(list(minor_items.keys()))
 | 
						|
            placed_items[spot] = junk
 | 
						|
            minor_items[junk] -= 1
 | 
						|
 | 
						|
    # Finish Pool
 | 
						|
    final_pool = basic_pool
 | 
						|
    if world.multiworld.ExpandedPool[world.player]:
 | 
						|
        final_pool = {
 | 
						|
            item: basic_pool.get(item, 0) + minor_items.get(item, 0) + take_any_items.get(item, 0)
 | 
						|
            for item in set(basic_pool) | set(minor_items) | set(take_any_items)
 | 
						|
        }
 | 
						|
        final_pool["Five Rupees"] -= 1
 | 
						|
    for item in final_pool.keys():
 | 
						|
        for i in range(0, final_pool[item]):
 | 
						|
            pool.append(item)
 | 
						|
 | 
						|
    return pool, placed_items
 |