sci2-ts 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/996.sc +81 -24
- package/package.json +1 -1
- package/packages/content/src/room.js +2 -0
- package/packages/content/src/room.ts +2 -0
- package/packages/content/src/target.d.ts +3 -1
- package/packages/content/src/target.ts +3 -2
- package/tools/game/target.js +2 -2
- package/tools/game/target.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project. Versions follow [Semantic Versioning](https
|
|
|
4
4
|
and the entries are generated from commit messages
|
|
5
5
|
([Conventional Commits](https://www.conventionalcommits.org/)) when a release is made.
|
|
6
6
|
|
|
7
|
+
## [0.12.0](https://github.com/rlueder/sci-ts/compare/v0.11.0...v0.12.0) (2026-10-02)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* **lib:** portraits that face the middle from their character's side, framed, and one for the hero ([#14](https://github.com/rlueder/sci-ts/issues/14)) ([e7be055](https://github.com/rlueder/sci-ts/commit/e7be0555af2c49743c539e7231cf979ac274617e))
|
|
12
|
+
|
|
7
13
|
## [0.11.0](https://github.com/rlueder/sci-ts/compare/v0.10.0...v0.11.0) (2026-10-02)
|
|
8
14
|
|
|
9
15
|
### Added
|
package/lib/996.sc
CHANGED
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
back 255 ; paper
|
|
18
18
|
border 0 ; a one-pixel border's colour; -1: none
|
|
19
19
|
frame -1 ; a frame view, or -1
|
|
20
|
-
margin 4
|
|
20
|
+
margin 4 ; between the text and the border or frame
|
|
21
|
+
portraitFrame -1 ; a view around portraits: loop 0 behind the face, loop 1 over its edges
|
|
22
|
+
portraitX 8 ; where a portrait's face goes on the left (mirrored on the right)
|
|
23
|
+
portraitY 8))
|
|
21
24
|
|
|
22
25
|
;; A box of text over the room: drawn by the interpreter into a bitmap, shown as a screen
|
|
23
26
|
;; item in the UI plane. Set text (and width, x, y), then init; it's as tall as the text
|
|
@@ -191,34 +194,80 @@
|
|
|
191
194
|
(super say: line &rest whoCares)))
|
|
192
195
|
|
|
193
196
|
;; Someone with a portrait: a view whose loop 0 is the bust, loop 1 the mouth and loop 2 the
|
|
194
|
-
;; eyes, every cel the same size and anchored at its top-left corner
|
|
195
|
-
;;
|
|
196
|
-
;;
|
|
197
|
-
;; the line is said the mouth moves, then closes; the eyes blink.
|
|
197
|
+
;; eyes, every cel the same size and anchored at its top-left corner; loops 3 to 5, if there
|
|
198
|
+
;; are any, are the same facing left. A room's talker is handed its parts (init: mouth bust
|
|
199
|
+
;; eyes frame, where frame is drawn as the bust); one with a view of its own (the hero's)
|
|
200
|
+
;; makes them. While the line is said the mouth moves, then closes; the eyes blink.
|
|
201
|
+
;;
|
|
202
|
+
;; The portrait goes at the top left facing right, or the top right facing left, with the
|
|
203
|
+
;; text beside it on the side towards the middle. A character takes the side of the hero
|
|
204
|
+
;; it stands on (who: is its body in the room; without one, the right); the hero takes the
|
|
205
|
+
;; side opposite whoever spoke last. The textStyle places it (portraitX, portraitY) and can
|
|
206
|
+
;; frame it (portraitFrame).
|
|
198
207
|
(class PortraitTalker of Talker
|
|
199
208
|
(properties
|
|
200
209
|
mouth 0 bust 0 eyes 0 frame 0
|
|
210
|
+
view -1 ; the portrait's view, for a talker that makes its own parts
|
|
211
|
+
who 0 ; the character's body in the room
|
|
212
|
+
side 0 ; where the portrait is: 0 the left, 1 the right
|
|
213
|
+
otherSide 1 ; the hero's: the side of whoever spoke last
|
|
214
|
+
back 0 front 0 ; the portraitFrame, behind the face and over its edges
|
|
201
215
|
priority 150
|
|
202
216
|
mouthFor 0) ; cycles the mouth moves for
|
|
203
217
|
|
|
204
218
|
(method (init theMouth theBust theEyes theFrame)
|
|
205
|
-
(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
(
|
|
213
|
-
|
|
214
|
-
(=
|
|
215
|
-
(=
|
|
216
|
-
|
|
219
|
+
(if argc
|
|
220
|
+
(= mouth theMouth)
|
|
221
|
+
(= bust theBust)
|
|
222
|
+
(= eyes theEyes)
|
|
223
|
+
(= frame theFrame)))
|
|
224
|
+
|
|
225
|
+
(method (makeParts)
|
|
226
|
+
(if (and (!= view -1) (not bust) (not frame))
|
|
227
|
+
(= bust ((View new:) view: view yourself:))
|
|
228
|
+
(= mouth ((Prop new:) view: view yourself:))
|
|
229
|
+
(= eyes ((Prop new:) view: view yourself:))))
|
|
230
|
+
|
|
231
|
+
;; This line's side: see above.
|
|
232
|
+
(method (pickSide &tmp s)
|
|
233
|
+
(if (== self heroTalker) (return (- 1 otherSide)))
|
|
234
|
+
(= s (if (and who ego (< (who x?) (ego x?))) 0 else 1))
|
|
235
|
+
(if (and heroTalker (!= heroTalker self) (heroTalker respondsTo: #otherSide)) (heroTalker otherSide: s))
|
|
236
|
+
(return s))
|
|
237
|
+
|
|
238
|
+
(method (say txt whoCares &tmp face l pw f fx fy over)
|
|
239
|
+
(self init: makeParts:)
|
|
240
|
+
(= face (if frame frame else bust))
|
|
241
|
+
(if face
|
|
242
|
+
(= side (self pickSide:))
|
|
243
|
+
(= l (if (and side (>= (NumLoops face) 6)) 3 else 0))
|
|
244
|
+
(= pw (CelWide (face view?) l 0))
|
|
245
|
+
(= f (textStyle portraitFrame?))
|
|
246
|
+
(= over (if (!= f -1) (/ (- (CelWide f 0 0) pw) 2) else 0))
|
|
247
|
+
(= fx (if side (- SCREEN_WIDTH (+ (textStyle portraitX?) pw)) else (textStyle portraitX?)))
|
|
248
|
+
(= fy (textStyle portraitY?))
|
|
249
|
+
(face x: fx y: fy loop: l cel: 0)
|
|
250
|
+
(if mouth (mouth x: fx y: fy loop: (+ l 1) cel: 0))
|
|
251
|
+
(if eyes (eyes x: fx y: fy loop: (+ l 2) cel: 0))
|
|
252
|
+
(if (!= f -1)
|
|
253
|
+
(if (not back) (= back ((View new:) view: f loop: 0 cel: 0 yourself:)))
|
|
254
|
+
(back x: fx y: fy)
|
|
255
|
+
(if (and (not front) (>= (NumLoops back) 2)) (= front ((View new:) view: f loop: 1 cel: 0 yourself:)))
|
|
256
|
+
(if front (front x: fx y: fy)))
|
|
257
|
+
;; The text beside it, towards the middle.
|
|
258
|
+
(= y fy)
|
|
259
|
+
(if side
|
|
260
|
+
(= x 6)
|
|
261
|
+
(= width (- fx (+ over 12)))
|
|
262
|
+
else
|
|
263
|
+
(= x (+ fx pw over 6))
|
|
264
|
+
(= width (- SCREEN_WIDTH (+ x 6)))))
|
|
217
265
|
(super say: txt &rest whoCares)
|
|
218
|
-
(self showPart:
|
|
219
|
-
(self showPart:
|
|
220
|
-
(self showPart: eyes (+ priority 1))
|
|
266
|
+
(self showPart: back (- priority 1))
|
|
267
|
+
(self showPart: face priority)
|
|
221
268
|
(self showPart: mouth (+ priority 1))
|
|
269
|
+
(self showPart: eyes (+ priority 1))
|
|
270
|
+
(self showPart: front (+ priority 2))
|
|
222
271
|
(if eyes (eyes setCycle: Blink))
|
|
223
272
|
(if mouth
|
|
224
273
|
(mouth setCycle: Forward)
|
|
@@ -236,11 +285,19 @@
|
|
|
236
285
|
(part init:)
|
|
237
286
|
(part plane: uiPlane setPri: pri)))
|
|
238
287
|
|
|
288
|
+
;; Off the screen, kept for the next line.
|
|
289
|
+
(method (hidePart part)
|
|
290
|
+
(if part
|
|
291
|
+
(DeleteScreenItem part)
|
|
292
|
+
(cast delete: part)))
|
|
293
|
+
|
|
239
294
|
(method (clear)
|
|
240
|
-
(
|
|
241
|
-
(
|
|
242
|
-
(
|
|
243
|
-
(
|
|
295
|
+
(self hidePart: front)
|
|
296
|
+
(self hidePart: back)
|
|
297
|
+
(self hidePart: frame)
|
|
298
|
+
(self hidePart: bust)
|
|
299
|
+
(self hidePart: eyes)
|
|
300
|
+
(self hidePart: mouth)
|
|
244
301
|
(super clear:)))
|
|
245
302
|
|
|
246
303
|
;; Says the lines of a message file for a noun, verb and condition, in sequence:
|
package/package.json
CHANGED
|
@@ -837,6 +837,8 @@ class RoomCompiler {
|
|
|
837
837
|
"&rest 1", `super ${p.class} 12`,
|
|
838
838
|
"pushi #setPri", "push1", "pTos priority", "ldi 1", "add", "push", `lofsa @${key}Mouth`, "send 6",
|
|
839
839
|
"pushi #setPri", "push1", "pTos priority", "ldi 1", "add", "push", `lofsa @${key}Eyes`, "send 6",
|
|
840
|
+
// Its body in the room, if a prop has its name: where it stands picks the portrait's side.
|
|
841
|
+
...(p.who && this.spec.props?.[key] ? send("self", [["who", [{ obj: key }]]]) : []),
|
|
840
842
|
"ret",
|
|
841
843
|
], "");
|
|
842
844
|
}
|
|
@@ -975,6 +975,8 @@ class RoomCompiler {
|
|
|
975
975
|
"&rest 1", `super ${p.class} 12`,
|
|
976
976
|
"pushi #setPri", "push1", "pTos priority", "ldi 1", "add", "push", `lofsa @${key}Mouth`, "send 6",
|
|
977
977
|
"pushi #setPri", "push1", "pTos priority", "ldi 1", "add", "push", `lofsa @${key}Eyes`, "send 6",
|
|
978
|
+
// Its body in the room, if a prop has its name: where it stands picks the portrait's side.
|
|
979
|
+
...(p.who && this.spec.props?.[key] ? send("self", [["who", [{ obj: key }]]]) : []),
|
|
978
980
|
"ret",
|
|
979
981
|
],
|
|
980
982
|
"",
|
|
@@ -40,7 +40,8 @@ export interface Target {
|
|
|
40
40
|
/**
|
|
41
41
|
* A character with a portrait view: loop 0 the bust, loop 1 mouth shapes, loop 2 eyes
|
|
42
42
|
* (cel 0 open), all cels the same size so the parts line up. The talker class gets
|
|
43
|
-
* `init: mouth bust eyes frame`; parts are a View (bust) and Props at `at`.
|
|
43
|
+
* `init: mouth bust eyes frame`; parts are a View (bust) and Props at `at`. With `who`,
|
|
44
|
+
* the talker is also told the character's prop in the room, if it has one (`who:`).
|
|
44
45
|
*/
|
|
45
46
|
portrait: {
|
|
46
47
|
class: string;
|
|
@@ -48,6 +49,7 @@ export interface Target {
|
|
|
48
49
|
at: [number, number];
|
|
49
50
|
frameSignal: number;
|
|
50
51
|
partSignal: number;
|
|
52
|
+
who?: boolean;
|
|
51
53
|
};
|
|
52
54
|
/**
|
|
53
55
|
* Conversations: an instance of this class runs a menu of topics for a thing (e.g. a
|
|
@@ -37,9 +37,10 @@ export interface Target {
|
|
|
37
37
|
/**
|
|
38
38
|
* A character with a portrait view: loop 0 the bust, loop 1 mouth shapes, loop 2 eyes
|
|
39
39
|
* (cel 0 open), all cels the same size so the parts line up. The talker class gets
|
|
40
|
-
* `init: mouth bust eyes frame`; parts are a View (bust) and Props at `at`.
|
|
40
|
+
* `init: mouth bust eyes frame`; parts are a View (bust) and Props at `at`. With `who`,
|
|
41
|
+
* the talker is also told the character's prop in the room, if it has one (`who:`).
|
|
41
42
|
*/
|
|
42
|
-
portrait: { class: string; props: Record<string, number>; at: [number, number]; frameSignal: number; partSignal: number };
|
|
43
|
+
portrait: { class: string; props: Record<string, number>; at: [number, number]; frameSignal: number; partSignal: number; who?: boolean };
|
|
43
44
|
/**
|
|
44
45
|
* Conversations: an instance of this class runs a menu of topics for a thing (e.g. a
|
|
45
46
|
* Teller with `init: client modNum sayNoun verb rootNoun`; topic labels are messages at
|
package/tools/game/target.js
CHANGED
|
@@ -31,8 +31,8 @@ export function libraryTarget(globals, items = {}) {
|
|
|
31
31
|
heroTalker: 98,
|
|
32
32
|
firstRoomTalker: 200,
|
|
33
33
|
voice: { class: "Talker", props: {} },
|
|
34
|
-
// Portraits stand at the top left
|
|
35
|
-
portrait: { class: "PortraitTalker", props: {}, at: [8, 8], frameSignal: 0, partSignal: 0 },
|
|
34
|
+
// Portraits stand at the top, left or right by where the character is (who:).
|
|
35
|
+
portrait: { class: "PortraitTalker", props: {}, at: [8, 8], frameSignal: 0, partSignal: 0, who: true },
|
|
36
36
|
teller: { class: "Teller", props: {}, verb: 2 },
|
|
37
37
|
forwardCycle: "Forward",
|
|
38
38
|
closeUp: "CloseUp",
|
package/tools/game/target.ts
CHANGED
|
@@ -33,8 +33,8 @@ export function libraryTarget(globals: readonly string[], items: Record<string,
|
|
|
33
33
|
heroTalker: 98,
|
|
34
34
|
firstRoomTalker: 200,
|
|
35
35
|
voice: { class: "Talker", props: {} },
|
|
36
|
-
// Portraits stand at the top left
|
|
37
|
-
portrait: { class: "PortraitTalker", props: {}, at: [8, 8], frameSignal: 0, partSignal: 0 },
|
|
36
|
+
// Portraits stand at the top, left or right by where the character is (who:).
|
|
37
|
+
portrait: { class: "PortraitTalker", props: {}, at: [8, 8], frameSignal: 0, partSignal: 0, who: true },
|
|
38
38
|
teller: { class: "Teller", props: {}, verb: 2 },
|
|
39
39
|
forwardCycle: "Forward",
|
|
40
40
|
closeUp: "CloseUp",
|