incanto 0.72.0 → 0.74.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/bin/incanto-check.mjs +114 -42
- package/bin/incanto-verify.mjs +9 -2
- package/dist/2d.d.ts +29 -4
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +137 -15
- package/dist/3d.js +6 -6
- package/dist/{agent8-BqZ0_O1u.js → agent8-CHTT4unP.js} +1 -1
- package/dist/{audio-player-ioZ7VKC6.d.ts → audio-player-BOrk4eQx.d.ts} +1 -1
- package/dist/{behavior-Bf9P9oB2.d.ts → behavior-J1cmVah0.d.ts} +8 -0
- package/dist/{create-game-CmFAtLZp.js → create-game-BAiA-FjP.js} +7 -7
- package/dist/{create-game-C9rWqqAC.js → create-game-ssvGvP7W.js} +7 -7
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +1 -1
- package/dist/editor.js +965 -893
- package/dist/{environment-presets-BeHoaGhy.js → environment-presets-BkqlWewf.js} +277 -60
- package/dist/{gameplay-BlQe-M07.js → gameplay-Bxe1sMVT.js} +611 -39
- package/dist/gameplay.d.ts +141 -7
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +6 -4
- package/dist/index.js +6 -6
- package/dist/{loader-CBfQzB6S.d.ts → loader-BAeWMYfF.d.ts} +1 -1
- package/dist/net.d.ts +2 -2
- package/dist/net.js +2 -2
- package/dist/{physics-2d-DrIgTlLk.js → physics-2d-C-SfvjzH.js} +94 -11
- package/dist/{physics-3d-BzOCw1VS.js → physics-3d-rOzeg890.js} +202 -15
- package/dist/{picking-C9McVJrO.js → picking-BMV34Pjl.js} +2 -2
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-5IYfooAN.js → register-CjociOtt.js} +19 -4
- package/dist/{register-C8HuRkOf.js → register-DRQyZKGU.js} +45 -9
- package/dist/{replay-datiAE-b.js → replay-B6BbgGM_.js} +42 -6
- package/dist/{replay-CBEChqXq.d.ts → replay-wZK5Ok5c.d.ts} +1 -1
- package/dist/{save-slots-CEuJPUle.js → save-slots-CEUGeLuB.js} +11 -2
- package/dist/{split-screen-Bm5DTElG.js → split-screen-BxZ5rBe7.js} +4 -4
- package/dist/{split-screen-DkqLng6q.d.ts → split-screen-D6sx8z3Z.d.ts} +2 -2
- package/dist/{sprite-animation-CqR2o3SA.js → sprite-animation-Bz3DHD_4.js} +1 -1
- package/dist/{src-DRSsRleD.js → src-CqtvYtSN.js} +1 -1
- package/dist/{test-Djuq3Vhq.js → test-CEl0y2Sw.js} +162 -30
- package/dist/test.d.ts +56 -5
- package/dist/test.js +2 -2
- package/dist/{touch-BnCyPA0G.js → touch-CioTZB-y.js} +1 -1
- package/dist/vite.js +3 -3
- package/editor/assets/{agent8-CMKz2cax.js → agent8-BlzturGi.js} +1 -1
- package/editor/assets/{debug-DLrQm-az.js → debug-BMUi8usj.js} +1 -1
- package/editor/assets/{index-BEKuxYcE.js → index-CrUCQoaB.js} +53 -53
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +634 -10
- package/skills/incanto-3d-character.md +113 -5
- package/skills/incanto-assets.md +9 -3
- package/skills/incanto-behaviors-and-scripts.md +26 -2
- package/skills/incanto-building-2d-games.md +9 -0
- package/skills/incanto-building-3d-games.md +45 -0
- package/skills/incanto-editor.md +6 -1
- package/skills/incanto-environment.md +7 -2
- package/skills/incanto-game-feel.md +16 -11
- package/skills/incanto-gameplay-behaviors.md +179 -16
- package/skills/incanto-node-reference.md +124 -45
- package/skills/incanto-physics-and-input.md +67 -5
- package/skills/incanto-scene-json-authoring.md +9 -3
- package/skills/incanto-verifying-your-game.md +19 -2
- package/templates-app/beacon-isle-3d/PROJECT/Status.md +8 -0
- package/templates-app/beacon-isle-3d/PROJECT/Structure.md +3 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +136 -0
- package/templates-app/beacon-isle-3d/verify.ts +144 -0
- package/templates-app/molehill-2d/package.json +1 -1
- package/templates-app/platformer-2d/PROJECT/Status.md +7 -0
- package/templates-app/platformer-2d/PROJECT/Structure.md +3 -0
- package/templates-app/platformer-2d/package.json +1 -1
- package/templates-app/platformer-2d/src/game.scene.json +126 -0
- package/templates-app/platformer-2d/verify.ts +54 -0
- package/templates-app/star-survivor/package.json +1 -1
- package/templates-app/tps-3d/PROJECT/Context.md +1 -1
- package/templates-app/tps-3d/PROJECT/Status.md +40 -1
- package/templates-app/tps-3d/PROJECT/Structure.md +19 -0
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/behaviors.ts +9 -0
- package/templates-app/tps-3d/src/cover.scene.json +26 -0
- package/templates-app/tps-3d/src/game.scene.json +331 -75
- package/templates-app/tps-3d/src/main.ts +14 -0
- package/templates-app/tps-3d/src/pillar.scene.json +25 -0
- package/templates-app/tps-3d/verify.ts +582 -3
- package/templates-app/village-quest-3d/package.json +1 -1
package/dist/gameplay.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-
|
|
1
|
+
import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-J1cmVah0.js";
|
|
2
2
|
import { c as JsonValue, s as JsonObject } from "./rng-Bb-IutXB.js";
|
|
3
3
|
|
|
4
4
|
//#region src/gameplay/chase.d.ts
|
|
@@ -23,15 +23,39 @@ declare class Chase extends Behavior {
|
|
|
23
23
|
static readonly props: PropSchema;
|
|
24
24
|
static readonly signals: readonly string[];
|
|
25
25
|
target: string;
|
|
26
|
+
targetGroup: string;
|
|
27
|
+
retargetEvery: number;
|
|
26
28
|
speed: number;
|
|
29
|
+
/** The group member currently chased (`targetGroup`), or null. */
|
|
30
|
+
private picked;
|
|
31
|
+
private sincePick;
|
|
27
32
|
stopRange: number;
|
|
28
33
|
loseRange: number;
|
|
29
34
|
moveParent: boolean;
|
|
35
|
+
ground: boolean | null;
|
|
30
36
|
facePath: string;
|
|
37
|
+
/** Signed fall speed accumulated while a ground chaser is off the floor. */
|
|
38
|
+
private fall;
|
|
31
39
|
turnSpeed: number;
|
|
32
40
|
private inRange;
|
|
33
41
|
private lost;
|
|
34
42
|
override onReady(): void;
|
|
43
|
+
/**
|
|
44
|
+
* A walker falls off what it walks off. `CharacterBody3D` applies no gravity
|
|
45
|
+
* of its own ("integrate velocity yourself"), and a chaser that ignores the
|
|
46
|
+
* target's height would otherwise walk off a ledge and keep its altitude —
|
|
47
|
+
* measured on tps-3d's 0.6 m Ramp, where the old chase glided down over five
|
|
48
|
+
* seconds only because the player happened to stand lower. Scene gravity
|
|
49
|
+
* (default 9.81), accumulated while `isOnFloor()` says no, reset when it says
|
|
50
|
+
* yes; the KCC's snap-to-ground handles the last 10 cm.
|
|
51
|
+
*/
|
|
52
|
+
private fallStep;
|
|
53
|
+
/** Off the floor with nowhere to chase: still fall. */
|
|
54
|
+
private dropIfAirborne;
|
|
55
|
+
/** The nearest live member of `targetGroup` — re-picked every `retargetEvery` seconds, never the mover itself. */
|
|
56
|
+
private nearestOfGroup;
|
|
57
|
+
/** See `ground`: an explicit answer, else "is the mover a 3D kinematic capsule". */
|
|
58
|
+
private walksTheGround;
|
|
35
59
|
override update(dt: number): void;
|
|
36
60
|
}
|
|
37
61
|
//#endregion
|
|
@@ -142,6 +166,14 @@ declare class Health extends Behavior {
|
|
|
142
166
|
override update(dt: number): void;
|
|
143
167
|
/** Apply `n` damage. No-op while invulnerable or already dead. Emits `damaged`. */
|
|
144
168
|
damage(n: number): void;
|
|
169
|
+
/**
|
|
170
|
+
* Be immune for `seconds` from NOW — a dodge roll, a spawn, a cutscene.
|
|
171
|
+
*
|
|
172
|
+
* `invulnerableFor` grants i-frames only AFTER a hit; this is the window
|
|
173
|
+
* before one. It extends a window already open and never shortens it, so a
|
|
174
|
+
* second dodge mid-window cannot expose you. Dead or not, it is harmless.
|
|
175
|
+
*/
|
|
176
|
+
protect(seconds: number): void;
|
|
145
177
|
/** Restore `n` hit points (clamped to `max`). No-op when dead. Emits `healed`. */
|
|
146
178
|
heal(n: number): void;
|
|
147
179
|
/**
|
|
@@ -231,8 +263,10 @@ declare class Health extends Behavior {
|
|
|
231
263
|
* whose Health-owner node is in that group takes damage. This is how you stop
|
|
232
264
|
* enemies killing each other — give the player's weapon `targetGroup:'enemy'`
|
|
233
265
|
* and each enemy's contact hitbox `targetGroup:'player'`.
|
|
234
|
-
* - `oncePerTarget` (default) prevents re-hitting the same node
|
|
235
|
-
* hazard would otherwise drain a resting body every
|
|
266
|
+
* - `oncePerTarget` (default) prevents re-hitting the same node WHILE it stays
|
|
267
|
+
* in contact (a stationary hazard would otherwise drain a resting body every
|
|
268
|
+
* frame). It is per overlap, not per lifetime: leave and come back, or disarm
|
|
269
|
+
* the hitbox and arm it again over the same foe, and the hit lands again.
|
|
236
270
|
* - `repeatEvery` (seconds, 0 = off) re-damages targets that STAY overlapped —
|
|
237
271
|
* lava pools, poison clouds, an enemy standing on you. Contact events fire
|
|
238
272
|
* only on entry/exit; this is the "and it keeps hurting" knob.
|
|
@@ -344,9 +378,20 @@ declare class Interactable extends Behavior {
|
|
|
344
378
|
action: string;
|
|
345
379
|
range: number;
|
|
346
380
|
actorGroup: string;
|
|
381
|
+
prompt: string;
|
|
382
|
+
focus: "any" | "nearest" | "facing";
|
|
383
|
+
coneDeg: number;
|
|
384
|
+
/**
|
|
385
|
+
* The actor this Interactable would answer RIGHT NOW, or null — updated every
|
|
386
|
+
* frame, with `focused(actor)` / `unfocused(actor)` on the edges. A HUD reads
|
|
387
|
+
* the focused one's `prompt`.
|
|
388
|
+
*/
|
|
389
|
+
focusedBy: Node | null;
|
|
347
390
|
/** Actions already reported missing, so a per-frame read says it once. */
|
|
348
391
|
private readonly reportedActions;
|
|
349
392
|
override update(): void;
|
|
393
|
+
/** Is THIS the Interactable `actor` means — the nearest (that it faces) of every one in reach? */
|
|
394
|
+
private claims;
|
|
350
395
|
}
|
|
351
396
|
//#endregion
|
|
352
397
|
//#region src/gameplay/lifetime.d.ts
|
|
@@ -725,6 +770,13 @@ declare class ScoreKeeper extends Behavior {
|
|
|
725
770
|
scoreToWin: number;
|
|
726
771
|
private hasWon;
|
|
727
772
|
private hasLost;
|
|
773
|
+
/**
|
|
774
|
+
* Whether the run is over — readable, not only heard. A stealth yard's HUD
|
|
775
|
+
* and a melee arena's both read `score.won` for their banner and got
|
|
776
|
+
* `undefined`, silently, because only the signals were public.
|
|
777
|
+
*/
|
|
778
|
+
get won(): boolean;
|
|
779
|
+
get lost(): boolean;
|
|
728
780
|
override onReady(): void;
|
|
729
781
|
/** Add `n` to the score (negative subtracts), emit `scoreChanged`, check win. */
|
|
730
782
|
addScore(n: number): void;
|
|
@@ -769,6 +821,7 @@ declare class Spawner extends Behavior {
|
|
|
769
821
|
at: number[];
|
|
770
822
|
autoStart: boolean;
|
|
771
823
|
total: number;
|
|
824
|
+
into: string;
|
|
772
825
|
private readonly source;
|
|
773
826
|
private template;
|
|
774
827
|
private readonly live;
|
|
@@ -839,6 +892,10 @@ declare class WaveSpawner extends Behavior {
|
|
|
839
892
|
private parsed;
|
|
840
893
|
private readonly live;
|
|
841
894
|
private waveIndex;
|
|
895
|
+
/** The wave now running or being cleared, 1-based — what a HUD prints as `wave 2 / 5`. `0` before the first. */
|
|
896
|
+
get wave(): number;
|
|
897
|
+
/** How many waves were declared. */
|
|
898
|
+
get waveCount(): number;
|
|
842
899
|
private phase;
|
|
843
900
|
private timer;
|
|
844
901
|
private spawnedThisWave;
|
|
@@ -926,6 +983,33 @@ declare class ZombieAI extends Behavior {
|
|
|
926
983
|
private pickGoal;
|
|
927
984
|
}
|
|
928
985
|
//#endregion
|
|
986
|
+
//#region src/gameplay/checkpoint.d.ts
|
|
987
|
+
/**
|
|
988
|
+
* A checkpoint: touch it and a `Respawn` puts you back HERE from now on.
|
|
989
|
+
*
|
|
990
|
+
* Sits on an `Area2D`/`Area3D` (listens to `triggerEnter`). `respawn` names the
|
|
991
|
+
* `Respawn` node whose `to` becomes this checkpoint's world position, less
|
|
992
|
+
* `dropBelow` so the character lands ON the flag rather than inside it.
|
|
993
|
+
* `group` gates who can light it; `once` (default) lights it a single time.
|
|
994
|
+
* Emits `activated(other)`.
|
|
995
|
+
*
|
|
996
|
+
* Built after a platformer built from the tarball wrote exactly this in nine
|
|
997
|
+
* lines — the ninth being the one that found `Respawn.to` was read once at
|
|
998
|
+
* ready. A checkpoint is the second most common thing a platformer has, and it
|
|
999
|
+
* should be one node with two props, not a behaviour every game rewrites.
|
|
1000
|
+
*/
|
|
1001
|
+
declare class Checkpoint extends Behavior {
|
|
1002
|
+
static readonly props: PropSchema;
|
|
1003
|
+
static readonly signals: readonly string[];
|
|
1004
|
+
respawn: string;
|
|
1005
|
+
group: string;
|
|
1006
|
+
once: boolean;
|
|
1007
|
+
dropBelow: number;
|
|
1008
|
+
/** True after the first activation. */
|
|
1009
|
+
lit: boolean;
|
|
1010
|
+
override onReady(): void;
|
|
1011
|
+
}
|
|
1012
|
+
//#endregion
|
|
929
1013
|
//#region src/gameplay/day-night.d.ts
|
|
930
1014
|
/**
|
|
931
1015
|
* A live day/night cycle — drives the scene's `environment` (sun elevation +
|
|
@@ -1250,12 +1334,13 @@ declare function hitStop(engine: Engine, seconds?: number): void;
|
|
|
1250
1334
|
*/
|
|
1251
1335
|
declare class PathFollow extends Behavior {
|
|
1252
1336
|
static readonly signals: readonly string[];
|
|
1253
|
-
static readonly props:
|
|
1254
|
-
default: number | boolean;
|
|
1255
|
-
}>;
|
|
1337
|
+
static readonly props: PropSchema;
|
|
1256
1338
|
/** Units per second (px in 2D, meters in 3D). */
|
|
1257
1339
|
speed: number;
|
|
1258
1340
|
loop: boolean;
|
|
1341
|
+
moveParent: boolean;
|
|
1342
|
+
facePath: string;
|
|
1343
|
+
turnSpeed: number;
|
|
1259
1344
|
private waypoints;
|
|
1260
1345
|
private index;
|
|
1261
1346
|
/** True while there is somewhere left to go. */
|
|
@@ -1264,6 +1349,10 @@ declare class PathFollow extends Behavior {
|
|
|
1264
1349
|
/** Stop in place (keeps the node where it is). */
|
|
1265
1350
|
stop(): void;
|
|
1266
1351
|
override update(dt: number): void;
|
|
1352
|
+
/** `facePath` turns toward where this frame went — nothing when it did not move. */
|
|
1353
|
+
private face;
|
|
1354
|
+
/** The node this walks: the parent under `moveParent`, else this one — both must be spatial. */
|
|
1355
|
+
private mover;
|
|
1267
1356
|
}
|
|
1268
1357
|
//#endregion
|
|
1269
1358
|
//#region src/gameplay/prefab-shelf.d.ts
|
|
@@ -1363,6 +1452,51 @@ declare function worldPosition(node: Node): number[];
|
|
|
1363
1452
|
*/
|
|
1364
1453
|
declare function localFromWorld(node: Node, world: readonly number[]): number[];
|
|
1365
1454
|
//#endregion
|
|
1455
|
+
//#region src/gameplay/turret.d.ts
|
|
1456
|
+
/**
|
|
1457
|
+
* The oldest verb in games: pick the nearest live member of `targetGroup`
|
|
1458
|
+
* within `range` and hit it every `cooldown` — a defense tower, a ship's gun,
|
|
1459
|
+
* a sentry, a trooper who fights what he meets.
|
|
1460
|
+
*
|
|
1461
|
+
* Two games in a row wrote these forty lines before it existed (an RTS's
|
|
1462
|
+
* trooper, a tower defense's tower): the engine had `Chase` for going TO a
|
|
1463
|
+
* target and `Projectile` for the bullet, and nothing that decides to shoot.
|
|
1464
|
+
*
|
|
1465
|
+
* - **Hitscan** by default: the target's `Health` (on it or a child, as
|
|
1466
|
+
* `DamageOnContact` finds it) takes `damage(n)`.
|
|
1467
|
+
* - **Or a clone**: name a `shelf` (a `PrefabShelf`) and a `prefab` on it; each
|
|
1468
|
+
* shot takes one, puts it at the turret plus `muzzle`, points its
|
|
1469
|
+
* `Projectile` at the target and adds it under `into` (the turret's parent
|
|
1470
|
+
* when empty). The clone does the hurting then — give it `DamageOnContact`.
|
|
1471
|
+
* - `facePath` turns a barrel toward the target at `turnSpeed`.
|
|
1472
|
+
*
|
|
1473
|
+
* Signals: `acquired(target)` when something comes in range, `fired(target)`
|
|
1474
|
+
* per shot, `lost()` when nothing live is in range any more.
|
|
1475
|
+
*/
|
|
1476
|
+
declare class Turret extends Behavior {
|
|
1477
|
+
static readonly props: PropSchema;
|
|
1478
|
+
static readonly signals: readonly string[];
|
|
1479
|
+
targetGroup: string;
|
|
1480
|
+
range: number;
|
|
1481
|
+
damage: number;
|
|
1482
|
+
cooldown: number;
|
|
1483
|
+
shelf: string;
|
|
1484
|
+
prefab: string;
|
|
1485
|
+
muzzle: number[];
|
|
1486
|
+
into: string;
|
|
1487
|
+
facePath: string;
|
|
1488
|
+
turnSpeed: number;
|
|
1489
|
+
/** What it is shooting at right now, or null. */
|
|
1490
|
+
target: Node | null;
|
|
1491
|
+
/** Shots fired so far. */
|
|
1492
|
+
shots: number;
|
|
1493
|
+
private wait;
|
|
1494
|
+
override onReady(): void;
|
|
1495
|
+
override update(dt: number): void;
|
|
1496
|
+
/** One clone from the shelf, at the muzzle, aimed at the target, into the container. */
|
|
1497
|
+
private launch;
|
|
1498
|
+
}
|
|
1499
|
+
//#endregion
|
|
1366
1500
|
//#region src/gameplay/index.d.ts
|
|
1367
1501
|
/** Every built-in gameplay behavior, keyed by its registration name. */
|
|
1368
1502
|
declare const GAMEPLAY_BEHAVIORS: Readonly<Record<string, BehaviorCtor>>;
|
|
@@ -1375,4 +1509,4 @@ declare function registerGameplayBehaviors(opts?: {
|
|
|
1375
1509
|
replace?: boolean;
|
|
1376
1510
|
}): void;
|
|
1377
1511
|
//#endregion
|
|
1378
|
-
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
|
1512
|
+
export { CameraShake, Chase, Checkpoint, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Turret, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
package/dist/gameplay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
|
1
|
+
import { $ as localFromWorld, A as FaceTarget, C as GameFlow, D as FollowCamera, F as Currency, I as Collector, L as Checkpoint, M as phaseOf, N as DamageOnContact, P as Health, R as Chase, S as Interactable, T as restartScene, _ as Lifetime, a as Wander, b as hitStop, c as ScoreKeeper, d as PrefabShelf, et as worldPosition, f as Pickup, g as MoveTo, h as Oscillate, i as WaveSpawner, j as DayNight, k as FloatAway, l as SavePoint, m as PathFollow, n as registerGameplayBehaviors, o as Turret, p as Patrol, r as ZombieAI, s as Spawner, t as GAMEPLAY_BEHAVIORS, u as Projectile, v as CameraShake, w as goToScene, x as screenFlash, y as Cooldown } from "./gameplay-Bxe1sMVT.js";
|
|
2
|
+
export { CameraShake, Chase, Checkpoint, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Turret, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-
|
|
2
|
-
import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-
|
|
1
|
+
import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-BOrk4eQx.js";
|
|
2
|
+
import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-J1cmVah0.js";
|
|
3
3
|
import { a as SceneJson, c as JsonValue, d as jsonKind, i as SCENE_FORMAT, l as jsonClone, n as ConnectionJson, o as JsonKind, r as NodeJson, s as JsonObject, t as Rng, u as jsonEquals } from "./rng-Bb-IutXB.js";
|
|
4
|
-
import { n as loadScene, t as LoadSceneOptions } from "./loader-
|
|
4
|
+
import { n as loadScene, t as LoadSceneOptions } from "./loader-BAeWMYfF.js";
|
|
5
5
|
import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
|
|
6
6
|
import { i as gridFromRows, n as PathGrid, r as findPath, t as FindPathOptions } from "./pathfinding-_fGrCFmH.js";
|
|
7
|
-
import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-
|
|
7
|
+
import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-wZK5Ok5c.js";
|
|
8
8
|
|
|
9
9
|
//#region src/core/audio/crossfade.d.ts
|
|
10
10
|
/**
|
|
@@ -879,6 +879,8 @@ declare class Timer extends Node {
|
|
|
879
879
|
autostart: boolean;
|
|
880
880
|
running: boolean;
|
|
881
881
|
private remaining;
|
|
882
|
+
/** Seconds until the next `timeout` — a countdown a HUD can draw. `0` when stopped. */
|
|
883
|
+
get timeLeft(): number;
|
|
882
884
|
start(time?: number): void;
|
|
883
885
|
stop(): void;
|
|
884
886
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
|
|
2
|
-
import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-
|
|
3
|
-
import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-
|
|
2
|
+
import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-CEUGeLuB.js";
|
|
3
|
+
import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-CjociOtt.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
5
|
import { t as Rng } from "./rng-CDOMybym.js";
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
6
|
+
import { n as startRecording, r as auditScene, t as replay } from "./replay-B6BbgGM_.js";
|
|
7
|
+
import { c as getNodeSchema, f as mergeStaticSignals, i as joystickVector, l as getNodeSignals, m as registeredTypes, n as attachTouchControls, o as clearRegistry, p as registerNode, s as createNode, t as TouchControls, u as getNodeType } from "./touch-CioTZB-y.js";
|
|
8
8
|
import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
|
|
9
9
|
import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
|
|
10
10
|
import { t as createNoise2D } from "./noise-D3nPpmFg.js";
|
|
11
|
-
import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-
|
|
12
|
-
import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-
|
|
11
|
+
import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-Bz3DHD_4.js";
|
|
12
|
+
import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-CqtvYtSN.js";
|
|
13
13
|
export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, EffectLog, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Respawn, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, isWebGLAvailable, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadSceneAssets, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, sfxDuration, showBootFailure, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
package/dist/net.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as PropSchema, jt as Node } from "./behavior-
|
|
1
|
+
import { d as PropSchema, jt as Node } from "./behavior-J1cmVah0.js";
|
|
2
2
|
import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
|
|
3
|
-
import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-
|
|
3
|
+
import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-D6sx8z3Z.js";
|
|
4
4
|
|
|
5
5
|
//#region src/net/agent8.d.ts
|
|
6
6
|
/**
|
package/dist/net.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as createAgent8Server } from "./agent8-
|
|
2
|
-
import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-
|
|
1
|
+
import { n as createAgent8Server } from "./agent8-CHTT4unP.js";
|
|
2
|
+
import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-BxZ5rBe7.js";
|
|
3
3
|
export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as __exportAll } from "./json-CfTjpvW8.js";
|
|
2
|
-
import { Y as diagnose } from "./save-slots-
|
|
2
|
+
import { Y as diagnose } from "./save-slots-CEUGeLuB.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
|
-
import { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, y as Node2D } from "./register-
|
|
4
|
+
import { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, v as StaticBody2D, y as Node2D } from "./register-DRQyZKGU.js";
|
|
5
5
|
import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
|
|
6
6
|
import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
|
|
7
7
|
//#region src/2d/physics/physics-2d.ts
|
|
@@ -122,6 +122,7 @@ var Physics2D = class {
|
|
|
122
122
|
const b = this.byColliderHandle.get(h2);
|
|
123
123
|
if (!a || !b) return;
|
|
124
124
|
const sig = started ? "triggerEnter" : "triggerExit";
|
|
125
|
+
if (started === (this.overlaps.get(a)?.has(b) ?? false)) return;
|
|
125
126
|
this.trackOverlap(a, b, started);
|
|
126
127
|
this.trackOverlap(b, a, started);
|
|
127
128
|
try {
|
|
@@ -185,7 +186,8 @@ var Physics2D = class {
|
|
|
185
186
|
}
|
|
186
187
|
return true;
|
|
187
188
|
};
|
|
188
|
-
|
|
189
|
+
const filter = node.collideWithCharacters ? predicate : (c) => !(this.byColliderHandle.get(c.handle) instanceof CharacterBody2D) && predicate(c);
|
|
190
|
+
this.kcc.computeColliderMovement(e.collider, desired, this.R.QueryFilterFlags.EXCLUDE_SENSORS, void 0, filter);
|
|
189
191
|
const corrected = this.kcc.computedMovement();
|
|
190
192
|
const t = e.body.translation();
|
|
191
193
|
e.body.setNextKinematicTranslation({
|
|
@@ -350,6 +352,45 @@ var Physics2D = class {
|
|
|
350
352
|
if (others.size === 0) this.overlaps.delete(self);
|
|
351
353
|
}
|
|
352
354
|
}
|
|
355
|
+
/** Every overlap `node` is in ends now — the exits Rapier does not send for a disabled collider. */
|
|
356
|
+
releaseOverlaps(node) {
|
|
357
|
+
const set = this.overlaps.get(node);
|
|
358
|
+
if (!set || set.size === 0) return;
|
|
359
|
+
for (const other of [...set]) {
|
|
360
|
+
this.trackOverlap(node, other, false);
|
|
361
|
+
this.trackOverlap(other, node, false);
|
|
362
|
+
try {
|
|
363
|
+
node.emit("triggerExit", other);
|
|
364
|
+
other.emit("triggerExit", node);
|
|
365
|
+
} catch (error) {
|
|
366
|
+
diagnose(this.engine, "error", `incanto: error in a 'triggerExit' handler (${node.name} ↔ ${other.name}):`, error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/** Every body the armed sensor is inside of RIGHT NOW enters it — the starts Rapier does not send for a re-enabled collider. */
|
|
371
|
+
armOverlaps(node, collider) {
|
|
372
|
+
const found = [];
|
|
373
|
+
const t = collider.translation();
|
|
374
|
+
this.world.intersectionsWithShape({
|
|
375
|
+
x: t.x,
|
|
376
|
+
y: t.y
|
|
377
|
+
}, collider.rotation(), collider.shape, (hit) => {
|
|
378
|
+
const other = this.byColliderHandle.get(hit.handle);
|
|
379
|
+
if (other && other !== node && hit.isEnabled()) found.push(other);
|
|
380
|
+
return true;
|
|
381
|
+
}, void 0, void 0, collider);
|
|
382
|
+
for (const other of found) {
|
|
383
|
+
if (this.overlaps.get(node)?.has(other)) continue;
|
|
384
|
+
this.trackOverlap(node, other, true);
|
|
385
|
+
this.trackOverlap(other, node, true);
|
|
386
|
+
try {
|
|
387
|
+
node.emit("triggerEnter", other);
|
|
388
|
+
other.emit("triggerEnter", node);
|
|
389
|
+
} catch (error) {
|
|
390
|
+
diagnose(this.engine, "error", `incanto: error in a 'triggerEnter' handler (${node.name} ↔ ${other.name}):`, error);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
353
394
|
pruneOverlaps() {
|
|
354
395
|
for (const [self, others] of this.overlaps) {
|
|
355
396
|
if (self.tree === null) {
|
|
@@ -570,6 +611,7 @@ var Physics2D = class {
|
|
|
570
611
|
desc.setTranslation(x, y).setRotation(node.rotation * DEG);
|
|
571
612
|
if (node instanceof RigidBody2D) {
|
|
572
613
|
desc.setGravityScale(node.gravityScale);
|
|
614
|
+
desc.setLinearDamping(node.linearDamping).setAngularDamping(node.angularDamping);
|
|
573
615
|
desc.setLinvel((node.linearVelocity[0] ?? 0) / SCALE, (node.linearVelocity[1] ?? 0) / SCALE);
|
|
574
616
|
desc.setAngvel(node.fixedRotation ? 0 : node.angularVelocity);
|
|
575
617
|
if (node.fixedRotation) desc.lockRotations();
|
|
@@ -579,7 +621,8 @@ var Physics2D = class {
|
|
|
579
621
|
colDesc.setActiveEvents(R.ActiveEvents.COLLISION_EVENTS);
|
|
580
622
|
colDesc.setActiveCollisionTypes(R.ActiveCollisionTypes.ALL);
|
|
581
623
|
if (node instanceof Area2D) colDesc.setSensor(true);
|
|
582
|
-
if (node instanceof RigidBody2D) colDesc.setMass(node.mass)
|
|
624
|
+
if (node instanceof RigidBody2D) colDesc.setMass(node.mass);
|
|
625
|
+
if (node instanceof RigidBody2D || node instanceof StaticBody2D) applySurface(R, colDesc, node);
|
|
583
626
|
const collider = this.world.createCollider(colDesc, body);
|
|
584
627
|
e = {
|
|
585
628
|
body,
|
|
@@ -591,9 +634,11 @@ var Physics2D = class {
|
|
|
591
634
|
lastVY: 0,
|
|
592
635
|
lastAV: dyn ? node.angularVelocity : 0,
|
|
593
636
|
lastMass: dyn ? node.mass : 1,
|
|
594
|
-
lastFriction:
|
|
595
|
-
lastRestitution:
|
|
596
|
-
lastGravityScale: dyn ? node.gravityScale : 1
|
|
637
|
+
lastFriction: node.friction ?? .5,
|
|
638
|
+
lastRestitution: node.restitution ?? 0,
|
|
639
|
+
lastGravityScale: dyn ? node.gravityScale : 1,
|
|
640
|
+
lastLinDamp: dyn ? node.linearDamping : 0,
|
|
641
|
+
lastAngDamp: dyn ? node.angularDamping : 0
|
|
597
642
|
};
|
|
598
643
|
this.entries.set(node, e);
|
|
599
644
|
this.byColliderHandle.set(collider.handle, node);
|
|
@@ -607,9 +652,11 @@ var Physics2D = class {
|
|
|
607
652
|
return e;
|
|
608
653
|
}
|
|
609
654
|
if (node._enabledChanged) {
|
|
655
|
+
if (!node.enabled) this.releaseOverlaps(node);
|
|
610
656
|
e.collider.setEnabled(node.enabled);
|
|
611
657
|
e.body.setEnabled(node.enabled);
|
|
612
658
|
node._enabledChanged = false;
|
|
659
|
+
if (node.enabled) this.armOverlaps(node, e.collider);
|
|
613
660
|
}
|
|
614
661
|
const [px, py] = worldPosition2D(node);
|
|
615
662
|
if (px !== e.lastX || py !== e.lastY) {
|
|
@@ -647,12 +694,23 @@ var Physics2D = class {
|
|
|
647
694
|
e.collider.setMass(node.mass);
|
|
648
695
|
e.lastMass = node.mass;
|
|
649
696
|
}
|
|
650
|
-
if (node.friction !== e.lastFriction) {
|
|
651
|
-
e.collider
|
|
697
|
+
if (node.friction !== e.lastFriction || node.restitution !== e.lastRestitution) {
|
|
698
|
+
applySurface(this.R, e.collider, node);
|
|
652
699
|
e.lastFriction = node.friction;
|
|
700
|
+
e.lastRestitution = node.restitution;
|
|
701
|
+
}
|
|
702
|
+
if (node.linearDamping !== e.lastLinDamp) {
|
|
703
|
+
e.body.setLinearDamping(node.linearDamping);
|
|
704
|
+
e.lastLinDamp = node.linearDamping;
|
|
705
|
+
}
|
|
706
|
+
if (node.angularDamping !== e.lastAngDamp) {
|
|
707
|
+
e.body.setAngularDamping(node.angularDamping);
|
|
708
|
+
e.lastAngDamp = node.angularDamping;
|
|
653
709
|
}
|
|
654
|
-
|
|
655
|
-
|
|
710
|
+
} else if (node instanceof StaticBody2D) {
|
|
711
|
+
if (node.friction !== e.lastFriction || node.restitution !== e.lastRestitution) {
|
|
712
|
+
applySurface(this.R, e.collider, node);
|
|
713
|
+
e.lastFriction = node.friction;
|
|
656
714
|
e.lastRestitution = node.restitution;
|
|
657
715
|
}
|
|
658
716
|
}
|
|
@@ -727,5 +785,30 @@ function buildColliderDesc(R, collider, nodeName) {
|
|
|
727
785
|
}
|
|
728
786
|
throw new IncantoError("BAD_FORMAT", `Collider on '${nodeName}': "shape" must be 'rect', 'circle', or 'capsule', got ${JSON.stringify(shape)}.`);
|
|
729
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* A static body's authored surface, and the rule that makes it WIN the pair.
|
|
790
|
+
*
|
|
791
|
+
* Rapier combines two colliders' coefficients by the higher-priority rule of
|
|
792
|
+
* the two (Max > Multiply > Min > Average) and defaults to Average, which is
|
|
793
|
+
* why a 0.75 ball on a fixed-0 floor kept 37% of its speed. The surface an
|
|
794
|
+
* author writes on a floor is an intent about whatever touches it: a
|
|
795
|
+
* trampoline launches a dead ball (Max), an ice patch slides a grippy crate
|
|
796
|
+
* (Min), glue stops a slick one (Max). At the defaults nothing is set, so a
|
|
797
|
+
* scene that says nothing pairs exactly as it always did.
|
|
798
|
+
*
|
|
799
|
+
* The same rule on the MOVING body, because the character skill had said for
|
|
800
|
+
* a year "set `friction: 0` on the body" and nothing honoured it: a
|
|
801
|
+
* RigidBody's 0 met the floor's unwritten 0.5 under Average and became 0.25,
|
|
802
|
+
* and every 3D character walked at 3.7 where the skill promised 4.0. An
|
|
803
|
+
* authored value wins the pair whichever side wrote it; when both sides
|
|
804
|
+
* speak, Rapier's priority order (Max > Multiply > Min > Average) decides.
|
|
805
|
+
*/
|
|
806
|
+
function applySurface(R, target, node) {
|
|
807
|
+
const Rule = R.CoefficientCombineRule;
|
|
808
|
+
target.setFriction(node.friction);
|
|
809
|
+
target.setFrictionCombineRule(node.friction === .5 ? Rule.Average : node.friction < .5 ? Rule.Min : Rule.Max);
|
|
810
|
+
target.setRestitution(node.restitution);
|
|
811
|
+
target.setRestitutionCombineRule(node.restitution > 0 ? Rule.Max : Rule.Average);
|
|
812
|
+
}
|
|
730
813
|
//#endregion
|
|
731
814
|
export { enablePhysics2D as n, physics_2d_exports as r, Physics2D as t };
|