Compare commits

..

No commits in common. "master" and "v2.0" have entirely different histories.
master ... v2.0

2622 changed files with 18815 additions and 46681 deletions

View file

@ -1,32 +0,0 @@
name: "MALCO's Daily Challenge"
on:
schedule:
- cron: '53 15 * * *' # 9:53 AM, UTC-6
workflow_dispatch:
jobs:
Build:
runs-on: '${{ matrix.os }}'
strategy:
matrix:
os:
- ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 'stable'
- name: Install dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo add-apt-repository -y ppa:bartbes/love-stable
sudo apt-get -q update
sudo apt-get install -y xvfb love
- name: Generate Daily
env:
WEBHOOK: ${{ secrets.WEBHOOK }}
run: |
cd $GITHUB_WORKSPACE
sudo xvfb-run -a --server-args="-screen 0 1024x768x24" love src --daily
cat daily.txt
curl -H "Content-Type: application/json" -X POST -d @daily.txt "$WEBHOOK"

View file

@ -1,137 +0,0 @@
name: Python Package
on:
workflow_dispatch:
pull_request:
push:
branches:
- '*'
tags:
- '*'
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
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: 'recursive'
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.10"
- name: Install Python packages
run: python -m pip install --upgrade build pip
- name: build wheel
run: python -m build --wheel
- name: build sdist
run: python -m build --sdist
- name: Store the packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist
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@v4
with:
name: python-package-distributions
path: dist/
- name: Publish 📦 to TestPyPI
if: ${{ github.ref == 'refs/heads/patcher' }}
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.testpypi_password }}
repository_url: https://test.pypi.org/legacy/
- name: Publish 📦 to PyPI
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.pypi_password }}

View file

@ -1,33 +0,0 @@
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 {}

25
.gitignore vendored
View file

@ -1,22 +1,11 @@
data/*
notes/*
pre-edited-cs/Doukutsu\.exe\.blbkp
pre-edited-cs/Profile\.dat
pre-edited-cs/window\.rect
pre-edited-cs/Profile\.dat\.bkp
*Copy/
venv/
build/
dist/
cave_story_randomizer.egg-info/
**/__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

23
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,23 @@
# image: shru/arch-love-release:heavy
image: asmfreak/love-release:latest
variables:
ITCHIO_USER: shru
ITCHIO_GAME: cave-story-randomizer
CHANNEL: $CI_COMMIT_REF_NAME
stages:
- build-release
build-and-release:
stage: build-release
when: manual
script:
# I - Build
- cd src
- love-release -W
# II - Release to itch.io
- cd releases
- FILE=$(ls *-win32.zip) ;
zip -d "$FILE" "*/lovec.exe" "*/changes.txt" "*/readme.txt" "*.ico" ;
butler push "$FILE" "$ITCHIO_USER/$ITCHIO_GAME:win32-$CHANNEL"

View file

@ -1,18 +0,0 @@
# 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 ]

48
.travis.yml Normal file
View file

