Merged in DR v1.0.1.0

This commit is contained in:
codemann8
2022-07-08 10:59:00 -05:00
64 changed files with 4100 additions and 1396 deletions

View File

@@ -1,12 +1,13 @@
import RaceRandom as random
import logging
from math import ceil
from collections import defaultdict
from source.item.District import resolve_districts
from BaseClasses import PotItem, PotFlags
from DoorShuffle import validate_vanilla_reservation
from Dungeons import dungeon_table
from Items import item_table, ItemFactory
from PotShuffle import vanilla_pots
class ItemPoolConfig(object):
@@ -28,7 +29,6 @@ class LocationGroup(object):
# flags
self.keyshuffle = False
self.keydropshuffle = False
self.shopsanity = False
self.retro = False
@@ -36,9 +36,8 @@ class LocationGroup(object):
self.locations = list(locs)
return self
def flags(self, k, d=False, s=False, r=False):
def flags(self, k, s=False, r=False):
self.keyshuffle = k
self.keydropshuffle = d
self.shopsanity = s
self.retro = r
return self
@@ -64,34 +63,40 @@ def create_item_pool_config(world):
config.static_placement = {}
config.location_groups = {}
for player in range(1, world.players + 1):
config.static_placement[player] = vanilla_mapping.copy()
if world.keydropshuffle[player]:
config.static_placement[player] = defaultdict(list)
config.static_placement[player].update(vanilla_mapping)
if world.dropshuffle[player]:
for item, locs in keydrop_vanilla_mapping.items():
if item in config.static_placement[player]:
config.static_placement[player][item].extend(locs)
else:
config.static_placement[player][item] = list(locs)
config.static_placement[player][item].extend(locs)
if world.pottery[player] not in ['none', 'cave']:
for item, locs in potkeys_vanilla_mapping.items():
config.static_placement[player][item].extend(locs)
if world.pottery[player] in ['lottery', 'cave', 'dungeon']:
for super_tile, pot_list in vanilla_pots.items():
for pot_index, pot in enumerate(pot_list):
if pot.item not in [PotItem.Key, PotItem.Hole, PotItem.Switch]:
item = pot_items[pot.item]
descriptor = 'Large Block' if pot.flags & PotFlags.Block else f'Pot #{pot_index+1}'
location = f'{pot.room} {descriptor}'
config.static_placement[player][item].append(location)
if world.shopsanity[player]:
for item, locs in shop_vanilla_mapping.items():
if item in config.static_placement[player]:
config.static_placement[player][item].extend(locs)
else:
config.static_placement[player][item] = list(locs)
config.static_placement[player][item].extend(locs)
if world.retro[player]:
for item, locs in retro_vanilla_mapping.items():
if item in config.static_placement[player]:
config.static_placement[player][item].extend(locs)
else:
config.static_placement[player][item] = list(locs)
config.static_placement[player][item].extend(locs)
# universal keys
universal_key_locations = []
for item, locs in vanilla_mapping.items():
if 'Small Key' in item:
universal_key_locations.extend(locs)
if world.keydropshuffle[player]:
if world.dropshuffle[player]:
for item, locs in keydrop_vanilla_mapping.items():
if 'Small Key' in item:
universal_key_locations.extend(locs)
if world.pottery[player] not in ['none', 'cave']:
for item, locs in potkeys_vanilla_mapping.items():
universal_key_locations.extend(locs)
if world.shopsanity[player]:
single_arrow_placement = list(shop_vanilla_mapping['Red Potion'])
single_arrow_placement.append('Red Shield Shop - Right')
@@ -117,12 +122,14 @@ def create_item_pool_config(world):
groups = LocationGroup('Major').locs(init_set)
if world.bigkeyshuffle[player]:
groups.locations.extend(mode_grouping['Big Keys'])
if world.keydropshuffle[player]:
if world.dropshuffle[player] != 'none':
groups.locations.extend(mode_grouping['Big Key Drops'])
if world.keyshuffle[player]:
groups.locations.extend(mode_grouping['Small Keys'])
if world.keydropshuffle[player]:
if world.dropshuffle[player] != 'none':
groups.locations.extend(mode_grouping['Key Drops'])
if world.pottery[player] not in ['none', 'cave']:
groups.locations.extend(mode_grouping['Pot Keys'])
if world.compassshuffle[player]:
groups.locations.extend(mode_grouping['Compasses'])
if world.mapshuffle[player]:
@@ -268,7 +275,7 @@ def massage_item_pool(world):
world.itempool.remove(deleted)
discrepancy -= 1
if discrepancy > 0:
logging.getLogger('').warning(f'Too many good items in pool, something will be removed at random')
raise Exception(f'Too many required items in pool, {discrepancy} items cannot be placed')
if world.item_pool_config.placeholders is not None:
removed = 0
single_rupees = [item for item in world.itempool if item.name == 'Rupee (1)']
@@ -322,49 +329,6 @@ def count_major_items(config, world, player):
return sum(1 for x in world.itempool if x.name in config.item_pool[player] and x.player == player)
def calc_dungeon_limits(world, player):
b, s, c, m, k, r, bi = (world.bigkeyshuffle[player], world.keyshuffle[player], world.compassshuffle[player],
world.mapshuffle[player], world.keydropshuffle[player], world.retro[player],
world.restrict_boss_items[player])
if world.doorShuffle[player] in ['vanilla', 'basic']:
limits = {}
for dungeon, info in dungeon_table.items():
val = info.free_items
if bi != 'none' and info.prize:
if bi == 'mapcompass' and (not c or not m):
val -= 1
if bi == 'dungeon' and (not c or not m or not (s or r) or not b):
val -= 1
if b:
val += 1 if info.bk_present else 0
if k:
val += 1 if info.bk_drops else 0
if s or r:
val += info.key_num
if k:
val += info.key_drops
if c:
val += 1 if info.compass_present else 0
if m:
val += 1 if info.map_present else 0
limits[dungeon] = val
else:
limits = 60
if world.bigkeyshuffle[player]:
limits += 11
if world.keydropshuffle[player]:
limits += 1
if world.keyshuffle[player] or world.retro[player]:
limits += 29
if world.keydropshuffle[player]:
limits += 32
if world.compassshuffle[player]:
limits += 11
if world.mapshuffle[player]:
limits += 12
return limits
def determine_major_items(world, player):
major_item_set = set(major_items)
if world.progressive == 'off':
@@ -454,6 +418,19 @@ def filter_locations(item_to_place, locations, world, vanilla_skip=False, potion
return locations
def filter_pot_locations(locations, world):
if world.algorithm == 'district':
config = world.item_pool_config
restricted = config.location_groups[0].locations
filtered = [l for l in locations if l.name not in restricted or l.player not in restricted[l.name]]
return filtered if len(filtered) > 0 else locations
if world.algorithm == 'vanilla_fill':
filtered = [l for l in locations if l.pot and l.pot.item in [PotItem.Chicken, PotItem.BigMagic]]
return filtered if len(filtered) > 0 else locations
return locations
vanilla_mapping = {
'Green Pendant': ['Eastern Palace - Prize'],
'Red Pendant': ['Desert Palace - Prize', 'Tower of Hera - Prize'],
@@ -615,25 +592,31 @@ vanilla_mapping = {
keydrop_vanilla_mapping = {
'Small Key (Desert Palace)': ['Desert Palace - Desert Tiles 1 Pot Key',
'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key'],
'Small Key (Eastern Palace)': ['Eastern Palace - Dark Square Pot Key', 'Eastern Palace - Dark Eyegore Key Drop'],
'Small Key (Eastern Palace)': ['Eastern Palace - Dark Eyegore Key Drop'],
'Small Key (Escape)': ['Hyrule Castle - Map Guard Key Drop', 'Hyrule Castle - Boomerang Guard Key Drop',
'Hyrule Castle - Key Rat Key Drop'],
'Big Key (Escape)': ['Hyrule Castle - Big Key Drop'],
'Small Key (Agahnims Tower)': ['Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop'],
'Small Key (Skull Woods)': ['Skull Woods - Spike Corner Key Drop'],
'Small Key (Ice Palace)': ['Ice Palace - Jelly Key Drop', 'Ice Palace - Conveyor Key Drop'],
'Small Key (Misery Mire)': ['Misery Mire - Conveyor Crystal Key Drop'],
'Small Key (Turtle Rock)': ['Turtle Rock - Pokey 1 Key Drop', 'Turtle Rock - Pokey 2 Key Drop'],
'Small Key (Ganons Tower)': ['Ganons Tower - Mini Helmasaur Key Drop'],
}
potkeys_vanilla_mapping = {
'Small Key (Desert Palace)': ['Desert Palace - Desert Tiles 1 Pot Key',
'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key'],
'Small Key (Eastern Palace)': ['Eastern Palace - Dark Square Pot Key'],
'Small Key (Thieves Town)': ["Thieves' Town - Hallway Pot Key", "Thieves' Town - Spike Switch Pot Key"],
'Small Key (Skull Woods)': ['Skull Woods - West Lobby Pot Key', 'Skull Woods - Spike Corner Key Drop'],
'Small Key (Skull Woods)': ['Skull Woods - West Lobby Pot Key'],
'Small Key (Swamp Palace)': ['Swamp Palace - Pot Row Pot Key', 'Swamp Palace - Trench 1 Pot Key',
'Swamp Palace - Hookshot Pot Key', 'Swamp Palace - Trench 2 Pot Key',
'Swamp Palace - Waterway Pot Key'],
'Small Key (Ice Palace)': ['Ice Palace - Jelly Key Drop', 'Ice Palace - Conveyor Key Drop',
'Ice Palace - Hammer Block Key Drop', 'Ice Palace - Many Pots Pot Key'],
'Small Key (Misery Mire)': ['Misery Mire - Spikes Pot Key',
'Misery Mire - Fishbone Pot Key', 'Misery Mire - Conveyor Crystal Key Drop'],
'Small Key (Turtle Rock)': ['Turtle Rock - Pokey 1 Key Drop', 'Turtle Rock - Pokey 2 Key Drop'],
'Small Key (Ice Palace)': ['Ice Palace - Hammer Block Key Drop', 'Ice Palace - Many Pots Pot Key'],
'Small Key (Misery Mire)': ['Misery Mire - Spikes Pot Key', 'Misery Mire - Fishbone Pot Key'],
'Small Key (Ganons Tower)': ['Ganons Tower - Conveyor Cross Pot Key', 'Ganons Tower - Double Switch Pot Key',
'Ganons Tower - Conveyor Star Pits Pot Key', 'Ganons Tower - Mini Helmasuar Key Drop'],
'Ganons Tower - Conveyor Star Pits Pot Key'],
}
shop_vanilla_mapping = {
@@ -682,7 +665,7 @@ mode_grouping = {
'Maze Race', 'Spectacle Rock', 'Pyramid', "Zora's Ledge", 'Lumberjack Tree',
'Sunken Treasure', 'Spectacle Rock Cave', 'Lost Woods Hideout', 'Checkerboard Cave', 'Peg Cave', 'Cave 45',
'Graveyard Cave', 'Kakariko Well - Top', "Blind's Hideout - Top", 'Bonk Rock Cave', "Aginah's Cave",
'Chest Game', 'Digging Game', 'Mire Shed - Right', 'Mimic Cave'
'Chest Game', 'Digging Game', 'Mire Shed - Left', 'Mimic Cave'
],
'Big Keys': [
'Eastern Palace - Big Key Chest', 'Ganons Tower - Big Key Chest',
@@ -735,7 +718,7 @@ mode_grouping = {
'Paradox Cave Upper - Left', 'Paradox Cave Upper - Right', 'Spiral Cave', 'Brewery', 'C-Shaped House',
'Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left', 'Hype Cave - Bottom',
'Hype Cave - Generous Guy', 'Superbunny Cave - Bottom', 'Superbunny Cave - Top', 'Hookshot Cave - Top Right',
'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left', 'Mire Shed - Left'
'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left', 'Mire Shed - Right'
],
'GT Trash': [
'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Top Left',
@@ -751,19 +734,22 @@ mode_grouping = {
],
'Key Drops': [
'Hyrule Castle - Map Guard Key Drop', 'Hyrule Castle - Boomerang Guard Key Drop',
'Hyrule Castle - Key Rat Key Drop', 'Eastern Palace - Dark Square Pot Key',
'Eastern Palace - Dark Eyegore Key Drop', 'Desert Palace - Desert Tiles 1 Pot Key',
'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key',
'Hyrule Castle - Key Rat Key Drop', 'Eastern Palace - Dark Eyegore Key Drop',
'Castle Tower - Dark Archer Key Drop', 'Castle Tower - Circle of Pots Key Drop',
'Skull Woods - Spike Corner Key Drop', 'Ice Palace - Jelly Key Drop', 'Ice Palace - Conveyor Key Drop',
'Misery Mire - Conveyor Crystal Key Drop', 'Turtle Rock - Pokey 1 Key Drop',
'Turtle Rock - Pokey 2 Key Drop', 'Ganons Tower - Mini Helmasuar Key Drop',
],
'Pot Keys': [
'Eastern Palace - Dark Square Pot Key', 'Desert Palace - Desert Tiles 1 Pot Key',
'Desert Palace - Beamos Hall Pot Key', 'Desert Palace - Desert Tiles 2 Pot Key',
'Swamp Palace - Pot Row Pot Key', 'Swamp Palace - Trench 1 Pot Key', 'Swamp Palace - Hookshot Pot Key',
'Swamp Palace - Trench 2 Pot Key', 'Swamp Palace - Waterway Pot Key', 'Skull Woods - West Lobby Pot Key',
'Skull Woods - Spike Corner Key Drop', "Thieves' Town - Hallway Pot Key",
"Thieves' Town - Spike Switch Pot Key", 'Ice Palace - Jelly Key Drop', 'Ice Palace - Conveyor Key Drop',
"Thieves' Town - Hallway Pot Key", "Thieves' Town - Spike Switch Pot Key",
'Ice Palace - Hammer Block Key Drop', 'Ice Palace - Many Pots Pot Key', 'Misery Mire - Spikes Pot Key',
'Misery Mire - Fishbone Pot Key', 'Misery Mire - Conveyor Crystal Key Drop', 'Turtle Rock - Pokey 1 Key Drop',
'Turtle Rock - Pokey 2 Key Drop', 'Ganons Tower - Conveyor Cross Pot Key',
'Misery Mire - Fishbone Pot Key', 'Ganons Tower - Conveyor Cross Pot Key',
'Ganons Tower - Double Switch Pot Key', 'Ganons Tower - Conveyor Star Pits Pot Key',
'Ganons Tower - Mini Helmasuar Key Drop',
],
'Big Key Drops': ['Hyrule Castle - Big Key Drop'],
'Shops': [
@@ -804,25 +790,24 @@ vanilla_swords = {"Link's Uncle", 'Master Sword Pedestal', 'Blacksmith', 'Pyrami
trash_items = {
'Nothing': -1,
'Bee Trap': 0,
'Rupee (1)': 1,
'Rupees (5)': 1,
'Rupees (20)': 1,
'Small Heart': 2,
'Bee': 2,
'Arrows (5)': 2,
'Chicken': 2,
'Single Bomb': 2,
'Bombs (3)': 3,
'Arrows (10)': 3,
'Bombs (10)': 3,
'Red Potion': 4,
'Blue Shield': 4,
'Rupees (50)': 4,
'Rupees (100)': 4,
'Rupee (1)': 1, 'Rupees (5)': 1, 'Small Heart': 1, 'Bee': 1, 'Arrows (5)': 1, 'Chicken': 1, 'Single Bomb': 1,
'Rupees (20)': 2, 'Small Magic': 2,
'Bombs (3)': 3, 'Arrows (10)': 3, 'Bombs (10)': 3,
'Big Magic': 4, 'Red Potion': 4, 'Blue Shield': 4, 'Rupees (50)': 4, 'Rupees (100)': 4,
'Rupees (300)': 5,
'Piece of Heart': 17
}
pot_items = {
PotItem.Nothing: 'Nothing',
PotItem.Bomb: 'Single Bomb',
PotItem.FiveArrows: 'Arrows (5)', # convert to 10
PotItem.OneRupee: 'Rupee (1)',
PotItem.FiveRupees: 'Rupees (5)',
PotItem.Heart: 'Small Heart',
PotItem.BigMagic: 'Big Magic', # fast fill
PotItem.SmallMagic: 'Small Magic',
PotItem.Chicken: 'Chicken' # fast fill
}
valid_pot_items = {y: x for x, y in pot_items.items()}