@sagl/server 0.0.0-stage → 0.1.0-next.51

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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -2
  3. package/dist/actions.d.ts +46 -0
  4. package/dist/actions.js +80 -0
  5. package/dist/actions.js.map +1 -0
  6. package/dist/animations.d.ts +32 -0
  7. package/dist/animations.js +95 -0
  8. package/dist/animations.js.map +1 -0
  9. package/dist/audio.d.ts +180 -0
  10. package/dist/audio.js +353 -0
  11. package/dist/audio.js.map +1 -0
  12. package/dist/audio_effects.d.ts +219 -0
  13. package/dist/audio_effects.js +84 -0
  14. package/dist/audio_effects.js.map +1 -0
  15. package/dist/camera.d.ts +188 -0
  16. package/dist/camera.js +247 -0
  17. package/dist/camera.js.map +1 -0
  18. package/dist/claims.d.ts +27 -0
  19. package/dist/claims.js +48 -0
  20. package/dist/claims.js.map +1 -0
  21. package/dist/commands.d.ts +135 -0
  22. package/dist/commands.js +373 -0
  23. package/dist/commands.js.map +1 -0
  24. package/dist/console.d.ts +21 -0
  25. package/dist/console.js +100 -0
  26. package/dist/console.js.map +1 -0
  27. package/dist/constants.d.ts +654 -0
  28. package/dist/constants.js +657 -0
  29. package/dist/constants.js.map +1 -0
  30. package/dist/cutscene.d.ts +47 -0
  31. package/dist/cutscene.js +190 -0
  32. package/dist/cutscene.js.map +1 -0
  33. package/dist/draw.d.ts +106 -0
  34. package/dist/draw.js +132 -0
  35. package/dist/draw.js.map +1 -0
  36. package/dist/effects.d.ts +91 -0
  37. package/dist/effects.js +116 -0
  38. package/dist/effects.js.map +1 -0
  39. package/dist/gangzones.d.ts +47 -0
  40. package/dist/gangzones.js +122 -0
  41. package/dist/gangzones.js.map +1 -0
  42. package/dist/geo.d.ts +11 -0
  43. package/dist/geo.js +25 -0
  44. package/dist/geo.js.map +1 -0
  45. package/dist/hud.d.ts +159 -0
  46. package/dist/hud.js +247 -0
  47. package/dist/hud.js.map +1 -0
  48. package/dist/index.d.ts +40 -0
  49. package/dist/index.js +43 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/interaction.d.ts +81 -0
  52. package/dist/interaction.js +143 -0
  53. package/dist/interaction.js.map +1 -0
  54. package/dist/junctions.d.ts +1 -0
  55. package/dist/junctions.js +330 -0
  56. package/dist/junctions.js.map +1 -0
  57. package/dist/map.d.ts +55 -0
  58. package/dist/map.js +71 -0
  59. package/dist/map.js.map +1 -0
  60. package/dist/menu.d.ts +96 -0
  61. package/dist/menu.js +129 -0
  62. package/dist/menu.js.map +1 -0
  63. package/dist/mission.d.ts +482 -0
  64. package/dist/mission.js +1258 -0
  65. package/dist/mission.js.map +1 -0
  66. package/dist/models.d.ts +56 -0
  67. package/dist/models.js +71 -0
  68. package/dist/models.js.map +1 -0
  69. package/dist/modshop.d.ts +229 -0
  70. package/dist/modshop.js +904 -0
  71. package/dist/modshop.js.map +1 -0
  72. package/dist/modshop_data.d.ts +44 -0
  73. package/dist/modshop_data.js +287 -0
  74. package/dist/modshop_data.js.map +1 -0
  75. package/dist/native.d.ts +809 -0
  76. package/dist/native.js +27 -0
  77. package/dist/native.js.map +1 -0
  78. package/dist/objects.d.ts +249 -0
  79. package/dist/objects.js +455 -0
  80. package/dist/objects.js.map +1 -0
  81. package/dist/paint.d.ts +124 -0
  82. package/dist/paint.js +84 -0
  83. package/dist/paint.js.map +1 -0
  84. package/dist/paynspray.d.ts +44 -0
  85. package/dist/paynspray.js +177 -0
  86. package/dist/paynspray.js.map +1 -0
  87. package/dist/ped.d.ts +335 -0
  88. package/dist/ped.js +536 -0
  89. package/dist/ped.js.map +1 -0
  90. package/dist/player.d.ts +685 -0
  91. package/dist/player.js +1163 -0
  92. package/dist/player.js.map +1 -0
  93. package/dist/screeneffects.d.ts +99 -0
  94. package/dist/screeneffects.js +257 -0
  95. package/dist/screeneffects.js.map +1 -0
  96. package/dist/scripts.d.ts +69 -0
  97. package/dist/scripts.js +125 -0
  98. package/dist/scripts.js.map +1 -0
  99. package/dist/server.d.ts +713 -0
  100. package/dist/server.js +1080 -0
  101. package/dist/server.js.map +1 -0
  102. package/dist/shopblips.d.ts +9 -0
  103. package/dist/shopblips.js +30 -0
  104. package/dist/shopblips.js.map +1 -0
  105. package/dist/special.d.ts +33 -0
  106. package/dist/special.js +26 -0
  107. package/dist/special.js.map +1 -0
  108. package/dist/splash.d.ts +42 -0
  109. package/dist/splash.js +55 -0
  110. package/dist/splash.js.map +1 -0
  111. package/dist/text.d.ts +19 -0
  112. package/dist/text.js +25 -0
  113. package/dist/text.js.map +1 -0
  114. package/dist/ui.d.ts +141 -0
  115. package/dist/ui.js +243 -0
  116. package/dist/ui.js.map +1 -0
  117. package/dist/vehicle.d.ts +306 -0
  118. package/dist/vehicle.js +612 -0
  119. package/dist/vehicle.js.map +1 -0
  120. package/dist/vehiclecolors.d.ts +26 -0
  121. package/dist/vehiclecolors.js +49 -0
  122. package/dist/vehiclecolors.js.map +1 -0
  123. package/dist/world.d.ts +222 -0
  124. package/dist/world.js +227 -0
  125. package/dist/world.js.map +1 -0
  126. package/dist/zone.d.ts +89 -0
  127. package/dist/zone.js +140 -0
  128. package/dist/zone.js.map +1 -0
  129. package/package.json +33 -4
