Compare commits

...

51 commits

Author SHA1 Message Date
duncathan salt 03be08f0a2
Merge pull request #188 from duncathan/fix/tow-rope-mw
fix tow rope item location not always sending in MW
2025-05-03 17:42:28 -06:00
duncathan 1c35a17717 fix tow rope item location not always sending in MW 2025-05-03 17:40:25 -06:00
duncathan salt 5e6321dd55
Merge pull request #184 from cave-story-randomizer/duncathan-patch-1
Fix error handling in TscFile:_getLabelPositionRange()
2024-12-18 15:25:03 -06:00
duncathan salt 1a632137db
Fix error handling in TscFile:_getLabelPositionRange()
Fixes #180
2024-12-18 15:24:06 -06:00
duncathan salt 08f0c555f5
Merge pull request #182 from duncathan/auto-version
Automatically update in-game version on release
2024-12-18 15:23:01 -06:00
duncathan fad711364b add patch to read version from file 2024-12-18 15:12:48 -06:00
duncathan 902dcd71d9 Merge remote-tracking branch 'github/master' into auto-version 2024-12-18 14:52:04 -06:00
duncathan salt 140f892222
Merge pull request #181 from duncathan/typing
typing fixes and schema validation
2024-12-18 10:32:06 -06:00
duncathan b919a44e14 workflows for validation 2024-12-18 10:31:11 -06:00
duncathan ab1db92c40 fix mychar pattern 2024-12-18 10:10:14 -06:00
duncathan 6e27d66b06 bump python version in workflow 2024-12-18 00:03:24 -06:00
duncathan 6e9edf4290 typing fixes and schema validation 2024-12-17 21:25:33 -06:00
duncathan 45586f9a95 automatically update version number 2024-12-17 19:25:32 -06:00
duncathan salt 0a93bf3867
Update python.yml 2024-12-05 15:16:59 -06:00
duncathan salt 268209bff0
Merge pull request #179 from duncathan/fixes
Fixes
2024-12-05 15:05:10 -06:00
duncathan dab4ba4baa "document" undocumented patches 2024-12-05 15:03:04 -06:00
duncathan 43cb531c41 fix the alt-tab crash for real 2024-12-05 15:00:51 -06:00
duncathan a95c51c9c3 add ikuyo and kleckser to rando credits 2024-12-05 14:48:19 -06:00
duncathan 5bc2db4b58 moves the helper block in Weed lower to make the jump easier
also runs the CMP correctly on all entrances to Grasstown, including loading saves
2024-12-05 14:26:42 -06:00
duncathan 6bf382b6b0 removes the block in jail no. 1 when loading saves in there 2024-12-05 14:20:09 -06:00
duncathan 18a0eb77e4 fix plantation curly item not sending in MW in some circumstances
when collecting this item without either the mushroom badge in your inventory or the mimiga mask equipped, it would fail to send
2024-12-05 14:10:44 -06:00
duncathan salt ebf96d7d2f
Merge pull request #177 from calvarado194/tweaked
Bump Tweaked to v1.6
2024-05-27 07:03:06 -06:00
ikuyo 483585cd21 Updated several sprites from Lethrys. Added the missing item sprites back to casts.bmp. Removed spurious files. 2024-05-27 00:50:11 -04:00
duncathan salt 2ac159cd9c
Merge pull request #178 from periwinkle9/update-mw-dll
Update multiworld DLL to v1.2
2024-05-26 14:15:06 -06:00
periwinkle 1bade28b09 Include settings.ini for freeware multiworld DLL 2024-05-26 15:38:26 -04:00
periwinkle 8617fc3a0c Update multiworld DLL to v1.2 2024-05-26 11:16:42 -04:00
ikuyo 75317390eb Updated version on title screen 2024-05-25 02:23:12 -04:00
ikuyo e7eaf7f2ee Removed redundant file 2024-05-25 02:07:36 -04:00
ikuyo e0058a66ca Bump to Tweaked v1.6 2024-05-25 01:33:39 -04:00
duncathan salt 106e520a32
Merge pull request #176 from calvarado194/tweaked
Several fixes to graphical issues when playing over a freeware export. Windows build should not require DLLs anymore.
2024-03-13 17:59:06 -06:00
ikuyo dab682c263 Merge branch 'tweaked' of https://github.com/calvarado194/cave-story-randomizer into tweaked 2024-03-13 20:55:43 -03:00
ikuyo 91043f453b oops now the actual builds lol 2024-03-13 20:54:48 -03:00
Ema Alvarado 396c461738
Merge branch 'cave-story-randomizer:master' into tweaked 2024-03-11 22:51:18 -03:00
ikuyo 8d129d39c4 Tweaked prioritizes its own png files over vanilla's bmp files when overwriting an existing freeware export. Added imports to avoid needing DLLs 2024-03-11 22:50:04 -03:00
ikuyo 33f12180ae Fixed ItemImage missing the rando aggregator items on Tweaked builds 2024-03-09 19:55:41 -03:00
duncathan salt 83a7b13674
Merge pull request #175 from henriquegemignani/feature/lupa
Use randovania-lupa instead
2024-03-07 15:27:53 -06:00
Henrique Gemignani Passos Lima d6ca45ba01
Use randovania-lupa instead 2024-03-07 22:27:52 +02:00
duncathan salt d70e9214dd
Merge pull request #174 from calvarado194/tweaked
Fix: Missing Graphics in StageImage, fixed issues with config files.
2024-03-05 14:12:59 -06:00
ikuyo 925b8563bf Fixed several config issues. Added missing graphics for StageImage 2024-03-05 11:58:49 -03:00
ikuyo e3b44f719a improved sprites for StageSelect upscale 2024-03-02 17:08:30 -03:00
ikuyo 7371f18cdd Added missing Armory graphics for StageSelect 2024-03-02 13:32:09 -03:00
duncathan salt 409aa7fed9
Merge pull request #173 from calvarado194/tweaked
Support Cave Story: Tweaked as an export
2024-01-27 18:33:40 -06:00
ikuyo 0e44bbcb74 Exporter now checks OS it's running under and bundles only the executable required for the target OS 2024-01-20 00:37:56 -03:00
ikuyo 6d6426ff05 Moved shared data files out of Tweaked/Freeware and into data pre_edited_cs. Patcher moves data files from that folder into the respective build. Freeware files have been kept to ensure BL compatibility. 2024-01-14 19:11:21 -03:00
ikuyo 5358ef9fc6 Removed unnnecessary files 2024-01-14 17:10:44 -03:00
ikuyo 20dd317a09 Removed unneeded patcher_data.json file. Moved CSPlatform enum out of rdv and into the patcher class. 2024-01-13 18:36:11 -03:00
ikuyo 81202a77eb deleted a TON of redundant files 2024-01-13 18:18:59 -03:00
ikuyo bfc491b977 Replaced files for upscale with the Lethrys versions for Rando. Added code to handle exporting upscaled mychar. 2024-01-09 19:28:33 -03:00
ikuyo 6e0dfdac37 Added initial draft for CS:Tweaked exporter 2024-01-05 00:07:59 -03:00
duncathan ad4c5bbee6 a couple fixes 2023-10-14 14:43:23 -06:00
duncathan 3ada39e69a add py.typed 2023-10-13 22:12:24 -06:00
1986 changed files with 35352 additions and 65 deletions

View file

@ -1,6 +1,8 @@
name: Python Package
on:
workflow_dispatch:
pull_request:
push:
branches:
- '*'
@ -8,6 +10,74 @@ on:
- '*'
jobs:
mypy-required:
runs-on: 'ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Workaround for worktree config
run: git config --unset-all extensions.worktreeConfig || true
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install Python packages
run: |
python -m pip install -e .
python -m pip install mypy
- name: Mypy on required files
uses: tsuyoshicho/action-mypy@v5
with:
github_token: ${{ secrets.github_token }}
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
reporter: github-check
setup_method: nothing
target: --config-file=pyproject.toml
fail_on_error: true
install_types: false
mypy-modified:
runs-on: 'ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Workaround for worktree config
run: git config --unset-all extensions.worktreeConfig || true
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install Python packages
run: |
python -m pip install -e .
python -m pip install mypy
- name: Mypy on modified files
uses: tsuyoshicho/action-mypy@v5
with:
github_token: ${{ secrets.github_token }}
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
reporter: github-check
setup_method: nothing
level: warning
fail_on_error: false
install_types: false
build:
runs-on: ubuntu-latest
name: Wheel
@ -22,7 +92,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.9"
python-version: "3.10"
- name: Install Python packages
run: python -m pip install --upgrade build pip
@ -34,7 +104,7 @@ jobs:
run: python -m build --sdist
- name: Store the packages
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist
@ -42,11 +112,13 @@ jobs:
pypi:
runs-on: 'ubuntu-latest'
needs:
- mypy-required
- build
if: ${{ github.event_name != 'pull_request' }}
steps:
- name: Download all the dists
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/

33
.github/workflows/workflow-validate.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: Check Workflow Files
on:
push:
branches:
- main
merge_group:
pull_request:
defaults:
run:
shell: bash
jobs:
actions:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install action-validator with asdf
uses: asdf-vm/actions/install@v3
with:
tool_versions: |
action-validator 0.5.1
- name: Lint Actions
run: |
find .github/workflows -type f \( -iname \*.yaml -o -iname \*.yml \) \
| xargs -I {} action-validator --verbose {}

17
.gitignore vendored
View file

@ -1,12 +1,6 @@
data/*
notes/*
pre_edited_cs/Doukutsu\.exe\.blbkp
pre_edited_cs/Profile*
pre_edited_cs/window\.rect
*Copy/
venv/
@ -17,5 +11,12 @@ dist/
cave_story_randomizer.egg-info/
*/__pycache__
caver/version.py
**/__pycache__
pre_edited_cs/**/Doukutsu\.exe\.blbkp
pre_edited_cs/**/Profile*
pre_edited_cs/**/window\.rect
pre_edited_cs/data/version.txt
pre_edited_cs/freeware/Doukutsu_backup.exe

18
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,18 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.8.3
hooks:
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
- repo: https://github.com/henriquegemignani/jsonschema-to-typeddict
rev: v1.1.1
hooks:
- id: jsonschema-to-typeddict
files: caver/schema/schema.json
args: [ --output-path, caver/schema/types.py, --root-name, CaverData ]

View file

