feat: converter keeps layers of screens and camera, perspective, matrix calls; That New Teacher runs its own text-tag libraries

onlayer on show/hide/call screen and `camera <layer>` reach the player, `perspective`
is an ATL property now, RotateMatrix/OffsetMatrix/ScaleMatrix, Text.set_text and
renpy.fetch are accepted. The text-effect modules of That New Teacher are no longer
skipped (only the shader-based wave tag is).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-27 04:37:26 +03:00
1 parent 7652f7d010
commit 5da7ab1a90
6 files changed
+36 -14

No files matched your search

+15 -5
View File
@@ -1227,8 +1227,10 @@ class RpyParser:
def st_camera(self, line: Line) -> list[Node]:
c = self.cursor(line)
c.keyword("camera")
c.word() if not c.peek("at") and not c.peek(":") else None
layer = c.word() if not c.peek("at") and not c.peek(":") else None
node: Node = {"op": "camera", "at": []}
if layer:
node["layer"] = layer
if c.keyword("at"):
for item in _split_top(c.until(set(), ":")):
node["at"].append(self.transform_ref(item, line))
@@ -1466,8 +1468,10 @@ class RpyParser:
def screen_call(self, c: Cursor, line: Line) -> Node | None:
"""``name(args)`` after `call/show screen`; trailing `nopredict` and `with` are ignored."""
source = re.split(r"\s+(?:nopredict|with)\b", c.rest(), maxsplit=1)[0].strip()
# `onlayer name` only picks the stacking layer; the player keeps every screen in one layer
source = re.sub(r"\s+onlayer\s+\w+\s*$", "", source)
layer_match = re.search(r"\s+onlayer\s+(\w+)\s*$", source)
layer = layer_match.group(1) if layer_match else None
if layer_match:
source = source[:layer_match.start()]
call = self.expr(source, line) if source else None
if call is None:
self.d.warn("Не разобран вызов screen", self.where(line))
@@ -1480,7 +1484,10 @@ class RpyParser:
self.d.warn("Не разобран вызов screen", self.where(line))
return None
self.use_screen(name)
return {"name": name, "args": args, "kw": kw}
found: Node = {"name": name, "args": args, "kw": kw}
if layer:
found["layer"] = layer
return found
def st_scene(self, line: Line) -> list[Node]:
c = self.cursor(line)
@@ -1521,7 +1528,10 @@ class RpyParser:
name = c.word()
if not name:
return []
return [{"op": "hide_screen", "name": name}] # hiding a screen that does not exist is harmless
hidden: Node = {"op": "hide_screen", "name": name} # hiding a screen that does not exist is harmless
if c.keyword("onlayer"):
hidden["layer"] = c.word()
return [hidden]
spec = self.image_spec(c, line)
node: Node = {"op": "hide", "tag": spec.get("tag", spec.get("name", [""])[0])}
self.show_clauses(c, line, node)