@@ -0,0 +1,685 @@
1
+ import { type AudioEffects } from "./audio_effects.js";
2
+ import { GameMap, type MapColor } from "./map.js";
3
+ import { PlayerHud } from "./hud.js";
4
+ import { PlayerSplash } from "./splash.js";
5
+ import { PlayerCamera } from "./camera.js";
6
+ import { type MenuOptions, type PlayerMenu } from "./menu.js";
7
+ import { ScreenEffects } from "./screeneffects.js";
8
+ import { ScreenDraw } from "./draw.js";
9
+ import { PlayerUi } from "./ui.js";
10
+ import { type SpecialAction } from "./special.js";
11
+ import type { NativeServer } from "./native.js";
12
+ import type { Vehicle } from "./vehicle.js";
13
+ export interface Vector3 {
14
+ x: number;
15
+ y: number;
16
+ z: number;
17
+ }
18
+ /**
19
+ * A connected player. Getters read the latest state the server has (synced
20
+ * from the player's client ~20 times a second); setters send a change to the
21
+ * player's client.
22
+ *
23
+ * Player objects stay valid until the `playerQuit` event for them has been
24
+ * handled; after that `connected` is false and changes are ignored.
25
+ */
26
+ /** A dialog (`player.dialog`). */
27
+ /** A box on the map: see `player.worldBounds`. */
28
+ export interface WorldBounds {
29
+ minX: number;
30
+ maxX: number;
31
+ minY: number;
32
+ maxY: number;
33
+ }
34
+ /** A name tag: see `player.nameTag`. */
35
+ export interface NameTagSettings {
36
+ /** Not shown (default false). */
37
+ hidden?: boolean;
38
+ /** Shown instead of their name. */
39
+ text?: string | null;
40
+ /** 0xRRGGBB, instead of `player.color`. */
41
+ color?: number | null;
42
+ }
43
+ export interface DialogOptions {
44
+ /** msgbox (text, buttons), input, password, list (one row a line), tablist (columns by \t), tablistHeaders (the first row the headings). Default msgbox. */
45
+ style?: "msgbox" | "input" | "password" | "list" | "tablist" | "tablistHeaders";
46
+ title?: string;
47
+ /** The text, or the rows. `{RRGGBB}` colours a part. */
48
+ body?: string;
49
+ /** The first button (Enter). Default "OK". */
50
+ button1?: string;
51
+ /** The second (Escape); left out: only the one. */
52
+ button2?: string;
53
+ /** The body is markdown (the msgbox, input and password styles). `{key:ID}` shows an action's key either way. */
54
+ markdown?: boolean;
55
+ }
56
+ /** Their answer to a dialog. */
57
+ export interface DialogAnswer {
58
+ /** The first button (true), or the second / Escape (false). */
59
+ response: boolean;
60
+ /** The row chosen (list styles), or -1. */
61
+ listItem: number;
62
+ /** What they typed (input styles). */
63
+ input: string;
64
+ }
65
+ export declare class Player {
66
+ #private;
67
+ /** Slot number, unique among connected players (reused after they leave). */
68
+ readonly id: number;
69
+ /** Their name: as given when joining, or `setName`'s. */
70
+ get name(): string;
71
+ /**
72
+ * Gives them another name (SA-MP's SetPlayerName): 3-24 letters, digits
73
+ * and `_[]().$@=`, and not another player's (any case). Everyone's game
74
+ * shows it. **Returns** false if it can't be theirs.
75
+ */
76
+ setName(name: string): boolean;
77
+ /**
78
+ * Watches another player or a vehicle (SA-MP's TogglePlayerSpectating
79
+ * with PlayerSpectatePlayer / PlayerSpectateVehicle): no one sees them
80
+ * meanwhile, and their camera follows the target (a player's vehicle
81
+ * while they're in one). Another target switches to it; null ends it, and
82
+ * they're back where they were.
83
+ *
84
+ * ```ts
85
+ * admin.spectate(suspect);
86
+ * admin.spectate(null);
87
+ * ```
88
+ */
89
+ spectate(target: Player | Vehicle | null): void;
90
+ /**
91
+ * Whether `viewer` sees them at all (their character, name, blip):
92
+ * hidden, they aren't in the viewer's game. For scenes each player plays
93
+ * alone in the same spot (each sees only themselves answer a phone).
94
+ * Default visible.
95
+ */
96
+ setVisibleFor(viewer: Player, visible: boolean): void;
97
+ /** Who or what they watch (`spectate`), or null. */
98
+ get spectating(): Player | Vehicle | null;
99
+ /**
100
+ * Their own weather (`Weather`, 0-22; -1 the game's own cycle), over
101
+ * their world's (SA-MP's SetPlayerWeather); null: their world's again.
102
+ */
103
+ get weather(): number | null;
104
+ set weather(weather: number | null);
105
+ /**
106
+ * A box on the map they can't leave (SA-MP's SetPlayerWorldBounds, e.g. a
107
+ * prison yard): their game pushes them back in, on foot or driving.
108
+ * Null: free again.
109
+ *
110
+ * ```ts
111
+ * player.worldBounds = { minX: 101.6, maxX: 337.6, minY: 1798.7, maxY: 1941 };
112
+ * ```
113
+ */
114
+ get worldBounds(): WorldBounds | null;
115
+ set worldBounds(b: WorldBounds | null);
116
+ /**
117
+ * Plays them the police scanner reporting a crime (SA-MP's
118
+ * PlayCrimeReportForPlayer): `crime` is the game's (`Crime`), `suspect`
119
+ * a player or a spot (the scanner names its area).
120
+ *
121
+ * ```ts
122
+ * for (const cop of cops) cop.playCrimeReport(robber, Crime.FireWeapon);
123
+ * ```
124
+ */
125
+ playCrimeReport(suspect: Player | Vector3, crime: number): void;
126
+ /**
127
+ * The game's stunt bonuses for them: wheelies, stoppies, two wheels and
128
+ * insane stunt jumps (as SA-MP's EnableStuntBonusForPlayer). Off, their
129
+ * game gives neither the message nor the money. Default on, or as
130
+ * `server.stuntBonus`.
131
+ */
132
+ get stuntBonus(): boolean;
133
+ set stuntBonus(on: boolean);
134
+ /** A number by their name in the player list (SetPlayerScore); shown once anyone's isn't 0. */
135
+ get score(): number;
136
+ set score(score: number);
137
+ /** Free-form per-player storage for gamemode data. */
138
+ readonly data: Record<string, unknown>;
139
+ /** @internal Created by Server; gamemodes receive Player objects from events. */
140
+ constructor(nativeServer: NativeServer, id: number, vehicle: (id: number) => Vehicle | undefined);
141
+ /** False once the player has left. */
142
+ get connected(): boolean;
143
+ /** @internal */
144
+ markDisconnected(): void;
145
+ /**
146
+ * The player's IP address. Through a trusted proxy (proxy mode), the one
147
+ * the proxy forwarded rather than the proxy's own.
148
+ */
149
+ get ip(): string;
150
+ /** True when the player came through a trusted proxy. */
151
+ get viaProxy(): boolean;
152
+ /**
153
+ * The address the player connected to, as they typed it (e.g.
154
+ * "race.example.com" and 7777), for telling apart servers that share an IP.
155
+ */
156
+ get connectHost(): string;
157
+ get connectPort(): number;
158
+ /** Round-trip time in milliseconds. */
159
+ get ping(): number;
160
+ /** True while the player is alive in the world (as their client reports). */
161
+ /**
162
+ * Whether they're within `radius` m of `position` (and, `maxDz`, no more
163
+ * than that above or below it): the check before trusting a client
164
+ * script that says its player is at something.
165
+ */
166
+ isNear(position: Vector3, radius: number, maxDz?: number): boolean;
167
+ get alive(): boolean;
168
+ /** True while the player has the pause menu open. The game keeps running. */
169
+ get paused(): boolean;
170
+ /** False while the player's game window is in the background (alt-tabbed). */
171
+ get focused(): boolean;
172
+ /** The vehicle they are in (driving or as a passenger), or null. */
173
+ get vehicle(): Vehicle | null;
174
+ /**
175
+ * The vehicle they last drove, while it exists. Ambient cleanup leaves it
176
+ * alone while they're connected (unless it's a wreck); destroy it yourself
177
+ * to get rid of it.
178
+ */
179
+ get lastVehicle(): Vehicle | null;
180
+ /** The vehicle they remote-control (`remoteControl()`), or null. */
181
+ get remoteVehicle(): Vehicle | null;
182
+ /**
183
+ * Remote control, as with an RC vehicle: they drive `vehicle` (nobody in
184
+ * it, in their world) with their own controls from where they stand, the
185
+ * camera following it, until they press the enter/exit key, it blows up,
186
+ * or this is called with null. `detonate`: fire blows it up (and an RC
187
+ * Bandit blows up touching a car), as in the game's RC missions. Works
188
+ * with any vehicle, not just RC ones. False if it can't be given (they're
189
+ * in a vehicle, someone is in it, another world, a wreck).
190
+ */
191
+ remoteControl(vehicle: Vehicle | null, options?: {
192
+ detonate?: boolean;
193
+ }): boolean;
194
+ /** Their seat in `vehicle`: 0 is the driver's, 1-8 passengers'. null on foot. */
195
+ get seat(): number | null;
196
+ /** Ped model id (0 is CJ). Setting it changes the model for everyone. */
197
+ get skin(): number;
198
+ set skin(model: number);
199
+ /**
200
+ * Money, as the server keeps it. The player's game shows exactly this;
201
+ * anything their game changes by itself is undone.
202
+ */
203
+ get money(): number;
204
+ set money(value: number);
205
+ /** This player's own additions to the pause menu's map (see `GameMap`). */
206
+ get map(): GameMap;
207
+ /** Full-screen effects (your shaders) on their screen. See `ScreenEffects`. */
208
+ get screenEffects(): ScreenEffects;
209
+ /** Their camera: fixed shots, glides between them, following something, or back behind them. See `PlayerCamera`. */
210
+ get camera(): PlayerCamera;
211
+ /**
212
+ * Their splash screen: the loading screen kept up (or shown again) while
213
+ * you set the scene, their game's sound muted. See `PlayerSplash`.
214
+ */
215
+ get splash(): PlayerSplash;
216
+ /** @internal Joined with the splash up (the server option `splash`). */
217
+ holdSplash(): PlayerSplash;
218
+ /** Their mission HUD: radar blips, objective text, timers and counters, result screens. */
219
+ get hud(): PlayerHud;
220
+ /** Drawing on their screen, SA-MP textdraw style: see `ScreenDraw`. */
221
+ get draw(): ScreenDraw;
222
+ /** UI documents (RML client files) the server opens on their screen: see `PlayerUi`. */
223
+ get ui(): PlayerUi;
224
+ /**
225
+ * Sends data (anything JSON can hold) on a channel to this player's client
226
+ * scripts, where `sagl.on(channel, fn)` gets it. See `server.channel()`.
227
+ */
228
+ emit(channel: string, data?: unknown): void;
229
+ /**
230
+ * Wanted level, 0-6 stars, as the server keeps it; their game shows it
231
+ * and cops respond. Setting it sets it (capped at `maxWantedLevel`).
232
+ * Their crimes only change it where the population's `wanted` is on.
233
+ */
234
+ get wantedLevel(): number;
235
+ set wantedLevel(level: number);
236
+ /**
237
+ * Clears their wanted level. With `parole` (as the game's Pay 'n' Spray):
238
+ * their old stars flash for 20 seconds, and a crime meanwhile brings
239
+ * them back (where the population's `wanted` is on).
240
+ *
241
+ * ```ts
242
+ * player.clearWantedLevel({ parole: true });
243
+ * ```
244
+ */
245
+ clearWantedLevel(options?: {
246
+ parole?: boolean;
247
+ }): void;
248
+ /** The most their wanted level can be, 0-6 (default 6). */
249
+ get maxWantedLevel(): number;
250
+ set maxWantedLevel(level: number);
251
+ /**
252
+ * Their virtual world (default 0). They see and meet players and vehicles
253
+ * in it, and see into worlds it views (`server.setWorldView`). Changing it
254
+ * takes them out of a vehicle that stays behind; move both with
255
+ * `vehicle.world`.
256
+ */
257
+ get world(): number;
258
+ set world(world: number);
259
+ /**
260
+ * The interior they're in: the game's areas, 0 outside, 1-18 its
261
+ * interiors (as SA-MP's SetPlayerInterior). Their game shows that
262
+ * interior; they see, and are seen by, players and vehicles in the same.
263
+ * Teleports keep it: set both to go in or out.
264
+ *
265
+ * ```ts
266
+ * player.interior = 3;
267
+ * player.setPosition({ x: 384.8, y: 173.8, z: 1008.4 }); // the bike school
268
+ * ```
269
+ */
270
+ get interior(): number;
271
+ set interior(interior: number);
272
+ /** Never tires when sprinting (or swimming, cycling). */
273
+ get infiniteSprint(): boolean;
274
+ set infiniteSprint(infinite: boolean);
275
+ /**
276
+ * Walks, runs and idles like their skin (true) or like CJ (false, the
277
+ * default). Holding a gun they move like CJ either way: the player's
278
+ * armed moves are made for his animations.
279
+ */
280
+ get skinAnimations(): boolean;
281
+ set skinAnimations(skin: boolean);
282
+ /**
283
+ * Sets a game stat (`Stat`): stamina, muscle, max health, weapon and
284
+ * driving skills... Only the server changes stats: playing doesn't, and
285
+ * ones never set stay at a new game's values. 0-1000 for most.
286
+ */
287
+ setStat(stat: number, value: number): void;
288
+ /** A stat as the server set it, or undefined (a new game's value). */
289
+ getStat(stat: number): number | undefined;
290
+ /** Back to a new game's value. */
291
+ resetStat(stat: number): void;
292
+ /** The weapon in their hand (`Weapon`), 0 unarmed. */
293
+ get weapon(): number;
294
+ /** Puts a weapon they have in their hand (0: unarmed). */
295
+ set weapon(weapon: number);
296
+ /**
297
+ * Spawns them again, as SA-MP's SpawnPlayer: out of any vehicle,
298
+ * animations and special actions stopped, unfrozen, the camera behind
299
+ * them, health 100 and armour 0, then `playerSpawn` fires so your spawn
300
+ * code puts them where they belong (a short fade covers the move).
301
+ * Weapons, money and wanted level stay. A dead player respawns by
302
+ * themselves (`playerSpawn` follows): nothing happens then.
303
+ *
304
+ * ```ts
305
+ * kickFromFaction(player);
306
+ * await player.respawn(); // at the civilians' spawn, by your playerSpawn handler
307
+ * ```
308
+ */
309
+ respawn(): Promise<void>;
310
+ /** @internal */
311
+ setRespawner(fn: (p: Player) => void): void;
312
+ /**
313
+ * Puts the weapon in their hand away (unarmed). **Returns** a function
314
+ * that gives it back (if they still have it).
315
+ *
316
+ * ```ts
317
+ * const giveBack = player.holster();
318
+ * await scene();
319
+ * giveBack();
320
+ * ```
321
+ */
322
+ holster(): () => void;
323
+ /** What they carry, slot by slot, with ammo (the server's count). */
324
+ get weapons(): {
325
+ slot: number;
326
+ weapon: number;
327
+ ammo: number;
328
+ }[];
329
+ /**
330
+ * Gives a weapon with `ammo` (into its slot, replacing whatever was there),
331
+ * or adds `ammo` if they have it already.
332
+ */
333
+ giveWeapon(weapon: number, ammo: number): void;
334
+ /** Sets the ammo of a weapon they have. */
335
+ setAmmo(weapon: number, ammo: number): void;
336
+ removeWeapon(weapon: number): void;
337
+ /** Takes all their weapons. */
338
+ resetWeapons(): void;
339
+ /**
340
+ * Puts them out of their vehicle, beside it; with `jump`, they get out as
341
+ * the game does (diving out of one that's moving: a bail).
342
+ */
343
+ removeFromVehicle(options?: {
344
+ jump?: boolean;
345
+ }): void;
346
+ /** Radio station names aren't shown on their screen (in any vehicle). */
347
+ get radioNameHidden(): boolean;
348
+ set radioNameHidden(hidden: boolean);
349
+ /** Adds (or, if negative, takes) money. */
350
+ giveMoney(amount: number): void;
351
+ get health(): number;
352
+ set health(value: number);
353
+ get armour(): number;
354
+ set armour(value: number);
355
+ /** Position in metres (world coordinates); their vehicle's while driving. */
356
+ get position(): Vector3;
357
+ /** Facing direction in degrees, 0 = north, increasing anticlockwise. */
358
+ get heading(): number;
359
+ /** Velocity in m/s, as their last sync (a passenger: their vehicle's). */
360
+ get velocity(): Vector3;
361
+ /**
362
+ * Whether they're aiming a gun at `target` (a ped, player, vehicle or
363
+ * spot): holding aim with a firearm, within `range` m (default 10), their
364
+ * camera pointing within `angle` degrees of it (default 12). For a ped
365
+ * that gives up at gunpoint.
366
+ *
367
+ * ```ts
368
+ * if (player.isAimingAt(benny, { range: 6 })) void benny.handsUp(3000);
369
+ * ```
370
+ */
371
+ isAimingAt(target: {
372
+ position: Vector3;
373
+ } | Vector3, options?: {
374
+ range?: number;
375
+ angle?: number;
376
+ }): boolean;
377
+ /** The buttons they hold (`Key` bits), as their last sync. See `playerKeys`. */
378
+ get keys(): number;
379
+ /** Teleports the player. `heading` in degrees. */
380
+ setPosition(position: Vector3, heading?: number): void;
381
+ /**
382
+ * Fades their screen out to `color` (default black) over `ms`, and keeps
383
+ * it there until `fadeIn()`. Resolves when it's dark.
384
+ */
385
+ fadeOut(ms?: number, color?: MapColor): Promise<void>;
386
+ /** Fades their screen back in over `ms`. Resolves when it's clear. */
387
+ fadeIn(ms?: number): Promise<void>;
388
+ /**
389
+ * Plays one of the game's animations on them (everyone sees it), e.g.
390
+ * `playAnim("PED", "phone_talk", { loop: true })`. `ms` stops it after
391
+ * that long; without, it plays to its end (a looping one: until
392
+ * `stopAnim()`, or they move off). Blocks other than "PED" stream in
393
+ * first. Resolves after `ms` (or at once). `hold` keeps it on its last
394
+ * frame until the next replaces it (SA-MP's ApplyAnimation freeze): for
395
+ * animations played one after another, which otherwise blend back
396
+ * towards standing in the moment between them. `upperBody` plays it on
397
+ * the upper body only (the game's secondary task): they can walk
398
+ * meanwhile, e.g. `playAnim("GANGS", "smkcig_prtl", { upperBody: true })`.
399
+ */
400
+ playAnim(block: string, name: string, options?: {
401
+ loop?: boolean;
402
+ ms?: number;
403
+ hold?: boolean;
404
+ upperBody?: boolean;
405
+ }): Promise<void>;
406
+ /** Stops whatever animation they're playing. */
407
+ stopAnim(): void;
408
+ /**
409
+ * Whether they're frozen: they can't move (their controls are off, as in
410
+ * a cutscene) until unfrozen. Animations still play.
411
+ */
412
+ get frozen(): boolean;
413
+ set frozen(frozen: boolean);
414
+ /**
415
+ * Moves them on foot to a spot nearby and turns them to `heading`
416
+ * (degrees): the game's own slide, as its machine scripts put a player in
417
+ * front of a vending machine. Unlike `setPosition`, no teleport (no drop
418
+ * from the game standing them on `z`). Resolves when they're there, or
419
+ * after `ms` (default 2000). Works while `frozen`.
420
+ *
421
+ * ```ts
422
+ * player.frozen = true;
423
+ * await player.slideTo({ x: 2326.2, y: -1646.1, z: 14.2 }, 0);
424
+ * await player.playAnim("VENDING", "VEND_Use", { ms: 2600 });
425
+ * ```
426
+ */
427
+ slideTo(position: Vector3, heading?: number, ms?: number): Promise<void>;
428
+ /**
429
+ * Says a line of the game's mission dialogue as CJ (`dialogue`, its GXT
430
+ * key such as "RYD2_CA", from mission table `table`): its recording from
431
+ * this player, with its text as the subtitle, heard by `to` or everyone
432
+ * within 40 m. Resolves when it's done. `effects` puts the recording
433
+ * through audio effects (`"phone"`...; then the lips don't move).
434
+ */
435
+ say(line: {
436
+ dialogue: string;
437
+ table?: string;
438
+ subtitle?: string;
439
+ ms?: number;
440
+ to?: readonly Player[];
441
+ effects?: AudioEffects;
442
+ }): Promise<void>;
443
+ /**
444
+ * A subtitle at the bottom of their screen, in the game's style, for `ms`
445
+ * (left out: as long as reading it takes). Shown only if they have
446
+ * subtitles on in their pause menu.
447
+ */
448
+ subtitle(text: string, ms?: number): void;
449
+ /**
450
+ * Their colour: their name in chat and their name tag (as SA-MP's
451
+ * SetPlayerColor), unless `nameTag.color` says otherwise. 0xRRGGBB,
452
+ * default white.
453
+ */
454
+ get color(): number;
455
+ set color(color: number);
456
+ /**
457
+ * Their name tag, as everyone sees it (unless `setNameTagFor` says
458
+ * otherwise for someone): `hidden` (a mask), `text` instead of their name,
459
+ * `color` (0xRRGGBB) instead of `player.color`. Setting it replaces it
460
+ * (`{}`: as normal).
461
+ *
462
+ * ```ts
463
+ * player.nameTag = { text: `Stranger ${player.id}` }; // a mask
464
+ * player.nameTag = { hidden: true };
465
+ * ```
466
+ */
467
+ get nameTag(): NameTagSettings;
468
+ set nameTag(tag: NameTagSettings);
469
+ /**
470
+ * Their name tag as `viewer` sees it, over `nameTag` (as SA-MP's
471
+ * ShowPlayerNameTagForPlayer, with text and colour too); null: as
472
+ * everyone sees it.
473
+ *
474
+ * ```ts
475
+ * target.setNameTagFor(admin, { text: `${target.name} (masked)` });
476
+ * ```
477
+ */
478
+ setNameTagFor(viewer: Player, tag: NameTagSettings | null): void;
479
+ /** @internal Their tag as `viewer` sees it: [hidden, text, colour]. */
480
+ tagFor(viewer: Player): [boolean, string, number | null];
481
+ /** @internal A viewer left: their overrides go. */
482
+ forgetViewer(viewer: Player): void;
483
+ /** @internal */
484
+ setTagSender(fn: (target: Player, viewer?: Player) => void): void;
485
+ /**
486
+ * Shows a message to this player. `color` is 0xRRGGBB; `{RRGGBB}` in the
487
+ * text colours what follows. `markdown`: the text is markdown (bold,
488
+ * italic, code, links) instead. `{key:ID}` shows an action's key either way.
489
+ */
490
+ send(text: string, color?: number, options?: {
491
+ markdown?: boolean;
492
+ }): void;
493
+ /**
494
+ * Their checkpoint, as SA-MP's SetPlayerCheckpoint: a red cylinder on the
495
+ * ground at `position`, `size` m across (default 2), with a radar blip.
496
+ * One at a time: setting another replaces it. Entering and leaving it
497
+ * fire `playerEnterCheckpoint` / `playerLeaveCheckpoint`.
498
+ *
499
+ * ```ts
500
+ * player.setCheckpoint({ x: 2495, y: -1690, z: 13.5 }, 3);
501
+ * server.on("playerEnterCheckpoint", (player) => { player.disableCheckpoint(); ... });
502
+ * ```
503
+ */
504
+ setCheckpoint(position: Vector3, size?: number): void;
505
+ /** Takes their checkpoint away (DisablePlayerCheckpoint). */
506
+ disableCheckpoint(): void;
507
+ /**
508
+ * Their race checkpoint, as SA-MP's SetPlayerRaceCheckpoint: the game's
509
+ * own, its arrow pointing at `next`. `type`: 0 normal, 1 finish, 2
510
+ * nothing (no arrow), 3 in the air (a ring), 4 the air finish. Entering
511
+ * and leaving fire `playerEnterRaceCheckpoint` / `playerLeaveRaceCheckpoint`.
512
+ */
513
+ setRaceCheckpoint(position: Vector3, options?: {
514
+ next?: Vector3;
515
+ size?: number;
516
+ type?: number;
517
+ }): void;
518
+ /** Takes their race checkpoint away. */
519
+ disableRaceCheckpoint(): void;
520
+ /** Their checkpoint, or null. */
521
+ checkpoint: {
522
+ position: Vector3;
523
+ size: number;
524
+ } | null;
525
+ /** In it now. */
526
+ inCheckpoint: boolean;
527
+ /** Their race checkpoint, or null. */
528
+ raceCheckpoint: {
529
+ position: Vector3;
530
+ size: number;
531
+ type: number;
532
+ next: Vector3;
533
+ } | null;
534
+ /** In it now. */
535
+ inRaceCheckpoint: boolean;
536
+ /**
537
+ * Shows them a dialog, as SA-MP's ShowPlayerDialog, and resolves with
538
+ * their answer: `response` true for the first button (Enter), false for
539
+ * the second (Escape); `listItem` the row they chose (list styles, else
540
+ * -1); `input` what they typed. One at a time: a new one replaces (and
541
+ * resolves, `response` false) the one showing.
542
+ *
543
+ * ```ts
544
+ * const { response, input } = await player.dialog({ style: "password", title: "Login", body: "Your password:", button1: "Login", button2: "Quit" });
545
+ * const { listItem } = await player.dialog({ style: "tablist", title: "Buy", body: "Pistol\t$500\nShotgun\t$1200", button1: "Buy", button2: "Close" });
546
+ * ```
547
+ */
548
+ dialog(d: DialogOptions): Promise<DialogAnswer>;
549
+ /**
550
+ * Shows a menu as the game's shops have (SA-MP's CreateMenu /
551
+ * ShowMenuForPlayer): a box at the top left, a title, rows of up to two
552
+ * columns, one chosen. Up/Down move (`onChoose`), Enter selects
553
+ * (`onSelect`), Backspace or Escape go back (`onBack`; the menu stays up
554
+ * until you close it or show another). One at a time: a new one
555
+ * replaces it. Keys go to the menu while it's up, so freeze them or
556
+ * leave them be as you need.
557
+ *
558
+ * ```ts
559
+ * const menu = player.menu({
560
+ * title: "Ammu-Nation",
561
+ * rows: [["Pistol", "$500"], ["Shotgun", "$1200"]],
562
+ * footer: `Cash: $${player.money}`,
563
+ * onSelect: (row) => { ... },
564
+ * onBack: (m) => m.close(),
565
+ * });
566
+ * ```
567
+ */
568
+ menu(options: MenuOptions): PlayerMenu;
569
+ /** The menu showing, or null. */
570
+ get currentMenu(): PlayerMenu | null;
571
+ /** @internal */
572
+ menuHeard(id: number, kind: number, row: number): void;
573
+ /** @internal Gone: no more menu events. */
574
+ forgetMenus(): void;
575
+ /** Takes away the dialog showing (it resolves, `response` false). */
576
+ hideDialog(): void;
577
+ /** @internal Their answer to dialog `id`. */
578
+ dialogAnswered(id: number, a: DialogAnswer): void;
579
+ /**
580
+ * An object they hold, as SA-MP's SetPlayerAttachedObject: in `slot`
581
+ * (0-9; setting a slot again replaces it), on `bone` (`Bone`: SA-MP's
582
+ * 1-18, head, hands, spine...), offset, turned (degrees) and scaled from
583
+ * it. Everyone sees it, following every animation.
584
+ *
585
+ * ```ts
586
+ * player.attachObject(0, 19006, Bone.Head, { offset: { x: 0.1, y: 0.04, z: 0 }, rotation: { x: 90, y: 90, z: 0 } }); // glasses
587
+ * ```
588
+ */
589
+ attachObject(slot: number, model: number, bone: number, options?: {
590
+ offset?: Vector3;
591
+ rotation?: Vector3;
592
+ scale?: Vector3;
593
+ }): void;
594
+ /**
595
+ * What they're doing, as SA-MP's SetPlayerSpecialAction (or null):
596
+ * drinking (`"drinkBeer"`, `"drinkWine"`, `"drinkSprunk"`: a bottle or
597
+ * can in hand, fire to drink, which makes them drunker for beer and wine),
598
+ * `"smoke"` (fire for a drag), `"phone"` (on the phone; they can walk),
599
+ * `"carry"` (arms out as if carrying something; they can walk),
600
+ * `"handsUp"`, `"dance1"`-`"dance4"`, `"piss"` (these keep them in place),
601
+ * `"jetpack"`. Enter/exit drops a drink or cigarette (back to null).
602
+ * Everyone sees it, players arriving later too. It ends when they die,
603
+ * or get in a vehicle (except the phone).
604
+ *
605
+ * ```ts
606
+ * player.specialAction = "handsUp";
607
+ * player.specialAction = null;
608
+ * ```
609
+ */
610
+ get specialAction(): SpecialAction | null;
611
+ set specialAction(action: SpecialAction | null);
612
+ /** @internal Their buttons changed: what their special action does with them. */
613
+ specialKeys(keys: number, old: number): void;
614
+ /** @internal They died or got in a vehicle: it ends (the phone stays on in a vehicle). */
615
+ specialEnds(inVehicle: boolean): void;
616
+ /** Takes the object in `slot` away (RemovePlayerAttachedObject). */
617
+ removeAttachedObject(slot: number): void;
618
+ /** @internal What their client script attached (or took away), for everyone. */
619
+ attachedByScript(spec: Parameters<NativeServer["playerAttachment"]>[1]): void;
620
+ /** Whether `slot` holds an object (IsPlayerAttachedObjectSlotUsed). */
621
+ isAttachmentSlotUsed(slot: number): boolean;
622
+ /** @internal What they hold, by slot. */
623
+ readonly attachments: Map<number, {
624
+ playerId: number;
625
+ slot: number;
626
+ remove?: boolean;
627
+ model?: number;
628
+ bone?: number;
629
+ ox?: number;
630
+ oy?: number;
631
+ oz?: number;
632
+ rx?: number;
633
+ ry?: number;
634
+ rz?: number;
635
+ sx?: number;
636
+ sy?: number;
637
+ sz?: number;
638
+ }>;
639
+ /** @internal */
640
+ setAttachmentSender(fn: (spec: Parameters<NativeServer["playerAttachment"]>[1]) => void): void;
641
+ /**
642
+ * Text over their head for a while, as SA-MP's SetPlayerChatBubble: seen
643
+ * by those within `distance` m (default 20), for `ms` (default 5000).
644
+ * Another replaces it. A label on them that goes by itself.
645
+ *
646
+ * ```ts
647
+ * server.on("playerChat", (p, text) => { p.chatBubble(text, { color: 0xffffffff }); });
648
+ * ```
649
+ */
650
+ chatBubble(text: string, options?: {
651
+ color?: number;
652
+ distance?: number;
653
+ ms?: number;
654
+ }): void;
655
+ /** @internal */
656
+ setBubbleMaker(fn: (text: string, color: number, distance: number) => {
657
+ remove(): void;
658
+ }): void;
659
+ /**
660
+ * Puts them straight into a vehicle's seat (0 the driver's, the default;
661
+ * 1-8 passengers), as SA-MP's PutPlayerInVehicle. The vehicle must be in
662
+ * their world and near enough for their game to have it (move them to it
663
+ * first if it's far).
664
+ */
665
+ putInVehicle(vehicle: Vehicle, seat?: number): void;
666
+ /**
667
+ * Their fighting style (`FightingStyle`: Normal, Boxing, KungFu,
668
+ * KneeHead, GrabKick, Elbow), as SA-MP's SetPlayerFightingStyle (the
669
+ * same numbers). Everyone sees them fight so.
670
+ */
671
+ get fightingStyle(): number;
672
+ set fightingStyle(style: number);
673
+ /**
674
+ * How drunk they are, as SA-MP's SetPlayerDrunkLevel: above 2000 their
675
+ * camera sways (the more, the worse), and it falls by 60 a second
676
+ * (reading it gives what it's down to now). 0: sober.
677
+ */
678
+ get drunkLevel(): number;
679
+ set drunkLevel(level: number);
680
+ /** Empties their chat's log. */
681
+ clearChat(): void;
682
+ /** Disconnects the player, telling them why. */
683
+ kick(reason?: string): void;
684
+ toString(): string;
685
+ }