@rpgjs/server 5.0.0-alpha.29 → 5.0.0-alpha.30

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 (51) hide show
  1. package/dist/Gui/DialogGui.d.ts +1 -0
  2. package/dist/Gui/GameoverGui.d.ts +23 -0
  3. package/dist/Gui/Gui.d.ts +6 -0
  4. package/dist/Gui/MenuGui.d.ts +22 -3
  5. package/dist/Gui/NotificationGui.d.ts +1 -2
  6. package/dist/Gui/SaveLoadGui.d.ts +13 -0
  7. package/dist/Gui/ShopGui.d.ts +24 -3
  8. package/dist/Gui/TitleGui.d.ts +23 -0
  9. package/dist/Gui/index.d.ts +9 -1
  10. package/dist/Player/GuiManager.d.ts +86 -3
  11. package/dist/Player/Player.d.ts +24 -2
  12. package/dist/RpgServer.d.ts +7 -0
  13. package/dist/RpgServerEngine.d.ts +2 -1
  14. package/dist/index.d.ts +4 -1
  15. package/dist/index.js +1621 -336
  16. package/dist/index.js.map +1 -1
  17. package/dist/presets/index.d.ts +0 -9
  18. package/dist/rooms/BaseRoom.d.ts +37 -0
  19. package/dist/rooms/lobby.d.ts +6 -1
  20. package/dist/rooms/map.d.ts +22 -1
  21. package/dist/services/save.d.ts +43 -0
  22. package/dist/storage/index.d.ts +1 -0
  23. package/dist/storage/localStorage.d.ts +23 -0
  24. package/package.json +10 -10
  25. package/src/Gui/DialogGui.ts +12 -2
  26. package/src/Gui/GameoverGui.ts +39 -0
  27. package/src/Gui/Gui.ts +23 -1
  28. package/src/Gui/MenuGui.ts +155 -6
  29. package/src/Gui/NotificationGui.ts +1 -2
  30. package/src/Gui/SaveLoadGui.ts +60 -0
  31. package/src/Gui/ShopGui.ts +145 -16
  32. package/src/Gui/TitleGui.ts +39 -0
  33. package/src/Gui/index.ts +13 -2
  34. package/src/Player/BattleManager.ts +1 -1
  35. package/src/Player/ClassManager.ts +57 -2
  36. package/src/Player/GuiManager.ts +125 -14
  37. package/src/Player/ItemManager.ts +160 -41
  38. package/src/Player/ParameterManager.ts +1 -1
  39. package/src/Player/Player.ts +87 -12
  40. package/src/Player/SkillManager.ts +145 -66
  41. package/src/Player/StateManager.ts +70 -1
  42. package/src/Player/VariableManager.ts +10 -7
  43. package/src/RpgServer.ts +8 -0
  44. package/src/index.ts +5 -2
  45. package/src/presets/index.ts +1 -10
  46. package/src/rooms/BaseRoom.ts +112 -0
  47. package/src/rooms/lobby.ts +13 -6
  48. package/src/rooms/map.ts +31 -4
  49. package/src/services/save.ts +147 -0
  50. package/src/storage/index.ts +1 -0
  51. package/src/storage/localStorage.ts +76 -0
@@ -1,43 +1,172 @@
1
1
  import { PrebuiltGui } from '@rpgjs/common'
2
2
  import { Gui } from './Gui'
3
3
  import { RpgPlayer } from '../Player/Player'
4
- import { IGui } from '../Interfaces/Gui'
5
4
 