@ -0,0 +1,48 @@
language: python
os: linux
dist: xenial
addons:
apt:
update: true
packages:
- libzip-dev
- xvfb
services:
- xvfb
before_install:
- |
pip install hererocks
hererocks env --luarocks 3.0 --lua latest
export 'PATH='"$TRAVIS_BUILD_DIR"'/env/bin'":$PATH"
install:
- |
sudo add-apt-repository -y ppa:bartbes/love-stable
sudo apt-get -q update
sudo apt-get -y install love
luarocks install --server="http://luarocks.org/dev" lua-zip
luarocks install love-release
script:
- bash daily.sh
env:
global:
- secure: DU2Mq4FPbOidv0Go4b+2r5Vy7v0bbQo40ZZPkiwm/6nAJYkwySwVn2DyZGwh/kV4o6ZG0IgtLxPvHiF8lVZptbtkHJTt/GeokwwvsfpHJntPC9jyvXklFkkln9h2AgWrhTmFf+EYE4Mlm7FAjsr/9ZZHCuGn7wDCOBk3g4Zy7eAyKGqpYMN3296eUiZPXWtOAexmbavFI07pmu4ZyJ8K6HMmjd8YSAQpui3zJn/hMTupQm+o5s/ehZ72QnUyjRWdKvLlJCzORrajJxgYXQqLdjXVMcq4kuR4pDRnLdW9XBlAWiHOvj7wlVOUyBq2ZyhkTTNEYiQp+9UsIua1gG0hdLiOGH2ODtrb6NvQIRUfs5jE6xHmw3hQCfIe9itT+SbVQmuuTovM/MQTS/vH7k+AHtnJCGykMjAD6evNi1EkOG5oxrL7xEGPz7lzyVISoz0O4YmMWGF0qIzb68R11+Eo1URFrEUDxZc7F2kMoeAbnTxfiGABrMXrgIN7ReJhfD1z4ik6KwKBFw9AwJfldyb5w0QgqFAkkihqKGp5VbTMR6LeSN0Tq/Ic3QRvLHYt43+eoRXS4d2lvSo/0Nf7FftQPurbLI6c/r9nckwOZmjFicwYJ0Ulrbd46og74FUQZFSMcrVsiXo1PG2yTwu9bUvTBUHWdWh0o2xPpfAHbA05++c=
before_deploy:
- |
cd src; love-release -M; cd -
mv pre-edited-cs "src/releases/Cave Story"
cd src/releases
zip -9 -qur CaveStoryRandomizer-macos.zip "Cave Story"
zip -9 -qr CaveStoryRandomizer-linux.zip "Cave Story" CaveStoryRandomizer.love
cd -
# don't forget to create the windows releases!
deploy:
provider: releases
token:
secure: bMinTly2BOZCNQw625Fz744hvVQlnwZiC6pQZZx1f5evs0gi4TXbqqft5UN3orGgRiNnVnbf2qYC7PnS1LzynHUimdVk8iqfRKz4ADuWXyf9/i1gojzzSAI87lxbGaHxzqjZLtzf1zRonPlY1oj9X3a1eAle6EEAn/Utnm/jqZPhTYm8cMowLWqcVTcDOw1lhBpgsVYdej1wCaq7r2KBDvrqWZCdt8pJ2lcaShJEqmBONDvu9KO+gbNXwmhBAz4bG0DTVFhO459ZNjfNz749eiU7KhbxvFgz7O+j8HEdhlXznYgmzveUmVmhOSe3z037YwCNv+2ar0FITGkmTpgog0z2XuxDMb28Eakoc0uzaowwB68JRfEeRpBGidhSGraZ5DnHOS3QdDaEQ4jImv97DagiVoqcKm3JDGhGuvbI4dfPsXHKMncJC8cqf86NwSg63boabcoUTwzVLZdd4tbiOBqYPBgEtEz4uFgKvkrrzE0DoP1Efi1aZqcnOW6xckHbC261rxB5QG8WGcb1tDnmQgbhbEEguPHuzKBWP6ktpjpFdeS3Wbqb0UMaXQXMCcaMpJfCLNsLxQ6iHOh+XQhJREDPTuXm4F1m0BzSjBvQpWQ4tpO+kF1KiJ4wiwzn9jTfJxhgMgxEoY75dtH+E0K2jXLRezychR22V+7R9ifNLns=
file:
- src/releases/*.zip
file_glob: true
draft: true
skip_cleanup: true
on:
tags: true

View file

@ -1,8 +0,0 @@
{
"setup": {
"looseChecking": {
"events": true,
"arguments": true
}
}
}

BIN
CaveStoryRandomizer.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View file

@ -1,3 +1,52 @@
# Cave Story Randomizer [Open Mode]
A patcher for randomizing Cave Story. If you want to play, check out [Randovania](https://github.com/randovania/randovania)!
The Cave Story Randomizer shuffles the location of every item in Cave Story, creating a new experience each time you play! The randomizer has logic in place to ensure that you can always reach every item and finish the game. Get started by heading to the [releases page](https://github.com/cave-story-randomizer/cave-story-randomizer/releases) and downloading the most recent version! If you find yourself stuck, wanting to talk about the hilarious location you found the panties in, or just plain enjoying the game please consider joining our [official Discord server](https://discord.gg/7zUdPEn) and hanging out!
## Main differences
Note that there are a few key differences from the vanilla game in order to improve the playing experience:
- All 5 teleporter locations in Arthur's House are active from the beginning of the game
- All other teleporters from the vanilla game are active and linked to one another at all times
- A teleporter between Sand Zone (near the Storehouse) and Labyrinth I has been placed and can be activated in one of two ways:
1. Defeating Toroko+
2. Using the teleporter from the Labyrinth I side
- Most cutscenes have been abridged or skipped entirely
- Jellyfish Juice can be used an infinite number of times
- You can carry as many as 5 puppies at once: Jenka will only accept them once you've collected all 5
- By the way, all 5 puppies will be located somewhere in the Sand Zone
- Certain items that are received from NPCs have been placed in chests:
- Labyrinth B (Fallen Booster)
- Labyrinth Shop
- One requiring the Machine Gun to open
- One requiring the Fireball to open
- One requiring the Spur to open
- Jail no. 1
- Storage? (Ma Pignon)
- This chest requires saving Curly in the Waterway to open
- If you don't have Curly's Air Tank after defeating the Core, the water will not rise and you may leave without dying
- Curly cannot be left behind permanently in the Core; the shutter will never close once the boss has been defeated
- The jump in the Waterway to save Curly has been made much easier
- Ironhead will always give you his item on defeat (but there's still a special surprise if you defeat him without taking damage!)
- Kazuma will only open the door between Egg no. 0 and the Outer Wall if you save him in Grasstown
- Kazuma's door can be blown down from both the outside and the inside
- Entering the Throne Room to complete the game requires doing three things:
1. Saving Sue in the Egg Corridor
2. Obtaining the Booster 2.0
3. Obtaining the Iron Bond
## Help me!
If you find yourself stuck, here are a few common pitfalls:
- Remember that the Jellyfish Juice can quench more than one fireplace
- The Graveyard can only be accessed if you obtain the Silver Locket and see Toroko get kidnapped
- The Hermit Gunsmith will wake up and give you an item if you defeat the Core and show him his gun
- The western side of the Labyrinth can be accessed without flight if you defeat Toroko+
- The Plantation can be accessed without the Teleporter Room Key if you save Kazuma and teleport in or climb the Outer Wall
- The Waterway can be accessed without the Cure-All by using the teleporter in the Labyrinth Shop
- There may be a required item in the Last Cave (Hidden) as a reward for defeating the Red Demon
If you're still stuck, join our [official Discord server](https://discord.gg/7zUdPEn) and ask for help in there!
## Credits
- Original Cave Story Randomizer by shru: https://shru.itch.io/cave-story-randomizer
- Font: https://datagoblin.itch.io/monogram
- Icon: Bubbler (@Ethan#6397)

View file

@ -1,18 +0,0 @@
import os
# Functions
# =========
#
# .. _get_hook_dirs:
#
# get_hook_dirs
# -------------
#
# Tell PyInstaller where to find hooks provided by this distribution;
# this is referenced by the :ref:`hook registration <hook_registration>`.
# This function returns a list containing only the path to this
# directory, which is the location of these hooks.
def get_hook_dirs():
return [os.path.dirname(__file__)]

View file

@ -1,5 +0,0 @@
from PyInstaller.utils.hooks import collect_data_files
# https://pyinstaller.readthedocs.io/en/stable/hooks.html#provide-hooks-with-package
datas = collect_data_files('caver', excludes=['__pyinstaller'])

View file

@ -1,5 +0,0 @@
from PyInstaller.utils.hooks import collect_data_files
# https://pyinstaller.readthedocs.io/en/stable/hooks.html#provide-hooks-with-package
datas = collect_data_files('pre_edited_cs', excludes=['__pyinstaller'])

View file

View file

@ -1,218 +0,0 @@
from __future__ import annotations
import json
import logging
import platform as pl
import shutil
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,
)
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"))
else:
file_dir = Path(__file__).parent.parent
return file_dir.joinpath("caver")
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(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 = typing.cast(LuaFile, LuaRuntime().execute(lua_file))
for i, (mapname, mapdata) in enumerate(patch_data["maps"].items()):
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)
patch_other(filename, scripts, TscFile, output_dir)
i += 1
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)
patch_hash(patch_data["hash"], output_dir)
i += 1
progress_update("Copying UUID...", i / total)
patch_uuid(patch_data["uuid"], output_dir)
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()
with internal_copy.joinpath("data", "version.txt").open() as version_file:
latest_version = version_file.readline()
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(
[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.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"
)
output_dir.joinpath("data", "Plaintext").mkdir(exist_ok=True)
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"))
for event, script in mapdata["pickups"].items():
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname)
for event, song in mapdata["music"].items():
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
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname, needle)
for event, hint in mapdata["hints"].items():
script = create_hint_script(hint["text"], hint.get("facepic", "0000") != "0000", hint.get("ending", "<END"))
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname)
chars = TscFile.getText(tsc_file).values()
mappath.write_bytes(bytes(chars))
output_dir.joinpath("data", "Plaintext", f"{mapname}.txt").write_text(TscFile.getPlaintext(tsc_file))
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"))
for event, script in scripts.items():
TscFile.placeScriptAtEvent(tsc_file, script["script"], event, filename, script.get("needle", "<EVE...."))
chars = TscFile.getText(tsc_file).values()
filepath.write_bytes(bytes(chars))
output_dir.joinpath("data", "Plaintext", f"{filename}.txt").write_text(TscFile.getPlaintext(tsc_file))
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)
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) -> 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
max_lines = max_text_boxes * 3 if max_text_boxes is not None else None
lines = textwrap.wrap(text, width=msgbox_limit, max_lines=max_lines)
text = ""
for i, line in enumerate(lines):
text += line
if i < len(lines) - 1:
if i % 3 == 2:
text += "<NOD"
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.
"""
return f"<PRI<MSG<TUR{wrap_msg_text(text, facepic, ending=ending)}"

View file

View file

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

View file

@ -1,195 +0,0 @@
{
"$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"
}
}
}

View file

@ -1,54 +0,0 @@
# 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

@ -1,25 +0,0 @@
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

@ -1,281 +0,0 @@
offset 414bf0
#define
rectMax=0D
rectMaxx10=0D0
rcLeft.left=EBP-0D0
rcLeft.top=EBP-0CC
rcLeft.right=EBP-0C8
rcLeft.bottom=EBP-0C4
rcRight.left=EBP-1A0
rcRight.top=EBP-19C
rcRight.right=EBP-198
rcRight.bottom=EBP-194
gMC.rect.left=49E69C
gMC.rect.top=49E6A0
gMC.rect.right=49E6A4
gMC.rect.bottom=49E6A8
gMC.cond=49E638
gMC.flag=49E63C
gMC.ani_no=49E678
gMC.ani_wait=49E674
gMC.up=49E644
gMC.down=49E648
gMC.ym=49E670
gMC.direct=49E640
gMC.air=49E6DC
gKey_addr=49E210
gKeyUp=493634
gKeyLeft=493630
gKeyRight=493638
bKey=EBP+8
PlaySoundObject=00420640
#enddefine
PUSH EBP
MOV EBP,ESP
SUB ESP,1A0 ; or whatever
PUSH ESI
PUSH EDI
XOR ESI,ESI
; FRAMERECTS
; Push left framerects onto stack for ease of looping
PUSH 0D0 ; DROWNING SPRITES
PUSH 70
PUSH 60
PUSH 30
PUSH 50
PUSH 30
PUSH 40
PUSH 30
PUSH 0
PUSH 20
PUSH 0
PUSH 10
PUSH 0
MOV EAX, 0
MOV ECX, 10
MOV EDX, 20
JMP :loopbody
:looptop
ADD ESI, 10
CMP ESI, rectMaxx10
JGE :loopend
:loopbody
; Left top = 0, Right top = 0x10
MOV [rcLeft.top+ESI], EAX | MOV [rcRight.top+ESI], ECX
; Left bottom = 0x10, Right bottom = 0x20
MOV [rcLeft.bottom+ESI], ECX | MOV [rcRight.bottom+ESI], EDX
POP EDI
; Left/Right left = value from stack
MOV [rcLeft.left+ESI], EDI | MOV [rcRight.left+ESI], EDI
ADD EDI, 10
; Left/Right right = value from stack + 0x10
MOV [rcLeft.right+ESI], EDI | MOV [rcRight.right+ESI], EDI
JMP :looptop
:loopend
; if (gMC.air <= 0)
MOV EDX, [gMC.air]
CMP EDX, 0
JG :checkCond
MOV [gMC.ani_no], 0C
JMP :checkDir
; if (gMC.cond & 2)
:checkCond
MOVZX EAX, BYTE [gMC.cond]
TEST EAX, 00000002
JNE :return
; if (gMC.flag & 8)
:checkFlag
MOV ECX, [gMC.flag]
TEST ECX, 00000008
JE :checkUp
; if (gMC.cond & 1)
TEST EAX, 00000001
JE :keycheckWalk
MOV [gMC.ani_no], 0B
JMP :checkDir
; else if (gKey & (gKeyLeft | gKeyRight) && bKey)
:keycheckWalk
MOV ECX, [gKey_addr]
MOV EDX, [gKeyLeft]
OR EDX, [gKeyRight]
TEST ECX, EDX ; gKey & (gKeyLeft | gKeyRight)
JE :keycheckStop
CMP [bKey], 0 ; bKey
JE :keycheckStop
; if (gKey & gKeyUp)
TEST ECX, [gKeyUp]
JE :WalkFrames
:UpWalkFrames
PUSH 6
PUSH 9
PUSH 9
PUSH 7
JMP :WalkAni
:WalkFrames
PUSH 1
PUSH 4
PUSH 4
PUSH 2
:WalkAni
OR EAX, 00000004
MOV BYTE [gMC.cond], AL ;gMC.cond |= 4
POP EAX ; 7 if looking up, else 2
POP ECX ; 9 if looking up, else 4
MOV ESI, [gMC.ani_wait]
INC ESI ; ++gMC.ani_wait
MOV EDI, [gMC.ani_no]
; if (++gMC.ani_wait > 4)
CMP ESI, 4
JLE :checkWalkAni
XOR ESI,ESI ; gMC.ani_wait = 0
INC EDI ; ++gMC.ani_no
CMP EDI, EAX
JE :playSound
CMP EDI, ECX
JNE :checkWalkAni
:playSound
PUSH 1
PUSH 18
CALL PlaySoundObject
ADD ESP,8
; UP: if (gMC.ani_no > 9 || gMC.ani_no < 6)
; ELSE: if (gMC.ani_no > 4 || gMC.ani_no < 1)
:checkWalkAni
MOV [gMC.ani_wait], ESI
POP EAX ; 9 if looking up, else 4
POP ECX ; 6 if looking up, else 1
CMP EDI, EAX
JG :resetWalkAni
CMP EDI, ECX
JGE :setAniNo
:resetWalkAni
MOV EDI, ECX
:setAniNo
MOV [gMC.ani_no], EDI
JMP :checkDir
:keyChecKStop
TEST ECX, [gKeyUp]
JE :StopFrame
CMP [bKey], 0
JE :StopFrame
:UpStopFrame
PUSH 5
JMP :StopAni
:StopFrame
PUSH 0
:StopAni
TEST EAX, 00000004
JE :SetStopAni
PUSH 1
PUSH 18
CALL PlaySoundObject
ADD ESP,8
:SetStopAni
MOVZX EAX, BYTE [gMC.cond]
AND EAX, FFFFFFFB
MOV BYTE [gMC.cond], AL
POP ECX
MOV [gMC.ani_no], ECX
JMP :checkDir
:checkUp
LEA EAX, [gMC.ani_no]
CMP [gMC.up], 0
JE :checkDown
MOV [EAX], 6
JMP :checkDir
:checkDown
CMP [gMC.down], 0
JE :checkYm
MOV [EAX], 0A
JMP :checkDir
:checkYm
CMP [gMC.ym], 0
JLE :ymLess
:ymMore
MOV [EAX], 1
JMP :checkDir
:ymLess
MOV [EAX], 3
:checkDir
MOV EAX, [gMC.ani_no]
SHL EAX, 4
CMP [gMC.direct], 0
JNE :rectRight
:rectLeft
LEA EAX, [EAX+rcLeft.left]
JMP :setrect
:rectRight
LEA EAX, [EAX+rcRight.left]
:setrect
MOV ECX, [EAX]
MOV [gMC.rect.left], ECX
MOV ECX, [EAX+4]
MOV [gMC.rect.top], ECX
MOV ECX, [EAX+8]
MOV [gMC.rect.right], ECX
MOV ECX, [EAX+0C]
MOV [gMC.rect.bottom], ECX
:return
POP EDI
POP ESI
MOV ESP,EBP
POP EBP
RETN
INT3

View file

@ -1,36 +0,0 @@
offset 414b50
PUSH EBP
MOV EBP, ESP
PUSH 0B4
PUSH 0
PUSH 0049E638
CALL 00480D30
ADD ESP,0C ; memset(&gMC, 0, sizeof(MYCHAR))
MOV BYTE [49E638],80 ; gMC.cond = 0x80
MOV [49E640],2 ; gMC.direct = 2
MOV EAX,1000
MOV [49E694],EAX ; gMC.view.back = 8 * 0x200
MOV [49E690],EAX ; gMC.view.top = 8 * 0x200
MOV [49E68C],EAX ; gMC.view.front = 8 * 0x200
MOV [49E698],EAX ; gMC.view.bottom = 8 * 0x200
MOV ECX,0A00
MOV [49E684],ECX ; gMC.hit.back = 5 * 0x200
MOV [49E680],EAX ; gMC.hit.top = 8 * 0x200
MOV [49E67C],ECX ; gMC.hit.front = 5 * 0x200
MOV [49e688],EAX ; gMC.hit.bottom = 8 * 0x200
MOV WORD [49E6CC],3 ; gMC.life = 3
MOV WORD [49E6D0],3 ; gMC.max_life = 3
MOV [49E64C],0 ; gMC.unit = 0
MOV [49E6DC],3E8 ; gMC.air = 1000
POP EBP
RETN
INT3

View file

@ -1,34 +0,0 @@
offset 4169EB
#define
GetNPCFlag=40E930
StartTextScript=421990
setDeathCond=416A52
computeAirGet=416A65
gMC.air=49E6DC
#enddefine
PUSH 0FA0 ; 4000
CALL GetNPCFlag
POP ECX
TEST EAX,EAX ; if (GetNPCFlag(4000))
JE :drown
:core
PUSH 44C ; 1100
CALL StartTextScript
POP ECX
MOV [gMC.air], 3E8 ; gMC.air = 1000
JMP computeAirGet
:drown
PUSH 29 ; 41
CALL StartTextScript
POP ECX
JMP setDeathCond

View file

@ -1,16 +0,0 @@
offset 415256
#define
gMC.air=49E6DC
gMC.cond=49E638
#enddefine
CMP [gMC.air], 0
JLE 00415495
MOV AL, BYTE [gMC.cond]
TEST AL, 00000080
JE 00415270
TEST AL, 00000002
JE 00415275
//data 90 90 90 90 ; 4 bytes were saved

View file

@ -1,43 +0,0 @@
offset 40cf90
#define
count=EBP-4
Strip_addr=0049D628
Credit.mode=49D620
MAX_STRIP=40
size=50
Strip.flag=EAX
Strip.x=EAX+4
Strip.y=EAX+8
Strip.cast=EAX+0C
Strip.str=EAX+10
#enddefine
push ebp
mov ebp, esp
push ecx
mov eax, [Strip_addr]
mov edx, MAX_STRIP
:$LL4@ActionStri
test BYTE [Strip.flag], 80
je :$LN5@ActionStri
cmp [Credit.mode], 0
je :$LN5@ActionStri
sub [Strip.y], 100
:$LN5@ActionStri
cmp [Strip.y], -2000
jg :$LN2@ActionStri
and [Strip.flag], 0
:$LN2@ActionStri
add eax, size
sub edx, 1
jne :$LL4@ActionStri
leave
retn

View file

@ -1,36 +0,0 @@
offset 40d3e0
#define
size=50
MAX_STRIP=40
Strip_addr=0049d628
#enddefine
PUSH EBP
MOV EBP,ESP
PUSH 18
PUSH 0
PUSH 0049D610
CALL 00480D30
ADD ESP,0C
/*
PUSH 500
PUSH 0
PUSH 0049D628
CALL 00480D30
ADD ESP,0C
PUSH size
PUSH MAX_STRIP
CALL 00487701
ADD ESP,8
MOV [Strip_addr],EAX
*/
XOR EAX,EAX
MOV [Strip_addr],EAX
POP EBP
RETN
INT3

