@kingdomsconnected/types 1.5.2 → 1.5.4

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.
@@ -604,6 +604,11 @@ declare global {
604
604
  */
605
605
  readonly appearance: Appearance;
606
606
 
607
+ /**
608
+ * The prop-catalog mesh this player's body is drawn as, by its `objects/...cgf` path, or null while they look like themselves. Published by their own client, so it follows `setDisguise` once they have actually put it on.
609
+ */
610
+ readonly disguise: string | null;
611
+
607
612
  /**
608
613
  * Whether this player's body has both a pose and a soul, which is what everyone else waits for before spawning a puppet for them. False for the first moments of a connection.
609
614
  */
@@ -1304,6 +1309,11 @@ declare global {
1304
1309
  * This machine's own handle for it. Local to this client and to this session -- it is not the network ID and it is not portable, so store `entityGuid` instead. Null for terrain and static geometry.
1305
1310
  */
1306
1311
  entityId: number | null;
1312
+
1313
+ /**
1314
+ * The player whose body it was -- the local player's own included, when `ignoreSelf` is off -- or null for anything else. Found through the body's own entity, so it holds for a disguised player too: their collider is the mesh's size, and a trace that meets the mesh names them.
1315
+ */
1316
+ player: Player | null;
1307
1317
  }
1308
1318
 
1309
1319
  /**
@@ -1782,7 +1792,7 @@ declare global {
1782
1792
  /**
1783
1793
  * The view this client is drawing through. Nothing here is replicated and nothing here is authority: it describes one machine's own camera at one moment.
1784
1794
  *
1785
- * This is the game's camera, not a camera of the mod's own -- it follows the player, a dialogue, a cutscene or a free flight, whichever the game currently has. `NoClip` is what takes it over.
1795
+ * This is the game's camera, not a camera of the mod's own -- it follows the player, a dialogue, a cutscene or a free flight, whichever the game currently has. `NoClip` is what takes it over, and `setThirdPerson` puts it behind the player.
1786
1796
  */
1787
1797
  const Camera: {
1788
1798
  /**
@@ -1797,6 +1807,24 @@ declare global {
1797
1807
  * @returns The ray, or null when there is no active view.
1798
1808
  */
1799
1809
  screenRay(options?: { x?: number; y?: number; range?: number }): CameraRay | null;
1810
+
1811
+ /**
1812
+ * Puts this player's camera behind them, for as long as it is on.
1813
+ *
1814
+ * The game has no third-person view to switch to, so this is a camera of the mod's own, placed every frame behind the body along the direction the player is looking. Nothing about their controls changes: they walk and turn as they did, and the mouse still turns the body. When a wall is behind them the camera comes in along the same line rather than going through it.
1815
+ *
1816
+ * This is what a disguised player needs -- `player.setDisguise` hides the body the game's own camera sits in. It is this client's own view, so a gamemode turns it on from a client script, typically on an event the server sends the disguised player.
1817
+ *
1818
+ * There is one view to draw through: `NoClip` cannot start while this holds it, and while `NoClip` flies this waits. It lasts until the session ends.
1819
+ * @param options Where the camera sits, in metres: `distance` back from the body along where the player looks (3.5 by default, 0.3 to 20), `height` of the point it orbits above the body's feet (1.6, up to 5 either way), and `shoulder` to the right of it, negative for the left (0, up to 3 either way). Null hands the view back to the game's own camera. Called again while on, it only moves the camera.
1820
+ */
1821
+ setThirdPerson(options?: { distance?: number; height?: number; shoulder?: number } | null): void;
1822
+
1823
+ /**
1824
+ * Whether `setThirdPerson` is on.
1825
+ * @returns True from `setThirdPerson` until it is turned off, also while it waits for a body or for `NoClip`.
1826
+ */
1827
+ isThirdPerson(): boolean;
1800
1828
  };
1801
1829
 
1802
1830
  /**
@@ -168,7 +168,7 @@ declare global {
168
168
  dialogueClosed: [session: number, player: Player, reason: number];
169
169
 
170
170
  /**
171
- * Dispatched once a deal has settled: everything in it has already moved. `balance` is what the player came out with in money units -- positive when the vendor paid them. What the player sold does not join the vendor's stock; add it with `setStock` here if this vendor resells.
171
+ * Dispatched once a deal has settled: everything in it has already moved, in one commit on the player's inventory whose playerInventoryChanged reason is `trade`. `balance` is what the player came out with in money units -- positive when the vendor paid them. What the player sold does not join the vendor's stock; add it with `setStock` here if this vendor resells.
172
172
  */
173
173
  vendorTrade: [vendor: number, player: Player, bought: VendorTradeLine[], sold: VendorTradeLine[], balance: number];
174
174
 
@@ -249,6 +249,31 @@ declare global {
249
249
  */
250
250
  propDestroy: [prop: Prop];
251
251
 
252
+ /**
253
+ * Dispatched immediately after a cart is created and replicated, whether by `Cart.spawn`, the `/cart` command, or anything else.
254
+ */
255
+ cartSpawn: [cart: Cart];
256
+
257
+ /**
258
+ * Dispatched while a cart is being despawned, after everyone in it has been let out. The handle still resolves, so its blueprint and its pose can be read one last time.
259
+ */
260
+ cartDestroy: [cart: Cart];
261
+
262
+ /**
263
+ * Dispatched before a player is put in a seat -- by their own use of the cart's prompt, or `putPlayer`. Return `false` from a handler and the seat is refused: nothing changes, and the player's game never climbs in. Handlers run synchronously.
264
+ */
265
+ cartEntering: [cart: Cart, player: Player, seat: string];
266
+
267
+ /**
268
+ * Dispatched after a player is given a seat. `seat` is `driver` or `back`; a driver's client runs the cart from here on.
269
+ */
270
+ cartEnter: [cart: Cart, player: Player | null, seat: string];
271
+
272
+ /**
273
+ * Dispatched after a player leaves a seat: their own climb down, `removePlayer`, a disconnect, or the cart being destroyed.
274
+ */
275
+ cartExit: [cart: Cart, player: Player | null, seat: string];
276
+
252
277
  /**
253
278
  * Dispatched immediately after a replicated particle effect is placed, whether by `Vfx.spawn`, a command, or anything else.
254
279
  */
@@ -355,11 +380,21 @@ declare global {
355
380
  gatheringHarvested: [player: Player, event: GatheringHarvestedEvent];
356
381
 
357
382
  /**
358
- * Dispatched when a player's client reports working a door, before the server applies it. `action` is `open`, `close`, `lock`, `unlock` or `lockpick`; a key turned in the same use as the push arrives as `unlock` and then `open`. `keySide` says whether the player stood on the side with the keyhole, which is where an unlock needs a key.
383
+ * Dispatched when a player's client reports working a door, before the server applies it. `action` is `open`, `close`, `unlock` or `lockpick`; a key turned in the same use as the push arrives as `unlock` and then `open`. `keySide` says whether the player stood on the side with the keyhole, which is where an unlock needs a key.
359
384
  *
360
385
  * Return false to refuse it: the door is put back on every client, the player's included, and nobody else sees it happen. 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 door the server locked, opening a locked door, picking a door with no keyhole -- so this only sees what the game would allow.
361
386
  */
362
- doorInteract: [player: Player, door: Door, action: "open" | "close" | "lock" | "unlock" | "lockpick", keySide: boolean];
387
+ doorInteract: [player: Player, door: Door, action: "open" | "close" | "unlock" | "lockpick", keySide: boolean];
388
+
389
+ /**
390
+ * 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.
391
+ */
392
+ areaEnter: [area: Area, entity: Player | Horse | Cart | Npc, matchingVirtualWorld: boolean];
393
+
394
+ /**
395
+ * Dispatched when a body stops being inside an area: it walked out, or the area was moved, reshaped, disabled or destroyed. A body that leaves the server entirely -- a player disconnecting, a horse despawned -- raises nothing here; its own event already says it is gone.
396
+ */
397
+ areaExit: [area: Area, entity: Player | Horse | Cart | Npc, matchingVirtualWorld: boolean];
363
398
 
364
399
  /**
365
400
  * 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()`.
@@ -923,6 +958,11 @@ declare global {
923
958
  */
924
959
  readonly appearance: Appearance;
925
960
 
961
+ /**
962
+ * The prop-catalog mesh this player's body is drawn as, by its `objects/...cgf` path, or null while they look like themselves. Published by their own client, so it follows `setDisguise` once they have actually put it on.
963
+ */
964
+ readonly disguise: string | null;
965
+
926
966
  /**
927
967
  * Whether this player's body has both a pose and a soul, which is what everyone else waits for before spawning a puppet for them. False for the first moments of a connection.
928
968
  */
@@ -1410,6 +1450,19 @@ declare global {
1410
1450
  */
1411
1451
  heal(options?: { health?: number | boolean; injuries?: boolean; poisons?: boolean; bleeding?: boolean }): boolean;
1412
1452
 
1453
+ /**
1454
+ * Draws this player as a static mesh instead of themselves -- a barrel, a haystack, a cart wheel -- on their own screen and on everybody else's. It is state: a player who streams in or joins sees it too, and it lasts until the next call.
1455
+ *
1456
+ * Only the look and the collision change. The body is hidden rather than replaced, and its collision cylinder is resized around the mesh, so the player walks and is traced against in roughly the mesh's shape -- a client's `World.raycast` with `mode: "anything"` finds them where the mesh is drawn, and says which player it found. The mesh turns with the body. They keep everything else a person has: they can still be hurt, bleed and die, and nothing stops them drawing a weapon, which a gamemode that does not want that has to take away.
1457
+ *
1458
+ * 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.
1459
+ *
1460
+ * 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.
1461
+ * @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.
1462
+ * @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.
1463
+ */
1464
+ setDisguise(model: string | null): boolean;
1465
+
1413
1466
  /**
1414
1467
  * Takes this player out of whatever saddle they are in: their own client gets them off, and `horseDismount` is raised.
1415
1468
  * @returns The horse they were taken off, or null when they were not riding one.
@@ -1540,7 +1593,7 @@ declare global {
1540
1593
  revision: number;
1541
1594
 
1542
1595
  /**
1543
- * `add`, `remove`, `properties`, `set`, `transfer`, `wear` when the player's game wore an item down in use, `use` for food, potions and ointments, `shot` for a fired round, `pickpocket`, `drop` for `player.dropInventory`, or the ground, stash and gathering reasons.
1596
+ * `add`, `remove`, `properties`, `set`, `transfer`, `wear` when the player's game wore an item down in use, `use` for food, potions and ointments, `shot` for a fired round, `pickpocket`, `trade` for a vendor deal, `drop` for `player.dropInventory`, or the ground, stash and gathering reasons.
1544
1597
  */
1545
1598
  reason: string;
1546
1599
 
@@ -1989,7 +2042,7 @@ declare global {
1989
2042
  create(options?: VendorOptions): number;
1990
2043
 
1991
2044
  /**
1992
- * Closes every session at the vendor and forgets it. A deal already settling still completes.
2045
+ * Closes every session at the vendor and forgets it. A deal settles the moment its basket arrives, so none is ever left half done.
1993
2046
  * @param vendor The vendor to remove.
1994
2047
  * @returns False when there was no such vendor.
1995
2048
  */
@@ -2697,6 +2750,124 @@ declare global {
2697
2750
 
2698
2751
  interface Prop extends Entity {}
2699
2752
 
2753
+ /**
2754
+ * Replicated cart or wagon handle.
2755
+ */
2756
+ class Cart {
2757
+ /**
2758
+ * Creates a script wrapper for an existing cart with this ID; use Cart.spawn() to spawn one.
2759
+ * @param id Network entity identifier.
2760
+ */
2761
+ constructor(id: number);
2762
+
2763
+ /**
2764
+ * The game prefab this cart was built from, e.g. `wagon_b_covered`. `Cart.blueprints()` lists them all.
2765
+ */
2766
+ readonly blueprint: string;
2767
+
2768
+ /**
2769
+ * How many horses the cart is harnessed for: 2 for a wagon, 1 for the two-wheeled cart, 0 for `wagon_b_covered_empty`, whose chassis has nowhere to hitch one and so can be sat in but never pulled.
2770
+ */
2771
+ readonly horseCount: number;
2772
+
2773
+ /**
2774
+ * The player at the reins, or null when nobody drives it.
2775
+ */
2776
+ readonly driver: Player | null;
2777
+
2778
+ /**
2779
+ * How the driver last asked the cart to go: `stand`, `walk`, `trot` or `reverse`.
2780
+ */
2781
+ readonly pace: string;
2782
+
2783
+ /**
2784
+ * Formats this cart handle for logging and debugging.
2785
+ * @returns The cart ID, its blueprint, its driver and its pace.
2786
+ */
2787
+ toString(): string;
2788
+
2789
+ /**
2790
+ * Despawns this cart on every client. Everyone in it is let out first, each with a `cartExit`, then `cartDestroy` is raised.
2791
+ */
2792
+ destroy(): void;
2793
+
2794
+ /**
2795
+ * 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.
2796
+ * @param player The player to seat.
2797
+ * @param seat `driver` (the bench, holding the reins) or `back` (the right rail): the two seats the game animates a player in.
2798
+ * @returns Whether the player was seated: false for a taken seat, a player that is not connected, or a handler's refusal.
2799
+ */
2800
+ putPlayer(player: Player, seat: string): boolean;
2801
+
2802
+ /**
2803
+ * Lets a player out of this cart: their own game climbs down, and `cartExit` is raised.
2804
+ * @param player The player to let out.
2805
+ * @returns False when the player is not in this cart.
2806
+ */
2807
+ removePlayer(player: Player): boolean;
2808
+
2809
+ /**
2810
+ * Who sits in a seat.
2811
+ * @param seat `driver` or `back`.
2812
+ * @returns The player in it, or null when it is empty.
2813
+ */
2814
+ getOccupant(seat: string): Player | null;
2815
+
2816
+ /**
2817
+ * Where a player sits in this cart.
2818
+ * @param player The player to look for.
2819
+ * @returns `driver` or `back`, or null when they are not in it.
2820
+ */
2821
+ seatOf(player: Player): string | null;
2822
+
2823
+ /**
2824
+ * 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.
2825
+ * @param position Where the cart's front axle stands.
2826
+ * @param rotation Which way it faces; omitted keeps its heading.
2827
+ * @returns False for a pose that is not finite.
2828
+ */
2829
+ teleport(position: Vector3, rotation?: Vector3 | Quaternion): boolean;
2830
+
2831
+ /**
2832
+ * 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.
2833
+ * @param blueprint Which of the game's cart prefabs to build; omitted builds `wagon_b_covered`. `Cart.blueprints()` lists them.
2834
+ * @param position Where the cart's front axle stands; omitted components default to zero.
2835
+ * @param rotation Which way it faces: a Quaternion, or a Vector3 of Euler angles in degrees.
2836
+ * @param virtualWorld Optional virtual world the cart belongs to; omitted puts it in the global one.
2837
+ * @returns The newly spawned cart handle.
2838
+ */
2839
+ static spawn(blueprint?: string, position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): Cart;
2840
+
2841
+ /**
2842
+ * Lists the carts the server has.
2843
+ * @param virtualWorld Optional virtual world to list; omitted lists every one.
2844
+ * @returns One handle per live cart, in no particular order.
2845
+ */
2846
+ static all(virtualWorld?: number): Cart[];
2847
+
2848
+ /**
2849
+ * Looks a cart up by its network entity ID.
2850
+ * @param id Network entity identifier.
2851
+ * @returns The cart's handle, or null when no live cart has that ID.
2852
+ */
2853
+ static getById(id: number): Cart | null;
2854
+
2855
+ /**
2856
+ * Despawns carts, emitting cartDestroy for each one.
2857
+ * @param virtualWorld Optional virtual world to clear; omitted clears every one of them.
2858
+ * @returns How many carts were removed.
2859
+ */
2860
+ static destroyAll(virtualWorld?: number): number;
2861
+
2862
+ /**
2863
+ * Names every cart prefab `Cart.spawn` can build.
2864
+ * @returns The blueprint names, in catalog order.
2865
+ */
2866
+ static blueprints(): string[];
2867
+ }
2868
+
2869
+ interface Cart extends Entity {}
2870
+
2700
2871
  /**
2701
2872
  * Replicated particle effect handle.
2702
2873
  */
@@ -3013,6 +3184,173 @@ declare global {
3013
3184
 
3014
3185
  interface Blip extends Entity {}
3015
3186
 
3187
+ /** */
3188
+ interface LevelEditDefinition {
3189
+ /**
3190
+ * 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.
3191
+ */
3192
+ kind: 'brush' | 'entity' | undefined;
3193
+
3194
+ /**
3195
+ * 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.
3196
+ */
3197
+ name: string | undefined;
3198
+
3199
+ /**
3200
+ * An entity's level EntityGuid as sixteen hex digits; required for an entity.
3201
+ */
3202
+ guid: string | undefined;
3203
+
3204
+ /**
3205
+ * An entity's class, kept for reading only.
3206
+ */
3207
+ class: string | undefined;
3208
+
3209
+ /**
3210
+ * Where the level put the object: its pivot, matched within 5 cm. A brush's key, with its mesh.
3211
+ */
3212
+ at: Vector3 | number[];
3213
+
3214
+ /**
3215
+ * Whether it is taken out of the world: not drawn and not solid.
3216
+ */
3217
+ hidden: boolean | undefined;
3218
+
3219
+ /**
3220
+ * Where it stands instead; present, the edit is a move.
3221
+ */
3222
+ position: Vector3 | number[] | undefined;
3223
+
3224
+ /**
3225
+ * A move's orientation: a Quaternion, {x, y, z, w} or [x, y, z, w]. None when omitted.
3226
+ */
3227
+ rotation: Quaternion | number[] | undefined;
3228
+
3229
+ /**
3230
+ * A move's scale per axis, from 0.01 to 100. None when omitted.
3231
+ */
3232
+ scale: Vector3 | number[] | undefined;
3233
+ }
3234
+
3235
+ /**
3236
+ * One change the server makes, for every player, to an object the level itself placed -- a brush or a level entity taken out of the world, moved, or both. It is what a World Builder map's `world` array carries.
3237
+ */
3238
+ class LevelEdit {
3239
+ /**
3240
+ * Wraps an edit the server already holds; use LevelEdit.apply or LevelEdit.applyMap to make one.
3241
+ * @param id Network entity identifier.
3242
+ */
3243
+ constructor(id: number);
3244
+
3245
+ /**
3246
+ * Immutable network entity identifier.
3247
+ */
3248
+ readonly id: number;
3249
+
3250
+ /**
3251
+ * False once the edit has been restored; every other read then returns its empty value.
3252
+ */
3253
+ readonly exists: boolean;
3254
+
3255
+ /**
3256
+ * Whether the object is a brush, found by its mesh and where the level put it, or a level entity, found by its EntityGuid.
3257
+ */
3258
+ readonly kind: 'brush' | 'entity';
3259
+
3260
+ /**
3261
+ * A brush's mesh path, or the name the level gives the entity.
3262
+ */
3263
+ readonly name: string;
3264
+
3265
+ /**
3266
+ * An entity's level EntityGuid as sixteen lowercase hex digits; empty for a brush.
3267
+ */
3268
+ readonly guid: string;
3269
+
3270
+ /**
3271
+ * The virtual world whose players see the edit, fixed when it was applied.
3272
+ */
3273
+ readonly virtualWorld: number;
3274
+
3275
+ /**
3276
+ * Whether the object is taken out of the world: not drawn and not solid. Assignment takes it out or puts it back for every player, keeping any move.
3277
+ */
3278
+ hidden: boolean;
3279
+
3280
+ /**
3281
+ * Whether the object stands somewhere other than where the level placed it; `move` and `clearMove` change it.
3282
+ */
3283
+ readonly moved: boolean;
3284
+
3285
+ /**
3286
+ * Formats this edit for logging and debugging.
3287
+ * @returns Its id, kind, object and what it does to it.
3288
+ */
3289
+ toString(): string;
3290
+
3291
+ /**
3292
+ * Moves the object for every player, collision included.
3293
+ * @param position Where the object stands instead.
3294
+ * @param rotation Its orientation: a Quaternion, or Euler angles in degrees. Left out, it keeps the last move's.
3295
+ * @param scale A uniform scale or one per axis, from 0.01 to 100. Left out, it keeps the last move's.
3296
+ * @returns False for a gone edit or a transform that is not finite.
3297
+ */
3298
+ move(position: Vector3, rotation?: Quaternion | Vector3, scale?: number | Vector3): boolean;
3299
+
3300
+ /**
3301
+ * Puts the object back where the level placed it, keeping it out of the world if the edit takes it out.
3302
+ */
3303
+ clearMove(): void;
3304
+
3305
+ /**
3306
+ * Drops the edit: every player gets the object back exactly as the level had it, collision included.
3307
+ */
3308
+ restore(): void;
3309
+
3310
+ /**
3311
+ * The definition `LevelEdit.apply` takes to make this edit again, which is what a script saves: the server keeps nothing past a restart. It is one entry of a World Builder map's `world` array.
3312
+ * @returns Null once the edit is gone.
3313
+ */
3314
+ toJSON(): LevelEditDefinition | null;
3315
+
3316
+ /**
3317
+ * Takes an object the level placed out of the world, or moves it, for every player in the virtual world -- whenever they join, and however far away they are. Collision goes with it. An edit already made to the same object in that world is restated rather than doubled, so applying one twice changes nothing. Kept in memory only: apply it again on boot.
3318
+ * @param definition The object and what to do to it, in the format of one entry of a World Builder map's `world` array.
3319
+ * @param virtualWorld Optional virtual world whose players see it; the global one when omitted.
3320
+ * @returns The edit. Throws for a definition no client could find the object by.
3321
+ */
3322
+ static apply(definition: LevelEditDefinition, virtualWorld?: number): LevelEdit;
3323
+
3324
+ /**
3325
+ * Applies every entry of a map's `world` array, which is how edits made in the World Builder reach every player instead of being loaded by hand on each.
3326
+ * @param map A World Builder map saved from the editor, as its JSON text or the parsed object. Only its `world` array is read: its placed objects are `Prop.spawn`'s, its areas `Area.create`'s.
3327
+ * @param virtualWorld Optional virtual world whose players see the edits; the global one when omitted.
3328
+ * @returns One edit per entry, in the map's order. Throws, naming the entry, for one no client could find the object by.
3329
+ */
3330
+ static applyMap(map: string | Record<string, unknown>, virtualWorld?: number): LevelEdit[];
3331
+
3332
+ /**
3333
+ * Lists every edit the server currently has.
3334
+ * @param virtualWorld Optional virtual world to list; omitted lists every one of them.
3335
+ * @returns One handle per live edit, in no particular order.
3336
+ */
3337
+ static all(virtualWorld?: number): LevelEdit[];
3338
+
3339
+ /**
3340
+ * Looks an edit up by its network entity ID.
3341
+ * @param id Network entity identifier.
3342
+ * @returns The edit, or null when no live edit has that ID.
3343
+ */
3344
+ static getById(id: number): LevelEdit | null;
3345
+
3346
+ /**
3347
+ * Drops edits, giving every player the objects back as the level had them.
3348
+ * @param virtualWorld Optional virtual world to clear; omitted clears every one of them.
3349
+ * @returns How many edits were dropped.
3350
+ */
3351
+ static restoreAll(virtualWorld?: number): number;
3352
+ }
3353
+
3016
3354
  /**
3017
3355
  * A server-owned NPC: spawned by a resource, simulated by whichever client is nearest.
3018
3356
  */
@@ -3388,30 +3726,44 @@ declare global {
3388
3726
  * @param objective The line, as text or as an object carrying its state.
3389
3727
  * @param announce Whether to raise the quest-updated toast; defaults to true.
3390
3728
  */
3391
- setObjective(index: number, objective: string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean }, announce?: boolean): void;
3729
+ setObjective(index: number, objective: string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean; position?: Vector3 }, announce?: boolean): void;
3392
3730
 
3393
3731
  /**
3394
3732
  * Replaces the quest's objective list.
3395
3733
  * @param objectives The whole list, at most eight entries; anything past that is dropped.
3396
3734
  * @param announce Whether to raise the quest-updated toast; defaults to true.
3397
3735
  */
3398
- setObjectives(objectives: (string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean })[], announce?: boolean): void;
3736
+ setObjectives(objectives: (string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean; position?: Vector3 })[], announce?: boolean): void;
3399
3737
 
3400
3738
  /**
3401
3739
  * Reads the quest's objectives back.
3402
- * @returns One entry per objective, in journal order.
3740
+ * @returns One entry per objective, in journal order. `position` is present only on an objective that has one.
3741
+ */
3742
+ objectives(): { text: string; progress: 'active' | 'done' | 'failed' | 'none'; optional: boolean; position?: Vector3 }[];
3743
+
3744
+ /**
3745
+ * Makes the game follow this quest, exactly as the journal's track button does: it is listed in the HUD tracker, and every active objective that has a `position` is drawn as the game's own quest marker on the map and the compass. It is an instruction, not a lock -- the player can untrack it from the journal -- and the outcome arrives as `questTrackingChanged` like any other change. A quest given a moment ago can be tracked at once; the client waits for it to arrive.
3746
+ * @param player Network id of the player who should follow the quest. Omitted, everyone who has the quest follows it: its one owner, or every player in its world.
3747
+ * @returns How many clients were told. Zero when the player does not have this quest.
3748
+ */
3749
+ track(player?: number): number;
3750
+
3751
+ /**
3752
+ * Makes the game stop following this quest, which takes its markers off the map and the compass. The outcome arrives as `questTrackingChanged`.
3753
+ * @param player Network id of the player who should stop following the quest. Omitted, everyone who has the quest stops.
3754
+ * @returns How many clients were told.
3403
3755
  */
3404
- objectives(): { text: string; progress: 'active' | 'done' | 'failed' | 'none'; optional: boolean }[];
3756
+ untrack(player?: number): number;
3405
3757
 
3406
3758
  /**
3407
3759
  * Writes a quest into the game's own journal. It is a replicated entity, so a player who joins late, reloads or walks away still finds it in their log -- which is what a quest needs and what a one-shot notification cannot do. What the player sees is the game's quest UI: its journal row, its diary page, its objective tracker and its quest-updated toast, all reading a quest node the client builds with the game's own constructor.
3408
3760
  * @param key What the quest is filed under: up to 64 letters, digits, underscores or dashes, unique within its virtual world.
3409
3761
  * @param title The line the journal row shows.
3410
- * @param options `description` is the diary page, `type` the journal section, `objectives` the lines under it, `player` the network id of the one player it belongs to, and `announce` whether to raise the toast.
3762
+ * @param options `description` is the diary page, `type` the journal section, `objectives` the lines under it -- each with an optional world `position` the game marks on the map and compass while the quest is followed -- `player` the network id of the one player it belongs to, `announce` whether to raise the toast, and `track` whether its recipients start following it.
3411
3763
  * @param virtualWorld Optional virtual world the quest belongs to; omitted puts it in the global one.
3412
3764
  * @returns The newly written quest handle.
3413
3765
  */
3414
- static give(key: string, title: string, options?: { description?: string; type?: 'main' | 'side' | 'activity' | 'event' | 'micro' | 'racing'; objectives?: (string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean })[]; player?: number; announce?: boolean }, virtualWorld?: number): Quest;
3766
+ static give(key: string, title: string, options?: { description?: string; type?: 'main' | 'side' | 'activity' | 'event' | 'micro' | 'racing'; objectives?: (string | { text: string; progress?: 'active' | 'done' | 'failed'; optional?: boolean; position?: Vector3 })[]; player?: number; announce?: boolean; track?: boolean }, virtualWorld?: number): Quest;
3415
3767
 
3416
3768
  /**
3417
3769
  * Lists every replicated quest the server currently has.
@@ -3705,6 +4057,11 @@ declare global {
3705
4057
  */
3706
4058
  readonly lockpickable: boolean;
3707
4059
 
4060
+ /**
4061
+ * The level areas that link this door as one of their `crime_door`s -- the house, workshop or storage room it belongs to, as the level itself records it. Nothing is inferred from where the door stands.
4062
+ */
4063
+ readonly areas: Area[];
4064
+
3708
4065
  /**
3709
4066
  * Whether the level builds this door locked, which is the state it has at boot.
3710
4067
  */
@@ -3745,6 +4102,13 @@ declare global {
3745
4102
  */
3746
4103
  static find(guid: string, virtualWorld?: number): Door | null;
3747
4104
 
4105
+ /**
4106
+ * Lists the doors the level links to an area as its `crime_door`s, with their GUID, name, position and link type, straight from the level catalog -- so a door that no client has reported yet is listed too. Pass a `guid` to `Door.find` for the live handle and its `locked` state. Only native links: a script area has none.
4107
+ * @param areaId The area's id, as `area.id` prints it.
4108
+ * @returns The doors; empty for an unknown area or one with no links.
4109
+ */
4110
+ static getForArea(areaId: string): AreaDoor[];
4111
+
3748
4112
  /**
3749
4113
  * Asks a player's client which door their body is standing at. The server knows every door the level places but has no world to measure distances in, so this is how a command finds the door in front of a player, and the answer is what that client sees now rather than what the replica last carried.
3750
4114
  *
@@ -3871,6 +4235,294 @@ declare global {
3871
4235
 
3872
4236
  interface Gate extends Entity {}
3873
4237
 
4238
+ /** */
4239
+ interface AreaDefinition {
4240
+ /**
4241
+ * The area's identity, unique among script areas. It may not be sixteen hex digits, which is how a level area's GUID reads.
4242
+ */
4243
+ id: string;
4244
+
4245
+ /**
4246
+ * A readable name; the id when omitted.
4247
+ */
4248
+ name: string | undefined;
4249
+
4250
+ /**
4251
+ * CryEngine's own area shapes: `AreaBox`, `AreaShape` (a closed polygon with a height) and `AreaSphere`.
4252
+ */
4253
+ type: 'box' | 'shape' | 'sphere';
4254
+
4255
+ /**
4256
+ * Where the shape is placed from; the origin when omitted.
4257
+ */
4258
+ position: Vector3 | undefined;
4259
+
4260
+ /**
4261
+ * The shape's orientation: a Quaternion or {x, y, z, w}, or Euler angles in degrees.
4262
+ */
4263
+ rotation: Quaternion | Vector3 | undefined;
4264
+
4265
+ /**
4266
+ * box: the corner nearest negative infinity, relative to `position` before rotation.
4267
+ */
4268
+ min: Vector3 | undefined;
4269
+
4270
+ /**
4271
+ * box: the opposite corner. Every component must be above `min`'s.
4272
+ */
4273
+ max: Vector3 | undefined;
4274
+
4275
+ /**
4276
+ * 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.
4277
+ */
4278
+ points: Vector3[] | undefined;
4279
+
4280
+ /**
4281
+ * shape: how far above its lowest corner the area reaches; 0, the default, for no ceiling.
4282
+ */
4283
+ height: number | undefined;
4284
+
4285
+ /**
4286
+ * sphere: its radius around `position`.
4287
+ */
4288
+ radius: number | undefined;
4289
+
4290
+ /**
4291
+ * Free-form labels, found again with `Area.withLabel`.
4292
+ */
4293
+ labels: string[] | undefined;
4294
+
4295
+ /**
4296
+ * Anything JSON can hold, kept on the area for scripts.
4297
+ */
4298
+ metadata: Record<string, unknown> | undefined;
4299
+
4300
+ /**
4301
+ * The one virtual world it belongs to; every world when omitted.
4302
+ */
4303
+ virtualWorld: number | undefined;
4304
+
4305
+ /**
4306
+ * Whether it starts enabled; true when omitted.
4307
+ */
4308
+ enabled: boolean | undefined;
4309
+ }
4310
+
4311
+ /** */
4312
+ interface AreaDoor {
4313
+ /**
4314
+ * The door's level EntityGuid as hex, which `Door.find` takes.
4315
+ */
4316
+ guid: string;
4317
+
4318
+ /**
4319
+ * The entity name the level gives the door.
4320
+ */
4321
+ name: string;
4322
+
4323
+ /**
4324
+ * Where the level places the door.
4325
+ */
4326
+ position: Vector3;
4327
+
4328
+ /**
4329
+ * The `crime_doorKind` the level gives the link: the way in, an inner door, or a storage room's.
4330
+ */
4331
+ link: 'entrance' | 'basic' | 'storage';
4332
+ }
4333
+
4334
+ /**
4335
+ * Handle for one area: one of the level's own gameplay areas, or one a script or the World Builder drew. The server tests who is inside itself, by the game's own rule for that kind of area.
4336
+ */
4337
+ class Area {
4338
+ /**
4339
+ * Wraps an area handle the server already holds; use Area.create, Area.getById or the lookups to get one.
4340
+ * @param handle Internal area handle.
4341
+ */
4342
+ constructor(handle: number);
4343
+
4344
+ /**
4345
+ * False once a script area has been destroyed; every other read then returns its empty value.
4346
+ */
4347
+ readonly exists: boolean;
4348
+
4349
+ /**
4350
+ * The stable identity to store an area under. A level area's is its EntityGuid as sixteen lowercase hex digits, the same on every machine and every boot, as `door.guid` prints a door's; a script area's is the id it was created with.
4351
+ */
4352
+ readonly id: string;
4353
+
4354
+ /**
4355
+ * Whether the level placed it or a script built it.
4356
+ */
4357
+ readonly kind: 'level' | 'script';
4358
+
4359
+ /**
4360
+ * A level area's entity class -- a `TriggerArea` prism, an `AreaUnion` of them, or a `SmartAreaShape` -- or a script area's shape.
4361
+ */
4362
+ readonly type: 'TriggerArea' | 'AreaUnion' | 'SmartAreaShape' | 'box' | 'shape' | 'sphere';
4363
+
4364
+ /**
4365
+ * The level's entity name, or the script area's name. Only a script area's can be changed.
4366
+ */
4367
+ name: string;
4368
+
4369
+ /**
4370
+ * The level's own `Label` values -- `private`, `personal`, `interior`, `prohibited`, `castle` and the rest the game's AI reads -- or a script area's labels. Only a script area's can be changed.
4371
+ */
4372
+ labels: string[];
4373
+
4374
+ /**
4375
+ * Whatever a script keeps on a script area: ownership, a type, rules. Stored as JSON, so read it, change it and assign it back. Always empty on a level area.
4376
+ */
4377
+ metadata: Record<string, unknown>;
4378
+
4379
+ /**
4380
+ * Whether crossings are raised and the lookups find it. Switching it off raises `areaExit` for everyone inside on the next tick; switching it on, `areaEnter`. Works on level areas too.
4381
+ */
4382
+ enabled: boolean;
4383
+
4384
+ /**
4385
+ * The one virtual world a script area belongs to, or null for all of them. A body in another world still crosses it, with `matchingVirtualWorld` false. A level area is in every world.
4386
+ */
4387
+ virtualWorld: number | null;
4388
+
4389
+ /**
4390
+ * A script area's origin, which its shape is placed from; assignment moves it. A level area's is the centre of its bounds.
4391
+ */
4392
+ position: Vector3;
4393
+
4394
+ /**
4395
+ * A script area's orientation; assignment turns it. A level area's shape is already in world space, so its rotation is the identity.
4396
+ */
4397
+ rotation: Quaternion;
4398
+
4399
+ /**
4400
+ * How far above its lowest point a prism reaches, in metres; 0 for a shape with no ceiling. A TriggerArea's comes from the level's baked prism.
4401
+ */
4402
+ readonly height: number;
4403
+
4404
+ /**
4405
+ * For a SmartAreaShape bound to one of the game's map locations, that location's English name, e.g. a settlement. Empty otherwise.
4406
+ */
4407
+ readonly location: string;
4408
+
4409
+ /**
4410
+ * The world box around the area. An area with no ceiling reaches far above and below.
4411
+ */
4412
+ readonly bounds: { min: Vector3; max: Vector3 };
4413
+
4414
+ /**
4415
+ * For an AreaUnion, the TriggerAreas it joins; it contains whatever one of them does. Empty otherwise.
4416
+ */
4417
+ readonly members: Area[];
4418
+
4419
+ /**
4420
+ * The doors the level itself links to this area as its `crime_door`s, which is how the game knows a house's doors. Only native links: nothing is inferred from where a door stands.
4421
+ */
4422
+ readonly doors: AreaDoor[];
4423
+
4424
+ /**
4425
+ * Every player inside as of the last tick, in any world.
4426
+ */
4427
+ readonly players: Player[];
4428
+
4429
+ /**
4430
+ * Every body inside as of the last tick: players, horses, carts and server NPCs.
4431
+ */
4432
+ readonly occupants: (Player | Horse | Cart | Npc)[];
4433
+
4434
+ /**
4435
+ * Formats this area for logging and debugging.
4436
+ * @returns Its id, kind, type and name.
4437
+ */
4438
+ toString(): string;
4439
+
4440
+ /**
4441
+ * Tests a position the way the game tests its own areas, whether or not the area is enabled and in whatever world.
4442
+ * @param position The world position to test.
4443
+ * @returns True when the position is inside.
4444
+ */
4445
+ contains(position: Vector3): boolean;
4446
+
4447
+ /**
4448
+ * Tests where a body stands right now, and in which world: an area bound to another virtual world does not contain it. This is containment only -- whether the game considers the player to be trespassing is decided by its own crime system on the player's client.
4449
+ * @param player The body to test; a player who has not reported a pose yet is never inside.
4450
+ * @returns True when the body is inside.
4451
+ */
4452
+ containsPlayer(player: Player | Horse | Cart | Npc): boolean;
4453
+
4454
+ /**
4455
+ * Moves, turns or reshapes a script area. Bodies standing where it now is, or was, get their `areaEnter` and `areaExit` on the next tick. A level area cannot be reshaped.
4456
+ * @param definition The shape fields to change; any left out keep their value. `id`, `labels`, `metadata` and the rest are ignored here.
4457
+ * @returns False for a level area, a gone one, or a shape the engine could not build.
4458
+ */
4459
+ setShape(definition: Partial<AreaDefinition>): boolean;
4460
+
4461
+ /**
4462
+ * Removes a script area. Every body still inside gets its `areaExit` first, while the handle still resolves.
4463
+ * @returns False for a level area or one already gone.
4464
+ */
4465
+ destroy(): boolean;
4466
+
4467
+ /**
4468
+ * The definition `Area.create` takes to build this area again, which is what a script saves: the server keeps nothing past a restart. It is the format the World Builder exports too.
4469
+ * @returns Null for a level area, which the level always builds.
4470
+ */
4471
+ toJSON(): AreaDefinition | null;
4472
+
4473
+ /**
4474
+ * Builds a script area. Bodies already standing in it get `areaEnter` on the next tick. Kept in memory only: save `area.toJSON()` wherever the resource keeps its data, and create it again on boot.
4475
+ * @param definition The area to build, in the format `area.toJSON()` and the World Builder export write.
4476
+ * @returns The new area. Throws for an id already taken or a shape the engine could not build.
4477
+ */
4478
+ static create(definition: AreaDefinition): Area;
4479
+
4480
+ /**
4481
+ * Looks an area up by its stable identity.
4482
+ * @param id A script area's id, or a level area's GUID in hex as `area.definition.id` prints it.
4483
+ * @returns The area, or null when there is none.
4484
+ */
4485
+ static getById(id: string): Area | null;
4486
+
4487
+ /**
4488
+ * Every enabled area containing a position, level and script alike.
4489
+ * @param position The world position to test.
4490
+ * @param virtualWorld Optional world; when given, a script area bound to another world is left out.
4491
+ * @returns The areas, in no particular order.
4492
+ */
4493
+ static getAt(position: Vector3, virtualWorld?: number): Area[];
4494
+
4495
+ /**
4496
+ * Every enabled area the body stands in right now, in its own world.
4497
+ * @param player The body whose position and world to test.
4498
+ * @returns The areas; empty for a player who has not reported a pose yet.
4499
+ */
4500
+ static getAtPlayer(player: Player | Horse | Cart | Npc): Area[];
4501
+
4502
+ /**
4503
+ * Every area whose bounds come within a radius of a position, enabled or not.
4504
+ * @param position Where to look from.
4505
+ * @param radius How far, in metres, from the area's bounds.
4506
+ * @param virtualWorld Optional world; when given, a script area bound to another world is left out.
4507
+ * @returns The areas, nearest first.
4508
+ */
4509
+ static nearby(position: Vector3, radius: number, virtualWorld?: number): Area[];
4510
+
4511
+ /**
4512
+ * Every area carrying a label, such as `private` or `castle`.
4513
+ * @param label The label, compared without regard to case.
4514
+ * @returns The areas, level ones first.
4515
+ */
4516
+ static withLabel(label: string): Area[];
4517
+
4518
+ /**
4519
+ * Every area the server knows.
4520
+ * @param kind Optional: only the level's areas, or only script ones.
4521
+ * @returns The areas, level ones first.
4522
+ */
4523
+ static all(kind?: 'level' | 'script'): Area[];
4524
+ }
4525
+
3874
4526
  /**
3875
4527
  * Replicated container handle: one a script spawned, or one the level places.
3876
4528
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kingdomsconnected/types",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "TypeScript declarations for the Kingdoms Connected scripting API, one entry per side: @kingdomsconnected/types/server and @kingdomsconnected/types/client",
5
5
  "license": "UNLICENSED",
6
6
  "keywords": [