feat: player runtime for the Phone library and That New Teacher
Named stores (PyNamespace: dotted access, functions that see their own store first, restored after a
save is loaded), real generators run step by step (next, send, yield as an expression), len/bool through
__len__/__bool__, os/calendar/itertools/pygame_sdl2 helpers, Skip and ToggleLocalVariable actions,
text tags {glitch} and {wave} and plain display of explode/gradient/ruby, SnowBlossom and anim.Blink,
RoundedCorners as a transform, transforms listed in `at`, ATL choice weights that are flags, and
renpy.image_size from the converter's picture sizes.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
83cc7fdd5c
commit
11f87df712
15 files changed
+457
-24
No files matched your search
@@ -8,6 +8,38 @@ const runtime = original ? JSON.parse(readFileSync(original, "utf8")) : null;
|
||||
const click = (element) => element.onclick({ stopPropagation() {}, preventDefault() {} });
|
||||
const enter = (engine, label) => engine.restart(() => engine.guardedJump(label));
|
||||
|
||||
test("MIST's actual movie Skip survives a queued redraw and returns before its timer", { skip: !runtime }, async () => {
|
||||
const { engine, root, window } = makeEngine(runtime);
|
||||
globalThis.HTMLVideoElement = window.HTMLVideoElement ?? class {};
|
||||
const played = [], stopped = [];
|
||||
engine.audio.play = (...args) => played.push(args);
|
||||
engine.audio.stop = (...args) => stopped.push(args);
|
||||
engine.audio.mediaOf = () => null;
|
||||
try {
|
||||
engine.newStore();
|
||||
Object.assign(engine.store, { movielength: 63, movieplaying: "images/animations/movies/Intro_Movie.webm" });
|
||||
const completed = engine.exec({ op: "call_screen", name: "custommoviescreen", args: [], kw: {} });
|
||||
const button = [...root.querySelectorAll(".pg-sbtn")].find((element) => element.textContent === "Skip");
|
||||
assert.ok(button);
|
||||
assert.equal(button.classList.contains("pg-sdisabled"), false);
|
||||
engine.screens.refresh();
|
||||
window.dispatchEvent(new window.Event("pointerdown"));
|
||||
await until(() => engine.store.movielength < 63);
|
||||
assert.equal(button.isConnected, true);
|
||||
window.dispatchEvent(new window.Event("pointerup"));
|
||||
click(button);
|
||||
await completed;
|
||||
assert.equal(engine.store._return, 0);
|
||||
assert.ok(engine.store.movielength > 60, "Skip returns without waiting for the movie timer");
|
||||
assert.equal(root.querySelector(".pg-sbtn"), null);
|
||||
assert.equal(played[0][0], "movie");
|
||||
assert.equal(stopped.at(-1)[0], "movie");
|
||||
} finally {
|
||||
window.dispatchEvent(new window.Event("pointercancel"));
|
||||
engine.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test("MIST's actual raise-hand loop accepts screen input and resumes after a save", { skip: !runtime }, async () => {
|
||||
const { engine, root } = makeEngine(runtime);
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user