@kingdomsconnected/types 1.5.6 → 1.6.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.
@@ -74,6 +74,21 @@ declare global {
74
74
  */
75
75
  playerPutDown: [carrier: Player, carried: Player];
76
76
 
77
+ /**
78
+ * Dispatched when a player starts a carry of their own, before the server accepts it: they chose the game's pick-up prompt over a carryable `groundItem`, or took an item from one of the world's own piles (`groundItem` null). Return `false` from a handler and the carry is refused -- the prop stays where it is, and a pile's item is let go at once. Handlers run synchronously, so the decision cannot wait on anything awaited. A carry a script ordered with `carryItem` is not asked. `item` is the item's name.
79
+ */
80
+ playerCarryingItem: [player: Player, item: string, groundItem: GroundItem | null];
81
+
82
+ /**
83
+ * Dispatched once an item carry is accepted: everybody sees the player pick it up and carry it, and `player.carriedItem` names it. `groundItem` is the prop it was taken up from, still readable here and gone a moment later, or null. It is carried until `playerPutDownItem`.
84
+ */
85
+ playerCarryItem: [player: Player, item: string, groundItem: GroundItem | null];
86
+
87
+ /**
88
+ * Dispatched once an item carry is over, however it ended: the player put it down, `putDownItem` asked them to, it went into a pile, or they left. `groundItem` is the carryable prop it became where it fell -- still falling, settling where the game's physics puts it -- or null when it went into a pile or they have no room left on the ground.
89
+ */
90
+ playerPutDownItem: [player: Player, item: string, groundItem: GroundItem | null];
91
+
77
92
  /**
78
93
  * Dispatched once a joining player is really standing in the world: their level is up, their body is where `playerSpawning` put it, and the ground under it has loaded. Anything that acts on an arriving player -- kit, a welcome line, a marker -- belongs here rather than in `playerConnect`, which fires while they are still loading the level, or in `playerSpawning`, where the body is still mid-placement.
79
94
  *
@@ -204,6 +219,11 @@ declare global {
204
219
  */
205
220
  diceMatchEnd: [match: number, first: Player | null, second: Player | null, winner: number, reason: string, firstScore: number, secondScore: number];
206
221
 
222
+ /**
223
+ * Synchronous decision before an unfinished craft settles, including when no native refund is due. Call refund() to request a full refund; return values are ignored. No handler or no call preserves native rules. JavaScript exceptions are logged and do not cancel a call already made. The callback expires on return; delayed calls do nothing. The `cancelled`, `interrupted` and `clientError` reasons are reported by the player's own client: a modified client can send any of them, so refunding on one lets that client keep its materials. Never grants a completed craft twice. craftingEnded follows the actual inventory changes.
224
+ */
225
+ craftingRefunding: [player: Player, proposal: CraftRefundProposal, refund: () => void];
226
+
207
227
  /**
208
228
  * A player asks to open an alchemy table, or to begin a smithing recipe. Every handler runs; one returning literal `false` refuses it. An async handler cannot refuse.
209
229
  */
@@ -275,7 +295,7 @@ declare global {
275
295
  cartEntering: [cart: Cart, player: Player, seat: string];
276
296
 
277
297
  /**
278
- * Dispatched after a player is given a seat. `seat` is `driver` or `back`; a driver's client runs the cart from here on.
298
+ * Dispatched after a player is given a seat, named as in `cart.seats`; the `driver` seat's client runs the cart from here on.
279
299
  */
280
300
  cartEnter: [cart: Cart, player: Player | null, seat: string];
281
301
 
@@ -325,7 +345,7 @@ declare global {
325
345
  npcDestroy: [npc: Npc];
326
346
 
327
347
  /**
328
- * Dispatched when an NPC finishes what it was told to do. `status` is `reached` when it arrived, `blocked` when it could not make progress, or `failed` when the order could not be carried out at all. A patrol steps on this event, so a handler that re-orders the NPC here replaces the route rather than racing it.
348
+ * Dispatched once when an NPC finishes what it was told to do. `status` is `reached` when it arrived, `blocked` when it could not make progress, or `failed` when the order could not be carried out at all, or when a patrol gives up. Server-planned intermediate corners do not raise this event, and neither does a change of simulator: a finished order is not reported twice. A follow, which never finishes, raises `reached` the first time it catches up and again only after a change of simulator. A patrol steps on this event, so a handler that re-orders the NPC here replaces the route rather than racing it.
329
349
  */
330
350
  npcIntentDone: [npc: Npc, status: string];
331
351
 
@@ -396,6 +416,36 @@ declare global {
396
416
  */
397
417
  doorInteract: [player: Player, door: Door, action: "open" | "close" | "unlock" | "lockpick", keySide: boolean];
398
418
 
419
+ /**
420
+ * Dispatched immediately after a siege engine is built.
421
+ */
422
+ siegeEngineSpawn: [engine: SiegeEngine];
423
+
424
+ /**
425
+ * Dispatched while a siege engine is being removed. The handle still resolves.
426
+ */
427
+ siegeEngineDestroy: [engine: SiegeEngine];
428
+
429
+ /**
430
+ * Dispatched when an engine's load cycle finishes and it can fire.
431
+ */
432
+ siegeEngineReady: [engine: SiegeEngine];
433
+
434
+ /**
435
+ * Dispatched when a player presses a `usable` engine's native prompt, standing at it, on the step the prompt was offered for. Return false to refuse; otherwise the engine loads, or fires along the player's facing at `range` with the player as the attacker. A handler that works the engine itself should refuse, so it is not worked twice.
436
+ */
437
+ siegeEngineUse: [player: Player, engine: SiegeEngine, action: "load" | "fire"];
438
+
439
+ /**
440
+ * Dispatched the moment an engine lets its projectile go, partway through the shot `fire` started.
441
+ */
442
+ siegeFire: [engine: SiegeEngine, attacker: Player | null, target: Vector3];
443
+
444
+ /**
445
+ * Dispatched where a projectile came down: what the player nearest the target saw it hit, checked against the arc it was thrown on, or the target itself when nobody could see it. Players within `damageRadius` have already been told to take their share, and NPCs have taken theirs. `engine` is null when it was destroyed while the stone was in the air.
446
+ */
447
+ siegeImpact: [engine: SiegeEngine | null, position: Vector3, attacker: Player | null];
448
+
399
449
  /**
400
450
  * Dispatched when a body comes to be inside an enabled area: it walked or rode in, or the area was created, moved, reshaped or enabled around it. The server decides this itself from the pose it already replicates, by the game's own rule for that kind of area, so a client cannot claim it. `matchingVirtualWorld` is false when a script area bound to one world is crossed by a body in another; a level area is in every world.
401
451
  */
@@ -407,12 +457,12 @@ declare global {
407
457
  areaExit: [area: Area, entity: Player | Horse | Cart | Npc, matchingVirtualWorld: boolean];
408
458
 
409
459
  /**
410
- * A container now exists: one a script spawned, or one the level places, built in a virtual world the first time anything there asked for it. Every container starts empty; restore saved contents here with `setInventory`. The level's containers in the global world are built before any resource runs, so restore those from `resourceStart` by walking `Stash.all()`.
460
+ * A container now exists: a scripted chest, a virtual stash, or one the level places, built in a virtual world the first time anything there asked for it. Every container starts empty; restore saved contents here with `setInventory`. The level's containers in the global world are built before any resource runs, so restore those from `resourceStart` by walking `Stash.all()`.
411
461
  */
412
462
  stashSpawn: [stash: Stash];
413
463
 
414
464
  /**
415
- * A player opened a container and sees what it holds.
465
+ * A player holds a container view. Physical chests report the native opening; virtual stashes report the server grant before requesting the native screen.
416
466
  */
417
467
  stashOpen: [stash: Stash, player: Player];
418
468
 
@@ -432,9 +482,9 @@ declare global {
432
482
  stashDestroy: [stash: Stash];
433
483
 
434
484
  /**
435
- * Dispatched when a player presses a container's prompt, before anything happens: the player's client holds the game's own handler until the server answers. `action` is `open`, `unlock` -- a key turned, which opens it in the same use -- or `lockpick`, the minigame starting; a successful pick then opens it without asking again.
485
+ * Dispatched for a physical chest prompt or virtual stash open(player), before access is granted. For a prompt: the player's client holds the game's own handler until the server answers. `action` is `open`, `unlock` -- a key turned, which opens it in the same use -- or `lockpick`, the minigame starting; a successful pick then opens it without asking again.
436
486
  *
437
- * Return false to refuse it: the prompt does nothing, and no transfer screen, key or minigame ever appears. Every handler runs whatever an earlier one returned, and an async handler cannot refuse. The server has already refused what the game's own rules forbid -- a player out of reach, a container another player has open, opening a locked one, picking one that cannot be -- so this only sees what the game would allow. Closing is never asked.
487
+ * Return false to refuse it: the prompt does nothing, and no transfer screen, key or minigame ever appears. Every handler runs whatever an earlier one returned, and an async handler cannot refuse. The server has already refused what the game's own rules forbid -- a player out of reach, a container another player has open, opening a locked one, picking one that cannot be -- so this only sees what the game would allow. Virtual opening has no distance check; world, player readiness, lock and exclusive access checks still apply. Closing is never asked.
438
488
  */
439
489
  stashInteract: [player: Player, stash: Stash, action: "open" | "unlock" | "lockpick"];
440
490
 
@@ -1198,6 +1248,11 @@ declare global {
1198
1248
  */
1199
1249
  readonly carriedBy: Player | null;
1200
1250
 
1251
+ /**
1252
+ * The item this player carries in their arms, by its item name, or null. Set once `playerCarryItem` has fired, cleared once `playerPutDownItem` has.
1253
+ */
1254
+ readonly carriedItem: string | null;
1255
+
1201
1256
  /**
1202
1257
  * The horse this player is riding, or null when they are on foot.
1203
1258
  */
@@ -1330,10 +1385,10 @@ declare global {
1330
1385
  *
1331
1386
  * A hand tag is only half of holding something. `r_bucket` makes the body move as if it carried a bucket, but the bucket itself is a `props` entry.
1332
1387
  * @param fragment A Mannequin fragment, as `Animations.list` names it. `""` plays none and only puts the props and tags on, which with a hand tag like `r_bucket` makes the player carry something while they walk.
1333
- * @param options `tags` pick the variant, `loop` repeats it until stopped, `lockMovement` holds the player still, `props` puts up to two models in their hands.
1388
+ * @param options `clip` plays a clip the server streams instead of a fragment (`animations/kcdc/<resource>/wave.caf`, the fragment left `""`), `tags` pick the variant, `loop` repeats it until stopped, `lockMovement` holds the player still, `props` puts up to two models in their hands.
1334
1389
  * @returns True when the request went out; false for a player with no body yet. Throws for a prop or option it cannot use.
1335
1390
  */
1336
- playAnimation(fragment: string, options?: { tags?: string; loop?: boolean; lockMovement?: boolean; props?: { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> } | { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> }[] }): boolean;
1391
+ playAnimation(fragment: string, options?: { clip?: string; tags?: string; loop?: boolean; lockMovement?: boolean; props?: { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> } | { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> }[] }): boolean;
1337
1392
 
1338
1393
  /**
1339
1394
  * Ends what `playAnimation` started at once, takes its props away and hands the body back to the game. A stance tag the animation set goes with it, so without `standUp` a seated player pops upright.
@@ -1468,7 +1523,7 @@ declare global {
1468
1523
  * The game's own camera sits in the head, which the mesh now covers: pair this with the client's `Camera.setThirdPerson` for the disguised player. Nametags are not touched; `setNametagVisible` is the call for that. NPCs still see a person.
1469
1524
  *
1470
1525
  * The owning client is authoritative for its body, so this is a request that lands on their next frame; `player.disguise` reads what they actually have on.
1471
- * @param model A mesh from the prop catalog, by its `objects/...cgf` path or its file stem -- anything `Prop.spawn` takes. Null puts the player back in their own body.
1526
+ * @param model A mesh from the prop catalog, by its `objects/...cgf` path or its file stem, or one this server streams by its full path -- anything `Prop.spawn` takes. Null puts the player back in their own body.
1472
1527
  * @returns True when the request went out; false for a player with no connection to ask. Throws for a model the catalog does not carry.
1473
1528
  */
1474
1529
  setDisguise(model: string | null): boolean;
@@ -1485,6 +1540,24 @@ declare global {
1485
1540
  */
1486
1541
  putDown(): boolean;
1487
1542
 
1543
+ /**
1544
+ * Has this player carry an item in their arms, the way the game's own people carry firewood, sacks and baskets: the carrying walk, and the put-down at the end. While it is carried they walk, since the game has no running with a load.
1545
+ *
1546
+ * It is an instruction to their client, so the carry lands when that client reports it: `playerCarryItem` and `carriedItem` follow. A carry a script ordered is not put to `playerCarryingItem`. The item never enters their inventory. Put down -- with the game's own key or `putDownItem` -- it falls from their hands and becomes a carryable `GroundItem` where it lands, which `playerPutDownItem` hands over and anybody can take up again.
1547
+ *
1548
+ * Their hands have to be free -- a drawn weapon or a torch makes their game refuse the carry, and nothing is reported.
1549
+ * @param item What to carry. A name from `Animations.props()` whose `hand` the game has a carrying walk for -- the baskets (`basket_full_wood`, `basket_b_apples`, `stonebasket`, `eggbasket`, `shoppingbasket`), `firewoodChipsHand`, the buckets (`waterBucket`, `milkBucket`), and for a man only the sacks (`sack`, `sack_miller`), `barrel` and `crate_with_silver` -- puts a new one straight into their hands. A `GroundItem` of such a class has them pick that one up off the ground with the game's own bend-down; it has to be a single item within their reach.
1550
+ * @returns True when the order went out; false when they cannot act, are riding, already carry an item or a body, the stack is not resting within their reach or somebody else is taking it, or they have no connection. Throws for an item with no carrying walk, or none for this player's body.
1551
+ */
1552
+ carryItem(item: string | GroundItem): boolean;
1553
+
1554
+ /**
1555
+ * Has this player put down the item in their arms, with the game's own put-down. It is an instruction to their client, so the carry ends when that put-down lands: `playerPutDownItem` follows then.
1556
+ * @param options `immediate` lets go at once, without the put-down.
1557
+ * @returns True when the order went out; false when they carry no item or have no connection.
1558
+ */
1559
+ putDownItem(options?: { immediate?: boolean }): boolean;
1560
+
1488
1561
  /**
1489
1562
  * Puts this player in a horse's saddle, the way the game's own forced mount does -- their client plays the climb. It is an instruction to their client, so the seat is reported back like any other mount: `horseMounting` can still refuse it, and `horseMount` and `player.horse` follow once it lands. The player has to be standing near the horse; teleport them beside it first.
1490
1563
  * @param horse The horse to climb onto.
@@ -1911,7 +1984,7 @@ declare global {
1911
1984
  /**
1912
1985
  * Draws the row greyed and unpickable when false. A rendering hint only -- the server re-checks the choice when it arrives, so nothing a row costs may rely on this.
1913
1986
  */
1914
- enabled: boolean | undefined;
1987
+ enabled?: boolean | undefined;
1915
1988
  }
1916
1989
 
1917
1990
  /**
@@ -1921,12 +1994,12 @@ declare global {
1921
1994
  /**
1922
1995
  * Shown above the options. Omit it for a list with no preamble.
1923
1996
  */
1924
- line: string | undefined;
1997
+ line?: string | undefined;
1925
1998
 
1926
1999
  /**
1927
2000
  * Draws the list on the right of the screen instead of the left.
1928
2001
  */
1929
- onRight: boolean | undefined;
2002
+ onRight?: boolean | undefined;
1930
2003
 
1931
2004
  /**
1932
2005
  * The rows, at least one and at most eight. A page with none is refused.
@@ -1978,17 +2051,17 @@ declare global {
1978
2051
  /**
1979
2052
  * Shown in the server's log only. The trade screen names whoever keeps the shop.
1980
2053
  */
1981
- name: string | undefined;
2054
+ name?: string | undefined;
1982
2055
 
1983
2056
  /**
1984
2057
  * Money units the vendor starts with, and all it can pay out. Omit it for a purse that never runs out.
1985
2058
  */
1986
- purse: number | undefined;
2059
+ purse?: number | undefined;
1987
2060
 
1988
2061
  /**
1989
2062
  * Whether the vendor takes the player's items at all. On by default; `setBuyPrices` says which ones.
1990
2063
  */
1991
- buys: boolean | undefined;
2064
+ buys?: boolean | undefined;
1992
2065
  }
1993
2066
 
1994
2067
  /**
@@ -2155,6 +2228,26 @@ declare global {
2155
2228
  amount: number;
2156
2229
  }
2157
2230
 
2231
+ /**
2232
+ * A dice table placed by the current level. The catalog includes quest-layer tables that may not currently be loaded on a client.
2233
+ */
2234
+ interface DiceTableInfo {
2235
+ /**
2236
+ * The table's level GUID as sixteen lowercase hex digits.
2237
+ */
2238
+ id: string;
2239
+
2240
+ /**
2241
+ * The world-space midpoint between the table's two seat alignment points, in metres. The behavior entity itself may be offset from this interaction centre.
2242
+ */
2243
+ position: Vector3;
2244
+
2245
+ /**
2246
+ * The two sitting smart-object GUIDs, in native seat order. Compare with a seated player's seatGuid; these are not the minigame's alignment tagpoints.
2247
+ */
2248
+ seats: [string, string];
2249
+ }
2250
+
2158
2251
  /**
2159
2252
  * How a dice match is played.
2160
2253
  */
@@ -2162,7 +2255,7 @@ declare global {
2162
2255
  /**
2163
2256
  * The score that wins, banked at the end of a turn. 2000 when omitted, at most 100000.
2164
2257
  */
2165
- targetScore: number | undefined;
2258
+ targetScore?: number | undefined;
2166
2259
  }
2167
2260
 
2168
2261
  /**
@@ -2171,6 +2264,12 @@ declare global {
2171
2264
  * Both players sit down at the dice table nearest them and play it as they would against an NPC, the other player's body opposite. Every throw is dealt and every move checked by the server, by the game's own scoring rules; badges and dice perks are off, so a match is decided by the dice and the decisions alone.
2172
2265
  */
2173
2266
  const Dice: {
2267
+ /**
2268
+ * Lists the current level's dice tables and their seats. The same placements exist in every virtual world; readiness and occupancy belong to the gamemode.
2269
+ * @returns The level's tables, in GUID order.
2270
+ */
2271
+ tables(): DiceTableInfo[];
2272
+
2174
2273
  /**
2175
2274
  * Starts a match. Both players must stand together, within a few metres, at a dice table, and neither may be playing already. Throws an Error saying why when it cannot start.
2176
2275
  * @param first NetworkID of the player on the table's first seat.
@@ -2385,6 +2484,66 @@ declare global {
2385
2484
  knowledge: Record<string, number> | undefined;
2386
2485
  }
2387
2486
 
2487
+ /**
2488
+ * An original ingredient still held by this session, including its original inventory properties.
2489
+ */
2490
+ interface CraftRefundMaterial {
2491
+ /**
2492
+ * Item class GUID.
2493
+ */
2494
+ item: string;
2495
+
2496
+ /**
2497
+ * Units originally removed and not already returned.
2498
+ */
2499
+ amount: number;
2500
+
2501
+ /**
2502
+ * Original canonical inventory properties, preserved by refunds.
2503
+ */
2504
+ metadata: Record<string, unknown>;
2505
+ }
2506
+
2507
+ /**
2508
+ * An unfinished craft before material settlement. Frozen. Call the event's refund callback synchronously to request all its materials back; otherwise the native refund rules apply.
2509
+ */
2510
+ interface CraftRefundProposal {
2511
+ /**
2512
+ * Which craft.
2513
+ */
2514
+ kind: 'alchemy' | 'smithing';
2515
+
2516
+ /**
2517
+ * The session being settled, once only.
2518
+ */
2519
+ session: string;
2520
+
2521
+ /**
2522
+ * Station id.
2523
+ */
2524
+ station: string;
2525
+
2526
+ /**
2527
+ * The session's virtual world.
2528
+ */
2529
+ virtualWorld: number;
2530
+
2531
+ /**
2532
+ * No product was granted for this craft.
2533
+ */
2534
+ outcome: 'failed' | 'cancelled';
2535
+
2536
+ /**
2537
+ * Why it ended: cancelled for normal native or script cancellation; interrupted for native teardown without a normal exit; clientError for an alchemy adapter failure; craftingFailed for a broken smithing workpiece. Server closures also include disconnected, timeout and contextInvalidated; settlement refusals retain their existing reasons. Client exit reasons are observations, not server-verified combat evidence.
2538
+ */
2539
+ reason: string;
2540
+
2541
+ /**
2542
+ * All remaining original ingredients, including processed alchemy ingredients. Station liquids and ingredients already returned are excluded. Do not grant these yourself; call refund().
2543
+ */
2544
+ materials: CraftRefundMaterial[];
2545
+ }
2546
+
2388
2547
  /**
2389
2548
  * A batch or workpiece that is over, for any reason. A table kept for the next batch is not closed by this.
2390
2549
  */
@@ -2415,12 +2574,12 @@ declare global {
2415
2574
  outcome: 'success' | 'failed' | 'cancelled';
2416
2575
 
2417
2576
  /**
2418
- * Empty for a completed batch or a workpiece the game finished or broke. `craftingCompletingRejected` when a handler refused the result; `cancelled` by the player or a script; `disconnected`; `timeout` after 30 minutes; `contextInvalidated` when the player walked away, died or changed world. Smithing adds `abandoned` (the recipe never reached the anvil), `abandonTooLate`, `invalidQuality` and `inventoryUnavailable`.
2577
+ * Empty for a completed batch or a successful workpiece. `craftingFailed` for a broken workpiece; `cancelled` for normal native or script cancellation; `interrupted` for unexpected native teardown; `clientError` for alchemy adapter errors. Other reasons: `craftingCompletingRejected`, `disconnected`, `timeout`, `contextInvalidated`, and for smithing `abandoned`, `abandonTooLate`, `invalidQuality`, `inventoryUnavailable`. See CraftRefundProposal.
2419
2578
  */
2420
2579
  reason: string;
2421
2580
 
2422
2581
  /**
2423
- * The inventory rows ingredients went back to. Alchemy: wholly unmilled bowl, mortar and herb groups come back; everything else put on the table was spent. Smithing: a failed workpiece spends half of each divisible material, rounded down, and a coin decides a single unit; the rest comes back.
2582
+ * The inventory rows ingredients went back to. Alchemy: wholly unmilled bowl, mortar and herb groups come back; everything else put on the table was spent. Smithing: a failed workpiece spends half of each divisible material, rounded down, and a coin decides a single unit; the rest comes back. A full refund requested through craftingRefunding returns all remaining original materials instead.
2424
2583
  */
2425
2584
  refunded: InventoryUnit[];
2426
2585
  }
@@ -2820,7 +2979,7 @@ declare global {
2820
2979
  readonly modelName: string;
2821
2980
 
2822
2981
  /**
2823
- * Browsing bucket the mesh sits in, e.g. `manmade/structures`.
2982
+ * Browsing bucket the mesh sits in, e.g. `manmade/structures`; `kcdc/<resource>` for a mesh the server streams.
2824
2983
  */
2825
2984
  readonly modelGroup: string;
2826
2985
 
@@ -2847,7 +3006,7 @@ declare global {
2847
3006
 
2848
3007
  /**
2849
3008
  * Spawns and replicates a static mesh from the game's own object catalog.
2850
- * @param model Mesh to build, as either a full catalog path (`objects/manmade/barrels/barrel_a.cgf`) or its file stem (`barrel_a`). A stem several meshes share resolves to the first of them, so pass the path when it matters which.
3009
+ * @param model Mesh to build, as either a full catalog path (`objects/manmade/barrels/barrel_a.cgf`) or its file stem (`barrel_a`). A stem several meshes share resolves to the first of them, so pass the path when it matters which. A mesh this server streams -- a `.cgf` in a resource's `stream/objects/kcdc/<resource>/` folder -- is named by its full path, `objects/kcdc/<resource>/chair.cgf`; a player whose game does not have it yet sees the prop as soon as it does.
2851
3010
  * @param position Optional world-space spawn position; omitted components default to zero.
2852
3011
  * @param rotation Optional initial orientation: a Quaternion, or a Vector3 of Euler angles in degrees.
2853
3012
  * @param scale Optional uniform scale from 0.01 to 100; omitted spawns the mesh at its own size.
@@ -2910,6 +3069,16 @@ declare global {
2910
3069
  */
2911
3070
  readonly pace: string;
2912
3071
 
3072
+ /**
3073
+ * The names of this cart's seats, the reins first: six on a wagon, three on the two-wheeler.
3074
+ */
3075
+ readonly seats: string[];
3076
+
3077
+ /**
3078
+ * The fastest the driver may take it urged on (the trot key held), in metres a second, 0 to 15; 7 by default. Unurged the team trots at 3.6 or this, whichever is less. A value outside the range is ignored.
3079
+ */
3080
+ maxSpeed: number;
3081
+
2913
3082
  /**
2914
3083
  * Formats this cart handle for logging and debugging.
2915
3084
  * @returns The cart ID, its blueprint, its driver and its pace.
@@ -2924,7 +3093,7 @@ declare global {
2924
3093
  /**
2925
3094
  * Puts a player in a seat. They are taken out of any cart they were in, their own game walks them to the seat and climbs in, and `cartEnter` follows; the driver's client runs the cart from then on. `cartEntering` handlers are asked first.
2926
3095
  * @param player The player to seat.
2927
- * @param seat `driver` (the bench, holding the reins) or `back` (the right rail): the two seats the game animates a player in.
3096
+ * @param seat One of the cart's `seats`. A wagon has `driver` (the reins, on the bench's left), `bench` (beside them), `rightBack`, `leftBack`, `rightFront` and `leftFront` (on the rails); the two-wheeler `driver`, `rightBack` and `leftBack`.
2928
3097
  * @returns Whether the player was seated: false for a taken seat, a player that is not connected, or a handler's refusal.
2929
3098
  */
2930
3099
  putPlayer(player: Player, seat: string): boolean;
@@ -2938,7 +3107,7 @@ declare global {
2938
3107
 
2939
3108
  /**
2940
3109
  * Who sits in a seat.
2941
- * @param seat `driver` or `back`.
3110
+ * @param seat One of the cart's `seats`.
2942
3111
  * @returns The player in it, or null when it is empty.
2943
3112
  */
2944
3113
  getOccupant(seat: string): Player | null;
@@ -2946,12 +3115,12 @@ declare global {
2946
3115
  /**
2947
3116
  * Where a player sits in this cart.
2948
3117
  * @param player The player to look for.
2949
- * @returns `driver` or `back`, or null when they are not in it.
3118
+ * @returns The seat's name, one of `seats`, or null when they are not in it.
2950
3119
  */
2951
3120
  seatOf(player: Player): string | null;
2952
3121
 
2953
3122
  /**
2954
- * Moves the cart outright, with everyone in it: every client rebuilds it on a new short road at the new pose, and a driver carries on from there.
3123
+ * Moves the cart outright, standing, with everyone in it; a driver carries on from there.
2955
3124
  * @param position Where the cart's front axle stands.
2956
3125
  * @param rotation Which way it faces; omitted keeps its heading.
2957
3126
  * @returns False for a pose that is not finite.
@@ -2959,7 +3128,7 @@ declare global {
2959
3128
  teleport(position: Vector3, rotation?: Vector3 | Quaternion): boolean;
2960
3129
 
2961
3130
  /**
2962
- * Spawns and replicates a cart or wagon from the game's own prefabs, with its horses already in the shafts. It stands on a short straight road until somebody takes the reins.
3131
+ * Spawns and replicates a cart or wagon from the game's own prefabs, with its horses already in the shafts. It stands where it was put until somebody takes the reins.
2963
3132
  * @param blueprint Which of the game's cart prefabs to build; omitted builds `wagon_b_covered`. `Cart.blueprints()` lists them.
2964
3133
  * @param position Where the cart's front axle stands; omitted components default to zero.
2965
3134
  * @param rotation Which way it faces: a Quaternion, or a Vector3 of Euler angles in degrees.
@@ -3319,22 +3488,22 @@ declare global {
3319
3488
  /**
3320
3489
  * What the object is; a brush when omitted. A brush has no identity of its own, so it is found by its mesh and where the level put it; a level entity by its EntityGuid.
3321
3490
  */
3322
- kind: 'brush' | 'entity' | undefined;
3491
+ kind?: 'brush' | 'entity' | undefined;
3323
3492
 
3324
3493
  /**
3325
3494
  * A brush's mesh path, `objects/...cgf`, as the World Builder shows it; required for a brush. An entity's name, kept for reading only.
3326
3495
  */
3327
- name: string | undefined;
3496
+ name?: string | undefined;
3328
3497
 
3329
3498
  /**
3330
3499
  * An entity's level EntityGuid as sixteen hex digits; required for an entity.
3331
3500
  */
3332
- guid: string | undefined;
3501
+ guid?: string | undefined;
3333
3502
 
3334
3503
  /**
3335
3504
  * An entity's class, kept for reading only.
3336
3505
  */
3337
- class: string | undefined;
3506
+ class?: string | undefined;
3338
3507
 
3339
3508
  /**
3340
3509
  * Where the level put the object: its pivot, matched within 5 cm. A brush's key, with its mesh.
@@ -3344,22 +3513,22 @@ declare global {
3344
3513
  /**
3345
3514
  * Whether it is taken out of the world: not drawn and not solid.
3346
3515
  */
3347
- hidden: boolean | undefined;
3516
+ hidden?: boolean | undefined;
3348
3517
 
3349
3518
  /**
3350
3519
  * Where it stands instead; present, the edit is a move.
3351
3520
  */
3352
- position: Vector3 | number[] | undefined;
3521
+ position?: Vector3 | number[] | undefined;
3353
3522
 
3354
3523
  /**
3355
3524
  * A move's orientation: a Quaternion, {x, y, z, w} or [x, y, z, w]. None when omitted.
3356
3525
  */
3357
- rotation: Quaternion | number[] | undefined;
3526
+ rotation?: Quaternion | number[] | undefined;
3358
3527
 
3359
3528
  /**
3360
3529
  * A move's scale per axis, from 0.01 to 100. None when omitted.
3361
3530
  */
3362
- scale: Vector3 | number[] | undefined;
3531
+ scale?: Vector3 | number[] | undefined;
3363
3532
  }
3364
3533
 
3365
3534
  /**
@@ -3557,9 +3726,7 @@ declare global {
3557
3726
  lootable: boolean;
3558
3727
 
3559
3728
  /**
3560
- * How the simulating client moves this body.
3561
- *
3562
- * `kinematic` (the default) advances the pose and lets every client animate it -- predictable, and the same path every remote player's body already runs on. `native` hands the destination to the game's own movement controller, which walks the body with real footfalls and real turns but will walk into whatever the engine does not route around. Pick `native` for bodies in the open and `kinematic` for anything on an authored route.
3729
+ * How the client simulator moves the body. `native` (default) uses the game's movement controller and walk animations. `kinematic` moves the body directly without walk animation. Neither finds a way around anything: the game's movement controller steers straight at the point it is given. Routes come from server pathfinding, which hands either mode mesh corners -- see `moveTo`.
3563
3730
  */
3564
3731
  locomotion: string;
3565
3732
 
@@ -3569,7 +3736,7 @@ declare global {
3569
3736
  readonly intent: string;
3570
3737
 
3571
3738
  /**
3572
- * What the simulating client last reported about the current intent: `idle`, `running`, `reached`, `blocked` or `failed`. A dormant NPC that is walking an authored route reports through the server's own dead reckoning instead, so a patrol keeps stepping with nobody there to watch it.
3739
+ * What has become of the current order: `idle`, `running`, `reached`, `blocked` or `failed`. A move reads `running` from the moment it is given -- while its route is planned and while it walks the route's corners -- until it ends, and then the outcome `npcIntentDone` announced, which stays until the next order. A follow reads `reached` while it is within its radius. Dormant moves in `auto` or `server` mode are carried out and decided by the server; dormant `game` moves wait for a client simulator.
3573
3740
  */
3574
3741
  readonly status: string;
3575
3742
 
@@ -3653,23 +3820,31 @@ declare global {
3653
3820
  hold(): void;
3654
3821
 
3655
3822
  /**
3656
- * Sends the NPC somewhere and raises `npcIntentDone` when it arrives, cannot get there, or gives up. Cancels any patrol.
3823
+ * Moves to `position`, cancels any patrol, and emits `npcIntentDone` once when the move ends.
3824
+ *
3825
+ * The game's own movement steers a body straight at the point it is given and finds no way around anything, so routes come from the server's navigation mesh. The server plans the route and hands the simulating client one corner at a time, the next before the body reaches the last, so it walks through bends without stopping; a dormant NPC is walked along the same route by the server. Routes only use doorways whose door stands open.
3826
+ *
3827
+ * `auto` (the default) routes on the server whenever a mesh is loaded. Without one, a simulating client steers straight at `position` and a dormant NPC moves in a straight line. `game` steers straight at `position` and waits while dormant; if the body reports `blocked` and a mesh is loaded, the server tries a route before emitting `npcIntentDone`. `server` always routes on the server and throws without a loaded mesh, preserving the previous order.
3828
+ *
3829
+ * A missing or partial route ends with `blocked`, and a blocked route is not retried. Route plans are queued and spread over ticks; the move reads `running` meanwhile.
3657
3830
  * @param position Where to walk to.
3658
- * @param options `speed` is the pace to walk at; `radius` is how close counts as arrived, in metres.
3659
- * @returns True when the order went out.
3831
+ * @param options `speed` defaults to `walk`; `radius` is the arrival distance in metres (default 1.5). `pathfinding` defaults to `auto`.
3832
+ * @returns True when the order went out; false for an invalid NPC or destination.
3660
3833
  */
3661
- moveTo(position: Vector3 | Partial<Vector3>, options?: { speed?: 'walk' | 'jog' | 'run'; radius?: number }): boolean;
3834
+ moveTo(position: Vector3 | Partial<Vector3>, options?: { speed?: 'walk' | 'jog' | 'run'; radius?: number; pathfinding?: 'auto' | 'game' | 'server' }): boolean;
3662
3835
 
3663
3836
  /**
3664
- * Walks a route, one waypoint at a time. The route stays on the server and only the waypoint being walked to is ever replicated, so a player who joins mid-patrol sees one move rather than a plan to catch up with -- and a patrol nobody is near enough to simulate keeps advancing on the server's own reckoning.
3837
+ * Walks the waypoints in order. The server stores the route and replicates the current target. `npcIntentDone` fires once per leg, after its final mesh corner or a movement failure.
3838
+ *
3839
+ * A leg that ends `blocked` or `failed` is skipped after at least 2 seconds. When every leg of a lap has failed in a row, the patrol is abandoned and that last leg reports `failed` instead.
3665
3840
  * @param points The waypoints, in order.
3666
- * @param options `loop` walks the route forever (the default); `waitSeconds` is how long to stand at each waypoint; `speed` is the pace.
3667
- * @returns True when the route was accepted; false for an empty route or a point that is not finite.
3841
+ * @param options `loop` defaults to true; `waitSeconds` is the wait at each waypoint, 0 to 3600 (default 0); `speed` defaults to `walk`. `pathfinding` uses the modes documented for `moveTo` and applies to every leg.
3842
+ * @returns True when the route was accepted; false for an empty route, more than 256 waypoints, a waypoint that is not finite or lies outside the world, or a `waitSeconds` that is not a number. Throws if server mode has no loaded mesh, leaving the previous order intact.
3668
3843
  */
3669
- patrol(points: (Vector3 | Partial<Vector3>)[], options?: { speed?: 'walk' | 'jog' | 'run'; loop?: boolean; waitSeconds?: number }): boolean;
3844
+ patrol(points: (Vector3 | Partial<Vector3>)[], options?: { speed?: 'walk' | 'jog' | 'run'; loop?: boolean; waitSeconds?: number; pathfinding?: 'auto' | 'game' | 'server' }): boolean;
3670
3845
 
3671
3846
  /**
3672
- * Keeps the NPC near somebody as they move.
3847
+ * Keeps the NPC near somebody as they move, steering straight at them. `npcIntentDone` reports `reached` the first time it catches up, and the follow carries on. If the body reports `blocked`, a loaded mesh lets the server route to the target's current position before reporting it. After recovery it resumes following the moving target.
3673
3848
  * @param target Who to follow, as a handle or a network ID.
3674
3849
  * @param options `radius` is how close it tries to stay, in metres; `speed` is the pace.
3675
3850
  * @returns True when the order went out.
@@ -3677,7 +3852,7 @@ declare global {
3677
3852
  follow(target: Player | Npc | number, options?: { speed?: 'walk' | 'jog' | 'run'; radius?: number }): boolean;
3678
3853
 
3679
3854
  /**
3680
- * Sends the NPC away from a place. The one intent that picks its own direction.
3855
+ * Sends the NPC straight away from a place until the requested distance separates them. If the body reports `blocked`, a loaded mesh lets the server try a route to a point past that distance, on the ground at the NPC's own height, before reporting it.
3681
3856
  * @param from What to run away from.
3682
3857
  * @param options `radius` is how far away is far enough; `speed` is the pace, `run` by default.
3683
3858
  * @returns True when the order went out.
@@ -3706,10 +3881,10 @@ declare global {
3706
3881
  *
3707
3882
  * `npcAnimationEnd` fires once when the animation this request started is over, and says how.
3708
3883
  * @param fragment A Mannequin fragment, as `Animations.list` names it -- or, as before, a row of the shipped emote catalog, which plays that gesture once and is not remembered.
3709
- * @param options `tags` pick the variant, `loop` repeats it until stopped, `props` puts up to two models in its hands. `lockMovement` does nothing here: an NPC standing still is its intent's business.
3884
+ * @param options `clip` plays a clip the server streams instead of a fragment (`animations/kcdc/<resource>/wave.caf`, the fragment left `""`), `tags` pick the variant, `loop` repeats it until stopped, `props` puts up to two models in its hands. `lockMovement` does nothing here: an NPC standing still is its intent's business.
3710
3885
  * @returns True when the request went out; false for a dead NPC. Throws for a prop or option it cannot use.
3711
3886
  */
3712
- playAnimation(fragment: string | number, options?: { tags?: string; loop?: boolean; lockMovement?: boolean; props?: { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> } | { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> }[] }): boolean;
3887
+ playAnimation(fragment: string | number, options?: { clip?: string; tags?: string; loop?: boolean; lockMovement?: boolean; props?: { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> } | { item?: string; model?: string; hand?: 'right' | 'left'; joint?: string; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3> }[] }): boolean;
3713
3888
 
3714
3889
  /**
3715
3890
  * Ends what `playAnimation` started at once, takes its props away and hands the body back to its intent. The stand-up `standUp` asks for is an animation of its own and raises its own `npcAnimationEnd`.
@@ -4016,6 +4191,11 @@ declare global {
4016
4191
  */
4017
4192
  readonly resting: boolean;
4018
4193
 
4194
+ /**
4195
+ * Whether this is a prop people carry in their arms -- one a carry put down, or one spawned `carryable` -- rather than stock. Taking it up is a carry: the game's pick-up prompt or `player.carryItem(groundItem)`, never an inventory.
4196
+ */
4197
+ readonly carryable: boolean;
4198
+
4019
4199
  /**
4020
4200
  * Network ID of the player who dropped this stack, or 0 when the server spawned it.
4021
4201
  */
@@ -4044,10 +4224,10 @@ declare global {
4044
4224
  * @param rotation Optional resting orientation: a Quaternion, or a Vector3 of Euler angles in degrees.
4045
4225
  * @param amount Optional number of units in the stack, from 1 to 10000; omitted lays down one. A stack is picked up whole.
4046
4226
  * @param virtualWorld Optional virtual world the stack belongs to; omitted puts it in the global one.
4047
- * @param properties Optional condition of the item itself: `quality` as the game grades it, `health` and `condition` from 0 to 1. Each defaults to the class's own. Arrows and other missile classes are held to tighter bounds by the receiving client and are given a quality of 1 and full health when these are left out, since a stack outside those bounds is one no client would build.
4227
+ * @param properties Optional condition of the item itself: `quality` as the game grades it, `health` and `condition` from 0 to 1. Each defaults to the class's own. Arrows and other missile classes are held to tighter bounds by the receiving client and are given a quality of 1 and full health when these are left out, since a stack outside those bounds is one no client would build. `carryable` makes it a prop people carry in their arms rather than stock: the game's pick-up prompt over it starts a carry (raising `playerCarryingItem`) and never puts it in an inventory. Only for a single item `player.carryItem` takes by name.
4048
4228
  * @returns The newly spawned ground item handle. Throws when the item is not a class in the game's tables, or when no client could build the stack as described.
4049
4229
  */
4050
- static spawn(item: string, position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, amount?: number, virtualWorld?: number, properties?: { quality?: number; health?: number; condition?: number }): GroundItem;
4230
+ static spawn(item: string, position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, amount?: number, virtualWorld?: number, properties?: { quality?: number; health?: number; condition?: number; carryable?: boolean }): GroundItem;
4051
4231
 
4052
4232
  /**
4053
4233
  * Lists every stack lying in the world, however it got there.
@@ -4467,6 +4647,162 @@ declare global {
4467
4647
 
4468
4648
  interface Gate extends Entity {}
4469
4649
 
4650
+ /** */
4651
+ interface SiegeResult {
4652
+ /**
4653
+ * Whether the engine did it.
4654
+ */
4655
+ accepted: boolean;
4656
+
4657
+ /**
4658
+ * Why it did not, as a phrase that reads after the engine's name: `is not loaded`, `cannot fire: the target is further than the engine can throw`. Empty when it did.
4659
+ */
4660
+ reason: string;
4661
+
4662
+ /**
4663
+ * How long until the step it started is over: the whole load for `load`, until the projectile is let go for `fire`. 0 when nothing happened.
4664
+ */
4665
+ seconds: number;
4666
+ }
4667
+
4668
+ /**
4669
+ * Replicated handle for a trebuchet or a cannon.
4670
+ */
4671
+ class SiegeEngine {
4672
+ /**
4673
+ * Creates a script wrapper for an existing siege engine with this ID; use SiegeEngine.spawn() to build one.
4674
+ * @param id Network entity identifier.
4675
+ */
4676
+ constructor(id: number);
4677
+
4678
+ /**
4679
+ * What the engine is: `trebuchet` or `cannon`. The game ships no catapult and no ballista.
4680
+ */
4681
+ readonly kind: string;
4682
+
4683
+ /**
4684
+ * Where the engine is in its cycle: `idle` (unloaded), `drawing` (a trebuchet's arm being winched down), `loading` (the crew laying the projectile), `ready` or `firing`. Named `cycle` because every entity already has a `state`, which is its state bag.
4685
+ */
4686
+ readonly cycle: string;
4687
+
4688
+ /**
4689
+ * Whether the engine is ready to fire.
4690
+ */
4691
+ readonly loaded: boolean;
4692
+
4693
+ /**
4694
+ * How fast the cycle runs, from 0.1 to 20; 1 is the game's own pace, which takes a trebuchet's crew nearly two minutes to load and lets the stone go 3.5 seconds into the shot. Changing it mid-step carries on from where the engine has got to.
4695
+ */
4696
+ speed: number;
4697
+
4698
+ /**
4699
+ * Health taken from anything at the point of impact; a player has 100. A quarter of it reaches the edge of `damageRadius`. 0 leaves hits to `siegeImpact`.
4700
+ */
4701
+ damage: number;
4702
+
4703
+ /**
4704
+ * How far from the point of impact anything is hurt, in metres, up to 100.
4705
+ */
4706
+ damageRadius: number;
4707
+
4708
+ /**
4709
+ * Whether players within 12 m of the engine get the game's own action hint for it on the use key: Load while it is idle, Fire while it is loaded. A press raises `siegeEngineUse`, and unless a handler refuses it the engine loads, or fires along the player's facing at `range`. Off by default.
4710
+ */
4711
+ usable: boolean;
4712
+
4713
+ /**
4714
+ * How far a shot fired from the native prompt goes along the player's facing, in metres; kept between `minRange` and `maxRange`. 150 for a trebuchet and 120 for a cannon to start with.
4715
+ */
4716
+ range: number;
4717
+
4718
+ /**
4719
+ * The closest the engine can be aimed, in metres along the ground.
4720
+ */
4721
+ readonly minRange: number;
4722
+
4723
+ /**
4724
+ * The furthest the engine can be aimed, in metres along the ground.
4725
+ */
4726
+ readonly maxRange: number;
4727
+
4728
+ /**
4729
+ * How long `load` takes at the engine's speed, in seconds.
4730
+ */
4731
+ readonly loadDuration: number;
4732
+
4733
+ /**
4734
+ * Formats this engine handle for logging and debugging.
4735
+ * @returns The engine ID, its kind and where it is in its cycle.
4736
+ */
4737
+ toString(): string;
4738
+
4739
+ /**
4740
+ * Starts the reload cycle of an idle engine. `siegeEngineReady` fires when it can shoot.
4741
+ * @returns What happened, and the phrase to explain it with when nothing did.
4742
+ */
4743
+ load(): SiegeResult;
4744
+
4745
+ /**
4746
+ * Turns a loaded engine to face the target and shoots at it. A trebuchet's arm lets the stone go at one angle, so its speed is solved for the distance; a cannon fires at one speed, so its elevation is. The stone is let go partway through the shot (`seconds`), then every client nearby draws it along the same arc. It comes down where the world stops it, which the player nearest the target is asked to report, or on the target when nobody can.
4747
+ * @param target Where the projectile should come down.
4748
+ * @param attacker The player credited with whatever it hits, in `playerDamage`, `npcDamage` and `siegeImpact`.
4749
+ * @returns What happened, and the phrase to explain it with when nothing did.
4750
+ */
4751
+ fire(target: Vector3 | Partial<Vector3>, attacker?: Player | number | null): SiegeResult;
4752
+
4753
+ /**
4754
+ * Turns the engine to face a point without shooting. `fire` turns it anyway; this is for showing where it will shoot.
4755
+ * @param target The point to turn towards.
4756
+ * @returns What happened, and the phrase to explain it with when nothing did.
4757
+ */
4758
+ aim(target: Vector3 | Partial<Vector3>): SiegeResult;
4759
+
4760
+ /**
4761
+ * Whether the engine can reach a point from where it stands.
4762
+ * @param target The point to test.
4763
+ * @returns Empty when it can; otherwise why not, as a phrase.
4764
+ */
4765
+ canHit(target: Vector3 | Partial<Vector3>): string;
4766
+
4767
+ /**
4768
+ * Removes the engine on every client after emitting `siegeEngineDestroy`. A projectile already in the air still lands.
4769
+ */
4770
+ destroy(): void;
4771
+
4772
+ /**
4773
+ * Builds and replicates a siege engine, unloaded. The trebuchet is the game's own model and plays its own winch, load and fire animations; the cannon is the game's static gun.
4774
+ * @param kind `trebuchet` or `cannon`.
4775
+ * @param position World-space position of the engine's base.
4776
+ * @param rotation Optional initial orientation: a Quaternion, or a Vector3 of Euler angles in degrees. `fire` and `aim` turn it to face their target.
4777
+ * @param virtualWorld Optional virtual world the engine belongs to; omitted puts it in the global one.
4778
+ * @returns The new engine's handle.
4779
+ */
4780
+ static spawn(kind: string, position: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): SiegeEngine;
4781
+
4782
+ /**
4783
+ * Lists the siege engines the server has.
4784
+ * @param virtualWorld Optional virtual world to list; omitted lists every one.
4785
+ * @returns One handle per engine, in no particular order.
4786
+ */
4787
+ static all(virtualWorld?: number): SiegeEngine[];
4788
+
4789
+ /**
4790
+ * Looks an engine up by its network entity ID.
4791
+ * @param id Network entity identifier.
4792
+ * @returns The engine's handle, or null when no live engine has that ID.
4793
+ */
4794
+ static getById(id: number): SiegeEngine | null;
4795
+
4796
+ /**
4797
+ * Removes siege engines, emitting `siegeEngineDestroy` for each one.
4798
+ * @param virtualWorld Optional virtual world to clear; omitted clears every one.
4799
+ * @returns How many were removed.
4800
+ */
4801
+ static destroyAll(virtualWorld?: number): number;
4802
+ }
4803
+
4804
+ interface SiegeEngine extends Entity {}
4805
+
4470
4806
  /** */
4471
4807
  interface AreaDefinition {
4472
4808
  /**
@@ -4477,7 +4813,7 @@ declare global {
4477
4813
  /**
4478
4814
  * A readable name; the id when omitted.
4479
4815
  */
4480
- name: string | undefined;
4816
+ name?: string | undefined;
4481
4817
 
4482
4818
  /**
4483
4819
  * CryEngine's own area shapes: `AreaBox`, `AreaShape` (a closed polygon with a height) and `AreaSphere`.
@@ -4487,57 +4823,57 @@ declare global {
4487
4823
  /**
4488
4824
  * Where the shape is placed from; the origin when omitted.
4489
4825
  */
4490
- position: Vector3 | undefined;
4826
+ position?: Vector3 | undefined;
4491
4827
 
4492
4828
  /**
4493
4829
  * The shape's orientation: a Quaternion or {x, y, z, w}, or Euler angles in degrees.
4494
4830
  */
4495
- rotation: Quaternion | Vector3 | undefined;
4831
+ rotation?: Quaternion | Vector3 | undefined;
4496
4832
 
4497
4833
  /**
4498
4834
  * box: the corner nearest negative infinity, relative to `position` before rotation.
4499
4835
  */
4500
- min: Vector3 | undefined;
4836
+ min?: Vector3 | undefined;
4501
4837
 
4502
4838
  /**
4503
4839
  * box: the opposite corner. Every component must be above `min`'s.
4504
4840
  */
4505
- max: Vector3 | undefined;
4841
+ max?: Vector3 | undefined;
4506
4842
 
4507
4843
  /**
4508
4844
  * shape: 3 to 256 corners relative to `position` before rotation, closed back to the first. As in the engine, the floor is the lowest corner.
4509
4845
  */
4510
- points: Vector3[] | undefined;
4846
+ points?: Vector3[] | undefined;
4511
4847
 
4512
4848
  /**
4513
4849
  * shape: how far above its lowest corner the area reaches; 0, the default, for no ceiling.
4514
4850
  */
4515
- height: number | undefined;
4851
+ height?: number | undefined;
4516
4852
 
4517
4853
  /**
4518
4854
  * sphere: its radius around `position`.
4519
4855
  */
4520
- radius: number | undefined;
4856
+ radius?: number | undefined;
4521
4857
 
4522
4858
  /**
4523
4859
  * Free-form labels, found again with `Area.withLabel`.
4524
4860
  */
4525
- labels: string[] | undefined;
4861
+ labels?: string[] | undefined;
4526
4862
 
4527
4863
  /**
4528
4864
  * Anything JSON can hold, kept on the area for scripts.
4529
4865
  */
4530
- metadata: Record<string, unknown> | undefined;
4866
+ metadata?: Record<string, unknown> | undefined;
4531
4867
 
4532
4868
  /**
4533
4869
  * The one virtual world it belongs to; every world when omitted.
4534
4870
  */
4535
- virtualWorld: number | undefined;
4871
+ virtualWorld?: number | undefined;
4536
4872
 
4537
4873
  /**
4538
4874
  * Whether it starts enabled; true when omitted.
4539
4875
  */
4540
- enabled: boolean | undefined;
4876
+ enabled?: boolean | undefined;
4541
4877
  }
4542
4878
 
4543
4879
  /** */
@@ -4756,32 +5092,32 @@ declare global {
4756
5092
  }
4757
5093
 
4758
5094
  /**
4759
- * Replicated container handle: one a script spawned, or one the level places.
5095
+ * Container handle for a spawned chest, a level chest, or virtual stock without a world entity.
4760
5096
  */
4761
5097
  class Stash {
4762
5098
  /**
4763
- * Creates a script wrapper for an existing container with this ID; use Stash.spawn() to spawn one, or Stash.find() for one the level places.
5099
+ * Creates a script wrapper for an existing container with this ID; use Stash.spawn() for a chest, Stash.createVirtual() for stock without a chest, or Stash.find() for one the level places.
4764
5100
  * @param id Network entity identifier.
4765
5101
  */
4766
5102
  constructor(id: number);
4767
5103
 
4768
5104
  /**
4769
- * The identity every client turns into the same native container, for one a script spawned. Minted by the server from 1, and not `id`, which is the replication entity's. 0 for a container the level places.
5105
+ * The server-minted identity of a scripted chest or virtual stash, from 1. Distinct from the network entity id. Virtual stashes use it for an inventory GUID without creating a chest. 0 for a level chest.
4770
5106
  */
4771
5107
  readonly stashId: number;
4772
5108
 
4773
5109
  /**
4774
- * The EntityGuid every client finds this container under, as sixteen lowercase hex digits: the level's own for a container the level places, the one minted when a script spawned it otherwise. Every container has one, and `Stash.find` takes it back.
5110
+ * The EntityGuid every client finds this container under, as sixteen lowercase hex digits: the level's own for a container the level places, the one minted when a script spawned it otherwise. Empty for virtual stock; `Stash.find` takes physical container GUIDs back.
4775
5111
  */
4776
5112
  readonly guid: string;
4777
5113
 
4778
5114
  /**
4779
- * The level's own EntityGuid for a container the level places, as sixteen lowercase hex digits; empty for one a script spawned. The same on every machine, so it is the identity to store a container under; `Stash.find` takes it back.
5115
+ * The level's own EntityGuid for a container the level places, as sixteen lowercase hex digits; empty for a scripted chest or virtual stock. The same on every machine, so it is the identity to store a container under; `Stash.find` takes it back.
4780
5116
  */
4781
5117
  readonly levelGuid: string;
4782
5118
 
4783
5119
  /**
4784
- * The entity name the level gives the container, or `spawned_stash_<stashId>` for one a script spawned.
5120
+ * The entity name the level gives the container, or `spawned_stash_<stashId>` for a scripted chest; empty for virtual stock.
4785
5121
  */
4786
5122
  readonly name: string;
4787
5123
 
@@ -4791,10 +5127,15 @@ declare global {
4791
5127
  readonly itemCount: number;
4792
5128
 
4793
5129
  /**
4794
- * Whether a player has it open. Every client animates the lid by it.
5130
+ * Whether a player holds its view. Physical chests animate their lid by it; virtual stashes have no lid.
4795
5131
  */
4796
5132
  readonly isOpen: boolean;
4797
5133
 
5134
+ /**
5135
+ * Whether this stash has stock without a chest entity. Open it with open(player); its position and rotation do not govern access, and guid is empty.
5136
+ */
5137
+ readonly isVirtual: boolean;
5138
+
4798
5139
  /**
4799
5140
  * The network ID of the player who has its contents open, or 0. While it is held, every other player's open is refused before their transfer screen appears.
4800
5141
  */
@@ -4837,10 +5178,16 @@ declare global {
4837
5178
  toString(): string;
4838
5179
 
4839
5180
  /**
4840
- * Despawns this container on every client and forgets what was in it. Anything inside goes with it. Does nothing to a container the level places.
5181
+ * Destroys this scripted chest or virtual stash and forgets what was in it. Anything inside goes with it. Does nothing to a container the level places.
4841
5182
  */
4842
5183
  destroy(): void;
4843
5184
 
5185
+ /**
5186
+ * Opens a virtual stash from anywhere in its virtual world. Calls stashInteract before granting exclusive access. Returns false for a physical stash, a locked or busy stash, an unavailable player, or a script refusal. A true result requests the screen; the client releases access if it cannot open.
5187
+ * @param player Player whose native transfer screen should open.
5188
+ */
5189
+ open(player: Player): boolean;
5190
+
4844
5191
  /**
4845
5192
  * Reads what the container holds. A linked child reads its master's.
4846
5193
  * @returns A copy of its rows, or null once the container is gone.
@@ -4862,6 +5209,12 @@ declare global {
4862
5209
  */
4863
5210
  setInventory(request: { items: { id?: string; item: string; amount: number; metadata?: Record<string, unknown> }[]; revision?: number }): InventoryResult;
4864
5211
 
5212
+ /**
5213
+ * Creates empty server-owned stock without spawning a chest on any client. Supports the same inventory methods and events as physical stashes. Use open(player) to show the native transfer screen, and destroy() to discard it. Contents last until destroyed or the server restarts.
5214
+ * @param virtualWorld World whose players may open it, as a uint32 number; defaults to the global world. Invalid values throw before creating stock.
5215
+ */
5216
+ static createVirtual(virtualWorld?: number): Stash;
5217
+
4865
5218
  /**
4866
5219
  * Spawns and replicates an empty container. Fill it with `addItem` or `setInventory`, or let players put things in it.
4867
5220
  * @param position Optional world-space spawn position; omitted components default to zero.
@@ -4872,7 +5225,7 @@ declare global {
4872
5225
  static spawn(position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): Stash;
4873
5226
 
4874
5227
  /**
4875
- * Lists every container the server currently has: every one the level places, which exist from boot in the global world, and every one a script spawned. In another virtual world a level container is built the first time anything there reaches it, so this lists only those.
5228
+ * Lists every container the server currently has: every one the level places, which exist from boot in the global world, and every scripted chest or virtual stash. In another virtual world a level container is built the first time anything there reaches it, so this lists only those.
4876
5229
  * @returns One handle per live container, in no particular order.
4877
5230
  */
4878
5231
  static all(): Stash[];
@@ -4893,7 +5246,7 @@ declare global {
4893
5246
  static find(guid: string, virtualWorld?: number): Stash | null;
4894
5247
 
4895
5248
  /**
4896
- * Finds the container nearest a point, level or spawned. The server knows where every container the level places stands, so this answers at once, without asking a client.
5249
+ * Finds the physical container nearest a point, level or spawned. Virtual stock is excluded. The server knows where every container the level places stands, so this answers at once, without asking a client.
4897
5250
  * @param position The point to measure from, usually a player's position.
4898
5251
  * @param maxDistance How far to look, in metres; omitted looks 5 m, about the reach the game gives a chest.
4899
5252
  * @param virtualWorld Optional virtual world to look in; omitted looks in the global one.
@@ -4902,7 +5255,7 @@ declare global {
4902
5255
  static nearest(position: Vector3 | Partial<Vector3>, maxDistance?: number, virtualWorld?: number): Stash | null;
4903
5256
 
4904
5257
  /**
4905
- * Despawns containers a script spawned, and everything in them with them. The level's own stay.
5258
+ * Destroys scripted chests and virtual stashes, including everything inside. The level's own stay.
4906
5259
  * @param virtualWorld Optional virtual world to clear; omitted clears every one of them.
4907
5260
  * @returns How many containers were removed.
4908
5261
  */
@@ -5108,15 +5461,35 @@ declare global {
5108
5461
  distance: number;
5109
5462
 
5110
5463
  /**
5111
- * The surface type's own name, spelled the way the game's tables spell it -- `mat_wood`, `mat_stone`, `mat_water`. This is what a trace is worth over a position: it says what was hit, not just where. Empty only before the material tables are up.
5464
+ * The surface type's own name, spelled the way the game's tables spell it in `Libs/MaterialEffects/SurfaceTypes.xml` -- `mat_wood`, `mat_rock`, `mat_soil`, `mat_water`. It says what the thing is made of, which is how footsteps and blows sound, not what it is: a plank wall is `mat_wood` as much as a trunk is, so tell a tree by `category`. Among the 74 the game defines: `mat_wood`, `mat_wood_soft`, `mat_vegetation`, `mat_bushes`, `mat_rock`, `mat_rock_unwalk`, `mat_rock_horse_ignore`, `mat_stairs_stone`, `mat_gravel`, `mat_soil`, `mat_mud`, `mat_grass`, `mat_road`, `mat_metal`, `mat_glass`, `mat_plaster`, `mat_thatch`, `mat_fabric`, `mat_flesh`. Empty only before the material tables are up.
5112
5465
  */
5113
5466
  surface: string;
5114
5467
 
5115
5468
  /**
5116
- * Whether the ground itself was hit rather than anything placed on it. Nothing lies behind the terrain, so a trace stops there.
5469
+ * Whether the ground itself was hit rather than anything placed on it. Nothing lies behind the terrain, so a trace stops there. The same as `kind` being `terrain`.
5117
5470
  */
5118
5471
  terrain: boolean;
5119
5472
 
5473
+ /**
5474
+ * What sort of thing the ray stopped on. `entity` is anything with an `entityClass` -- doors, props, NPCs, players. `vegetation` is an instance the level paints on: trees, bushes, plants, and boulders painted the same way. `brush` is a static mesh placed one by one: walls, houses, rocks and cliffs. `static` is static geometry that is neither, or whose source the engine does not record. Trees and rocks are not entities, so for them this, `model` and `category` are what say what was hit.
5475
+ */
5476
+ kind: "terrain" | "entity" | "vegetation" | "brush" | "static";
5477
+
5478
+ /**
5479
+ * The mesh of a vegetation instance or a brush, as the path the game loads it from -- `objects/natural/vegetation/trees/normal_trees/quercus_robur/quercus_robur_big_a.cgf`. Null for terrain, entities and `static`. A tree or a rock has no GUID, but its `model` and `position` together are the same on every client on the same level, which is what a server keeps a felled tree or a mined rock by.
5480
+ */
5481
+ model: string | null;
5482
+
5483
+ /**
5484
+ * Which of the game's own folders of natural objects `model` comes from: `tree` for `objects/natural/vegetation/trees` -- living, dead, fallen and stumps alike, which `model` tells apart -- `bush` for its bushes, `plant` for the rest of its vegetation (grass, ferns, mushrooms, branches), and `rock` for `objects/natural/rocks` and `objects/natural/stones`. Null for anything else, man-made included.
5485
+ */
5486
+ category: "tree" | "bush" | "plant" | "rock" | null;
5487
+
5488
+ /**
5489
+ * The material drawn where the ray met it, as the path the material manager keys it by, the sub-material when the mesh has several -- a trunk's bark rather than the tree's whole material. Null for terrain and when nothing names one.
5490
+ */
5491
+ material: string | null;
5492
+
5120
5493
  /**
5121
5494
  * The level's own identity for what was hit, as sixteen lowercase hex digits -- the same on every machine, and what `Door.find` and the other GUID lookups take. Null for terrain, for static geometry and for anything the session spawned, none of which the level names.
5122
5495
  */
@@ -5213,6 +5586,129 @@ declare global {
5213
5586
  entities: WorldNearbyEntity[];
5214
5587
  }
5215
5588
 
5589
+ /**
5590
+ * A walk across the mesh.
5591
+ */
5592
+ interface NavigationPath {
5593
+ /**
5594
+ * The corners to walk through, first the point on the mesh nearest `from`. Straight lines between them stay on the mesh.
5595
+ */
5596
+ points: Vector3[];
5597
+
5598
+ /**
5599
+ * Whether it reaches `to`. False when `to` cannot be reached, and the path then ends at the nearest point the mesh allows.
5600
+ */
5601
+ complete: boolean;
5602
+
5603
+ /**
5604
+ * Its length in metres.
5605
+ */
5606
+ length: number;
5607
+ }
5608
+
5609
+ /**
5610
+ * How far a straight walk across the mesh gets.
5611
+ */
5612
+ interface NavigationRay {
5613
+ /**
5614
+ * Whether the edge of the mesh -- a wall, a drop, a locked door -- stops it before `to`.
5615
+ */
5616
+ hit: boolean;
5617
+
5618
+ /**
5619
+ * Where it stops: the edge, or the point on the mesh under `to`.
5620
+ */
5621
+ point: Vector3;
5622
+ }
5623
+
5624
+ /**
5625
+ * Queries the level's navigation mesh on the server. The mesh includes walkable floors, bridges and stairs.
5626
+ *
5627
+ * Copy the game's `Data/Levels/<level>/recast.pak` to the server's `files/<level>/` directory. The server searches `files/` recursively at startup. An optional `mod.navmesh` in `server.json` takes priority and can name a game install, level folder or pak file. The game data must be supplied separately. Without a mesh, `ready` is false and geometry queries return null or false. Points are world-space metres, Z up. Every query takes an optional options object. `searchRadius` and `searchHeight` limit how far a point may be from the mesh, across the ground and up or down: 2 metres by default, up to 64, and 4 by default, up to 128. Keep `searchHeight` under a storey's height, or a point on one floor snaps to the floor above. `doors` picks which doors a query walks through: `unlocked`, the default, is how an NPC treats a door -- open or shut, it goes through unless the door is locked; `open` only through doors that stand open; `any` ignores locks; `none` treats every doorway as a wall. A door's state is read off the door in the global world. A field given with the wrong type or out of range throws.
5628
+ */
5629
+ const Navigation: {
5630
+ /**
5631
+ * Whether a mesh loaded from `mod.navmesh` or the server's `files/` directory. False when no usable copy is found; the server log gives the reason.
5632
+ */
5633
+ readonly ready: boolean;
5634
+
5635
+ /**
5636
+ * Available overlay names, sorted. Overlays contain replacement navigation data for quest states. Enabling one replaces the covered part of the mesh. Empty without a mesh.
5637
+ */
5638
+ readonly overlays: string[];
5639
+
5640
+ /**
5641
+ * Enabled overlays in activation order. Initially empty; the level starts with its base mesh.
5642
+ */
5643
+ readonly activeOverlays: string[];
5644
+
5645
+ /**
5646
+ * Snaps a point to the nearest walkable surface.
5647
+ * @param point The point to snap; omitted components default to zero.
5648
+ * @param options How far to look, and which doors count.
5649
+ * @returns The nearest point within the search limits, or null when none is found or no mesh is loaded.
5650
+ */
5651
+ closestPoint(point: Vector3 | Partial<Vector3>, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): Vector3 | null;
5652
+
5653
+ /**
5654
+ * Returns the height of the nearest walkable surface, including upper floors, bridges and stairs.
5655
+ * @param point The point to measure; omitted components default to zero. Its z estimates the floor height and selects the storey.
5656
+ * @param options How far to look.
5657
+ * @returns The height in metres, or null when none is found or no mesh is loaded.
5658
+ */
5659
+ floorAt(point: Vector3 | Partial<Vector3>, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): number | null;
5660
+
5661
+ /**
5662
+ * Plans a path around obstacles on the mesh. Plan when a destination changes; avoid recalculating every NPC's path each tick.
5663
+ * @param from Where the walk starts; omitted components default to zero.
5664
+ * @param to Where it should end; omitted components default to zero.
5665
+ * @param options How far to look for each end, and which doors to walk through.
5666
+ * @returns The path, or null when an endpoint cannot be found, the query fails or no mesh is loaded. A partial path has `complete: false`.
5667
+ */
5668
+ findPath(from: Vector3 | Partial<Vector3>, to: Vector3 | Partial<Vector3>, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): NavigationPath | null;
5669
+
5670
+ /**
5671
+ * Checks reachability by calling `findPath`.
5672
+ * @param from Where the walk starts; omitted components default to zero.
5673
+ * @param to Where it should end; omitted components default to zero.
5674
+ * @param options How far to look for each end, and which doors to walk through.
5675
+ * @returns True when a complete path exists; false otherwise, including when no mesh is loaded.
5676
+ */
5677
+ canReach(from: Vector3 | Partial<Vector3>, to: Vector3 | Partial<Vector3>, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): boolean;
5678
+
5679
+ /**
5680
+ * Checks a straight line across the mesh and reports where it stops.
5681
+ * @param from Where the walk starts; omitted components default to zero.
5682
+ * @param to Where it heads; only its x and y are used, the walk follows the surface.
5683
+ * @param options How far to look for `from`, and which doors let the walk through.
5684
+ * @returns The result, or null when `from` is off the mesh, the query fails or no mesh is loaded.
5685
+ */
5686
+ raycast(from: Vector3 | Partial<Vector3>, to: Vector3 | Partial<Vector3>, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): NavigationRay | null;
5687
+
5688
+ /**
5689
+ * Returns a random walkable point reachable from `center` and no further from it across the ground than `radius`. A point drawn outside the circle is drawn again, a bounded number of times. Without a centre, samples the whole level, choosing each tile with equal probability.
5690
+ * @param center The point to scatter around; it has to be on the mesh, and omitted components default to zero. Omitted entirely, the point can be anywhere on the level's mesh; pass `undefined` for it and for `radius` to give options.
5691
+ * @param radius How far from `center`, in metres, up to 512. Required with a centre.
5692
+ * @param options How far to look for `center`, and which doors the point may lie behind.
5693
+ * @returns The point, or null when `center` is off the mesh, no draw lands within `radius`, the query fails or no mesh is loaded.
5694
+ */
5695
+ randomPoint(center?: Vector3 | Partial<Vector3>, radius?: number, options?: { searchRadius?: number; searchHeight?: number; doors?: "unlocked" | "open" | "any" | "none" }): Vector3 | null;
5696
+
5697
+ /**
5698
+ * Enables an overlay. Where overlays overlap, the last enabled takes precedence. Subsequent queries use the updated mesh.
5699
+ * @param name An entry of `overlays`.
5700
+ * @returns False for a name the level does not ship, one already enabled, one whose tiles cannot be read or loaded (the server log says why), or without a mesh.
5701
+ */
5702
+ enableOverlay(name: string): boolean;
5703
+
5704
+ /**
5705
+ * Disables an overlay, restoring the previous enabled overlay or the base mesh in that area.
5706
+ * @param name An entry of `activeOverlays`.
5707
+ * @returns False for a name that is not enabled, or when part of the area could not be restored (the server log says why); the overlay is disabled either way.
5708
+ */
5709
+ disableOverlay(name: string): boolean;
5710
+ };
5711
+
5216
5712
  /**
5217
5713
  * What the game's own tables say about one status effect.
5218
5714
  */