6
- export class ShopGui extends Gui implements IGui {
5
+ export type ShopSellList = Record<string, number> | Array<{ id: string; multiplier: number }>
6
+
7
+ export interface ShopGuiOptions {
8
+ items: any[]
9
+ sell?: ShopSellList
10
+ sellMultiplier?: number
11
+ message?: string
12
+ face?: {
13
+ id: string
14
+ expression?: string
15
+ }
16
+ }
17
+
18
+ export class ShopGui extends Gui {
19
+ private itemsInput: any[] = []
20
+ private sellMultipliers: Record<string, number> = {}
21
+ private baseSellMultiplier = 0.5
22
+ private messageInput?: string
23
+ private faceInput?: { id: string; expression?: string }
24
+
7
25
  constructor(player: RpgPlayer) {
8
26
  super(PrebuiltGui.Shop, player)
9
27
  }
10
28
 
11
- open(items: any[]) {
12
- items = items.map(item => {
13
- const it = new item()
29
+ private normalizeSellMultipliers(sell?: ShopSellList) {
30
+ if (!sell) return {}
31
+ if (Array.isArray(sell)) {
32
+ return sell.reduce<Record<string, number>>((acc, entry) => {
33
+ if (entry && entry.id) acc[entry.id] = entry.multiplier ?? 0
34
+ return acc
35
+ }, {})
36
+ }
37
+ return { ...sell }
38
+ }
39
+
40
+ private buildShopData() {
41
+ const player = this.player as any
42
+ const databaseById = player.databaseById?.bind(player)
43
+ const equippedIds = new Set(
44
+ (player.equipments?.() || []).map((it) => it?.id?.() ?? it?.id ?? it?.name)
45
+ )
46
+ const playerParams = {
47
+ ...(player.param || {}),
48
+ atk: player.atk ?? 0,
49
+ def: player.pdef ?? 0,
50
+ pdef: player.pdef ?? 0,
51
+ sdef: player.sdef ?? 0
52
+ }
53
+
54
+ const getStatValue = (data, key, fallbackKeys: string[] = []) => {
55
+ if (data && typeof data[key] === 'number') return data[key]
56
+ for (const fallbackKey of fallbackKeys) {
57
+ if (data && typeof data[fallbackKey] === 'number') return data[fallbackKey]
58
+ }
59
+ const modifier = data?.paramsModifier?.[key]
60
+ if (modifier && typeof modifier.value === 'number') return modifier.value
61
+ for (const fallbackKey of fallbackKeys) {
62
+ const fallbackModifier = data?.paramsModifier?.[fallbackKey]
63
+ if (fallbackModifier && typeof fallbackModifier.value === 'number') return fallbackModifier.value
64
+ }
65
+ return undefined
66
+ }
67
+
68
+ const buildItemData = (item, overrides: { price?: number; quantity?: number } = {}) => {
69
+ const rawId = typeof item === 'string'
70
+ ? item
71
+ : (typeof item?.id === 'function' ? item.id() : (item?.id ?? item?.name))
72
+ const data = databaseById(rawId)
73
+ const itemName = typeof item?.name === 'function' ? item.name() : item?.name
74
+ const itemDescription = typeof item?.description === 'function' ? item.description() : item?.description
75
+ const itemPrice = typeof item?.price === 'function' ? item.price() : item?.price
76
+ const itemIcon = typeof item?.icon === 'function' ? item.icon() : item?.icon
77
+ const atk = getStatValue(data, 'atk')
78
+ const def = getStatValue(data, 'def', ['pdef', 'sdef'])
79
+ const intValue = getStatValue(data, 'int')
80
+ const agi = getStatValue(data, 'agi')
81
+ const stats = {
82
+ ...(atk !== undefined ? { atk } : {}),
83
+ ...(def !== undefined ? { def } : {}),
84
+ ...(intValue !== undefined ? { int: intValue } : {}),
85
+ ...(agi !== undefined ? { agi } : {})
86
+ }
14
87
  return {
15
- price: it.price,
16
- name: it.name,
17
- description: it.description,
18
- id: it.id,
19
- type: item.type
88
+ price: overrides.price ?? data?.price ?? itemPrice ?? 0,
89
+ name: data?.name ?? itemName ?? rawId,
90
+ description: data?.description ?? itemDescription ?? '',
91
+ icon: data?.icon ?? itemIcon,
92
+ id: rawId,
93
+ type: data?._type ?? item.type ?? item?._type,
94
+ stats: Object.keys(stats).length ? stats : undefined,
95
+ equipped: rawId ? equippedIds.has(rawId) : false,
96
+ ...(overrides.quantity !== undefined ? { quantity: overrides.quantity } : {})
20
97
  }
21
- })
22
- this.on('buyItem', ({ id, nb }) => {
98
+ }
99
+
100
+ const items = this.itemsInput.map(item => buildItemData(item))
101
+
102
+ const sellItems = (player.items?.() || [])
103
+ .map((item) => {
104
+ const id = item?.id?.()
105
+ if (!id) return null
106
+ const multiplier = Object.prototype.hasOwnProperty.call(this.sellMultipliers, id)
107
+ ? this.sellMultipliers[id]
108
+ : this.baseSellMultiplier
109
+ const basePrice = databaseById(id)?.price ?? (typeof item?.price === 'function' ? item.price() : item?.price) ?? 0
110
+ const price = basePrice * multiplier
111
+ const quantity = item?.quantity?.()
112
+ return buildItemData(item, { price, quantity })
113
+ })
114
+ .filter(Boolean)
115
+
116
+ return { items, sellItems, playerParams, message: this.messageInput, face: this.faceInput }
117
+ }
118
+
119
+ private refreshShop(clientActionId?: string) {
120
+ this.update(this.buildShopData(), { clientActionId })
121
+ }
122
+
123
+ open(itemsOrOptions: any[] | ShopGuiOptions) {
124
+ const options: ShopGuiOptions = Array.isArray(itemsOrOptions)
125
+ ? { items: itemsOrOptions }
126
+ : (itemsOrOptions || { items: [] })
127
+ this.itemsInput = options.items || []
128
+ this.baseSellMultiplier = typeof options.sellMultiplier === 'number' ? options.sellMultiplier : 0.5
129
+ this.sellMultipliers = this.normalizeSellMultipliers(options.sell)
130
+ this.messageInput = options.message
131
+ this.faceInput = options.face
132
+ this.on('buyItem', ({ id, nb, clientActionId }) => {
23
133
  try {
24
134
  this.player.buyItem(id, nb)
135
+ this.player.syncChanges()
25
136
  }
26
137
  catch (err) {
27
138
  console.log(err)
28
139
  }
140
+ finally {
141
+ this.refreshShop(clientActionId)
142
+ }
29
143
  })
30
- this.on('sellItem', ({ id, nb }) => {
144
+ this.on('sellItem', ({ id, nb, clientActionId }) => {
31
145
  try {
32
- this.player.sellItem(id, nb)
146
+ const multiplier = Object.prototype.hasOwnProperty.call(this.sellMultipliers, id)
147
+ ? this.sellMultipliers[id]
148
+ : this.baseSellMultiplier
149
+ const basePrice = (this.player as any).databaseById?.(id)?.price ?? (typeof (inventory as any)?.price === 'function' ? (inventory as any).price() : (inventory as any)?.price) ?? 0
150
+ const price = basePrice * multiplier
151
+ if (!basePrice || price <= 0) return
152
+ const inventory = (this.player as any).getItem?.(id)
153
+ if (!inventory) return
154
+ const quantity = inventory.quantity()
155
+ if (quantity - nb < 0) return
156
+ ;(this.player as any)._gold.update((gold) => gold + price * nb)
157
+ ;(this.player as any).removeItem(id, nb)
158
+ this.player.syncChanges()
33
159
  }
34
160
  catch (err) {
35
161
  console.log(err)
36
162
  }
163
+ finally {
164
+ this.refreshShop(clientActionId)
165
+ }
37
166
  })
38
- return super.open({ items }, {
167
+ return super.open(this.buildShopData(), {
39
168
  waitingAction: true,
40
169
  blockPlayerInput: true
41
170
  })
42
171
  }
43
- }
172
+ }
@@ -0,0 +1,39 @@
1
+ import { PrebuiltGui } from '@rpgjs/common'
2
+ import { Gui } from './Gui'
3
+ import { RpgPlayer } from '../Player/Player'
4
+
5
+ export interface TitleEntry {
6
+ id: string
7
+ label: string
8
+ disabled?: boolean
9
+ }
10
+
11
+ export interface TitleGuiOptions {
12
+ entries?: TitleEntry[]
13
+ title?: string
14
+ subtitle?: string
15
+ version?: string
16
+ showPressStart?: boolean
17
+ }
18
+
19
+ export interface TitleGuiSelection {
20
+ id?: string
21
+ index?: number
22
+ entry?: TitleEntry
23
+ }
24
+
25
+ export class TitleGui extends Gui {
26
+ constructor(player: RpgPlayer) {
27
+ super(PrebuiltGui.TitleScreen, player)
28
+ }
29
+
30
+ open(options: TitleGuiOptions = {}): Promise<TitleGuiSelection | null> {
31
+ this.on('select', (selection: TitleGuiSelection) => {
32
+ this.close(selection)
33
+ })
34
+ return super.open(options, {
35
+ waitingAction: true,
36
+ blockPlayerInput: true
37
+ })
38
+ }
39
+ }
package/src/Gui/index.ts CHANGED
@@ -3,13 +3,24 @@ import { DialogGui } from './DialogGui'
3
3
  import { MenuGui } from './MenuGui'
4
4
  import { ShopGui } from './ShopGui'
5
5
  import { NotificationGui } from './NotificationGui'
6
+ import { SaveLoadGui } from './SaveLoadGui'
7
+ import { TitleGui } from './TitleGui'
8
+ import { GameoverGui } from './GameoverGui'
6
9
 
7
10
  export {
8
11
  Gui,
9
12
  DialogGui,
10
13
  MenuGui,
11
14
  ShopGui,
12
- NotificationGui
15
+ NotificationGui,
16
+ SaveLoadGui,
17
+ TitleGui,
18
+ GameoverGui
13
19
  }
14
20
 
15
- export { DialogPosition } from './DialogGui'
21
+ export { DialogPosition } from './DialogGui'
22
+ export type { SaveLoadMode, SaveLoadOptions, SaveSlot } from './SaveLoadGui'
23
+ export type { MenuEntryId, MenuEntry, MenuGuiOptions } from './MenuGui'
24
+ export type { ShopGuiOptions, ShopSellList } from './ShopGui'
25
+ export type { TitleEntry, TitleGuiOptions, TitleGuiSelection } from './TitleGui'
26
+ export type { GameoverEntry, GameoverGuiOptions, GameoverGuiSelection } from './GameoverGui'
@@ -1,6 +1,6 @@
1
1
  import { Constructor, PlayerCtor, RpgCommonPlayer } from "@rpgjs/common";
2
2
  import { RpgPlayer } from "./Player";
3
- import { ATK, PDEF, SDEF } from "../presets";
3
+ import { ATK, PDEF, SDEF } from "@rpgjs/common";
4
4
  import { Effect } from "./EffectManager";
5
5
  import type { IElementManager } from "./ElementManager";
6
6
  import type { IEffectManager } from "./EffectManager";
@@ -36,9 +36,64 @@ interface PlayerWithMixins extends RpgCommonPlayer {
36
36
  */
37
37
  export function WithClassManager<TBase extends PlayerCtor>(Base: TBase) {
38
38
  return class extends Base {
39
+ private _resolveClassInput(classInput: ClassClass | string, databaseByIdOverride?: (id: string) => any) {
40
+ if (isString(classInput)) {
41
+ return databaseByIdOverride
42
+ ? databaseByIdOverride(classInput)
43
+ : (this as any).databaseById(classInput);
44
+ }
45
+ return classInput;
46
+ }
47
+
48
+ private _createClassInstance(classInput: ClassClass | string) {
49
+ const classClass = this._resolveClassInput(classInput);
50
+ const instance = new (classClass as ClassClass)();
51
+ return { classClass, instance };
52
+ }
53
+
54
+ /**
55
+ * Create a class instance without side effects.
56
+ */
57
+ createClassInstance(classInput: ClassClass | string) {
58
+ return this._createClassInstance(classInput);
59
+ }
60
+
61
+ /**
62
+ * Resolve class snapshot entry into a class instance without side effects.
63
+ */
64
+ resolveClassSnapshot(snapshot: { _class?: any }, mapOverride?: any) {
65
+ if (!snapshot || snapshot._class == null) {
66
+ return snapshot;
67
+ }
68
+
69
+ const map = mapOverride ?? ((this as any).getCurrentMap?.() || (this as any).map);
70
+ if (!map || !map.database) {
71
+ return snapshot;
72
+ }
73
+
74
+ const databaseByIdOverride = (id: string) => {
75
+ const data = map.database()[id];
76
+ if (!data) {
77
+ throw new Error(
78
+ `The ID=${id} data is not found in the database. Add the data in the property "database"`
79
+ );
80
+ }
81
+ return data;
82
+ };
83
+
84
+ const classId = isString(snapshot._class) ? snapshot._class : snapshot._class?.id;
85
+ if (!classId) {
86
+ return snapshot;
87
+ }
88
+
89
+ const classClass = this._resolveClassInput(classId, databaseByIdOverride);
90
+ const { instance } = this._createClassInstance(classClass as ClassClass);
91
+ return { ...snapshot, _class: instance };
92
+ }
93
+
39
94
  setClass(_class: ClassClass | string) {
40
- if (isString(_class)) _class = (this as any).databaseById(_class);
41
- const classInstance = new (_class as ClassClass)();
95
+ const { instance } = this._createClassInstance(_class);
96
+ const classInstance = instance;
42
97
  (this as any)["execMethod"]("onSet", [this], classInstance);
43
98
  return classInstance;
44
99
  }
@@ -1,6 +1,9 @@
1
1
  import { RpgPlayer } from "./Player";
2
- import { Gui, DialogGui, MenuGui, ShopGui, NotificationGui } from "../Gui";
2
+ import { Gui, DialogGui, MenuGui, ShopGui, NotificationGui, SaveLoadGui, GameoverGui } from "../Gui";
3
3
  import { DialogOptions, Choice } from "../Gui/DialogGui";
4
+ import { SaveLoadOptions, SaveSlot } from "../Gui/SaveLoadGui";
5
+ import { MenuGuiOptions } from "../Gui/MenuGui";
6
+ import { GameoverGuiOptions, GameoverGuiSelection } from "../Gui/GameoverGui";
4
7
  import { Constructor, PlayerCtor } from "@rpgjs/common";
5
8
 
6
9
  /**
@@ -56,21 +59,42 @@ export function WithGuiManager<TBase extends PlayerCtor>(
56
59
 
57
60
  showNotification(
58
61
  message: string,
59
- options: { time?: number; icon?: string; sound?: string } = {}
62
+ options: { time?: number; icon?: string; sound?: string; type?: "info" | "warn" | "error" } = {}
60
63
  ): Promise<any> {
61
- const gui = new NotificationGui(<any>this);
62
- this._gui[gui.id] = gui;
63
- const data = {
64
+ this.emit('notification', {
64
65
  message,
65
66
  ...options,
66
- };
67
- return gui.open(data);
67
+ });
68
+ return Promise.resolve(true);
68
69
  }
69
70
 
70
- callMainMenu() {
71
+ callMainMenu(options: MenuGuiOptions = {}) {
71
72
  const gui = new MenuGui(<any>this);
72
73
  this._gui[gui.id] = gui;
73
- return gui.open();
74
+ return gui.open(options);
75
+ }
76
+
77
+ callGameover(options: GameoverGuiOptions = {}): Promise<GameoverGuiSelection | null> {
78
+ const gui = new GameoverGui(<any>this);
79
+ this._gui[gui.id] = gui;
80
+ return gui.open(options);
81
+ }
82
+
83
+ showSaveLoad(slots: SaveSlot[] = [], options: SaveLoadOptions = {}): Promise<number | null> {
84
+ const gui = new SaveLoadGui(<any>this);
85
+ this._gui[gui.id] = gui;
86
+ return gui.open(slots, options).then((index) => {
87
+ if (typeof index !== 'number') return null;
88
+ return index;
89
+ });
90
+ }
91
+
92
+ showSave(slots: SaveSlot[] = [], options: SaveLoadOptions = {}): Promise<number | null> {
93
+ return this.showSaveLoad(slots, { ...options, mode: 'save' });
94
+ }
95
+
96
+ showLoad(slots: SaveSlot[] = [], options: SaveLoadOptions = {}): Promise<number | null> {
97
+ return this.showSaveLoad(slots, { ...options, mode: 'load' });
74
98
  }
75
99
 
76
100
  /**
@@ -81,7 +105,13 @@ export function WithGuiManager<TBase extends PlayerCtor>(
81
105
  * @returns {void}
82
106
  * @memberof GuiManager
83
107
  */
84
- callShop(items: any[]) {
108
+ callShop(items: any[] | {
109
+ items: any[]
110
+ sell?: Record<string, number> | Array<{ id: string; multiplier: number }>
111
+ sellMultiplier?: number
112
+ message?: string
113
+ face?: { id: string; expression?: string }
114
+ }) {
85
115
  const gui = new ShopGui(<any>this);
86
116
  this._gui[gui.id] = gui;
87
117
  return gui.open(items);
@@ -128,6 +158,10 @@ export function WithGuiManager<TBase extends PlayerCtor>(
128
158
  return gui;
129
159
  }
130
160
 
161
+ getGui(guiId: string) {
162
+ return this._gui[guiId];
163
+ }
164
+
131
165
  /**
132
166
  * Closes the GUI and removes it from memory
133
167
  *
@@ -345,19 +379,96 @@ export interface IGuiManager {
345
379
  */
346
380
  showNotification(
347
381
  message: string,
348
- options?: { time?: number; icon?: string; sound?: string }
382
+ options?: { time?: number; icon?: string; sound?: string; type?: "info" | "warn" | "error" }
349
383
  ): Promise<any>;
384
+
385
+ /**
386
+ * Display a save/load slots screen. Opens the GUI named `rpg-save`
387
+ *
388
+ * ```ts
389
+ * const index = await player.showSaveLoad(slots, { mode: 'save' })
390
+ * ```
391
+ *
392
+ * @title Show Save/Load
393
+ * @method player.showSaveLoad(slots,options)
394
+ * @param {Array<object>} slots
395
+ * @param {object} [options]
396
+ * @returns {Promise<number | null>}
397
+ * @memberof GuiManager
398
+ */
399
+ showSaveLoad(slots?: SaveSlot[], options?: SaveLoadOptions): Promise<number | null>;
400
+
401
+ /**
402
+ * Display a save slots screen. Opens the GUI named `rpg-save`
403
+ *
404
+ * ```ts
405
+ * const index = await player.showSave(slots)
406
+ * ```
407
+ *
408
+ * @title Show Save
409
+ * @method player.showSave(slots,options)
410
+ * @param {Array<object>} slots
411
+ * @param {object} [options]
412
+ * @returns {Promise<number | null>}
413
+ * @memberof GuiManager
414
+ */
415
+ showSave(slots?: SaveSlot[], options?: SaveLoadOptions): Promise<number | null>;
416
+
417
+ /**
418
+ * Display a load slots screen. Opens the GUI named `rpg-save`
419
+ *
420
+ * ```ts
421
+ * const index = await player.showLoad(slots)
422
+ * ```
423
+ *
424
+ * @title Show Load
425
+ * @method player.showLoad(slots,options)
426
+ * @param {Array<object>} slots
427
+ * @param {object} [options]
428
+ * @returns {Promise<number | null>}
429
+ * @memberof GuiManager
430
+ */
431
+ showLoad(slots?: SaveSlot[], options?: SaveLoadOptions): Promise<number | null>;
350
432
  /**
351
433
  * Calls main menu. Opens the GUI named `rpg-main-menu`
352
434
  *
353
435
  * @title Call Main Menu
354
- * @method player.callMainMenu()
436
+ * @method player.callMainMenu(options)
437
+ * @param {object} [options]
355
438
  * @returns {void}
356
439
  * @memberof GuiManager
357
440
  */
358
- callMainMenu(): void;
359
- callShop(items: any[]): void;
441
+ callMainMenu(options?: MenuGuiOptions): void;
442
+
443
+ /**
444
+ * Calls game over menu. Opens the GUI named `rpg-gameover`
445
+ *
446
+ * ```ts
447
+ * const selection = await player.callGameover()
448
+ * if (selection?.id === 'title') {
449
+ * await player.gui('rpg-title-screen').open()
450
+ * }
451
+ * if (selection?.id === 'load') {
452
+ * await player.showLoad()
453
+ * }
454
+ * ```
455
+ *
456
+ * @title Call Game Over Menu
457
+ * @method player.callGameover(options)
458
+ * @param {object} [options]
459
+ * @returns {Promise<GameoverGuiSelection | null>}
460
+ * @memberof GuiManager
461
+ */
462
+ callGameover(options?: GameoverGuiOptions): Promise<GameoverGuiSelection | null>;
463
+ callShop(items: any[] | {
464
+ items: any[]
465
+ sell?: Record<string, number> | Array<{ id: string; multiplier: number }>
466
+ sellMultiplier?: number
467
+ message?: string
468
+ face?: { id: string; expression?: string }
469
+ }): void;
360
470
  gui(guiId: string): Gui;
471
+ getGui(guiId: string): Gui;
361
472
  removeGui(guiId: string, data?: any): void;
362
473
  showAttachedGui(players?: RpgPlayer[] | RpgPlayer): void;
363
474
  hideAttachedGui(players?: RpgPlayer[] | RpgPlayer): void;