@ -1,20 +1,44 @@
from pathlib import Path
from typing import Callable, Optional
from uuid import UUID
from lupa import LuaRuntime
from __future__ import annotations
import json
import logging
import platform as pl
import shutil
import textwrap
import sys
import textwrap
import typing
from enum import Enum
from pathlib import Path
from uuid import UUID
import pre_edited_cs
from randovania_lupa import LuaRuntime # type: ignore
from caver.schema.validator_with_default import DefaultValidatingDraft7Validator
LuaFile = typing.Any
if typing.TYPE_CHECKING:
from collections.abc import Callable
from caver.schema import (
CaverData,
CaverdataMaps,
CaverdataOtherTsc,
EventNumber,
MapName,
)
CSVERSION = 5
class CaverException(Exception):
pass
class CSPlatform(Enum):
FREEWARE = "freeware"
TWEAKED = "tweaked"
def get_path() -> Path:
if getattr(sys, "frozen", False):
file_dir = Path(getattr(sys, "_MEIPASS"))
@ -22,56 +46,91 @@ def get_path() -> Path:
file_dir = Path(__file__).parent.parent
return file_dir.joinpath("caver")
def patch_files(patch_data: dict, output_dir: Path, progress_update: Callable[[str, float], None]):
def validate(patch_data: dict) -> None:
with Path(__file__).parent.joinpath("schema/schema.json").open() as f:
schema = json.load(f)
DefaultValidatingDraft7Validator(schema).validate(patch_data)
def patch_files(
patch_data: CaverData, output_dir: Path, platform: CSPlatform, progress_update: Callable[[str, float], None]
) -> None:
progress_update("Validating schema...", -1)
validate(typing.cast(dict, patch_data))
progress_update("Copying base files...", -1)
ensure_base_files_exist(output_dir)
ensure_base_files_exist(platform, output_dir)
total = len(patch_data["maps"].keys()) + len(patch_data["other_tsc"].keys()) + 3
lua_file = get_path().joinpath("tsc_file.lua").read_text()
TscFile = LuaRuntime().execute(lua_file)
TscFile = typing.cast(LuaFile, LuaRuntime().execute(lua_file))
for i, (mapname, mapdata) in enumerate(patch_data["maps"].items()):
progress_update(f"Patching {mapname}...", i/total)
progress_update(f"Patching {mapname}...", i / total)
patch_map(mapname, mapdata, TscFile, output_dir)
for filename, scripts in patch_data["other_tsc"].items():
i += 1
progress_update(f"Patching {filename}.tsc...", i/total)
progress_update(f"Patching {filename}.tsc...", i / total)
patch_other(filename, scripts, TscFile, output_dir)
i += 1
progress_update("Copying MyChar...", i/total)
patch_mychar(patch_data["mychar"], output_dir)
progress_update("Copying MyChar...", i / total)
patch_mychar(patch_data["mychar"], output_dir, platform is CSPlatform.TWEAKED)
i += 1
progress_update("Copying hash...", i/total)
progress_update("Copying hash...", i / total)
patch_hash(patch_data["hash"], output_dir)
i += 1
progress_update("Copying UUID...", i/total)
progress_update("Copying UUID...", i / total)
patch_uuid(patch_data["uuid"], output_dir)
def ensure_base_files_exist(output_dir: Path):
if platform == CSPlatform.TWEAKED:
if pl.system() == "Linux":
output_dir.joinpath("CSTweaked.exe").unlink()
else:
output_dir.joinpath("CSTweaked").unlink()
def ensure_base_files_exist(platform: CSPlatform, output_dir: Path) -> None:
internal_copy = pre_edited_cs.get_path()
version = output_dir.joinpath("data", "Stage", "_version.txt")
keep_existing_files = version.exists() and int(version.read_text()) >= CSVERSION
with internal_copy.joinpath("data", "version.txt").open() as version_file:
latest_version = version_file.readline()
def should_ignore(path: str, names: list[str]):
version = output_dir.joinpath("data", "version.txt")
current_version = "v0.0.0.0"
if version.exists():
with version.open() as version_file:
current_version = version_file.readline()
keep_existing_files = current_version >= latest_version
def should_ignore(path: str, names: list[str]) -> list[str]:
base = ["__init__.py", "__pycache__", "ScriptSource", "__pyinstaller"]
if keep_existing_files:
p = Path(path)
base.extend([p.joinpath(name) for name in names if p.joinpath(name).exists() and p.joinpath(name).is_file()])
base.extend(
[str(p.joinpath(name)) for name in names if p.joinpath(name).exists() and p.joinpath(name).is_file()]
)
return base
try:
shutil.copytree(internal_copy, output_dir, ignore=should_ignore, dirs_exist_ok=True)
shutil.copytree(internal_copy.joinpath(platform.value), output_dir, ignore=should_ignore, dirs_exist_ok=True)
shutil.copytree(
internal_copy.joinpath("data"), output_dir.joinpath("data"), ignore=should_ignore, dirs_exist_ok=True
)
except shutil.Error:
raise CaverException("Error copying base files. Ensure the directory is not read-only, and that Doukutsu.exe is closed")
raise CaverException(
"Error copying base files. Ensure the directory is not read-only, and that Doukutsu.exe is closed"
)
output_dir.joinpath("data", "Plaintext").mkdir(exist_ok=True)
def patch_map(mapname: str, mapdata: dict[str, dict], TscFile, output_dir: Path):
def patch_map(mapname: MapName, mapdata: CaverdataMaps, TscFile: LuaFile, output_dir: Path) -> None:
mappath = output_dir.joinpath("data", "Stage", f"{mapname}.tsc")
tsc_file = TscFile.new(TscFile, mappath.read_bytes(), logging.getLogger("caver"))
@ -82,7 +141,7 @@ def patch_map(mapname: str, mapdata: dict[str, dict], TscFile, output_dir: Path)
TscFile.placeSongAtCue(tsc_file, song["song_id"], event, song["original_id"], mapname)
for event, script in mapdata["entrances"].items():
needle = "<EVE...." # TODO: create a proper pattern
needle = "<EVE...." # TODO: create a proper pattern
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname, needle)
for event, hint in mapdata["hints"].items():
@ -93,7 +152,10 @@ def patch_map(mapname: str, mapdata: dict[str, dict], TscFile, output_dir: Path)
mappath.write_bytes(bytes(chars))
output_dir.joinpath("data", "Plaintext", f"{mapname}.txt").write_text(TscFile.getPlaintext(tsc_file))
def patch_other(filename: str, scripts: dict[str, dict[str, str]], TscFile, output_dir: Path):
def patch_other(
filename: MapName, scripts: dict[EventNumber, CaverdataOtherTsc], TscFile: LuaFile, output_dir: Path
) -> None:
filepath = output_dir.joinpath("data", f"{filename}.tsc")
tsc_file = TscFile.new(TscFile, filepath.read_bytes(), logging.getLogger("caver"))
@ -104,20 +166,30 @@ def patch_other(filename: str, scripts: dict[str, dict[str, str]], TscFile, outp
filepath.write_bytes(bytes(chars))
output_dir.joinpath("data", "Plaintext", f"{filename}.txt").write_text(TscFile.getPlaintext(tsc_file))
def patch_mychar(mychar: Optional[str], output_dir: Path):
def patch_mychar(mychar: str | None, output_dir: Path, add_upscale: bool) -> None:
if mychar is None:
return
mychar_img = Path(mychar).read_bytes()
output_dir.joinpath("data", "MyChar.bmp").write_bytes(mychar_img)
def patch_hash(hash: list[int], output_dir: Path):
if add_upscale:
mychar_name = Path(mychar).name
mychar_up_img = Path(mychar).parent.joinpath("2x", mychar_name).read_bytes()
output_dir.joinpath("data", "sprites_up", "MyChar.bmp").write_bytes(mychar_up_img)
def patch_hash(hash: list[int], output_dir: Path) -> None:
hash_strings = [f"{num:04d}" for num in hash]
hash_string = ",".join(hash_strings)
output_dir.joinpath("data", "hash.txt").write_text(hash_string)
def patch_uuid(uuid: str, output_dir: Path):
def patch_uuid(uuid: str, output_dir: Path) -> None:
uuid = f"{{{UUID(uuid)}}}"
output_dir.joinpath("data", "uuid.txt").write_text(uuid)
def wrap_msg_text(text: str, facepic: bool, *, ending: str = "<NOD", max_text_boxes: int | None = 1) -> str:
hard_limit = 35
msgbox_limit = 26 if facepic else hard_limit
@ -126,19 +198,21 @@ def wrap_msg_text(text: str, facepic: bool, *, ending: str = "<NOD", max_text_bo
lines = textwrap.wrap(text, width=msgbox_limit, max_lines=max_lines)
text = ""
for i, l in enumerate(lines):
text += l
if i < len(lines)-1:
for i, line in enumerate(lines):
text += line
if i < len(lines) - 1:
if i % 3 == 2:
text += "<NOD"
if len(l) != hard_limit:
if len(line) != hard_limit:
text += "\r\n"
text += ending
return text
def create_hint_script(text: str, facepic: bool, ending: str) -> str:
"""
A desperate attempt to generate valid <MSG text. Fills one text box (up to three lines). Attempts to wrap words elegantly.
A desperate attempt to generate valid <MSG text.
Fills one text box (up to three lines). Attempts to wrap words elegantly.
"""
return f"<PRI<MSG<TUR{wrap_msg_text(text, facepic, ending=ending)}"

0
caver/py.typed Normal file
View file

23
caver/schema/__init__.py Normal file
View file

@ -0,0 +1,23 @@
from caver.schema.types import (
CaverData,
CaverdataMaps,
CaverdataMapsHints,
CaverdataMapsMusic,
CaverdataOtherTsc,
EventNumber,
MapName,
TscScript,
TscValue,
)
__all__ = [
"CaverData",
"TscValue",
"EventNumber",
"MapName",
"TscScript",
"CaverdataMapsHints",
"CaverdataMapsMusic",
"CaverdataMaps",
"CaverdataOtherTsc",
]

195
caver/schema/schema.json Normal file
View file

@ -0,0 +1,195 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"$schema": {
"type": "string",
"format": "uri"
},
"maps": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/map_name"
},
"additionalProperties": {
"type": "object",
"properties": {
"pickups": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/event_number"
},
"additionalProperties": {
"$ref": "#/$defs/tsc_script"
},
"default": {}
},
"hints": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/event_number"
},
"additionalProperties": {
"type": "object",
"properties": {
"text": {
"type": "string"
},
"facepic": {
"$ref": "#/$defs/tsc_value",
"default": "0000"
},
"ending": {
"$ref": "#/$defs/tsc_script",
"default": "<END"
}
},
"required": [
"text",
"facepic",
"ending"
],
"additionalProperties": false
},
"default": {}
},
"music": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/event_number"
},
"additionalProperties": {
"type": "object",
"properties": {
"original_id": {
"$ref": "#/$defs/tsc_value"
},
"song_id": {
"$ref": "#/$defs/tsc_value"
}
},
"required": [
"original_id",
"song_id"
],
"additionalProperties": false
},
"default": {}
},
"entrances": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/event_number"
},
"additionalProperties": {
"$ref": "#/$defs/tsc_script"
},
"default": {}
}
},
"additionalProperties": false,
"required": [
"pickups",
"hints",
"music",
"entrances"
]
},
"default": {}
},
"other_tsc": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/map_name"
},
"additionalProperties": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/event_number"
},
"additionalProperties": {
"type": "object",
"properties": {
"needle": {
"type": "string",
"description": "Lua pattern to search for and replace within the event"
},
"script": {
"$ref": "#/$defs/tsc_script"
}
},
"required": [
"needle",
"script"
],
"additionalProperties": false
}
},
"default": {}
},
"mychar": {
"description": "A path to the mychar.bmp file to use (Optional)",
"anyOf": [
{
"type": "null"
},
{
"type": "string",
"pattern": "^.*\\.bmp$"
}
],
"default": null
},
"hash": {
"description": "An array of five item IDs to display on the title screen, within [1, 39]",
"type": "array",
"items": {
"type": "integer",
"minimum": 1,
"maximum": 39
},
"minItems": 5,
"maxItems": 5,
"default": [1,1,1,1,1]
},
"uuid": {
"description": "The UUID for the world in a multiworld session, or the empty UUID if single player.",
"type": "string",
"pattern": "^\\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\}$",
"default": "{00000000-0000-0000-0000-000000000000}"
},
"platform": {
"description": "Which supported platform to export to.",
"$comment": "Not actually used by the patcher.",
"type": "string",
"enum": [
"freeware",
"tweaked"
]
}
},
"required": [
"maps",
"other_tsc",
"mychar",
"hash",
"uuid"
],
"additionalProperties": false,
"$defs": {
"tsc_value": {
"type": "string",
"pattern": "^[ -~]{4}$"
},
"event_number": {
"$ref": "#/$defs/tsc_value",
"$comment": "Semantic alias for tsc_value"
},
"map_name": {
"type": "string"
},
"tsc_script": {
"type": "string"
}
}
}

