Merge remote-tracking branch 'origin' into OverworldShuffle

This commit is contained in:
2023-09-04 18:35:36 -05:00
76 changed files with 4251 additions and 2604 deletions

49
Main.py
View File

@@ -36,7 +36,9 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
from source.tools.BPS import create_bps_from_data
from source.classes.CustomSettings import CustomSettings
__version__ = '1.2.0.9-u'
version_number = '1.2.0.20'
version_branch = '-u'
__version__ = f'{version_number}{version_branch}'
from source.classes.BabelFish import BabelFish
@@ -147,6 +149,7 @@ def main(args, seed=None, fish=None):
world.trap_door_mode = args.trap_door_mode.copy()
world.key_logic_algorithm = args.key_logic_algorithm.copy()
world.decoupledoors = args.decoupledoors.copy()
world.door_self_loops = args.door_self_loops.copy()
world.experimental = args.experimental.copy()
world.dungeon_counters = args.dungeon_counters.copy()
world.fish = fish
@@ -156,8 +159,6 @@ def main(args, seed=None, fish=None):
world.potshuffle = args.shufflepots.copy()
world.mixed_travel = args.mixed_travel.copy()
world.standardize_palettes = args.standardize_palettes.copy()
world.treasure_hunt_count = {k: int(v) for k, v in args.triforce_goal.items()}
world.treasure_hunt_total = {k: int(v) for k, v in args.triforce_pool.items()}
world.shufflelinks = args.shufflelinks.copy()
world.shuffletavern = args.shuffletavern.copy()
world.pseudoboots = args.pseudoboots.copy()
@@ -166,7 +167,26 @@ def main(args, seed=None, fish=None):
world.restrict_boss_items = args.restrict_boss_items.copy()
world.collection_rate = args.collection_rate.copy()
world.colorizepots = args.colorizepots.copy()
world.trolls = args.trolls.copy()
world.treasure_hunt_count = {}
world.treasure_hunt_total = {}
for p in args.triforce_goal:
if int(args.triforce_goal[p]) != 0 or int(args.triforce_pool[p]) != 0 or int(args.triforce_goal_min[p]) != 0 or int(args.triforce_goal_max[p]) != 0 or int(args.triforce_pool_min[p]) != 0 or int(args.triforce_pool_max[p]) != 0:
if int(args.triforce_goal[p]) != 0:
world.treasure_hunt_count[p] = int(args.triforce_goal[p])
elif int(args.triforce_goal_min[p]) != 0 and int(args.triforce_goal_max[p]) != 0:
world.treasure_hunt_count[p] = random.randint(int(args.triforce_goal_min[p]), int(args.triforce_goal_max[p]))
else:
world.treasure_hunt_count[p] = 8 if world.goal[p] == 'trinity' else 20
if int(args.triforce_pool[p]) != 0:
world.treasure_hunt_total[p] = int(args.triforce_pool[p])
elif int(args.triforce_pool_min[p]) != 0 and int(args.triforce_pool_max[p]) != 0:
world.treasure_hunt_total[p] = random.randint(max(int(args.triforce_pool_min[p]), world.treasure_hunt_count[p] + int(args.triforce_min_difference[p])), min(int(args.triforce_pool_max[p]), world.treasure_hunt_count[p] + int(args.triforce_max_difference[p])))
else:
world.treasure_hunt_total[p] = 10 if world.goal[p] == 'trinity' else 30
else:
# this will be handled in ItemList.py and custom item pool is used to determine the numbers
world.treasure_hunt_count[p], world.treasure_hunt_total[p] = 0, 0
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
world.finish_init()
@@ -191,7 +211,7 @@ def main(args, seed=None, fish=None):
world.player_names[player].append(name)
logger.info('')
world.settings = CustomSettings()
world.settings.create_from_world(world, args.race)
world.settings.create_from_world(world, args)
outfilebase = f'OR_{args.outputname if args.outputname else world.seed}'
@@ -253,6 +273,8 @@ def main(args, seed=None, fish=None):
update_world_regions(world, player)
mark_light_dark_world_regions(world, player)
create_dynamic_exits(world, player)
if args.print_custom_yaml:
world.settings.record_overworld(world)
init_districts(world)
@@ -293,6 +315,8 @@ def main(args, seed=None, fish=None):
set_rules(world, player)
district_item_pool_config(world)
dungeon_tracking(world)
fill_specific_items(world)
for player in range(1, world.players + 1):
if world.shopsanity[player]:
sell_potions(world, player)
@@ -304,9 +328,6 @@ def main(args, seed=None, fish=None):
massage_item_pool(world)
if args.print_custom_yaml:
world.settings.record_item_pool(world)
dungeon_tracking(world)
fill_specific_items(world)
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
fill_prizes(world)
@@ -528,6 +549,7 @@ def copy_world(world):
ret.beemizer = world.beemizer.copy()
ret.intensity = world.intensity.copy()
ret.decoupledoors = world.decoupledoors.copy()
ret.door_self_loops = world.door_self_loops.copy()
ret.experimental = world.experimental.copy()
ret.shopsanity = world.shopsanity.copy()
ret.dropshuffle = world.dropshuffle.copy()
@@ -540,7 +562,6 @@ def copy_world(world):
ret.prizes = world.prizes.copy()
ret.restrict_boss_items = world.restrict_boss_items.copy()
ret.inaccessible_regions = world.inaccessible_regions.copy()
ret.trolls = world.trolls.copy()
for player in range(1, world.players + 1):
create_regions(ret, player)
@@ -717,7 +738,6 @@ def copy_world_premature(world, player):
ret.prizes = world.prizes.copy()
ret.restrict_boss_items = world.restrict_boss_items.copy()
ret.key_logic = world.key_logic.copy()
ret.trolls = world.trolls.copy()
ret.is_copied_world = True
@@ -816,8 +836,8 @@ def create_playthrough(world):
# get locations containing progress items
prog_locations = [location for location in world.get_filled_locations() if location.item.advancement
or world.goal[location.player] == 'completionist']
optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop', 'Skull Star Tile']
optional_locations.extend(['Hyrule Castle Courtyard Tree Pull', 'Mountain Entry Area Tree Pull']) # adding pre-aga tree pulls
optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop', 'Skull Star Tile', 'Flute Activation']
optional_locations.extend(['Hyrule Castle Courtyard Tree Pull', 'Mountain Pass Area Tree Pull']) # adding pre-aga tree pulls
optional_locations.extend(['Lumberjack Area Crab Drop', 'South Pass Area Crab Drop']) # adding pre-aga bush crabs
state_cache = [None]
collection_spheres = []
@@ -843,7 +863,9 @@ def create_playthrough(world):
logging.getLogger('').debug(world.fish.translate("cli", "cli", "building.calculating.spheres"), len(collection_spheres), len(sphere), len(prog_locations))
if not sphere:
logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
if world.accessibility[location.item.player] != 'none':
logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"),
[world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
if any([location.name not in optional_locations and world.accessibility[location.item.player] != 'none' for location in sphere_candidates]):
raise RuntimeError(world.fish.translate("cli", "cli", "cannot.reach.progression"))
else:
@@ -906,6 +928,7 @@ def create_playthrough(world):
if world.has_beaten_game(state):
required_locations.clear()
else:
logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (loc.item.name, loc.item.player, loc.name, loc.player) for loc in required_locations])
raise RuntimeError(world.fish.translate("cli","cli","cannot.reach.required"))
# store the required locations for statistical analysis