2023-03-05 12:31:31 +00:00
|
|
|
from BaseClasses import ItemClassification
|
|
|
|
from .Locations import level_locations, all_level_locations, standard_level_locations, shop_locations
|
2023-03-08 10:22:14 +00:00
|
|
|
from .Options import TriforceLocations, StartingPosition
|
2023-03-05 12:31:31 +00:00
|
|
|
|
|
|
|
# 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
|
2023-05-08 20:36:35 +00:00
|
|
|
start_weapon_locations = starting_weapon_locations.copy()
|
2023-03-05 12:31:31 +00:00
|
|
|
starting_weapon = random.choice(starting_weapons)
|
2023-03-08 10:22:14 +00:00
|
|
|
if world.multiworld.StartingPosition[world.player] == StartingPosition.option_safe:
|
2023-05-08 20:36:35 +00:00
|
|
|
placed_items[start_weapon_locations[0]] = starting_weapon
|
2023-03-08 10:22:14 +00:00
|
|
|
elif world.multiworld.StartingPosition[world.player] in \
|
|
|
|
[StartingPosition.option_unsafe, StartingPosition.option_dangerous]:
|
|
|
|
if world.multiworld.StartingPosition[world.player] == StartingPosition.option_dangerous:
|
2023-03-05 12:31:31 +00:00
|
|
|
for location in dangerous_weapon_locations:
|
|
|
|
if world.multiworld.ExpandedPool[world.player] or "Drop" not in location:
|
2023-05-08 20:36:35 +00:00
|
|
|
start_weapon_locations.append(location)
|
|
|
|
placed_items[random.choice(start_weapon_locations)] = starting_weapon
|
2023-03-05 12:31:31 +00:00
|
|
|
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 level in range(1, 9):
|
2023-03-08 10:22:14 +00:00
|
|
|
if world.multiworld.TriforceLocations[world.player] == TriforceLocations.option_vanilla:
|
2023-03-05 12:31:31 +00:00
|
|
|
placed_items[f"Level {level} Triforce"] = fragment
|
2023-03-08 10:22:14 +00:00
|
|
|
elif world.multiworld.TriforceLocations[world.player] == TriforceLocations.option_dungeons:
|
2023-03-05 12:31:31 +00:00
|
|
|
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
|