54
caver/schema/types.py Normal file
View file

@ -0,0 +1,54 @@
# This file is generated. Manual changes will be lost
# fmt: off
# ruff: noqa
from __future__ import annotations
import typing_extensions as typ
# Definitions
TscValue: typ.TypeAlias = str
EventNumber: typ.TypeAlias = TscValue
MapName: typ.TypeAlias = str
TscScript: typ.TypeAlias = str
# Schema entries
@typ.final
class CaverdataMapsHints(typ.TypedDict):
text: str
facepic: TscValue
ending: TscScript
@typ.final
class CaverdataMapsMusic(typ.TypedDict):
original_id: TscValue
song_id: TscValue
@typ.final
class CaverdataMaps(typ.TypedDict):
pickups: dict[EventNumber, TscScript]
hints: dict[EventNumber, CaverdataMapsHints]
music: dict[EventNumber, CaverdataMapsMusic]
entrances: dict[EventNumber, TscScript]
@typ.final
class CaverdataOtherTsc(typ.TypedDict):
needle: str
script: TscScript
@typ.final
class Caverdata(typ.TypedDict):
maps: dict[MapName, CaverdataMaps]
other_tsc: dict[MapName, dict[EventNumber, CaverdataOtherTsc]]
mychar: None | str
hash: list[int]
uuid: str
platform: typ.NotRequired[str]
CaverData: typ.TypeAlias = Caverdata

View file

@ -0,0 +1,25 @@
from jsonschema import Draft7Validator, validators
def extend_with_default(validator_class):
validate_properties = validator_class.VALIDATORS["properties"]
def set_defaults(validator, properties, instance, schema):
for property, subschema in properties.items():
if "default" in subschema:
instance.setdefault(property, subschema["default"])
yield from validate_properties(
validator,
properties,
instance,
schema,
)
return validators.extend(
validator_class,
{"properties": set_defaults},
)
DefaultValidatingDraft7Validator = extend_with_default(Draft7Validator)

View file

@ -112,7 +112,7 @@ function TscFile:_getLabelPositionRange(label)
end
if labelStart == nil then
error(("%s: Could not find label: %s"):format(self.mapName, label))
error(("Could not find label: %s"):format(label))
labelStart = 1
end

View file

