@kingdomsconnected/types 1.5.7 → 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
  */
@@ -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.
@@ -3329,22 +3488,22 @@ declare global {
3329
3488
  /**
3330
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.
3331
3490
  */
3332
- kind: 'brush' | 'entity' | undefined;
3491
+ kind?: 'brush' | 'entity' | undefined;
3333
3492
 
3334
3493
  /**
3335
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.
3336
3495
  */
3337
- name: string | undefined;
3496
+ name?: string | undefined;
3338
3497
 
3339
3498
  /**
3340
3499
  * An entity's level EntityGuid as sixteen hex digits; required for an entity.
3341
3500
  */
3342
- guid: string | undefined;
3501
+ guid?: string | undefined;
3343
3502
 
3344
3503
  /**
3345
3504
  * An entity's class, kept for reading only.
3346
3505
  */
3347
- class: string | undefined;
3506
+ class?: string | undefined;
3348
3507
 
3349
3508
  /**
3350
3509
  * Where the level put the object: its pivot, matched within 5 cm. A brush's key, with its mesh.
@@ -3354,22 +3513,22 @@ declare global {
3354
3513
  /**
3355
3514
  * Whether it is taken out of the world: not drawn and not solid.
3356
3515
  */
3357
- hidden: boolean | undefined;
3516
+ hidden?: boolean | undefined;
3358
3517
 
3359
3518
  /**
3360
3519
  * Where it stands instead; present, the edit is a move.
3361
3520
  */
3362
- position: Vector3 | number[] | undefined;
3521
+ position?: Vector3 | number[] | undefined;
3363
3522
 
3364
3523
  /**
3365
3524
  * A move's orientation: a Quaternion, {x, y, z, w} or [x, y, z, w]. None when omitted.
3366
3525
  */
3367
- rotation: Quaternion | number[] | undefined;
3526
+ rotation?: Quaternion | number[] | undefined;
3368
3527
 
3369
3528
  /**
3370
3529
  * A move's scale per axis, from 0.01 to 100. None when omitted.
3371
3530
  */
3372
- scale: Vector3 | number[] | undefined;
3531
+ scale?: Vector3 | number[] | undefined;
3373
3532
  }
3374
3533
 
3375
3534
  /**
@@ -3722,10 +3881,10 @@ declare global {
3722
3881
  *
3723
3882
  * `npcAnimationEnd` fires once when the animation this request started is over, and says how.
3724
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.
3725
- * @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.
3726
3885
  * @returns True when the request went out; false for a dead NPC. Throws for a prop or option it cannot use.
3727
3886
  */
3728
- 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;
3729
3888
 
3730
3889
  /**
3731
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`.
@@ -4032,6 +4191,11 @@ declare global {
4032
4191
  */
4033
4192
  readonly resting: boolean;
4034
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
+
4035
4199
  /**
4036
4200
  * Network ID of the player who dropped this stack, or 0 when the server spawned it.
4037
4201
  */
