mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2025-02-08 12:28:25 +00:00
support patching hints
This commit is contained in:
parent
61407e6e0e
commit
08fe90b770
|
@ -3,6 +3,7 @@ from typing import Callable, Optional
|
||||||
from lupa import LuaRuntime
|
from lupa import LuaRuntime
|
||||||
import logging
|
import logging
|
||||||
import shutil
|
import shutil
|
||||||
|
import re
|
||||||
pre_edited_cs = __import__("pre-edited-cs")
|
pre_edited_cs = __import__("pre-edited-cs")
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,16 +53,18 @@ def patch_map(mapname: str, mapdata: dict[str, dict], TscFile, output_dir: Path)
|
||||||
tsc_file = TscFile.new(TscFile, mappath.read_bytes(), logging.getLogger("caver"))
|
tsc_file = TscFile.new(TscFile, mappath.read_bytes(), logging.getLogger("caver"))
|
||||||
|
|
||||||
for event, script in mapdata["pickups"].items():
|
for event, script in mapdata["pickups"].items():
|
||||||
TscFile.placeItemAtLocation(tsc_file, script, event, mapname)
|
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname)
|
||||||
|
|
||||||
for event, song in mapdata["music"].items():
|
for event, song in mapdata["music"].items():
|
||||||
TscFile.placeSongAtCue(tsc_file, song["song_id"], event, song["original_id"], mapname)
|
TscFile.placeSongAtCue(tsc_file, song["song_id"], event, song["original_id"], mapname)
|
||||||
|
|
||||||
for event, script in mapdata["entrances"].items():
|
for event, script in mapdata["entrances"].items():
|
||||||
TscFile.placeTraAtEntrance(tsc_file, script, event, mapname)
|
needle = "<EVE...." # TODO: create a proper pattern
|
||||||
|
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname, needle)
|
||||||
|
|
||||||
for event, script in mapdata["hints"].items():
|
for event, hint in mapdata["hints"].items():
|
||||||
TscFile.placeHintAtEvent(tsc_file, script, event, mapname)
|
script = create_hint_script(hint["text"], hint.get("facepic", "0000"), hint.get("ending", "<END"))
|
||||||
|
TscFile.placeScriptAtEvent(tsc_file, script, event, mapname)
|
||||||
|
|
||||||
chars = TscFile.getText(tsc_file).values()
|
chars = TscFile.getText(tsc_file).values()
|
||||||
mappath.write_bytes(bytes(chars))
|
mappath.write_bytes(bytes(chars))
|
||||||
|
@ -77,3 +80,37 @@ def patch_hash(hash: list[int], output_dir: Path):
|
||||||
hash_strings = [f"{num:04d}" for num in hash]
|
hash_strings = [f"{num:04d}" for num in hash]
|
||||||
hash_string = ",".join(hash_strings)
|
hash_string = ",".join(hash_strings)
|
||||||
output_dir.joinpath("data", "hash.txt").write_text(hash_string)
|
output_dir.joinpath("data", "hash.txt").write_text(hash_string)
|
||||||
|
|
||||||
|
def create_hint_script(text: str, facepic: str, ending: str) -> str:
|
||||||
|
"""
|
||||||
|
A desperate attempt to generate valid <MSG text. Fills one text box (up to three lines). Attempts to wrap words elegantly.
|
||||||
|
"""
|
||||||
|
hard_limit = 35
|
||||||
|
msgbox_limit = hard_limit if facepic == "0000" else 26
|
||||||
|
pattern = r' [^ ]*$'
|
||||||
|
line1, line2, line3 = "", "", ""
|
||||||
|
|
||||||
|
split = 0
|
||||||
|
line1 = text[split:split+msgbox_limit]
|
||||||
|
|
||||||
|
match = next(re.finditer(pattern, line1), None)
|
||||||
|
if match is not None and len(text) > msgbox_limit:
|
||||||
|
line1 = line1[:match.start]
|
||||||
|
split += match.start
|
||||||
|
if split % hard_limit != 0:
|
||||||
|
line2 = "\r\n"
|
||||||
|
line2 += text[split:split+msgbox_limit]
|
||||||
|
|
||||||
|
match = next(re.finditer(pattern, line2), None)
|
||||||
|
if match is not None and len(text) > msgbox_limit*2:
|
||||||
|
line2 = line2[:match.start]
|
||||||
|
if split % hard_limit != 0:
|
||||||
|
split -= 2
|
||||||
|
split += match.start
|
||||||
|
if split % hard_limit != 0:
|
||||||
|
line3 = "\r\n"
|
||||||
|
line3 += text[split:split+msgbox_limit]
|
||||||
|
|
||||||
|
return f"<PRI<MSG<TUR<FAC{facepic}{line1}{line2}{line3}<NOD{ending}"
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@ function TscFile:new(contents)
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
function TscFile:placeItemAtLocation(script, event, mapname)
|
function TscFile:placeScriptAtEvent(script, event, mapname, needle)
|
||||||
|
needle = needle or "<EVE...."
|
||||||
local wasChanged
|
local wasChanged
|
||||||
self._text, wasChanged = self:_stringReplace(self._text, "<EVE....", script, event)
|
self._text, wasChanged = self:_stringReplace(self._text, needle, script, event)
|
||||||
if not wasChanged then
|
if not wasChanged then
|
||||||
local template = 'Unable to place script "%s" at [%s] event "%s".'
|
local template = 'Unable to place script "%s" at [%s] event "%s".'
|
||||||
error(template:format(script, mapname, event))
|
error(template:format(script, mapname, event))
|
||||||
|
@ -26,14 +27,6 @@ function TscFile:placeSongAtCue(songid, event, originalid, mapname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function TscFile:placeTraAtEntrance(script, event, mapname)
|
|
||||||
return -- TODO for entrance rando
|
|
||||||
end
|
|
||||||
|
|
||||||
function TscFile:placeHintAtEvent(script, event, mapname)
|
|
||||||
return -- TODO
|
|
||||||
end
|
|
||||||
|
|
||||||
function TscFile:_stringReplace(text, needle, replacement, label, overrides)
|
function TscFile:_stringReplace(text, needle, replacement, label, overrides)
|
||||||
overrides = overrides or {}
|
overrides = overrides or {}
|
||||||
local pStart, pEnd = self:_getLabelPositionRange(label)
|
local pStart, pEnd = self:_getLabelPositionRange(label)
|
||||||
|
|
Loading…
Reference in a new issue