View file

@ -1,2 +0,0 @@
offset 4115e6
PUSH 3F0 ; (MAX_STRIP - 1) * 0x10

View file

@ -1,8 +0,0 @@
ActionStripper.txt
InitCreditScript.txt
LoadGenericDataMAX_STRIP.txt
PutStripper.txt
RestoreStripper.txt
SetStripper.txt
StartCreditScript.txt
ReleaseCreditScript.txt

View file

@ -1,135 +0,0 @@
offset 40D010
#define
; Constants
MAX_STRIP=40
MAX_STRIPx10=400
size=50
; Locals
ArrayPad=EBP-4
rc_addr=EBP-14
rc.left=EBP-14
rc.right=EBP-0C
rc.top=EBP-10
rc.bottom=EBP-8
; References
Strip_addr=0049D628
Strip.flag=ecx
Strip.x=ecx+4
Strip.y=ecx+8
Strip.cast=ecx+0c
Strip.str=ecx+10
grcFull=0048f92c
; Functions
PutBitmap3=0040c3c0
; Builtins
___security_cookie=498b20
__security_check_cookie=00480dc1
#enddefine
push ebp
mov ebp,esp
sub esp, 14 ; 00000018H
push ebx
push esi
push edi
; Line 92
xor esi, esi
xor edi, edi
:$LL4@PutStrippe
; Line 94
mov ecx, [Strip_addr]
test BYTE [esi+Strip.flag], 80 ; 00000080H
je :$LN2@PutStrippe
; Line 97
and [rc.left], 0
mov [rc.right], 140 ; 00000140H
mov [rc.top], edi
lea eax, [edi+10]
mov [rc.bottom], eax
; Line 102
push 23 ; 00000023H
lea eax, [rc_addr]
push eax
mov ebx, 1ff ; 000001ffH
mov eax, [esi+Strip.y]
cdq
and edx, ebx
add eax, edx
sar eax, 9
push eax
mov eax, [esi+Strip.x]
cdq
and edx, ebx
add eax, edx
sar eax, 9
push eax
push grcFull
call PutBitmap3
; Line 110
push 25 ; 00000025H
mov ecx, [Strip_addr]
mov eax, [esi+Strip.cast]
cdq
mov ebx, 0d
idiv ebx
imul edx, edx, 18
imul eax, eax, 18
mov [rc.left], edx
add edx, 18 ; 00000018H
mov [rc.right], edx
mov [rc.top], eax
add eax, 18
mov [rc.bottom], eax
lea eax, [rc_addr]
push eax
mov ebx, 1ff
mov eax, [esi+Strip.y]
cdq
and edx, ebx
add eax, edx
sar eax, 9
sub eax, 8
push eax
mov eax, [esi+Strip.x]
cdq
and edx, ebx
add eax, edx
sar eax, 9
sub eax, 18 ; 00000018H
push eax
push grcFull
call PutBitmap3
add esp, 28 ; 00000028H
:$LN2@PutStrippe
; Line 92
add edi, 10 ; 00000010H
add esi, size ; 00000050H
cmp edi, MAX_STRIPx10 ; 000007f0H
jl :$LL4@PutStrippe
; Line 113
pop edi
pop esi
pop ebx
leave
retn

