sci2-ts 0.8.1 → 0.8.2

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 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.8.2](https://github.com/rlueder/sci-ts/compare/v0.8.1...v0.8.2) (2026-10-02)
8
+
9
+ ### Fixed
10
+
11
+ * **lib:** actors walk past each other and are clicked only where they're drawn ([#10](https://github.com/rlueder/sci-ts/issues/10)) ([99deb4a](https://github.com/rlueder/sci-ts/commit/99deb4a1e63bb5170ab0742942041ce3fde1801d))
12
+
7
13
  ## [0.8.1](https://github.com/rlueder/sci-ts/compare/v0.8.0...v0.8.1) (2026-10-02)
8
14
 
9
15
  ### Fixed
package/lib/998.sc CHANGED
@@ -208,10 +208,13 @@
208
208
  (curRoom doVerb: verb))))
209
209
 
210
210
  ;; A Feature drawn with a view: a screen item in the room's plane. One that's only there to
211
- ;; look at (rain on a window, a sky) has clickable 0, and clicks go to what's behind it.
211
+ ;; look at (rain on a window, a sky) has clickable 0, and clicks go to what's behind it. With
212
+ ;; checkPixels, it's hit only where it's drawn, not anywhere in its cel (Actors: people are
213
+ ;; often drawn on canvases much wider than they are).
212
214
  (class View of Feature
213
215
  (properties
214
216
  clickable 1
217
+ checkPixels 0
215
218
  view -1 loop 0 cel 0
216
219
  z 0
217
220
  priority 0 fixPriority 0
@@ -232,7 +235,7 @@
232
235
  (if (not (& signal SIG_HIDDEN)) (UpdateScreenItem self)))
233
236
 
234
237
  (method (onMe theX theY)
235
- (return (and clickable (not (& signal SIG_HIDDEN)) (IsOnMe theX theY self))))
238
+ (return (and clickable (not (& signal SIG_HIDDEN)) (IsOnMe theX theY self checkPixels))))
236
239
 
237
240
  (method (hide)
238
241
  (|= signal SIG_HIDDEN)
@@ -315,9 +318,13 @@
315
318
  (if script (script dispose:))
316
319
  (super dispose:)))
317
320
 
318
- ;; A Prop that moves (a mover), facing where it goes.
321
+ ;; A Prop that moves (a mover), facing where it goes. Actors walk through each other unless
322
+ ;; ignoreActors is 0: the interpreter measures an actor by its whole cel, and characters are
323
+ ;; often drawn on canvases much wider than they are, so blocking would stop them far apart.
319
324
  (class Actor of Prop
320
325
  (properties
326
+ ignoreActors 1
327
+ checkPixels 1
321
328
  mover 0
322
329
  moveSpeed 2 ; cycles between steps
323
330
  heading 0
@@ -359,6 +366,7 @@
359
366
 
360
367
  ;; Whether another actor is in the way (DoBresen asks).
361
368
  (method (cantBeHere)
369
+ (if ignoreActors (return 0))
362
370
  (return (CantBeHere self (cast elements?))))
363
371
 
364
372
  (method (dispose)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sci2-ts",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "An SCI2 adventure game engine in TypeScript, and the tools to make games with it",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -409,14 +409,22 @@ export const graphicsKernels = {
409
409
  vm.setProp(obj, "brBottom", fromInt(bottom));
410
410
  vm.setProp(obj, "brTop", fromInt(bottom - g.prop(obj, "yStep")));
411
411
  },
412
- IsOnMe: (vm, [x = 0, y = 0, obj = 0]) => {
412
+ // IsOnMe(x, y, obj, checkPixels): with checkPixels, only where the cel isn't transparent.
413
+ IsOnMe: (vm, [x = 0, y = 0, obj = 0, checkPixels = 0]) => {
413
414
  const g = graphics(vm);
414
415
  const px = toSigned(x), py = toSigned(y);
415
416
  // Like SSCI, a screen item is hit where its cel is actually drawn (scaled, current
416
417
  // position): its ns* props can be stale, since only SetNowSeen updates them.
417
418
  const r = g.items.has(obj) ? g.viewRect(obj) : undefined;
418
- if (r)
419
- return bool(px >= r.x && px < r.x + r.width && py >= r.y && py < r.y + r.height);
419
+ if (r) {
420
+ if (!(px >= r.x && px < r.x + r.width && py >= r.y && py < r.y + r.height))
421
+ return 0;
422
+ if (!checkPixels)
423
+ return 1;
424
+ const cx = Math.min(r.cel.width - 1, Math.floor((px - r.x) / r.sx));
425
+ const cy = Math.min(r.cel.height - 1, Math.floor((py - r.y) / r.sy));
426
+ return bool(r.cel.pixels[cy * r.cel.width + (r.mirror ? r.cel.width - 1 - cx : cx)] !== r.cel.skipColor);
427
+ }
420
428
  return bool(px >= g.prop(obj, "nsLeft") && px <= g.prop(obj, "nsRight") && py >= g.prop(obj, "nsTop") && py <= g.prop(obj, "nsBottom"));
421
429
  },
422
430
  IsHiRes: () => 0,
@@ -448,13 +448,20 @@ export const graphicsKernels: Record<string, KernelFn> = {
448
448
  vm.setProp(obj, "brBottom", fromInt(bottom));
449
449
  vm.setProp(obj, "brTop", fromInt(bottom - g.prop(obj, "yStep")));
450
450
  },
451
- IsOnMe: (vm, [x = 0, y = 0, obj = 0]) => {
451
+ // IsOnMe(x, y, obj, checkPixels): with checkPixels, only where the cel isn't transparent.
452
+ IsOnMe: (vm, [x = 0, y = 0, obj = 0, checkPixels = 0]) => {
452
453
  const g = graphics(vm);
453
454
  const px = toSigned(x), py = toSigned(y);
454
455
  // Like SSCI, a screen item is hit where its cel is actually drawn (scaled, current
455
456
  // position): its ns* props can be stale, since only SetNowSeen updates them.
456
457
  const r = g.items.has(obj) ? g.viewRect(obj) : undefined;
457
- if (r) return bool(px >= r.x && px < r.x + r.width && py >= r.y && py < r.y + r.height);
458
+ if (r) {
459
+ if (!(px >= r.x && px < r.x + r.width && py >= r.y && py < r.y + r.height)) return 0;
460
+ if (!checkPixels) return 1;
461
+ const cx = Math.min(r.cel.width - 1, Math.floor((px - r.x) / r.sx));
462
+ const cy = Math.min(r.cel.height - 1, Math.floor((py - r.y) / r.sy));
463
+ return bool(r.cel.pixels[cy * r.cel.width + (r.mirror ? r.cel.width - 1 - cx : cx)] !== r.cel.skipColor);
464
+ }
458
465
  return bool(px >= g.prop(obj, "nsLeft") && px <= g.prop(obj, "nsRight") && py >= g.prop(obj, "nsTop") && py <= g.prop(obj, "nsBottom"));
459
466
  },
460
467
  IsHiRes: () => 0,