Merge branch 'main' into breaking_changes

# Conflicts:
#	BaseClasses.py
#	Mystery.py
#	WebHostLib/downloads.py
#	WebHostLib/models.py
#	WebHostLib/templates/macros.html
#	WebHostLib/upload.py
#	worlds/alttp/ItemPool.py
#	worlds/alttp/Main.py
This commit is contained in:
Fabian Dill
2021-01-17 06:50:25 +01:00
35 changed files with 965 additions and 187 deletions

View File

@@ -18,7 +18,7 @@ from worlds.alttp.EntranceShuffle import link_entrances, link_inverted_entrances
from worlds.alttp.Rom import patch_rom, patch_race_rom, patch_enemizer, apply_rom_settings, LocalRom, get_hash_string
from worlds.alttp.Rules import set_rules
from worlds.alttp.Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression
from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression, distribute_planned
from worlds.alttp.ItemPool import generate_itempool, difficulties, fill_prizes
from Utils import output_path, parse_player_names, get_options, __version__, _version_tuple
import Patch
@@ -120,6 +120,11 @@ def main(args, seed=None):
item.strip() in item_table}
world.non_local_items[player] = {item.strip() for item in args.non_local_items[player].split(',') if
item.strip() in item_table}
# enforce pre-defined local items.
if world.goal[player] in ["localtriforcehunt", "localganontriforcehunt"]:
world.local_items[player].add('Triforce Piece')
# items can't be both local and non-local, prefer local
world.non_local_items[player] -= world.local_items[player]
@@ -180,42 +185,7 @@ def main(args, seed=None):
logger.info("Running Item Plando")
world_name_lookup = {world.player_names[player_id][0]: player_id for player_id in world.player_ids}
for player in world.player_ids:
placement: PlandoItem
for placement in world.plando_items[player]:
target_world: int = placement.world
if target_world is False or world.players == 1:
target_world = player # in own world
elif target_world is True: # in any other world
target_world = player
while target_world == player:
target_world = world.random.randint(1, world.players + 1)
elif target_world is None: # any random world
target_world = world.random.randint(1, world.players + 1)
elif type(target_world) == int: # target world by player id
pass
else: # find world by name
target_world = world_name_lookup[target_world]
location = world.get_location(placement.location, target_world)
if location.item:
raise Exception(f"Cannot place item into already filled location {location}.")
item = ItemFactory(placement.item, player)
if placement.from_pool:
try:
world.itempool.remove(item)
except ValueError:
logger.warning(f"Could not remove {item} from pool as it's already missing from it.")
if location.can_fill(world.state, item, False):
world.push_item(location, item, collect=False)
location.event = True # flag location to be checked during fill
location.locked = True
logger.debug(f"Plando placed {item} at {location}")
else:
raise Exception(f"Can't place {item} at {location} due to fill condition not met.")
distribute_planned(world)
logger.info('Placing Dungeon Items.')
@@ -343,6 +313,7 @@ def main(args, seed=None):
pool = concurrent.futures.ThreadPoolExecutor()
multidata_task = None
check_beatability_task = pool.submit(world.can_beat_game)
if not args.suppress_rom:
rom_futures = []
@@ -427,7 +398,8 @@ def main(args, seed=None):
f.write(multidata)
multidata_task = pool.submit(write_multidata, rom_futures)
if not check_beatability_task.result():
raise Exception("Game appears unbeatable. Aborting.")
if not args.skip_playthrough:
logger.info('Calculating playthrough.')
create_playthrough(world)
@@ -573,10 +545,6 @@ def create_playthrough(world):
old_world = world
world = copy_world(world)
# if we only check for beatable, we can do this sanity check first before writing down spheres
if not world.can_beat_game():
raise RuntimeError('Cannot beat game. Something went terribly wrong here!')
# get locations containing progress items
prog_locations = [location for location in world.get_filled_locations() if location.item.advancement]
state_cache = [None]