View file

@ -1,34 +0,0 @@
offset 40d410
#define
Credit.pData=49d614
Strip=49d628
_free=0048128b
#enddefine
push ebp
mov ebp,esp
mov eax, [Credit.pData]
test eax, eax
je :$LN2@ReleaseCre
push eax
call _free
pop ecx
and [Credit.pData], 0
:$LN2@ReleaseCre
mov eax, [Strip]
test eax, eax
je :$LN3@ReleaseCre
push eax
call _free
pop ecx
:$LN3@ReleaseCre
mov esp, ebp
pop ebp
retn

View file

@ -1,86 +0,0 @@
offset 40d240
#define
; Constants
MAX_STRIPx10=400
; Locals
ArrayPad = EBP-4
rc_addr = EBP-14
rc.left=EBP-14
rc.right=EBP-0c
rc.top=EBP-10
rc.bottom=EBP-8
; References
Credit=49D620
Strip_addr=0049D628
Strip.flag=0049D628
Strip.x=0049D62C
Strip.y=0049D630
Strip.cast=0049D634
Strip.str=0049D638
; Functions
CortBox2=0040ca80
PutText2=0040ceb0
; Builtins
___security_cookie=498b20
__security_check_cookie=00480dc1
#enddefine
push ebp
mov ebp, esp
sub esp, 14 ; 00000014H
push esi
push edi
; Line 151
xor edi, edi
xor esi, esi
:$LL4@RestoreStr
; Line 153
mov eax, [Strip_addr]
test eax, eax
je :return
test [edi+eax], 128 ; 00000080H
je :$LN2@RestoreStr
; Line 155
and [rc.left], 0
; Line 156
mov [rc.right], 140 ; 00000140H
; Line 157
mov [rc.top], esi
; Line 158
lea eax, [esi+16]
mov [rc.bottom], eax
; Line 160
push 23 ; 00000023H
push 0
lea eax, [rc_addr]
push eax
call CortBox2
; Line 161
push 23 ; 00000023H
push 00feffff ; 00feffffH
mov eax, [Strip_addr]
add eax, 10 ; 00000010H
add eax, edi
push eax
push [rc.top]
push 0
call PutText2
add esp, 20 ; 00000020H
:$LN2@RestoreStr
; Line 151
add esi, 10 ; 00000010H
add edi, 50 ; 00000050H
cmp esi, MAX_STRIPx10 ; 000007f0H
jl :$LL4@RestoreStr
; Line 164
:return
pop edi
pop esi
leave
retn

