From 4d174c441e5f211ec4c77aeedb6da660afb0f4be Mon Sep 17 00:00:00 2001 From: Gandalf-The-It-Wizard Date: Sun, 7 Jun 2026 10:05:55 +0000 Subject: [PATCH 1/5] Add unlockable hearts option --- README.md | 6 + apworld_src/minecraft/Constants.py | 20 + apworld_src/minecraft/Container.py | 31 + apworld_src/minecraft/ItemPool.py | 59 + apworld_src/minecraft/MinecraftClient.py | 754 ++++++++ apworld_src/minecraft/Options.py | 149 ++ apworld_src/minecraft/Rules.py | 690 +++++++ apworld_src/minecraft/Structures.py | 67 + apworld_src/minecraft/__init__.py | 280 +++ apworld_src/minecraft/archipelago.json | 1 + apworld_src/minecraft/assets/delete.png | Bin 0 -> 501 bytes apworld_src/minecraft/assets/edit.png | Bin 0 -> 455 bytes apworld_src/minecraft/assets/icon.png | Bin 0 -> 594 bytes apworld_src/minecraft/assets/mcicon.png | Bin 0 -> 594 bytes .../minecraft/data/excluded_locations.json | 47 + apworld_src/minecraft/data/items.json | 142 ++ apworld_src/minecraft/data/locations.json | 304 +++ apworld_src/minecraft/data/regions.json | 38 + apworld_src/minecraft/docs/en_Minecraft.md | 132 ++ apworld_src/minecraft/docs/minecraft_en.md | 92 + apworld_src/minecraft/docs/minecraft_es.md | 148 ++ apworld_src/minecraft/docs/minecraft_fr.md | 74 + apworld_src/minecraft/docs/minecraft_sv.md | 132 ++ apworld_src/minecraft/downloader/Java.py | 148 ++ apworld_src/minecraft/downloader/Modrinth.py | 56 + apworld_src/minecraft/downloader/NeoForge.py | 166 ++ apworld_src/minecraft/downloader/Utilities.py | 193 ++ apworld_src/minecraft/downloader/__init__.py | 127 ++ apworld_src/minecraft/layouts/minecraft.kv | 312 +++ apworld_src/minecraft/test/__init__.py | 0 apworld_src/minecraft/test/bases.py | 99 + .../minecraft/test/test_advancements.py | 1722 +++++++++++++++++ apworld_src/minecraft/test/test_data_load.py | 60 + apworld_src/minecraft/test/test_entrances.py | 97 + apworld_src/minecraft/test/test_options.py | 63 + gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 46175 bytes gradlew | 0 minecraft.apworld | Bin 0 -> 61552 bytes .../aprandomizer/archipelago_item/heart.json | 5 + .../gg/archipelago/aprandomizer/SlotData.java | 3 + .../aprandomizer/ap/storage/APMCData.java | 3 + .../common/Utils/UnlockableHearts.java | 43 + .../common/commands/StartCommand.java | 7 +- .../aprandomizer/common/events/OnJoin.java | 5 + .../aprandomizer/items/APItems.java | 5 + .../aprandomizer/items/APRewardTypes.java | 1 + .../aprandomizer/items/HeartReward.java | 19 + .../managers/itemmanager/ItemManager.java | 1 + 48 files changed, 6300 insertions(+), 1 deletion(-) create mode 100644 apworld_src/minecraft/Constants.py create mode 100644 apworld_src/minecraft/Container.py create mode 100644 apworld_src/minecraft/ItemPool.py create mode 100644 apworld_src/minecraft/MinecraftClient.py create mode 100644 apworld_src/minecraft/Options.py create mode 100644 apworld_src/minecraft/Rules.py create mode 100644 apworld_src/minecraft/Structures.py create mode 100644 apworld_src/minecraft/__init__.py create mode 100644 apworld_src/minecraft/archipelago.json create mode 100644 apworld_src/minecraft/assets/delete.png create mode 100644 apworld_src/minecraft/assets/edit.png create mode 100644 apworld_src/minecraft/assets/icon.png create mode 100644 apworld_src/minecraft/assets/mcicon.png create mode 100644 apworld_src/minecraft/data/excluded_locations.json create mode 100644 apworld_src/minecraft/data/items.json create mode 100644 apworld_src/minecraft/data/locations.json create mode 100644 apworld_src/minecraft/data/regions.json create mode 100644 apworld_src/minecraft/docs/en_Minecraft.md create mode 100644 apworld_src/minecraft/docs/minecraft_en.md create mode 100644 apworld_src/minecraft/docs/minecraft_es.md create mode 100644 apworld_src/minecraft/docs/minecraft_fr.md create mode 100644 apworld_src/minecraft/docs/minecraft_sv.md create mode 100644 apworld_src/minecraft/downloader/Java.py create mode 100644 apworld_src/minecraft/downloader/Modrinth.py create mode 100644 apworld_src/minecraft/downloader/NeoForge.py create mode 100644 apworld_src/minecraft/downloader/Utilities.py create mode 100644 apworld_src/minecraft/downloader/__init__.py create mode 100644 apworld_src/minecraft/layouts/minecraft.kv create mode 100644 apworld_src/minecraft/test/__init__.py create mode 100644 apworld_src/minecraft/test/bases.py create mode 100644 apworld_src/minecraft/test/test_advancements.py create mode 100644 apworld_src/minecraft/test/test_data_load.py create mode 100644 apworld_src/minecraft/test/test_entrances.py create mode 100644 apworld_src/minecraft/test/test_options.py mode change 100644 => 100755 gradlew create mode 100644 minecraft.apworld create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/archipelago_item/heart.json create mode 100644 src/main/java/gg/archipelago/aprandomizer/common/Utils/UnlockableHearts.java create mode 100644 src/main/java/gg/archipelago/aprandomizer/items/HeartReward.java diff --git a/README.md b/README.md index 860499e..062c8c5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ Original (Forge) Implementation by KonoTyran. ## Configuring your YAML file +### Unlockable Hearts + +This fork adds an `unlockable_hearts` option to the Minecraft APWorld. When enabled, players start with one heart, and nine progression `Heart` items are added to the item pool. Each received `Heart` restores one additional max heart up to the vanilla ten hearts. + +Use the packaged `minecraft.apworld` from this repository together with the matching NeoForgeAP mod jar built from this branch. + ### What is a YAML file and why do I need one? See the guide on setting up a basic YAML at the Archipelago setup diff --git a/apworld_src/minecraft/Constants.py b/apworld_src/minecraft/Constants.py new file mode 100644 index 0000000..6a296d9 --- /dev/null +++ b/apworld_src/minecraft/Constants.py @@ -0,0 +1,20 @@ +import json +import pkgutil + + +def load_data_file(*args) -> dict: + fname = "/".join(["data", *args]) + return json.loads(pkgutil.get_data(__name__, fname).decode()) + + +item_info = load_data_file("items.json") +item_name_to_id = {name: index \ + for index, name in enumerate(item_info["all_items"], start=1)} + +location_info = load_data_file("locations.json") +location_name_to_id = {name: index \ + for index, name in enumerate(location_info["all_locations"], start=1)} + +exclusion_info = load_data_file("excluded_locations.json") + +region_info = load_data_file("regions.json") diff --git a/apworld_src/minecraft/Container.py b/apworld_src/minecraft/Container.py new file mode 100644 index 0000000..2d8cc8b --- /dev/null +++ b/apworld_src/minecraft/Container.py @@ -0,0 +1,31 @@ +import json +import zipfile +from base64 import b64encode +from typing import Any, Optional + +from worlds.Files import APPlayerContainer + + +class MinecraftContainer(APPlayerContainer): + """ + Generates the apmc file + """ + game = "Minecraft" + patch_file_ending = ".apmc" + + def __init__(self, + patch_data: dict[str, Any], + patch_name: str, + path: Optional[str] = None, + player: Optional[int] = None, + player_name: str = "", + server: str = ""): + super().__init__(path, player, player_name, server) + self.patch_data = patch_data + self.patch_name = patch_name + + def write_contents(self, opened_zipfile: zipfile.ZipFile) -> None: + super().write_contents(opened_zipfile) + filename = f"{self.patch_name}_json.apmcmeta" + opened_zipfile.writestr(filename,json.dumps(self.patch_data)) + diff --git a/apworld_src/minecraft/ItemPool.py b/apworld_src/minecraft/ItemPool.py new file mode 100644 index 0000000..677029c --- /dev/null +++ b/apworld_src/minecraft/ItemPool.py @@ -0,0 +1,59 @@ +from math import ceil +from typing import List + +from BaseClasses import Item + +from . import Constants +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from . import MinecraftWorld + + +def get_junk_item_names(rand, k: int) -> str: + junk_weights = Constants.item_info["junk_weights"] + junk = rand.choices( + list(junk_weights.keys()), + weights=list(junk_weights.values()), + k=k) + return junk + +def build_item_pool(world: "MinecraftWorld") -> List[Item]: + multiworld = world.multiworld + player = world.player + + itempool = [] + total_location_count = len(multiworld.get_unfilled_locations(player)) + + required_pool = Constants.item_info["required_pool"] + + # Add required progression items + for item_name, num in required_pool.items(): + itempool += [world.create_item(item_name) for _ in range(num)] + + # Add structure compasses + if world.options.structure_compasses: + compasses = [name for name in world.item_name_to_id if "Structure Compass" in name] + for item_name in compasses: + itempool.append(world.create_item(item_name)) + + # Dragon egg shards + if world.options.egg_shards_required > 0: + num = world.options.egg_shards_available + itempool += [world.create_item("Dragon Egg Shard") for _ in range(num)] + + # Unlockable hearts + if world.options.unlockable_hearts: + itempool += [world.create_item("Heart") for _ in range(9)] + + # Bee traps + bee_trap_percentage = world.options.bee_traps * 0.01 + if bee_trap_percentage > 0: + bee_trap_qty = ceil(bee_trap_percentage * (total_location_count - len(itempool))) + itempool += [world.create_item("Bee Trap") for _ in range(bee_trap_qty)] + + # Fill remaining itempool with randomly generated junk + junk = get_junk_item_names(world.random, total_location_count - len(itempool)) + itempool += [world.create_item(name) for name in junk] + + return itempool diff --git a/apworld_src/minecraft/MinecraftClient.py b/apworld_src/minecraft/MinecraftClient.py new file mode 100644 index 0000000..ff8b5a5 --- /dev/null +++ b/apworld_src/minecraft/MinecraftClient.py @@ -0,0 +1,754 @@ +import argparse +import io +import json +import logging +import os +import pkgutil +import re +import shutil +import subprocess +import sys +import threading +import time +import zipfile +from base64 import b64encode, b64decode +from collections import defaultdict + +from enum import Enum +from math import floor, log +from queue import Queue +from typing import List, Optional, TYPE_CHECKING, Any, TypedDict + +import Utils + +from kivy import Config +from kivy.core.window import Window +from kivy.core.image import Image as CoreImage +from kivy.clock import Clock, mainthread +from kivy.lang import Builder +from kivy.properties import StringProperty, NumericProperty, ObjectProperty, ListProperty +from kivy.uix.popup import Popup +from kivy.uix.screenmanager import NoTransition +from kivy.uix.textinput import TextInput +from kivy.utils import escape_markup + +from kivymd.app import MDApp +from kivymd.uix.boxlayout import MDBoxLayout +from kivymd.uix.gridlayout import MDGridLayout +from kivymd.uix.label import MDLabel +from kivymd.uix.recycleview import MDRecycleView +from kivymd.uix.screenmanager import MDScreenManager +from kivymd.uix.screen import MDScreen +from kivymd.uix.stacklayout import MDStackLayout +from kivymd.uix.widget import MDWidget + +from worlds.minecraft.downloader import StepsStep, SyncStep, BytesToStringStep +from worlds.minecraft.downloader.Java import DownloadJava +from worlds.minecraft.downloader.NeoForge import DownloadNeoForge +from worlds.minecraft.downloader.Utilities import DownloadStep, FetchStep + + +if TYPE_CHECKING: + from worlds.minecraft import MinecraftSettings + +logger = logging.getLogger("MinecraftClient") + +version_file_endpoint = "https://raw.githubusercontent.com/qixils/NeoForgeAP/refs/heads/main/versions/minecraft_versions.json" + +default_save_name = "Archipelago" + +class VersionsJson(TypedDict): + version: str + channel: str + data: int + java: int + minecraft: str + url: str + +def load_text(*path: str): + data_path = 'worlds.minecraft' if __name__ == '__main__' else __name__ + return pkgutil.get_data(data_path, "/".join(path)).decode() + + +def load_image(*path: str): + data_path = 'worlds.minecraft' if __name__ == '__main__' else __name__ + data = io.BytesIO(pkgutil.get_data(data_path, "/".join(path))) + texture = CoreImage(data, ext="png") + return texture + + +def format_bytes(size): + power = 0 if size <= 0 else floor(log(size, 1024)) + return f"{round(size / 1024 ** power, 2)} {['B', 'KB', 'MB', 'GB', 'TB'][int(power)]}" + + +def get_options() -> 'MinecraftSettings': + return Utils.get_settings()['minecraft_options'] + +class ServerStatus(Enum): + STOPPED = 0 + STARTING = 1 + RUNNING = 2 + + def __lt__(self, other): + return self.value < other.value + + def __gt__(self, other): + return self.value > other.value + + def __eq__(self, other): + return self.value == other.value + + +def get_recent_items(options: 'MinecraftSettings') -> List: + if not os.path.isdir(options.server_directory): + os.makedirs(options.server_directory) + saves = [] + for directory in os.listdir(options.server_directory): + try: + if directory.startswith("Archipelago-"): + world_dir = os.path.join(options.server_directory, directory) + + save = os.path.join(world_dir, "save.apmc") + if not os.path.isfile(save): + continue + + metadata_path = os.path.join(world_dir, "metadata.json") + if not os.path.exists(metadata_path): + # it doesn't really matter if the metadata exists... + # *except* it suggests the save.apmc is using the old broken format + # so we ignore this entry to force the user to re-import their apmc + continue + + description = default_save_name + with open(metadata_path, "r") as jsonfile: + metadata = json.load(jsonfile) + if 'description' in metadata: + description = metadata["description"] + saves.append((description, directory)) + except: + pass + return saves + + +class MinecraftClient(MDApp): + stop = threading.Event() + + def __init__(self, args, **kwargs): + super().__init__(**kwargs) + self.index = 0 + self.welcome_window: Optional[WelcomeWindow] = None + self.window_manager: Optional[WindowManager] = None + self.server_window: Optional[ServerWindow] = None + self.minecraft_versions: defaultdict[str, List[VersionsJson]] = defaultdict(lambda: list()) + # release channel to list of versions, I guess + self.apmc = None + self.version: VersionsJson = dict() + self.server = None + self.java_url = None + self.status: ServerStatus = ServerStatus.STOPPED + self.apmc_path = None + self.mod_info: List[VersionsJson] = list() + self.release_chanel = None + self.args = args + self.closing_at = 0 + Utils.init_logging('MinecraftClient') + logger.info(f"Client Initialized") + + # Handles (re)loading mod info, whether from a successful HTTP request or not + def _handle_mod_info(self, context: dict[str, Any], resp: Optional[Any] = None) -> None: + options = get_options() + fp = os.path.join(options.server_directory, 'ap-version.json') + logger.debug(f"Got response: {resp}") + if resp: + self.mod_info: List[VersionsJson] = json.loads(resp) + os.makedirs(options.server_directory, exist_ok=True) + with open(fp, 'w') as f: + json.dump(self.mod_info, f) + self._init_mc_versions() + return + + if not os.path.exists(fp): + return + + try: + with open(fp, 'r') as f: + self.mod_info: List[VersionsJson] = json.load(f) + self._init_mc_versions() + except: + logger.error("Failed to parse ap-version JSON", exc_info=True) + + + def _init_mc_versions(self): + self.minecraft_versions.clear() + for data in self.mod_info: + self.minecraft_versions[data['channel']].append(data) + + # Handles initializing the mod info fetching process + def _init_mod_info(self): + StepsStep( + "Download Versions", + SyncStep(self._handle_mod_info), # Load the cached JSON file + FetchStep(url=version_file_endpoint), # Download the latest version + BytesToStringStep(), + SyncStep(self._handle_mod_info), # Save the latest version (if available) + SyncStep(self.auto_start_server), + ).run(dict(), error_ok=True) + + def build(self): + logger.info(f"building client") + # TODO: Rewrite minecraft.kv to work with KivyMD. Look under the data file. + Builder.load_string(load_text("layouts", "minecraft.kv")) + self.window_manager = WindowManager(transition=NoTransition()) + self.welcome_window = WelcomeWindow(self) + self.server_window = ServerWindow(self) + self.window_manager.add_widget(self.welcome_window) + self.window_manager.add_widget(self.server_window) + logger.info(f"client built") + + logger.info(f"binding on close request") + Window.bind(on_request_close=self.on_request_close) + + logger.info(f"returning window manager") + return self.window_manager + + def on_start(self): + # send our request out to fetch the versions file + logger.info(f"fetching versions file") + self._init_mod_info() + + def on_request_close(self, *arg): + # if the server is stopped already then we don't need to intervene + if self.stop.is_set(): + return + + # likewise if there is no server, nothing to worry about + if not self.server: + return + + # if this is the first request to close the server, then let's send the shutdown signals + if self.closing_at == 0: + # save when shutdown started using increasing clock + # (`close` function's `dt` arg does not work like you might expect from the docs description; it is just a delta, so it isn't useful) + self.closing_at = time.monotonic() + + # send `/stop` to start server shutdown + self.send_command("stop") + + # check every tenth second for the server to be closed + Clock.schedule_interval(self.close, 0.1) + + # cancel the close request (we'll close it ourselves when we're ready) + return True + + + def close(self, dt): + # determine if X seconds have elapsed since starting + elapsed = time.monotonic() - self.closing_at + force_close = elapsed >= 15 + if force_close: + # server is not responding + try: + # attempt somewhat graceful shutdown + self.server.terminate() + self.server.wait(timeout=2) + except: + try: + # attempt less graceful shutdown + self.server.kill() + self.server.wait(timeout=2) + except Exception as e: + logger.warning("Failed to kill Minecraft server", exc_info=e) + pass + + # once server is stopped, close kivy window (has to be done manually since the close request was cancelled) + if self.stop.is_set() or force_close: + super().stop() + + def get_application_icon(self): + return load_image("assets", "icon.png") + + def init(self, dt=None): + options = get_options() + layout: MDWidget = self.welcome_window.ids.saves + layout.clear_widgets() + saves = get_recent_items(options) + if len(saves) == 0: + layout.add_widget(MDLabel(text="No saves")) + else: + for name, path in saves: + layout.add_widget(RecentItem(name=name, path=path, client=self)) + + ids: MDStackLayout = self.welcome_window.ids + ids.path.value = options.server_directory + ids.max_memory.value = options.max_heap_size + ids.min_memory.value = options.min_heap_size + ids.release_option.value = options.release_channel + ids.release_option.mc_options = self.minecraft_versions.keys() + + def auto_start_server(self, context: dict[str, Any], *ignore): + Clock.schedule_once(self.init, 1) + self.apmc_path = os.path.abspath(self.args.apmc_file) if type(self.args.apmc_file) is str else None + if self.apmc_path: + self.open_apmc(path=self.apmc_path) + + def read_possible_b64(self, data: str) -> dict[str, Any]: + if data.startswith("e"): + return json.loads(b64decode(data)) + elif data.startswith("{"): + return json.loads(data) + + def open_apmc(self, path=None): + options = get_options() + logger.info(self.mod_info) + self.apmc_path = path + if self.apmc_path is None: + self.apmc_path = Utils.open_filename(title="Choose AP Minecraft file", + filetypes=(("Archipelago Minecraft", ["*.apmc"]),)) + if self.apmc_path is None or self.apmc_path == "" or not os.path.isfile(self.apmc_path): + return + + # APContainer makes zips + try: + if zipfile.is_zipfile(self.apmc_path): + with zipfile.ZipFile(self.apmc_path, 'r') as zf: + embedded_apmc = None + for entry in zf.infolist(): + if entry.filename.endswith(".apmc") or entry.filename.endswith(".apmcmeta"): + embedded_apmc = entry.filename + break + if embedded_apmc: + with zf.open(embedded_apmc, 'r' ) as f: + data = f.read() + data = data.decode('utf-8') + apmc = self.read_possible_b64(data) + else: + logger.error(f"unable to find metadata file in zip") + else: + with open(self.apmc_path, 'r') as f: + data = f.read() + apmc = self.read_possible_b64(data) + except Exception as e: + logger.error("failed to load apmc file", exc_info=e) + + if apmc is None: + info_dialog("Invalid APMC", content=""" + An error occurred while parsing the APMC. + Please check the logs. + """) + return + + try: + self.apmc = apmc + # TODO(cang) Not sure if this is supposed to handle multiple valid MC versions + self.version = next(filter(lambda entry: entry['data'] == self.apmc["client_version"], + self.minecraft_versions[options.release_channel])) + self.server_window.status.text = f"Initializing {self.version['minecraft']}" + + self.window_manager.current = "Server" + self.start_server() + except KeyError: + logger.error(f"unable to find version {self.apmc['client_version']} on {options.release_channel}") + self.log_error(f"unable to find version {self.apmc['client_version']} on {options.release_channel}") + self.apmc_path = None + + def update_progress(self, value: float, content: str): + self.server_window.update_progress(value, content) + + def set_description(self, text): + self.apmc["description"] = text + self.start_server() + + @mainthread + def start_server(self) -> None: + options = get_options() + self.server_window.show_progress_bar_dialog("Installing Dependencies", "", 100) + context: dict[str, Any] = dict() + StepsStep( + "Download Dependencies", + DownloadJava(options.server_directory, self.version['java']), + DownloadNeoForge(options.server_directory, confirm_prompt, self.version["minecraft"]), + SyncStep(lambda context, data: (None, os.path.join(data.mods_dir, "Archipelago.jar"), self.version['version'])), + DownloadStep(self.version["url"]), + SyncStep(self.copy_apmc), + SyncStep(lambda *args: self.server_window.close_progress_bar_dialog()), + SyncStep(lambda *args: threading.Thread(target=self.server_thread, args=(context,)).start()) + ).run( + context, + on_failure=self.handle_server_start_failure, + on_progress=self.update_progress, + ) + + def handle_server_start_failure(self, *args): + logger.error(f"Dependency Downloads failed {args}", exc_info=True) + self.server_window.close_progress_bar_dialog() + self.window_manager.current = "Welcome" + info_dialog("Server Start Failure", content=""" + An error occurred while starting the server. + Please check the logs. + """) + + def copy_apmc(self, context: dict[str, Any], *arg): + if self.apmc_path is None: + return + neo_dir = context['neoforge_dir'] + apdata_dir = os.path.join(neo_dir, 'APData') + os.makedirs(apdata_dir, exist_ok=True) + + neo_apmc = os.path.join(apdata_dir, 'save.apmc') + shutil.copy2(self.apmc_path, neo_apmc) + + def server_thread(self, context: dict[str, Any]): + options = get_options() + + self.status = ServerStatus.STOPPED + self.server_window.background_color = (.5, .1, .1, 1) + world_name = f"Archipelago-{self.apmc['seed_name']}-P{self.apmc['player_id']}" + self.server_window.status.text = f"Archipelago-{self.apmc['seed_name']}-{self.apmc['player_name']}" + world_dir = os.path.join(options.server_directory, world_name) + if not os.path.isdir(world_dir): + os.makedirs(world_dir) + + save_path = os.path.join(world_dir, "save.apmc") + # we might consider skipping this if save_path exists + # but for now we want to repair broken installs + if self.apmc_path != save_path: + shutil.copy2(self.apmc_path, save_path) + + metadata_path = os.path.join(world_dir, "metadata.json") + if not os.path.isfile(metadata_path): + metadata = {"description": "Archipelago"} + with open(metadata_path, "w") as meta_file: + json.dump(metadata, meta_file) + + os.environ["JAVA_OPTS"] = "" + neo_run = context['neoforge_run_args'] + neo_dir = context['neoforge_dir'] + + cmd = (*neo_run, "--nogui", "--world", world_name) + logger.info(f"Invoking: {cmd}") + logger.info(f"With working dir: {neo_dir}") + self.server = subprocess.Popen(cmd, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + encoding="utf-8", + text=True, + cwd=neo_dir, + ) + + server_queue = Queue() + stream_server_output(self.server.stdout, server_queue, self.server) + stream_server_output(self.server.stderr, server_queue, self.server) + + while not self.stop.is_set(): + if self.server.poll() is not None: + self.log_raw("[color=FFFF00]Minecraft server has exited.[/color]") + self.stop.set() + self.server_window.status.text = "Server Stopped" + self.server_window.background_color = (.5, .1, .1, 1) + self.status = ServerStatus.STOPPED + + while not server_queue.empty(): + raw_message: str = server_queue.get() + + match = re.match(r"^\[[0-9:]+] \[.+/(WARN|INFO|ERROR)] \[.+]: (.*)", raw_message) + if match: + level = match.group(1) + msg = escape_markup(match.group(2)) + + if level == "WARN": + self.log_warn(msg) + elif level == "ERROR": + self.log_error(msg) + elif level == "INFO": + self.log_info(msg) + else: + self.log_info(raw_message) + + if self.status < ServerStatus.RUNNING: + + server_starting_match = re.match(r"\[[0-9:]+] (?:\[[A-Za-z0-9 /]+] ?){1,2}: Starting minecraft server version ([0-9.]+)", raw_message) + if server_starting_match: + self.log_info(f"Starting Minecraft {server_starting_match.group(1)}") + self.server_window.status.text = f"Starting Server for {server_starting_match.group(1)}" + self.server_window.background_color = (.5, .5, .0, 1) + self.version["minecraft"] = server_starting_match.group(1) + self.status = ServerStatus.STARTING + + server_started_match = re.match(r"\[[0-9:]+] (?:\[[A-Za-z0-9 /]+] ?){1,2}: Done", raw_message) + if server_started_match: + self.server_window.status.text = f"Server Running. Connect to `127.0.0.1` in Minecraft {self.version['minecraft']}" + self.server_window.background_color = (.1, .5, .1, 1) + self.status = ServerStatus.RUNNING + + server_queue.task_done() + time.sleep(0.01) + + def send_command(self, cmd): + try: + self.server.stdin.write(f'{cmd}\n') + self.server.stdin.flush() + except Exception: + pass + + @mainthread + def log_info(self, msg): + self.server_window.log.on_message_markup(f"[b][INFO][/b] {escape_markup(msg)}") + + @mainthread + def log_warn(self, msg): + self.server_window.log.on_message_markup(f"[color=FFFF00][b][WARN][/b][/color] {escape_markup(msg)}") + + @mainthread + def log_error(self, msg): + self.server_window.log.on_message_markup(f"[color=FFFF00][b][ERROR][/b][/color] {escape_markup(msg)}") + + @mainthread + def log_raw(self, msg): + self.server_window.log.on_message_markup(msg) + + +def stream_server_output(pipe, queue, process): + def queuer(): + while process.poll() is None: + text = pipe.readline().rstrip().expandtabs() + if text: + queue.put_nowait(text) + + thread = threading.Thread(target=queuer, name="Minecraft Output Queue", daemon=True) + thread.start() + return thread + + +class TextOption(MDGridLayout): + value = StringProperty() + label = StringProperty() + button_label = StringProperty() + + +class DropdownOption(MDGridLayout): + value = StringProperty() + label = StringProperty() + options = ListProperty() + + +class FolderOption(TextOption): + + def button_press(self): + new_dir = Utils.open_directory(title="Choose Server Directory") + if new_dir: + self.value = new_dir + + +class RecentItem(MDBoxLayout): + name = StringProperty() + path = StringProperty() + client: MinecraftClient = ObjectProperty() + + def __init__(self, **kwargs): + super().__init__(**kwargs) + icon_delete = load_image("assets", "delete.png") + icon_edit = load_image("assets", "edit.png") + self.ids.delete_icon.texture = icon_delete.texture + self.ids.rename_icon.texture = icon_edit.texture + + def load(self): + options = get_options() + save_path = os.path.join(options.server_directory, self.path, "save.apmc") + if os.path.isfile(save_path): + self.client.open_apmc(save_path) + else: + info_dialog(title="Error", content=f"Unable to find save file for world {self.path}") + + def delete(self): + self.client.welcome_window.confirm_delete(target=self.path, title="Confirm Delete", + content=f"Delete {self.name}?\nThis Action is permanent.") + + def rename(self): + edit_prompt(title="Confirm Edit", content=f"Rename {self.name}", default=self.name, + confirm=lambda text: self.set_name(text)) + + def set_name(self, name): + options = get_options() + self.name = name + try: + with open(os.path.join(options.server_directory, self.path, "metadata.json"), "r+") as file: + data = json.load(file) + data["description"] = name + file.seek(0) + file.truncate() + json.dump(data, file) + except Exception as e: + info_dialog(title="Error", content=f"Error renaming world: {e}") + + +class ConfirmDialog(Popup): + text = StringProperty() + confirm_text = StringProperty() + cancel_text = StringProperty() + + +class InfoDialog(Popup): + text = StringProperty() + button_text = StringProperty() + + +class ProgressBarDialog(Popup): + text = StringProperty("") + progress_text = StringProperty("") + progress = NumericProperty(0) + max = NumericProperty(100) + + def __init__(self, max, **kwargs): + super().__init__(**kwargs) + self.max = max + + +# TODO: migrate to Steps +def confirm_prompt(confirm=None, title="Prompt", content="Are you sure?", cancel=None, confirm_text="Yes", + cancel_text="No"): + popup = ConfirmDialog(title=title, text=content, confirm_text=confirm_text, cancel_text=cancel_text) + popup.open() + + if cancel is not None: + popup.ids.cancel.bind(on_press=cancel) + + if confirm is not None: + popup.ids.confirm.bind(on_press=confirm) + + +def info_dialog(title="Prompt", content="Are you sure?", cancel=None): + popup = InfoDialog(title=title, text=content, button_text="OK") + popup.open() + + +def edit_prompt(confirm, title="Prompt", content="Are you sure?", cancel=None, default=""): + popup = ConfirmDialog(title=title, text=content, confirm_text="Confirm", cancel_text="Cancel") + popup.open() + + content: MDWidget = popup.ids.content + + textinput = TextInput(text=default, + size_hint=(1, None), + height=30, + multiline=False, + ) + content.add_widget(textinput) + textinput.bind(on_text_validate=lambda _: confirm(textinput.text)) + textinput.bind(on_text_validate=popup.dismiss) + + if cancel is not None: + popup.ids.cancel.bind(on_press=cancel) + + popup.ids.confirm.bind(on_press=lambda _: confirm(textinput.text)) + + +class WindowManager(MDScreenManager): + pass + + +class LogEntry(MDLabel): + pass + + +class ServerWindow(MDScreen): + + def __init__(self, client, **kw): + super().__init__(**kw) + self.client = client + self.log: ServerLog = self.ids.log + self.status: MDLabel = self.ids.status + self.cmd: TextInput = self.ids.cmd + self.progress_popup: Optional[ProgressBarDialog] = None + self.background_color = (.5, .1, .1, 1) + + def send_command(self, value): + self.client.send_command(value) + self.cmd.text = "" + Clock.schedule_once(self.focus_cmd, 0) + + def focus_cmd(self, dv): + self.cmd.focus = True + + def show_progress_bar_dialog(self, title, content, max): + self.progress_popup = ProgressBarDialog(title=title, text=content, max=max) + self.progress_popup.open() + + def update_progress(self, progress: float, content: str): + if self.progress_popup is None: + return + self.progress_popup.progress = progress * 100.0 + self.progress_popup.progress_text = content + + def close_progress_bar_dialog(self): + if self.progress_popup is not None: + self.progress_popup.dismiss() + self.progress_popup = None + + +class ServerLog(MDRecycleView): + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.data = [] + + def on_log(self, record: str): + self.data.append({"text": escape_markup(record)}) + self.clean_old() + + def on_message_markup(self, text): + self.data.append({"text": text}) + self.clean_old() + + def clean_old(self): + if len(self.data) > self.messages: + self.data.pop(0) + + +class WelcomeWindow(MDScreen): + version = StringProperty() + + def __init__(self, client: MinecraftClient, **kwargs): + super().__init__(**kwargs) + self.client = client + self.apmc = None + options = get_options() + Window.minimum_width, Window.minimum_height = (400, 300) + self.ids['path'].value = options.server_directory + self.ids['max_memory'].value = options.max_heap_size + self.ids['min_memory'].value = options.min_heap_size + self.ids['release_option'].value = options.release_channel + + def do_delete(self, target): + options = get_options() + world_path = os.path.join(options.server_directory, target) + if options.server_directory in world_path and os.path.isdir(world_path): + shutil.rmtree(world_path) + self.client.init() + + def confirm_delete(self, target, title="Confirm Delete", content="This Action is permanent."): + confirm_prompt(title=title, content=content, confirm=lambda _: self.do_delete(target)) + + def save_options(self): + options = get_options() + options.server_directory = self.ids.path.value + options.max_heap_size = self.ids.max_memory.value + options.min_heap_size = self.ids.min_memory.value + options.release_channel = self.ids.release_option.value + Utils.get_settings().save() + self.client.init() + +def launch_subprocess(*args): + from worlds.LauncherComponents import launch + launch(mc_launch, "Minecraft Client", args) + +def mc_launch(*arguments): + parser = argparse.ArgumentParser() + parser.add_argument("apmc_file", default=None, nargs='?', help="Path to an Archipelago Minecraft data file (.apmc)") + args = parser.parse_args(arguments) + Config.set("network", "implementation", "requests") + MinecraftClient(args).run() + +if __name__ == "__main__": + mc_launch(sys.argv) \ No newline at end of file diff --git a/apworld_src/minecraft/Options.py b/apworld_src/minecraft/Options.py new file mode 100644 index 0000000..9a7afb4 --- /dev/null +++ b/apworld_src/minecraft/Options.py @@ -0,0 +1,149 @@ +from Options import Choice, Toggle, DefaultOnToggle, Range, OptionList, DeathLink, PlandoConnections, \ + PerGameCommonOptions +from .Constants import region_info +from dataclasses import dataclass + + +class AdvancementGoal(Range): + """Number of advancements required to spawn bosses.""" + display_name = "Advancement Goal" + range_start = 0 + range_end = 137 + default = 40 + + +class EggShardsRequired(Range): + """Number of dragon egg shards to collect to spawn bosses.""" + display_name = "Egg Shards Required" + range_start = 0 + range_end = 50 + default = 0 + + +class EggShardsAvailable(Range): + """Number of dragon egg shards available to collect.""" + display_name = "Egg Shards Available" + range_start = 0 + range_end = 50 + default = 0 + + +class BossGoal(Choice): + """Bosses which must be defeated to finish the game.""" + display_name = "Required Bosses" + option_none = 0 + option_ender_dragon = 1 + option_wither = 2 + option_both = 3 + default = 1 + + @property + def dragon(self): + return self.value % 2 == 1 + + @property + def wither(self): + return self.value > 1 + + +class ShuffleStructures(DefaultOnToggle): + """Enables shuffling of villages, outposts, fortresses, bastions, and end cities.""" + display_name = "Shuffle Structures" + + +class StructureCompasses(DefaultOnToggle): + """Adds structure compasses to the item pool, which point to the nearest indicated structure.""" + display_name = "Structure Compasses" + + +class BeeTraps(Range): + """Replaces a percentage of junk items with bee traps, which spawn multiple angered bees around every player when + received.""" + display_name = "Bee Trap Percentage" + range_start = 0 + range_end = 100 + default = 0 + + +class CombatDifficulty(Choice): + """Modifies the level of items logically required for exploring dangerous areas and fighting bosses.""" + display_name = "Combat Difficulty" + option_easy = 0 + option_normal = 1 + option_hard = 2 + default = 1 + + +class HardAdvancements(Toggle): + """Enables certain RNG-reliant or tedious advancements.""" + display_name = "Include Hard Advancements" + + +class UnreasonableAdvancements(Toggle): + """Enables the extremely difficult advancements "How Did We Get Here?" and "Adventuring Time.\"""" + display_name = "Include Unreasonable Advancements" + + +class PostgameAdvancements(Toggle): + """Enables advancements that require spawning and defeating the required bosses.""" + display_name = "Include Postgame Advancements" + + +class SendDefeatedMobs(Toggle): + """Send killed mobs to other Minecraft worlds which have this option enabled.""" + display_name = "Send Defeated Mobs" + + +class UnlockableHearts(Toggle): + """Start players with one heart and add nine Heart items to the item pool. Each Heart restores one max heart, up to the vanilla ten hearts.""" + display_name = "Unlockable Hearts" + + +class StartingItems(OptionList): + """Start with these items. Each entry should be of this format: {item: "item_name", amount: #} + `item` can include components, and should be in an identical format to a `/give` command with + `"` escaped for json reasons. + + `amount` is optional and will default to 1 if omitted. + + example: + ``` + starting_items: [ + { "item": "minecraft:stick[minecraft:custom_name=\"{'text':'pointy stick'}\"]" }, + { "item": "minecraft:arrow[minecraft:rarity=epic]", amount: 64 } + ] + ``` + """ + display_name = "Starting Items" + + +class MCPlandoConnections(PlandoConnections): + entrances = set(connection[0] for connection in region_info["default_connections"]) + exits = set(connection[1] for connection in region_info["default_connections"]) + + @classmethod + def can_connect(cls, entrance, exit): + if exit in region_info["illegal_connections"] and entrance in region_info["illegal_connections"][exit]: + return False + return True + + +@dataclass +class MinecraftOptions(PerGameCommonOptions): + plando_connections: MCPlandoConnections + advancement_goal: AdvancementGoal + egg_shards_required: EggShardsRequired + egg_shards_available: EggShardsAvailable + required_bosses: BossGoal + shuffle_structures: ShuffleStructures + structure_compasses: StructureCompasses + + combat_difficulty: CombatDifficulty + include_hard_advancements: HardAdvancements + include_unreasonable_advancements: UnreasonableAdvancements + include_postgame_advancements: PostgameAdvancements + bee_traps: BeeTraps + send_defeated_mobs: SendDefeatedMobs + unlockable_hearts: UnlockableHearts + death_link: DeathLink + starting_items: StartingItems diff --git a/apworld_src/minecraft/Rules.py b/apworld_src/minecraft/Rules.py new file mode 100644 index 0000000..e1a83c9 --- /dev/null +++ b/apworld_src/minecraft/Rules.py @@ -0,0 +1,690 @@ +from BaseClasses import CollectionState +from worlds.generic.Rules import exclusion_rules + +from . import Constants +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from . import MinecraftWorld + + +# Helper functions +# moved from logicmixin + +def has_iron_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Progressive Tools', player) and state.has('Progressive Resource Crafting', player) + + +def has_copper_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Progressive Tools', player) and state.has('Progressive Resource Crafting', player) + + +def has_gold_ingots(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (state.has('Progressive Resource Crafting', player) + and ( + state.has('Progressive Tools', player, 2) + or state.can_reach_region('The Nether', player) + ) + ) + + +def has_diamond_pickaxe(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Progressive Tools', player, 3) and has_iron_ingots(world, state, player) + + +def craft_crossbow(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Archery', player) and has_iron_ingots(world, state, player) + + +def has_bottle(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Bottles', player) and state.has('Progressive Resource Crafting', player) + + +def has_spyglass(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (has_copper_ingots(world, state, player) + and state.has('Spyglass', player) + and can_adventure(world, state, player) + ) + + +def can_enchant(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Enchanting', player) and has_diamond_pickaxe(world, state, player) # mine obsidian and lapis + + +def can_use_anvil(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (state.has('Enchanting', player) + and state.has('Progressive Resource Crafting', player,2) + and has_iron_ingots(world, state, player) + ) + + +def fortress_loot(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: # blaze rods, wither skulls + return state.can_reach_region('Nether Fortress', player) and basic_combat(world, state, player) + + +def can_excavate(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (has_copper_ingots(world, state, player) and state.has('Brush', player) + and can_adventure(world, state, player) + ) + + +def can_brew_potions(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Blaze Rods', player) and state.has('Brewing', player) and has_bottle(world, state, player) + +def can_piglin_trade(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (has_gold_ingots(world, state, player) + and ( + state.can_reach_region('The Nether', player) + or state.can_reach_region('Bastion Remnant', player) + )) + + +def overworld_villager(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + village_region = state.multiworld.get_region('Village', player).entrances[0].parent_region.name + if village_region == 'The Nether': # 2 options: cure zombie villager or build portal in village + return (state.can_reach_location('Zombie Doctor', player) + or ( + has_diamond_pickaxe(world, state, player) + and state.can_reach_region('Village', player) + )) + elif village_region == 'The End': + return state.can_reach_location('Zombie Doctor', player) + return state.can_reach_region('Village', player) or state.can_reach_location('Zombie Doctor', player) + + +def enter_stronghold(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return state.has('Blaze Rods', player) and state.has('Brewing', player) and state.has('3 Ender Pearls', player) + + +# Difficulty-dependent functions +def combat_difficulty(world: "MinecraftWorld", state: CollectionState, player: int) -> str: + return world.options.combat_difficulty.current_key + + +def can_adventure(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + death_link_check = not world.options.death_link or state.has('Bed', player) + if combat_difficulty(world, state, player) == 'easy': + return state.has('Progressive Weapons', player, 2) and has_iron_ingots(world, state, player) and death_link_check + elif combat_difficulty(world, state, player) == 'hard': + return True + return (state.has('Progressive Weapons', player) and death_link_check and + (state.has('Progressive Resource Crafting', player) or state.has('Campfire', player))) + + +def basic_combat(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + if combat_difficulty(world, state, player) == 'easy': + return (state.has('Progressive Weapons', player, 2) + and state.has('Progressive Armor', player) + and state.has('Shield', player) + and has_iron_ingots(world, state, player) + ) + elif combat_difficulty(world, state, player) == 'hard': + return True + return (state.has('Progressive Weapons', player) + and ( + state.has('Progressive Armor', player) + or state.has('Shield', player) + ) + and has_iron_ingots(world, state, player) + ) + + +def ominous_vaults(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + if combat_difficulty(world, state, player) == 'easy': + return (state.can_reach_region("Pillager Outpost", player) + and state.has('Progressive Weapons', player, 3) + and state.has('Progressive Armor', player, 2) + and state.has('Shield', player) + and state.has('Progressive Tools', player, 2) + and has_iron_ingots(world, state, player) + ) + elif combat_difficulty(world, state, player) == 'hard': + return (state.can_reach_region("Pillager Outpost", player) + and state.has('Progressive Weapons', player, 2) + and has_iron_ingots(world, state, player) + and ( + state.has('Progressive Armor', player) + or state.has('Shield', player) + ) + ) + return (state.can_reach_region("Pillager Outpost", player) + and state.has('Progressive Weapons', player, 2) + and has_iron_ingots(world, state, player) + and state.has('Progressive Armor', player) + and state.has('Shield', player) + ) + + +def complete_raid(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + reach_regions = (state.can_reach_region('Village', player) + and state.can_reach_region('Pillager Outpost', player)) + if combat_difficulty(world, state, player) == 'easy': + return (reach_regions + and state.has('Progressive Weapons', player, 3) + and state.has('Progressive Armor', player, 2) + and state.has('Shield', player) + and state.has('Archery', player) + and state.has('Progressive Tools', player, 2) + and has_iron_ingots(world, state, player) + ) + elif combat_difficulty(world, state, player) == 'hard': # might be too hard? + return (reach_regions + and state.has('Progressive Weapons', player, 2) + and has_iron_ingots(world, state, player) + and ( + state.has('Progressive Armor', player) + or state.has('Shield', player) + ) + ) + return (reach_regions + and state.has('Progressive Weapons', player, 2) + and has_iron_ingots(world, state, player) + and state.has('Progressive Armor', player) + and state.has('Shield', player) + ) + + +def can_kill_wither(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + normal_kill = (state.has("Progressive Weapons", player, 3) + and state.has("Progressive Armor", player, 2) + and can_brew_potions(world, state, player) + and can_enchant(world, state, player) + ) + if combat_difficulty(world, state, player) == 'easy': + return (fortress_loot(world, state, player) + and normal_kill + and state.has('Archery', player) + ) + elif combat_difficulty(world, state, player) == 'hard': # cheese kill using bedrock ceilings + return (fortress_loot(world, state, player) + and ( + normal_kill + or state.can_reach_region('The Nether', player) + or state.can_reach_region('The End', player) + ) + ) + + return fortress_loot(world, state, player) and normal_kill + + +def can_respawn_ender_dragon(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + return (state.can_reach_region('The Nether', player) + and state.can_reach_region('The End', player) + and state.has('Progressive Resource Crafting', player) # smelt sand into glass + ) + + +def can_kill_ender_dragon(world: "MinecraftWorld", state: CollectionState, player: int) -> bool: + if combat_difficulty(world, state, player) == 'easy': + return (state.has("Progressive Weapons", player, 3) + and state.has("Progressive Armor", player, 2) + and state.has('Archery', player) + and can_brew_potions(world, state, player) + and can_enchant(world, state, player) + ) + if combat_difficulty(world, state, player) == 'hard': + return ( + ( + state.has('Progressive Weapons', player, 2) + and state.has('Progressive Armor', player) + ) or ( + state.has('Progressive Weapons', player, 1) + and state.has('Bed', player) # who needs armor when you can respawn right outside the chamber + ) + ) + return (state.has('Progressive Weapons', player, 2) + and state.has('Progressive Armor', player) + and state.has('Archery', player) + ) + + +def has_structure_compass(world: "MinecraftWorld", state: CollectionState, entrance_name: str, player: int) -> bool: + if not world.options.structure_compasses: + return True + return state.has(f"Structure Compass ({state.multiworld.get_entrance(entrance_name, player).connected_region.name})", player) + + +def get_rules_lookup(world, player: int): + rules_lookup = { + "entrances": { + "Nether Portal": lambda state: state.has('Flint and Steel', player) + and ( + state.has('Bucket', player) + or state.has('Progressive Tools', player, 3) + ) + and has_iron_ingots(world, state, player), + "End Portal": lambda state: enter_stronghold(world, state, player) + and state.has('3 Ender Pearls', player, 4), + "Overworld Structure 1": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Overworld Structure 1", player), + "Overworld Structure 2": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Overworld Structure 2", player), + "Nether Structure 1": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Nether Structure 1", player), + "Nether Structure 2": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Nether Structure 2", player), + "The End Structure": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "The End Structure", player), + "Ocean": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Ocean", player), + "Dark Forest": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Dark Forest", player), + "Deep Dark": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has("Progressive Tools", player, 2) + and has_structure_compass(world, state, "Deep Dark", player), + "Ruins": lambda state: can_adventure(world, state, player) + and has_structure_compass(world, state, "Ruins", player), + "Underground": lambda state: can_adventure(world, state, player) and state.has("Progressive Tools", player) + and has_structure_compass(world, state, "Underground", player) + }, + "locations": { + "Ender Dragon": lambda state: can_respawn_ender_dragon(world, state, player) + and can_kill_ender_dragon(world, state, player), + "Wither": lambda state: can_kill_wither(world, state, player), + "Blaze Rods": lambda state: fortress_loot(world, state, player), + "Who is Cutting Onions?": lambda state: can_piglin_trade(world, state, player), + "Oh Shiny": lambda state: can_piglin_trade(world, state, player), + "Suit Up": lambda state: state.has("Progressive Armor", player) + and has_iron_ingots(world, state, player), + "Very Very Frightening": lambda state: state.has("Channeling Book", player) + and can_use_anvil(world, state, player) + and can_enchant(world, state, player) + and overworld_villager(world, state, player), + "Hot Stuff": lambda state: state.has("Bucket", player) + and has_iron_ingots(world, state, player), + "Free the End": lambda state: can_respawn_ender_dragon(world, state, player) + and can_kill_ender_dragon(world, state, player), + "A Furious Cocktail": lambda state: (can_brew_potions(world, state, player) + and state.has("Fishing Rod", player) # Water Breathing + and state.can_reach_region("The Nether", player) # Regeneration, Fire Resistance, gold nuggets + and state.can_reach_region("Village", player) # Night Vision, Invisibility + and state.can_reach_location("Bring Home the Beacon", player) # Resistance + and can_adventure(world, state, player) + and state.can_reach_region("Trial Chambers", player) # Wind Charged + ), + "Bring Home the Beacon": lambda state: can_kill_wither(world, state, player) + and has_diamond_pickaxe(world, state, player) + and state.has("Progressive Resource Crafting", player, 2), + "Not Today, Thank You": lambda state: state.has("Shield", player) + and has_iron_ingots(world, state, player), + "Isn't It Iron Pick": lambda state: state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player), + "Local Brewery": lambda state: can_brew_potions(world, state, player), + "The Next Generation": lambda state: can_respawn_ender_dragon(world, state, player) + and can_kill_ender_dragon(world, state, player), + "Fishy Business": lambda state: state.has("Fishing Rod", player), + "This Boat Has Legs": lambda state: has_iron_ingots(world, state, player) + and state.has("Saddle", player) + and state.has("Fishing Rod", player), + "Sniper Duel": lambda state: state.has("Archery", player), + "Great View From Up Here": lambda state: basic_combat(world, state, player), + "How Did We Get Here?": lambda state: (can_brew_potions(world, state, player) + and has_gold_ingots(world, state, player) # Absorption + and state.can_reach_region('End City', player) # Levitation + and state.can_reach_region('The Nether', player) # potion ingredients + and state.can_reach_region('Ocean Monument', player) # Heart of the Sea, Dolphin's Grace, Mining Fatigue + and state.can_reach_region('Ancient City', player) # Darkness + and state.can_reach_region('Trial Chambers', player) # Wind Charged + and state.has("Fishing Rod", player) # Pufferfish, Nautilus Shells + and state.has("Archery", player) # Spectral Arrows + and state.can_reach_location("Bring Home the Beacon", player) # Haste + and state.can_reach_location("Hero of the Village", player)), # Bad Omen, Hero of the Village + "Bullseye": lambda state: state.has("Archery", player) + and state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player), + "Spooky Scary Skeleton": lambda state: basic_combat(world, state, player), + "Two by Two": lambda state: can_excavate(world, state, player) + and state.can_reach_region("Ocean Monument", player) # Sniffers + and state.has("Bucket", player) # Axolotls + and state.can_reach_region("Village", player) # Cats + and state.has("Brush", player) + and state.has("Fishing Rod", player), # Pufferfish for Nautiluses + "Two Birds, One Arrow": lambda state: craft_crossbow(world, state, player) + and can_enchant(world, state, player), + "Who's the Pillager Now?": lambda state: craft_crossbow(world, state, player), + "Getting an Upgrade": lambda state: state.has("Progressive Tools", player), + "Tactical Fishing": lambda state: state.has("Bucket", player) + and has_iron_ingots(world, state, player), + "Zombie Doctor": lambda state: can_brew_potions(world, state, player) + and has_gold_ingots(world, state, player), + "Ice Bucket Challenge": lambda state: has_diamond_pickaxe(world, state, player), + "Into Fire": lambda state: basic_combat(world, state, player), + "War Pigs": lambda state: basic_combat(world, state, player), + "Take Aim": lambda state: state.has("Archery", player), + "Total Beelocation": lambda state: state.has("Silk Touch Book", player) + and can_use_anvil(world, state, player) + and can_enchant(world, state, player), + "Arbalistic": lambda state: (craft_crossbow(world, state, player) + and state.has("Piercing IV Book", player) + and can_use_anvil(world, state, player) + and can_enchant(world, state, player) + ), + "The End... Again...": lambda state: can_respawn_ender_dragon(world, state, player) + and can_kill_ender_dragon(world, state, player), + "Acquire Hardware": lambda state: has_iron_ingots(world, state, player), + "Not Quite \"Nine\" Lives": lambda state: can_piglin_trade(world, state, player) + and state.has("Progressive Resource Crafting", player, 2), + "Cover Me with Diamonds": lambda state: state.has("Progressive Armor", player, 2) + and state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player), + "Sky's the Limit": lambda state: basic_combat(world, state, player), + "Hired Help": lambda state: state.has("Progressive Resource Crafting", player, 2) + and has_iron_ingots(world, state, player), + "Sweet Dreams": lambda state: state.has("Bed", player) + or state.can_reach_region('Village', player), + "You Need a Mint": lambda state: can_respawn_ender_dragon(world, state, player) + and has_bottle(world, state, player), + "Monsters Hunted": lambda state: can_respawn_ender_dragon(world, state, player) # Ghast, Hoglin, Magma Cube, Piglin + and can_kill_ender_dragon(world, state, player) # Ender Dragon, Enderman, Endermite, Silverfish + and can_kill_wither(world, state, player) # Blaze, Wither, Wither Skeleton, Zombified Piglin + and complete_raid(world, state, player) # Ravagers; Pillager Outposts + and state.can_reach_region('Bastion Remnant', player) # Piglin Brute + and state.can_reach_region('End City', player) # Shulker + and state.can_reach_region('Trial Chambers', player) # Breeze + and state.has("Lead", player) # Zoglins + and state.can_reach_region('Ocean Monument', player) # Drowned + and ( + (can_brew_potions(world, state, player) and state.has("Fishing Rod", player)) # Water Breathing Potions for Elder Guardian, Guardian + or (can_enchant(world, state, player) and state.has("Bucket", player)) # Aqua Affinity/Respiration and Milk/Axolotls for Elder Guardian, Guardian + ), + "Enchanter": lambda state: can_enchant(world, state, player), + "Voluntary Exile": lambda state: basic_combat(world, state, player), + "Eye Spy": lambda state: enter_stronghold(world, state, player), + "Serious Dedication": lambda state: (state.can_reach_location("Hidden in the Depths", player) + and state.has("8 Netherite Scrap", player) + and has_gold_ingots(world, state, player)), + "Postmortal": lambda state: complete_raid(world, state, player), + "Adventuring Time": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has("Progressive Tools", player, 2) + and state.can_reach_region('Ocean Monument', player) # Most Oceans + and state.can_reach_region('Woodland Mansion', player) # Dark Forest + and state.can_reach_region('Ancient City', player) # Deep Dark + and state.can_reach_region('Trail Ruins', player), # Jungle, Birch Forest, Old Growth Birch Forest, all Taiga variants + "Hero of the Village": lambda state: complete_raid(world, state, player), + "Hidden in the Depths": lambda state: can_brew_potions(world, state, player) + and state.has("Bed", player) + and has_diamond_pickaxe(world, state, player), + "Beaconator": lambda state: (can_kill_wither(world, state, player) + and has_diamond_pickaxe(world, state, player) + and state.has("Progressive Resource Crafting", player, 2)), + "Withering Heights": lambda state: can_kill_wither(world, state, player), + "A Balanced Diet": lambda state: (has_bottle(world, state, player) # honey bottle + and state.has("Campfire", player) # honey bottle + and state.has("Fishing Rod", player) + and state.can_reach_location("Overpowered", player) # gapple, notch apple + and state.can_reach_region('The End', player)), # chorus fruit + "Subspace Bubble": lambda state: has_diamond_pickaxe(world, state, player), + "Country Lode, Take Me Home": lambda state: state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player), + "Bee Our Guest": lambda state: state.has("Campfire", player) + and has_bottle(world, state, player), + "Uneasy Alliance": lambda state: has_diamond_pickaxe(world, state, player) + and state.has('Fishing Rod', player), + "Diamonds!": lambda state: state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player), + "A Throwaway Joke": lambda state: basic_combat(world, state, player), + "Sticky Situation": lambda state: state.has("Campfire", player) + and has_bottle(world, state, player), + "Ol' Betsy": lambda state: craft_crossbow(world, state, player), + "Cover Me in Debris": lambda state: state.has("Progressive Armor", player, 2) + and state.has("8 Netherite Scrap", player, 2) + and state.can_reach_location("Hidden in the Depths", player), + "Hot Topic": lambda state: state.has("Progressive Resource Crafting", player), + "The Lie": lambda state: has_iron_ingots(world, state, player) + and state.has("Bucket", player), + "On a Rail": lambda state: has_iron_ingots(world, state, player) + and state.has('Progressive Tools', player, 2), + "When Pigs Fly": lambda state: has_iron_ingots(world, state, player) + and state.has("Saddle", player) + and state.has("Fishing Rod", player) + and can_adventure(world, state, player), + "Overkill": lambda state: ( + can_brew_potions(world, state, player) + and ( + state.has("Progressive Weapons", player) + or state.can_reach_region('The Nether', player) + ) + ) + or ( + state.can_reach_location("Over-Overkill", player) + and world.options.include_hard_advancements + and "Over-Overkill" not in world.options.exclude_locations.value + ), + "Librarian": lambda state: state.has("Enchanting", player), + "Overpowered": lambda state: has_iron_ingots(world, state, player) + and state.has('Progressive Tools', player, 2) + and basic_combat(world, state, player), + "Wax On": lambda state: state.has('Campfire', player) + and has_copper_ingots(world, state, player), + "Wax Off": lambda state: ( + has_copper_ingots(world, state, player) + and state.has('Campfire', player) + ) + or state.can_reach_region("Trial Chambers", player), + "The Cutest Predator": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has('Bucket', player), + "The Healing Power of Friendship": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has('Bucket', player), + "Is It a Bird?": lambda state: has_spyglass(world, state, player), + "Is It a Balloon?": lambda state: has_spyglass(world, state, player), + "Is It a Plane?": lambda state: has_spyglass(world, state, player) + and can_respawn_ender_dragon(world, state, player), + "Surge Protector": lambda state: state.has("Channeling Book", player) + and can_use_anvil(world, state, player) + and can_enchant(world, state, player) + and overworld_villager(world, state, player), + "Light as a Rabbit": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has('Bucket', player), + "Glow and Behold!": lambda state: can_adventure(world, state, player), + "Whatever Floats Your Goat!": lambda state: can_adventure(world, state, player), + "Caves & Cliffs": lambda state: has_iron_ingots(world, state, player) + and state.has('Bucket', player) + and state.has('Progressive Tools', player, 2), + "Feels Like Home": lambda state: has_iron_ingots(world, state, player) + and state.has('Bucket', player) + and state.has('Fishing Rod', player) + and state.has("Saddle", player), + "Sound of Music": lambda state: state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player) + and can_adventure(world, state, player) + and ( + basic_combat(world, state, player) + or state.can_reach_region("The Nether", player) + or state.can_reach_region("Ancient City", player) + ), + "Star Trader": lambda state: has_iron_ingots(world, state, player) + and state.has('Bucket', player) + and ( + state.can_reach_region("The Nether", player) # soul sand in nether + or state.can_reach_region("Nether Fortress", player) # soul sand in fortress if not in nether for water elevator + or can_piglin_trade(world, state, player) # piglins give soul sand + ) + and overworld_villager(world, state, player), + "Birthday Song": lambda state: state.can_reach_location("The Lie", player) + and state.has("Progressive Tools", player, 2) + and has_iron_ingots(world, state, player) + and ( + state.can_reach_region('Pillager Outpost', player) + or ( + basic_combat(world, state, player) + and state.can_reach_region('Woodland Mansion', player) + ) + ), + "Bukkit Bukkit": lambda state: state.has("Bucket", player) + and has_iron_ingots(world, state, player) + and can_adventure(world, state, player), + "It Spreads": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has("Progressive Tools", player, 2), + "Sneak 100": lambda state: can_adventure(world, state, player) + and has_iron_ingots(world, state, player) + and state.has("Progressive Tools", player, 2), + "When the Squad Hops into Town": lambda state: can_adventure(world, state, player) + and state.has("Lead", player) + and state.has("Bucket", player) + and has_iron_ingots(world, state, player), + "With Our Powers Combined!": lambda state: can_adventure(world, state, player) + and state.has("Lead", player) + and state.has("Bucket", player) + and has_iron_ingots(world, state, player), + "You've Got a Friend in Me": lambda state: state.can_reach_region('Pillager Outpost', player) + or ( + basic_combat(world, state, player) + and state.can_reach_region('Woodland Mansion', player) + ), + "Smells Interesting": lambda state: can_excavate(world, state, player), + "Little Sniffs": lambda state: can_excavate(world, state, player), + "Planting the Past": lambda state: can_excavate(world, state, player), + "Crafting a New Look": lambda state: has_iron_ingots(world, state, player) # Maybe streamline this one + and ( + fortress_loot(world, state, player) + or ( + state.can_reach_region("Pillager Outpost", player) + and basic_combat(world, state, player) + ) + or ( + state.can_reach_region("Bastion Remnant", player) + and basic_combat(world, state, player) + ) + or ( + state.can_reach_region("End City", player) + and basic_combat(world, state, player) + ) + or ( + state.can_reach_region("Ocean Monument", player) + and basic_combat(world, state, player) + and state.has("Bucket", player) + and can_enchant(world, state, player) + ) + or ( + state.can_reach_region("Woodland Mansion", player) + and basic_combat(world, state, player) + ) + or state.can_reach_region("Ancient City", player) + or ( + state.can_reach_region("Trail Ruins", player) + and state.has("Brush", player) + ) + ), + "Smithing with Style": lambda state: can_excavate(world, state, player) # Wayfinder Armor Trim + and fortress_loot(world, state, player) # Rib Armor Trim + and state.can_reach_region("Bastion Remnant", player) # Snout Armor Trim + and state.can_reach_region("End City", player) # Spire Armor Trim + and ( + ( # Water Breathing Potions + state.has("Fishing Rod", player) + and can_brew_potions(world, state, player) + ) + or ( + state.has("Bucket", player) # Milk/Axolotls + and can_enchant(world, state, player) # Respiration + ) + ) + and state.can_reach_region("Woodland Mansion", player) # Vex Armor Trim + and state.can_reach_region("Ancient City", player) # Ward and Silence Armor Trims + and state.can_reach_region("Trail Ruins", player) + and state.can_reach_region("Ocean Monument", player), # Tide Armor Trim + "Respecting the Remnants": lambda state: can_excavate(world, state, player) + and ( + state.can_reach_region("Ocean Monument", player) + or state.can_reach_region("Trail Ruins", player) + ), + "Careful Restoration": lambda state: can_excavate(world, state, player) + and ( + state.can_reach_region("Ocean Monument", player) + or state.can_reach_region("Trail Ruins", player) + ), + "The Power of Books": lambda state: state.has("Progressive Tools", player, 2), + "Isn't It Scute?": lambda state: can_adventure(world, state, player) + and has_copper_ingots(world, state, player) + and state.has("Brush", player), + "Shear Brilliance": lambda state: can_adventure(world, state, player) + and has_copper_ingots(world, state, player) + and state.has("Brush", player), + "Good as New": lambda state: can_adventure(world, state, player) + and has_copper_ingots(world, state, player) + and state.has("Brush", player), + "The Whole Pack": lambda state: can_adventure(world, state, player), + "Under Lock and Key": lambda state: basic_combat(world, state, player), + "Blowback": lambda state: basic_combat(world, state, player), + "Who Needs Rockets?": lambda state: basic_combat(world, state, player), + "Crafters Crafting Crafters": lambda state: has_iron_ingots(world, state, player) + and state.has("Progressive Tools", player, 2), + "Lighten Up": lambda state: ( + fortress_loot(world, state, player) + and state.has("Progressive Tools", player, 2) + and state.has("Progressive Resource Crafting", player, 2) + ) + or state.can_reach_region("Trial Chambers", player), + "Over-Overkill": lambda state: ominous_vaults(world, state, player), + "Revaulting": lambda state: ominous_vaults(world, state, player), + "Stay Hydrated!": lambda state: state.can_reach_region("The Nether", player) + or can_piglin_trade(world, state, player), + "Heart Transplanter": lambda state: can_adventure(world, state, player) + and ( + ( + basic_combat(world, state, player) + and state.has("Progressive Resource Crafting", player, 2) + ) + or ( + state.has("Silk Touch Book", player) + and can_use_anvil(world, state, player) + and can_enchant(world, state, player) + ) + ), + "Mob Kabob": lambda state: state.has("Progressive Resource Crafting", player) + } + } + return rules_lookup + + +def set_rules(self: "MinecraftWorld") -> None: + multiworld = self.multiworld + player = self.player + + rules_lookup = get_rules_lookup(self, player) + + # Set entrance rules + for entrance_name, rule in rules_lookup["entrances"].items(): + multiworld.get_entrance(entrance_name, player).access_rule = rule + + # Set location rules + for location_name, rule in rules_lookup["locations"].items(): + multiworld.get_location(location_name, player).access_rule = rule + + # Set rules surrounding completion + bosses = self.options.required_bosses + postgame_advancements = set() + if bosses.dragon: + postgame_advancements.update(Constants.exclusion_info["ender_dragon"]) + if bosses.wither: + postgame_advancements.update(Constants.exclusion_info["wither"]) + + def location_count(state: CollectionState) -> int: + return len([location for location in multiworld.get_locations(player) if + location.address is not None and + location.can_reach(state)]) + + def defeated_bosses(state: CollectionState) -> bool: + return ((not bosses.dragon or state.has("Ender Dragon", player)) + and (not bosses.wither or state.has("Wither", player))) + + egg_shards = min(self.options.egg_shards_required.value, self.options.egg_shards_available.value) + completion_requirements = lambda state: (location_count(state) >= self.options.advancement_goal + and state.has("Dragon Egg Shard", player, egg_shards)) + multiworld.completion_condition[player] = lambda state: completion_requirements(state) and defeated_bosses(state) + + # Set exclusions on hard/unreasonable/postgame + excluded_advancements = set() + if not self.options.include_hard_advancements: + excluded_advancements.update(Constants.exclusion_info["hard"]) + if not self.options.include_unreasonable_advancements: + excluded_advancements.update(Constants.exclusion_info["unreasonable"]) + if not self.options.include_postgame_advancements: + excluded_advancements.update(postgame_advancements) + exclusion_rules(multiworld, player, excluded_advancements) diff --git a/apworld_src/minecraft/Structures.py b/apworld_src/minecraft/Structures.py new file mode 100644 index 0000000..630dac1 --- /dev/null +++ b/apworld_src/minecraft/Structures.py @@ -0,0 +1,67 @@ +from . import Constants +from typing import TYPE_CHECKING +from Options import PlandoConnection +if TYPE_CHECKING: + from . import MinecraftWorld + + +def shuffle_structures(self: "MinecraftWorld") -> None: + multiworld = self.multiworld + player = self.player + + default_connections = Constants.region_info["default_connections"] + illegal_connections = Constants.region_info["illegal_connections"] + + # Get all unpaired exits and all regions without entrances (except the Menu) + # This function is destructive on these lists. + exits = [exit.name for r in multiworld.regions if r.player == player for exit in r.exits if exit.connected_region is None] + structs = [r.name for r in multiworld.regions if r.player == player and r.entrances == [] and r.name != 'Menu'] + exits_spoiler = exits[:] # copy the original order for the spoiler log + + pairs = {} + + def set_pair(exit, struct): + if (exit in exits) and (struct in structs) and (exit not in illegal_connections.get(struct, [])): + pairs[exit] = struct + exits.remove(exit) + structs.remove(struct) + else: + raise Exception(f"Invalid connection: {exit} => {struct} for player {player} ({multiworld.player_name[player]})") + + if self.using_ut: + self.options.plando_connections.value.clear() + for exit, struct in self.passthrough["structures"].items(): + exit_name = exit + struct_name = struct + self.options.plando_connections.value.append(PlandoConnection(exit_name, struct_name, "both")) + + # Connect plando structures first + if self.options.plando_connections: + for conn in self.options.plando_connections: + set_pair(conn.entrance, conn.exit) + + # The algorithm tries to place the most restrictive structures first. This algorithm always works on the + # relatively small set of restrictions here, but does not work on all possible inputs with valid configurations. + if self.options.shuffle_structures: + structs.sort(reverse=True, key=lambda s: len(illegal_connections.get(s, []))) + for struct in structs[:]: + try: + exit = self.random.choice([e for e in exits if e not in illegal_connections.get(struct, [])]) + except IndexError: + raise Exception(f"No valid structure placements remaining for player {player} ({self.player_name})") + set_pair(exit, struct) + else: # write remaining default connections + for (exit, struct) in default_connections: + if exit in exits: + set_pair(exit, struct) + + # Make sure we actually paired everything; might fail if plando + try: + assert len(exits) == len(structs) == 0 + except AssertionError: + raise Exception(f"Failed to connect all Minecraft structures for player {player} ({self.player_name})") + + for exit in exits_spoiler: + multiworld.get_entrance(exit, player).connect(multiworld.get_region(pairs[exit], player)) + if self.options.shuffle_structures or self.options.plando_connections: + multiworld.spoiler.set_entrance(exit, pairs[exit], 'entrance', player) diff --git a/apworld_src/minecraft/__init__.py b/apworld_src/minecraft/__init__.py new file mode 100644 index 0000000..b1c3de2 --- /dev/null +++ b/apworld_src/minecraft/__init__.py @@ -0,0 +1,280 @@ +import os +import json +import settings +import typing +from base64 import b64encode, b64decode +from typing import Dict, Any + +from BaseClasses import Region, Entrance, Item, Tutorial, ItemClassification, Location +from worlds.AutoWorld import World, WebWorld +from worlds.LauncherComponents import Component, components, Type, SuffixIdentifier + +from . import Constants +from .Container import MinecraftContainer +from .Options import MinecraftOptions +from .Structures import shuffle_structures +from .ItemPool import build_item_pool, get_junk_item_names +from .Rules import set_rules +from ..LauncherComponents import icon_paths + +client_version = 10 + +icon_paths['mcicon'] = f"ap:{__name__}/assets/mcicon.png" + +# register client +def launch_client(*args): + from .MinecraftClient import launch_subprocess + launch_subprocess(*args) + +components.append( + Component( + "Minecraft Client", + icon="mcicon", + func=launch_client, + component_type=Type.CLIENT, + file_identifier=SuffixIdentifier('.apmc'), + ) +) + + +class MinecraftSettings(settings.Group): + class ForgeDirectory(settings.OptionalUserFolderPath): + pass + + class ReleaseChannel(str): + """ + release channel, currently "release", or "beta" + any games played on the "beta" channel have a high likelihood of no longer working on the "release" channel. + """ + + class JavaExecutable(settings.OptionalUserFilePath): + """ + Path to Java executable. If not set, will attempt to fall back to Java system installation. + """ + + class ServerDirectory(settings.OptionalUserFolderPath): + """ + Path to local directory to install Java, Neo Forge, etc. + """ + @classmethod + def validate(cls, path: str): + if os.path.exists(path) and not os.path.isdir(path): + raise ValueError(f"'{path}' must be a folder") + + server_directory: ServerDirectory = ServerDirectory("Minecraft AP Server Directory") + max_heap_size: str = "2G" + min_heap_size: str = "1G" + release_channel: ReleaseChannel = ReleaseChannel("release") + java: JavaExecutable = JavaExecutable("") + + +class MinecraftWebWorld(WebWorld): + theme = "jungle" + bug_report_page = "https://github.com/qixils/NeoForgeAP/issues/new?assignees=&labels=bug&template=bug_report.yaml&title=%5BBug%5D%3A+Brief+Description+of+bug+here" + + setup = Tutorial( + "Multiworld Setup Guide", + "A guide to setting up the Archipelago Minecraft software on your computer. This guide covers" + "single-player, multiworld, and related software.", + "English", + "minecraft_en.md", + "minecraft/en", + ["qixils"] + ) + + setup_es = Tutorial( + setup.tutorial_name, + setup.description, + "Español", + "minecraft_es.md", + "minecraft/es", + ["Edos"] + ) + + setup_sv = Tutorial( + setup.tutorial_name, + setup.description, + "Swedish", + "minecraft_sv.md", + "minecraft/sv", + ["Albinum"] + ) + + setup_fr = Tutorial( + setup.tutorial_name, + setup.description, + "Français", + "minecraft_fr.md", + "minecraft/fr", + ["TheLynk"] + ) + + tutorials = [setup, setup_es, setup_sv, setup_fr] + + +class MinecraftWorld(World): + """ + Minecraft is a game about creativity. In a world made entirely of cubes, you explore, discover, mine, + craft, and try not to explode. Delve deep into the earth and discover abandoned mines, ancient + structures, and materials to create a portal to another world. Defeat the Ender Dragon, and claim + victory! + """ + game = "Minecraft" + options_dataclass = MinecraftOptions + options: MinecraftOptions + settings: typing.ClassVar[MinecraftSettings] + topology_present = True + web = MinecraftWebWorld() + + item_name_to_id = Constants.item_name_to_id + location_name_to_id = Constants.location_name_to_id + + using_ut: bool + passthrough: dict[str, Any] + ut_can_gen_without_yaml = True + + def _get_mc_data(self) -> Dict[str, Any]: + exits = [connection[0] for connection in Constants.region_info["default_connections"]] + return { + # Mod data + 'world_seed': self.random.getrandbits(32), + 'seed_name': self.multiworld.seed_name, + 'player_name': self.player_name, + 'player_id': self.player, + 'client_version': client_version, + 'structures': {exit: self.multiworld.get_entrance(exit, self.player).connected_region.name for exit in exits}, + 'advancement_goal': self.options.advancement_goal.value, + 'egg_shards_required': min(self.options.egg_shards_required.value, + self.options.egg_shards_available.value), + 'egg_shards_available': self.options.egg_shards_available.value, + 'required_bosses': self.options.required_bosses.current_key, + 'MC35': bool(self.options.send_defeated_mobs.value), + 'death_link': bool(self.options.death_link.value), + 'unlockable_hearts': bool(self.options.unlockable_hearts.value), + 'starting_items': json.dumps(self.options.starting_items.value), + 'race': self.multiworld.is_race, + + # Universal Tracker data + 'bosses_to_defeat': self.options.required_bosses.value, + 'shuffle_structures': self.options.shuffle_structures.value, + 'structure_compasses': self.options.structure_compasses.value, + 'combat_difficulty': self.options.combat_difficulty.value, + 'include_hard_advancements': self.options.include_hard_advancements.value, + 'include_unreasonable_advancements': self.options.include_unreasonable_advancements.value, + 'include_postgame_advancements': self.options.include_postgame_advancements.value, + 'unlockable_hearts': self.options.unlockable_hearts.value, + } + + def generate_early(self: "MinecraftWorld") -> None: + re_gen_passthrough = getattr(self.multiworld, "re_gen_passthrough", {}) + if re_gen_passthrough and self.game in re_gen_passthrough: + self.using_ut = True + self.passthrough = re_gen_passthrough["Minecraft"] + self.options.advancement_goal.value = self.passthrough["advancement_goal"] + self.options.egg_shards_required.value = self.passthrough["egg_shards_required"] + self.options.egg_shards_available.value = self.passthrough["egg_shards_available"] + self.options.required_bosses.value = self.passthrough["bosses_to_defeat"] + self.options.shuffle_structures.value = self.passthrough["shuffle_structures"] + self.options.structure_compasses.value = self.passthrough["structure_compasses"] + self.options.combat_difficulty.value = self.passthrough["combat_difficulty"] + self.options.include_hard_advancements.value = self.passthrough["include_hard_advancements"] + self.options.include_unreasonable_advancements.value = self.passthrough["include_unreasonable_advancements"] + self.options.include_postgame_advancements.value = self.passthrough["include_postgame_advancements"] + self.options.unlockable_hearts.value = self.passthrough.get("unlockable_hearts", 0) + self.options.death_link.value = self.passthrough["death_link"] + else: + self.using_ut = False + + def create_item(self, name: str) -> Item: + item_class = ItemClassification.filler + if name in Constants.item_info["progression_items"]: + item_class |= ItemClassification.progression + if name in Constants.item_info["useful_items"]: + item_class |= ItemClassification.useful + if name in Constants.item_info["trap_items"]: + item_class |= ItemClassification.trap + + return MinecraftItem(name, item_class, self.item_name_to_id.get(name, None), self.player) + + def create_event(self, region_name: str, event_name: str) -> None: + region = self.multiworld.get_region(region_name, self.player) + loc = MinecraftLocation(self.player, event_name, None, region) + loc.place_locked_item(self.create_event_item(event_name)) + region.locations.append(loc) + + def create_event_item(self, name: str) -> Item: + item = self.create_item(name) + item.classification = ItemClassification.progression + return item + + def create_regions(self) -> None: + # Create regions + for region_name, exits in Constants.region_info["regions"]: + r = Region(region_name, self.player, self.multiworld) + for exit_name in exits: + r.exits.append(Entrance(self.player, exit_name, r)) + self.multiworld.regions.append(r) + + # Bind mandatory connections + for entr_name, region_name in Constants.region_info["mandatory_connections"]: + e = self.multiworld.get_entrance(entr_name, self.player) + r = self.multiworld.get_region(region_name, self.player) + e.connect(r) + + # Add locations + for region_name, locations in Constants.location_info["locations_by_region"].items(): + region = self.multiworld.get_region(region_name, self.player) + for loc_name in locations: + loc = MinecraftLocation(self.player, loc_name, + self.location_name_to_id.get(loc_name, None), region) + region.locations.append(loc) + + # Add events + self.create_event("Nether Fortress", "Blaze Rods") + self.create_event("The End", "Ender Dragon") + self.create_event("Nether Fortress", "Wither") + + # Shuffle the connections + shuffle_structures(self) + + def create_items(self) -> None: + self.multiworld.itempool += build_item_pool(self) + + set_rules = set_rules + + def generate_output(self, output_directory: str) -> None: + data = self._get_mc_data() + filename = self.multiworld.get_out_file_name_base(self.player) + MinecraftContainer.patch_file_ending + + container = MinecraftContainer(data, + filename, + os.path.join(output_directory, filename), + self.player, + self.multiworld.get_file_safe_player_name(self.player), + ) + container.write() + + def fill_slot_data(self) -> dict: + return self._get_mc_data() + + def get_filler_item_name(self) -> str: + return get_junk_item_names(self.random, 1)[0] + + # For UT + @staticmethod + def interpret_slot_data(slot_data: dict[str, Any]) -> dict[str, Any]: + return slot_data + + +class MinecraftLocation(Location): + game = "Minecraft" + +class MinecraftItem(Item): + game = "Minecraft" + + +def mc_update_output(raw_data, server, port): + data = json.loads(b64decode(raw_data)) + data['server'] = server + data['port'] = port + return b64encode(bytes(json.dumps(data), 'utf-8')) diff --git a/apworld_src/minecraft/archipelago.json b/apworld_src/minecraft/archipelago.json new file mode 100644 index 0000000..66ce26e --- /dev/null +++ b/apworld_src/minecraft/archipelago.json @@ -0,0 +1 @@ +{"game": "Minecraft", "authors": ["qixils", "Seafo", "cjmang"], "minimum_ap_version": "0.6.3", "world_version": "2.1.3", "compatible_version": 7, "version": 7} \ No newline at end of file diff --git a/apworld_src/minecraft/assets/delete.png b/apworld_src/minecraft/assets/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..83c044b557a7a426b38b07f206975b6e676526f4 GIT binary patch literal 501 zcmVlWq&FwRKgU zhg$8F300k2YwJn3;9ey?2U6=-1Ehot#xmsrk_Q}5xeoyE05pO5D~??u#+awd)g+gE roR(K{t+h=DaY$%GHp_mWym#l9i1ajY00000NkvXXu0mjfm5|N7 literal 0 HcmV?d00001 diff --git a/apworld_src/minecraft/assets/edit.png b/apworld_src/minecraft/assets/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..e4827521713c6bac3a6a57088ddf1bb4ea3c9208 GIT binary patch literal 455 zcmV;&0XY7NP)_A#4l?kgQtZvA}~B4xpUcwuHdt zG}@j8_eGt#bM9nF$p^_@?|r9m0RYWWZ~&?B+yXKDcobY!J8^x56S<5JJs25Zy(c{>9)?<&lr$qVCWC* z{ylIFQP(^iICZgLaOFh24Fjerk{N~-GdoEPkgIR#-RKxNLsN|o4 zTB3S7T~GP!Q_b(Eh&lTwK3Gm$S@|gxDT$C)==|tMfy^_AUT)I45rbc>>Z5NZ$vt-@)k< zeIs1TYUu@^3)%^k9cRMb!y9%W#AkKibKK`~8s4$zxh}5&BY-8LhQa>@n}!khzUO$q|9AF~O(U-WBOud) z=tU*}3^*&z1mC+r-5&SdSF?bRp{Cd66%Zo>SR{}MT+G3BtRZKb{3dw?7y6S<5JJs25Zy(c{>9)?<&lr$qVCWC* z{ylIFQP(^iICZgLaOFh24Fjerk{N~-GdoEPkgIR#-RKxNLsN|o4 zTB3S7T~GP!Q_b(Eh&lTwK3Gm$S@|gxDT$C)==|tMfy^_AUT)I45rbc>>Z5NZ$vt-@)k< zeIs1TYUu@^3)%^k9cRMb!y9%W#AkKibKK`~8s4$zxh}5&BY-8LhQa>@n}!khzUO$q|9AF~O(U-WBOud) z=tU*}3^*&z1mC+r-5&SdSF?bRp{Cd66%Zo>SR{}MT+G3BtRZKb{3dw?7y Direct Connection`, and join the `localhost` server address. + +If you are using the website to host the game then it should auto-connect to the AP server without the need to `/connect`. + +Otherwise, once you are in-game, type `/connect (Port) (Password)`, where `` is the address of the +Archipelago server. `(Port)` is only required if the Archipelago server is not using the default port of 38281. +Note that there is no colon between `` and `(Port)`. +`(Password)` is only required if the Archipelago server you are using has a password set. + +_Example usage: `/connect archipelago.gg 38281 password123`_ + +### Play the game + +When the console tells you that you have joined the room, you're all set. Congratulations on successfully joining a +multiworld game! At this point any additional minecraft players may connect to your NeoForge server. To start the game once +everyone is ready use the command `/start`. + +## Non-Windows Installation + +The Minecraft Client will install NeoForge and the Archipelago mod. +On supported operating systems, it will additionally download a local copy of the Temurin JRE. + +For other operating systems, you will need to have a Java installation available on your system path to install and launch the server. +Head to [minecraft_versions.json] +to see which Java version is required. +When in doubt, the latest release of Java should almost always work on modern (1.17+) releases of Minecraft. + +- Install the matching Java JRE + - see [Manual Installation Software Links](#manual-installation-software-links) + - or package manager provided by your OS / distribution +- For non-installed downloads, open your `host.yaml` and add the path to your Java below the `minecraft_options` key + - `java: "path/to/jdk-XX.X.X+X-jre/bin/java"` +- Run the Minecraft Client and select your .apmc file + +## Full Manual Installation + +If you're crafty, the Archipelago client is fully optional. +The following steps may help you setup an Archipelago on a remotely hosted server. +Exact version numbers are omitted; refer to [minecraft_versions.json] for specifics. + +- Download and install a compatible version of Java +- Download and install a local NeoForge server +- Download the NeoForgeAP mod and copy it to your `mods` folder +- Download your randomized .apmc file and copy it to a new `APData` folder + +### Manual Installation Software Links + +- [Minecraft NeoForge Download Page](https://neoforged.net/) +- [Minecraft Archipelago Randomizer Mod Releases Page](https://github.com/qixils/NeoForgeAP/releases) + - Please note that the mod runs only on the server side and is not intended to be installed to your Minecraft client. +- [Java JRE (Temurin)](https://adoptium.net/temurin/releases?arch=x64&package=jre) + - Download the "JRE" package for your operating system + + + + +[minecraft_version.json](https://raw.githubusercontent.com/qixils/NeoForgeAP/main/versions/minecraft_versions.json) diff --git a/apworld_src/minecraft/docs/minecraft_es.md b/apworld_src/minecraft/docs/minecraft_es.md new file mode 100644 index 0000000..30ed690 --- /dev/null +++ b/apworld_src/minecraft/docs/minecraft_es.md @@ -0,0 +1,148 @@ +# Guia instalación de Minecraft Randomizer + +# Instalacion automatica para el huesped de partida + +- descarga e instala [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) and activa el + modulo `Minecraft Client` + +## Software Requerido + +- [Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) + +## Configura tu fichero YAML + +### Que es un fichero YAML y potque necesito uno? + +Tu fichero YAML contiene un numero de opciones que proveen al generador con informacion sobre como debe generar tu +juego. Cada jugador de un multiworld entregara u propio fichero YAML. Esto permite que cada jugador disfrute de una +experiencia personalizada a su gusto y diferentes jugadores dentro del mismo multiworld pueden tener diferentes opciones + +### Where do I get a YAML file? + +Un fichero basico yaml para minecraft tendra este aspecto. + +```yaml +description: Basic Minecraft Yaml +# Tu nombre en el juego. Espacios seran sustituidos por guinoes bajos y +# hay un limite de 16 caracteres +name: TuNombre +game: Minecraft + +# Opciones compartidas por todos los juegos: +accessibility: full +progression_balancing: 50 +# Opciones Especficicas para Minecraft + +Minecraft: + # Numero de logros requeridos (87 max) para que aparezca el Ender Dragon y completar el juego. + advancement_goal: 50 + + # Numero de trozos de huevo de dragon a obtener (30 max) antes de que el Ender Dragon aparezca. + egg_shards_required: 10 + + # Numero de huevos disponibles en la partida (30 max). + egg_shards_available: 15 + + # Modifica el nivel de objetos logicamente requeridos para + # explorar areas peligrosas y luchar contra jefes. + combat_difficulty: + easy: 0 + normal: 1 + hard: 0 + + # Si off, los logros que dependan de suerte o sean tediosos tendran objetos de apoyo, no necesarios para completar el juego. + include_hard_advancements: + on: 0 + off: 1 + + # Si off, los logros muy dificiles tendran objetos de apoyo, no necesarios para completar el juego. + # Solo afecta a How Did We Get Here? and Adventuring Time. + include_insane_advancements: + on: 0 + off: 1 + + # Algunos logros requieren derrotar al Ender Dragon; + # Si esto se queda en off, dichos logros no tendran objetos necesarios. + include_postgame_advancements: + on: 0 + off: 1 + + # Permite el mezclado de villas, puesto, fortalezas, bastiones y ciudades de END. + shuffle_structures: + on: 0 + off: 1 + + # Añade brujulas de estructura al juego, + # apuntaran a la estructura correspondiente mas cercana. + structure_compasses: + on: 0 + off: 1 + + # Reemplaza un porcentaje de objetos innecesarios por trampas abeja + # las cuales crearan multiples abejas agresivas alrededor de los jugadores cuando se reciba. + bee_traps: + 0: 1 + 25: 0 + 50: 0 + 75: 0 + 100: 0 +``` + +## Unirse a un juego MultiWorld + +### Obten tu ficheros de datos Minecraft + +**Solo un fichero yaml es necesario por mundo minecraft, sin importar el numero de jugadores que jueguen en el.** + +Cuando te unes a un juego multiworld, se te pedirá que entregues tu fichero YAML a quien sea que hospede el juego +multiworld (no confundir con hospedar el mundo minecraft). Una vez la generación acabe, el anfitrión te dará un enlace a +tu fichero de datos o un zip con los ficheros de todos. Tu fichero de datos tiene una extensión `.apmc`. + +Haz doble click en tu fichero `.apmc` para que se arranque el cliente de minecraft y el servidor forge se ejecute. + +### Conectar al multiserver + +Despues de poner tu fichero en el directorio `APData`, arranca el Forge server y asegurate que tienes el estado OP +tecleando `/op TuUsuarioMinecraft` en la consola del servidor y entonces conectate con tu cliente Minecraft. + +Una vez en juego introduce `/connect (Port) ()` donde `` es la dirección del +servidor. `(Port)` solo es requerido si el servidor Archipelago no esta usando el puerto por defecto 38281. +`()` +solo se necesita si el servidor Archipleago tiene un password activo. + +### Jugar al juego + +Cuando la consola te diga que te has unido a la sala, estas lista/o para empezar a jugar. Felicidades por unirte +exitosamente a un juego multiworld! Llegados a este punto cualquier jugador adicional puede conectarse a tu servidor +forge. + +## Procedimiento de instalación manual + +Solo es requerido si quieres usar una instalacion de forge por ti mismo, recomendamos usar el instalador de Archipelago + +### Software Requerido + +- [Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html) +- [Minecraft Archipelago Randomizer Mod](https://github.com/qixils/NeoForgeAP/releases) + **NO INSTALES ESTO EN TU CLIENTE MINECRAFT** + +### Instalación de servidor dedicado + +Solo una persona ha de realizar este proceso y hospedar un servidor dedicado para que los demas jueguen conectandose a +él. + +1. Descarga el instalador de **Minecraft Forge** 1.16.5 desde el enlace proporcionado, siempre asegurandose de bajar la + version mas reciente. + +2. Ejecuta el fichero `forge-1.16.5-xx.x.x-installer.jar` y elije **install server**. + - En esta pagina elegiras ademas donde instalar el servidor, importante recordar esta localización en el siguiente + paso. + +3. Navega al directorio donde hayas instalado el servidor y abre `forge-1.16.5-xx.x.x.jar` + - La primera vez que lances el servidor se cerrara (o no aparecerá nada en absoluto), debería haber un fichero nuevo + en el directorio llamado `eula.txt`, el cual que contiene un enlace al EULA de minecraft, cambia la linea + a `eula=true` para aceptar el EULA y poder utilizar el software de servidor. + - Esto creara la estructura de directorios apropiada para el siguiente paso + +4. Coloca el fichero `aprandomizer-x.x.x.jar` del segundo enlace en el directorio `mods` + - Cuando se ejecute el servidor de nuevo, generara el directorio `APData` que se necesitara para jugar diff --git a/apworld_src/minecraft/docs/minecraft_fr.md b/apworld_src/minecraft/docs/minecraft_fr.md new file mode 100644 index 0000000..15b6d5a --- /dev/null +++ b/apworld_src/minecraft/docs/minecraft_fr.md @@ -0,0 +1,74 @@ +# Guide de configuration du randomiseur Minecraft + +## Logiciel requis + +- Minecraft Java Edition à partir de + la [page de la boutique Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) +- Archipelago depuis la [page des versions d'Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) + - (sélectionnez `Minecraft Client` lors de l'installation.) + +## Configuration de votre fichier YAML + +### Qu'est-ce qu'un fichier YAML et pourquoi en ai-je besoin ? + +Voir le guide sur la configuration d'un YAML de base lors de la configuration d'Archipelago +guide : [Guide de configuration de base de Multiworld](/tutorial/Archipelago/setup/en) + +### Où puis-je obtenir un fichier YAML ? + +Vous pouvez personnaliser vos paramètres Minecraft en allant sur la [page des paramètres de joueur](/games/Minecraft/player-options) + +## Rejoindre une partie MultiWorld + +### Obtenez votre fichier de données Minecraft + +**Un seul fichier yaml doit être soumis par monde minecraft, quel que soit le nombre de joueurs qui y jouent.** + +Lorsque vous rejoignez un jeu multimonde, il vous sera demandé de fournir votre fichier YAML à l'hébergeur. Une fois cela fait, +l'hébergeur vous fournira soit un lien pour télécharger votre fichier de données, soit un fichier zip contenant les données de chacun +des dossiers. Votre fichier de données doit avoir une extension `.apmc`. + +Double-cliquez sur votre fichier `.apmc` pour que le client Minecraft lance automatiquement le serveur forge installé. Assurez-vous de +laissez cette fenêtre ouverte car il s'agit de votre console serveur. + +### Connectez-vous au multiserveur + +Ouvrez Minecraft, accédez à "Multijoueur> Connexion directe" et rejoignez l'adresse du serveur "localhost". + +Si vous utilisez le site Web pour héberger le jeu, il devrait se connecter automatiquement au serveur AP sans avoir besoin de `/connect` + +sinon, une fois que vous êtes dans le jeu, tapez `/connect (Port) (Password)` où `` est l'adresse du +Serveur Archipelago. `(Port)` n'est requis que si le serveur Archipelago n'utilise pas le port par défaut 38281. Notez qu'il n'y a pas de deux-points entre `` et `(Port)` mais un espace. +`(Mot de passe)` n'est requis que si le serveur Archipelago que vous utilisez a un mot de passe défini. + +### Jouer le jeu + +Lorsque la console vous indique que vous avez rejoint la salle, vous êtes prêt. Félicitations pour avoir rejoint avec succès un +jeu multimonde ! À ce stade, tous les joueurs minecraft supplémentaires peuvent se connecter à votre serveur forge. Pour commencer le jeu une fois +que tout le monde est prêt utilisez la commande `/start`. + +## Installation non Windows + +Le client Minecraft installera forge et le mod pour d'autres systèmes d'exploitation, mais Java doit être fourni par l' +utilisateur. Rendez-vous sur [minecraft_versions.json sur le MC AP GitHub](https://raw.githubusercontent.com/qixils/NeoForgeAP/master/versions/minecraft_versions.json) +pour voir quelle version de Java est requise. Les nouvelles installations utiliseront par défaut la version "release" la plus élevée. +- Installez le JDK Amazon Corretto correspondant + - voir les [Liens d'installation manuelle du logiciel](#manual-installation-software-links) + - ou gestionnaire de paquets fourni par votre OS/distribution +- Ouvrez votre `host.yaml` et ajoutez le chemin vers votre Java sous la clé `minecraft_options` + - ` java : "chemin/vers/java-xx-amazon-corretto/bin/java"` +- Exécutez le client Minecraft et sélectionnez votre fichier .apmc + +## Installation manuelle complète + +Il est fortement recommandé d'utiliser le programme d'installation d'Archipelago pour gérer l'installation du serveur forge pour vous. +Le support ne sera pas fourni pour ceux qui souhaitent installer manuellement forge. Pour ceux d'entre vous qui savent comment faire et qui souhaitent le faire, +les liens suivants sont les versions des logiciels que nous utilisons. + +### Liens d'installation manuelle du logiciel + +- [Page de téléchargement de Minecraft Forge] (https://files.minecraftforge.net/net/minecraftforge/forge/) +- [Page des versions du mod Minecraft Archipelago Randomizer] (https://github.com/qixils/NeoForgeAP/releases) + - **NE PAS INSTALLER CECI SUR VOTRE CLIENT** +- [Amazon Corretto](https://docs.aws.amazon.com/corretto/) + - choisissez la version correspondante et sélectionnez "Téléchargements" sur la gauche diff --git a/apworld_src/minecraft/docs/minecraft_sv.md b/apworld_src/minecraft/docs/minecraft_sv.md new file mode 100644 index 0000000..acf848e --- /dev/null +++ b/apworld_src/minecraft/docs/minecraft_sv.md @@ -0,0 +1,132 @@ +# Minecraft Randomizer Uppsättningsguide + +## Nödvändig Mjukvara + +### Server Värd + +- [Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.16.5.html) +- [Minecraft Archipelago Randomizer Mod](https://github.com/qixils/NeoForgeAP/releases) + +### Spelare + +- [Minecraft Java Edition](https://www.minecraft.net/en-us/store/minecraft-java-edition) + +## Installationsprocedurer + +### Tillägnad + +Bara en person behöver göra denna uppsättning och vara värd för en server för alla andra spelare att koppla till. + +1. Ladda ner 1.16.5 **Minecraft Forge** installeraren från länken ovanför och se till att ladda ner den senaste + rekommenderade versionen. + +2. Kör `forge-1.16.5-xx.x.x-installer.jar` filen och välj **installera server**. + - På denna sida kommer du också välja vart du ska installera servern för att komma ihåg denna katalog. Detta är + viktigt för nästa steg. + +3. Navigera till vart du har installerat servern och öppna `forge-1.16.5-xx.x.x-installer.jar` + - Under första serverstart så kommer den att stängas ner och fråga dig att acceptera Minecrafts EULA. En ny fil + kommer skapas vid namn `eula.txt` som har en länk till Minecrafts EULA, och en linje som du behöver byta + till `eula=true` för att acceptera Minecrafts EULA. + - Detta kommer skapa de lämpliga katalogerna för dig att placera filerna i de följande steget. + +4. Placera `aprandomizer-x.x.x.jar` länken ovanför i `mods` mappen som ligger ovanför installationen av din forge + server. + - Kör servern igen. Den kommer ladda up och generera den nödvändiga katalogen `APData` för när du är redo att spela! + +### Grundläggande Spelaruppsättning + +- Köp och installera Minecraft från länken ovanför. + + **Du är klar**. + + Andra spelare behöver endast ha en 'Vanilla' omodifierad version av Minecraft för att kunna spela! + +### Avancerad Spelaruppsättning + +***Detta är inte nödvändigt för att spela ett slumpmässigt Minecraftspel.*** +Dock så är det rekommenderat eftersom det hjälper att göra upplevelsen mer trevligt. + +#### Rekommenderade Moddar + +- [JourneyMap](https://www.curseforge.com/minecraft/mc-mods/journeymap) (Minimap) + + +1. Installera och Kör Minecraft från länken ovanför minst en gång. +2. Kör `forge-1.16.5-xx.x.x-installer.jar` filen och välj **installera klient**. + - Starta Minecraft Forge minst en gång för att skapa katalogerna som behövs för de nästa stegen. +3. Navigera till din Minecraft installationskatalog och placera de önskade moddarna med `.jar` i `mods` -katalogen. + - Standardinstallationskatalogerna är som följande; + - Windows `%APPDATA%\.minecraft\mods` + - macOS `~/Library/Application Support/minecraft/mods` + - Linux `~/.minecraft/mods` + +## Konfigurera Din YAML-fil + +### Vad är en YAML-fil och varför behöver jag en? + +Din YAML-fil behåller en uppsättning av konfigurationsalternativ som ger generatorn med information om hur den borde +generera ditt spel. Varje spelare i en multivärld kommer behöva ge deras egen YAML-fil. Denna uppsättning tillåter varje +spelare att an njuta av en upplevelse anpassade för deras smaker, och olika spelare i samma multivärld kan ha helt olika +alternativ. + +### Vart kan jag få tag i en YAML-fil? + +En grundläggande Minecraft YAML kommer se ut så här. + +```yaml +description: Template Name +# Ditt spelnamn. Mellanslag kommer bli omplacerad med understräck och det är en 16-karaktärsgräns. +name: YourName +game: Minecraft +accessibility: full +progression_balancing: 0 +advancement_goal: + few: 0 + normal: 1 + many: 0 +combat_difficulty: + easy: 0 + normal: 1 + hard: 0 +include_hard_advancements: + on: 0 + off: 1 +include_insane_advancements: + on: 0 + off: 1 +include_postgame_advancements: + on: 0 + off: 1 +shuffle_structures: + on: 1 + off: 0 +``` + + +## Gå med i ett Multivärld-spel + +### Skaffa din Minecraft data-fil + +**Endast en YAML-fil behöver användats per Minecraft-värld oavsett hur många spelare det är som spelar.** + +När du går med it ett Multivärld spel så kommer du bli ombedd att lämna in din YAML-fil till personen som värdar. När +detta är klart så kommer värden att ge dig antingen en länk till att ladda ner din data-fil, eller mer en zip-fil som +innehåller allas data-filer. Din data-fil borde ha en `.apmc` -extension. + +Lägg din data-fil i dina forge-servrar `APData` -mapp. Se till att ta bort alla tidigare data-filer som var i där förut. + +### Koppla till Multiservern + +Efter du har placerat din data-fil i `APData` -mappen, starta forge-servern och se till att you har OP-status genom att +skriva `/op DittAnvändarnamn` i forger-serverns konsol innan du kopplar dig till din Minecraft klient. När du är inne i +spelet, skriv `/connect ()` där `` är addressen av +Archipelago-servern. `()` är endast nödvändigt om Archipelago-servern som du använder har ett tillsatt +lösenord. + +### Spela spelet + +När konsolen har informerat att du har gått med i rummet så är du redo att börja spela. Grattis att du har lykats med +att gått med i ett Multivärld-spel! Vid detta tillfälle, alla ytterligare Minecraft-spelare må koppla in till din +forge-server. + diff --git a/apworld_src/minecraft/downloader/Java.py b/apworld_src/minecraft/downloader/Java.py new file mode 100644 index 0000000..afa30f3 --- /dev/null +++ b/apworld_src/minecraft/downloader/Java.py @@ -0,0 +1,148 @@ +import logging +import shutil +import tempfile + +from . import StepsStep, SyncStep +from .Utilities import DownloadStep, FetchStep, jre_paths +from Utils import is_windows, is_linux +import os +import zipfile +import platform +import tarfile +from typing import TypedDict, Any + + +class Download(TypedDict): + checksum: str + checksum_link: str + download_count: int + link: str + metadata_link: str + name: str + signature_link: str + size: int + +class Binary(TypedDict): + architecture: str + download_count: int + heap_size: str + image_type: str + installer: Download + jvm_impl: str + os: str + package: Download + project: str + scm_ref: str + updated_at: str + +class Version(TypedDict): + build: int + major: int + minor: int + openjdk_version: str + optional: str + security: int + semver: str + +class Asset(TypedDict): + binary: Binary + release_link: str + release_name: str + vendor: str + version: Version + +class DownloadJava(StepsStep): + def __init__(self, to: str, version: int): + self.to = to + self.version = version + self.outpath = os.path.join(to, "java", jre_paths[self.version]) + self.zip_path = os.path.join(self.outpath, "jre.zip") + self.logger = logging.getLogger("MinecraftClient") + super().__init__( + f"Downloading Java {version}...", + SyncStep(self._get_api_url), + FetchStep(), + SyncStep(self._process_assets), + DownloadStep(filepath=self.zip_path), + SyncStep(self._process_extract), + ) + + def run(self, context, *args, **kwargs): + context['java_dir'] = self.outpath + super().run(context, *args, **kwargs) + + def _get_api_url(self, context: dict[str, Any]) -> str: + self.logger.info(f"Fetching Java {self.version} versions") + + system = "windows" if is_windows else "linux" if is_linux else None + if not system: + raise Exception("Unsupported operating system for Java download") + + arch = "aarch64" if platform.machine() in ["aarch64", "arm64"] else "x64" + + return f"https://api.adoptium.net/v3/assets/latest/{self.version}/hotspot?architecture={arch}&image_type=jre&os={system}&vendor=eclipse" + + def _process_assets(self, context: dict[str, Any], assets: list[Asset]) -> tuple: + data: Asset = assets[0] + os.makedirs(self.outpath, exist_ok=True) + release_path = os.path.join(self.outpath, "release") + semver = None + + if os.path.exists(release_path): + with open(release_path, 'r') as file: + info = file.read() + semver = info.split('SEMANTIC_VERSION="')[1].split('"')[0] + self.logger.info(f"Received semver: {data['version']['semver']} local ver: {semver}") + if data["version"]["semver"] == semver: + self.logger.info("Already up-to-date, skipping download") + return False + + self.logger.info(f"Downloading Java {data['version']['semver']}") + context['java_semver'] = data['version']['semver'] + return data["binary"]["package"]["link"], None, data['version']['semver'] + + def _process_extract(self,context: dict[str, Any], res): + if not res: + # download is skipped + return + + self.logger.info(f"Extracting Java {self.version}") + # TODO: this probably also needs a mac flow, for .pkg files + if is_linux: + with tempfile.TemporaryDirectory() as temp_dir: + with tarfile.open(self.zip_path, 'r') as tarball: + tarball.extractall(temp_dir, filter='tar') + items = os.listdir(temp_dir) + if len(items) == 1 and os.path.isdir(os.path.join(temp_dir, items[0])): + original_dir = os.path.join(temp_dir, items[0]) + else: + original_dir = temp_dir + shutil.copytree(original_dir, self.outpath, dirs_exist_ok=True) + else: + with zipfile.ZipFile(self.zip_path, 'r') as zip_ref: + subfolder = zip_ref.namelist()[0] + for entry in zip_ref.infolist()[1:]: + if entry.is_dir(): + continue + relative = entry.filename[len(subfolder):] + filepath = os.path.join(self.outpath, *relative.split("/")) + dirpath = os.path.dirname(filepath) + os.makedirs(dirpath, exist_ok=True) + with open(filepath, 'wb') as file: + file.write(zip_ref.read(entry.filename)) + + os.remove(self.zip_path) + +def get_java_path(to: str, version: int) -> str: + jre = jre_paths[version] + + bin = "javaw.exe" if is_windows else "java" if is_linux else None + if not bin: + raise Exception("Unsupported operating system for Java path retrieval") + + java_path = os.path.join(to, "java", jre, "bin", bin) + + if not os.path.exists(java_path): + raise Exception(f"Java {version} not found at {java_path}") + + return java_path diff --git a/apworld_src/minecraft/downloader/Modrinth.py b/apworld_src/minecraft/downloader/Modrinth.py new file mode 100644 index 0000000..02f9ac5 --- /dev/null +++ b/apworld_src/minecraft/downloader/Modrinth.py @@ -0,0 +1,56 @@ +from .Utilities import DownloadStep, FetchStep, download_file, ua_header +from . import StepsStep, SyncStep +from typing import TypedDict +import os +import requests + +class ModrinthFile(TypedDict): + url: str + primary: bool + +class ModrinthVersion(TypedDict): + id: str + game_versions: list[str] + files: list[ModrinthFile] + +class DownloadMod(StepsStep): + def __init__(self, destination_folder: str, platform: str, game_version: str, project: str, filename: str): + self.destination_folder = destination_folder + self.platform = platform + self.game_version = game_version + self.project = project + self.filename = filename + self.jar_path = os.path.join(destination_folder, filename) + + super().__init__( + SyncStep(lambda: print(f"Downloading mod {project} for {platform} {game_version}")), + FetchStep(f"https://api.modrinth.com/v2/project/{project}/version?loaders={platform}"), + SyncStep(self._process_versions), + DownloadStep(filepath=self.jar_path), + SyncStep(lambda: self.version), + ) + + def _process_versions(self, versions: list[ModrinthVersion]) -> str: + self.version = next((ver for ver in versions if self.game_version in ver["game_versions"]), None) + if not self.version: + raise Exception(f"No version found for {self.platform} {self.game_version}") + + return self.version["files"][0]["url"] + +def download_mod(destination_folder: str, platform: str, game_version: str, project: str, filename: str) -> ModrinthVersion: + print(f"Downloading mod {project} for {platform} {game_version}") + + versions = requests.get( + f"https://api.modrinth.com/v2/project/{project}/version?loaders={platform}", + headers=ua_header, + ).json() + + version = next((ver for ver in versions if game_version in ver["game_versions"]), None) + if not version: + raise Exception(f"No version found for {platform} {game_version}") + + url = version["files"][0]["url"] + jar_path = os.path.join(destination_folder, filename) + download_file(jar_path, url, version=version["id"]) + + return version diff --git a/apworld_src/minecraft/downloader/NeoForge.py b/apworld_src/minecraft/downloader/NeoForge.py new file mode 100644 index 0000000..2754d7a --- /dev/null +++ b/apworld_src/minecraft/downloader/NeoForge.py @@ -0,0 +1,166 @@ +import logging + +from .Utilities import DownloadStep, FetchStep, SubprocessStep +from .Java import get_java_path +from . import ServerInstallData, StepsStep, SyncStep, Step +from typing import TypedDict, Any, Callable +import Utils +import os +import subprocess + +class NeoVersions(TypedDict): + isSnapshot: bool + versions: list[str] + +class DownloadNeoForge(StepsStep): + def __init__(self, to: str, + eula_popup: Callable, + force_version: str | None = None, + heap: str = "2048M"): + self.name = f"Downloading {force_version if force_version else 'latest'} NeoForge..." + + self.to = to + self.force_version = (force_version.split(".", 1)[1] + ".") if force_version else None + self.heap = heap + self.installer_jar = os.path.join(to, f"neoforge-installer.jar") + self.logger = logging.getLogger("MinecraftClient") + + super().__init__( + "Installing Neo Forge", + SyncStep(lambda *args: print(f"Downloading NeoForge index")), + FetchStep("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge"), + SyncStep(self._process_versions), + ConfirmEula(eula_popup), + DownloadStep(filepath=self.installer_jar), + SyncStep(self._process_server), + SubprocessStep("Installing NeoForge"), + SyncStep(self._process_cleanup), + ) + + def _process_versions(self,context: dict[str, Any], neo_versions: NeoVersions) -> str: + self.neo_latest = next( + (ver for ver in reversed(neo_versions["versions"]) if self.force_version is None or ver.startswith(self.force_version)), + None + ) + + if not self.neo_latest: + raise Exception("No suitable NeoForge version found") + + self.minecraft = f"1.{'.'.join(self.neo_latest.split('.', 2)[:2])}" + + self.root = os.path.join(self.to, f"NeoForge {self.minecraft}") + os.makedirs(self.root, exist_ok=True) + + self.java_path = get_java_path(self.to, 21) + self.java_path_relative = os.path.relpath(self.java_path, self.root) + self.logger.info(f"Using Java at {self.java_path}") + + self.all_run = [self.java_path, f"-Xmx{self.heap}", f"-Xms{self.heap}", "@user_jvm_args.txt"] + self.windows_run = self.all_run + [f"@libraries/net/neoforged/neoforge/{self.neo_latest}/win_args.txt"] + self.unix_run = self.all_run + [f"@libraries/net/neoforged/neoforge/{self.neo_latest}/unix_args.txt"] + self.system_run = self.windows_run if Utils.is_windows else (self.unix_run if Utils.is_linux else None) + + self.mods = os.path.join(self.root, "mods") + os.makedirs(self.mods, exist_ok=True) + + self.version_path = os.path.join(self.root, "neo_version") + context['neoforge_dir'] = self.root + context['neoforge_mod_dir'] = self.mods + context['neoforge_run_args'] = self.system_run + + if os.path.exists(self.version_path): + with open(self.version_path, 'r') as f: + if f.read().strip() == self.neo_latest: + self.logger.info(f"NeoForge {self.neo_latest} is already installed, skipping download") + return False + + self.logger.info(f"Downloading NeoForge {self.neo_latest} installer") + return f"https://maven.neoforged.net/releases/net/neoforged/neoforge/{self.neo_latest}/neoforge-{self.neo_latest}-installer.jar", None, self.neo_latest + + def _process_server(self, context: dict[str, Any], req): + if req is False: + # install is skipped + return + + self.logger.info(f"Running NeoForge {self.neo_latest} installer") + java_path = get_java_path(self.to, 21) + return (java_path, "-jar", self.installer_jar, "--installServer"), {"cwd": self.root, "stderr": subprocess.DEVNULL, "stdout": subprocess.DEVNULL} + + def _process_cleanup(self, context: dict[str, Any], req): + bat_file = os.path.join(self.root, "run.bat") + sh_file = os.path.join(self.root, "run.sh") + context['neoforge_run'] = bat_file if Utils.is_windows else (sh_file if Utils.is_linux else None) + + if req is False: + # install is skipped + return ServerInstallData(root_dir=self.root, mods_dir=self.mods, run_args=self.system_run) + + os.unlink(self.installer_jar) + os.unlink(self.installer_jar + '.version') + + # we don't actually use these ourselves but they're nice to have + # (although they are not very well tested) + with open(bat_file, 'w') as f: + windows_run = list(self.windows_run) + windows_run[0] = f'&"{windows_run[0]}"' + f.write(f"@echo off\nstart {' '.join(windows_run)} %* > log.txt 2> errorlog.txt") + + with open(sh_file, 'w') as f: + unix_run = list(self.unix_run) + unix_run[0] = unix_run[0].replace(' ', '\\ ') + f.write(f"#!/bin/bash\nexec {' '.join(self.unix_run)} \"$@\" > log.txt 2> errorlog.txt") + + with open(self.version_path, 'w') as f: + f.write(self.neo_latest) + + return ServerInstallData(root_dir=self.root, mods_dir=self.mods, run_args=self.system_run) + +class ConfirmEula(Step): + + def __init__(self, confirm_prompt: Callable): + super().__init__() + self.logger = logging.Logger("MinecraftClient") + self.confirm_prompt = confirm_prompt + self.outdir: str | None = None + + def run(self, + context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable | None = None, + error_ok: bool = False): + + if not previous or not previous[0]: + on_success(False) + return + + if 'neoforge_dir' not in context: + on_success(False) + return + + self.outdir = context['neoforge_dir'] + file = os.path.join(self.outdir, "eula.txt") + if os.path.exists(file): + with open(file, 'r') as f: + if 'eula=true' in f.read(): + on_success(*previous) + return + + success_fn = lambda *args: self.confirmed(previous, on_success) + self.confirm_prompt( + confirm=success_fn, + title="Minecraft Eula", + content=""" + Please note that by running a Minecraft server, + you are indicating your agreement to Minecraft's + EULA (https://aka.ms/MinecraftEULA).""", + cancel=on_failure, + ) + + def confirmed(self, previous, on_success: Callable | None = None): + self.logger.info(f"confirmed {previous}") + contents = "eula=true" + with open(os.path.join(self.outdir, 'eula.txt'), 'w') as f: + f.write(contents) + on_success(*previous) diff --git a/apworld_src/minecraft/downloader/Utilities.py b/apworld_src/minecraft/downloader/Utilities.py new file mode 100644 index 0000000..a106a59 --- /dev/null +++ b/apworld_src/minecraft/downloader/Utilities.py @@ -0,0 +1,193 @@ +import logging +import os +import subprocess +import threading + +import certifi +import requests +from typing import Any, Callable, Optional +from . import Step +from kivy.network.urlrequest import UrlRequest, UrlRequestRequests + +ua = "qixils/minecraft-crowdcontrol/1.0.0" +ua_header = {"User-Agent": ua} + +jre_paths: dict[int, str] = { + 8: "jdk-8", + 21: "jdk-21", +} + +# TODO: headers +# TODO: redirects + +class DownloadStep(Step): + def __init__(self, url: str | None = None, filepath: str | None = None): + super().__init__() + self.filepath = filepath + self.url = url + self.logger = logging.getLogger("MinecraftClient") + + def run(self, + context: dict[str, Any], + *args, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + url = self.url + filepath = self.filepath + version = None + self.logger.info(f"Got arguments {args}") + if len(args) > 0: + url = args[0] or url + if len(args) > 1: + filepath = args[1] or filepath + if len(args) > 2: + version = args[2] or version + + if callable(url): + url = url() + if callable(filepath): + filepath = filepath() + if callable(version): + version = version() + + self.filepath = filepath + # If we were passed a blank URL then we assume this skip should be skipped for already being downloaded + if not url or not filepath: + if on_success is not None: + on_success(False) + return + + # Optionally check if a file with a matching version is already downloaded + version_path = filepath + ".version" + if version is not None: + if os.path.exists(version_path): + with open(version_path, 'r') as f: + if f.read().strip() == version: + on_success(False) + return + self.logger.info(f"Sending request to {url}; downloading to {filepath}") + # Using requests over urllib, cause redirects + UrlRequestRequests(url, + file_path=filepath, + on_progress=lambda req, current_size, total_size: on_progress is not None and on_progress(current_size / total_size if total_size > 0 else 0, f"Downloading {os.path.basename(filepath)}..."), + on_success=lambda req, res: self._on_success(res, version=version, on_success=on_success), + on_error=on_failure, + on_redirect= lambda req, res: self.logger.info(f"{req}, {res}, {req.resp_status} {req.resp_headers}"), + chunk_size=1024000, + # ca_file=certifi.where() + ) + + def _on_success(self, res, version: str | None = None, on_success: Callable | None = None): + with open(self.filepath + ".version", 'w') as f: + f.write(version) + if on_success is not None: + on_success(res or True) + +class FetchStep(Step): + def __init__(self, url: str | None = None): + super().__init__() + self.url = url + self.logger = logging.getLogger("MinecraftClient") + + def run(self, + context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + if previous: + url = previous[0] if previous[0] is not None and type(previous[0]) is str else self.url + self.logger.info(f"Requesting to url: {url}") + payload_lambda = lambda req, resp: on_success(resp) + UrlRequest(url, + on_progress=lambda req, current_size, total_size: on_progress is not None and on_progress(current_size / total_size, "Loading data..."), + on_success=payload_lambda, + on_error=on_failure, + ca_file=certifi.where()) + +class SubprocessStep(Step): + def __init__(self, name: str, *args): + super().__init__() + self.args = args + self.logger = logging.getLogger("MinecraftClient") + self.name = name + + def run(self, + context: dict[str, Any], + *previous, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable | None = None, + error_ok: bool = False): + args = previous if len(previous) > 0 else self.args + + if args is None or len(args) == 0 or not args[0]: + on_success(False) + return + self.logger.info(f"Arguments: {args}") + thread = threading.Thread(target=self._run_in_thread, args=(on_success, args)) + thread.start() + + @staticmethod + def _run_in_thread(on_exit: Callable, popen_args: tuple): + logger = logging.getLogger("MinecraftClient") + kwargs = dict() + logger.info(f"Arguments: {popen_args}") + if type(popen_args[-1]) is dict: + kwargs = popen_args[-1] + popen_args = popen_args[:-1] + logger.info(f"Arguments: {popen_args} {kwargs}") + proc = subprocess.Popen(*popen_args, **kwargs) + proc.wait() + on_exit(True) + + +def is_semver_ge(new_semver: str, old_semver: str) -> bool: + new_parts = new_semver.split(".") + old_parts = old_semver.split(".") + parts = max(len(new_parts), len(old_parts)) + + for i in range(parts): + new_part = int(new_parts[i]) if i < len(new_parts) else 0 + old_part = int(old_parts[i]) if i < len(old_parts) else 0 + + if new_part > old_part: + return True + elif new_part < old_part: + return False + + return True + +def semver_sort(a: str, b: str) -> int: + if a == b: + return 0 + if is_semver_ge(a, b): + return -1 + if is_semver_ge(b, a): + return 1 + return 0 # fallback + +def download_file(path: str, url: str, version: Optional[str] = None) -> None: + # Optionally check if a file with a matching version is already downloaded + version_path = path + ".version" + if version is not None: + if os.path.exists(version_path): + with open(version_path, 'r') as f: + if f.read().strip() == version: + return + + response = requests.get(url, stream=True) + if response.status_code != 200: + raise Exception(f"Failure while retrieving remote data (source: {url})") + + with open(path, 'wb') as file: + for chunk in response.iter_content(chunk_size=8192): + file.write(chunk) + + if version is not None: + with open(version_path, 'w') as f: + f.write(version) + diff --git a/apworld_src/minecraft/downloader/__init__.py b/apworld_src/minecraft/downloader/__init__.py new file mode 100644 index 0000000..5a9db79 --- /dev/null +++ b/apworld_src/minecraft/downloader/__init__.py @@ -0,0 +1,127 @@ +from typing import NamedTuple, Any, Callable +from abc import ABC, abstractmethod + +import logging + +class ServerInstallData(NamedTuple): + root_dir: str + mods_dir: str + run_args: list[str] + + +class Step(ABC): + @abstractmethod + def run(self, + context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + pass + + +class StepsStep(Step): + def __init__(self, name: str, *steps: Step): + super().__init__() + self.steps = steps + self.logger = logging.Logger("MinecraftClient") + self.name = name + + def run(self, context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + self._run_index(0, context, *previous, on_success=on_success, on_failure=on_failure, on_progress=on_progress, error_ok=error_ok) + + def _run_index(self, index: int, + context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + + self.logger.debug(f"running step {index}; {type(self)}") + + if len(self.steps) <= index: + if on_progress is not None: + on_progress(1.0, self.name) + if on_success is not None: + on_success(*previous) + return + if on_progress is not None: + on_progress(index / len(self.steps), self.name) + success_lambda = lambda *result: self._run_index(index + 1, + context, + *result if type(result) is tuple else result, + on_success=on_success, + on_failure=on_failure, + on_progress=on_progress, + error_ok=error_ok) + try: + self.steps[index].run( + context, + *previous, + on_success=success_lambda, + on_failure=on_failure if not error_ok else (lambda err: success_lambda(*previous)), + on_progress=lambda value, name: self._emit_on_progress(index=index, extra=value, name=name, on_progress=on_progress), + error_ok=error_ok, + ) + except Exception as e: + self.logger.error("Exception while performing step", exc_info=True) + if error_ok: + success_lambda(*previous) + elif on_failure is not None: + on_failure(e) + + def _emit_on_progress(self, index: int, name: str, extra: float = 0, on_progress: Callable[[float, str], None] | None = None): + if on_progress is None: + return + + if extra is None: + extra = 0 + else: + extra = max(0.0, min(1.0, extra)) + + on_progress((index / len(self.steps)) + (extra / len(self.steps)), name or self.steps[index].name or self.name) + + + + +class SyncStep(Step): + def __init__(self, fn: Callable): + super().__init__() + self.fn = fn + self.logger = logging.Logger("MinecraftClient") + + def run(self, + context: dict[str, Any], + *previous: Any, + on_success: Callable | None = None, + on_failure: Callable | None = None, + on_progress: Callable[[float, str], None] | None = None, + error_ok: bool = False): + try: + res = self.fn(context, *previous if type(previous) is tuple else previous) + self.logger.info(f"Got result {res}") + if on_success is not None: + if res is None or type(res) is not tuple: + on_success(res) + else: + on_success(*res) + except Exception as e: + self.logger.error("Step failed", exc_info=True) + if on_failure is not None: + on_failure(e) + +class BytesToStringStep(SyncStep): + def __init__(self): + super().__init__(BytesToStringStep.bytes_to_string) + + + @staticmethod + def bytes_to_string(context: dict[str, Any], data: bytes): + return data.decode('utf-8') \ No newline at end of file diff --git a/apworld_src/minecraft/layouts/minecraft.kv b/apworld_src/minecraft/layouts/minecraft.kv new file mode 100644 index 0000000..93d39d0 --- /dev/null +++ b/apworld_src/minecraft/layouts/minecraft.kv @@ -0,0 +1,312 @@ +: + size_hint: 1, None + height: 50 + spacing: 10 + + Button: + text: '[b]' +root.name + '[/b]\n[color=bbb]' + root.path + '[/color]' + halign: 'left' + padding: 10, 0 + markup: True + size: self.texture_size + id: load + text_size: self.width - 10, None + on_press: root.load() + + Button: + id: rename + size_hint: None, 1 + width: 50 + padding: 20, 0 + on_press: root.rename() + Image: + id: rename_icon + center_x: self.parent.center_x + center_y: self.parent.center_y + size: self.width, self.height + color: 1, 1, 1, 1 + fit_mode: "scale-down" + + Button: + id: delete + size_hint: None, 1 + width: 50 + padding: 20, 0 + on_press: root.delete() + Image: + id: delete_icon + center_x: self.parent.center_x + center_y: self.parent.center_y + size: self.width, self.height + color: 1, .2, .2, 1 + fit_mode: "scale-down" + + + rows: 1 + size_hint: 1, None + height: 30 + spacing: 10 + Label: + size_hint: None, 1 + width: dp(150) + text: root.label + ":" + text_size: self.size + valign: "middle" + halign: "right" + TextInput: + text: root.value + multiline: False + on_text_validate: root.button_press() + + + rows: 1 + size_hint: 1, None + height: 30 + spacing: 10 + Label: + size_hint: None, 1 + width: dp(150) + text: root.label + ":" + text_size: self.size + valign: "middle" + halign: "right" + Spinner: + text: root.value + values: root.options + size_hint: None, None + height: 30 + width: dp(200) + on_text: + root.value = self.text + + + size_hint_y: None + thickness: 2 + margin: 2 + height: self.thickness + 2 * self.margin + color: 1, 1, 1 + canvas: + Color: + rgb: self.color + Rectangle: + pos: self.x + self.margin, self.y + self.margin + 1 + size: self.width - 2 * self.margin , self.thickness + +: + auto_dismiss: False + size_hint: .5, .5 + BoxLayout: + orientation: 'vertical' + padding: 10 + Label: + text: root.text + ProgressBar: + max: root.max + value: root.progress + Label: + text: root.progress_text + +: + auto_dismiss: True + confirm_text: "Confirm" + cancel_text: "Cancel" + size_hint: .5, .5 + GridLayout: + cols: 1 + padding: 10 + BoxLayout: + padding: 10 + orientation: 'vertical' + id: content + Label: + text: root.text + + GridLayout: + rows: 1 + spacing: 10 + padding: 10, 0 + size_hint: 1, None + height: 40 + Button: + id: confirm + text: root.confirm_text + background_color: 0, 1, 0, 1 + on_press: root.dismiss() + Button + id: cancel + text: root.cancel_text + background_color: 1, 0, 0, 1 + on_press: root.dismiss() + +: + auto_dismiss: True + button_text: "OK" + size_hint: .5, .5 + GridLayout: + cols: 1 + padding: 10 + BoxLayout: + padding: 10 + orientation: 'vertical' + id: content + Label: + text: root.text + text_size: self.width, None + size_hint: 1, None + + GridLayout: + rows: 1 + spacing: 10 + padding: 10, 0 + size_hint: 1, None + height: 40 + Button: + text: root.button_text + background_color: 0, 1, 0, 1 + on_press: root.dismiss() + +: + markup: True + size_hint: 1, None + text_size: self.width, None + size: self.width, self.texture_size[1] + +: + markup: True + padding: 5,0 + size_hint_y: None + text_size: self.width, None + height: self.texture_size[1] + canvas.before: + Color: + rgba: (0.2, 0.2, 0.2, 1) + Rectangle: + size: self.size + pos: self.pos + +: + messages: 1000 # amount of messages stored in client logs. + cols: 1 + viewclass: 'LogLabel' + scroll_y: 0 + scroll_type: ["content", "bars"] + bar_width: dp(12) + effect_cls: "ScrollEffect" + RecycleBoxLayout: + default_size: None, dp(20) + default_size_hint: 1, None + size_hint_y: None + height: self.minimum_height + orientation: 'vertical' + spacing: dp(3) + +: + name: "Server" + background_color: .5, .1, .1 , 1 + GridLayout: + cols: 1 + padding: dp(2) + spacing: dp(2) + Label: + id: status + size_hint: 1, None + height: 50 + text: "...Server Starting..." + font_size: dp(25) + + canvas.before: + Color: + rgba: root.background_color + Rectangle: + size: self.size + pos: self.pos + ServerLog: + id: log + TextInput: + id: cmd + multiline: False + size_hint: 1, None + height: self.minimum_height + on_text_validate: root.send_command(self.text) + +: + id: 'welcome' + name: "Welcome" + padding: 10, 5, 10, 10 + TabbedPanel: + do_default_tab: False + TabbedPanelItem: + text: 'Games' + padding: 10 + GridLayout: + cols: 1 + padding: 10 + GridLayout: + rows: 1 + orientation: 'rl-tb' + size_hint: 1, None + height: 30 + Button: + text: 'Open APMC File' + padding: 10, 5 + size_hint: None, 1 + width: self.texture_size[0] + on_press: root.client.open_apmc() + + Separator: + color: .5, .5, 1 + thickness: 3 + margin: 5 + + ScrollView: + do_scroll_x: False + effect_cls: 'ScrollEffect' + GridLayout: + cols: 1 + spacing: 10 + padding: 0, 5 + size_hint_y: None + height: self.minimum_height + id: saves + TabbedPanelItem: + text: "Options" + GridLayout: + cols: 1 + id: option_layout + size_hint: 1, None + height: self.minimum_height + padding: 10 + spacing: 10 + + GridLayout: + rows: 1 + orientation: "rl-tb" + size_hint: 1, None + height: 30 + Button: + size_hint: None, 1 + width: self.texture_size[0] + 20 + text: "Save" + on_press: root.save_options() + + FolderOption: + id: path + label: "Server Path" + button_label: "Open Folder" + Button: + size_hint: None, 1 + width: self.texture_size[0] + dp(20) + text: self.parent.button_label + on_press: self.parent.button_press() + + TextOption: + id: max_memory + label: "Max Memory" + + TextOption: + id: min_memory + label: "Min Memory" + + DropdownOption: + id: release_option + label: "Release Channel" diff --git a/apworld_src/minecraft/test/__init__.py b/apworld_src/minecraft/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apworld_src/minecraft/test/bases.py b/apworld_src/minecraft/test/bases.py new file mode 100644 index 0000000..932ee83 --- /dev/null +++ b/apworld_src/minecraft/test/bases.py @@ -0,0 +1,99 @@ +from typing import ClassVar + +from BaseClasses import CollectionState, ItemClassification +from test.bases import WorldTestBase + +from .. import MinecraftOptions, MinecraftWorld + + +class MCTestBase(WorldTestBase): + game = "Minecraft" + player: ClassVar[int] = 1 + + def _create_items(self, items, player): + singleton = False + if isinstance(items, str): + items = [items] + singleton = True + ret = [self.multiworld.worlds[player].create_item(item) for item in items] + if singleton: + return ret[0] + return ret + + def _get_items(self, item_pool, all_except): + if all_except and len(all_except) > 0: + items = self.multiworld.itempool[:] + items = [item for item in items if item.name not in all_except] + items.extend(self._create_items(item_pool[0], 1)) + else: + items = self._create_items(item_pool[0], 1) + return self.get_state(items) + + def _get_items_partial(self, item_pool, missing_item): + new_items = item_pool[0].copy() + new_items.remove(missing_item) + items = self._create_items(new_items, 1) + return self.get_state(items) +# LTTP Code Minecraft was using for Unit Tests. Find a way to re implement properly (Code Author: berserker55) + _state_cache = {} + def get_state(self, items): + if (self.multiworld, tuple(items)) in self._state_cache: + return self._state_cache[self.multiworld, tuple(items)] + state = CollectionState(self.multiworld) + for item in items: + item.classification = ItemClassification.progression + state.collect(item, prevent_sweep=True) + state.sweep_for_advancements() + state.update_reachable_regions(1) + self._state_cache[self.multiworld, tuple(items)] = state + return state + + def get_path(self, state, region): + def flist_to_iter(node): + while node: + value, node = node + yield value + + def run_location_tests(self, access_pool): + for i, (location, access, *item_pool) in enumerate(access_pool): + items = item_pool[0] + all_except = item_pool[1] if len(item_pool) > 1 else None + state = self._get_items(item_pool, all_except) + path = self.get_path(state, self.multiworld.get_location(location, 1).parent_region) + with self.subTest(msg="Reach Location", location=location, access=access, items=items, + all_except=all_except, path=path, entry=i): + + self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, + f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") + + # check for partial solution + if not all_except and access: # we are not supposed to be able to reach location with partial inventory + for missing_item in item_pool[0]: + with self.subTest(msg="Location reachable without required item", location=location, + items=item_pool[0], missing_item=missing_item, entry=i): + state = self._get_items_partial(item_pool, missing_item) + + self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), False, + f"failed {self.multiworld.get_location(location, 1)}: succeeded with " + f"{missing_item} removed from: {item_pool}") + + def run_entrance_tests(self, access_pool): + for i, (entrance, access, *item_pool) in enumerate(access_pool): + items = item_pool[0] + all_except = item_pool[1] if len(item_pool) > 1 else None + state = self._get_items(item_pool, all_except) + path = self.get_path(state, self.multiworld.get_entrance(entrance, 1).parent_region) + with self.subTest(msg="Reach Entrance", entrance=entrance, access=access, items=items, + all_except=all_except, path=path, entry=i): + + self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), access) + + # check for partial solution + if not all_except and access: # we are not supposed to be able to reach location with partial inventory + for missing_item in item_pool[0]: + with self.subTest(msg="Entrance reachable without required item", entrance=entrance, + items=item_pool[0], missing_item=missing_item, entry=i): + state = self._get_items_partial(item_pool, missing_item) + self.assertEqual(self.multiworld.get_entrance(entrance, 1).can_reach(state), False, + f"failed {self.multiworld.get_entrance(entrance, 1)} with: {item_pool}") + diff --git a/apworld_src/minecraft/test/test_advancements.py b/apworld_src/minecraft/test/test_advancements.py new file mode 100644 index 0000000..4337f9e --- /dev/null +++ b/apworld_src/minecraft/test/test_advancements.py @@ -0,0 +1,1722 @@ +from ..test.bases import MCTestBase + + +# Format: +# [location, expected_result, given_items, [excluded_items]] +# Every advancement has its own test, named by its internal ID number. +class TestAdvancements(MCTestBase): + options = { + "shuffle_structures": False, + "structure_compasses": False, + "include_hard_advancements": False, + } + + def test_42000(self): + self.run_location_tests([ + ["Who is Cutting Onions?", False, []], + ["Who is Cutting Onions?", False, [], ['Progressive Resource Crafting']], + ["Who is Cutting Onions?", False, [], ['Flint and Steel']], + ["Who is Cutting Onions?", False, [], ['Progressive Tools']], + ["Who is Cutting Onions?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Who is Cutting Onions?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Who is Cutting Onions?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42001(self): + self.run_location_tests([ + ["Oh Shiny", False, []], + ["Oh Shiny", False, [], ['Progressive Resource Crafting']], + ["Oh Shiny", False, [], ['Flint and Steel']], + ["Oh Shiny", False, [], ['Progressive Tools']], + ["Oh Shiny", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Oh Shiny", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Oh Shiny", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42002(self): + self.run_location_tests([ + ["Suit Up", False, []], + ["Suit Up", False, [], ["Progressive Armor"]], + ["Suit Up", False, [], ["Progressive Resource Crafting"]], + ["Suit Up", False, [], ["Progressive Tools"]], + ["Suit Up", True, ["Progressive Armor", "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + def test_42003(self): + self.run_location_tests([ + ["Very Very Frightening", False, []], + ["Very Very Frightening", False, [], ['Channeling Book']], + ["Very Very Frightening", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Very Very Frightening", False, [], ['Enchanting']], + ["Very Very Frightening", False, [], ['Progressive Tools']], + ["Very Very Frightening", False, [], ['Progressive Weapons']], + ["Very Very Frightening", True, ['Progressive Weapons', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Enchanting', 'Progressive Resource Crafting', 'Progressive Resource Crafting', 'Channeling Book']], + ]) + + def test_42004(self): + self.run_location_tests([ + ["Hot Stuff", False, []], + ["Hot Stuff", False, [], ["Bucket"]], + ["Hot Stuff", False, [], ["Progressive Resource Crafting"]], + ["Hot Stuff", False, [], ["Progressive Tools"]], + ["Hot Stuff", True, ["Bucket", "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + def test_42005(self): + self.run_location_tests([ + ["Free the End", False, []], + ["Free the End", False, [], ['Progressive Resource Crafting']], + ["Free the End", False, [], ['Flint and Steel']], + ["Free the End", False, [], ['Progressive Tools']], + ["Free the End", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Free the End", False, [], ['Progressive Armor']], + ["Free the End", False, [], ['Brewing']], + ["Free the End", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Free the End", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Free the End", False, [], ['Archery']], + ["Free the End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Free the End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42006(self): + self.run_location_tests([ + ["A Furious Cocktail", False, []], + ["A Furious Cocktail", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["A Furious Cocktail", False, [], ['Flint and Steel']], + ["A Furious Cocktail", False, [], ['Progressive Tools']], + ["A Furious Cocktail", False, [], ['Progressive Weapons']], + ["A Furious Cocktail", False, [], ['Progressive Armor', 'Shield']], + ["A Furious Cocktail", False, [], ['Brewing']], + ["A Furious Cocktail", False, [], ['Bottles']], + ["A Furious Cocktail", False, [], ['Fishing Rod']], + ["A Furious Cocktail", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["A Furious Cocktail", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', + 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', + 'Progressive Armor', 'Progressive Armor', + 'Enchanting', 'Brewing', 'Bottles', 'Fishing Rod']], + ]) + + def test_42007(self): + self.run_location_tests([ + ["Best Friends Forever", True, []], + ]) + + def test_42008(self): + self.run_location_tests([ + ["Bring Home the Beacon", False, []], + ["Bring Home the Beacon", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Bring Home the Beacon", False, [], ['Flint and Steel']], + ["Bring Home the Beacon", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Bring Home the Beacon", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Bring Home the Beacon", False, ['Progressive Armor'], ['Progressive Armor']], + ["Bring Home the Beacon", False, [], ['Enchanting']], + ["Bring Home the Beacon", False, [], ['Brewing']], + ["Bring Home the Beacon", False, [], ['Bottles']], + ["Bring Home the Beacon", True, [], ['Bucket']], + ["Bring Home the Beacon", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', + 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', + 'Progressive Armor', 'Progressive Armor', + 'Enchanting', 'Brewing', 'Bottles']], + ]) + + def test_42009(self): + self.run_location_tests([ + ["Not Today, Thank You", False, []], + ["Not Today, Thank You", False, [], ["Shield"]], + ["Not Today, Thank You", False, [], ["Progressive Resource Crafting"]], + ["Not Today, Thank You", False, [], ["Progressive Tools"]], + ["Not Today, Thank You", True, ["Shield", "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + def test_42010(self): + self.run_location_tests([ + ["Isn't It Iron Pick", False, []], + ["Isn't It Iron Pick", True, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], + ["Isn't It Iron Pick", False, [], ["Progressive Tools", "Progressive Tools"]], + ["Isn't It Iron Pick", False, [], ["Progressive Resource Crafting"]], + ["Isn't It Iron Pick", False, ["Progressive Tools", "Progressive Resource Crafting"]], + ["Isn't It Iron Pick", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], + ]) + + def test_42011(self): + self.run_location_tests([ + ["Local Brewery", False, []], + ["Local Brewery", False, [], ['Progressive Resource Crafting']], + ["Local Brewery", False, [], ['Flint and Steel']], + ["Local Brewery", False, [], ['Progressive Tools']], + ["Local Brewery", False, [], ['Progressive Weapons']], + ["Local Brewery", False, [], ['Progressive Armor', 'Shield']], + ["Local Brewery", False, [], ['Brewing']], + ["Local Brewery", False, [], ['Bottles']], + ["Local Brewery", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ["Local Brewery", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ]) + + def test_42012(self): + self.run_location_tests([ + ["The Next Generation", False, []], + ["The Next Generation", False, [], ['Progressive Resource Crafting']], + ["The Next Generation", False, [], ['Flint and Steel']], + ["The Next Generation", False, [], ['Progressive Tools']], + ["The Next Generation", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["The Next Generation", False, [], ['Progressive Armor']], + ["The Next Generation", False, [], ['Brewing']], + ["The Next Generation", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["The Next Generation", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["The Next Generation", False, [], ['Archery']], + ["The Next Generation", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The Next Generation", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42013(self): + self.run_location_tests([ + ["Fishy Business", False, []], + ["Fishy Business", False, [], ['Fishing Rod']], + ["Fishy Business", True, ['Fishing Rod']], + ]) + + def test_42014(self): + self.run_location_tests([ + ["Hot Tourist Destinations", False, []], + ["Hot Tourist Destinations", False, [], ['Progressive Resource Crafting']], + ["Hot Tourist Destinations", False, [], ['Flint and Steel']], + ["Hot Tourist Destinations", False, [], ['Progressive Tools']], + ["Hot Tourist Destinations", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Hot Tourist Destinations", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Hot Tourist Destinations", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42015(self): + self.run_location_tests([ + ["This Boat Has Legs", False, []], + ["This Boat Has Legs", False, [], ['Progressive Resource Crafting']], + ["This Boat Has Legs", False, [], ['Flint and Steel']], + ["This Boat Has Legs", False, [], ['Progressive Tools']], + ["This Boat Has Legs", False, [], ['Fishing Rod']], + ["This Boat Has Legs", False, [], ['Saddle']], + ["This Boat Has Legs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Fishing Rod']], + ["This Boat Has Legs", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']], + ]) + + def test_42016(self): + self.run_location_tests([ + ["Sniper Duel", False, []], + ["Sniper Duel", False, [], ['Archery']], + ["Sniper Duel", True, ['Archery']], + ]) + + def test_42017(self): + self.run_location_tests([ + ["Nether", False, []], + ["Nether", False, [], ['Progressive Resource Crafting']], + ["Nether", False, [], ['Flint and Steel']], + ["Nether", False, [], ['Progressive Tools']], + ["Nether", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Nether", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Nether", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42018(self): + self.run_location_tests([ + ["Great View From Up Here", False, []], + ["Great View From Up Here", False, [], ['Progressive Resource Crafting']], + ["Great View From Up Here", False, [], ['Flint and Steel']], + ["Great View From Up Here", False, [], ['Progressive Tools']], + ["Great View From Up Here", False, [], ['Progressive Weapons']], + ["Great View From Up Here", False, [], ['Progressive Armor', 'Shield']], + ["Great View From Up Here", False, [], ['Brewing']], + ["Great View From Up Here", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Great View From Up Here", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Great View From Up Here", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42019(self): + self.run_location_tests([ + ["How Did We Get Here?", False, []], + ["How Did We Get Here?", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["How Did We Get Here?", False, [], ['Flint and Steel']], + ["How Did We Get Here?", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["How Did We Get Here?", False, ['Progressive Weapons', 'Progressive Weapons'], ['Progressive Weapons']], + ["How Did We Get Here?", False, ['Progressive Armor'], ['Progressive Armor']], + ["How Did We Get Here?", False, [], ['Shield']], + ["How Did We Get Here?", False, [], ['Enchanting']], + ["How Did We Get Here?", False, [], ['Brewing']], + ["How Did We Get Here?", False, [], ['Bottles']], + ["How Did We Get Here?", False, [], ['Archery']], + ["How Did We Get Here?", False, [], ['Fishing Rod']], + ["How Did We Get Here?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["How Did We Get Here?", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Flint and Steel', + 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', + 'Progressive Armor', 'Progressive Armor', 'Shield', + 'Enchanting', 'Brewing', 'Archery', 'Bottles', 'Fishing Rod', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42020(self): + self.run_location_tests([ + ["Bullseye", False, []], + ["Bullseye", False, [], ['Archery']], + ["Bullseye", False, [], ['Progressive Resource Crafting']], + ["Bullseye", False, [], ['Progressive Tools']], + ["Bullseye", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Resource Crafting', 'Archery']], + ]) + + def test_42021(self): + self.run_location_tests([ + ["Spooky Scary Skeleton", False, []], + ["Spooky Scary Skeleton", False, [], ['Progressive Resource Crafting']], + ["Spooky Scary Skeleton", False, [], ['Flint and Steel']], + ["Spooky Scary Skeleton", False, [], ['Progressive Tools']], + ["Spooky Scary Skeleton", False, [], ['Progressive Weapons']], + ["Spooky Scary Skeleton", False, [], ['Progressive Armor', 'Shield']], + ["Spooky Scary Skeleton", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], + ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], + ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], + ["Spooky Scary Skeleton", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], + ]) + + def test_42022(self): + self.run_location_tests([ + ["Two by Two", False, []], + ["Two by Two", False, [], ['Progressive Resource Crafting']], + ["Two by Two", False, [], ['Flint and Steel']], + ["Two by Two", False, [], ['Progressive Tools']], + ["Two by Two", False, [], ['Progressive Weapons']], + ["Two by Two", False, [], ['Bucket']], + ["Two by Two", False, [], ['Brush']], + ["Two by Two", False, [], ['Fishing Rod']], + ["Two by Two", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Two by Two", False, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], + ["Two by Two", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Brush', 'Fishing Rod']], + ]) + + def test_42023(self): + self.run_location_tests([ + ["Stone Age", True, []], + ]) + + def test_42024(self): + self.run_location_tests([ + ["Two Birds, One Arrow", False, []], + ["Two Birds, One Arrow", False, [], ['Archery']], + ["Two Birds, One Arrow", False, [], ['Progressive Resource Crafting']], + ["Two Birds, One Arrow", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], + ["Two Birds, One Arrow", False, [], ['Enchanting']], + ["Two Birds, One Arrow", True, ['Archery', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting']], + ]) + + def test_42025(self): + self.run_location_tests([ + ["We Need to Go Deeper", False, []], + ["We Need to Go Deeper", False, [], ['Progressive Resource Crafting']], + ["We Need to Go Deeper", False, [], ['Flint and Steel']], + ["We Need to Go Deeper", False, [], ['Progressive Tools']], + ["We Need to Go Deeper", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["We Need to Go Deeper", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["We Need to Go Deeper", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42026(self): + self.run_location_tests([ + ["Who's the Pillager Now?", False, []], + ["Who's the Pillager Now?", False, [], ['Archery']], + ["Who's the Pillager Now?", False, [], ['Progressive Resource Crafting']], + ["Who's the Pillager Now?", False, [], ['Progressive Tools']], + ["Who's the Pillager Now?", False, [], ['Progressive Weapons']], + ["Who's the Pillager Now?", True, ['Archery', 'Progressive Tools', 'Progressive Weapons', 'Progressive Resource Crafting']], + ]) + + def test_42027(self): + self.run_location_tests([ + ["Getting an Upgrade", False, []], + ["Getting an Upgrade", True, ["Progressive Tools"]], + ]) + + def test_42028(self): + self.run_location_tests([ + ["Tactical Fishing", False, []], + ["Tactical Fishing", False, [], ['Progressive Resource Crafting']], + ["Tactical Fishing", False, [], ['Progressive Tools']], + ["Tactical Fishing", False, [], ['Bucket']], + ["Tactical Fishing", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Bucket']], + ]) + + def test_42029(self): + self.run_location_tests([ + ["Zombie Doctor", False, []], + ["Zombie Doctor", False, [], ['Progressive Resource Crafting']], + ["Zombie Doctor", False, [], ['Flint and Steel']], + ["Zombie Doctor", False, [], ['Progressive Tools']], + ["Zombie Doctor", False, [], ['Progressive Weapons']], + ["Zombie Doctor", False, [], ['Progressive Armor', 'Shield']], + ["Zombie Doctor", False, [], ['Brewing']], + ["Zombie Doctor", False, [], ['Bottles']], + ["Zombie Doctor", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ["Zombie Doctor", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ]) + + def test_42030(self): + self.run_location_tests([ + ["The City at the End of the Game", False, []], + ["The City at the End of the Game", False, [], ['Progressive Resource Crafting']], + ["The City at the End of the Game", False, [], ['Flint and Steel']], + ["The City at the End of the Game", False, [], ['Progressive Tools']], + ["The City at the End of the Game", False, [], ['Progressive Weapons']], + ["The City at the End of the Game", False, [], ['Progressive Armor', 'Shield']], + ["The City at the End of the Game", False, [], ['Brewing']], + ["The City at the End of the Game", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["The City at the End of the Game", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The City at the End of the Game", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42031(self): + self.run_location_tests([ + ["Ice Bucket Challenge", False, []], + ["Ice Bucket Challenge", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], + ["Ice Bucket Challenge", False, [], ["Progressive Resource Crafting"]], + ["Ice Bucket Challenge", True, ["Progressive Tools", "Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], + ]) + + def test_42032(self): + self.run_location_tests([ + ["Remote Getaway", False, []], + ["Remote Getaway", False, [], ['Progressive Resource Crafting']], + ["Remote Getaway", False, [], ['Flint and Steel']], + ["Remote Getaway", False, [], ['Progressive Tools']], + ["Remote Getaway", False, [], ['Progressive Weapons']], + ["Remote Getaway", False, [], ['Progressive Armor', 'Shield']], + ["Remote Getaway", False, [], ['Brewing']], + ["Remote Getaway", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Remote Getaway", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Remote Getaway", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42033(self): + self.run_location_tests([ + ["Into Fire", False, []], + ["Into Fire", False, [], ['Progressive Resource Crafting']], + ["Into Fire", False, [], ['Flint and Steel']], + ["Into Fire", False, [], ['Progressive Tools']], + ["Into Fire", False, [], ['Progressive Weapons']], + ["Into Fire", False, [], ['Progressive Armor', 'Shield']], + ["Into Fire", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], + ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], + ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], + ["Into Fire", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], + ]) + + def test_42034(self): + self.run_location_tests([ + ["War Pigs", False, []], + ["War Pigs", False, [], ['Progressive Resource Crafting']], + ["War Pigs", False, [], ['Flint and Steel']], + ["War Pigs", False, [], ['Progressive Tools']], + ["War Pigs", False, [], ['Progressive Weapons']], + ["War Pigs", False, [], ['Progressive Armor', 'Shield']], + ["War Pigs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["War Pigs", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], + ["War Pigs", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield']], + ]) + + def test_42035(self): + self.run_location_tests([ + ["Take Aim", False, []], + ["Take Aim", False, [], ['Archery']], + ["Take Aim", True, ['Archery']], + ]) + + def test_42036(self): + self.run_location_tests([ + ["Total Beelocation", False, []], + ["Total Beelocation", False, [], ['Enchanting']], + ["Total Beelocation", False, [], ['Silk Touch Book']], + ["Total Beelocation", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Total Beelocation", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Total Beelocation", True, ['Enchanting', 'Silk Touch Book', 'Progressive Resource Crafting', 'Progressive Resource Crafting', + 'Progressive Tools', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42037(self): + self.run_location_tests([ + ["Arbalistic", False, []], + ["Arbalistic", False, [], ['Enchanting']], + ["Arbalistic", False, [], ['Piercing IV Book']], + ["Arbalistic", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Arbalistic", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Arbalistic", False, [], ['Archery']], + ["Arbalistic", True, ['Enchanting', 'Piercing IV Book', 'Progressive Resource Crafting', 'Progressive Resource Crafting', + 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Archery']], + ]) + + def test_42038(self): + self.run_location_tests([ + ["The End... Again...", False, []], + ["The End... Again...", False, [], ['Progressive Resource Crafting']], + ["The End... Again...", False, [], ['Flint and Steel']], + ["The End... Again...", False, [], ['Progressive Tools']], + ["The End... Again...", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["The End... Again...", False, [], ['Progressive Armor']], + ["The End... Again...", False, [], ['Brewing']], + ["The End... Again...", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["The End... Again...", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["The End... Again...", False, [], ['Archery']], + ["The End... Again...", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End... Again...", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Archery', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42039(self): + self.run_location_tests([ + ["Acquire Hardware", False, []], + ["Acquire Hardware", False, [], ["Progressive Tools"]], + ["Acquire Hardware", False, [], ["Progressive Resource Crafting"]], + ["Acquire Hardware", True, ["Progressive Tools", "Progressive Resource Crafting"]], + ]) + + def test_42040(self): + self.run_location_tests([ + ["Not Quite \"Nine\" Lives", False, []], + ["Not Quite \"Nine\" Lives", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Not Quite \"Nine\" Lives", False, [], ['Flint and Steel']], + ["Not Quite \"Nine\" Lives", False, [], ['Progressive Tools']], + ["Not Quite \"Nine\" Lives", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Not Quite \"Nine\" Lives", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Not Quite \"Nine\" Lives", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42041(self): + self.run_location_tests([ + ["Cover Me with Diamonds", False, []], + ["Cover Me with Diamonds", False, ['Progressive Armor'], ['Progressive Armor']], + ["Cover Me with Diamonds", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], + ["Cover Me with Diamonds", False, [], ['Progressive Resource Crafting']], + ["Cover Me with Diamonds", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Armor', 'Progressive Armor']], + ]) + + def test_42042(self): + self.run_location_tests([ + ["Sky's the Limit", False, []], + ["Sky's the Limit", False, [], ['Progressive Resource Crafting']], + ["Sky's the Limit", False, [], ['Flint and Steel']], + ["Sky's the Limit", False, [], ['Progressive Tools']], + ["Sky's the Limit", False, [], ['Progressive Weapons']], + ["Sky's the Limit", False, [], ['Progressive Armor', 'Shield']], + ["Sky's the Limit", False, [], ['Brewing']], + ["Sky's the Limit", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Sky's the Limit", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Sky's the Limit", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42043(self): + self.run_location_tests([ + ["Hired Help", False, []], + ["Hired Help", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Hired Help", False, [], ['Progressive Tools']], + ["Hired Help", True, ['Progressive Tools', 'Progressive Resource Crafting', 'Progressive Resource Crafting']], + ]) + + def test_42044(self): + self.run_location_tests([ + ["Return to Sender", False, []], + ["Return to Sender", False, [], ['Progressive Resource Crafting']], + ["Return to Sender", False, [], ['Flint and Steel']], + ["Return to Sender", False, [], ['Progressive Tools']], + ["Return to Sender", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Return to Sender", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket']], + ["Return to Sender", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42045(self): + self.run_location_tests([ + ["Sweet Dreams", False, []], + ["Sweet Dreams", True, ['Bed']], + ["Sweet Dreams", False, [], ['Bed', 'Progressive Weapons']], + ["Sweet Dreams", False, [], ['Bed', 'Progressive Resource Crafting', 'Campfire']], + ["Sweet Dreams", True, ['Progressive Weapons', 'Progressive Resource Crafting'], ['Bed', 'Campfire']], + ["Sweet Dreams", True, ['Progressive Weapons', 'Campfire'], ['Bed', 'Progressive Resource Crafting']], + ]) + + def test_42046(self): + self.run_location_tests([ + ["You Need a Mint", False, []], + ["You Need a Mint", False, [], ['Progressive Resource Crafting']], + ["You Need a Mint", False, [], ['Flint and Steel']], + ["You Need a Mint", False, [], ['Progressive Tools']], + ["You Need a Mint", False, [], ['Progressive Weapons']], + ["You Need a Mint", False, [], ['Progressive Armor', 'Shield']], + ["You Need a Mint", False, [], ['Brewing']], + ["You Need a Mint", False, [], ['Bottles']], + ["You Need a Mint", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["You Need a Mint", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], + ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], + ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], + ["You Need a Mint", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Bottles']], + ]) + + def test_42047(self): + self.run_location_tests([ + ["Adventure", True, []], + ]) + + def test_42048(self): + self.run_location_tests([ + ["Monsters Hunted", False, []], + ["Monsters Hunted", False, [], ['Progressive Resource Crafting']], + ["Monsters Hunted", False, [], ['Flint and Steel']], + ["Monsters Hunted", False, [], ['Progressive Tools']], + ["Monsters Hunted", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Monsters Hunted", False, [], ['Progressive Armor']], + ["Monsters Hunted", False, [], ['Shield']], + ["Monsters Hunted", False, [], ['Brewing']], + ["Monsters Hunted", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Monsters Hunted", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Monsters Hunted", False, [], ['Archery']], + ["Monsters Hunted", False, [], ['Enchanting']], + ["Monsters Hunted", False, [], ['Lead']], + ["Monsters Hunted", False, [], ['Bucket', 'Fishing Rod']], + ["Monsters Hunted", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Lead', + 'Progressive Resource Crafting', 'Flint and Steel', 'Brewing', 'Bottles', + 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting', + 'Progressive Armor', 'Progressive Armor', 'Shield', 'Archery', 'Bucket', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["Monsters Hunted", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Lead', + 'Progressive Resource Crafting', 'Flint and Steel', 'Brewing', 'Bottles', + 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting', + 'Progressive Armor', 'Progressive Armor', 'Shield', 'Archery', 'Fishing Rod', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42049(self): + self.run_location_tests([ + ["Enchanter", False, []], + ["Enchanter", False, [], ['Enchanting']], + ["Enchanter", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Enchanter", False, [], ['Progressive Resource Crafting']], + ["Enchanter", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Enchanting', 'Progressive Resource Crafting']], + ]) + + def test_42050(self): + self.run_location_tests([ + ["Voluntary Exile", False, []], + ["Voluntary Exile", False, [], ['Progressive Weapons']], + ["Voluntary Exile", False, [], ['Progressive Armor', 'Shield']], + ["Voluntary Exile", False, [], ['Progressive Tools']], + ["Voluntary Exile", False, [], ['Progressive Resource Crafting']], + ["Voluntary Exile", True, ['Progressive Tools', 'Progressive Armor', 'Progressive Weapons', 'Progressive Resource Crafting']], + ["Voluntary Exile", True, ['Progressive Tools', 'Shield', 'Progressive Weapons', 'Progressive Resource Crafting']], + ]) + + def test_42051(self): + self.run_location_tests([ + ["Eye Spy", False, []], + ["Eye Spy", False, [], ['Progressive Resource Crafting']], + ["Eye Spy", False, [], ['Flint and Steel']], + ["Eye Spy", False, [], ['Progressive Tools']], + ["Eye Spy", False, [], ['Progressive Weapons']], + ["Eye Spy", False, [], ['Progressive Armor', 'Shield']], + ["Eye Spy", False, [], ['Brewing']], + ["Eye Spy", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Eye Spy", False, [], ['3 Ender Pearls']], + ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', '3 Ender Pearls']], + ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', '3 Ender Pearls']], + ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', '3 Ender Pearls']], + ["Eye Spy", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', '3 Ender Pearls']], + ]) + + def test_42052(self): + self.run_location_tests([ + ["The End", False, []], + ["The End", False, [], ['Progressive Resource Crafting']], + ["The End", False, [], ['Flint and Steel']], + ["The End", False, [], ['Progressive Tools']], + ["The End", False, [], ['Progressive Weapons']], + ["The End", False, [], ['Progressive Armor', 'Shield']], + ["The End", False, [], ['Brewing']], + ["The End", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["The End", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42053(self): + self.run_location_tests([ + ["Serious Dedication", False, []], + ["Serious Dedication", False, [], ['Progressive Resource Crafting']], + ["Serious Dedication", False, [], ['Flint and Steel']], + ["Serious Dedication", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Serious Dedication", False, [], ['Progressive Weapons']], + ["Serious Dedication", False, [], ['Progressive Armor', 'Shield']], + ["Serious Dedication", False, [], ['Brewing']], + ["Serious Dedication", False, [], ['Bottles']], + ["Serious Dedication", False, [], ['Bed']], + ["Serious Dedication", False, [], ['8 Netherite Scrap']], + ["Serious Dedication", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles', 'Bed', '8 Netherite Scrap']], + ["Serious Dedication", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles', 'Bed', '8 Netherite Scrap']], + ]) + + def test_42054(self): + self.run_location_tests([ + ["Postmortal", False, []], + ["Postmortal", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Postmortal", False, [], ['Progressive Armor']], + ["Postmortal", False, [], ['Shield']], + ["Postmortal", False, [], ['Progressive Resource Crafting']], + ["Postmortal", False, [], ['Progressive Tools']], + ["Postmortal", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Progressive Resource Crafting', 'Progressive Tools']], + ]) + + def test_42055(self): + self.run_location_tests([ + ["Monster Hunter", True, []], + ]) + + def test_42056(self): + self.run_location_tests([ + ["Adventuring Time", False, []], + ["Adventuring Time", False, [], ['Progressive Weapons']], + ["Adventuring Time", False, [], ['Progressive Resource Crafting']], + ["Adventuring Time", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], + ["Adventuring Time", True, ['Progressive Weapons', 'Progressive Resource Crafting', + 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42057(self): + self.run_location_tests([ + ["A Seedy Place", True, []], + ]) + + def test_42058(self): + self.run_location_tests([ + ["Those Were the Days", False, []], + ["Those Were the Days", False, [], ['Progressive Resource Crafting']], + ["Those Were the Days", False, [], ['Flint and Steel']], + ["Those Were the Days", False, [], ['Progressive Tools']], + ["Those Were the Days", False, [], ['Progressive Weapons']], + ["Those Were the Days", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Those Were the Days", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons']], + ["Those Were the Days", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], + ]) + + def test_42059(self): + self.run_location_tests([ + ["Hero of the Village", False, []], + ["Hero of the Village", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Hero of the Village", False, [], ['Progressive Armor']], + ["Hero of the Village", False, [], ['Shield']], + ["Hero of the Village", False, [], ['Progressive Resource Crafting']], + ["Hero of the Village", False, [], ['Progressive Tools']], + ["Hero of the Village", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Progressive Resource Crafting', 'Progressive Tools']], + ]) + + def test_42060(self): + self.run_location_tests([ + ["Hidden in the Depths", False, []], + ["Hidden in the Depths", False, [], ['Progressive Resource Crafting']], + ["Hidden in the Depths", False, [], ['Flint and Steel']], + ["Hidden in the Depths", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Hidden in the Depths", False, [], ['Progressive Weapons']], + ["Hidden in the Depths", False, [], ['Progressive Armor', 'Shield']], + ["Hidden in the Depths", False, [], ['Brewing']], + ["Hidden in the Depths", False, [], ['Bottles']], + ["Hidden in the Depths", False, [], ['Bed']], + ["Hidden in the Depths", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles', 'Bed']], + ["Hidden in the Depths", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles', 'Bed']], + ]) + + def test_42061(self): + self.run_location_tests([ + ["Beaconator", False, []], + ["Beaconator", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Beaconator", False, [], ['Flint and Steel']], + ["Beaconator", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Beaconator", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Beaconator", False, ['Progressive Armor'], ['Progressive Armor']], + ["Beaconator", False, [], ['Brewing']], + ["Beaconator", False, [], ['Bottles']], + ["Beaconator", False, [], ['Enchanting']], + ["Beaconator", True, [], ['Bucket']], + ["Beaconator", True, ['Progressive Resource Crafting', 'Progressive Resource Crafting', + 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', + 'Brewing', 'Bottles', 'Enchanting']], + ]) + + def test_42062(self): + self.run_location_tests([ + ["Withering Heights", False, []], + ["Withering Heights", False, [], ['Progressive Resource Crafting']], + ["Withering Heights", False, [], ['Flint and Steel']], + ["Withering Heights", False, [], ['Progressive Tools']], + ["Withering Heights", False, ['Progressive Weapons'], ['Progressive Weapons', 'Progressive Weapons']], + ["Withering Heights", False, ['Progressive Armor'], ['Progressive Armor']], + ["Withering Heights", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Withering Heights", False, [], ['Brewing']], + ["Withering Heights", False, [], ['Bottles']], + ["Withering Heights", False, [], ['Enchanting']], + ["Withering Heights", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', + 'Brewing', 'Bottles', 'Enchanting']], + ]) + + def test_42063(self): + self.run_location_tests([ + ["A Balanced Diet", False, []], + ["A Balanced Diet", False, [], ['Fishing Rod']], + ["A Balanced Diet", False, [], ['Campfire']], + ["A Balanced Diet", False, [], ['Bottles']], + ["A Balanced Diet", False, [], ['Progressive Resource Crafting']], + ["A Balanced Diet", False, [], ['Flint and Steel']], + ["A Balanced Diet", False, [], ['Progressive Weapons']], + ["A Balanced Diet", False, [], ['Progressive Armor', 'Shield']], + ["A Balanced Diet", False, [], ['Brewing']], + ["A Balanced Diet", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["A Balanced Diet", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Bottles', 'Campfire', 'Fishing Rod', + 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', + 'Flint and Steel', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', + 'Progressive Tools', 'Progressive Armor']], + ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Bottles', 'Campfire', 'Fishing Rod', + 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', + 'Flint and Steel', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', + 'Bucket', 'Progressive Armor']], + ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Bottles', 'Campfire', 'Fishing Rod', + 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', + 'Flint and Steel', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', + 'Progressive Tools', 'Shield']], + ["A Balanced Diet", True, ['Progressive Resource Crafting', 'Bottles', 'Campfire', 'Fishing Rod', + 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', + 'Flint and Steel', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', + 'Bucket', 'Shield']], + ]) + + def test_42064(self): + self.run_location_tests([ + ["Subspace Bubble", False, []], + ["Subspace Bubble", False, [], ['Progressive Resource Crafting']], + ["Subspace Bubble", False, [], ['Flint and Steel']], + ["Subspace Bubble", False, [], ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Subspace Bubble", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Resource Crafting']], + ]) + + def test_42065(self): + self.run_location_tests([ + ["Husbandry", True, []], + ]) + + def test_42066(self): + self.run_location_tests([ + ["Country Lode, Take Me Home", False, []], + ["Country Lode, Take Me Home", False, [], ['Progressive Resource Crafting']], + ["Country Lode, Take Me Home", False, [], ['Progressive Tools', 'Progressive Tools']], + ["Country Lode, Take Me Home", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Resource Crafting']], + ]) + + def test_42067(self): + self.run_location_tests([ + ["Bee Our Guest", False, []], + ["Bee Our Guest", False, [], ['Campfire']], + ["Bee Our Guest", False, [], ['Bottles']], + ["Bee Our Guest", False, [], ['Progressive Resource Crafting']], + ["Bee Our Guest", True, ['Campfire', 'Bottles', 'Progressive Resource Crafting']], + ]) + + def test_42068(self): + self.run_location_tests([ + ["What a Deal!", False, []], + ["What a Deal!", False, [], ['Progressive Weapons']], + ["What a Deal!", False, [], ['Campfire', 'Progressive Resource Crafting']], + ["What a Deal!", True, ['Progressive Weapons', 'Campfire']], + ["What a Deal!", True, ['Progressive Weapons', 'Progressive Resource Crafting']], + ]) + + def test_42069(self): + self.run_location_tests([ + ["Uneasy Alliance", False, []], + ["Uneasy Alliance", False, [], ['Progressive Resource Crafting']], + ["Uneasy Alliance", False, [], ['Flint and Steel']], + ["Uneasy Alliance", False, [], ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Uneasy Alliance", False, [], ['Fishing Rod']], + ["Uneasy Alliance", True, ['Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Resource Crafting', 'Fishing Rod']], + ]) + + def test_42070(self): + self.run_location_tests([ + ["Diamonds!", False, []], + ["Diamonds!", True, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools"]], + ["Diamonds!", False, [], ["Progressive Tools", "Progressive Tools"]], + ["Diamonds!", False, [], ["Progressive Resource Crafting"]], + ["Diamonds!", False, ["Progressive Tools", "Progressive Resource Crafting"]], + ["Diamonds!", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting"]], + ]) + + def test_42071(self): + self.run_location_tests([ + ["A Terrible Fortress", False, []], + ["A Terrible Fortress", False, [], ['Progressive Resource Crafting']], + ["A Terrible Fortress", False, [], ['Flint and Steel']], + ["A Terrible Fortress", False, [], ['Progressive Tools']], + ["A Terrible Fortress", False, [], ['Progressive Weapons']], + ["A Terrible Fortress", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["A Terrible Fortress", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons']], + ["A Terrible Fortress", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], + ]) + + def test_42072(self): + self.run_location_tests([ + ["A Throwaway Joke", False, []], + ["A Throwaway Joke", False, [], ['Progressive Weapons']], + ["A Throwaway Joke", True, ['Progressive Weapons', 'Progressive Armor', 'Progressive Tools', 'Progressive Resource Crafting']], + ]) + + def test_42073(self): + self.run_location_tests([ + ["Minecraft", True, []], + ]) + + def test_42074(self): + self.run_location_tests([ + ["Sticky Situation", False, []], + ["Sticky Situation", False, [], ['Bottles']], + ["Sticky Situation", False, [], ['Progressive Resource Crafting']], + ["Sticky Situation", False, [], ['Campfire']], + ["Sticky Situation", True, ['Bottles', 'Progressive Resource Crafting', 'Campfire']], + ]) + + def test_42075(self): + self.run_location_tests([ + ["Ol' Betsy", False, []], + ["Ol' Betsy", False, [], ['Archery']], + ["Ol' Betsy", False, [], ['Progressive Resource Crafting']], + ["Ol' Betsy", False, [], ['Progressive Tools']], + ["Ol' Betsy", True, ['Archery', 'Progressive Resource Crafting', 'Progressive Tools']], + ]) + + def test_42076(self): + self.run_location_tests([ + ["Cover Me in Debris", False, []], + ["Cover Me in Debris", False, [], ['Progressive Resource Crafting']], + ["Cover Me in Debris", False, [], ['Flint and Steel']], + ["Cover Me in Debris", False, ['Progressive Tools', 'Progressive Tools'], ['Progressive Tools']], + ["Cover Me in Debris", False, [], ['Progressive Weapons']], + ["Cover Me in Debris", False, ['Progressive Armor'], ['Progressive Armor']], + ["Cover Me in Debris", False, [], ['Brewing']], + ["Cover Me in Debris", False, [], ['Bottles']], + ["Cover Me in Debris", False, [], ['Bed']], + ["Cover Me in Debris", False, ['8 Netherite Scrap'], ['8 Netherite Scrap']], + ["Cover Me in Debris", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Progressive Armor', + 'Brewing', 'Bottles', 'Bed', '8 Netherite Scrap', '8 Netherite Scrap']], + ]) + + def test_42077(self): + self.run_location_tests([ + ["The End?", False, []], + ["The End?", False, [], ['Progressive Resource Crafting']], + ["The End?", False, [], ['Flint and Steel']], + ["The End?", False, [], ['Progressive Tools']], + ["The End?", False, [], ['Progressive Weapons']], + ["The End?", False, [], ['Progressive Armor', 'Shield']], + ["The End?", False, [], ['Brewing']], + ["The End?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["The End?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ["The End?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def test_42078(self): + self.run_location_tests([ + ["The Parrots and the Bats", True, []], + ]) + + def test_42079(self): + self.run_location_tests([ + ["A Complete Catalogue", False, []], + ["A Complete Catalogue", False, [], ['Progressive Weapons']], + ["A Complete Catalogue", False, [], ['Campfire', 'Progressive Resource Crafting']], + ["A Complete Catalogue", True, ['Progressive Weapons', 'Campfire']], + ["A Complete Catalogue", True, ['Progressive Weapons', 'Progressive Resource Crafting']], + ]) + + def test_42080(self): + self.run_location_tests([ + ["Getting Wood", True, []], + ]) + + def test_42081(self): + self.run_location_tests([ + ["Time to Mine!", True, []], + ]) + + def test_42082(self): + self.run_location_tests([ + ["Hot Topic", False, []], + ["Hot Topic", True, ['Progressive Resource Crafting']], + ]) + + def test_42083(self): + self.run_location_tests([ + ["Bake Bread", True, []], + ]) + + def test_42084(self): + self.run_location_tests([ + ["The Lie", False, []], + ["The Lie", False, [], ['Progressive Resource Crafting']], + ["The Lie", False, [], ['Bucket']], + ["The Lie", False, [], ['Progressive Tools']], + ["The Lie", True, ['Bucket', 'Progressive Resource Crafting', 'Progressive Tools']], + ]) + + def test_42085(self): + self.run_location_tests([ + ["On a Rail", False, []], + ["On a Rail", False, [], ['Progressive Resource Crafting']], + ["On a Rail", False, ['Progressive Tools'], ['Progressive Tools', 'Progressive Tools']], + ["On a Rail", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools']], + ]) + + def test_42086(self): + self.run_location_tests([ + ["Time to Strike!", True, []], + ]) + + def test_42087(self): + self.run_location_tests([ + ["Cow Tipper", True, []], + ]) + + def test_42088(self): + self.run_location_tests([ + ["When Pigs Fly", False, []], + ["When Pigs Fly", False, [], ['Progressive Resource Crafting']], + ["When Pigs Fly", False, [], ['Progressive Tools']], + ["When Pigs Fly", False, [], ['Progressive Weapons']], + ["When Pigs Fly", False, [], ['Fishing Rod']], + ["When Pigs Fly", False, [], ['Saddle']], + ["When Pigs Fly", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', + 'Fishing Rod', 'Progressive Weapons']], + ]) + + def test_42089(self): + self.run_location_tests([ + ["Overkill", False, []], + ["Overkill", False, [], ['Progressive Resource Crafting']], + ["Overkill", False, [], ['Flint and Steel']], + ["Overkill", False, [], ['Progressive Tools']], + ["Overkill", False, [], ['Progressive Weapons']], + ["Overkill", False, [], ['Progressive Armor', 'Shield']], + ["Overkill", False, [], ['Brewing']], + ["Overkill", False, [], ['Bottles']], + ["Overkill", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', 'Bottles']], + ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ["Overkill", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', 'Bottles']], + ]) + + def test_42090(self): + self.run_location_tests([ + ["Librarian", False, []], + ["Librarian", True, ['Enchanting']], + ]) + + def test_42091(self): + self.run_location_tests([ + ["Overpowered", False, []], + ["Overpowered", False, [], ['Progressive Resource Crafting']], + ["Overpowered", False, [], ['Flint and Steel']], + ["Overpowered", False, ['Progressive Tools', 'Progressive Tools', 'Bucket', 'Flint and Steel']], + ["Overpowered", False, [], ['Progressive Weapons']], + ["Overpowered", False, [], ['Progressive Armor', 'Shield']], + ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor']], + ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor']], + ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Weapons', 'Shield']], + ["Overpowered", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield']], + ]) + + def test_42092(self): + self.run_location_tests([ + ["Wax On", False, []], + ["Wax On", False, [], ["Progressive Tools"]], + ["Wax On", False, [], ["Progressive Resource Crafting"]], + ["Wax On", False, [], ["Campfire"]], + ["Wax On", True, ["Progressive Resource Crafting", "Progressive Tools", "Campfire"]], + ]) + + def test_42093(self): + self.run_location_tests([ + ["Wax Off", False, []], + ["Wax Off", False, [], ["Progressive Tools"]], + ["Wax Off", False, [], ["Campfire", "Progressive Weapons"]], + ["Wax Off", False, [], ["Campfire", "Progressive Resource Crafting"]], + ["Wax Off", False, [], ["Progressive Weapons", "Progressive Resource Crafting"]], + ["Wax Off", True, ["Progressive Tools", "Progressive Resource Crafting", "Campfire"]], + ["Wax Off", True, ["Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons"]], + ["Wax Off", True, ["Progressive Tools", "Campfire", "Progressive Weapons"]] + ]) + + def test_42094(self): + self.run_location_tests([ + ["The Cutest Predator", False, []], + ["The Cutest Predator", False, [], ["Progressive Weapons"]], + ["The Cutest Predator", False, [], ["Progressive Tools"]], + ["The Cutest Predator", False, [], ["Progressive Resource Crafting"]], + ["The Cutest Predator", False, [], ["Bucket"]], + ["The Cutest Predator", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Bucket"]], + ]) + + def test_42095(self): + self.run_location_tests([ + ["The Healing Power of Friendship", False, []], + ["The Healing Power of Friendship", False, [], ["Progressive Weapons"]], + ["The Healing Power of Friendship", False, [], ["Progressive Tools"]], + ["The Healing Power of Friendship", False, [], ["Progressive Resource Crafting"]], + ["The Healing Power of Friendship", False, [], ["Bucket"]], + ["The Healing Power of Friendship", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Bucket"]], + ]) + + def test_42096(self): + self.run_location_tests([ + ["Is It a Bird?", False, []], + ["Is It a Bird?", False, [], ["Progressive Weapons"]], + ["Is It a Bird?", False, [], ["Progressive Tools"]], + ["Is It a Bird?", False, [], ["Progressive Resource Crafting"]], + ["Is It a Bird?", False, [], ["Spyglass"]], + ["Is It a Bird?", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Spyglass"]], + ]) + + def test_42097(self): + self.run_location_tests([ + ["Is It a Balloon?", False, []], + ["Is It a Balloon?", False, [], ['Progressive Resource Crafting']], + ["Is It a Balloon?", False, [], ['Flint and Steel']], + ["Is It a Balloon?", False, [], ['Progressive Tools']], + ["Is It a Balloon?", False, [], ['Progressive Weapons']], + ["Is It a Balloon?", False, [], ['Spyglass']], + ["Is It a Balloon?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Is It a Balloon?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Spyglass']], + ["Is It a Balloon?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Spyglass']], + ]) + + def test_42098(self): + self.run_location_tests([ + ["Is It a Plane?", False, []], + ["Is It a Plane?", False, [], ['Progressive Resource Crafting']], + ["Is It a Plane?", False, [], ['Flint and Steel']], + ["Is It a Plane?", False, [], ['Progressive Tools']], + ["Is It a Plane?", False, [], ['Progressive Weapons']], + ["Is It a Plane?", False, [], ['Progressive Armor', 'Shield']], + ["Is It a Plane?", False, [], ['Brewing']], + ["Is It a Plane?", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ["Is It a Plane?", False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ["Is It a Plane?", False, [], ['Spyglass']], + ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], + ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], + ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', + 'Progressive Weapons', 'Shield', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], + ["Is It a Plane?", True, ['Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', 'Brewing', + '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', 'Spyglass']], + ]) + + def test_42099(self): + self.run_location_tests([ + ["Surge Protector", False, []], + ["Surge Protector", False, [], ['Channeling Book']], + ["Surge Protector", False, ['Progressive Resource Crafting'], ['Progressive Resource Crafting']], + ["Surge Protector", False, [], ['Enchanting']], + ["Surge Protector", False, [], ['Progressive Tools']], + ["Surge Protector", False, [], ['Progressive Weapons']], + ["Surge Protector", True, ['Progressive Weapons', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Enchanting', 'Progressive Resource Crafting', 'Progressive Resource Crafting', 'Channeling Book']], + ]) + + def test_42100(self): + self.run_location_tests([ + ["Light as a Rabbit", False, []], + ["Light as a Rabbit", False, [], ["Progressive Weapons"]], + ["Light as a Rabbit", False, [], ["Progressive Tools"]], + ["Light as a Rabbit", False, [], ["Progressive Resource Crafting"]], + ["Light as a Rabbit", False, [], ["Bucket"]], + ["Light as a Rabbit", True, ["Progressive Weapons", "Progressive Tools", "Progressive Resource Crafting", "Bucket"]], + ]) + + def test_42101(self): + self.run_location_tests([ + ["Glow and Behold!", False, []], + ["Glow and Behold!", False, [], ["Progressive Weapons"]], + ["Glow and Behold!", False, [], ["Progressive Resource Crafting", "Campfire"]], + ["Glow and Behold!", True, ["Progressive Weapons", "Progressive Resource Crafting"]], + ["Glow and Behold!", True, ["Progressive Weapons", "Campfire"]], + ]) + + def test_42102(self): + self.run_location_tests([ + ["Whatever Floats Your Goat!", False, []], + ["Whatever Floats Your Goat!", False, [], ["Progressive Weapons"]], + ["Whatever Floats Your Goat!", False, [], ["Progressive Resource Crafting", "Campfire"]], + ["Whatever Floats Your Goat!", True, ["Progressive Weapons", "Progressive Resource Crafting"]], + ["Whatever Floats Your Goat!", True, ["Progressive Weapons", "Campfire"]], + ]) + + # bucket, iron pick + def test_42103(self): + self.run_location_tests([ + ["Caves & Cliffs", False, []], + ["Caves & Cliffs", False, [], ["Bucket"]], + ["Caves & Cliffs", False, [], ["Progressive Tools"]], + ["Caves & Cliffs", False, [], ["Progressive Resource Crafting"]], + ["Caves & Cliffs", True, ["Progressive Resource Crafting", "Progressive Tools", "Progressive Tools", "Bucket"]], + ]) + + # bucket, fishing rod, saddle + def test_42104(self): + self.run_location_tests([ + ["Feels Like Home", False, []], + ["Feels Like Home", False, [], ['Progressive Resource Crafting']], + ["Feels Like Home", False, [], ['Progressive Tools']], + ["Feels Like Home", False, [], ['Fishing Rod']], + ["Feels Like Home", False, [], ['Saddle']], + ["Feels Like Home", False, [], ['Bucket']], + ["Feels Like Home", False, [], ['Flint and Steel']], + ["Feels Like Home", True, ['Saddle', 'Progressive Resource Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Fishing Rod']], + ]) + + # iron pick, combat + def test_42105(self): + self.run_location_tests([ + ["Sound of Music", False, []], + ["Sound of Music", False, [], ["Progressive Tools"]], + ["Sound of Music", False, [], ["Progressive Resource Crafting"]], + ["Sound of Music", False, [], ["Progressive Weapons"]], + ["Sound of Music", True, ["Progressive Tools", "Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons"]], + ]) + + # bucket, nether, villager + def test_42106(self): + self.run_location_tests([ + ["Star Trader", False, []], + ["Star Trader", False, [], ["Bucket"]], + ["Star Trader", False, [], ["Flint and Steel"]], + ["Star Trader", False, [], ["Progressive Tools"]], + ["Star Trader", False, [], ["Progressive Resource Crafting"]], + ["Star Trader", False, [], ["Progressive Weapons"]], + ["Star Trader", True, ["Bucket", "Flint and Steel", "Progressive Tools", "Progressive Resource Crafting", "Progressive Weapons"]], + ]) + + # bucket, redstone -> iron pick, pillager outpost -> adventure + def test_42107(self): + self.run_location_tests([ + ["Birthday Song", False, []], + ["Birthday Song", False, [], ["Bucket"]], + ["Birthday Song", False, [], ["Progressive Tools"]], + ["Birthday Song", False, [], ["Progressive Weapons"]], + ["Birthday Song", False, [], ["Progressive Resource Crafting"]], + ["Birthday Song", True, ["Progressive Resource Crafting", "Progressive Tools", "Progressive Tools", "Progressive Weapons", "Bucket"]], + ]) + + # bucket, adventure + def test_42108(self): + self.run_location_tests([ + ["Bukkit Bukkit", False, []], + ["Bukkit Bukkit", False, [], ["Bucket"]], + ["Bukkit Bukkit", False, [], ["Progressive Tools"]], + ["Bukkit Bukkit", False, [], ["Progressive Weapons"]], + ["Bukkit Bukkit", False, [], ["Progressive Resource Crafting"]], + ["Bukkit Bukkit", True, ["Bucket", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], + ]) + + # iron pick, adventure + def test_42109(self): + self.run_location_tests([ + ["It Spreads", False, []], + ["It Spreads", False, [], ["Progressive Tools"]], + ["It Spreads", False, [], ["Progressive Weapons"]], + ["It Spreads", False, [], ["Progressive Resource Crafting"]], + ["It Spreads", True, ["Progressive Tools", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], + ]) + + # iron pick, adventure + def test_42110(self): + self.run_location_tests([ + ["Sneak 100", False, []], + ["Sneak 100", False, [], ["Progressive Tools"]], + ["Sneak 100", False, [], ["Progressive Weapons"]], + ["Sneak 100", False, [], ["Progressive Resource Crafting"]], + ["Sneak 100", True, ["Progressive Tools", "Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], + ]) + + # adventure, lead, bucket + def test_42111(self): + self.run_location_tests([ + ["When the Squad Hops into Town", False, []], + ["When the Squad Hops into Town", False, [], ["Progressive Weapons"]], + ["When the Squad Hops into Town", False, [], ["Progressive Resource Crafting"]], + ["When the Squad Hops into Town", False, [], ["Progressive Tools"]], + ["When the Squad Hops into Town", False, [], ["Bucket"]], + ["When the Squad Hops into Town", False, [], ["Lead"]], + ["When the Squad Hops into Town", True, ["Progressive Weapons", "Lead", "Progressive Resource Crafting", + "Progressive Tools", "Bucket"]], + ]) + + # adventure, lead, bucket, nether + def test_42112(self): + self.run_location_tests([ + ["With Our Powers Combined!", False, []], + ["With Our Powers Combined!", False, [], ["Lead"]], + ["With Our Powers Combined!", False, [], ["Bucket"]], + ["With Our Powers Combined!", False, [], ["Progressive Tools"]], + ["With Our Powers Combined!", False, [], ["Flint and Steel"]], + ["With Our Powers Combined!", False, [], ["Progressive Weapons"]], + ["With Our Powers Combined!", False, [], ["Progressive Resource Crafting"]], + ["With Our Powers Combined!", True, ["Progressive Weapons", "Lead", "Progressive Resource Crafting", + "Flint and Steel", "Progressive Tools", "Bucket"]], + ]) + + # pillager outpost -> adventure + def test_42113(self): + self.run_location_tests([ + ["You've Got a Friend in Me", False, []], + ["You've Got a Friend in Me", False, [], ["Progressive Weapons"]], + ["You've Got a Friend in Me", False, [], ["Campfire", "Progressive Resource Crafting"]], + ["You've Got a Friend in Me", True, ["Progressive Weapons", "Campfire"]], + ["You've Got a Friend in Me", True, ["Progressive Weapons", "Progressive Resource Crafting"]], + ]) + + # ocean ruins, brush + def test_42114(self): + self.run_location_tests([ + ["Smells Interesting", False, []], + ["Smells Interesting", False, [], ["Brush"]], + ["Smells Interesting", False, [], ["Progressive Weapons"]], + ["Smells Interesting", False, [], ["Progressive Resource Crafting"]], + ["Smells Interesting", False, [], ["Progressive Tools"]], + ["Smells Interesting", True, ["Brush", "Progressive Weapons", + "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + # ocean ruins, brush + def test_42115(self): + self.run_location_tests([ + ["Little Sniffs", False, []], + ["Little Sniffs", False, [], ["Brush"]], + ["Little Sniffs", False, [], ["Progressive Weapons"]], + ["Little Sniffs", False, [], ["Progressive Resource Crafting"]], + ["Little Sniffs", False, [], ["Progressive Tools"]], + ["Little Sniffs", True, ["Brush", "Progressive Weapons", + "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + # ocean ruins, brush + def test_42116(self): + self.run_location_tests([ + ["Planting the Past", False, []], + ["Planting the Past", False, [], ["Brush"]], + ["Planting the Past", False, [], ["Progressive Weapons"]], + ["Planting the Past", False, [], ["Progressive Resource Crafting"]], + ["Planting the Past", False, [], ["Progressive Tools"]], + ["Planting the Past", True, ["Brush", "Progressive Weapons", + "Progressive Resource Crafting", "Progressive Tools"]], + ]) + + def test_42117(self): + self.run_location_tests([ + ["Crafting a New Look", False, []], + ["Crafting a New Look", False, [], ["Progressive Tools"]], + ["Crafting a New Look", False, [], ["Progressive Resource Crafting"]], + ["Crafting a New Look", False, [], ["Progressive Weapons"]], + ["Crafting a New Look", False, ["Progressive Tools"], ["Progressive Tools", "Progressive Tools", + "Progressive Armor", "Shield", "Brush"]], + ["Crafting a New Look", True, ["Progressive Resource Crafting", "Progressive Weapons", + "Progressive Tools", "Progressive Armor"], []], + ["Crafting a New Look", True, ["Progressive Resource Crafting", "Progressive Weapons", + "Progressive Tools", "Shield"], []], + ["Crafting a New Look", True, ["Progressive Resource Crafting", "Progressive Weapons", + "Progressive Tools", "Progressive Tools"], []], + ["Crafting a New Look", True, ["Progressive Resource Crafting", "Progressive Weapons", + "Progressive Tools", "Brush"], []], + ]) + + def test_42118(self): + self.run_location_tests([ + ["Smithing with Style", False, []], + ["Smithing with Style", False, [], ["Progressive Resource Crafting"]], + ["Smithing with Style", False, [], ["Brush"]], + ["Smithing with Style", False, [], ["Progressive Weapons"]], + ["Smithing with Style", False, ["3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls"], ["3 Ender Pearls"]], + ["Smithing with Style", False, [], ["Brewing"]], + ["Smithing with Style", False, [], ["Flint and Steel"]], + ["Smithing with Style", False, ["Progressive Tools"], ["Progressive Tools", "Progressive Tools"]], + ["Smithing with Style", False, [], ["Progressive Armor", "Shield"]], + ["Smithing with Style", False, ["Progressive Tools", "Progressive Tools"], ["Bucket", "Progressive Tools"]], + ["Smithing with Style", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools", + "Fishing Rod"]], + ["Smithing with Style", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools", "Bucket"]], + ["Smithing with Style", False, [], ["Bucket", "Fishing Rod"]], + ["Smithing with Style", False, [], ["Bucket", "Bottles"]], + ["Smithing with Style", False, [], ["Fishing Rod", "Enchanting"]], + ["Smithing with Style", False, [], ["Bottles", "Enchanting"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Progressive Armor", "Bucket", "Bottles", "Fishing Rod"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Shield", "Bucket", "Bottles", "Fishing Rod"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Progressive Armor", "Progressive Tools", + "Bottles", "Fishing Rod"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Shield", "Bottles", "Fishing Rod"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Progressive Armor", "Bucket", "Enchanting"]], + ["Smithing with Style", True, ["Progressive Tools", "Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting", "Brush", "Progressive Weapons", "Brewing", + "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", "3 Ender Pearls", + "Flint and Steel", "Shield", "Bucket", "Enchanting"]], + ]) + + def test_42119(self): + self.run_location_tests([ + ["Respecting the Remnants", False, []], + ["Respecting the Remnants", False, [], ["Progressive Tools"]], + ["Respecting the Remnants", False, [], ["Progressive Resource Crafting"]], + ["Respecting the Remnants", False, [], ["Brush"]], + ["Respecting the Remnants", False, [], ["Progressive Weapons"]], + ["Respecting the Remnants", True, ["Progressive Tools", "Progressive Resource Crafting", + "Brush", "Progressive Weapons"]], + ]) + + def test_42120(self): + self.run_location_tests([ + ["Careful Restoration", False, []], + ["Careful Restoration", False, [], ["Progressive Tools"]], + ["Careful Restoration", False, [], ["Progressive Resource Crafting"]], + ["Careful Restoration", False, [], ["Brush"]], + ["Careful Restoration", False, [], ["Progressive Weapons"]], + ["Careful Restoration", True, ["Progressive Tools", "Progressive Resource Crafting", + "Brush", "Progressive Weapons"]], + ]) + + def test_42121(self): + self.run_location_tests([ + ["The Power of Books", False, []], + ["The Power of Books", False, [], ["Progressive Resource Crafting"]], + ["The Power of Books", False, [], ["Flint and Steel"]], + ["The Power of Books", False, ["Progressive Tools"], ["Progressive Tools", "Progressive Tools"]], + ["The Power of Books", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools", "Bucket"]], + ["The Power of Books", True, ["Progressive Resource Crafting", "Flint and Steel", + "Progressive Tools", "Progressive Tools", "Progressive Tools"]], + ["The Power of Books", True, ["Progressive Resource Crafting", "Flint and Steel", + "Progressive Tools", "Progressive Tools", "Bucket"]], + ]) + + def test_42122(self): + self.run_location_tests([ + ["Isn't It Scute?", False, []], + ["Isn't It Scute?", False, [], ["Progressive Weapons"]], + ["Isn't It Scute?", False, [], ["Progressive Resource Crafting"]], + ["Isn't It Scute?", False, [], ["Progressive Tools"]], + ["Isn't It Scute?", False, [], ["Brush"]], + ["Isn't It Scute?", True, ["Progressive Weapons", "Progressive Resource Crafting", + "Progressive Tools", "Brush"]], + ]) + + def test_42123(self): + self.run_location_tests([ + ["Shear Brilliance", False, []], + ["Shear Brilliance", False, [], ["Progressive Weapons"]], + ["Shear Brilliance", False, [], ["Progressive Resource Crafting"]], + ["Shear Brilliance", False, [], ["Progressive Tools"]], + ["Shear Brilliance", False, [], ["Brush"]], + ["Shear Brilliance", True, ["Progressive Weapons", "Progressive Resource Crafting", + "Progressive Tools", "Brush"]], + ]) + + def test_42124(self): + self.run_location_tests([ + ["Good as New", False, []], + ["Good as New", False, [], ["Progressive Weapons"]], + ["Good as New", False, [], ["Progressive Resource Crafting"]], + ["Good as New", False, [], ["Progressive Tools"]], + ["Good as New", False, [], ["Brush"]], + ["Good as New", True, ["Progressive Weapons", "Progressive Resource Crafting", + "Progressive Tools", "Brush"]], + ]) + + def test_42125(self): + self.run_location_tests([ + ["The Whole Pack", False, []], + ["The Whole Pack", False, [], ["Progressive Weapons"]], + ["The Whole Pack", False, [], ["Progressive Resource Crafting", "Campfire"]], + ["The Whole Pack", True, ["Progressive Weapons", "Progressive Resource Crafting"]], + ["The Whole Pack", True, ["Progressive Weapons", "Campfire"]], + ]) + + def test_42126(self): + self.run_location_tests([ + ["Minecraft: Trial(s) Edition", False, []], + ["Minecraft: Trial(s) Edition", False, [], ["Progressive Weapons"]], + ["Minecraft: Trial(s) Edition", False, [], ["Progressive Tools"]], + ["Minecraft: Trial(s) Edition", False, [], ["Progressive Resource Crafting", "Campfire"]], + ["Minecraft: Trial(s) Edition", True, ["Progressive Tools", "Progressive Weapons", + "Progressive Resource Crafting"]], + ["Minecraft: Trial(s) Edition", True, ["Progressive Tools", "Progressive Weapons", + "Campfire"]], + ]) + + def test_42127(self): + self.run_location_tests([ + ["Under Lock and Key", False, []], + ["Under Lock and Key", False, [], ["Progressive Weapons"]], + ["Under Lock and Key", False, [], ["Progressive Resource Crafting"]], + ["Under Lock and Key", False, [], ["Progressive Tools"]], + ["Under Lock and Key", False, [], ["Progressive Armor", "Shield"]], + ["Under Lock and Key", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Progressive Armor"]], + ["Under Lock and Key", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Shield"]], + ]) + + def test_42128(self): + self.run_location_tests([ + ["Blowback", False, []], + ["Blowback", False, [], ["Progressive Weapons"]], + ["Blowback", False, [], ["Progressive Resource Crafting"]], + ["Blowback", False, [], ["Progressive Tools"]], + ["Blowback", False, [], ["Progressive Armor", "Shield"]], + ["Blowback", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Progressive Armor"]], + ["Blowback", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Shield"]], + ]) + + def test_42129(self): + self.run_location_tests([ + ["Who Needs Rockets?", False, []], + ["Who Needs Rockets?", False, [], ["Progressive Weapons"]], + ["Who Needs Rockets?", False, [], ["Progressive Resource Crafting"]], + ["Who Needs Rockets?", False, [], ["Progressive Tools"]], + ["Who Needs Rockets?", False, [], ["Progressive Armor", "Shield"]], + ["Who Needs Rockets?", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Progressive Armor"]], + ["Who Needs Rockets?", True, ["Progressive Weapons", "Progressive Tools", + "Progressive Resource Crafting", "Shield"]], + ]) + + def test_42130(self): + self.run_location_tests([ + ["Crafters Crafting Crafters", False, []], + ["Crafters Crafting Crafters", False, [], ["Progressive Resource Crafting"]], + ["Crafters Crafting Crafters", False, ["Progressive Tools"], ["Progressive Tools", "Progressive Tools"]], + ["Crafters Crafting Crafters", True, ["Progressive Tools", "Progressive Tools", + "Progressive Resource Crafting"]], + ]) + + def test_42131(self): + self.run_location_tests([ + ["Lighten Up", False, []], + ["Lighten Up", False, [], ["Progressive Weapons"]], + ["Lighten Up", False, [], ["Progressive Tools"]], + ["Lighten Up", False, [], ["Progressive Resource Crafting", "Campfire"]], + ["Lighten Up", True, ["Progressive Tools", "Progressive Weapons", "Progressive Resource Crafting"]], + ["Lighten Up", True, ["Progressive Tools", "Progressive Weapons", "Campfire"]], + ]) + + def test_42132(self): + self.run_location_tests([ + ["Over-Overkill", False, []], + ["Over-Overkill", False, [], ["Progressive Resource Crafting"]], + ["Over-Overkill", False, [], ["Progressive Tools"]], + ["Over-Overkill", False, ["Progressive Weapons"], ["Progressive Weapons", "Progressive Weapons"]], + ["Over-Overkill", False, [], ["Progressive Armor"]], + ["Over-Overkill", False, [], ["Shield"]], + ["Over-Overkill", True, ["Progressive Resource Crafting", "Progressive Tools", + "Progressive Weapons", "Progressive Weapons", "Progressive Armor", "Shield"]], + ]) + + def test_42133(self): + self.run_location_tests([ + ["Revaulting", False, []], + ["Revaulting", False, [], ["Progressive Resource Crafting"]], + ["Revaulting", False, [], ["Progressive Tools"]], + ["Revaulting", False, ["Progressive Weapons"], ["Progressive Weapons", "Progressive Weapons"]], + ["Revaulting", False, [], ["Progressive Armor"]], + ["Revaulting", False, [], ["Shield"]], + ["Revaulting", True, ["Progressive Resource Crafting", "Progressive Tools", + "Progressive Weapons", "Progressive Weapons", "Progressive Armor", "Shield"]], + ]) + + def test_42134(self): + self.run_location_tests([ + ["Stay Hydrated!", False, []], + ["Stay Hydrated!", False, [], ["Progressive Resource Crafting"]], + ["Stay Hydrated!", False, [], ["Progressive Tools"]], + ["Stay Hydrated!", False, [], ["Flint and Steel"]], + ["Stay Hydrated!", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools", "Bucket"]], + ["Stay Hydrated!", True, ["Progressive Resource Crafting", "Flint and Steel", + "Progressive Tools", "Progressive Tools", "Progressive Tools"]], + ["Stay Hydrated!", True, ["Progressive Resource Crafting", "Flint and Steel", + "Progressive Tools", "Bucket"]], + ]) + + def test_42135(self): + self.run_location_tests([ + ["Heart Transplanter", False, []], + ["Heart Transplanter", False, [], ["Progressive Weapons"]], + ["Heart Transplanter", False, [], ["Progressive Tools"]], + ["Heart Transplanter", False, ["Progressive Resource Crafting"], ["Progressive Resource Crafting"]], + ["Heart Transplanter", False, [], ["Progressive Armor", "Shield", "Silk Touch Book"]], + ["Heart Transplanter", False, [], ["Progressive Armor", "Shield", "Enchanting"]], + ["Heart Transplanter", False, ["Progressive Tools", "Progressive Tools"], ["Progressive Tools", + "Progressive Armor", "Shield"]], + ["Heart Transplanter", True, ["Progressive Resource Crafting", "Progressive Resource Crafting", + "Progressive Weapons", "Progressive Armor", + "Progressive Tools"]], + ["Heart Transplanter", True, ["Progressive Resource Crafting", "Progressive Resource Crafting", + "Progressive Weapons", "Shield", + "Progressive Tools"]], + ["Heart Transplanter", True, ["Progressive Resource Crafting", "Progressive Resource Crafting", + "Progressive Weapons", "Enchanting", "Silk Touch Book", + "Progressive Tools", "Progressive Tools", "Progressive Tools"]], + ]) + + def test_42136(self): + self.run_location_tests([ + ["Mob Kabob", False, []], + ["Mob Kabob", False, [], ["Progressive Resource Crafting"]], + ["Mob Kabob", True, ["Progressive Resource Crafting"]] + ]) diff --git a/apworld_src/minecraft/test/test_data_load.py b/apworld_src/minecraft/test/test_data_load.py new file mode 100644 index 0000000..6f96739 --- /dev/null +++ b/apworld_src/minecraft/test/test_data_load.py @@ -0,0 +1,60 @@ +import unittest + +from .. import Constants + + +class TestDataLoad(unittest.TestCase): + + def test_item_data(self): + item_info = Constants.item_info + + # All items in sub-tables are in all_items + all_items: set = set(item_info['all_items']) + assert set(item_info['progression_items']) <= all_items + assert set(item_info['useful_items']) <= all_items + assert set(item_info['trap_items']) <= all_items + assert set(item_info['required_pool'].keys()) <= all_items + assert set(item_info['junk_weights'].keys()) <= all_items + + # No overlapping ids (because of bee trap stuff) + all_ids: set = set(Constants.item_name_to_id.values()) + assert len(all_items) == len(all_ids) + + def test_location_data(self): + location_info = Constants.location_info + exclusion_info = Constants.exclusion_info + + # Every location has a region and every region's locations are in all_locations + all_locations: set = set(location_info['all_locations']) + all_locs_2: set = set() + for v in location_info['locations_by_region'].values(): + all_locs_2.update(v) + assert all_locations == all_locs_2 + + # All exclusions are locations + for v in exclusion_info.values(): + assert set(v) <= all_locations + + def test_region_data(self): + region_info = Constants.region_info + + # Every entrance and region in mandatory/default/illegal connections is a real entrance and region + all_regions = set() + all_entrances = set() + for v in region_info['regions']: + assert isinstance(v[0], str) + assert isinstance(v[1], list) + all_regions.add(v[0]) + all_entrances.update(v[1]) + + for v in region_info['mandatory_connections']: + assert v[0] in all_entrances + assert v[1] in all_regions + + for v in region_info['default_connections']: + assert v[0] in all_entrances + assert v[1] in all_regions + + for k, v in region_info['illegal_connections'].items(): + assert k in all_regions + assert set(v) <= all_entrances diff --git a/apworld_src/minecraft/test/test_entrances.py b/apworld_src/minecraft/test/test_entrances.py new file mode 100644 index 0000000..32e0eaf --- /dev/null +++ b/apworld_src/minecraft/test/test_entrances.py @@ -0,0 +1,97 @@ +from ..test.bases import MCTestBase + + +class TestEntrances(MCTestBase): + options = { + "shuffle_structures": False, + "structure_compasses": False + } + + def testPortals(self): + self.run_entrance_tests([ + ['Nether Portal', False, []], + ['Nether Portal', False, [], ['Flint and Steel']], + ['Nether Portal', False, [], ['Progressive Resource Crafting']], + ['Nether Portal', False, [], ['Progressive Tools']], + ['Nether Portal', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ['Nether Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket']], + ['Nether Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools']], + + ['End Portal', False, []], + ['End Portal', False, [], ['Brewing']], + ['End Portal', False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ['End Portal', False, [], ['Flint and Steel']], + ['End Portal', False, [], ['Progressive Resource Crafting']], + ['End Portal', False, [], ['Progressive Tools']], + ['End Portal', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ['End Portal', False, [], ['Progressive Weapons']], + ['End Portal', False, [], ['Progressive Armor', 'Shield']], + ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['End Portal', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ]) + + def testStructures(self): + self.run_entrance_tests([ # Structures 1 and 2 should be logically equivalent + ['Overworld Structure 1', False, []], + ['Overworld Structure 1', False, [], ['Progressive Weapons']], + ['Overworld Structure 1', False, [], ['Progressive Resource Crafting', 'Campfire']], + ['Overworld Structure 1', True, ['Progressive Weapons', 'Progressive Resource Crafting']], + ['Overworld Structure 1', True, ['Progressive Weapons', 'Campfire']], + + ['Overworld Structure 2', False, []], + ['Overworld Structure 2', False, [], ['Progressive Weapons']], + ['Overworld Structure 2', False, [], ['Progressive Resource Crafting', 'Campfire']], + ['Overworld Structure 2', True, ['Progressive Weapons', 'Progressive Resource Crafting']], + ['Overworld Structure 2', True, ['Progressive Weapons', 'Campfire']], + + ['Nether Structure 1', False, []], + ['Nether Structure 1', False, [], ['Flint and Steel']], + ['Nether Structure 1', False, [], ['Progressive Resource Crafting']], + ['Nether Structure 1', False, [], ['Progressive Tools']], + ['Nether Structure 1', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ['Nether Structure 1', False, [], ['Progressive Weapons']], + ['Nether Structure 1', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', 'Progressive Weapons']], + ['Nether Structure 1', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], + + ['Nether Structure 2', False, []], + ['Nether Structure 2', False, [], ['Flint and Steel']], + ['Nether Structure 2', False, [], ['Progressive Resource Crafting']], + ['Nether Structure 2', False, [], ['Progressive Tools']], + ['Nether Structure 2', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ['Nether Structure 2', False, [], ['Progressive Weapons']], + ['Nether Structure 2', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', 'Progressive Weapons']], + ['Nether Structure 2', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons']], + + ['The End Structure', False, []], + ['The End Structure', False, [], ['Brewing']], + ['The End Structure', False, ['3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls'], ['3 Ender Pearls']], + ['The End Structure', False, [], ['Flint and Steel']], + ['The End Structure', False, [], ['Progressive Resource Crafting']], + ['The End Structure', False, [], ['Progressive Tools']], + ['The End Structure', False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']], + ['The End Structure', False, [], ['Progressive Weapons']], + ['The End Structure', False, [], ['Progressive Armor', 'Shield']], + ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Bucket', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Progressive Armor', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + ['The End Structure', True, ['Flint and Steel', 'Progressive Resource Crafting', 'Progressive Tools', 'Progressive Tools', 'Progressive Tools', + 'Progressive Weapons', 'Shield', + 'Brewing', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls', '3 Ender Pearls']], + + ]) \ No newline at end of file diff --git a/apworld_src/minecraft/test/test_options.py b/apworld_src/minecraft/test/test_options.py new file mode 100644 index 0000000..feb9d67 --- /dev/null +++ b/apworld_src/minecraft/test/test_options.py @@ -0,0 +1,63 @@ +from ..test.bases import MCTestBase +from ..Constants import region_info +from .. import Options + +from BaseClasses import ItemClassification + +class AdvancementTestBase(MCTestBase): + options = { + "advancement_goal": Options.AdvancementGoal.range_end + } + # beatability test implicit + +class ShardTestBase(MCTestBase): + options = { + "egg_shards_required": Options.EggShardsRequired.range_end, + "egg_shards_available": Options.EggShardsAvailable.range_end + } + + # check that itempool is not overfilled with shards + def test_itempool(self): + assert len(self.multiworld.get_unfilled_locations()) == len(self.multiworld.itempool) + +class CompassTestBase(MCTestBase): + def test_compasses_in_pool(self): + structures = [x[1] for x in region_info["default_connections"]] + itempool_str = {item.name for item in self.multiworld.itempool} + for struct in structures: + assert f"Structure Compass ({struct})" in itempool_str + +class UnlockableHeartsTestBase(MCTestBase): + options = { + "unlockable_hearts": True + } + + def test_hearts_in_pool(self): + hearts = [item for item in self.multiworld.itempool if item.name == "Heart"] + assert len(hearts) == 9 + assert all(item.classification == ItemClassification.progression for item in hearts) + + def test_unlockable_hearts_in_slot_data(self): + slot_data = self.multiworld.worlds[self.player].fill_slot_data() + assert slot_data["unlockable_hearts"] is True + +class NoBeeTestBase(MCTestBase): + options = { + "bee_traps": Options.BeeTraps.range_start + } + + # With no bees, there are no traps in the pool + def test_bees(self): + for item in self.multiworld.itempool: + assert item.classification != ItemClassification.trap + + +class AllBeeTestBase(MCTestBase): + options = { + "bee_traps": Options.BeeTraps.range_end + } + + # With max bees, there are no filler items, only bee traps + def test_bees(self): + for item in self.multiworld.itempool: + assert item.classification != ItemClassification.filler diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9bbc975c742b298b441bfb90dbc124400a3751b9..61285a659d17295f1de7c53e24fdf13ad755c379 100644 GIT binary patch delta 37985 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 E0qmRh?f?J) delta 35439 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 A>Hq)$ diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/minecraft.apworld b/minecraft.apworld new file mode 100644 index 0000000000000000000000000000000000000000..8fdb4d4ca19ef73890b1628f981d5d3ff0fbdaa8 GIT binary patch literal 61552 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%0DbtLGsS2-=)FPWT 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 TCs0t7ke>l$D5$p^x3B&WEYlkH literal 0 HcmV?d00001 diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/archipelago_item/heart.json b/src/generated/resources/data/aprandomizer/aprandomizer/archipelago_item/heart.json new file mode 100644 index 0000000..157c3fd --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/archipelago_item/heart.json @@ -0,0 +1,5 @@ +{ + "rewards": { + "type": "aprandomizer:heart" + } +} \ No newline at end of file diff --git a/src/main/java/gg/archipelago/aprandomizer/SlotData.java b/src/main/java/gg/archipelago/aprandomizer/SlotData.java index 671b9b8..597cd1d 100644 --- a/src/main/java/gg/archipelago/aprandomizer/SlotData.java +++ b/src/main/java/gg/archipelago/aprandomizer/SlotData.java @@ -32,6 +32,9 @@ public class SlotData { @SerializedName("death_link") public boolean deathlink = false; + @SerializedName("unlockable_hearts") + public boolean unlockableHearts = false; + @SerializedName("starting_items") public String startingItems; diff --git a/src/main/java/gg/archipelago/aprandomizer/ap/storage/APMCData.java b/src/main/java/gg/archipelago/aprandomizer/ap/storage/APMCData.java index aed8f7e..18e0cd6 100644 --- a/src/main/java/gg/archipelago/aprandomizer/ap/storage/APMCData.java +++ b/src/main/java/gg/archipelago/aprandomizer/ap/storage/APMCData.java @@ -28,6 +28,9 @@ public class APMCData { @SerializedName("advancement_goal") public int advancements_required = -1; + @SerializedName("unlockable_hearts") + public boolean unlockable_hearts = false; + @SerializedName("required_bosses") public Bosses required_bosses = Bosses.ENDER_DRAGON; diff --git a/src/main/java/gg/archipelago/aprandomizer/common/Utils/UnlockableHearts.java b/src/main/java/gg/archipelago/aprandomizer/common/Utils/UnlockableHearts.java new file mode 100644 index 0000000..b224130 --- /dev/null +++ b/src/main/java/gg/archipelago/aprandomizer/common/Utils/UnlockableHearts.java @@ -0,0 +1,43 @@ +package gg.archipelago.aprandomizer.common.Utils; + +import gg.archipelago.aprandomizer.APRandomizer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.Attributes; + +public final class UnlockableHearts { + public static final double STARTING_MAX_HEALTH = 2.0D; + public static final double HEART_HEALTH = 2.0D; + public static final double VANILLA_MAX_HEALTH = 20.0D; + + private UnlockableHearts() { + } + + public static boolean enabled() { + return APRandomizer.getApmcData().unlockable_hearts; + } + + public static void initialize(ServerPlayer player) { + if (!enabled()) return; + setMaxHealth(player, STARTING_MAX_HEALTH); + player.setHealth((float) STARTING_MAX_HEALTH); + } + + public static void grantHeart(ServerPlayer player) { + if (!enabled()) return; + AttributeInstance maxHealth = player.getAttribute(Attributes.MAX_HEALTH); + if (maxHealth == null) return; + double newMaxHealth = Math.min(VANILLA_MAX_HEALTH, maxHealth.getBaseValue() + HEART_HEALTH); + setMaxHealth(player, newMaxHealth); + player.setHealth((float) Math.min(newMaxHealth, player.getHealth() + HEART_HEALTH)); + } + + private static void setMaxHealth(ServerPlayer player, double health) { + AttributeInstance maxHealth = player.getAttribute(Attributes.MAX_HEALTH); + if (maxHealth == null) return; + maxHealth.setBaseValue(health); + if (player.getHealth() > health) { + player.setHealth((float) health); + } + } +} diff --git a/src/main/java/gg/archipelago/aprandomizer/common/commands/StartCommand.java b/src/main/java/gg/archipelago/aprandomizer/common/commands/StartCommand.java index fc09e08..aa6bdce 100644 --- a/src/main/java/gg/archipelago/aprandomizer/common/commands/StartCommand.java +++ b/src/main/java/gg/archipelago/aprandomizer/common/commands/StartCommand.java @@ -5,6 +5,7 @@ import io.github.archipelagomw.ClientStatus; import gg.archipelago.aprandomizer.APRandomizer; import gg.archipelago.aprandomizer.SlotData; +import gg.archipelago.aprandomizer.common.Utils.UnlockableHearts; import gg.archipelago.aprandomizer.common.Utils.Utils; import gg.archipelago.aprandomizer.managers.itemmanager.ItemManager; import net.minecraft.commands.CommandSourceStack; @@ -82,7 +83,11 @@ private static int Start(CommandContext commandSourceCommand server.execute(() -> { for (ServerPlayer player : server.getPlayerList().getPlayers()) { player.getFoodData().eat(20, 20); - player.setHealth(20); + if (UnlockableHearts.enabled()) { + UnlockableHearts.initialize(player); + } else { + player.setHealth(20); + } player.getInventory().clearContent(); player.resetStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)); player.teleportTo(spawn.getX(), spawn.getY(), spawn.getZ()); diff --git a/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java b/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java index 9de88ca..a0523c1 100644 --- a/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java +++ b/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java @@ -2,6 +2,8 @@ import gg.archipelago.aprandomizer.APRandomizer; import gg.archipelago.aprandomizer.ap.storage.APMCData; +import gg.archipelago.aprandomizer.attachments.APAttachmentTypes; +import gg.archipelago.aprandomizer.common.Utils.UnlockableHearts; import gg.archipelago.aprandomizer.common.Utils.Utils; import gg.archipelago.aprandomizer.managers.GoalManager; import gg.archipelago.aprandomizer.managers.advancementmanager.AdvancementManager; @@ -52,6 +54,9 @@ else if (data.state == APMCData.State.INVALID_SEED) { } advancementManager.syncAllAdvancements(); goalManager.updateInfoBar(); + if (UnlockableHearts.enabled() && player.getData(APAttachmentTypes.AP_PLAYER).getIndex() == 0) { + UnlockableHearts.initialize(player); + } itemManager.catchUpPlayer(player); if (APRandomizer.isJailPlayers()) { diff --git a/src/main/java/gg/archipelago/aprandomizer/items/APItems.java b/src/main/java/gg/archipelago/aprandomizer/items/APItems.java index bd21a4a..46a1ef9 100644 --- a/src/main/java/gg/archipelago/aprandomizer/items/APItems.java +++ b/src/main/java/gg/archipelago/aprandomizer/items/APItems.java @@ -93,6 +93,7 @@ public class APItems { public static final ResourceKey TRAP_BEES = id("trap/bees"); public static final ResourceKey DRAGON_EGG_SHARD = id("dragon_egg_shard"); + public static final ResourceKey HEART = id("heart"); private static ResourceKey id(String name) { return ResourceKey.create(APRegistries.ARCHIPELAGO_ITEM, Identifier.fromNamespaceAndPath(APRandomizer.MODID, name)); @@ -409,6 +410,10 @@ public static void bootstrap(BootstrapContext context) { context.register(DRAGON_EGG_SHARD, APItem.ofReward( new DragonEggShardReward())); + + context.register(HEART, + APItem.ofReward( + new HeartReward())); } private static ItemStack enchantment(Holder enchantment, int level) { diff --git a/src/main/java/gg/archipelago/aprandomizer/items/APRewardTypes.java b/src/main/java/gg/archipelago/aprandomizer/items/APRewardTypes.java index 3e63670..680545d 100644 --- a/src/main/java/gg/archipelago/aprandomizer/items/APRewardTypes.java +++ b/src/main/java/gg/archipelago/aprandomizer/items/APRewardTypes.java @@ -19,4 +19,5 @@ public class APRewardTypes { public static final DeferredHolder, MapCodec> COMPASS = REGISTER.register("compass", () -> CompassReward.MAP_CODEC); public static final DeferredHolder, MapCodec> MOB_TRAP = REGISTER.register("mob_trap", () -> MobTrap.MAP_CODEC); public static final DeferredHolder, MapCodec> DRAGON_EGG_SHARD = REGISTER.register("dragon_egg_shard", () -> DragonEggShardReward.MAP_CODEC); + public static final DeferredHolder, MapCodec> HEART = REGISTER.register("heart", () -> HeartReward.MAP_CODEC); } diff --git a/src/main/java/gg/archipelago/aprandomizer/items/HeartReward.java b/src/main/java/gg/archipelago/aprandomizer/items/HeartReward.java new file mode 100644 index 0000000..b95635a --- /dev/null +++ b/src/main/java/gg/archipelago/aprandomizer/items/HeartReward.java @@ -0,0 +1,19 @@ +package gg.archipelago.aprandomizer.items; + +import com.mojang.serialization.MapCodec; +import gg.archipelago.aprandomizer.common.Utils.UnlockableHearts; +import net.minecraft.server.level.ServerPlayer; + +public record HeartReward() implements APReward { + public static final MapCodec MAP_CODEC = MapCodec.unit(new HeartReward()); + + @Override + public MapCodec codec() { + return MAP_CODEC; + } + + @Override + public void give(ServerPlayer player) { + UnlockableHearts.grantHeart(player); + } +} diff --git a/src/main/java/gg/archipelago/aprandomizer/managers/itemmanager/ItemManager.java b/src/main/java/gg/archipelago/aprandomizer/managers/itemmanager/ItemManager.java index a446871..869d90b 100644 --- a/src/main/java/gg/archipelago/aprandomizer/managers/itemmanager/ItemManager.java +++ b/src/main/java/gg/archipelago/aprandomizer/managers/itemmanager/ItemManager.java @@ -100,6 +100,7 @@ public class ItemManager { map.put(50L, APItems.COMPASS_ANCIENT_CITY); map.put(51L, APItems.COMPASS_TRAIL_RUINS); map.put(52L, APItems.COMPASS_TRIAL_CHAMBERS); + map.put(53L, APItems.HEART); }); // long index = 51L; From e5be203734c3f65e71b8051a093871d58af55d78 Mon Sep 17 00:00:00 2001 From: Gandalf-The-It-Wizard Date: Sun, 7 Jun 2026 15:36:39 +0200 Subject: [PATCH 2/5] Fix unlockable hearts APWorld mod download --- apworld_src/minecraft/MinecraftClient.py | 2 +- apworld_src/minecraft/__init__.py | 1 - minecraft.apworld | Bin 61552 -> 61216 bytes versions/minecraft_versions.json | 4 ++-- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apworld_src/minecraft/MinecraftClient.py b/apworld_src/minecraft/MinecraftClient.py index ff8b5a5..da62163 100644 --- a/apworld_src/minecraft/MinecraftClient.py +++ b/apworld_src/minecraft/MinecraftClient.py @@ -53,7 +53,7 @@ logger = logging.getLogger("MinecraftClient") -version_file_endpoint = "https://raw.githubusercontent.com/qixils/NeoForgeAP/refs/heads/main/versions/minecraft_versions.json" +version_file_endpoint = "https://raw.githubusercontent.com/Gandalf-The-IT-Wizard/NeoForgeAP/refs/heads/feat/unlockable-hearts/versions/minecraft_versions.json" default_save_name = "Archipelago" diff --git a/apworld_src/minecraft/__init__.py b/apworld_src/minecraft/__init__.py index b1c3de2..7a05e2c 100644 --- a/apworld_src/minecraft/__init__.py +++ b/apworld_src/minecraft/__init__.py @@ -162,7 +162,6 @@ def _get_mc_data(self) -> Dict[str, Any]: 'include_hard_advancements': self.options.include_hard_advancements.value, 'include_unreasonable_advancements': self.options.include_unreasonable_advancements.value, 'include_postgame_advancements': self.options.include_postgame_advancements.value, - 'unlockable_hearts': self.options.unlockable_hearts.value, } def generate_early(self: "MinecraftWorld") -> None: diff --git a/minecraft.apworld b/minecraft.apworld index 8fdb4d4ca19ef73890b1628f981d5d3ff0fbdaa8..965e0c886c3596c859900f0479df4d4027a7d275 100644 GIT binary patch delta 51873 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 lJ#u3&^t@%j Date: Sun, 7 Jun 2026 15:38:33 +0200 Subject: [PATCH 3/5] Prepare unlockable hearts APWorld for upstream --- apworld_src/minecraft/MinecraftClient.py | 2 +- minecraft.apworld | Bin 61216 -> 61188 bytes versions/minecraft_versions.json | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apworld_src/minecraft/MinecraftClient.py b/apworld_src/minecraft/MinecraftClient.py index da62163..ff8b5a5 100644 --- a/apworld_src/minecraft/MinecraftClient.py +++ b/apworld_src/minecraft/MinecraftClient.py @@ -53,7 +53,7 @@ logger = logging.getLogger("MinecraftClient") -version_file_endpoint = "https://raw.githubusercontent.com/Gandalf-The-IT-Wizard/NeoForgeAP/refs/heads/feat/unlockable-hearts/versions/minecraft_versions.json" +version_file_endpoint = "https://raw.githubusercontent.com/qixils/NeoForgeAP/refs/heads/main/versions/minecraft_versions.json" default_save_name = "Archipelago" diff --git a/minecraft.apworld b/minecraft.apworld index 965e0c886c3596c859900f0479df4d4027a7d275..87d0a112b37d986dee5218cea8fae19e5b2fd076 100644 GIT binary patch delta 7830 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 LBFpUm-{t=Rd?E*y diff --git a/versions/minecraft_versions.json b/versions/minecraft_versions.json index 0d0796d..d055858 100644 --- a/versions/minecraft_versions.json +++ b/versions/minecraft_versions.json @@ -1,11 +1,11 @@ [ { - "version": "2.1.4-unlockable-hearts.1+1.21.11", + "version": "2.1.3+1.21.11", "channel": "release", "data": 10, "java": 21, "minecraft": "1.21.11", - "url": "https://github.com/Gandalf-The-IT-Wizard/NeoForgeAP/releases/download/v2.1.4-unlockable-hearts.1/neoforgeap-unlockable-hearts-2.1.4-SNAPSHOT%2B1.21.11.jar" + "url": "https://github.com/qixils/NeoForgeAP/releases/download/v2.1.3/aprandomizer-2.1.3+1.21.11.jar" }, { "version": "2.0.1+1.21.8", From 62ec844b10e9b8a8ff57c0d326ad389c9082761b Mon Sep 17 00:00:00 2001 From: Gandalf-The-It-Wizard Date: Sun, 7 Jun 2026 13:52:40 +0000 Subject: [PATCH 4/5] Add received item advancements for unlockable hearts --- .../advancement/received/heart_1.json | 25 ++++++++++++++++++ .../advancement/received/heart_2.json | 26 +++++++++++++++++++ .../advancement/received/heart_3.json | 26 +++++++++++++++++++ .../advancement/received/heart_4.json | 26 +++++++++++++++++++ .../advancement/received/heart_5.json | 26 +++++++++++++++++++ .../advancement/received/heart_6.json | 26 +++++++++++++++++++ .../advancement/received/heart_7.json | 26 +++++++++++++++++++ .../advancement/received/heart_8.json | 26 +++++++++++++++++++ .../advancement/received/heart_9.json | 26 +++++++++++++++++++ .../ReceivedAdvancementProvider.java | 17 ++++++++++++ 10 files changed, 250 insertions(+) create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_1.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_2.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_3.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_4.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_5.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_6.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_7.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_8.json create mode 100644 src/generated/resources/data/aprandomizer/advancement/received/heart_9.json diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_1.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_1.json new file mode 100644 index 0000000..546ab0c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_1.json @@ -0,0 +1,25 @@ +{ + "parent": "aprandomizer:received/root", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart" + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 1" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_2.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_2.json new file mode 100644 index 0000000..0540ead --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_2.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_1", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 2 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 2" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_3.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_3.json new file mode 100644 index 0000000..cad0939 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_3.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_2", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 3 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 3" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_4.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_4.json new file mode 100644 index 0000000..2525bf4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_4.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_3", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 4 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 4" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_5.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_5.json new file mode 100644 index 0000000..ed5fb1f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_5.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_4", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 5 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 5" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_6.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_6.json new file mode 100644 index 0000000..db9395e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_6.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_5", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 6 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 6" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_7.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_7.json new file mode 100644 index 0000000..2ca4004 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_7.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_6", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 7 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 7" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_8.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_8.json new file mode 100644 index 0000000..7ab61f6 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_8.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_7", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 8 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 8" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/advancement/received/heart_9.json b/src/generated/resources/data/aprandomizer/advancement/received/heart_9.json new file mode 100644 index 0000000..13a3218 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/advancement/received/heart_9.json @@ -0,0 +1,26 @@ +{ + "parent": "aprandomizer:received/heart_8", + "criteria": { + "received": { + "conditions": { + "item": "aprandomizer:heart", + "tier": 9 + }, + "trigger": "aprandomizer:received_item" + } + }, + "display": { + "announce_to_chat": false, + "description": "Increase your maximum health by one heart.", + "icon": { + "count": 1, + "id": "minecraft:red_dye" + }, + "title": "Heart Unlock 9" + }, + "requirements": [ + [ + "received" + ] + ] +} \ No newline at end of file diff --git a/src/main/java/gg/archipelago/aprandomizer/data/advancements/ReceivedAdvancementProvider.java b/src/main/java/gg/archipelago/aprandomizer/data/advancements/ReceivedAdvancementProvider.java index dee3532..788a4f1 100644 --- a/src/main/java/gg/archipelago/aprandomizer/data/advancements/ReceivedAdvancementProvider.java +++ b/src/main/java/gg/archipelago/aprandomizer/data/advancements/ReceivedAdvancementProvider.java @@ -346,6 +346,23 @@ public void generate(Provider registries, Consumer writer) { .addCriterion("auto", PlayerTrigger.TriggerInstance.tick()) .save(writer, Identifier.fromNamespaceAndPath(APRandomizer.MODID, "received/progressive_weapons_after")); + AdvancementHolder heartParent = root; + for (int heart = 1; heart <= 9; heart++) { + heartParent = Advancement.Builder.recipeAdvancement() + .display( + Items.RED_DYE, + Component.literal("Heart Unlock " + heart), + Component.literal("Increase your maximum health by one heart."), + null, + AdvancementType.TASK, + true, + false, + false) + .parent(heartParent) + .addCriterion("received", ReceivedItemCriteria.TriggerInstance.receivedItem(APItems.HEART, heart)) + .save(writer, Identifier.fromNamespaceAndPath(APRandomizer.MODID, "received/heart_" + heart)); + } + AdvancementHolder saddle = Advancement.Builder.recipeAdvancement() .display( Items.SADDLE, From 9c445dd1b80c9e6114e076af65ed286f6d83ea79 Mon Sep 17 00:00:00 2001 From: Gandalf-The-It-Wizard Date: Sun, 7 Jun 2026 13:57:55 +0000 Subject: [PATCH 5/5] Split unlockable hearts into distinct AP items --- apworld_src/minecraft/ItemPool.py | 2 +- apworld_src/minecraft/data/items.json | 20 ++++++++++++++++-- apworld_src/minecraft/test/test_options.py | 5 +++-- minecraft.apworld | Bin 61188 -> 61576 bytes .../managers/itemmanager/ItemManager.java | 8 +++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/apworld_src/minecraft/ItemPool.py b/apworld_src/minecraft/ItemPool.py index 677029c..874a89c 100644 --- a/apworld_src/minecraft/ItemPool.py +++ b/apworld_src/minecraft/ItemPool.py @@ -44,7 +44,7 @@ def build_item_pool(world: "MinecraftWorld") -> List[Item]: # Unlockable hearts if world.options.unlockable_hearts: - itempool += [world.create_item("Heart") for _ in range(9)] + itempool += [world.create_item(f"Heart {heart}") for heart in range(1, 10)] # Bee traps bee_trap_percentage = world.options.bee_traps * 0.01 diff --git a/apworld_src/minecraft/data/items.json b/apworld_src/minecraft/data/items.json index 59d6472..5b4cdb9 100644 --- a/apworld_src/minecraft/data/items.json +++ b/apworld_src/minecraft/data/items.json @@ -52,7 +52,15 @@ "Structure Compass (Ancient City)", "Structure Compass (Trail Ruins)", "Structure Compass (Trial Chambers)", - "Heart" + "Heart 1", + "Heart 2", + "Heart 3", + "Heart 4", + "Heart 5", + "Heart 6", + "Heart 7", + "Heart 8", + "Heart 9" ], "progression_items": [ "Archery", @@ -89,7 +97,15 @@ "Structure Compass (Ancient City)", "Structure Compass (Trail Ruins)", "Structure Compass (Trial Chambers)", - "Heart" + "Heart 1", + "Heart 2", + "Heart 3", + "Heart 4", + "Heart 5", + "Heart 6", + "Heart 7", + "Heart 8", + "Heart 9" ], "useful_items": [ "Sharpness III Book", diff --git a/apworld_src/minecraft/test/test_options.py b/apworld_src/minecraft/test/test_options.py index feb9d67..a406bbf 100644 --- a/apworld_src/minecraft/test/test_options.py +++ b/apworld_src/minecraft/test/test_options.py @@ -33,8 +33,9 @@ class UnlockableHeartsTestBase(MCTestBase): } def test_hearts_in_pool(self): - hearts = [item for item in self.multiworld.itempool if item.name == "Heart"] - assert len(hearts) == 9 + heart_names = {f"Heart {heart}" for heart in range(1, 10)} + hearts = [item for item in self.multiworld.itempool if item.name in heart_names] + assert {item.name for item in hearts} == heart_names assert all(item.classification == ItemClassification.progression for item in hearts) def test_unlockable_hearts_in_slot_data(self): diff --git a/minecraft.apworld b/minecraft.apworld index 87d0a112b37d986dee5218cea8fae19e5b2fd076..40d070533f28415e7c9065949d1e5d794cdaee7c 100644 GIT binary patch delta 45167 zcmY(qW00Utu&vv+ZBA?2wr$(C&3C4I+O|Dy+qP}np0@6{&%F`*+#eN@zcaE{W<9y; z&o+429yqp=EI0%P2nYxa2v>l;US9PN5-?B@5btSoyQ_9~K_R^zu~1I5Be_?FIMTU9qf*RTcjbkc_%G#;ulZNFt{a zkxY|rKcGTIrf4^heltd1mx!=dznRa%zFZ}LwLq3K=RC&)7kDB_51 z5rJ@myi6*Dj5_TOPZ8Y;mu#*^6m973?(rE2EB~7G&UeIn-JZZ|{O{mT^cQH^-v$>q zy?2`%+yW#sP(cz~xk{R#BhVG%U2i=g|0gME|0gT03J!V!vGg^8|7E2oQ4*90P?c94 zU_$89JO{#jbc*H|8bvAMP|&h|Weck&v7ccrQY!B=BMt&o4sWpHhiV%$Gfxe)_=WUw zoF(c6V@7^bs$)8X%I5B(Pm|$O8E$o-7W8Um-o(L?@#nLWj!P8eGf;muDq{+fT$h`V z8G4?x9E2QN*gIf+OE8(r{)oE)1j+2KF?>Ff*4mJwZjbP}Sk7V}vI#%@_+W0#cV&B( zQ7keN{?J&Ig4;s0QI07UJm5ne#hZX(MjS{HC6UVp`jh^Nj8OWS3?ZYbu&9pp(SYs6 z1+Ia@AnWCB#JXty%&GI50~gq9K3a#vCf=UycqL6+7v>{aJkn*xb=6F zJI9_KIhs-(a3&oGajm*8J6kT`X^$i-By`2SmS#{9M~f%H;S)rk1x#xM<`oH|<@W~D zquPI1JFREC&+T}Aks)rI$y7V&{Kk@a>*KV{ko#@1qLu9Tb@~*!f3rlSO8$$&bUlkv z?E$XFr@d1Cuw?j;Hl;`rKF#ze;{R6dt;2}kRA^SfFc=63R^k&FF`%%?gyL@i3{m?_ zpQ6#%NJXkOH|80r!IqbcP_vBvxTrRT-T0D_k4UG(Qf7u z)b($B`ATP2zRo3R0M-Q7IP;k}JKcI3;~`Bed(nQnt>tRivj`ut4%s%=?Uknu9OL|P zfhEZKXpE4#yk?-u3__soyBaE#P3k|KnGpYNCo-ArYPdhRlqdtX-QHzm3Xx2`7`8j zsmhHkuWav@bBnM}oBS1P3g=t^H}h4d8%4ZYx^^LELhd|^H(x#FLW3JlTJ0`|{;|5H z97Dx~InaJHo)Y$<{aVMEdfipAy$hPGW9^dAj~WhVI-j|n#frWzXr{r9s`0n;va6E4 zylDu3u~MKNC7|kYzn$1!{klowi9;77Sq#DFjMds&&P2Iywt~8q$5A3pdf4vJ-$ivX zzAd)}@p%?DE|GL&{BcY4Zj!I@B7DRXQ5QdXCWj%kId`Pxw!|z(bR*1G>QC-xRC7$t zcO)NF9%eY71CdRPSTkx_`Lov6A%Z3tW3t_d1L+I`3+OJ$9lZZ`3YZB#Y(X<5mRa<4 zk;vA2yF3j(`%rWH=E%WW9*xdCZzp8d4)q?GqAqkr4jzfSYjGs?yIkkW7?>+?Jj6iF z+CyY_ie!^`OJ}!oQH#-hnalt+-2=fo+ox{iPhQ>N4Y}S-8U2WfDcOZaQS9CuxDA1x zgPr<#RO9xN)*Sra{4Ux0_a->Uk>{!9n%|#5+)51bX?X{)w&EiDu9Ke+C*E=&0?FGn z+!4|~$=xZ9;VVCXU4~pUtl4FJKt^=GCiuTKzHHa90?9-O2CvuvOAbH*{|U9}-Nzd^ zHV8;=I|#`C2$j9HgSn}Tv4tC>io2b;D}$5w6~C?P0Y}14iOmnoNAUA31HrHQL-%pzmM9z6^2PYm&qK7uuHvzPFqRT|` z0uUZKzmJ#4ioY{w0aA=GW!O+-*n1vRUEXh32Q$cyl-Qh(3;}+=Ky>yi-S^tsg(gJK zN1ErRX^f)f9=b@#mO;;3;3iX@g+RJ^j*jrJ+^R!X*Mn`5={BHYKesh>N}q!q9#5_n zIS*Wj1tG*H+tMtKIKW8+Ol(*im6ytl{xs#)@{jKx^Xok{OR~xjkaxN$KgMfsICR8V zB0uhDZIoL}38H*srz9jNxzdvqcK;bL+*c%WY#3Cb_8TllKK*d=mD&%%5uIa|R{m-; zD{$g5zSd#muR`EoS#S~h{Z(CC$G=2W0ywgv(uQBaNp0)i+(BTxFBU_ZA(Y0~448tx zg66y{mF+d%8P!v$^C;{qg9TdQ3&jHdi%1`rvmY*mYTFs^hwBa~pCi287K(|TK(aCQ zo5Yip{CpD%)WsD+OQ^w*S~1hJQMw3y3-tqt-k&t$%mu(T>w}SwhG`7lfUxEu}ccp7~?z)h2CEqMd5tMQWRWJJO zQUqn*Cqy=DkLnM~AWD>k8}wPtc$l^f=#LU7=x-pj^^xdW)yOs12MIpl_3hv+pk>6s zpzsEktnyUjvY zM1J70E-~}t*Y%1JhqOp^naVV@2G|zCpIXsrY?7VaDvn9E7bIq+&bQuD#=!mZZjw|# zjsql^l_%NMD%{4${>qD*q~dkr-)-~7SJ+5WlQq0pS7O@=O}L7}Aj#B>YaBiNm>$hB zrF$%RV2)0X+@R3I+JQv(W?H{ocC2Q!nAL$aT{Crq2nl;YQrVboHDx^9;+UVg9qN~h zgR_5-LK7VW7x|d{u7T3dkDb_nK^t+T2wGcL{LN`SVi=?nK;SszqEcW{Y?}(_MAnOD#_7qqf0uqC?A;P9UPa>)X2RtbcGUx z$Q89B{!wJ&tjlsGZ=5Zqg1I(JG4#L}+c+1J(+oCgIt!YN^zA{Hnffi55rC-QeN)rr2eh|8~zQ84`g#)Sotdr|z zjYy(;In*t=gEhcKc{t6MK-~-$5bN6}KEf{+xO4DT@@e9v^B~HopB<-Hug})DtmwO1Y{|Z6aIJDLjq)i=zFKB5@zV2&QO7TJ zJO@dJ?=SSS$4c;uY6H!OAqPID`0A5U=c9h`guje)q$uM!VI!EKxaS?&jQiQPY|PhR z^omtjJe#DboJu0)6dEP@+9y{h5p^lt<~<_Jcp;r(f69r22SKunw7iSYKpnV2fG9-^ zg?zK+ke2KsxjNk_CJ>(W^@|=`%)|nM(@@eX5as07lN&?)&bU>oeZW+;z*Z*9RIk`!)3W{6lm4!RFWq@8f@vgGhmT$a@w`M=}a7r&{ktKsz(B8L5Z_>9_#^OMhaMN1H z4>H@bE)2p>moaCYN1veXZZm2onf%VbUudkn+9*#^XX_}I!aqYZ>)88Jx^U;n=LDI)r3j`kIa zd^M|fW1X{0**=y8TT*EF`sw7NG-G%+0n15_8pZ}p4c3tW+p<8PB7TiTlzb4vrY=!j zB=z7Zn)eCm_P5O+wV7W6Y%d*q3f3y&#_Bk& zf9u)`wBBnIfcdBvlnTlsx+_$Zs%b0XJd7LDDtJ;RJoH0gJF3LrR> z;d#%3b3ui+3IYptK7}!Sbv@RRt8iSFK+stOt?GxRukj*C%QpjGMyhrx?mk`&;sKHv zwsPVmR{`^sLrYwB>nE<{ysc{Ms>2$Q?Ny_?2Ecn4qHsK(V#r;)V;)SM^q^l~Zd%}lqXU();uY(F^JNLuWw zk=LqXvj;>qBuX#fmL(+4?WQuaubt^2U2yBlS%FYtmsvG|X?BNywF`BKX^Sq9#e!|d zAup?Y@2%};t)!`&6p9F~9BPH<0*b)Xv_T-U!ONihnIE2%VYXY-;;fGbn8Xu9uiI#@ z_jbJ{(YygA8-?<25_1G>UcV)SWll1^I)76Hd;;&8IBiN-W5mJ^(|M@a^dbYl#lJs# zGC&=ah9KN%lj7WT$HD1rJZvxw0LKA%L>00(bTXk~*HcA#O zM`lyMxdi&kBo`@egkTiH@}1`bhYDcrDgfK9pFaS~zP;h6IWPJn7ujK?$Gsg2bUHRI z)~V;rk?0=_^uLKE7N`wL3L*>jwl2nOdjk2q2!d;WlVF@`MAet-UnF9%*pUrI>+iv@ zn`Kh>M`1GA$rb8QDjPHzn|YLMX&LRtpgz~Bjq%0~$w;4|i-Hz2$i?f_@ry3vZ~zi& zcpVkw&n~7g_$wef4R2Zm5l{}F*8C%MPxAu3%!;n8$M9i zU5|v-xh+&9xH{EAOvhx2Z>R=#D*!N+Y@=<0MS;*HaZo)Ky6T#Z%v=wIYD|uTtEP>< zdLI76Dk+vOK0Y$jCrQ4y6Fqua$D6P0{V(r`k6VcB)X=oqk?|wnkzS*tf>6(!rr$Vm zx~qzlG@zle^i_5~^Tt0O!4wxq2~~qJ2W|I`C&7uZO;#bA zq25St)e25|^%4#})Lq`nMg#$jw(!olCjM9P=RG_jm_G5;QYVE`!t5IAwy@&ab730N zNOktvE*KGxjpH9*w&I>W&VU`_)0pe!VIyeC`L3)u9n;y-pFwZ7vzhGB0Fk6MzJp%I zr_#Bb`%DsV&~X_ffg_Ppbn@8Rl_zCz zyfJ>m0S$&p^O`MDSSC?`CfOo|f4Rw6>Tb7hbYXF`CzVZ(%3_308jwIYD#}+0XWWTe zid;?3)WdcD`yVHK>mAREuFs3xO}eBQg=?PPBkH*|BvJJPARTF|hhh`OqP^ch@HgptvUnBbPI%Xdds<31O& zeAtakyX3B^uo{%_aPi357nZjxXcWtScY_p`kH|J`s@{MAEbwLh1^*Mm`>&tE7%L>N zFfTL*k)u0_zC`vvusu!0mMgvLORwd+m6yhZ46xaOYSpDT8KnlK;-tgtiUYlnvQ&#^ ztE^!_K|;-F`>!km_X6SO9w{_Nuq`QnGlg?S%1^E;GoDjhu)?9WV5D_?EH5e-dd^8p zNN6L46mh1iYD0Prs z&gnKq21Xc4waLPV)(xlFr7ef<;S{e@n(#Gx8i#Jx@P`bqwFb83#x?c!bI8e3F21>(_dpTa#t8uq4EO%w;TXPQP zG`UMtg%#k%x)5)%eyG1r_@De<>jGDlh zU`-Fr$xIDtSy|~DA>}n={D?D0xmwGAeix16&0_E@p$&sxGgOwB0V}Wx z0lii?+2Q(s(^)jvNfHBBd{;6qo;8O{rl~YbUggbrei-zr zd_V4Dw;dv$Mk29>Ik?6S*iiD zcac{1dLU&EHEghH5XXq1Up(=qnvS%5WsA$d((~xwnYE`vF7|rSg5=5=Eggv1_Wl(F z)}LY<#8CK>(>+1CnedA2wC7ff17jiW-CjXN8D`lHgxbh~?*vvtKTQ;i8&0aggCYsN2V zfI<=XYrZ4xTUc*QHKetkMKhQ7Z65ZmPWhedmu&7#)U9~M;RBUFJj4_3xQ02Fx&FrrziPMG4{%C7g1%Z_x|v%ZD3+J?E*&Hn!MA-M=q^Mt=s z>-d-A#>~#E{&M2_*hKCAdKclh#bJJ;t>#_gH6{O&So4K> zP0`P0y(2zzc<4q^E%)f47kW7Bxj<}D{SLZzN_?j3Tk!YAT)E5^pi8UVPt%>y6;y3B z!fS=`;?%~lBBOA!U3~?S_-<>!oQsGga?jT@(Mi0($G)E=Mb{=11WbU@>Q2*Q&cm_` zXFl7HBNC!KNJ*npCg1g~F@Fkv?g-M#WD;!K{M#hJ{7Tn76xqnb5e1i5*-A?GO5lEn zq^etAL!%F3WpW=9D6~4et%q;q$6`4PxI)AR5IcTY);{A~8buUaJ^>dP?@E!s}Osf&$3wV><+ycRV*d^Jv-o>#FNb$j*cB&Eh& z9PuA(G(p*8NDAI9V58J*nJ$cQ(8X)3dM58k14I9vPy{T01a3Lg zxmhH*lu4?aYW2wNTY8f$gz}T)3*J&S&&=o-)`Q#qAvvU|1;29%<7is27RS3Q?(g&ehsc zk>0I|encv-8WkB=oU19)4zze7N_mb=2IpUhlowM9A67i)6mF%c6>ki^7PG+QNsCPW zYwnm)OZW9e1F~oJq4o%hXSSL(`3H>qGyPH!yzmS;Co3mc-`R9Ja3orL*Ozb*BW~7A zfqzJsBk5xO*Nluv0yYbSkTdIw=&^;AVIv}QYouF!85#p(4vc?Ma7GfgaRim_2fCQR zMag0Vy$1|EIup!M4kOTHpa51Yl8jX{`g$&!8U*(r2~JWG zzL^^h(E2s2yy1q+x=;5|jK`S!wx47p0K7|CA4|Bib0b=EQdS+g!hWl<$gAgr%anoR z2kBo+q;Zmc8TiLse&1I=%%55d24HDyC39)8-F|9qGX3^qR5}wX)59P@K<6Y(B!){! zHQpH0Q<-BxK{HM7OrIIU!H#DZdxDpB&fOcGEFgf500-VFu3wdPwPB&=G0CJPfaag) z-)cXYg`-H!48@6@Y)JUU-Zab1s1~CyoLiU1VcMudx97`AaTPd_{I!CqKLRS5Jw4P3 z2jU3ZvFIe+wXu;*PYw|LG0f`j>MW}f;4`2?zrK)x>cjBw)+-Kmr9oJ_ORs+n#Rqh4uPal>0@Sdk;9f~c2U#|gOU2g|( z=QEidj>`Kr)6yz3WIM@Lvho%>n|DL6>6OJk6A!F;K#$G-vqnNEYVx}-zIsmXT@M;< zt-GN*T+4ELz==-~M?+~j1zj;-BtgIzoM-!xRrgtPqM{!ptx@v67upXV3M8v}`xlcI zKgnvya7Ry3q7(>dC%7PAo{jP5`HP{bTNCt4sUj!F#gWTNn1*blGk8ByXc3yz4F#zn ziroe`01L(eAdu7cN~m7$0=LUXy+Wcld+8jQ{#}9UP0E-)d5EI1Ftui9uzFhYY3CYi%XsF{2;5(8mr8w2)KJur)1D>qpVRW9K#CvM`1 z3%;F`mfkXqRoINA(N~SHMARnI%j}d7x?TUnFf$<}zLEw@mvRCDe?8`T1eX6qJ zp8`yHXx)TYDP>-l+x^y49@S>f&h2AL5s6C3T{LgVD_~FUe>Lzws4SX~B|-qG29?APo+!^R15l9m^D^SPkO=e%YtB z(x}ZY%?Y4uMu!A;QQ3Ok)j-wW6yINXsGf=^c;>KkmjbO3kaC+BQ!S`bqV08&VM_u1M3HK5(X-5!hIX zsM$l~(UihFxoix(D-;!w?ict5aJ-)NzWRGFq`dgqM{&5`b()v+652B5;rW#2KQ*ZB zNQ|Zst3If)`vkwh!XL72EF@y0Y9^h`Gv11QhLRiJ*|V4^@>Y#5;(&8JWN}XkGF*V( za{FyZa!mDAdF2V4#N}9hz%bZcg8wZ+WZ&vrO6seb9reG;LsO~SVS4QYU_8g?nCpJd z%O+&9R7>hyey~@HzkN~IyBY57bi$dx6puSryz@c|#iKHd8GZafs+onQ@+;`QW9IWg zl{dgI{E+B~dh^WWqTk0yI63=F%9aYnR_4$-4;n9>_{yaG75bto#|QW0SZy`^cI3DI z--$@l(T4^A^#4;S$o~u*X?6`#;<*Um(Dg2f=gQ>}_7OPR4QVQjU=aK@|3wpO-=Gk# zb@G}G(;5+A5J;d|x(#~TQDBJw6SYARjcxvCX(&m2)MWtF~}7q|pY&zKMqre$ya&1f8a9I~+FH@)z1n ziyQ~KMXTXXdyRrn5evLu1=74M+ByKUO?;IF(#}N=Q@rH&wK1Xpa4lSf@raCRM*YpK z@F_}puCg`t*&(Dh$*S_ryc9ams#pm9<3TBer9A;~zG9tQ_$NGVHg-=P$4%-B`Nd{yymdEjY)~DCC7%$tm32Z8ow74d$=-)F8^%#& zS{XqanoElj39(2?dHNd ztpp!XakqUYY5E%06WHkXl3OP|ZO0MhT@jTSJNTVka5z!@Q!BEQ(cp_0*;6>7nT0Yx zof(%sWvz(d$?`y|d+^So(pz{yG@U=!%^`IB}bjY(z}Qy`y*Z93+#Uz+y9s) zlE;(%KL0aIkpI`%aR1-NmWX4318h0|R|0^;H(Z4x$z5$MlElt(b+8P6#k#eqh!x8i zJG1-c?rIeC6>w6&TAj$Y5a%W08~(wY>woh8a&-OP1$y)mVm%ts7v^{N>=T5JS(JAT zpy!L!xIK*%s$r?Xl15MHF;7(@^Y?3Mi+mCBLNkfkod8 zE5)h*wYnZ$K)^VvNCN}oCT?bjzHe)RgP zPQst4A_!;O?pkLNc-A2Vu>B~BvOo*+*(0m}PMJ)`(CwSsCVK6x&Fp)#>frmKiW)=) zpBM4ok~5cu`SNMc_29|)cU`P(5*|ArIRSb(HBA!5ETm0NpG&NN!id(}wu(?~)I4*T zxn)FCCtV6ZSe>#V%cRvnpLyCEtcDj8D>;x1TjHdCb}K_YW=!rUpua5CvY&>PVT_O( z2U~gKAdY~aZX}Z>Ve33f?#ID4BTBFM606vWqAAr zrjSBNPtcTpC;zSVm929UvyDxmrV-SH|d|}pp!n)=#ygo$o zt!(;jPTb>m-E*p^+Pls+oLK#R+VGu5Dz3|m*OBKigkHC#bUR=~KFrDeg#B|X^n;n~ zeI_psmAkYqj29Cn99^5ixmKFW01LE`<<-Xia)91yU zYE5lUAHHH68}{AW&AhVJk$zU-TpP7-gzL9owC$J1|6nH@i0f~Tv5Oq3;6l4iktMnf z_x=ke_PH&pExi-Hy15A^tD@g30#_`9o&TnH!T>MHOI1#BX^_?`ca3;n;>g za38B$Ea!e5{5n|)e`=kVA356z z;s!Wf+UiA&Cw?8M=xVG!ozZCVbBZu^pk2zTgYG3|w@930-JiMGw^f4Qi?J;eQm8G} zy4nvmFp&m1^XQ*P?*x!}m8thS!~Z^R-`|4fFm!IR=sDvsYPDJPov6NDu^PHIZ$lbg zVX~c~l(@|E5K2Gj)xF!QhtK~*x)CZfVF4`FNpDC|WLOv#wS^ojIYJQ@o$F&?Be%%2 zwOl4}Uh2?^y5t{f;BeTATQ%r{%Kp)4X9DZ+OE!TvJxA;uX9z}(m*V9}#Pr3O9YNzq zNRZZDi9YSGiKtq>h{2?gl*6!9hR4@7?q0B)WB&M08FP(FWSNa}q*U37QA$Yg3jt5i zfkM`{(zK;ZkpVXo{IUouU`L5=bE5rNR_j#bMnpc3xCl(Mc5wdoCt6^t22Tku^zhxM zVVAa4pGAA)IzqqkPx}$0bAiS5fC59t7fQbUabOo3@enT*eETtUzmb93 z4i%*@J&9}ILnu5+QkD~29A$@oall?*2)>RH$5W#@_S^s9k zwk@6m!7$5!)aJt8OmYM7sJ}=EG2EnR6_(2=D(rQ2g#i~_y8b0vDq z3f!~A?6Dx@uL}e3F$>(f>Z+0&VMmQOuKA=4Cs^{p%TK-oeYNX9bMJaD=L;+@2I{aw zfA4c6tMr5MU)rY+l6;e@7lAoMl1=wTv3mutDRo%E>Ax^tT8)tw6EyJHk)v;^_6@t` z5#^t11A4d1P1O+9XsOyT8lDeg32+`Ocph^Fm6FM@!M{a$4SL{V43l={M-(n}c&x$K z1(3JJGp2%>(E>YU=Q3V=K>dTq&t#zAV+|zpBM|5ife3`aD9>QMb-)8h%Jb0|17Twj z>x>mEATu12p+T)TfQW9}HOYM=??dBj{uq2j{?Q_`0s=Cb+~=_#QGFHrREPXOfay`IXMkaRH4-rnsFcrYLM>J`Vluck;}9eU4iay zLCBQ8p8TN9%2LPZ?IsThYzMd+I}!|;;+^dwM@&WdXOO(@EAS5k>X@5Bo`l)UC+!9D z99;i}6U5IvNw+oY1j$ltR~@edjKw@SMrru3e$DUh&)8YJUn{!Uwahpeep6qc4>JQw zt~44SYc88HJ{u(3sMW4rk%5Ey?bQzPErfW`lgecEBy>+-xTRveBd<v`V2zJfE;~z2{hfd0M&15dU9V{co9+cIdmw4IdOHsoWTS56ll#=pQyobqq~v z4OO8y7ZQxCjDGppQ~`IfIbQekw1BSLPLvi;p}z?ru5#U2R#BT7z^vF^_@w)z-KJ)? zwxRej2-s>`;a)QKH6%Js2|rU3l#_eSNz)qc(5*3T=Y4dc;bcT^{`FpDr50HfnAY#-N;Zrz%#RrV$=AQe8C7k(( zOKJCul{#pgzuz%&)nR1LP!|#Tr0paiM_K{w|gwP%|EJN&{K@$cOl?+lA zx+q#6`VmgAe3WV0`VC7+Mc0zb>Ut(wc#R=MBvZ2{MQ{T+DVkR1sdcCPU**ZGSUEij zF)0(ro;?uDZ!HD2V{otc;1j7y`48NrP54~l@xge}iLSL6;mPfn!qPQ(-iVlRzKB2k zfI9->vj`EaOZYoA%mw@Sfqabykt^B^YHLG_5tc8SB9xJjHw#H3j>Ip@x#7NJWM2X? z|G^B20E2#ICdos-Jn|Hr#Wq2p)8zc*o(+Q7q{Wo-=98iAjJFPf>gsFaa4=IUba*9T zgM7GXFb&_q#~gWbsZ(-T(pYRJsw6B2xVR4|U10YuBv|l$62NUVOviCrm^TKA;ur7o zOYxpRs}kVI0Q~P)|7LlyJRAwV#XshU7aEU;DL)mih-n-`Hx4G^mZ16Db*}+g#Am1r z7u;iEZ~{jGa{Qs?hlUv8N4tfj&d~xN-jRe}3=eRGK7{1ehe0veY}`*z%hS<7x34Hd z=peanU1SX;$1pON@yp$$S8kPq|s?@2Vq|HQk z$LlP|U=p=gk3I20uCzEoN3{B9_Gje{ms16fDrc^6BVvCNmL~0av;#g-5te_3QN|mOxSFbdoIb7&kEkX5u z7Rwf+%`6p|IFocGU9)41K<_uoYl4l*)m&ov>j`lSwK=lGXG^mM{;s1JlvgB_tmKxak`0jNTW!V;Lgs@t zW_{Kp?)vMcXz;$9OVFaciaSU2^w#WMYSRYpAI3^&CIa=AwGqf4vhcE@Wcd;0aQY4T z|DQ{*SVdCO{^OD(h>3z;n29^K*Z}7)fMfT|04wGlR(x4{9psE7ENDt}4q69K_79B; z1&wc);f|*aZbfo!wfd^}^i+*Q$BjE(Z` z4d^Y{fnXDwWHUdNeY7}4Kb-PiPY+#c55=N;>_X2PETu+Tl!$M^IR-b#N}aM9eB2#m}bXj$WVTHs@R zdrtBE!wO{N|MNZNNBQW!invZtHf*H#E5PSN3_5&kvIzcllx^F)6uadh;nPpWXQ@e5 z7@a4^==U3`G;VRVzTI%4 z@>7lzE7KwN0eA0))t@=^`fhmrVPYKbgkz5oX9D^MUoiDu(AgM4-qTnLNh8ubp2@Xa z>wjjy)in{uy=q=fBadpcrsy)fr1OD=u6~9&MI$qfI;X5C#;gt))@|CDSliJOlX2g( zeWe`vZD++a4FJskjfoi4A^nPHq@tF6*lFh!?Bs2pII!F&@`^w4-_A<0GPVScSWd-1 zHDY)Qy~;;aR>eS$Y6N7(WsJL*8)jQ9_Tg3KZYjBU(yk`y&N;b@pt{#pzlUt9+P&r; zwi<+LFy3RUEARv)e~Yv6^QA{4(&aD~9q2!>+`=md9YAtHzeX$#@5rymKZ=9WOB##V zA94ZIXXwRrl#jGi0(3jGUnS}D)`7*UPJ;_P3Sy4%ynPvF1kMr2;U47B)u=bys1J*S z)aEDY)4;lS37Tg&hiA{XrN>Kk-;C6=^qHx=Eg&L>GK2l>^e3pP)4j)rbO{%=~_w=PS59KjA7(`I|qa{4R% zjoFRJi5)9byVzyeuI)0RVIVOh1?Ef)nSRpZ&d55<_PMHpa*@dXjvmtZ0ojp^wtsQg8{iijS4vBRVzm%dL$XNr852DSF z=_;g$A3ru*s*Cj0lUjCz;VA=mZHfmLd=!bJITL!7LG^T-B)#ea2;!3ohBU zsv2v#nEwOfV8j26R%iE5gFSd@J8@%n+Fh;OMv>WoQ81k!eg6G9H4@%-gu>69x*&7f z2(oAU?xfv$1B$4PA`k%I>=iiD5*8Wiou@~WTs|740rz0A-G_6g1wzx}!8iR6$$02w z4bD6i05O%)@$8351sP5C>11r%CJ?%l3CNK#sJZ7!Vu3$|)&r-by~rrfbMl10>gDGw zhVfq*ZbNafDzW+<%{*gOV~{GaW=w?h*vMHMVm~=f;f|tnq$+JH{HUOc?}fGD`3$X| z7uj{i^6~#<&KI>G;90L8xPU670oCIU{YK(@xGQd39X?x%>#}gxPF{SD9 zhKa3W$(IVZvWF5;mY}t3Y z|2>f%8{z(>Xll5~K>dqZ>tDVYJgVG-5XcqU_1}tNp%^z9ibd_ug9oCcFSmz@KW!&8 zP>w=bSC@c8<}C+PfrBsToq(1%CN;K-cP)m(KX;+sPc&AxMYLpSACdnku<2G{sKGM zRYq2vDY%!4>HIhsst$;8p{U=qUBtlY5IF8}gH&iUDYapc>~=P)q)DF)xCvtT$V_GdiaB68P>cgZOh+wrvw~iq5zn+7vU% zZ}Ap5g%}E<3CtFq&$^JS@l{BPGz8_^=)#x&`~^vbF3|N@?Gw8XU1;@0Y_*9{)IjmuF7P0R!dy z_!YM8zrNQ;r7DoMFc?P=y_25S1!5+EXIVLb6*U=Y-kH4Mm^S|Pc_vLGF-EXE_$&b% z>(H$!USd?E@k+R!Q^Wc)hoIWC+mXfO>@JFnIUG7%xuKN<%Y1|Rp#bhmjepBf$fRIG zM1E$F%prpZCtpusg-Jft?jgC@0{A{owyI| za5^UF@?kC)kFOqYM}YgUX-F3K+)yBm1SRneQXft;b&M{kmcsjk-dg+A%Z1N;zFH!# z8Zs&AC>NRh951eG;+!TkJWI*DDCOg|w>`scOCs+D58b3FEkJ94xW>`cmwQBpl_V1t z*0gW4;6EsLx>I>4zTEn?-E)pA7CihPh;`tgeD-%1AUXp16>UG70R@H7a_MBVg9X&l zoR7s95UsLC4e&T%SdlrCqM7|?O*RHK2gQgahpyj5m{~KCxTqtC)IPUzcb=O0Gp3nk z3G7&*X0L%;%GpL8-L`34x9mNN5VcrJb|7z8EZBaafqZ;EJbFHiY30iIPUQksb@tVT zZt4#eVZ9rT>Ok%(@z2ktzK12l)5sM91SNe;<&l+#%=_N4yCa@t1ZdpCg#foKdEC;# zjskkfIF!_pQDA>!BsTZ!aR&GY_eh@MD|eD-blvyer99di_AYt0CuTC75=q=GgO)y8 zIal6hx|IMOUGl?w5G(gt(vCfr`C7u=T8tRIdoL8RmC|x88%(x?RVp|ugD<>{BXqDa1d*uy7JWO2fwo|_EMpnjGs~u)RCJ-;qM+hj*lOt z_6cWj0uBhietvTI7J$4;sm(zF0|a3yZtpbQo3g%vSceJw*Q&7()mD#=?TP<@_^1b96AR^+8{pjxsdnqa1M z3YtcHGbIN!PMd+{d)P=Xp-7pQU8UrQr;!*Hs4=W0n{>?6d#^L<^F9vfPE1#1 zB3#yT{;j2^1dQ()SQT<16LaEb%GRi^lDVR9Hz{Fzf$-aV36 zdv4O~u0Ov-0(t0PSQ*#QN4%_@5R%Yp`gyG3mN;W#ftuMGu~U( ztG>0654=9gsJCD{0f`s*g3@+6C4YgNflsecE$y(d|9_Y|hww~;Z3`zI+v?c1ZQC8& zw)4lfZQC|GwrxA})IvPY7fMW^wKz;iY_xL=dri9{(2^gb*Qd*R<_?yicMmUTPF2bu5cDK zGN5M)6Gw|X(y6bMuf^Hpa>I8p;B}hvTPo{9GjOPRrcu@c?MpeAVPNhS#Pz_A^1s{F z(cub=(x5;608m=T)T#~zsV^eHid*_lQ3tL~fVz56BKzQkvZ#{9T?bkjiTt!ZmhU6=EO9SSDH<9rYe-KHleea`G2^!US5)g=0q)pN=l3uo0M65T!Vgh z16)DW8W8kYxe;LP&3{Q9eh+eG1g0f80#gu?_?Y1jw@(j|llp>=cZ0xx^fkI<@%EkW z&Svb(omft=%Q$M3?Hp~b(l8Eqw{o)z(s$WUCuBQzf_yECi6YH=*`lB_wAiOH<=u$k z5!GSm$cnUB(^uC*uK1=tu|KUA_y^Rm0MeLIzaVU)9)&X~>l`Q;R(U*f&>N> zH#kr&Io(I;WKy#RZ#OucmWjrzlUG}ji(ehIX10!s-?4_c$=>jxuM2{_Pu63o8()$W z{f3Kmm#^E&2V}L#C<(NHuj}_^1J(=zWGGZh<2cPd2zoUm7*TZt$Bsyo@z~!(z-$Wy zU&O(|i4cbf6Z-v?Xt{vCzfFT)KP45o{~*l$lkW{FOgw7cD7^0ub87=WQe( zq>9*+tYQB(!O@N@^{q9s%>;*kYouEPswl86Nn0e@zYg|+yAgBZB^=FJnnu<*K8w=W z=6;3!6`oF|RJhO^SA_zlz== z_dBK4Rgpv>Yw;Vn~44eLTwHmZb(6tpKGDb&IS5i zgG+`RcUlx$p+s-A1lWJoorg-{IaEC8KMTEt7b?CpGrq72=o+#PvKJ#8I;X`ns5meu z5hny~ikkN2xPQyg>VcF3Af}2Tbs(AF-9?OKAFcII7V!R&LIjfy9d*CAlA_pWqbdtm z>K)xu85P{*$ozHdNJW4BTAi7ojjkXfZKpTxc*vI1aE3|X3^=(5Z7|%qhg`f1;woY^ zaUv>fuVyC-e(LcYaDgrvTmH8HiL-XJPv@aj?P!~el%A;te(m`3Mtoa3_b)thaDI_- zN?uoP;#``aqTe5{hshz(>)w1+_4$RBQ)aBSnGh&%_1Me4>LpZR!Dfr7}d^Mo(nBF##4tkIH9RjxxD zhJ8dm%MSKBe}A(@k>Szx|7lDk0E&|3)MH$6F!bn#y;M@6f!ri2=$0F5_6AZyEN}tW zQt_c*0nFPW6SkDb6k(^P67_$v^XU%ohJqwS5{F6)-PfH<2}=pou;a=EEzRmX*C~F*wyD>i8=S`A)^<3{5Em?cgqLociNGq`ooyecp-R2K8G)bkk=H6rFRcyE>=OqvOli{1 zmiJx~ejTwr*tE>78;Q!cw=}>8a`F!zzp3~J%d>jdrmxog3qLXJeb)Q03J(9Dj`YKo z|JTTmm^AtyF$o`F>i8cu>Cc87u_Urj>meYF5dl1?vZ<54aL!T;eQwi2NHhWg;;tO%um-Lm@B*g$0I zm>I3&u_P#Y&o4|#ls#B8LiK~MHJSZ6`D^@D{+;>;=2-`apNB_8gBay#eUvL#h0b+5 zh0AtF=Gxw~VDJpY)moE`TKQCkmev~GzU?Nku$d0m7?*a0cW(N2{za8F7CCdc`}qX_ z9WY!h*9>r6$CZc@L0NapOjRMj6syU#SRQuE`knobRovp75L`c&t!_az77Kq)gKw8A zvatT9v{3D@sxx1^@X$!mF5atRboD_p=d2f9=`9`7R63w`=;} zI-QR1YP3hlBwDKV{<5hSTIDMb>htQjcZl^U?{f13C;!qoFS@}oE1b1LG4Hr6QVRGM zIot(SDcPonV6X;4bQt*8NYU}WK#ziMC& zT6PMYvXK+DIob*IGOxHD4R-k$u~!WF1=0JBr6ai z{2$)33*PR~mdd{1FP{7^+p4}4Ty;XNX;;?*@a56T@NhfWvft#*n9|+V%XK@$_99f0 zZ1gZZAS7b*l)yN&Sv=G#S$+b+?T#XCTj?j%{sC;z{Csybyqh^;; z%;)RLY=v2+vb-N425Ed5Zy@aWD^OrZVKZPVke_+acJUN%8?AuP zfAmN?fBO7KF%mLjb0x-r(=nC~iUcycKyaBWT)UsM&9L;xX)AT|k)sEu|IJhbA+KkB zeS6zAZW{{KUsshX6fm?~#D4<7)2xB!%|;nWi?KvV+w@v;mP7XINz#s%LGAKU`qR5B zFi81`-=H3YuO=pLoq;oeWv494qy*4TQ|Ys!_VhEu&al@%u%l&8T}w=6$kL{MC)kPq zNKyK51)5x~rx~i7NRO9p!(Yy+zDKZ1}1+w5gJPQb=x_!vhQxupvQd z<_#9+=3{|kZX+A5P*I#<&BrtEmBOZcjjy{(K#jI!U@uuY$DE^i3?W1&8AN}&M{8i- zrRc6OA>L%-e@iaN@E)wz(@Ia`z@YA8r~{Fw^<1TN!&g=oW-+_y!#5}|A;owE>-$f={bBpWO>DE$(*MPTw^ES6Opw#m$@Q4`;hraYlQz1UN$qlw~|!qw!RIw0b$wM-k>VKfAQ#W!hxiGB;{27a>TRZtWhFuZuDI&5iquVYS*M zu>Bt+4-_i~lt=LksH%Tq8pU087Y%|LXTDlU=D{fptQ`P&_#jSyn-ZomaHYza5erV1 zno+^m=VJSg&}y6eT&U_?lQpPw{HB*H&D^X^@_(-z6dY|$?wi_)E#%t9+2{7QSJ9t+ z`e^XzJ&RrE@EP7U%^7QPz-Ws&hCPZyE%z<=xhf69JS zMGp1h&#TPuA7mlke^WV$GVaI#C)b}Ip!&~-EzT&C4|yMeB9MUwXW$Dg9SohE~ikBgt3HT!hUxp9eSW9kU#&}6-ccBJy< z%GbJLYkN0%K4tP{&+kPT_*QDy{ytb@3R=&VFNIMy&rRAo0RzZZ!7G1tetZ7@W@TGI za5EcQQy;rYG@*!G`9aj!_OLY5spv-Qv{y6;+Sm>>w96l>a({=bx6^(vWLZo18nsg=H#BF{mQT z9uhfJ8xGc{KF*#Sqn^X~WR!pqVLne;Do{;zmuLjwHxxCWlvzOWIFl$kh7sNA<0HXD zX{m7m|GHpYaqtGOMgW9sbg5-w)v0k~7y4d7)hVf&VYVtC!HdY@V+WNq94JS!MZglC z|Gb*@o2<}IW1EUSQ@ENe9v<>X`eO(Q^^ua{>KbP3mQj7cRba6VkK7MJND`%EjkkI4 z5j-Uvj-kfiuNg4P9-q(A0 zJ~%foBKxMm-@UnhTMkbJp8 z?yx{8tpK?4w#$@l1;$Nt1N*vDYj|iYE0JD-nr`m08B$tKSjL zerD+QQxEdjD_AJ+z?YkmKstV7gO?fi*)utLo7Q~xKBc%AG{F^aJ5Gpjg%meUgTRQb zq3U8OLy?mZ&9ycaj7AG(9FRu`RC+0J)&P8W#?c|TOauOIF#`q=ib>!iq_Y)&>)>&i z&Z|GI3NMCE=*|=2F|4mf=G=eH&N1r!Y}RvLSo-*|HZ?VTxpn!F8+vzcHpj)MTk(p} zn)GGmX>rZyVqMCdH$N##z4fag8O8_^ce|IR#bft=)I=_CXrpp0wZi+9?)1h z5&l^9rv+c3?lKOK&&4U#xRg9PdEDVt-rJ5w9G-{q&!3^~7x3#pt?NdJsz@Au{njMD zlcz$h(1|6Bc5H4_%k6&cVmUxsy2 zKmFKG51X*IY)a-~o2KMr-zm<(As$TG5xlpiP9asgj5(P#<1plz2D0~-<@?J`th=4( zxraam(|wlmTGn9TUlzJ7@I-yWVT_*oziZw88croIIlX;%vQOwkyz6@@v=eO=m`_DM zWQ`C52RXA31**>EXM#sBv}?dDDTZlGl+6)(O6`^O3d5<%{r0NIobg+X-exqaSNpVJ z^2CxMA$#Wm0fEWWw|#z%_io!q1hwxP4SH~oFnopw5HIY>^qZ3&G`OMFJ|*~W98vPM zH!Febz}ijfOtU7(oczwnt1y0D*lbh-6EcNNQ~Qwsr-K0F-@m|;;j8ZHhPGn^relkh2)pj1`P_Y} z4fx82Y9UUY3B#l(WrP`1FX^x>YYe0kGQ2t)Adx#;fGEc*^I8~Nk(~t0drG`NfU!9Z zOc)ch#mvmsq^CFdm>zJI=M{sx5ffxlaPAm$T!tUeqRle^kt##z)#35T-i7x!sUL(* zbCm&4-aSD6)U}D47q>!MX7oU} zRkp<%1%7I)Rd$2@@IZjMZI(9Y01coeTF<{JW6#HugN;Em%nn$bU&ne(an@WC3TZ?i zh=F1ZR*Jvk+RN!IsMUw_j4=s3u%q4&cp7L!F{^_twVm6YObC~igmCX?>kIM-MtBg= zo3SNpq%pdF57G7UY4;jQibMrGa7Fvej*=_Im+vQDDvyd6>Pfq#kSF1VMI_NKb+Jzo zv(RtesI9g9JglKz3&ujfU6*Evl=IGY(jcecT32_1&2PD?g?G1%b9QRbgv?vNLxh@O zEo)`Cgr2G^-vTkHOc6o0wsbf9_#;=Z!;CG6*bzd55V)BdcFX+cH^r~U``+BAqI1fQ zbiV-7Z_pLPfmh+CUqn})Yvbs8K9C=xZX zKau1o*tNm-lT?oT_E+%Nq|!DS4&lYT4Y9THhqHpA(ZDyw{6(zDXe5a$F&=|`2-v~p zH;N9b-yCp0VA$LopAW`RR7Az)Za61)-0e_dag{P(7zSEu=+c@?!)zv*j zQ>{?vx|U2BJ_7UC>oIs$b9oA&pbgb3J7Qa<&x)hL&?&?SVqeFLI<+jZ5M;%DU~dAL z_LuIv!7bss+lZ9Ds2>-3eF6^Pl0%iR$|u>i8*zrcV@t5bHYUe!!aZbf{($G;ShGnj zR2VwWy-(w9-kig3>VP!~f#K6mwG!A(E=xHeSca$_yO3#MT{_dcN26gq8E?PQ%TUo} zC_mV7>!SI4uy$iGeH>5iYBg20)3*TDrlDbN%vr5xXK9A-<}8MQIWVY(RXyq5QLGrr=Xe1Wm|%bE zp-F2J<4FVpt)*1l;h>XYB?}q3_X!jGF8vt0jo#=RF~spb1|21(KfQ)E3L(05U{EF3 zJ1^aXdYSIG#ZCod6UEK?lru`^yd|!Im#DJ+p|NZ{mdB{D6#xDC9V;)!l$YjMq9Vrl zu$aaHdWu<(+}(up^1yx62tf;=G`N zWU0hD7ErV2)DkuyP{;`Zvg4rURv~@7P$&hX%%f5#Tg#`eLb-p#kok0|*)W#$P>yJe zlA(#YgKK;oEA5W(M2kua41k9r6RlYg4N4U}Ag)r15-E9lC4MkK;0p(Y;0E_Q5H}^Z zV~R;D!9U*MJDLhm$9!4z>8%25_#={+i%n(o&GJ?w^-uiOOAW=Y&+8TAwM)6l(BtN&|>YCKUF zkRzYQS+4?f`XE&cySYI#ucK8@z_I#>(Sq+sO}la)`Vo-HTLeSks;nWy07@43raK)(|)9nNhU?pefl&RS_uB{MVC=E{Yxixo534G5OLc9N`Z2BSpOUas%}qiu?$UrN2Q$du0PMd$|0{k z7@|K2@}qrWF&HMLzSlWs*_ru&8;E1{(RTrf_4)GEmoxP z2qzZXuS>eMc3-CaI7#5=Yq{^ED~Ok8ZS-AuzI8H|OIvA0H1G*r)rcD`STmj>tM5VQ z&^awU`-)qhKL#-;Q-(exZiwE4kOpE1Lo>rjf*@3YP+4UG;Xn(EQ2{Gzq;5aYT82)~ z!i3?VuMu!|J^r0cy;m!3n8=!fLzxjjPGXO`K zqFyur7fMVEg););a0!Id1B;I>otq6<5g6WU?qFLuFSkaRsQB4(n6r*xA4NF-(C@W9jL?K>jNYoW$R2LL&cJ zsr<<`H~z>21pk!=OcUj+;Q+FB#*P-Y&gMT{>}oaH*h~h*Zt-zI9f!Y&Ilc#Xv+jCvpbL7$8oeIwR>zsZG@|eA`#LR1RZL} z5&xf2hljksaRuB3=by%Grumi@;!4g#OF6qCVNVsf%xj=rnsQora)7Gk6ez_~|Ay@7 zcgNonPSRG*y6NoNT*`4b;zVd&e`?R+rNj9i#1u;Yx%uIBc1!l?61v9}OvI}g-h&Hz z(a3Rn9(Hxg+(ko5a&}G%VbhPnKNops2${riQ7xgPPgtlX{!o{TlbN$jkW-ArBZ4g@ zA}b=8Dk`W_imd$gIRFeMe}HwD?%~UDD<$V<4VE0|uvh3O#UOnNnwfHHq6KG9H3dG+ zvo4Xr(bVe#by~o~noSY+Qo$5^u#Yn;mdeSf|Fk{{`>_UwfuJw>E#VQhO*SRta+us5 zF`BX=Z(*e#aUdd*r(5-R72#8Fwhew71v*tzl!^J$OX1&OPLzrYru} z%Jj}WnulHX>6S3B`0c(IGkE=N7iLqS0@7(gkHcr<2cngU)cqdu0s7xlKCWY{y|fc! zu>0eCRbeLzR$~L?Ozgz$9L-FA&ULefR_sO_n(t4e*GFYTYJ%&*d@5|vCy3q-MBC6` zutozt2@9)PFtQmhNh>)OwfEM0!Rc@>Y{da&-a-H@TIvb+4vEd`TL(G*hg2T#$C>dshBTf zCzc0<<7tQCOzsn?c?90};Y(R)cHx$XXfs)E`bRM3RPpQ>0jCZRKx}vP2}97TJKj`q zSxIf{Tn8ZEOMtd=tc2~tJKksu(vDx;VKAnjg{E1TP^G4A->6BNp?VaB*-k)Ux{Tz` zzpSz=uEG9fSmzv3lSE}!>1$QZa*uzn0WFqtl}nieSLh<%K{7Y|40wN!jo%{qvbRgm z(?V4gTV{wF+FlTIKdU6KnvWVnW0lE#5vZbXpaDeAD(Czn7VL`eub{V+M7I0MsF7G9 zo6JRZ$XG4fj0^IEqL)))`J`_3lKZA`YC^CRo#Nv0@Z%h7gwvk0o#$3BIT$J=D zVPJVvIjimJ85{pev`Wk+nVGwH0bU-_{1StO>Tfll`gQ&DxQ}d9QuPf41){M(>9I=oFd%Ug1X!Ity;gx4h4f1m? zTA3)tQ!b%O*=4X@B~d*mrinNx_$DQKt8$;w@_DKfD8HL;k0{20$@q8mj`6y5bTtcuj0{wivSIwZ zhD4BX8|&}m2z2nk4=LLX0hM&Zn)%EFczF)hhgbJzOLa!VA=_~0-MW0|z3#XLTLMi1 z6{R6NjAjpYEcXaWjdQaWmqEX1N%H_p>e0cAF_?>w;0Q|aDEWT#TIJx_qb6kyQM#XA z?{)YceT3&LO}*&dHY~pew_Jl~)6*ePbRaCRfffaeU{KHaD z$j#nH<;8lmMtBwl0q`9E>?re#^)ZRV=rs)m;$NlR?sr;7uTH07`=$QKx^Bz06wd@o$#I_S81Y`nm zwwwDJPq?(*v@p?ZlRN9>zD(~bj&jxoDnNz|PfwJ@98c(Bo)Nv@L;GSq670|fXe5!C z!o40zf7*u0;ne*%7Rw7@)zIm(eIKmd%+HUAE$FxeI0o0hKR6985MTl#?BO!XqQMTn z;#zMga*G2=vIZp3o`9^G9&K&QMoXG60nJQty5*04OTLUtoy8lwH7JIaG4koWa2rb6 z#U(iqPsBUs@XA}Fg!Rq3{$3eM@h@E7Uv`L=D)e*K>+ZO z+}ToqKCP3 z*&Ksu?;;la*jfgdc6mJ1j1FjJh~EIFwZGh>dR!5A=|LA~CHt^Z)O~Awb|a@*_&G|s z!sVYDLJoLSqjj6uYre!KfVK`-i^bTpyFEce67DM$FVA50U!pxbBG`fr-fn)xi4q$W zqoKPMJ=i}Bx4#B_LJPFAm{`t+enuALfPeeVQtcYvzI_8IcEWvAiIvR~;y;Y#Z$t#t zN4c92A7WxrDNY_K3m^s`AVM)&Y2k3D3?D;z#j`kQIAXAv?k>x2c8XiFDjUG`Z|D}Q zS=C6?9w!yudzcan4F_T;6iwn%LNX(0NAJlY#rB46u*D5h6j5LCeJ$nT(}Y*I$_X!U zQ(U-7m6-t0SElb+ckONs7T8=Yd^yU2GId3e!5xNL3Sl7q1SHGA@1eE1z69aCYqMGz zHc#FJqqP>`-0(K}L}p8lRqo$%PC=!N(70c6!}}^%_@Al4fH+K%#O`EIj^EnB{nDX7 z^vBUBBg@>HtW`C+EWT~XY9Y7B%<0>m|KmXY2TTVE^dFv66vVTV-A`Z8jtvAv2$VQ; zfsxo({6nexX$g@2SNnP5%Sy6D^O_6Iy2fE?V+jSBKaPtn6(yKOZa&sPM@xus>)iVO zG^J1?GT~hF2BNj3QA6fr&Z7U~5bm)HUMxaaSMO@~eDQnU5rV6&*l1Ehm5CPiq{gC! z`(#jKDEAl+wHxDema)*UC|X7FS@^|UpE#2N$PD@ry2!A#Oo>ykJ}$^_E|$ez!=BRQ zZaKiWn-4h)jO%PlY(~4G*cp3s;ZJbCsfEDB<2$9$NF0Xnow9mzpTSm>&^&t(iV)Ta z6O&ft*DaoKZWmbhh5=`SqG^qEix_(_Q?HtfjB;DUn0CZ(RiaV)2uF;l~;U$S}t=Q>N-Ne$GdUMgltOK9roCTXkHTlw4)) zb}3K+nEbBQHZ*+=pv;$_LFY)x>XuAo8QLyjWNvJS2SaA!uxLjvWQ^7~{FK3xl*V+fSZk2}F+PG;XhBuatxlgD*P>Kmn-X_O$OtXDI__)$ZAv>T zB-Kd0V6xp|TZB2qLv&ov)?3Fw^&(T*paVt^sT2)!(OTkZUAi3WypWE^-&!j-nULtjYYZs{{bw>vYwke;M zer2CW)5yXucnH#-bfi)hY?LK|)2x|5Y%K_Ua0&2U8!;43WK&u)3fD(;kYX>E5b~Ha zd0`D#oh=;rZQ6=@rw=I(6Wflw- z9!e;4J~z@E>ad>tSKz4+@G&wt5}`E51;z~T_f|*Iy29}9j%UPkI@twL?|BmJ^FAU4 zstcoZuQ8y)aOvD;AF`gXyQfFT<1($-lS@e<3>6AeQ&yP9OLSAf4e~F9C4N4E^GY`L zjB~jy58@W|PVS=w!wpvMgX^H?SWMdr&Y5x_ z!IMtcmWFq4(gWd9NUS}Fy#sWhzXo^$6^{h%cnD=cd)HvQ2J^e+w`#65c#&HeuzoKW z)LZmaroGDLZ{6d7MYV=lZD&Mr>%=d;3)LS7V77gJT-LDobS`5CNm{CBl;vJb76E6u=gVIcfXjIK&s;G z6Fy)TX$SIT`fOvaGyQGn zH^lxc;HkTD?8)Jp8_z0}P$kiKO2W@ZzsZl-#2O^OLZ@SSuqC$?p-A2Zg_(1Y;4u9n zvN3(6t(OtxA*8bLvDzb&WtOS?+KN&FLSm|mTq>&K!d#^qKRotO=t-_PCg38W*T`Tn zl6OH%(X$gk`sbI4aAH354O7i<1Hou8Q$c47e86M!hQ3?f+_3jQw=D~d7)u#DOwTs_ z68af+-u=Q$NtI9+;rlrAEEuRpzkA(`gbm-}+fAU`fsIt)k@+3jqbGA?&??VGC%Kn- zkR$&=>pmhax^{z2C`{cN$KihpsYmKGmaF}~8Um;QmotQ+!;kW{m}M)89U-E8e6ekn zW>%UuiELSl;rM9e*uOYqIlAI)C=h23hOWm1WbpUscBmYCaPdvR*q+ezRdTQr$I*Dj zx{i~-Zh>CYgC^EO{yyaEtVLj=rbl41@*pE^+i)c3z!x-fzA&&}bM#y0KA+6o{#JoD zd#e=yxaNYffh7ScwU=t3kV252Nk76Zs> zC?WE{+vw7u;C9a=dteDeX+yx8;&5UBPMwVy8R*U45Dz!Cqg<>kU2biZGPB7FVty&dKM zCTsquKu23ima_kF8}1VYsww}UCvz)ZEaSA%DwyflvZe{U`ZnJM79t>>L@h%EmmplLxCvf7WUkimUAd%2kAMC^jMvgs zb=IoCsQgua#&#jG189rh?VL|A?J#|-{99XFQ@g$(b?FKqz;J7bpc3t2c4`+(huJ{)fB^4yq@}CU&UdIV+HZx)an|EHa zho>2)p3Hy&w)sWxq*&cs=OImE(`>8iSex#vkRl^Me-I*r6)FV(C6+-bwK&azbY{)y zw&Yo!rH#N5RxV`aFC#UUF0uOSkVmYiPr`LE*i3kXAX;RKN9#D1N zet01<>Ffnd6xHV4Qlk6?Xd)Qtr*(S5kMSdF z@|d7F^_{7k%z6%VC>+X_Ka1889b&r*z5~F*<2Jw!vcU@lHFcel+Te^>vU(svk;qsFuK%l?^#?N#Og+3JMEMS%uJeYYA|I zmJu(gK_TKuo|!(s>gHemFB0z=Jajyz4{zKEt%VeJwW&}ZF`dQLEsX_oc&Le=BGRtF z3A>2Jw4HWQC)|fmNf~nLqNY+ zZl;PpJdSzEz_5%z;9(8l$XNuGJ=nOY`Q%ubBLJ6?? zK0O_b7(@2c`^dIBcx^Mi3T$hPfki<6J&H<{tEPLv$-{X7A-uWb0~-=!MCTdtB}a4& zbCr<@+=Ps3F4;Bg%~aa!#Hgt)R}NFZ)@Ut#EoxA;Yyz+eB4w#$LV2 z)9|h*bT=hhC6j;a1p$*cNhKYVAKw%1u>DFS30aorU?H1JW9XJn(ER#L@r}Exg^{@c z545lUNAY?7aeJ9*WDOR7++GpF#PWI)z?H@isgMoT7r*XXz#KtNZKZMHb=W+z=1db* zdL@r?Ig|#`Jlr)*s)%4Lyj!n#Fp?yJ2+hPQ5^h6~{@)&tVQ#E;kW z4Ld{y(Qkq~IFl!6+LBZC>9GAB#Ex#@W5=2!=q!a6FiL%j=S zE%~Y9mrZ<^-| z9+I%eHVR4A>Lfpj%0Ew@DY2gb)T7IqoJMrC>u+Eyl-o_18u@h4Dw|^s! zU3h+EwY&_<^rc`tMN!oAIs_Q_nCG&6cLPN2Wq*pxCzoojY7gf`L{ywd`SmdVo_a+2X12GQV$LpM{;TKu|ocN&~TrQe9wwx1sM)$w)bFkzqQNwvwl+ z0!{qrcRPqh?dpO+TKuan14{LkuF^sb%lh-TS#mV95`Dc-gjK;wtw~JfrgGcEqv{w8 zQs{Sg?5v3(7V#0q&P1&&0NClQ%d$`99n)UN%xl-!)>9yK9ym~r^s$P&%2T~_Hg3Y3c5T5+hYgh#(sR^z>BXo_n z1{OrFIL>I+wfZ?u+BtAGU@^^x83P_h_YBHQ;YYF*UhF>}V26kS@IbT}A!l%@Nq_4m zc~e85lG5oZX5HB={NB@Ua@En4*Qu+$+>-jbvuTaP+kH7)7^LanF-~PSy-B7W1f!iT6-~$ zOjJ(Gu-RenFRK88$iC(45nO85Z#7Ir^an-$^5;e;~4^oT6}RF1{?F7Zsl+6;9)6W?+p&E>S9;(pNQ~??$y+0*ZiC1 zLHG@KF)wDsna#b<>9goFzUGrunGmPoGjA=+)4FgZ8}8!)0Pzxl{0g4${pnNH}dzLEO!vqDW7CSUZ50{;xc4jc}6p? z;m@p~q)k#R^l~N(p#rNODXAQjfib5@MSSSlZ>o6?L|MhA5fd~E@`01pHkmB**tjY1 z4FmNSS)u@Nn*4qhfEJsfa9fjYM+w zfY#^{;1enznk^ft>M$fL!gke0!wUytc%9LQ9ywY+p_GmJgJABIo6J2>m4M>5LlNn0 zf@hS5*U~@@Z9qJsAF`fWaFwB5nHZ&#qsjdc=hwbONC)CK>*zm-F5Se(U(D2@%BMXn zB#Z7_4}T_%Y4A0-G_!=O%%)yJWj*)3OwjEJ(J_euk7r{A)5Sz=1$(WBeCGpPo9T( z0KFi0o$MaXFauCD6stv7v1f5)b3U?IfQV(!v)9?a+MSd62luT4y;D z6Gyl5zfwK}F^^x-9Gj8@MufFV2wfgi0;Vr{Aqn?D@ z@#}RTXh@64NByFS`iJQIz7$_!1UJ?T05FKKr=|3rQ=lFsWmh05Jq0IQox#%M@5l0P zC9FpKd+AmmB!|-%zM0sNQZdgCa*n!qA;J&nH*;E)7@tqw6xgj8oBR;}8UQ~*qFNHH ze$~XTL9ZV5hSNuIW-`5k@BinA&D1+;{|I0}Kc?^he!qX##JV;zQ5Pa{`CFe^{iaNyR1iFf*?_Y8K|ud$!MMIN++no z@DxV)3{S3D&?%<==@i zJ4~%Ss;%ZPO>#ZdZxQvM(ysw(-XafEGa%F2>hgg@U>1Rpf(7M2r6*^!hhG0!XC78 z7Ql8Fd+4RBQPy11o+2KW)qI2PRT@WY+s>v9IDVVTq^n>H>e3&^y_+07P`DuM^W!9w zh$Rb??PJ3fPF0erv#LaC)8LC?uBXJ0l7&EY<-&XqnlH@D*#E{9N23)nHk&-0d;?!K7V`8y3y5TbXPg`FZ7T3G{4~*Pi^CJ1g1QE7{q}TK7^E6kjHg z@Q*vzLNawN-{;#ek>FDLGPtQEOIhj?f#Q9dW;exi^6~Q(cM3le%a|5Nlp3!li{^4^ zW^v0GCoP->PS2-4fDQ=*7O*1*UvZ;7n}sC*)7)_@4KS-_hn>qjy;h3ttwe1(Dk)Ps zVZeN|)6W(>KQ&w1uW@QxhuX6n$C zro`6Ol*O=(#pdxvVP+!r(nhtWOgPz|aGOjDfX@Nx)M)O7Bk#qxyk5Zgi-_#OL9}Yi zTD}?r9dNz~*^!ZMoM?9()r8^YrklEAw1o1*Y`+IG<0M#7eSXxqfzQXmnb5j~RB~3A z+;kamrlBF_50EF{8^~Sw%6?S3NS+02;{|0%rZdG^2-1iiNMeniBH+|TXvWc97 zc4?UjrZ?M+#oSWT6>?5|ET1e@n8XV8$zTmPzwO>QhUyg!x+2O80d9jsO1@NO|NQla zX@aUjy9H}sbSd0*D-6~h7<%d&8Zv*+!(_2~U4&?JrR*3w@HjbICM=d@vF!&@S92#Bg?NC+wj z(B{co&_*W=fS5nw^*4js3W`%2WP>=_@4b*P;2pop%wOwa$+K+oT$av+7pWe|^d*^tK?iSIP_%v~~BAPS$=RGL^I)m_&#(v#oS+;<(=+Tq9-a%yD zmzOC3TAjDmtM|jkPQPmRQ$-|W5{fA8y_nH{hgw1ZMWwtsi|bFRgHoZ^DM@#4Zr{w^ zB$f+m_3B#Yt@wu{BRE~P=2FqFAY(H?P#J)bal+34Ad)BAK`g*lvpA@v3W#9%b zC((irFqFG4C!=ULIk#73uVt+L8U^tADs@J`!CqMT08zx6KZR$^S_T_LBCWig59PiA zShoz`95tws)3ki`CRzlLF(E(Yx3CQau`M-Lq4cMD5Ge_g%f;>sOAou1L-wE$ijpCkzV^W35VAKF5PQT)F)ZZkfmllpYKIJcafxy66qaTZoBp` zkEew$Mr?3WQG_p~*2amsHYs+pS-F-jH+~cijve*OYb<-G*Et?`*CWOp6om*k_$#5M z&i@7);#USrF{YRziuT$;0xj$U{Z&y##ePCpbQPQ#MtHre+E zWd@uC+H&cejPOfcxJI}sajnBs6ih*MLE?Crgj4#+bCT`4KNi_gFm&|@`isjrNbeXP zt@&Nn4t%Ka4H`N^Vol=MFS+7Q0kAx##LrLGR0qB!eHVJQLH4Jpr-w~8BRH&JKQgA` zaDV4#`jwW`g&_y3vP+YLX(ljDhC^aBW6vc5B+_jY{O-plr?Y)CW0#d4b?V9mFEyp& zG23a6M~uC*7v@0EUE5PABFZe{MXMMfOA+@Z2kHt z*A`trTLwX_zMWB~#LHE@QkfJrW~OU|=2(gcYWHMz>bEYBMcn z+QYp0OO0Cf2>=;XUf{+y7&g7Umcp6V8SvV;kQJ#wYeE<~p~irdfXAH~<^-|x8FC;} zHkf>=`&(kYaT`V5rtu5~z!6p2)XUn=TC6%U+TTmX4rTC^ctE0qBopn%fufBksJHo( z1K;rIg-BIcO#P(iuL#sfOV3(lBBG!7`YYMDhgMeRXQ)g9n2k(B9)ed|uezn$0`mh6 z^j%jNFyhD<(4blr#JA9>R53GJ5Mp$~E%TNe6v(L?tHg#e2$Ls806Id_P&0<-*^H*T z`gJ%p3*<@CLRP`Udo2kzql;k(TMa4hoX88K(yTT`*T-Ec@a9r-e5)Rnp_RH=_NJT} z|BqVD#fFO6Z2N@WnceK`1_Qb&Dv~fZ#RU%Iz zd4)#P1bI^GB7xaGK>te5GQ2<~4)vI2(r^f$av@X8&jQGY5vNpZcKddgg0ORmgS`uR zMi+i1f_TqUL$<0|tVA{dmTL6ux0!Hv+#8$siEkiL5%+wOY`*tWK>qT>goSi;=T1+C zFfPq*n8+XH=)Tw|F%T)o&JY zk|m<;eUzwrT1(SSV$V}_jl~yez3=zCKBgM5k+k{uCiN*C@N86sCu*jYZ_fai=Ci=g z;fE0jXm@&;p%9dq)lnoAcTPj7wT^g~dvTru$lEc>04jOuM{LtU?J`kWq{p+`NjK@a zlQ?SezFrA)FNTi?J?wZ?Z~Q_CA~A>Z*p{Pu#X3GLlOXZTX5jFSBiNlB#dWgIPo5mP z?2|&6601{wvR;8rxd8x4>YEL890-HAb`o`6dUQ4M__an5pnAdyf{RPW;%j1o#}%

k0Zy03R@rHxYnsn87Th#s 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 Q3kh_3iUC)?`?~@E0~`O&p#T5? delta 44738 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