@ -0,0 +1,9 @@
this file isn't a real hex patch; it's a copy and paste of peri's discord message on 5 dec 2024:
---
There is an undocumented hex edit to increase the size of the Casts.bmp surface (0x411569: F0 00 -> E0 01, which I presume we just used BL's hacks/intro/surface_bitmap_sizes.xml here);
There is an undocumented hex edit to increase the TSC buffer size (0x421545: 00 50 00 -> 20 A1 07, again this was probably from the BL hack and we never wrote it down);
Randomly the byte at 0x414B24 was changed from 0x80 to 0x5F, which is the number of bytes to memset when initializing the map flag array. Not sure why this was changed, but the multiworld DLL overwrites this function anyways so it doesn't really make a difference (anymore).

View file

@ -0,0 +1,103 @@
; Reads version number from data\version.txt
; The file must start with the version string in the format shown at the bottom of this file
; Made by periwinkle
#define
gDataPath=49E220
gVersionString=48C2BC
sprintf=481010
fopen=480FFD
rb=48C28C
fread=480F55
fclose=480E1B
sscanf=4817E8
call VirtualProtect=data ff 15 84 c0 48 00
filePath=[ebp-114]
bufchk=[ebp-10]
tmp=[ebp-c]
oldProtect=[ebp-8]
fp=[ebp-4]
v1=[ebp+8]
v2=[ebp+c]
v3=[ebp+10]
v4=[ebp+14]
#enddefine
offset 410990 ; GetCompileVersion
push ebp
mov ebp, esp
sub esp, 114
mov eax, [498B20]
mov bufchk, eax
; Get path to data\version.txt file
push gDataPath
push :VersionPath ; "%s\version.txt"
lea edx, filePath
push edx
call sprintf
add esp, c
; Open file
push rb ; "rb"
lea ecx, filePath
push ecx
call fopen
add esp, 8
test eax, eax
jz :ReadVersion
mov fp, eax
; Mark gVersionString as read/write (it's normally in a read-only segment)
lea eax, oldProtect
push eax
push 4 ; PAGE_READWRITE
push 40 ; Max size of gVersionString (including null character)
push gVersionString
call VirtualProtect
test eax, eax
jz :CloseFile
; Read contents of file into gVersionString
push fp
push 3F ; count (excluding null character)
push 1 ; size
push gVersionString
call fread
add esp, 10
mov byte [eax+gVersionString], 0 ; Write null terminator
; Restore previous protection status
lea eax, tmp
push eax
push oldProtect
push 40
push gVersionString
call VirtualProtect
:CloseFile
push fp
call fclose
pop ecx
:ReadVersion
; Parse the version string
push v4
push v3
push v2
push v1
push :VersionString
push gVersionString
call sscanf
add esp, 18
mov ecx, bufchk
call 480DC1
leave
retn
:VersionPath
data 25 73 5C 76 65 72 73 69 6F 6E 2E 74 78 74 00 00 ; "%s\version.txt"
:VersionString
data 76 25 64 2E 25 64 2E 25 64 2E 25 64 00 ; "v%d.%d.%d.%d"

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
?<Ubbkb?<n€snu嘼bdenxs{bbbbnw€v?<Ubbkc?<n€snu嘼bdenxs{bbbcnw€v?<Ubbkd?<n€snu嘼bdenxs{bbbdnx~|bjdklbbkjnx~|bjddlbbkinw€v?<Ubbke?<n€snu嘼bdenxs{bbbenw€v?<Ubbkf?<n€snu嘼bdenxs{bbbfnw€v?<Ubbki?<ns€俠dgelbbdblbbbbnw€v?<Ubbkj?<nu€俠ebhlbccilbbbbns€俠ebhlbbedlbbbdnw€v?<Ubcbb?<n}w媙x~|bjeklbcbcnx~|bjbblbcbdnw坵bcbf?<Ubcbc?<n}w媙厃n唶剓<E594B6><E58993><EFBFBD>、棤```n€乿nw€v?<Ubcbd?<n{唡bbdclbcbenw坵bcbf?<Ubcbe?<nx~]bjednw坵bcbf?<Ubcbf?<n厑嘼bccns€俠cbblbbbblbbbd?<nxs乥bbbnx~_gbbhn唲sbbfhlbbkblbbcilbbbk?<Ubdbb?<n}w媙卻<E5AA99>?<nx~|bjedlbdbf?<nx~|bjdflbdbe?<nx~|bjdelbdbd?<nx~|bjdclbdbcn厃n唶<6E>?<亗w€R厇噯唚剄n媭|bbbbnu~乶媣bbbb?<n塻{bbebns€俠dgblbbcblbbbcn塻{bbcbns€俠ebblbbbclbbbd?<n塻{bbddns€俠dgclbbcblbbbcns€俠ebblbbbelbbbd?<n塻{bbedns€俠dgdlbbcblbbbc?<n塻{bbedns€俠dgelbbcblbbbc?<n塻{bbedns€俠dgflbbcblbbbcnv€俠dgb?<n塻{bbednv€俠dgc?<n塻{bbednv€俠dgd?<ns€俠dgelbbbclbbbbn塻{bbednv€俠ebb?<nu€俠ebclbccilbbbb?<ns€俠ebclbbdclbbbd?<nx~_bjdbnx~]bjdcnx~]bjddn厃n唶剆t€亜s~{唻Rvw唚u唚vR{€?<厇噯唚凴€乣Rfn€乿nw€v?<Ubdbc?<n}w媙厃n唶剆t€亜s~{唻Rvw唚u唚vR{€?<厇噯唚凴€乣Rfn€乿nw€v?<Ubdbd?<n}w媙厃n唶<6E>?<~亯w凴~{x唓n媭|bbbbnx~]bjdfnu~乶x亐bdgilbbch?<n塻{bbgb?<ns€俠dgilbbcblbbben塻{bckdns€俠dgilbbbblbbbb?<n塻{bbgbnx<6E>bbch?<nw€v?<Ubdbe?<n}w媙厃n唶<6E>?<~{x哛{匯~亯w剋vn€乿nw€v?<Ubdbf?<n}w媙厃?<w剟亜n€乿nw€v?<Ubdcb?<n}w媙卻唍x~|bjeblbdcdnx~|bjdglbdccn厃n唶<6E>?<亗w€R厇噯唚剄n媭|bbbbnx~]bjdgnu~乶塻{bbfb?<ns€俠dghlbbcblbbbcn塻{bcdjnv€俠dgh?<nw€v?<Ubdcc?<n}w媙厃n唶<6E>?<厇噯唚凴亗w€wvn€乿nw€v?<Ubdcd?<n}w媙厃n唶<6E>?<w剟亜n€乿nw€v?<Ubdfb?<n倓{nx~|bjdjlbdfcnv€俠dfbnx~|bjeblbdfenx~]bjeknx~]iecknw坵bdfe?<Ubdfc?<n倓{n厃n唶<6E>?<```qn€乿nw€v?<Ubdfd?<n倓{n厃n唶剓<E594B6><E58993><EFBFBD>牂灄朢Б`?<嫛<>晸燳<E699B8><EFBFBD>洣R灐ˉ梎``n€乿nw€v?<Ubdfe?<nw坵bbjb?<Ubdgb?<Ubdgc?<Ubdgd?<Ubdge?<Ubdgf?<Ubdgg?<n倓{n厃n唶剆R敜<52>棤Rぁ敗<E38181>n€乿?<{<7B><><EFBFBD><EFBFBD><EFBFBD>灚R枔煋櫁朻n€乿nw€v?<Ubdgh?<Ubdgi?<Ubdgj?<Ubebb?<n}w媙厃n唶刵xsubbck墬洡朢<E6B4A1>摃梌R棜q?<{R<>爾棨R洏R<E6B48F>洢R⿹<52>?<ァ煑RァうR<E38186>R敁<52>`n€乿nw€v?<Ubebc?<n}w媙x~|bjdelbebdn厃n唶刵xsubbdg啔洢R<E6B4A2>Е<EFBFBD><D095><EFBFBD><EFBFBD>灚?<煋枟R洣R殦灅⿹玆、棤`n€乿nu~剘 潵R灈潡R洣Y<E6B4A3><EFBFBD>殾?<<3C>Rァ煑<E382A1>洜檂``n€乿nw€v?<Ubebd?<n}w媙厃n唶刵xsubbck|Д<><D094>Е<EFBFBD><D095><EFBFBD><E6918C>?<<3C>Е<EFBFBD><D095>n€乿nu~剆灋R<E7818B>洢R<E6B4A2><EFBFBD>ΛR煋潡<E7858B>?<煑R<E78591>爾棨R湩ウR<E382A6>摝Y<E6919D><EFBFBD>?<殫<>`n€乿nw€v?<Ubebf?<n倓{n厃{```n€乿nw€v?<Ubebg?<n倓{n厃n唶剗牎暆棖R¨<52>n€乿nw€v?<Ubebh?<n倓{n厃n唶剢殫<E589A2>R洢R牎R<E7898E><52>玚``n€乿n{唡bbeblbebinw€v?<Ubebi?<n倓{n卻唍厃?<ny{哻beb墰灋R<E7818B><52>Д桼<D094>桼o啞㏑劇<E38F91>oqn媭|bbbbnu~乶y{哹bbb?<nu€俠ebhlbdgklbbbb?<nx~]bjegnx~]bjehnx~_bjdk?<nw€v?<Ubefb?<n}w媙v€俠efbn塻{bbcbn厑嘼bd2n塻{bbcb?<n厃n唶剫¨R殫摛Rァ煑<E382A1>洜橰櫅<E6A9B0>`n€乿nu~乶塻{bbgbns€俠dgelbbcblbbbc?<n塻{bbfjnv€俠dge?<ns€俠ebclbbbelbbbdn塻{bcdj?<ns€俠ebclbbbclbbbd?<nx~_bjddnx~]bjdenx~]bjdhnw€v?<Ubegb?<nx~|bjdglbegcnw€v?<Ubegc?<nv€俠egb?<nv€俠ebc?<nv€俠ebd?<nx~_bjddnx~_bjdhnx~]bjdi?<nu€俠fgblbccilbbbdnw€v?<Ubehb?<nx~|bjeblbehcnw€v?<Ubehc?<n}w媙v€俠ehbnu嘼bdenw€v?<Ubfbb?<Ubfbc?<Ubfbd?<Ubfcb?<Ubfgb?<n}w媙厎|bbbhlbfgcn厎]bbbhnw坵bfgd?<Ubfgc?<n卻唍w坵bfgd?<Ubfgd?<n}w媙卻<E5AA99>?<nx~|bjeilbebf?<nx~|bjdjlbebg?<n媡bbbdn塻{bbebn媣bbbdn厃nxsubbck~ 漙n€乿nu~剢殯<E589A2>洢R揜ァ灃洍<E78183><EFBFBD>?<<3C>桼ェ<E6A1BC>摃梎n€乿nu~乶xsubbbb?<nu嘼bbbns€俠dgglbbdblbbbbn塻{bbdbnx<6E>bbch?<ns€俠fgblbbbclbbbdn厃?<nxsubbdgSSSn塻{bbgbnu~乶xsubbbb?<n塻{bbebns€俠fgblbbbclbbbdn厃?<nxsubbck{<7B><>ウ洖濺摓洦桽Sn€乿nu~<7E>?<nx亐bdgjlbbchnx~]bjdjnx~_bjdfn€俠dgilbbbilbbcjlbbbb?<nu俠bfblbbcglbbebnu俠bfblbbchlbbeb?<nu€俠dgjlbcjflbbbb?<ns€俠dgjlbbcblbbben塻{bcdj?<ns€俠dgjlbbdblbbbbnx<6E>bbch?<n塻{bbdb?<ns€俠dgglbbcblbbbb?<ns€俠fgblbbeblbbbdn塻{bbfb?<nv€俠gbbnt乻bdbbnu嘼bddnt厏bbbb?<nu€俠fgblbcjblbbbdns€俠fgblbbfblbbbd?<ns€俠fcblbbdblbbbbnw€v?<Ubgbb?<nv€俠gbbnt乻bdbbnu嘼bddnt厏bbbbnw€v?<Ucbbb?<n}w媙t乻bgbb?<n媣bfbcnx~_bjdj?<ns€俠fcblbbcblbbbb?<nu€俠fgblbccilbbbf?<n塻{bbcbb?<n厃n唶刵xsubbck墬R枦朢洣qSn塻{bcbbn€乿nu~乶xsubbbb?<nx亐bfbclbbchnu€俠fbblbbhilbbbdn塻{bbgb?<n厃n唶刵xsubbdhx 灔SSn€乿nu~乶xsubbbb?<nu€俠fbdlbceklbbbbns€俠fbdlbbfblbbbbn塻{bcbb?<n厃n唶刵xsubbdc?<z棲Sn€乿nu~乶xsubbbb?<ns€俠fbblbbcelbbbdn塻{bbgb?<nu€俠fbblbbjdlbbbdn塻{bbdb?<ns€俠fbblbbdglbbbdnx<78>?<n厃z   亖亖亖亖zSSn塻{bbgbn€乿nu~<7E>?<nt乻bhbbn塻{bbeb?<ns€俠fbblbbdblbbbd?<ns€俠fbdlbbeblbbbb?<ns€俠fcblbbeblbbbb?<ns€俠fgblbbdblbbbdnv€sbcjcnv€sbcjd?<nu俠bfblbbcglbbfinu俠bfblbbchlbbfi?<n塻{bcbbnu嘼bbbnx<6E>bbch?<nx~]fbbbnx~]befcnx~]bijenx~]bjeinw僟bbchnx~_dkgbnx~]hcbjnw€v?<Uccbb?<n}w媙x~_fbbbnxs乥bbfn塻{bbgb?<nv€俠fgb?<nx~]bchb?<nx~]bjebnx~]bjdknx~_bjdi?<nx~]bjbbnx~]bjbcnx~]beidnx~]bfcc?<nx~]befbnx~]bcgknx~]bjej?<nx~_chfdnx~]chfenx~_bjek?<n{唡bbdclccbcnw坵ccbd?<Uccbc?<n€俠fcblbbbclbbbdlbbbb?<ns€俠fcblbbbblbbbb?<nw僝bbchnx~]dkgbnw坵cccb?<Uccbd?<n€俠fcblbbbclbbddlbbbb?<ns€俠fcblbbbblbbbbnw坵cccb?<Ucccb?<nu€俠ebhlbccilbbbd?<ns€俠ebhlbbedlbbbd?<ns€俠dgjlbbcblbbbcn塻{bbkhns€俠dgjlbbbclbbbb?<n塻{bbgb?<n亪bbgglbbcjn塻{bbeb?<nv€sbcjenxs{bbbfn塻{bbgbnx~]iedbnw坵cccc?<Ucccc?<nw坵bbic?<Ucdbb?<nv€sbdgkn}w媙s€俢dbblbbdblbbbd?<nx~|bjdklcdbcnw坵cdbd?<Ucdbc?<nu€俠ebhlbccilbbbbns€俠ebhlbbedlbbbdnw坵cdbd?<Ucdbd?<nx亐cdbblbbchnxs{bbbc?<n塻{bcbbnxs乥bbcn唲sbbghlcdbblbbhklbbih
?<Ubbkb?<n€snu嘼bdenxs{bbbbnw€v?<Ubbkc?<n€snu嘼bdenxs{bbbcnw€v?<Ubbkd?<n€snu嘼bdenxs{bbbdnx~|bjdklbbkjnx~|bjddlbbkinw€v?<Ubbke?<n€snu嘼bdenxs{bbbenw€v?<Ubbkf?<n€snu嘼bdenxs{bbbfnw€v?<Ubbki?<ns€俠dgelbbdblbbbbnw€v?<Ubbkj?<nu€俠ebhlbccilbbbbns€俠ebhlbbedlbbbdnw€v?<Ubcbb?<n}w媙x~|bjeklbcbcnx~|bjbblbcbdnw坵bcbf?<Ubcbc?<n}w媙厃n唶剓<E594B6><E58993><EFBFBD>、棤```n€乿nw€v?<Ubcbd?<n{唡bbdclbcbenw坵bcbf?<Ubcbe?<nx~]bjednw坵bcbf?<Ubcbf?<n厑嘼bccns€俠cbblbbbblbbbd?<nxs乥bbbnx~_gbbhn唲sbbfhlbbkblbbcilbbbk?<Ubdbb?<n}w媙卻<E5AA99>?<nx~|bjedlbdbf?<nx~|bjdflbdbe?<nx~|bjdelbdbd?<nx~|bjdclbdbcn厃n唶<6E>?<亗w€R厇噯唚剄n媭|bbbbnu~乶媣bbbb?<n塻{bbebns€俠dgblbbcblbbbcn塻{bbcbns€俠ebblbbbclbbbd?<n塻{bbddns€俠dgclbbcblbbbcns€俠ebblbbbelbbbd?<n塻{bbedns€俠dgdlbbcblbbbc?<n塻{bbedns€俠dgelbbcblbbbc?<n塻{bbedns€俠dgflbbcblbbbcnv€俠dgb?<n塻{bbednv€俠dgc?<n塻{bbednv€俠dgd?<ns€俠dgelbbbclbbbbn塻{bbednv€俠ebb?<nu€俠ebclbccilbbbb?<ns€俠ebclbbdclbbbd?<nx~_bjdbnx~]bjdcnx~]bjddn厃n唶剆t€亜s~{唻Rvw唚u唚vR{€?<厇噯唚凴€乣Rfn€乿nw€v?<Ubdbc?<n}w媙厃n唶剆t€亜s~{唻Rvw唚u唚vR{€?<厇噯唚凴€乣Rfn€乿nw€v?<Ubdbd?<n}w媙厃n唶<6E>?<~亯w凴~{x唓n媭|bbbbnx~]bjdfnu~乶x亐bdgilbbch?<n塻{bbgb?<ns€俠dgilbbcblbbben塻{bckdns€俠dgilbbbblbbbb?<n塻{bbgbnx<6E>bbch?<nw€v?<Ubdbe?<n}w媙厃n唶<6E>?<~{x哛{匯~亯w剋vn€乿nw€v?<Ubdbf?<n}w媙厃?<w剟亜n€乿nw€v?<Ubdcb?<n}w媙卻唍x~|bjeblbdcdnx~|bjdglbdccn厃n唶<6E>?<亗w€R厇噯唚剄n媭|bbbbnx~]bjdgnu~乶塻{bbfb?<ns€俠dghlbbcblbbbcn塻{bcdjnv€俠dgh?<nw€v?<Ubdcc?<n}w媙厃n唶<6E>?<厇噯唚凴亗w€wvn€乿nw€v?<Ubdcd?<n}w媙厃n唶<6E>?<w剟亜n€乿nw€v?<Ubdfb?<n倓{nx~|bjdjlbdfcnv€俠dfbnx~]iecknx~|bjeblbdfenx~]bjeknw坵bdfe?<Ubdfc?<n倓{n厃n唶<6E>?<```qn€乿nw€v?<Ubdfd?<n倓{n厃n唶剓<E594B6><E58993><EFBFBD>牂灄朢Б`?<嫛<>晸燳<E699B8><EFBFBD>洣R灐ˉ梎``n€乿nw€v?<Ubdfe?<nw坵bbjb?<Ubdgb?<Ubdgc?<Ubdgd?<Ubdge?<Ubdgf?<Ubdgg?<n倓{n厃n唶剆R敜<52>棤Rぁ敗<E38181>n€乿?<{<7B><><EFBFBD><EFBFBD><EFBFBD>灚R枔煋櫁朻n€乿nw€v?<Ubdgh?<Ubdgi?<Ubdgj?<Ubebb?<n}w媙厃n唶刵xsubbck墬洡朢<E6B4A1>摃梌R棜q?<{R<>爾棨R洏R<E6B48F>洢R⿹<52>?<ァ煑RァうR<E38186>R敁<52>`n€乿nw€v?<Ubebc?<n}w媙x~|bjdelbebdn厃n唶刵xsubbdg啔洢R<E6B4A2>Е<EFBFBD><D095><EFBFBD><EFBFBD>灚?<煋枟R洣R殦灅⿹玆、棤`n€乿nu~剘 潵R灈潡R洣Y<E6B4A3><EFBFBD>殾?<<3C>Rァ煑<E382A1>洜檂``n€乿nw€v?<Ubebd?<n}w媙厃n唶刵xsubbck|Д<><D094>Е<EFBFBD><D095><EFBFBD><E6918C>?<<3C>Е<EFBFBD><D095>n€乿nu~剆灋R<E7818B>洢R<E6B4A2><EFBFBD>ΛR煋潡<E7858B>?<煑R<E78591>爾棨R湩ウR<E382A6>摝Y<E6919D><EFBFBD>?<殫<>`n€乿nw€v?<Ubebf?<n倓{n厃{```n€乿nw€v?<Ubebg?<n倓{n厃n唶剗牎暆棖R¨<52>n€乿nw€v?<Ubebh?<n倓{n厃n唶剢殫<E589A2>R洢R牎R<E7898E><52>玚``n€乿n{唡bbeblbebinw€v?<Ubebi?<n倓{n卻唍厃?<ny{哻beb墰灋R<E7818B><52>Д桼<D094>桼o啞㏑劇<E38F91>oqn媭|bbbbnu~乶y{哹bbb?<nu€俠ebhlbdgklbbbb?<nx~]bjegnx~]bjehnx~_bjdk?<nw€v?<Ubefb?<n}w媙v€俠efbn塻{bbcbn厑嘼bd2n塻{bbcb?<n厃n唶剫¨R殫摛Rァ煑<E382A1>洜橰櫅<E6A9B0>`n€乿nu~乶塻{bbgbns€俠dgelbbcblbbbc?<n塻{bbfjnv€俠dge?<ns€俠ebclbbbelbbbdn塻{bcdj?<ns€俠ebclbbbclbbbd?<nx~_bjddnx~]bjdenx~]bjdhnw€v?<Ubegb?<nx~|bjdglbegcnw€v?<Ubegc?<nv€俠egb?<nv€俠ebc?<nv€俠ebd?<nx~_bjddnx~_bjdhnx~]bjdi?<nu€俠fgblbccilbbbdnw€v?<Ubehb?<nx~|bjeblbehcnw€v?<Ubehc?<n}w媙v€俠ehbnu嘼bdenw€v?<Ubfbb?<Ubfbc?<Ubfbd?<Ubfcb?<Ubfgb?<n}w媙厎|bbbhlbfgcn厎]bbbhnw坵bfgd?<Ubfgc?<n卻唍w坵bfgd?<Ubfgd?<n}w媙卻<E5AA99>?<nx~|bjeilbebf?<nx~|bjdjlbebg?<n媡bbbdn塻{bbebn媣bbbdn厃nxsubbck~ 漙n€乿nu~剢殯<E589A2>洢R揜ァ灃洍<E78183><EFBFBD>?<<3C>桼ェ<E6A1BC>摃梎n€乿nu~乶xsubbbb?<nu嘼bbbns€俠dgglbbdblbbbbn塻{bbdbnx<6E>bbch?<ns€俠fgblbbbclbbbdn厃?<nxsubbdgSSSn塻{bbgbnu~乶xsubbbb?<n塻{bbebns€俠fgblbbbclbbbdn厃?<nxsubbck{<7B><>ウ洖濺摓洦桽Sn€乿nu~<7E>?<nx亐bdgjlbbchnx~]bjdjnx~_bjdfn€俠dgilbbbilbbcjlbbbb?<nu俠bfblbbcglbbebnu俠bfblbbchlbbeb?<nu€俠dgjlbcjflbbbb?<ns€俠dgjlbbcblbbben塻{bcdj?<ns€俠dgjlbbdblbbbbnx<6E>bbch?<n塻{bbdb?<ns€俠dgglbbcblbbbb?<ns€俠fgblbbeblbbbdn塻{bbfb?<nv€俠gbbnt乻bdbbnu嘼bddnt厏bbbb?<nu€俠fgblbcjblbbbdns€俠fgblbbfblbbbd?<ns€俠fcblbbdblbbbbnw€v?<Ubgbb?<nv€俠gbbnt乻bdbbnu嘼bddnt厏bbbbnw€v?<Ucbbb?<n}w媙t乻bgbb?<n媣bfbcnx~_bjdj?<ns€俠fcblbbcblbbbb?<nu€俠fgblbccilbbbf?<n塻{bbcbb?<n厃n唶刵xsubbck墬R枦朢洣qSn塻{bcbbn€乿nu~乶xsubbbb?<nx亐bfbclbbchnu€俠fbblbbhilbbbdn塻{bbgb?<n厃n唶刵xsubbdhx 灔SSn€乿nu~乶xsubbbb?<nu€俠fbdlbceklbbbbns€俠fbdlbbfblbbbbn塻{bcbb?<n厃n唶刵xsubbdc?<z棲Sn€乿nu~乶xsubbbb?<ns€俠fbblbbcelbbbdn塻{bbgb?<nu€俠fbblbbjdlbbbdn塻{bbdb?<ns€俠fbblbbdglbbbdnx<78>?<n厃z   亖亖亖亖zSSn塻{bbgbn€乿nu~<7E>?<nt乻bhbbn塻{bbeb?<ns€俠fbblbbdblbbbd?<ns€俠fbdlbbeblbbbb?<ns€俠fcblbbeblbbbb?<ns€俠fgblbbdblbbbdnv€sbcjcnv€sbcjd?<nu俠bfblbbcglbbfinu俠bfblbbchlbbfi?<n塻{bcbbnu嘼bbbnx<6E>bbch?<nx~]fbbbnx~]befcnx~]bijenx~]bjeinw僟bbchnx~_dkgbnx~]hcbjnw€v?<Uccbb?<n}w媙x~_fbbbnxs乥bbfn塻{bbgb?<nv€俠fgb?<nx~]bchb?<nx~]bjebnx~]bjdknx~_bjdi?<nx~]bjbbnx~]bjbcnx~]beidnx~]bfcc?<nx~]befbnx~]bcgknx~]bjej?<nx~_chfdnx~]chfenx~_bjek?<n{唡bbdclccbcnw坵ccbd?<Uccbc?<n€俠fcblbbbclbbbdlbbbb?<ns€俠fcblbbbblbbbb?<nw僝bbchnx~]dkgbnw坵cccb?<Uccbd?<n€俠fcblbbbclbbddlbbbb?<ns€俠fcblbbbblbbbbnw坵cccb?<Ucccb?<nu€俠ebhlbccilbbbd?<ns€俠ebhlbbedlbbbd?<ns€俠dgjlbbcblbbbcn塻{bbkhns€俠dgjlbbbclbbbb?<n塻{bbgb?<n亪bbgglbbcjn塻{bbeb?<nv€sbcjenxs{bbbfn塻{bbgbnx~]iedbnw坵cccc?<Ucccc?<nw坵bbic?<Ucdbb?<nv€sbdgkn}w媙s€俢dbblbbdblbbbd?<nx~|bjdklcdbcnw坵cdbd?<Ucdbc?<nu€俠ebhlbccilbbbbns€俠ebhlbbedlbbbdnw坵cdbd?<Ucdbd?<nx亐cdbblbbchnxs{bbbc?<n塻{bcbbnxs乥bbcn唲sbbghlcdbblbbhklbbih

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
IF_llulIFx炎}x苑llltx<74><78>lllx<78>sllvlluqx♀€IF_llumIFx炎}x苑llltx<74><78>llmx<78>sllvlluqx♀€IF_llunIFx炎}x苑llltx<74><78>llnx<78>sllvlluqx♀€IF_lluoIFx炎}x苑llltx<74><78>llox<78>sllvlluqx♀€IF_llupIFx炎}x苑llltx<74><78>llpx<78>sllvlluqx♀€IF_lluqIFx煙llnpvllmrvllrrx♀€IF_lmllIFx〟富<E3809F>詰lllx錘}llqrvllulvlmlnvllqqIF_lmmlIFx〟富暑鼠lmmx}褐lmmlvllllvlllnx<6E>詰lllx錘}llqrvllulvlluuvllppIF_lnllIFx〟富殉蝕Fx<78>ltmvlnlnIFx<78>ltlvlnlmIFx縁デ、ォゥャ\洟ォゥャfjjjx葛€x<78>]x葛€x<78>IFx鴛~llllx}褐lnllvlllnvlllpx党<78>lolx鴛€llllxgmltlximlnqxgmlnrIF<縁ル、h\ィォォァ\ウ、ォcッ\攀擧。jx葛€x<78>畝ォア」、ー\オォア\ゥ・」、ー\棕\<5C>。擒jx葛€x£nluIF_lnlmIFx縁ベgmltm共\オ。擘jx葛€x<78><7F>ッー\棕「ォョ。\ー、。オ\、擲ィ。<EFBDA8>\、。ョ\ォ「「hIF<49>ッ攀\、。ョ\洌擠\ッォゥ。ー、・ェ」\・ェーォIFオォアョ\ャォ洫。ーjx葛€x£nluIF_lnlnIFx〟富縁ン、擴\ウ擶\・ーh\拿ィォイ。\ィ。ーー。ョ{x葛€x煙llnpvllmrvllrrx£nluIF_lnluIFx〟富}褐lnllvllllvlllnx♀€IF_lnnlIFx〟富чx褐lnnmvlmqlvlllnx}褐lnnmvllmlvlllnx党<78>lqlIFx炎}x苑llltx<74><78>llpx党<78>lqlx初x€褐lnnmx♀€IF_lnnmIF_lollIFx月<78><EFBFBD>sllvlllmxgnsllx暑鼠lnnx褐lollvllnmvllllx煙llnpvllmrvllrrxgsoqmx£olmIF_lolmIFx£lsr
=:S``i`=:l}~qls}<7D>``hlvqy````lv|zbg``j``ielu~t=:S``ia=:l}~qls}<7D>``hlvqy```alv|zbg``j``ielu~t=:S``ib=:l}~qls}<7D>``hlvqy```blv|zbg``j``ielu~t=:S``ic=:l}~qls}<7D>``hlvqy```clv|zbg``j``ielu~t=:S``id=:l}~qls}<7D>``hlvqy```dlv|zbg``j``ielu~t=:S``ie=:ls}<7D>``bdj``afj``fflu~t=:S``ih=:lv|zbg``j``ielu~t=:S`a``=:l{u炼vq````l<>q``efj``i`j`a`bj``ee=:S`aa`=:l{u炼<75><E782BC>`aalq~<7E>`aa`j````j```blvq````l<>q``efj``i`j``iij``dd=:S`b``=:l{u炼<75><E782BC>=:lv|za`haj`b`b=:lv|za`h`j`b`a=:l}<7D>Zs<5A><73>P<EFBFBD><50><EFBFBD>^^^l~tls|<7C>l~tls|=:l}经````lq~<7E>`b``j```bj```dl𩺰y``c`l}缆````lv|[a`h`lv|]a0belv|[a`bf=:l}<7D>娫P<E5A8AB><50>P<EFBFBD>Ν<CE9D>𦖠l~tls|<7C><><EFBFBD>𠈔P<F0A08894><EFBFBD><E4BB99><EFBFBD>P<EFBFBD><50>^l~tlu<6C>`b`i=:S`b`a=:l}<7D>lv|[a`ha<7F><E5A9B1>^l~tls|<7C>奴匕<E5A5B4><E58C95><EFBFBD>P<EFBFBD>襔P<E8A594><50><EFBFBD>P<EFBFBD><EFBFBD>䓀=:yP<79><EFBFBD>㎜𤙥<E38E9C>P<EFBFBD><50><EFBFBD><EFBFBD>𢰦<EFBFBD><F0A2B0A6>=:<3A>失P<E5A4B1><50>袿^l~tlu<6C>`b`i=:S`b`b=:l{u炼}<7D><>𪈠P<F0AA88A0>Ν膄\P𩡗<50><F0A9A197>P<EFBFBD>中佅ol~tls}<7D>``bdj``afj``fflu<6C>`b`i=:S`b`i=:l{u炼q~<7E>`b``j````j```blu~t=:S`bb`=:l{u炼x}sls~<7E>`bbaj`ae`j```blq~<7E>`bbaj``a`j```bl𩺰y``e`=:l}~qls}<7D>``hlvqy```dl𩺰y``e`l<>slt~<7E>`bbalu~t=:S`bba=:S`c``=:l<><6C>lv|zbg``j```alv|[bg``l<><6C>`bbls~<7E>`c``j``baj````ls}<7D>``bdj``afj``fflv|[gcealu<6C>`c`a=:S`c`a=:lu<6C>``gf

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
=:S``i`=:l}~qls}<7D>```lvqy````lu~t=:S``ia=:l}~qls}<7D>```lvqy```alu~t=:S``ib=:l}~qls}<7D>```lvqy```blu~t=:S``ic=:l}~qls}<7D>```lvqy```clu~t=:S``id=:l}~qls}<7D>```lvqy```dlu~t=:S`a``=:l<EFBFBD><EFBFBD>l}<7D>l<EFBFBD><6C>䰻W<E4B0BB>Pㄓ<50>顇^^l~tlu~t=:=:S`aa`=:l<><6C>lvq```c=:lv|[aecdlv|[aee`=:lv|za`dfj`aaal<61>q``h`j``icj``agj```a=:S`aaa=:lv|[aecal<61>q``h`j``icj``agj```a=:S`b`0=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD>凹硂<E587B9><E7A182>P<EFBFBD>P<EFBFBD><50>P<EFBFBD>\=:yP<79><EFBFBD><E9B1B2>P<EFBFBD><EFBFBD><E4BB99>P𩡗<50><EFBFBD>P<EFBFBD><50>^l~tls|<7C>𡼏<EFBFBD><EFBFBD>䣳P<E4A3B3>P<EFBFBD><50>P<EFBFBD>ol轮z````ls|=:lv|[a`calv|[a`cb=:lv|]abe`lv|]abg`lv|]abgalv|]abgblv|]abgclv|]abgd=:lv|]acd`lv|]acdalv|[aci`lv|[acialv|[acib=:ls}<7D>```lvq```al𩺰y`a``=:l<>q``ffj``idj``a`j```h=:S`be`=:l<><6C>l}<7D>l<EFBFBD><6C>=:<3A>𠠬<EFBFBD>Ν<E78A94>憕𤙥<E68695><F0A499A5>𣻸^^l~tlu~t
=:S``i`=:l}~qls}<7D>```lvqy````lu~t=:S``ia=:l}~qls}<7D>```lvqy```alu~t=:S``ib=:l}~qls}<7D>```lvqy```blu~t=:S``ic=:l}~qls}<7D>```lvqy```clu~t=:S``id=:l}~qls}<7D>```lvqy```dlu~t=:S`a``=:lq~<7E>`a``j````j```bl<62><6C>`aalvq```dl<64>q``g`j``idj``gij``gc=:S`aa`=:l<><6C>lvq```c=:lv|[aecdlv|[aee`=:lv|za`dfj`aaal<61>q``h`j``icj``agj```a=:S`aaa=:lv|[aecal<61>q``h`j``icj``agj0``a=:S`b``=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD>凹硂<E587B9><E7A182>P<EFBFBD>P<EFBFBD><50>P<EFBFBD>\=:yP<79><EFBFBD><E9B1B2>P<EFBFBD><EFBFBD><E4BB99>P𩡗<50><EFBFBD>P<EFBFBD><50>^l~tls|<7C>𡼏<EFBFBD><EFBFBD>䣳P<E4A3B3>P<EFBFBD><50>P<EFBFBD>ol轮z````ls|=:lv|[a`calv|[a`cb=:lv|]abe`lv|]abg`lv|]abgalv|]abgblv|]abgclv|]abgd=:lv|]acd`lv|]acdalv|[aci`lv|[acialv|[acib=:ls}<7D>```lvq```al𩺰y`a``=:l<>q``ffj``idj``a`j```h=:S`be`=:l<><6C>l}<7D>l<EFBFBD><6C>=:<3A>𠠬<EFBFBD>Ν<E78A94>憕𤙥<E68695><F0A499A5>𣻸^^l~tlu~t

View file

@ -73,7 +73,7 @@ SHUTTER OPENED<NOD<END
<KEY<MSG<TUR
ERROR<NOD<END
#0240
<PRI<FLJ0828:0241<DNP0240<FLJ0830:0243<FL+0839<FL+7319<EVE0243
<PRI<FLJ0828:0241<DNP0240<FL+7319<FLJ0830:0243<FL+0839<EVE0243
#0241
<PRI<MSG<TUR
...?<NOD<END

View file

@ -195,7 +195,7 @@ bad robots...<NOD<ITJ0044:0322<ITJ0034:0322<END
#0322
<PRI<FAC0000<MSG<TUR<GIT1034<IT-0034<CMU0000<CLR<FL+1046
Jammed it into Curly's mouth.<NOD<CLR<CLO<WAI0050<EQ-0064<WAI0050
<FL+1045<RMU<ITJ0044:0326<FLJ1020:0323<EVE0324
<FL+1045<RMU<ITJ0044:0326<FLJ1020:0323<FL+7345<EVE0324
#0323
<PRI<EQ+0064<FL+7345<EVE0324
#0324

View file

@ -13,6 +13,9 @@
#0095
<CMP0024:0016:0066<END
#0098
<FLJ2700:0095<END
#0100
<KEY<FAO0000<TRA0056:0090:0102:0055

View file

@ -259,7 +259,7 @@ Egg Corridor?<YNJ0000<FLJ0159:6011<CLO<EVE6010
#6002
<PRI<MSG<TURDo you want to go to Grasstown?<YNJ0000<CLO
<KEY<CNP0300:0111:0002<HMC<WAI0060<ANP0500:0001:0000
<WAI0100<FAO0004<TRA0006:0098:0004:0018
<WAI0100<FAO0004<TRA0006:0097:0004:0018
#6003
<PRI<MSG<TURDo you want to go to the
Sand Zone?<YNJ0000<CLO

View file

@ -11,8 +11,7 @@
<MNA<CMU0000<FAI0004<END
#0100
<PRI<MSG<TURYou're stuck...<NOD<END
<ANP0100:0000:0002<SOU0011<FAO0004<TRA0062:0094:0079:0073
<ANP0100:0000:0002<SOU0011<FAO0004<TRA0070:0094:0079:0073
#0110
<PRI<FAO0003

View file

@ -11,15 +11,18 @@
<MNA<CMU0005<FAI0004<FLJ2410:0095<END
#0095
<CMP0182:0011:0001<END
<CMP0182:0012:0001<END
#0098
#0097
<KEY<MNA<CMU0005<FL+0224
<ANP0100:0001:0000<FAI0004
<CNP0401:0112:0002<WAI0100
<ANP0100:0000:0000
<MYD0002<SMC<DNP0401<END
#0098
<FLJ2410:0095<END
#0099
<KEY<MNA<CMU0005
@ -162,7 +165,7 @@ door down...<NOD<END
#0302
<PRI<FLJ0218:0001<FL+0218
<SOU0022<CNP0302:0021:0000<FL+73-6<EVE0303
<SOU0022<CNP0302:0021:0000<FL+7306<EVE0303
#0303
<EVE0030
@ -212,7 +215,7 @@ Now what...<NOD<END
<ANP0450:0010:0000<DNP0451<DNP0452<WAI0030
<ANP0450:0020:0000<WAI0060<FOM0016<MYB0000
<WAI0200<MSG<TURIt won't STOOOOOOOOP!!<WAI0080<NOD<CMU0005
<DNP0450<FL-0523<FL+0225<END
<DNP0450<FL-0523<FL+0225<FLJ2410:0095<END
#0700
<EVE0053

View file

@ -1 +1 @@
B?XeeneB?qƒvqxŠeeejq{v~eeeeq{<7B>gifeoeenjqzƒyB?XeenfB?qƒvqxŠeeejq{v~eeefq{<7B>gifeoeenjqzƒyB?XeengB?qƒvqxŠeeejq{v~eeegq{<7B>gifeoeenjqzƒyB?XeenhB?qƒvqxŠeeejq{v~eeehq{<7B>gifeoeenjqzƒyB?XeeniB?qƒvqxŠeeejq{v~eeeiq{<7B>gifeoeenjqzƒyB?XeenjB?qx…efmgoeeffoeeefqzƒyB?XeenmB?q€zŽqƒvqxŠeeejq{<7B>`eggiB?qvƒ…efeeoeeefoeeeeq{v~eeeiB?qxƒ…eiefoeffgoeeegqŒv~efeeB?qvƒ…efeeoeeeeoeeeeB?qŽyeeegqˆxqyƒ…eiefqzƒyB?XeennB?q€zŽqƒvqxŠeeejB?qvƒ…eennoeefeoeeeeB?q{v~eeeiqŒv~eeleB?qvƒ…eennoeeeeoeeeeqŒv~eeheq{<7B>`gifeqzzeenjB?XefeeB?q€zŽqˆ|q‰Š‡y¤U®¤ªU¬£©U©¤Uœ¤U©¤Uv§©<C2A7>ª§\¨B?<3F>¤ª¨štq{<7B>begglqŽƒeeeeqx<71>„B?qxƒ…eieeoefffoeeegq}xqŒv~eekeqvƒ…efeeoeeefoeeeeB?qŒv~efeeq{v„eeeiq‰‡veeefoeennoeeejoeeemB?XefefB?q…‡~q{<7B>begglq{<7B>egfgoefegqˆ|q‰Š‡~©\¨U¡¤˜ š™cqƒ„yqzƒyB?XefegB?q…‡~qˆ„Šeeffqyƒ…efefq{v„eeeiq‰‡veeeloeenioeefjoeeemB?XefehB?q…‡~qˆ„Šeeffqyƒ…efehq{v„eeeiq‰‡veeemoeenioeeenoeeffB?XefeiB?q…‡~B?q{<7B>egfioefekB?q{<7B>lfeloefejB?qˆ|q‰Š‡~©\¨U¡¤˜ š™cqƒ„yqzƒyB?XefejB?qˆ„Šeeggqˆ|q‰Š‡q|~‰feenЍš™U©<55>šUr‡ª¨©®U€š®rcqƒ„yq|~‰eeeeqx<71>„q{<7B>`egfiqzzefekB?XefekB?q…‡~qˆ„Šeeffqyƒ…efeiq{v„eeeiq‰‡veegjoeenioeefkoeeelB?XefelB?q…‡~qˆ„Šeeffqyƒ…efelq{v„eeeiq‰‡veegkoeenioeefeoeeelB?XefemB?q…‡~qˆ„Šeeffqyƒ…efemq{v„eeeiq‰‡veegloeenioeefeoeeenB?XefenB?q…‡~B?q{<7B>egggoefffB?q{<7B>lfemoeffeB?qˆ|q‰Š‡~©U¨šš¢¨U©¤U—šU¡¤˜ š™cB?‰<>šU¬¤§™UW|ª¢WUž¨U¬§ž©©š£U¤£B?©<>šU™¤¤§cqƒ„yqzƒyB?XeffeB?qˆ„Šeeggqˆ|q‰Š‡q|~‰fefeЍš™U©<55>šUr|ª¢U€š®rcqƒ„yq~‰beefeq|~‰eeeeqx<71>„q{<7B>`egggqzzefffB?XefffB?q…‡~qˆ„Šeeffqyƒ…efenq{v„eeeiq‰‡veegmoeenioeeekoeefhB?XeffgB?q…‡~q{v„eeeiq‰‡veefmoeenioeeekoeefeB?XeffhB?q…‡~qˆ„Šeeffqyƒ…effhq{v„eeeiq‰‡veeheoeenioeeeloeeenB?XefgfB?q…‡~qˆ|q‰Š‡B?UUUUUUUUUUUUUUUˆ£©\¨U}¤ª¨šqƒ„yqzƒyB?XefghB?q…‡~qˆ|q‰Š‡B?UUUUUUUUUUUUUUUU…¤¬š§U‡¤¤¢qƒ„yqzƒyB?XefheB?q€zŽq{<7B>behgnq{<7B>begfnqŽyeeegq‰‡veeffoeigeoeegioeegnB?XegeeB?q…‡~qyƒ…egeeq{<7B>`egfeq{<7B>`lheiqzzeleeB?XegefB?qzzeeeeB?XegegB?q{<7B>giheoegeiqƒxeenioegehqyƒ…egegq{<7B>`giheq…‡~q{<7B>`lhenqzzelegB?XegehB?qˆ„Šeelgqxƒ…egegoeefjoeeegqzƒyB?XegeiB?qxƒ…egegoeeefoeeeeqzƒyB?XegejB?qzzeeeeB?XegelB?q…‡~qˆ|q‰Š‡~U®¤ª\§šUœ¤ž£œU¤£U<55>š™aB?¬©˜<C2A9>U¤ª©U¤§U©<55>¤¨šU…¤¬š§B?x§ž©©š§¨cqƒ„yqx<71>‡q‰Š‡Œ<E280A1>š£U©<55>š®U¡£™U¤£U®¤ªaUž©U<C2A9>ª§©¨cqƒ„yqzƒyB?XegfeB?q…‡~qˆ|q‰Š‡‰<E280A1>šU¢¤©¤§—ž šU€¯ª¢¨U™§ž«ž£œcB?~©\¨U£¤©U¡¤¤ ž£œU¨¤U<C2A4>¤©U£®¢¤§šcqƒ„yqzƒyB?XeggeB?q~‰eefhoeg5eB?q{<7B>eggfoegieB?q{<7B>eimioeghnB?q{<7B>egfjoeghiB?q…‡~qˆ|q‰Š‡~©U¬¤£\©U¤¥š£cccqƒ„yqx<71>„B?qxƒ…egheoefekoeeeeqŽyeeegqzƒyB?XegheB?q{<7B>`egfkqyƒ…egheq{<7B>`lhelqzzemeeB?XeghiB?q…‡~qˆ|q‰Š‡‰<E280A1>š§š\¨U£¤U š®<C5A1>¤¡šcB?‰<>šU™¤¤§U¢ª¨©U—šU§ª¨©š™U¨<55>ª©cqƒ„yqzƒyB?XeghjB?q{<7B>egfjoeghkB?q…‡~qˆ|q‰Š‡~<55>š§š\¨U£¤U š®<C5A1>¤¡šaU©<55>š£B?¬š\¡¡UŸª¨©U<C2A9>«šU©¤U—§š <55>šB?™¤¤§U™¤¬£cccqƒ„yqzƒyB?XeghkB?q…‡~q{<7B>egghoeeefq{<7B>lfeloeghlB?qˆ|q‰Š‡~©\¨U¡¤˜ š™cqƒ„yB?q|~‰feen<65>¤¤ ¨U¡ž šUUr‡ª¨©®U€š®rU¬¤ª¡™Už©cqŒv~eegjqƒ„yqzƒyB?XeghlB?q…‡~q{<7B>`egghB?qˆ„Šeeggqxƒ…eghkoeegfoeeeeq{<7B>`lhemqzzemefB?XeghnB?q…‡~qˆ|q‰Š‡‡ª¨©š™U¨<55>ª©aU¨¢šU¨U¡¬®¨cccqƒ„yqx<71>„B?qxƒ…egheoefekoeeeeqŽyeeegqzƒyB?XegieB?q…‡~qˆ|q‰Š‡‡ª¨©š™U¨<55>ª©aU¨¢šU¨U¡¬®¨cccqƒ„yqzƒyB?XegjeB?q…‡~q{<7B>`ejgfq{<7B>`ejggq~‰beefhB?qˆ|q‰Š‡q|~‰fefhˆš©U©<55>šUrz­¥¡¤¨ž«šrcqŒv~eegjqƒ„yqx<71>„B?q†Šveeheqˆ„ŠeeiiB?q{v„eeeiq{<7B>`ejgeq{<7B>bejggq{<7B>`ejghq{<7B>`ejgjq{<7B>`eggkq{<7B>`egglq{<7B>`gikeq‰‡veeekoekeeoegfloeefkB?XehegB?q…‡~q{<7B>egfmoeeefq{<7B>`egfmB?qˆ„Šeeggqxƒ…ehegoeegfoeeeeq{<7B>`lhbkqzzehehB?XehehB?qzzeeheB?XehejB?q…‡~qyƒ…ehejqˆ„Šeeggq{<7B>`lhejqzzelefB?XeieeB?XeiefB?XeijeB?q…‡~qˆ|q‰Š‡vU¢¤©¤§—ž šaU¢®—štqƒ„yqzƒyB?XeijfB?XeijgB?XejeeB?q…‡~B?q{<7B>lfegoejehB?q{<7B>egffoejefB?q{<7B>`egffB?qˆ|q‰Š‡ccc~\¢U¡¤˜ š™U¤ª©U¤U¢®U¤¬£U<C2A3>¤ª¨šcqƒ„yqzƒyB?XejefB?q…‡~qˆ|q‰Š‡Œž©<C5BE>U¢®U š®Uœ¤£šaU~\¢U¡¤˜ š™B?¤ª©cccB?ƒ¤¬U¬<55>©cccqƒ„yqzƒyB?XejegB?q{<7B>lfegoejehqzƒyB?XejehB?q€zŽq{<7B>`egfgqeqŽyeeeeqŒv~eeheB?q~‰beeehq€zŽqvƒ…ejeeoeeehoeeeeqŒv~eflkqvƒ…ejeeoeeeeoeeegB?qˆ„Šeeffqxƒ…efefoeeeeoeeeeqŒv~eefeB?qvƒ…ejeeoeeejoeeegqŒv~eefeqyƒ…ejeeB?qˆ„Šeeffqxƒ…efefoeefmoeeeeqyƒ…ejegqˆ„ŠeeghqzƒyB?XekeeB?q€zŽq{<7B>`egfnqxŠeeeeq{v~eeeiqŽyeeegB?qvƒ…eijgoeeeeoeeeeqŒv~eefeB?qŒv~eefeqvƒ…eijfoeeeeoeeegqŒv~eefeqvƒ…eijgoeeeeoeeegq{„ƒeijeoeefkqŒv~eejeB?qvƒ…eijfoeeehoeeegqŒv~eeieB?qvƒ…eijgoeeehoeeegqŒv~eeieB?qvƒ…eijfoeeejoeeeeqŒv~eehkB?qvƒ…eijgoeeeeoeeeeqŒv~eejeB?qvƒ…eijfoeeeeoeeegB?qvƒ…eijfoeeejoeeeeB?qvƒ…eijgoeeejoeeeeqŒv~eegeB?qvƒ…eijeoeefeoeeeeqyƒ…eijfqyƒ…eijgqŒv~eeheB?qvƒ…eijeoeegeoeeeeqŒv~eekeq{„eefkqŽweeeeB?qŒv~egeeqˆ|q‰Š‡~©U¬¤£\©Uˆ‰„„„„„„„„…VVqŒv~eemeqƒ„yqxŠeeejB?qyƒ…eijeq{<7B>bejghq{<7B>`eggjqzƒyB?XeleeB?qzzeejhB?XelefB?qzzeefiB?XelegB?qzzeejmB?XemeeB?qzzeejnB?XemefB?qzzeekeB?XfgeeB?q€zŽqvƒ…fgeeoeegeoeeegB?q{„ƒfgeeoeefkq{v~eeefB?qŒv~efeeq{v„eeefq‰‡veefeofgeeoeejeoeehi
=:S``i`=:l}~qls}<7D>``elvqy````lv|zbda`j``ielu~t=:S``ia=:l}~qls}<7D>``elvqy```alv|zbda`j``ielu~t=:S``ib=:l}~qls}<7D>``elvqy```blv|zbda`j``ielu~t=:S``ic=:l}~qls}<7D>``elvqy```clv|zbda`j``ielu~t=:S``id=:l}~qls}<7D>``elvqy```dlv|zbda`j``ielu~t=:S``ie=:ls}<7D>`ahbj``abj```alu~t=:S``ig=:l{u炼}~qls}<7D>``elv|[`bbd=:lq~<7E>`a``j```aj````lvqy```d=:ls~<7E>`d`aj`aabj```bl𩺰y`a``=:lq~<7E>`a``j````j````=:l}缆```bl<62>slt~<7E>`d`alu~t=:S``ih=:lv|zbda`j``ielu~t=:S``ii=:l{u炼}~qls}<7D>``e=:lq~<7E>``iij``a`j````=:lvqy```dl𩺰y``g`=:lq~<7E>``iij````j````l𩺰y``c`lv|[bda`lu<6C>``ie=:S`a``=:l{u炼}<7D>l<EFBFBD><6C>𡼏<EFBFBD><EFBFBD>䣳P<E4A3B3>P<EFBFBD>P<EFBFBD>Pq═坾㏄<E59DBE>=:<3A>奴𦶧lv|]`bbgl轮z````ls|=:ls~<7E>`d``j`aaaj```blx}sl𩺰y``f`lq~<7E>`a``j```aj````=:l𩺰y`a``lvq```dl<64>q```aj``iij```ej```h=:S`a`a=:l<><6C>lv|]`bbglv|z`babj`a`bl}<7D>l<EFBFBD><6C>Ν<E4B88A><CE9D><EFBFBD>^l~tlu~t=:S`a`b=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`alvq```dl<64>q```gj``idj``aej```h=:S`a`c=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`clvq```dl<64>q```hj``idj```ij``aa=:S`a`d=:l<><6C>=:lv|z`badj`a`f=:lv|zga`gj`a`e=:l}<7D>l<EFBFBD><6C>Ν<E4B88A><CE9D><EFBFBD>^l~tlu~t=:S`a`e=:l<><6C>`bbl}<7D>l<EFBFBD><6C>wy<77>``i<><69>P<EFBFBD>𠠬m<F0A0A0AC>ㄓ周{襔m^l~tlwy<77>```ls|lv|[`badlu<6C>`a`f=:S`a`f=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`dlvq```dl<64>q``bej``idj``afj```g=:S`a`g=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`glvq```dl<64>q``bfj``idj``a`j```g=:S`a`h=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`hlvq```dl<64>q``bgj``idj``a`j```i=:S`a`i=:l<><6C>=:lv|z`bbbj`aaa=:lv|zga`hj`aa`=:l}<7D>l<EFBFBD><6C><EFBFBD><E58C95>Ν<EFBFBD>P<EFBFBD>P<EFBFBD><50><EFBFBD>^=:<3A>𠠬<EFBFBD><F0A0A0AC>PRw<52>RP腼P坎膄<E59D8E><EFBFBD>=:<3A>𠠬<EFBFBD>叚^l~tlu~t=:S`aa`=:l<><6C>`bbl}<7D>l<EFBFBD><6C>wy<77>`a`<60><>P<EFBFBD>𠠬mw<6D>P{襔m^l~tly<6C>``a`lwy<77>```ls|lv|[`bbblu<6C>`aaa=:S`aaa=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`a`ilvq```dl<64>q``bhj``idj```fj``ac=:S`aab=:l<><6C>lvq```dl<64>q``ahj``idj```fj``a`=:S`aac=:l<><6C>l<EFBFBD><6C>`aalt~<7E>`aaclvq```dl<64>q``c`j``idj```gj```i=:S`aba=:l<><6C>l}<7D>l<EFBFBD><6C>=:PPPPPPPPPPPPPPP<50>䣳𥜥Νx䰻<78>l~tlu~t=:S`abc=:l<><6C>l}<7D>l<EFBFBD><6C>=:PPPPPPPPPPPPPPPP<50>榀佅P<E4BD85><50>l~tlu~t=:S`ac`=:l{u炼v|]`cbilv|]`bail}缆```bl<62>q``aaj`db`j``bdj``bi=:S`b``=:l<><6C>lt~<7E>`b``lv|[`ba`lv|[gc`dlu<6C>`g``=:S`b`a=:lu<6C>````=:S`b`b=:lv|zbdc`j`b`dl~sz``idj`b`clt~<7E>`b`blv|[bdc`l<><6C>lv|[gc`ilu<6C>`g`b=:S`b`c=:l<><6C>`gbls~<7E>`b`bj``aej```blu~t=:S`b`d=:ls~<7E>`b`bj```aj````lu~t=:S`b`e=:lu<6C>````=:S`b`g=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD><EFBFBD>P<EFBFBD><50>𢰦<EFBFBD>P<EFBFBD><50>𠗫=:<3A><>婱䰻匕<E4B0BB><EFBFBD>鰊𠠬<E9B08A>榀佅=:s<>中佅γl~tls|<7C><><EFBFBD><EFBFBD><EFBFBD>襔P<E8A594><50>P<EFBFBD>P<EFBFBD>功P膄P坾═γl~tlu~t=:S`ba`=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD>P<EFBFBD><50><EFBFBD><EFBFBD>𠠬{麐<>𩡗<EFBFBD>Ν𤩎膓<F0A4A98E>璴=:y上Ν<E4B88A><EFBFBD><E58C95><EFBFBD>𢰦<EFBFBD>P<EFBFBD><EFBFBD><E58C95>叚𦖠l~tlu~t=:S`bb`=:ly<6C>0`acj`be`=:lv|z`bbaj`bd`=:lv|z`dhdj`bci=:lv|z`baej`bcd=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD>唞匕<E5949E><E58C95>^^^l~tls|=:ls~<7E>`bc`j`a`fj````l}缆```blu~t=:S`bc`=:lv|[`baflt~<7E>`bc`lv|[gc`glu<6C>`h``=:S`bcd=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD><EFBFBD>WΝ<57>P<EFBFBD><50><EFBFBD>𦖠=:<3A>𠠬<EFBFBD>叚P䔉ㄓP<E38493>P╞ㄓ<E2959E>P<EFBFBD>奶^l~tlu~t=:S`bce=:lv|z`baej`bcf=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD>佅驣Ν<E9A9A3>P<EFBFBD><50><EFBFBD>𦖭P<F0A696AD><50>=:<3A>W<EFBFBD>P鷀ㄓP<E38493><50>P<EFBFBD>P儍<50>𢏺<EFBFBD><F0A28FBA>=:<3A>叚P<E58F9A><50>^^^l~tlu~t=:S`bcf=:l<><6C>lv|z`bbcj```alv|zga`gj`bcg=:l}<7D>l<EFBFBD><6C>Ν<E4B88A><CE9D><EFBFBD>^l~t=:lwy<77>``i|<7C>𧙗P<F0A79997><50>P𩡗m<F0A9A197>ㄓ周{襔mP<6D><50><EFBFBD>乞l𩺰y``bel~tlu~t=:S`bcg=:l<><6C>lv|[`bbc=:l<><6C>`bbls~<7E>`bcfj``baj````lv|[gc`hlu<6C>`h`a=:S`bci=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD><EFBFBD>奶\P<><50>P𪆓P<F0AA8693><50>岡^^^l~tls|=:ls~<7E>`bc`j`a`fj````l}缆```blu~t=:S`bd`=:l<><6C>l}<7D>l<EFBFBD><6C><EFBFBD><EFBFBD>奶\P<><50>P𪆓P<F0AA8693><50>岡^^^l~tlu~t=:S`be`=:l<><6C>lv|[`ebalv|[`ebbly<6C>``ac=:l}<7D>l<EFBFBD><6C>wy<77>`ac<61><EFBFBD>𠠬mu<6D><75><EFBFBD><EFBFBD>m^l𩺰y``bel~tls|=:l<>q``c`l<><6C>`dd=:lvq```dlv|[`eb`lv|]`ebblv|[`ebclv|[`ebelv|[`bbflv|[`bbglv|[bdf`l<>q```fj`f``j`bagj``af=:S`c`b=:l<><6C>lv|z`bahj```alv|[`bah=:l<><6C>`bbls~<7E>`c`bj``baj````lv|[gc`flu<6C>`c`c=:S`c`c=:lu<6C>``c`=:S`c`e=:l<><6C>lt~<7E>`c`el<65><6C>`bblv|[gc`elu<6C>`g`a=:S`d``=:S`d`a=:S`de`=:l<><6C>l}<7D>l<EFBFBD><6C>P<EFBFBD><50><EFBFBD><EFBFBD>𦖭P<F0A696AD><50>𦶧l~tlu~t=:S`dea=:S`deb=:S`e``=:l<><6C>=:lv|zga`bj`e`c=:lv|z`baaj`e`a=:lv|[`baa=:l}<7D>l<EFBFBD><6C>^^yW𨧧<57><F0A8A7A7><EFBFBD>P䰻匕<E4B0BB>P仪P榀鱲<E6A680>奴𦖠l~tlu~t=:S`e`a=:l<><6C>l}<7D>l<EFBFBD><6C>膄婱仪P<E4BBAA><EFBFBD><E591A8>\PyW𨧧<57><F0A8A7A7><EFBFBD>=:䰻乞^^=:~榀P<E6A680>𪈠^^^l~tlu~t=:S`e`b=:lv|zga`bj`e`clu~t=:S`e`c=:l{u炼v|[`babl}}`l}缆````l𩺰y``c`=:ly<6C>```cl{u炼q~<7E>`e``j```cj````l𩺰y`agflq~<7E>`e``j````j```b=:l<><6C>`aals~<7E>`a`aj````j````l𩺰y``a`=:lq~<7E>`e``j```ej```bl𩺰y``a`lt~<7E>`e``=:l<><6C>`aals~<7E>`a`aj``ahj````lt~<7E>`e`bl<62><6C>`bclu~t=:S`f``=:l{u炼v|[`bails}<7D>```lvqy```dl}缆```b=:lq~<7E>`debj````j````l𩺰y``a`=:l𩺰y``a`lq~<7E>`deaj````j```bl𩺰y``a`lq~<7E>`debj````j```blv~`de`j``afl𩺰y``e`=:lq~<7E>`deaj```cj```bl𩺰y``d`=:lq~<7E>`debj```cj```bl𩺰y``d`=:lq~<7E>`deaj```ej````l𩺰y``cf=:lq~<7E>`debj````j````l𩺰y``e`=:lq~<7E>`deaj````j```b=:lq~<7E>`deaj```ej````=:lq~<7E>`debj```ej````l𩺰y``b`=:lq~<7E>`de`j``a`j````lt~<7E>`dealt~<7E>`debl𩺰y``c`=:lq~<7E>`de`j``b`j````l𩺰y``f`lv}``afl}经````=:l𩺰y`b``l}<7D>l<EFBFBD><6C><EFBFBD>唞匕<E5949E><7F>QQl𩺰y``h`l~tls}<7D>``e=:lt~<7E>`de`lv|]`ebclv|[`bbelv|zbda`j``ielu~t=:S`g``=:lu<6C>``ec=:S`g`a=:lu<6C>``ad=:S`g`b=:lu<6C>``eh=:S`h``=:lu<6C>``ei=:S`h`a=:lu<6C>``f`=:Sab``=:l{u炼q~<7E>ab``j``b`j```b=:lv~ab``j``aflvqy```a=:l𩺰y`a``lvq```al<61>q``a`jab``j``e`j``cd

Binary file not shown.

Binary file not shown.

View file

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

View file

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

View file

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View file

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 134 B

View file

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

View file

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 638 B

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Some files were not shown because too many files have changed in this diff Show more