View file

@ -1,116 +0,0 @@
offset 40d150
#define
; Constants
MAX_STRIP=40
size=50
; Locals
ArrayPad=EBP-4
rc_addr=EBP-14
rc.left=EBP-14
rc.right=EBP-0C
rc.top=EBP-10
rc.bottom=EBP-8
; Arguments
argx=EBP+8
argy=EBP+0C
argtext=EBP+10
argcast=EBP+14
; References
Strip_addr=0049D628
Strip.flag=edx
Strip.x=edx+4
Strip.y=edx+8
Strip.cast=edx+0c
Strip.str=edx+10
; Functions
CortBox2=0040ca80
PutText2=0040ceb0
; Builtins
___security_cookie=498b20
__security_check_cookie=00480dc1
_strcpy=00481100
#enddefine
push ebp
mov ebp, esp
sub esp, 14 ; 00000014H
mov eax, [___security_cookie]
mov [ArrayPad], eax
mov edx, [Strip_addr]
mov eax, edx
push esi
push edi
mov edi, [argtext]
; Line 121
xor esi, esi
:$LL4@SetStrippe
; Line 122
test [eax], 80 ; 00000080H
je :$LN13@SetStrippe
; Line 121
inc esi
add eax, size ; 00000050H
mov ecx, esi
cmp esi, MAX_STRIP ; 0000007fH
jl :$LL4@SetStrippe
; Line 125
cmp ecx, MAX_STRIP ; 0000007fH
je :$LN1@SetStrippe
:$LN13@SetStrippe
; Line 129
imul ecx, esi, size
mov [ecx+Strip.flag], 80 ; 00000080H
; Line 130
mov eax, [argx]
mov [ecx+Strip.x], eax
; Line 131
mov eax, [argy]
mov [ecx+Strip.y], eax
; Line 132
mov eax, [argcast]
mov [ecx+Strip.cast], eax
; Line 133
push edi
lea eax, [Strip.str]
add eax, ecx
push eax
call _strcpy
; Line 136
and [rc.left], 0
; Line 137
mov [rc.right], 140 ; 00000140H
; Line 138
shl esi, 4
mov [rc.top], esi
; Line 139
lea eax, [esi+10]
mov [rc.bottom], eax
; Line 141
push 23 ; 00000023H
push 0
lea eax, [rc_addr]
push eax
call CortBox2
; Line 142
push 23 ; 00000023H
push 00feffff ; 00feffffH
push edi
push [rc.top]
push 0
call PutText2
add esp, 28 ; 00000028H
:$LN1@SetStrippe
; Line 143
pop edi
pop esi
mov ecx, [ArrayPad]
call __security_check_cookie
leave
retn

View file

@ -1,160 +0,0 @@
offset 40d440
#define
; Constants
MAX_STRIP=40
size=50
; Locals
path=EBP-108
ArrayPad=EBP-4
; References
Strip_addr=0049D628
Credit.pData=49D614
Credit.size=49d610
Credit.offset=49d618
Credit.wait=49d61c
Credit.mode=49d620
Illust.x=49d60c
Illust.act_no=49d608
grcGame.left=48f91c
gDataPath=0049E220
; Functions
GetFileSizeLong=00410d80
EncryptionBinaryData2=004215c0
ReloadBitmapFile=0040BFD0
; Builtins
___security_cookie=498b20
__security_check_cookie=00480dc1
_malloc=004813a3
_calloc=00487701
_free=0048128B
_memset=00480d30
_sprintf=00481010
_fopen=00480FFD
_fread=00480f55
; Strings
credit_script=48f918
format=0048C374
str_rb=0048C37C
str_casts=0048c380
#enddefine
push ebp
mov ebp, esp
sub esp, 108 ; 00000108H
mov eax, [___security_cookie]
mov [ArrayPad], eax
; Line 241
mov eax, [Credit.pData]
push esi
xor esi, esi
push edi
test eax, eax
je :$LN2@StartCredi
; Line 243
push eax
call _free
pop ecx
; Line 244
mov [Credit.pData], esi
:$LN2@StartCredi
; Line 248
push [credit_script]
lea eax, [path]
push gDataPath
push format
push eax
call _sprintf
; Line 250
lea eax, [path]
push eax
call GetFileSizeLong
add esp, 14 ; 00000014H
mov [Credit.size], eax
; Line 251
cmp eax, -1
je :$LN8@StartCredi
; Line 255
push eax
call _malloc
mov [Credit.pData], eax
pop ecx
; Line 256
test eax, eax
je :$LN8@StartCredi
; Line 259
lea eax, [path]
push str_rb
push eax
call _fopen
pop ecx
pop ecx
; Line 260
test eax, eax
jne :$LN5@StartCredi
; Line 262
push [Credit.pData]
call _free
pop ecx
:$LN8@StartCredi
; Line 299
xor eax, eax
:$LN1@StartCredi
pop edi
pop esi
mov ecx, [ArrayPad]
call __security_check_cookie
leave
retn
:$LN5@StartCredi
; Line 267
push eax
push [Credit.size]
xor edi, edi
inc edi
push edi
push [Credit.pData]
call _fread
; Line 274
push [Credit.size]
push [Credit.pData]
call EncryptionBinaryData2
; Line 293
push 25 ; 00000025H
push str_casts
mov [Credit.offset], esi
mov [Credit.wait], esi
mov [Credit.mode], edi
mov [Illust.x], fffec000 ; fffec000H
mov [Illust.act_no], esi
mov [grcGame.left], 0a0 ; 000000a0H
call ReloadBitmapFile
add esp, 20 ; 00000020H
test eax, eax
je SHORT :$LN8@StartCredi
; Line 297
mov eax, [Strip_addr]
test eax, eax
je :blah
push eax
call _free
pop ecx
:blah
push size
push MAX_STRIP
call _calloc
add ESP,8
mov [Strip_addr],EAX
; Line 298
mov eax, edi
jmp :$LN1@StartCredi
data cc cc cc cc cc cc cc cc