@@ -4060,10 +4224,10 @@ declare global {
4060
4224
  * @param rotation Optional resting orientation: a Quaternion, or a Vector3 of Euler angles in degrees.
4061
4225
  * @param amount Optional number of units in the stack, from 1 to 10000; omitted lays down one. A stack is picked up whole.
4062
4226
  * @param virtualWorld Optional virtual world the stack belongs to; omitted puts it in the global one.
4063
- * @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.
4064
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.
4065
4229
  */
4066
- 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;
4067
4231
 
4068
4232
  /**
4069
4233
  * Lists every stack lying in the world, however it got there.
@@ -4483,6 +4647,162 @@ declare global {
4483
4647
 
4484
4648
  interface Gate extends Entity {}
4485
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
+
4486
4806
  /** */
4487
4807
  interface AreaDefinition {
4488
4808
  /**
@@ -4493,7 +4813,7 @@ declare global {
4493
4813
  /**
4494
4814
  * A readable name; the id when omitted.
4495
4815
  */
4496
- name: string | undefined;
4816
+ name?: string | undefined;
4497
4817
 
4498
4818
  /**
4499
4819
  * CryEngine's own area shapes: `AreaBox`, `AreaShape` (a closed polygon with a height) and `AreaSphere`.
@@ -4503,57 +4823,57 @@ declare global {
4503
4823
  /**
4504
4824
  * Where the shape is placed from; the origin when omitted.
4505
4825
  */
4506
- position: Vector3 | undefined;
4826
+ position?: Vector3 | undefined;
4507
4827
 
4508
4828
  /**
4509
4829
  * The shape's orientation: a Quaternion or {x, y, z, w}, or Euler angles in degrees.
4510
4830
  */
4511
- rotation: Quaternion | Vector3 | undefined;
4831
+ rotation?: Quaternion | Vector3 | undefined;
4512
4832
 
4513
4833
  /**
4514
4834
  * box: the corner nearest negative infinity, relative to `position` before rotation.
4515
4835
  */
4516
- min: Vector3 | undefined;
4836
+ min?: Vector3 | undefined;
4517
4837
 
4518
4838
  /**
4519
4839
  * box: the opposite corner. Every component must be above `min`'s.
4520
4840
  */
4521
- max: Vector3 | undefined;
4841
+ max?: Vector3 | undefined;
4522
4842
 
4523
4843
  /**
4524
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.
4525
4845
  */
4526
- points: Vector3[] | undefined;
4846
+ points?: Vector3[] | undefined;
4527
4847
 
4528
4848
  /**
4529
4849
  * shape: how far above its lowest corner the area reaches; 0, the default, for no ceiling.
4530
4850
  */
4531
- height: number | undefined;
4851
+ height?: number | undefined;
4532
4852
 
4533
4853
  /**
4534
4854
  * sphere: its radius around `position`.
4535
4855
  */
4536
- radius: number | undefined;
4856
+ radius?: number | undefined;
4537
4857
 
4538
4858
  /**
4539
4859
  * Free-form labels, found again with `Area.withLabel`.
4540
4860
  */
4541
- labels: string[] | undefined;
4861
+ labels?: string[] | undefined;
4542
4862
 
4543
4863
  /**
4544
4864
  * Anything JSON can hold, kept on the area for scripts.
4545
4865
  */
4546
- metadata: Record<string, unknown> | undefined;
4866
+ metadata?: Record<string, unknown> | undefined;
4547
4867
 
4548
4868
  /**
4549
4869
  * The one virtual world it belongs to; every world when omitted.
4550
4870
  */
4551
- virtualWorld: number | undefined;
4871
+ virtualWorld?: number | undefined;
4552
4872
 
4553
4873
  /**
4554
4874
  * Whether it starts enabled; true when omitted.
4555
4875
  */
4556
- enabled: boolean | undefined;
4876
+ enabled?: boolean | undefined;
4557
4877
  }
4558
4878
 
4559
4879
  /** */
@@ -4772,32 +5092,32 @@ declare global {
4772
5092
  }
4773
5093
 
4774
5094
  /**
4775
- * 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.
4776
5096
  */
4777
5097
  class Stash {
4778
5098
  /**
4779
- * 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.
4780
5100
  * @param id Network entity identifier.
4781
5101
  */
4782
5102
  constructor(id: number);
4783
5103
 
4784
5104
  /**
4785
- * 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.
4786
5106
  */
4787
5107
  readonly stashId: number;
4788
5108
 
4789
5109
  /**
4790
- * 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.
4791
5111
  */
4792
5112
  readonly guid: string;
4793
5113
 
4794
5114
  /**
4795
- * 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.
4796
5116
  */
4797
5117
  readonly levelGuid: string;
4798
5118
 
4799
5119
  /**
4800
- * 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.
4801
5121
  */
4802
5122
  readonly name: string;
4803
5123
 
@@ -4807,10 +5127,15 @@ declare global {
4807
5127
  readonly itemCount: number;
4808
5128
 
4809
5129
  /**
4810
- * 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.
4811
5131
  */
4812
5132
  readonly isOpen: boolean;
4813
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
+
4814
5139
  /**
4815
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.
4816
5141
  */
@@ -4853,10 +5178,16 @@ declare global {
4853
5178
  toString(): string;
4854
5179
 
4855
5180
  /**
4856
- * 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.
4857
5182
  */
4858
5183
  destroy(): void;
4859
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
+
4860
5191
  /**
4861
5192
  * Reads what the container holds. A linked child reads its master's.
4862
5193
  * @returns A copy of its rows, or null once the container is gone.
@@ -4878,6 +5209,12 @@ declare global {
4878
5209
  */
4879
5210
  setInventory(request: { items: { id?: string; item: string; amount: number; metadata?: Record<string, unknown> }[]; revision?: number }): InventoryResult;
4880
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
+
4881
5218
  /**
4882
5219
  * Spawns and replicates an empty container. Fill it with `addItem` or `setInventory`, or let players put things in it.
4883
5220
  * @param position Optional world-space spawn position; omitted components default to zero.
@@ -4888,7 +5225,7 @@ declare global {
4888
5225
  static spawn(position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): Stash;
4889
5226
 
4890
5227
  /**
4891
- * 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.
4892
5229
  * @returns One handle per live container, in no particular order.
4893
5230
  */
4894
5231
  static all(): Stash[];
@@ -4909,7 +5246,7 @@ declare global {
4909
5246
  static find(guid: string, virtualWorld?: number): Stash | null;
4910
5247
 
4911
5248
  /**
4912
- * 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.
4913
5250
  * @param position The point to measure from, usually a player's position.
4914
5251
  * @param maxDistance How far to look, in metres; omitted looks 5 m, about the reach the game gives a chest.
4915
5252
  * @param virtualWorld Optional virtual world to look in; omitted looks in the global one.
@@ -4918,7 +5255,7 @@ declare global {
4918
5255
  static nearest(position: Vector3 | Partial<Vector3>, maxDistance?: number, virtualWorld?: number): Stash | null;
4919
5256
 
4920
5257
  /**
4921
- * 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.
4922
5259
  * @param virtualWorld Optional virtual world to clear; omitted clears every one of them.
4923
5260
  * @returns How many containers were removed.
4924
5261
  */
@@ -5124,15 +5461,35 @@ declare global {
5124
5461
  distance: number;
5125
5462
 
5126
5463
  /**
5127
- * 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.
5128
5465
  */
5129
5466
  surface: string;
5130
5467
 
5131
5468
  /**
5132
- * 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`.
5133
5470
  */
5134
5471
  terrain: boolean;
5135
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
+
5136
5493
  /**
5137
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.
5138
5495
  */