Merge branch 'main' into player-tracker

This commit is contained in:
Chris Wilson
2022-09-24 18:35:59 -04:00
144 changed files with 4851 additions and 3263 deletions

View File

@@ -4,6 +4,7 @@ import random
import threading
import typing
import Utils
from BaseClasses import Item, CollectionState, Tutorial
from .Dungeons import create_dungeons
from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect
@@ -11,7 +12,8 @@ from .InvertedRegions import create_inverted_regions, mark_dark_world_regions
from .ItemPool import generate_itempool, difficulties
from .Items import item_init_table, item_name_groups, item_table, GetBeemizerItem
from .Options import alttp_options, smallkey_shuffle
from .Regions import lookup_name_to_id, create_regions, mark_light_world_regions
from .Regions import lookup_name_to_id, create_regions, mark_light_world_regions, lookup_vanilla_location_to_entrance, \
is_main_entrance
from .Rom import LocalRom, patch_rom, patch_race_rom, check_enemizer, patch_enemizer, apply_rom_settings, \
get_hash_string, get_base_rom_path, LttPDeltaPatch
from .Rules import set_rules
@@ -23,6 +25,7 @@ lttp_logger = logging.getLogger("A Link to the Past")
extras_list = sum(difficulties['normal'].extras[0:5], [])
class ALTTPWeb(WebWorld):
setup_en = Tutorial(
"Multiworld Setup Tutorial",
@@ -362,6 +365,10 @@ class ALTTPWorld(World):
create_items = generate_itempool
enemizer_path: str = Utils.get_options()["generator"]["enemizer_path"] \
if os.path.isabs(Utils.get_options()["generator"]["enemizer_path"]) \
else Utils.local_path(Utils.get_options()["generator"]["enemizer_path"])
def __init__(self, *args, **kwargs):
self.dungeon_local_item_names = set()
self.dungeon_specific_item_names = set()
@@ -376,12 +383,12 @@ class ALTTPWorld(World):
raise FileNotFoundError(rom_file)
def generate_early(self):
if self.use_enemizer():
check_enemizer(self.enemizer_path)
player = self.player
world = self.world
if self.use_enemizer():
check_enemizer(world.enemizer)
# system for sharing ER layouts
self.er_seed = str(world.random.randint(0, 2 ** 64))
@@ -570,7 +577,7 @@ class ALTTPWorld(World):
def use_enemizer(self):
world = self.world
player = self.player
return (world.boss_shuffle[player] != 'none' or world.enemy_shuffle[player]
return (world.boss_shuffle[player] or world.enemy_shuffle[player]
or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default'
or world.pot_shuffle[player] or world.bush_shuffle[player]
or world.killable_thieves[player])
@@ -586,7 +593,7 @@ class ALTTPWorld(World):
patch_rom(world, rom, player, use_enemizer)
if use_enemizer:
patch_enemizer(world, player, rom, world.enemizer, output_directory)
patch_enemizer(world, player, rom, self.enemizer_path, output_directory)
if world.is_race:
patch_race_rom(rom, world, player)
@@ -599,7 +606,7 @@ class ALTTPWorld(World):
'hud': world.hud_palettes[player],
'sword': world.sword_palettes[player],
'shield': world.shield_palettes[player],
'link': world.link_palettes[player]
# 'link': world.link_palettes[player]
}
palettes_options = {key: option.current_key for key, option in palettes_options.items()}
@@ -631,6 +638,20 @@ class ALTTPWorld(World):
finally:
self.rom_name_available_event.set() # make sure threading continues and errors are collected
@classmethod
def stage_extend_hint_information(cls, world, hint_data: typing.Dict[int, typing.Dict[int, str]]):
er_hint_data = {player: {} for player in world.get_game_players("A Link to the Past") if
world.shuffle[player] != "vanilla" or world.retro_caves[player]}
for region in world.regions:
if region.player in er_hint_data and region.locations:
main_entrance = region.get_connecting_entrance(is_main_entrance)
for location in region.locations:
if type(location.address) == int: # skips events and crystals
if lookup_vanilla_location_to_entrance[location.address] != main_entrance.name:
er_hint_data[region.player][location.address] = main_entrance.name
hint_data.update(er_hint_data)
def modify_multidata(self, multidata: dict):
import base64
# wait for self.rom_name to be available.
@@ -645,8 +666,7 @@ class ALTTPWorld(World):
return ALttPItem(name, self.player, **item_init_table[name])
@classmethod
def stage_fill_hook(cls, world, progitempool, nonexcludeditempool, localrestitempool, nonlocalrestitempool,
restitempool, fill_locations):
def stage_fill_hook(cls, world, progitempool, usefulitempool, filleritempool, fill_locations):
trash_counts = {}
standard_keyshuffle_players = set()
for player in world.get_game_players("A Link to the Past"):
@@ -693,26 +713,15 @@ class ALTTPWorld(World):
for player, trash_count in trash_counts.items():
gtower_locations = locations_mapping[player]
world.random.shuffle(gtower_locations)
localrest = localrestitempool[player]
if localrest:
gt_item_pool = restitempool + localrest
world.random.shuffle(gt_item_pool)
else:
gt_item_pool = restitempool.copy()
while gtower_locations and gt_item_pool and trash_count > 0:
while gtower_locations and filleritempool and trash_count > 0:
spot_to_fill = gtower_locations.pop()
item_to_place = gt_item_pool.pop()
item_to_place = filleritempool.pop()
if spot_to_fill.item_rule(item_to_place):
if item_to_place in localrest:
localrest.remove(item_to_place)
else:
restitempool.remove(item_to_place)
world.push_item(spot_to_fill, item_to_place, False)
fill_locations.remove(spot_to_fill) # very slow, unfortunately
trash_count -= 1
def get_filler_item_name(self) -> str:
if self.world.goal[self.player] == "icerodhunt":
item = "Nothing"