View file

@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hack name="SuperOrg" author="txin">
<panel>
<panel title="Info">
</panel>
<field type="info" col="0">
Causes the game to load music and instruments from files instead of resources.
This effectively allows for near unlimited music files in a mod.
</field>
<field type="info" col="0">
&#60;CMUabcd will now change the current music to "data\Orgs\abcd.org".
"abcd" can be any ascii character, and letters are case sensitive.
It will also load the instruments within "data\Orgs\abcd.dat" as a wave100 file.
</field>
<field type="info" col="0">
If the "*.dat" file is not found, the game will simply skip loading it.
However, if the "*.org" file is not found, the game may crash.
The default/empty org is "0000.org", and the default wave100 is "0000.dat".
</field>
<panel title="Customize" col="0">
</panel>
<panel>
<panel title="" col="0">
<field type="label">New *.org size limit (bytes)</field>
<field type="text" size="4" offset="0x41BAED" col="1">1048576</field>
</panel>
</panel>
<panel title="Data" col="0">
</panel>
<panel>
<field type="data" offset="0x40FDF4" col="0">
89 85 9C FE FF FF 85 C0 74 58 3D 28 23 00 00 7D
0F 6A 04 8F 85 E4 FE FF FF 68 30 30 30 32 EB 47
3D E0 2E 00 00 7D 0F 6A 03 8F 85 E4 FE FF FF 68
30 30 34 31 EB 31 3D 98 3A 00 00 7D 0F 6A 02 8F
85 E4 FE FF FF 68 30 30 34 30 EB 1B 3D 50 46 00
00 7D 0F 6A 01 8F 85 E4 FE FF FF 68 30 30 33 36
EB 05 68 30 30 32 34 E8 80 10 01 00 58 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
</field>
<field type="data" offset="0x41B379" col="1">
2E 64 61 74 00 CC CC 60 89 E5 8B 7D 24 6A 7F 59
31 C0 89 CA F2 AE E3 47 29 CA 89 D1 8B 75 24 BF
B9 4F 49 00 F3 A4 68 48 C7 48 00 68 B0 4F 49 00
6A 05 59 E8 50 8F 00 00 F3 A4 E8 45 5C 06 00 85
C0 74 1C 50 93 6A 01 68 00 64 00 00 68 00 E7 49
00 E8 86 5B 06 00 53 E8 46 5A 06 00 31 C0 40 89
45 1C 89 EC 61 C3 CC B8 F4 57 4A 00 89 08 C3 CC
CC CC CC CC CC CC CC
</field>
<field type="data" offset="0x41BAD0" col="2">
60 8B EC 81 EC 9C 00 00 00 A1 20 8B 49 00 89 45
EC 56 89 8D 64 FF FF FF C6 45 F7 00 68 00 00 10
00 E8 AD 58 06 00 89 45 FC FF 75 24 E8 7F F8 FF
FF 6A 05 BE A3 C0 41 00 59 F3 A4 68 48 C7 48 00
68 B0 4F 49 00 E8 E3 54 06 00 93 31 C0 40 E8 E8
87 00 00
</field>
<field type="data" offset="0x41C09D" col="3">
8B E5 61 C2 04 00 2E 6F 72 67 00 CC
</field>
<field type="data" offset="0x41C6B1" col="4">
30 30 30 30 00 CC CC CC CC CC CC CC CC CC CC 55
8B EC 8B 0D E8 57 4A 00 E3 21 68 B1 C6 41 00 E8
AB EC FF FF 85 C0 75 04 33 C0 EB 0F B9 18 4E 4A
00 E8 69 EF FF FF B8 01 00 00 00 C9 C3
</field>
<field type="data" offset="0x420EE0" col="0">
55 8B EC 8B 4D 08 E3 0A 3B 0D F4 57 4A 00 75 02
C9 C3 E8 79 B8 FF FF BA F4 57 4A 00 89 42 04 8B
0A 89 4A 08 E8 E7 B8 FF FF 83 7D 08 00 75 07 C7
45 08 30 30 30 30 E8 1F 34 00 00 9B E8 CF B7 FF
FF 83 C4 04 6A 64 E8 95 B8 FF FF 83 C4 04 6A 00
E8 FB B7 FF FF 83 C4 04 E8 53 B8 FF FF 8B 4D 08
E8 9B A4 FF FF C9 C3 CC
</field>
<field type="data" offset="0x420F50" col="1">
60 8B EC E8 18 B8 FF FF 97 E8 92 B8 FF FF BE F4
57 4A 00 8B 1E 8B 46 08 B9 A8 4F 49 00 89 01 C6
41 04 00 51 E8 77 B7 FF FF FF 76 04 E8 AF B7 FF
FF 6A 64 E8 38 B8 FF FF E8 03 B8 FF FF 8B 46 08
89 06 89 7E 08 89 EC 61 C3
</field>
<field type="data" offset="0x4242DA" col="2">
B9 E0 5A 4A 00 8B 51 F8 03 11 81 3A 3C 43 4D 55
75 60 FF 72 04 E8 EC CB FF FF 58 83 05 E0 5A 4A
00 08 E9 CA E2 FF FF BE 79 B3 41 00 4F 89 7D 00
C3 8B 75 FC 3C 01 75 0F 53 50 50 56 E8 3A CC 05
00 46 83 C4 10 EB ED 8B 0D D4 4F 49 00 E3 07 51
E8 5C CF 05 00 59 8B 55 FC 89 15 D4 4F 49 00 C3
5A B9 A8 4F 49 00 8B 45 08 89 01 C6 41 04 00 51
FF E2
</field>
<field type="data" offset="0x494FB0" col="3">
64 61 74 61 5C 4F 72 67 5C 51 57 45 52 54 59 55
49 4F 50 2E 64 61 74 00
</field>
</panel>
</panel>
</hack>

