forked from mirror/Archipelago
Merge branch 'main' into kvui_fixed_dpi
This commit is contained in:
+1
-5
@@ -49,7 +49,7 @@ class ThreadBarrierProxy:
|
||||
return getattr(self.obj, name)
|
||||
else:
|
||||
raise RuntimeError("You are in a threaded context and global random state was removed for your safety. "
|
||||
"Please use multiworld.per_slot_randoms[player] or randomize ahead of output.")
|
||||
"Please use world.random or randomize ahead of output.")
|
||||
|
||||
|
||||
class HasNameAndPlayer(Protocol):
|
||||
@@ -100,8 +100,6 @@ class MultiWorld():
|
||||
game: Dict[int, str]
|
||||
|
||||
random: random.Random
|
||||
per_slot_randoms: Utils.DeprecateDict[int, random.Random]
|
||||
"""Deprecated. Please use `self.random` instead."""
|
||||
|
||||
class AttributeProxy():
|
||||
def __init__(self, rule):
|
||||
@@ -177,8 +175,6 @@ class MultiWorld():
|
||||
set_player_attr('game', "Archipelago")
|
||||
set_player_attr('completion_condition', lambda state: True)
|
||||
self.worlds = {}
|
||||
self.per_slot_randoms = Utils.DeprecateDict("Using per_slot_randoms is now deprecated. Please use the "
|
||||
"world's random object instead (usually self.random)", True)
|
||||
self.plando_options = PlandoOptions.none
|
||||
|
||||
def get_all_ids(self) -> Tuple[int, ...]:
|
||||
|
||||
@@ -1012,23 +1012,6 @@ def deprecate(message: str, add_stacklevels: int = 0):
|
||||
warnings.warn(message, stacklevel=2 + add_stacklevels)
|
||||
|
||||
|
||||
class DeprecateDict(dict):
|
||||
log_message: str
|
||||
should_error: bool
|
||||
|
||||
def __init__(self, message: str, error: bool = False) -> None:
|
||||
self.log_message = message
|
||||
self.should_error = error
|
||||
super().__init__()
|
||||
|
||||
def __getitem__(self, item: Any) -> Any:
|
||||
if self.should_error:
|
||||
deprecate(self.log_message, add_stacklevels=1)
|
||||
elif __debug__:
|
||||
warnings.warn(self.log_message, stacklevel=2)
|
||||
return super().__getitem__(item)
|
||||
|
||||
|
||||
def _extend_freeze_support() -> None:
|
||||
"""Extend multiprocessing.freeze_support() to also work on Non-Windows and without setting spawn method first."""
|
||||
# original upstream issue: https://github.com/python/cpython/issues/76327
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ jinja2==3.1.6
|
||||
schema==0.7.8
|
||||
kivy==2.3.1
|
||||
bsdiff4==1.2.6
|
||||
platformdirs==4.9.4
|
||||
platformdirs==4.10.1
|
||||
certifi==2026.2.25
|
||||
cython==3.2.4
|
||||
cymem==2.0.13
|
||||
|
||||
@@ -115,6 +115,7 @@ class TestGenerateWeights(TestGenerateMain):
|
||||
settings = get_settings()
|
||||
settings.generator.player_files_path = settings.generator.PlayerFilesPath(self.yaml_input_dir)
|
||||
settings.generator.players = 5 # arbitrary number, should be enough
|
||||
settings.generator.race = 0 # make sure race mode is disabled so the below seed is actually respected
|
||||
settings._filename = None
|
||||
user_path_backup = user_path.cached_path
|
||||
user_path.cached_path = local_path()
|
||||
|
||||
@@ -363,7 +363,6 @@ class World(metaclass=AutoWorldRegister):
|
||||
self.multiworld = multiworld
|
||||
self.player = player
|
||||
self.random = Random(multiworld.random.getrandbits(64))
|
||||
multiworld.per_slot_randoms[player] = self.random
|
||||
|
||||
def __getattr__(self, item: str) -> Any:
|
||||
if item == "settings":
|
||||
|
||||
@@ -405,7 +405,6 @@ if not is_frozen():
|
||||
|
||||
from worlds import AutoWorldRegister
|
||||
from worlds.Files import APWorldContainer
|
||||
from Launcher import open_folder
|
||||
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(prog="Build APWorlds", description="Build script for APWorlds")
|
||||
|
||||
@@ -19,7 +19,7 @@ from .rules import MessengerHardRules, MessengerOOBRules, MessengerRules
|
||||
from .shop import FIGURINES, PROG_SHOP_ITEMS, SHOP_ITEMS, USEFUL_SHOP_ITEMS, shuffle_shop_prices
|
||||
from .subclasses import MessengerItem, MessengerRegion, MessengerShopLocation
|
||||
from .transitions import disconnect_entrances, shuffle_transitions
|
||||
from .universal_tracker import reverse_portal_exits_into_portal_plando, reverse_transitions_into_plando_connections
|
||||
from .universal_tracker import reverse_portal_exits_into_portal_plando, reverse_shop_prices, reverse_transitions_into_plando_connections
|
||||
|
||||
components.append(
|
||||
Component(
|
||||
@@ -169,7 +169,11 @@ class MessengerWorld(World):
|
||||
if self.options.early_meditation:
|
||||
self.multiworld.early_items[self.player]["Meditation"] = 1
|
||||
|
||||
self.shop_prices, self.figurine_prices = shuffle_shop_prices(self)
|
||||
if not hasattr(self.multiworld, "re_gen_passthrough"):
|
||||
self.shop_prices, self.figurine_prices = shuffle_shop_prices(self)
|
||||
else:
|
||||
if slot_data := self.multiworld.re_gen_passthrough.get(self.game):
|
||||
self.shop_prices, self.figurine_prices = reverse_shop_prices(slot_data["shop"], slot_data["figures"])
|
||||
|
||||
starting_portals = ["Autumn Hills", "Howling Grotto", "Glacial Peak", "Riviere Turquoise", "Sunken Shrine",
|
||||
"Searing Crags"]
|
||||
@@ -276,6 +280,10 @@ class MessengerWorld(World):
|
||||
|
||||
self.multiworld.itempool += filler
|
||||
|
||||
if hasattr(self.multiworld, "re_gen_passthrough"):
|
||||
if slot_data := self.multiworld.re_gen_passthrough.get(self.game):
|
||||
self.total_shards = slot_data["max_price"]
|
||||
|
||||
def set_rules(self) -> None:
|
||||
logic = self.options.logic_level
|
||||
if logic == Logic.option_normal:
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from Options import PlandoConnection
|
||||
from .connections import RANDOMIZED_CONNECTIONS
|
||||
from .portals import REGION_ORDER, SHOP_POINTS, CHECKPOINTS
|
||||
from .shop import FIGURINES, SHOP_ITEMS
|
||||
from .transitions import TRANSITIONS
|
||||
|
||||
REVERSED_RANDOMIZED_CONNECTIONS = {v: k for k, v in RANDOMIZED_CONNECTIONS.items()}
|
||||
REVERSED_SHOP_ITEMS = {v.internal_name: k for k, v in (SHOP_ITEMS | FIGURINES).items()}
|
||||
|
||||
|
||||
def find_spot(portal_key: int) -> str:
|
||||
@@ -26,6 +28,14 @@ def reverse_portal_exits_into_portal_plando(portal_exits: list[int]) -> list[Pla
|
||||
PlandoConnection("Glacial Peak", find_spot(portal_exits[5]), "both"),
|
||||
]
|
||||
|
||||
def reverse_shop_prices(
|
||||
shop_prices: dict[str, int], figures_prices: dict[str, int]
|
||||
) -> tuple[dict[str, int], dict[str, int]]:
|
||||
return (
|
||||
{REVERSED_SHOP_ITEMS[item_internal_name]: price for item_internal_name, price in shop_prices.items()},
|
||||
{REVERSED_SHOP_ITEMS[item_internal_name]: price for item_internal_name, price in figures_prices.items()},
|
||||
)
|
||||
|
||||
|
||||
def reverse_transitions_into_plando_connections(transitions: list[list[int]]) -> list[PlandoConnection]:
|
||||
plando_connections = []
|
||||
|
||||
@@ -91,6 +91,7 @@ class SC2World(World):
|
||||
game = "Starcraft 2"
|
||||
web = Starcraft2WebWorld()
|
||||
settings: ClassVar[settings.Starcraft2Settings]
|
||||
disable_ut = True
|
||||
|
||||
item_name_to_id = {name: data.code for name, data in get_full_item_list().items()}
|
||||
location_name_to_id = {location.name: location.code for location in DEFAULT_LOCATION_LIST}
|
||||
@@ -433,7 +434,7 @@ def create_and_flag_explicit_item_locks_and_excludes(world: SC2World) -> List[Fi
|
||||
if max_count and count > max_count:
|
||||
return max_count
|
||||
return count
|
||||
|
||||
|
||||
auto_excludes = Counter({item_name: 1 for item_name in item_groups.legacy_items})
|
||||
if world.options.exclude_overpowered_items.value == ExcludeOverpoweredItems.option_true:
|
||||
for item_name in item_groups.overpowered_items:
|
||||
@@ -1066,7 +1067,7 @@ def fill_pool_with_kerrigan_levels(world: SC2World, item_pool: List[StarcraftIte
|
||||
or (world.options.grant_story_levels and not kerrigan_build_missions)
|
||||
):
|
||||
return
|
||||
|
||||
|
||||
def add_kerrigan_level_items(level_amount: int, item_amount: int):
|
||||
name = f"{level_amount} Kerrigan Level"
|
||||
if level_amount > 1:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import logging
|
||||
from typing import Callable, Dict, List, Set, Tuple, TYPE_CHECKING, Iterable
|
||||
from collections import Counter
|
||||
|
||||
from BaseClasses import Location, ItemClassification
|
||||
from .item import StarcraftItem, ItemFilterFlags, item_names, item_parents, item_groups
|
||||
@@ -110,7 +111,7 @@ class ValidInventory:
|
||||
self.player = world.player
|
||||
self.world: 'SC2World' = world
|
||||
# Track all Progression items and those with complex rules for filtering
|
||||
self.logical_inventory: Dict[str, int] = {}
|
||||
self.logical_inventory: Counter[str] = Counter()
|
||||
for item in item_pool:
|
||||
if not item_table[item.name].is_important_for_filtering():
|
||||
continue
|
||||
@@ -125,13 +126,13 @@ class ValidInventory:
|
||||
self.item_name_to_child_items.setdefault(parent_item, []).append(item)
|
||||
|
||||
def has(self, item: str, player: int, count: int = 1) -> bool:
|
||||
return self.logical_inventory.get(item, 0) >= count
|
||||
return self.logical_inventory[item] >= count
|
||||
|
||||
def has_any(self, items: Set[str], player: int) -> bool:
|
||||
return any(self.logical_inventory.get(item) for item in items)
|
||||
return any(self.logical_inventory[item] for item in items)
|
||||
|
||||
def has_all(self, items: Set[str], player: int) -> bool:
|
||||
return all(self.logical_inventory.get(item) for item in items)
|
||||
return all(self.logical_inventory[item] for item in items)
|
||||
|
||||
def has_group(self, item_group: str, player: int, count: int = 1) -> bool:
|
||||
return False # Deliberately fails here, as item pooling is not aware about mission layout
|
||||
@@ -140,13 +141,17 @@ class ValidInventory:
|
||||
return 0 # For item filtering assume no missions are beaten
|
||||
|
||||
def count(self, item: str, player: int) -> int:
|
||||
return self.logical_inventory.get(item, 0)
|
||||
return self.logical_inventory[item]
|
||||
|
||||
def count_from_list(self, items: Iterable[str], player: int) -> int:
|
||||
return sum(self.logical_inventory.get(item, 0) for item in items)
|
||||
return sum(self.logical_inventory[item] for item in items)
|
||||
|
||||
def count_from_list_unique(self, items: Iterable[str], player: int) -> int:
|
||||
return sum(item in self.logical_inventory for item in items)
|
||||
result = 0
|
||||
for item in items:
|
||||
if self.logical_inventory[item] > 0:
|
||||
result += 1
|
||||
return result
|
||||
|
||||
def generate_reduced_inventory(self, inventory_size: int, filler_amount: int, mission_requirements: List[Tuple[str, Callable]]) -> List[StarcraftItem]:
|
||||
"""Attempts to generate a reduced inventory that can fulfill the mission requirements."""
|
||||
|
||||
Reference in New Issue
Block a user