View file

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hack name="SpeedText" author="txin">
<panel>
<panel title="Description">
</panel>
<field type="info">
Causes message box text to scroll instantly, displaying = signs as circles.
</field>
<panel title="Data">
</panel>
<panel>
<field type="data" offset="0x421d01" col="0">
FE 45 D4 C3
</field>
<field type="data" offset="0x422573" col="1">
6A 01 5A B9 28 36 49 00 A1 10 E2 49 00 F6 C4 02
71 24 85 01 74 03 C1 F2 02 85 41 04 74 03 C1 F2
02 B9 FC 5A 4A 00 01 11 83 39 04 0F 8C 98 31 00
00 83 21 00 EB 1B 42 EB DD 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 C7 45 D4 00 00 00 00 83 7D D4 00 0F 85 9C 2F
00 00 8B 0D D8 5A 4A 00 03 0D E0 5A 4A 00 0F BE
11 83 FA 3C 0F 85 BF 2C 00 00 81 39 3C 45 4E 44
75 71 C6 05 DC 5A 4A 00 00 80 25 38 E6 49 00 FE
80 0D E8 E1 49 00 03 83 25 0C 5B 4A 00 00 6A 01
8F 45 D4 EB B3 90 90 90 90 90 90 90 90 B9 28 36
49 00 A1 10 E2 49 00 F6 C4 02 71 09 85 01 74 12
85 41 04 74 0D 6A 00 6A 00 E8 0F 00 00 00 89 45
D4 C3 6A 01 58 EB F7 90 90 90 90 90 90 B9 B1 37
49 00 8B 44 E4 08 80 09 01 9B C2 08 00 90 90 90
90 90 90
</field>
<field type="data" offset="0x423654" col="2">
00
</field>
<field type="data" offset="0x4236B4" col="2">
00
</field>
<field type="data" offset="0x425565" col="0">
E8 B6 D0 FF FF D9 D0 E9 5A D0 FF FF E9 C6 01 00 00
</field>
<field type="data" offset="0x425737" col="1">
E9 00 00 00 00 80 3D DC 5A 4A 00 00 75 0E 83 25 E8 E1 49 00 FB
65 66 0F 19 C4
</field>
</panel>
</panel>
</hack>

View file

@ -1,4 +0,0 @@
0x40CD91
03
0x40CDC8
03

View file

@ -1,4 +0,0 @@
0x40149E
8B 4D F8 49 79 01 41 B8 68 9C 49 00 31 D2 39 10
7D 02 89 08 39 08 7E 14 89 10 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90

View file

@ -1,2 +0,0 @@
0x41DB17
95 EA

View file

@ -1,9 +0,0 @@
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

@ -1,5 +0,0 @@
0x41D9C6
A1 09 DF 49 00 90
0x41DA1F
C7 45 F8 00 00 00 00 C7 45 FC 00 00 00 00

View file

@ -1,56 +0,0 @@
Author: Enlight
DUNC NOTE: flag range changed from 4008 through 4015 to 2888 through 2919 in rando
also: skip the second patch it's not needed and also bugged
Instructions:
1. Backup your .exe, then patch your .exe with the patches in patches.txt.
2. Learn how to use the hack and setup your teleporters with the demonstration mod and the information below.
3. Make a similar system in your mod.
Important Files:
Patches.txt - The first patch allows you to edit where teleporter menus draw. The 2nd one just fixes a graphic bug with slots 6 and 7.
OOBFlagGen.jar - What helps you generate the flags for the top framerects. Input address 49DF09 and the value will be how many pixels down you want
the mod to START drawing the teleporter icons IN HEXADECIMAL. The rows are IN DECIMAL 0, 16, 32, 48, 64... etc. In HEXADECIMAL it's 0, 10, 20, 30 etc.
Keep it in bytes. You will then copy the flags it generates (should be just over flag 4000) to use in your level TSC (explained below)
StageSelect.tsc - Example of how you can setup having different location names for different teleporters.
This is just normal TSC using flags. The game is hardcoded to run events 1001-1007 for the slots, but flagjumps can change what it says.
The TSC file for Arthur's House (Pens1.tsc) - Example of how to setup everything else for the teleporters (explained below)
~~~~~
Please open the demonstration mod in a CS editor of you choice to see how the tsc all comes together.
The most important events though are the ones for displaying the teleporter.
One of these events is shown below with comments.
#0100
<KEY
<FL-4008<FL-4009<FL-4010<FL-4011<FL-4012<FL-4013<FL-4014<FL-4015
// What you generate with OOBFlagGen, tells the game the top framerect of where to draw the teleporter images.
<FL+5001<FL-5002<FL-5003<FL-5004
// These are used like normal flags, telling StageSelect.tsc what to call the teleporter options.
<PS+0001:0110<PS+0002:0111<PS+0003:0112<PS+0004:0113
// These are overwriting the teleporter slots to run events 110-113, this is what's saved to profile.dat
but you can (probably) ignore that and just overwrite it every time before you display the tele menu.
<SLP<END
// Displays the teleporter menu.
~~~~~
If you have any other questions you can just contact me (Enlight) because I'm not good at writing tutorials at 4:30 AM
<Cave Story ~ Doukutsu Monogatari> (C) Studio Pixel 2004

View file

@ -1,108 +0,0 @@
; ActionCredit_Read
offset 0040d684
#define
var_a=ebp-30
len=ebp-34
var_text=ebp-2c
Credit.pData=49d614
Credit.offset=49d618
Credit.wait=49d61c
Credit.start_x=49d624
_memcpy=4813c0
GetScriptNumber=40db00
SetStripper=40d150
IsShiftJIS=410e90
#enddefine
mov ecx,[Credit.offset]
inc ecx
mov [Credit.offset],ecx
mov [var_a],ecx
:loop
mov eax,[Credit.pData]
add eax,[var_a]
movsx ecx,BYTE [eax]
cmp ecx,5d
je :break
push ecx
call IsShiftJIS
pop ecx
mov ecx,[var_a]
test eax,eax
je :notShiftJIS
inc ecx
:notShiftJIS
inc ecx
mov [var_a],ecx
jmp :loop
:break
; len = a - Credit.offset
mov edx,[var_a]
sub edx,[Credit.offset]
mov [len],edx
push edx ; Arg3 = len
mov ecx,[Credit.pData]
add ecx,[Credit.offset]
push ecx ; Arg2 = &Credit.pData[Credit.offset]
lea ecx,[var_text]
push ecx ; Arg1 = text
call _memcpy
add esp,0c
; text[len] = '\0'
mov ecx,[len]
mov [ecx+var_text],0
; Credit.offset = a+1
mov eax,[var_a]
inc eax
mov [Credit.offset],eax
add eax,[Credit.pData]
push eax ; Arg1 = &Credit.pData[Credit.offset]
call GetScriptNumber
; len = GetScriptNumber
mov [len],eax
pop ecx
push eax ; Arg4 = len
lea eax,[var_text]
push eax ; Arg3 = text
mov edx,1f000
mov eax,[Credit.wait]
cmp eax,0
jge :more
imul eax,eax,200
add edx,eax
:more
push edx
mov eax,[Credit.start_x]
push eax ; Arg1 = Credit.start_x
call SetStripper
add esp,10
; Credit.wait = 0
mov [Credit.wait],0
; Credit.offset += 0
mov eax,[Credit.offset]
add eax,4
mov [Credit.offset],eax
jmp 0040da6a

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hack name="noLoseFocus" author="Clownacy / txin">
<panel>
<field type="info">
Prevents the game stopping when in the background
</field>
<field type="data" offset="0x413593">
71
</field>
<field type="data" offset="0x412BC0">
C3
</field>
<field type="data" offset="0x412BF0">
C3
</field>
</panel>
</hack>

View file

@ -1,99 +0,0 @@
0x434101
8B 75 08 8B 46 10 01 46 08 8B 46 14 01 46 0C 6A
20 59 3E 83 A4 8D 7C FF FF FF 00 E2 F5 C6 45 C0
20 C6 45 C4 20 C6 45 C8 30 C6 45 CC 30 C6 45 D0
30 C6 45 D4 20 C6 45 D8 40 C6 45 DC 30 C6 45 E0
40 C6 45 E4 20 C6 45 E8 50 C6 45 EC 30 C6 45 F0
50 C6 45 F4 20 C6 45 F8 60 C6 45 FC 30 C6 45 80
20 C6 45 84 30 C6 45 88 30 C6 45 8C 40 C6 45 90
30 C6 45 94 30 C6 45 98 40 C6 45 9C 40 C6 45 A0
40 C6 45 A4 30 C6 45 A8 50 C6 45 AC 40 C6 45 B0
50 C6 45 B4 30 C6 45 B8 60 C6 45 BC 40 FF 46 64
83 7E 64 01 7E 07 83 66 64 00 FF 46 68 83 7E 68
02 7E 04 83 66 68 00 89 F7 83 C7 54 8B 46 68 C1
E0 04 83 7E 4C 00 75 06 8D 74 05 C0 EB 04 8D 74
05 80 6A 04 59 F3 A5 C9 C3 CC CC CC CC CC CC 64
61 74 61 5C 68 61 73 68 2E 74 78 74 00 CC CC C8
34 01 00 6A 02 6A 05 E8 04 35 05 00 83 C4 04 89
45 DC 68 E0 41 43 00 68 28 E3 49 00 68 40 C7 48
00 8D 85 CC FE FF FF 50 E8 F2 CD 04 00 83 C4 10
68 8C C2 48 00 8D 85 CC FE FF FF 50 E8 CB CD 04
00 83 C4 08 85 C0 75 05 8B 45 DC C9 C3 50 6A 01
6A 20 8D 45 E0 50 E8 09 CD 04 00 83 C4 0C E8 C7
CB 04 00 83 C4 04 31 C9 31 D2 31 DB 30 E4 8A 44
29 E0 3C 30 72 0F 3C 39 77 0B 2C 30 6B DB 0A 66
01 C3 41 EB E9 8B 45 DC 66 89 1C 50 41 42 83 FA
05 7C D7 C9 C3 CC CC CC CC CC CC CC CC CC CC CC
CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
CC CC CC CC CC CC CC CC CC
0x433CC7
43
0x433EFB
8B 75 08 83 46 14 40 81 7E 14 FF 05 00 00 7E 07
C7 46 14 FF 05 00 00 8B 46 10 01 46 08 8B 46 14
01 46 0C 8B 45 08 89 F7 83 C7 54 8B 46 68 C1 E0
04 83 7E 4C 00 75 06 8D 74 05 D0 EB 04 8D 74 05
A0 6A 04 59 F3 A5 C9 C3 CB 3C 43 00 E7 3C 43 00
59 3E 43 00 BC 3E 43 00 CC CC CC CC CC CC CC CC
CC CC CC CC CC C8 10 00 00 6A 41 5B 6A 05 59 8B
75 08 0F B7 06 6A 08 5F 31 D2 F7 F7 6B D2 20 6B
C0 10 89 55 F0 89 45 F4 83 C2 20 83 C0 10 89 55
F8 89 45 FC 51 6A 08 8D 45 F0 50 6A 08 53 68 1C
F9 48 00 E8 1D 84 FD FF 5B 5B 83 C4 0C 59 83 C3
28 83 C6 02 E2 BC C9 C3 CC CC
0x40F9B5
F4
0x40FD8A
E8 61 44 02 00 89 85 0C FE FF FF 83 A5 64 FF FF
FF 00 83 A5 E4 FE FF FF 00 83 A5 9C FE FF FF 00
68 20 20 20 00 E8 FC CA FF FF 89 45 C0 58
0x40FF0D
55
0x40FF52
10
0x40FF8F
2A
0x40FF99
20
0x410141
CF
0x4102FB
FF 75 C4 8D 85 FC FE FF FF 50 FF B5 0C FF FF FF
6A 74 68 1C F9 48 00 E8 A9 C0 FF FF 83 C4 14 6A
00 6A 00 E8 9D A8 FF FF 83 C4 08 FF B5 0C FE FF
FF E8 2F 3C 02 00 83 C4 04 83 BD 9C FE FF FF 00
74 0C 6A 08 6A 10 E8 EA A0 00 00 83 C4 04 E8 22
20 00 00 FF 35 58 E4 49 00 E8 E7 AF FF FF 83 C4
04 85 C0 0F 85 A0 FB FF FF EB 57 6A 00 E8 73 0B
01 00 83 C4 04 FF 15 24 C1 48 00 89 85 E8 FE FF
FF FF 15 24 C1 48 00 8B 8D E8 FE FF FF 81 C1 E8
03 00 00 39 C8 73 28 6A 00 68 1C F9 48 00 E8 42
C6 FF FF 83 C4 08 E8 CA 1F 00 00 FF 35 58 E4 49
00 E8 8F AF FF FF 83 C4 04 85 C0 75 C4 EB 03 6A
03 58 50 FF B5 0C FE FF FF E8 C2 0E 07 00 83 C4
04 58 C9 C3 45 01 41 00 98 01 41 00 EB 01 41 00
3E 02 41 00 8E 02 41 00 CC CC CC CC CC CC CC CC
CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
CC CC CC CC CC
----------Specifications:
The hack reads the first 5 item numbers listed in data\hash.txt, and displays them on the title screen in order.
The item numbers in data\hash.txt can be separated by any non-numerical character.
If data\hash.txt does not exist, the title screen will display item 0 in all 5 slots.
The hack optimises NPCs 64 and 65's velocity and frame code.
004341F0 - load items from hash.txt
00433F60 - render title screen items
----------Limitations:
If you enter item numbers in hash.txt over 65535, it will not work properly.
If hash.txt is more than 31 bytes large, a buffer will overflow, and the game will likely crash. That said, due to the previous limitation, this should never happen.
----------Info:
This is version 1.2 of the "Titlescreen Hash Display" hack, created by zxin and commissioned by duncathan_salt.

View file

@ -1,103 +0,0 @@
; 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"

9
daily.sh Normal file
View file

@ -0,0 +1,9 @@
set -ev
if [ "$TRAVIS_EVENT_TYPE" != "cron" ]; then exit 0; fi
cd src
love-release
sudo xvfb-run -a --server-args="-screen 0 1024x768x24" love "releases/CaveStoryRandomizer.love" --daily
cat daily.txt
curl -H "Content-Type: application/json" -X POST -d @daily.txt "$WEBHOOK"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 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