@rpgjs/common 3.3.2 → 4.0.0-beta.10

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 (80) hide show
  1. package/LICENSE +19 -0
  2. package/lib/AbstractObject.d.ts +3 -2
  3. package/lib/AbstractObject.js +296 -323
  4. package/lib/AbstractObject.js.map +1 -1
  5. package/lib/Color.js +1 -5
  6. package/lib/Color.js.map +1 -1
  7. package/lib/Event.js +2 -6
  8. package/lib/Event.js.map +1 -1
  9. package/lib/EventEmitter.js +3 -7
  10. package/lib/EventEmitter.js.map +1 -1
  11. package/lib/Game.js +73 -85
  12. package/lib/Game.js.map +1 -1
  13. package/lib/Hit.js +21 -28
  14. package/lib/Hit.js.map +1 -1
  15. package/lib/Logger.js +2 -7
  16. package/lib/Logger.js.map +1 -1
  17. package/lib/Map.d.ts +1 -0
  18. package/lib/Map.js +29 -53
  19. package/lib/Map.js.map +1 -1
  20. package/lib/Module.d.ts +2 -2
  21. package/lib/Module.js +84 -97
  22. package/lib/Module.js.map +1 -1
  23. package/lib/Player.d.ts +1 -0
  24. package/lib/Player.js +4 -7
  25. package/lib/Player.js.map +1 -1
  26. package/lib/Plugin.d.ts +4 -3
  27. package/lib/Plugin.js +14 -14
  28. package/lib/Plugin.js.map +1 -1
  29. package/lib/Scheduler.js +14 -21
  30. package/lib/Scheduler.js.map +1 -1
  31. package/lib/Shape.d.ts +1 -1
  32. package/lib/Shape.js +39 -52
  33. package/lib/Shape.js.map +1 -1
  34. package/lib/Utils.d.ts +4 -1
  35. package/lib/Utils.js +38 -53
  36. package/lib/Utils.js.map +1 -1
  37. package/lib/Vector2d.js +3 -8
  38. package/lib/Vector2d.js.map +1 -1
  39. package/lib/VirtualGrid.d.ts +1 -1
  40. package/lib/VirtualGrid.js +5 -12
  41. package/lib/VirtualGrid.js.map +1 -1
  42. package/lib/Worker.js +2 -10
  43. package/lib/Worker.js.map +1 -1
  44. package/lib/WorldMaps.d.ts +3 -1
  45. package/lib/WorldMaps.js +29 -15
  46. package/lib/WorldMaps.js.map +1 -1
  47. package/lib/gui/PrebuiltGui.js +2 -5
  48. package/lib/gui/PrebuiltGui.js.map +1 -1
  49. package/lib/index.d.ts +3 -1
  50. package/lib/index.js +24 -69
  51. package/lib/index.js.map +1 -1
  52. package/lib/transports/io.js +5 -9
  53. package/lib/transports/io.js.map +1 -1
  54. package/lib/workers/move.js +26 -42
  55. package/lib/workers/move.js.map +1 -1
  56. package/package.json +9 -11
  57. package/src/AbstractObject.ts +915 -0
  58. package/src/Color.ts +29 -0
  59. package/src/DefaultInput.ts +26 -0
  60. package/src/Event.ts +3 -0
  61. package/src/EventEmitter.ts +52 -0
  62. package/src/Game.ts +150 -0
  63. package/src/Hit.ts +70 -0
  64. package/src/Logger.ts +7 -0
  65. package/src/Map.ts +335 -0
  66. package/src/Module.ts +108 -0
  67. package/src/Player.ts +30 -0
  68. package/src/Plugin.ts +91 -0
  69. package/src/Scheduler.ts +88 -0
  70. package/src/Shape.ts +300 -0
  71. package/src/Utils.ts +168 -0
  72. package/src/Vector2d.ts +70 -0
  73. package/src/VirtualGrid.ts +78 -0
  74. package/src/Worker.ts +17 -0
  75. package/src/WorldMaps.ts +204 -0
  76. package/src/gui/PrebuiltGui.ts +27 -0
  77. package/src/index.ts +24 -0
  78. package/src/transports/io.ts +91 -0
  79. package/src/workers/move.ts +61 -0
  80. package/tsconfig.json +25 -0
package/src/Utils.ts ADDED
@@ -0,0 +1,168 @@
1
+ import { constructor } from "@rpgjs/types";
2
+
3
+ export function random(min: number, max: number): number {
4
+ return Math.floor(Math.random() * (max - min + 1) + min)
5
+ }
6
+
7
+ export function isBrowser(): boolean {
8
+ return typeof window !== 'undefined'
9
+ }
10
+
11
+ export function isFunction(val: unknown): boolean {
12
+ return {}.toString.call(val) === '[object Function]'
13
+ }
14
+
15
+ export function isClass(func: unknown): boolean {
16
+ return typeof func === 'function'
17
+ && /^class\s/.test(Function.prototype.toString.call(func));
18
+ }
19
+
20
+ export function isPromise(val: unknown) {
21
+ return isInstanceOf<Promise<unknown>>(val, Promise)
22
+ }
23
+
24
+ export function isArray(val: unknown) {
25
+ return isInstanceOf<Array<unknown>>(val, Array)
26
+ }
27
+
28
+ export function isObject(val: unknown): boolean {
29
+ return typeof val == 'object' && val != null && !isArray(val)
30
+ }
31
+
32
+ export function isString(val: unknown): boolean {
33
+ return typeof val == 'string'
34
+ }
35
+
36
+ export function isInstanceOf<T = any>(val: unknown, _class: any) {
37
+ return val instanceof _class
38
+ }
39
+
40
+ export function arrayUniq(array: any[]): any[] {
41
+ return [...new Set(array)]
42
+ }
43
+
44
+ export function arrayFlat(array: any[]): any[] {
45
+ return array.reduce((acc, val) => acc.concat(val), [])
46
+ }
47
+
48
+ export function intersection([start1, end1]: [number, number], [start2, end2]: [number, number]): boolean {
49
+ return (start1 >= start2 && start1 <= end2) || (start2 >= start1 && start2 < end1)
50
+ }
51
+
52
+ export function capitalize(s: unknown): string {
53
+ if (typeof s !== 'string') return ''
54
+ return s.charAt(0).toUpperCase() + s.slice(1)
55
+ }
56
+
57
+ export function arrayEquals(a: any[], b: any[]): boolean {
58
+ return a.length === b.length && a.every((v, i) => v === b[i])
59
+ }
60
+
61
+ export function applyMixins(derivedCtor: constructor<any>, baseCtors: constructor<any>[]) {
62
+ baseCtors.forEach((baseCtor) => {
63
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
64
+ const baseCtorName = Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
65
+ if (!baseCtorName) {
66
+ return
67
+ }
68
+ Object.defineProperty(derivedCtor.prototype, name, baseCtorName)
69
+ })
70
+ })
71
+ }
72
+
73
+ export function generateUID(): string {
74
+ let firstPart: any = (Math.random() * 46656) | 0
75
+ let secondPart: any = (Math.random() * 46656) | 0
76
+ firstPart = ("000" + firstPart.toString(36)).slice(-3)
77
+ secondPart = ("000" + secondPart.toString(36)).slice(-3)
78
+ return firstPart + secondPart
79
+ }
80
+
81
+ export function createConstructor<T>(...propNames: any[]): T {
82
+ return class {
83
+ constructor(...propValues){
84
+ propNames.forEach((name, idx) => {
85
+ this[name] = propValues[idx]
86
+ })
87
+ }
88
+ } as unknown as T
89
+ }
90
+
91
+ export function sharedArrayBuffer() {
92
+ let buffer
93
+ if (typeof SharedArrayBuffer != 'undefined') {
94
+ buffer = SharedArrayBuffer
95
+ }
96
+ else {
97
+ buffer = ArrayBuffer
98
+ }
99
+ return buffer
100
+ }
101
+
102
+ export function toRadians(angle: number) {
103
+ return angle * (Math.PI / 180)
104
+ }
105
+
106
+ export function hexaToNumber(hexa: string): {
107
+ value: number,
108
+ alpha: number
109
+ } {
110
+ let val = hexa.replace('#', '')
111
+ let alpha = 1
112
+ if (val.length === 3) {
113
+ val = val.split('').map((v) => v + v).join('')
114
+ }
115
+ if (val.length === 8) {
116
+ alpha = parseInt(val.substring(0, 2), 16) / 255
117
+ val = val.substring(2)
118
+ }
119
+ return {
120
+ value: parseInt(val, 16),
121
+ alpha
122
+ }
123
+ }
124
+
125
+ export function extractId(path: string): string | null {
126
+ const id = path.match(/([a-zA-Z0-9-_$!]+)\.[a-z]+$/i)
127
+ if (!id) return null
128
+ return id[1]
129
+ }
130
+
131
+ export function basename(path: string): string {
132
+ return path.substring(path.lastIndexOf('/') + 1)
133
+ }
134
+
135
+ export function fps2ms(fps: number): number {
136
+ return 1000 / fps
137
+ }
138
+
139
+ export function preciseNow(): number {
140
+ return typeof performance !== 'undefined' ? performance.now() : Date.now()
141
+ }
142
+
143
+ export default {
144
+ random,
145
+ isBrowser,
146
+ isPromise,
147
+ isArray,
148
+ isObject,
149
+ isString,
150
+ isFunction,
151
+ isClass,
152
+ isInstanceOf,
153
+ arrayUniq,
154
+ arrayFlat,
155
+ arrayEquals,
156
+ intersection,
157
+ applyMixins,
158
+ capitalize,
159
+ sharedArrayBuffer,
160
+ generateUID,
161
+ createConstructor,
162
+ toRadians,
163
+ extractId,
164
+ basename,
165
+ fps2ms,
166
+ preciseNow,
167
+ hexaToNumber
168
+ }
@@ -0,0 +1,70 @@
1
+ export class Vector2d {
2
+ constructor(public x: number, public y: number, public z: number = 0) {}
3
+
4
+ set(vector: Vector2d) {
5
+ this.x = vector.x
6
+ this.y = vector.y
7
+ this.z = vector.z
8
+ return this
9
+ }
10
+
11
+ add(vector: Vector2d) {
12
+ this.x += vector.x
13
+ this.y += vector.y
14
+ return this
15
+ }
16
+
17
+ subtract(vector: Vector2d) {
18
+ this.x -= vector.x
19
+ this.y -= vector.y
20
+ return this
21
+ }
22
+
23
+ multiply(scalar: number) {
24
+ this.x *= scalar
25
+ this.y *= scalar
26
+ return this
27
+ }
28
+
29
+ divide(scalar: number) {
30
+ this.x /= scalar
31
+ this.y /= scalar
32
+ return this
33
+ }
34
+
35
+ distanceWith(vector: Vector2d): number {
36
+ const dx = this.x - vector.x
37
+ const dy = this.y - vector.y
38
+ return Math.sqrt(dx ** 2 + dy ** 2)
39
+ }
40
+
41
+ magnitude(): number {
42
+ return Math.sqrt(this.x * this.x + this.y * this.y)
43
+ }
44
+
45
+ copy(): Vector2d {
46
+ return new Vector2d(this.x, this.y, this.z)
47
+ }
48
+
49
+ normalize() {
50
+ return this.divide(this.magnitude())
51
+ }
52
+
53
+ isEqual(vector: Vector2d): boolean {
54
+ return this.x === vector.x &&
55
+ this.y === vector.y &&
56
+ this.z === vector.z
57
+ }
58
+
59
+ hasDifferentValues(vector: Vector2d): boolean {
60
+ return this.x !== vector.x ||
61
+ this.y !== vector.y ||
62
+ this.z !== vector.z
63
+ }
64
+ }
65
+
66
+ export class Vector2dZero extends Vector2d {
67
+ constructor() {
68
+ super(0, 0)
69
+ }
70
+ }
@@ -0,0 +1,78 @@
1
+ export type Box = { minX: number, minY: number, maxX: number, maxY: number }
2
+
3
+ export class VirtualGrid {
4
+ private cells: Map<number, Set<string>> = new Map()
5
+ private inverseCells: Map<string, Set<number>> = new Map()
6
+
7
+ constructor(private nbCellWidth: number, private cellWidth: number, private cellHeight: number) {}
8
+
9
+ zoom(nbCell: number): VirtualGrid {
10
+ this.nbCellWidth = Math.ceil(this.nbCellWidth / nbCell)
11
+ this.cellWidth *= nbCell
12
+ this.cellHeight *= nbCell
13
+ return this
14
+ }
15
+
16
+ getCellIndex(x: number, y: number) {
17
+ return this.nbCellWidth * Math.floor(y / this.cellHeight) + Math.floor(x / this.cellWidth)
18
+ }
19
+
20
+ getCells(box: Box, cb: (index: number) => void) {
21
+ const {
22
+ minX,
23
+ minY,
24
+ maxX,
25
+ maxY
26
+ } = box
27
+ const topLeft = this.getCellIndex(minX, minY)
28
+ const topRight = this.getCellIndex(maxX, minY)
29
+ const bottomLeft = this.getCellIndex(minX, maxY)
30
+ const nbLines = (bottomLeft - topLeft) / this.nbCellWidth + 1
31
+ for (let j=0 ; j < nbLines ; j++) {
32
+ for (let i = topLeft ; i <= topRight ; i++) {
33
+ const index = i + (j * this.nbCellWidth)
34
+ cb(index)
35
+ }
36
+ }
37
+ }
38
+
39
+ getObjectsByBox(box: Box): Set<string> {
40
+ let objects: string[] = []
41
+ this.getCells(box, (index) => {
42
+ objects = [...objects, ...this.cells.get(index) || []]
43
+ })
44
+ return new Set(objects)
45
+ }
46
+
47
+ getObjectsById(id: string): Set<string> {
48
+ let objects: string[] = []
49
+ const cells = this.inverseCells.get(id)
50
+ cells?.forEach((index) => {
51
+ objects = [...objects, ...this.cells.get(index) || []]
52
+ })
53
+ return new Set(objects)
54
+ }
55
+
56
+ clearObjectInCells(id: string) {
57
+ if (this.inverseCells.has(id)) {
58
+ this.inverseCells.get(id)?.forEach((cellIndex: number) => {
59
+ this.cells.get(cellIndex)?.delete(id)
60
+ })
61
+ this.inverseCells.delete(id)
62
+ }
63
+ }
64
+
65
+ insertInCells(id: string, box: { minX: number, minY: number, maxX: number, maxY: number }) {
66
+ this.clearObjectInCells(id)
67
+ const cells: Set<number> = new Set()
68
+ this.getCells(box, (index) => {
69
+ cells.add(index)
70
+ const memoryCells = this.cells.get(index)
71
+ if (!memoryCells) {
72
+ this.cells.set(index, new Set())
73
+ }
74
+ this.cells.get(index)?.add(id)
75
+ })
76
+ this.inverseCells.set(id, cells)
77
+ }
78
+ }
package/src/Worker.ts ADDED
@@ -0,0 +1,17 @@
1
+ import workerpool from 'workerpool'
2
+
3
+ export class GameWorker {
4
+ pool: any
5
+
6
+ constructor(private options = {}) {
7
+ //this.pool = workerpool.pool(__dirname + '/workers/move.js', options)
8
+ }
9
+
10
+ load() {
11
+ return this
12
+ }
13
+
14
+ call(methodName: string, data: any) {
15
+ return this.pool.exec(methodName, [data])
16
+ }
17
+ }
@@ -0,0 +1,204 @@
1
+ import RBush from 'rbush'
2
+ import { TiledWorldMap } from '@rpgjs/tiled'
3
+ import { RpgCommonMap } from './Map'
4
+ import { Direction } from '@rpgjs/types'
5
+
6
+ export interface RpgClassMap<T> {
7
+ id?: string
8
+ new (server: any): T,
9
+ }
10
+
11
+ export interface RpgTiledWorldMap extends TiledWorldMap{
12
+ properties?: {
13
+ [key: string]: any
14
+ }
15
+ }
16
+
17
+ type PositionBox = { minX: number, minY: number, maxX: number, maxY: number }
18
+ type MapTree = { map: RpgClassMap<RpgCommonMap> } & PositionBox
19
+
20
+ export class RpgCommonWorldMaps {
21
+ private mapsTree: RBush = new RBush(500)
22
+ private maps: Map<string, RpgTiledWorldMap> = new Map()
23
+
24
+ constructor(public id: string) {}
25
+
26
+ /**
27
+ * Adding information from the map to the world
28
+ *
29
+ * > Maximum maps in world: 500
30
+ *
31
+ * @title Add Map in world
32
+ * @method world.addMap(wordMapInfo,map)
33
+ * @param {object} wordMapInfo
34
+ * Object file:
35
+ * ```ts
36
+ * {
37
+ * fileName: string;
38
+ height: number;
39
+ width: number;
40
+ x: number;
41
+ y: number;
42
+ * }
43
+ ```
44
+ `fileName` represents a file to the JSON file (TMX transformed) or directly the Tiled Map Editor object
45
+ *
46
+ * @param {class of RpgMap} map
47
+ * @since 3.0.0-beta.8
48
+ * @memberof RpgWorldMaps
49
+ */
50
+ addMap(wordMapInfo: RpgTiledWorldMap, map: RpgClassMap<RpgCommonMap>) {
51
+ const { x, y, height, width } = wordMapInfo
52
+ map.prototype.worldMapParent = this
53
+ this.maps.set(map.id as string, wordMapInfo)
54
+ this.mapsTree.insert<MapTree>({
55
+ minX: x,
56
+ minY: y,
57
+ maxX: x + width,
58
+ maxY: y + height,
59
+ map
60
+ })
61
+ }
62
+
63
+ updateMap(mapId: string, wordMapInfo: RpgTiledWorldMap): boolean {
64
+ const map = this.maps.get(mapId)
65
+ if (map) {
66
+ const item = (this.mapsTree.all() as MapTree[]).find(item => item.map.id == mapId)
67
+ if (!item) return false
68
+ this.maps.set(mapId, wordMapInfo)
69
+ item.map.prototype.worldMapParent = this
70
+ item.minX = wordMapInfo.x
71
+ item.minY = wordMapInfo.y
72
+ item.maxX = wordMapInfo.x + wordMapInfo.width
73
+ item.maxY = wordMapInfo.y + wordMapInfo.height
74
+ return true
75
+ }
76
+ return false
77
+ }
78
+
79
+ /**
80
+ * Remove map of the world
81
+ * @title Remove map of the world
82
+ * @method world.removeMap(mapId)
83
+ * @param {string} mapId
84
+ * @returns {boolean}
85
+ * @since 3.0.0-beta.8
86
+ * @memberof RpgWorldMaps
87
+ */
88
+ removeMap(mapId: string): boolean {
89
+ const map = this.maps.get(mapId)
90
+ if (map) {
91
+ const item = (this.mapsTree.all() as MapTree[]).find(item => item.map.id == mapId)
92
+ if (!item) return false
93
+ this.maps.delete(mapId)
94
+ item.map.prototype.worldMapParent = undefined
95
+ this.mapsTree.remove(item)
96
+ return true
97
+ }
98
+ return false
99
+ }
100
+
101
+ removeAllMaps() {
102
+ this.maps.forEach((map, id) => {
103
+ this.removeMap(id)
104
+ })
105
+ }
106
+
107
+ /**
108
+ * Retrieve information from the world
109
+ *
110
+ * @title Retrieve information from the world
111
+ * @method world.getMapInfo(id)
112
+ * @param {string} id map id
113
+ * @return {RpgTiledWorldMap | undefined}
114
+ * {
115
+ * id?: string
116
+ * properties?: object
117
+ * fileName: string;
118
+ height: number;
119
+ width: number;
120
+ x: number;
121
+ y: number;
122
+ * }
123
+ * @since 3.0.0-beta.8
124
+ * @memberof RpgWorldMaps
125
+ */
126
+ getMapInfo(id: string): RpgTiledWorldMap | undefined {
127
+ return this.maps.get(id)
128
+ }
129
+
130
+ /**
131
+ * Retrieves neighboring maps according to positions or direction
132
+ *
133
+ * @title Retrieves neighboring maps
134
+ * @method world.getAdjacentMaps(map,search)
135
+ * @param {RpgMap} map The source map. We want to find the neighboring maps of the source map
136
+ * @param { PositionBox | Direction | { x: number, y: number } } search Research method
137
+ * * PositionBox. An object of the following form:
138
+ * `{ minX: number, minY: number, maxX: number, maxY: number }`
139
+ * * Direction. Collect all the maps in the given direction (e.g. the maps at the top)
140
+ * * Point: { x: number, y: number }
141
+ * @return { {class of RpgMap}[] }
142
+ * @since 3.0.0-beta.8
143
+ * @example
144
+ * ```ts
145
+ * world.getAdjacentMaps(mymap, Direction.Up) // returns [class of RpgMap]
146
+ * ```
147
+ * @memberof RpgWorldMaps
148
+ */
149
+ getAdjacentMaps(map: RpgCommonMap, search: PositionBox | Direction | { x: number, y: number }): RpgClassMap<RpgCommonMap>[] {
150
+ let position: PositionBox = {} as PositionBox
151
+ const point = search as { x: number, y: number }
152
+ if (typeof search == 'number') {
153
+ const padding = 1
154
+ switch (search) {
155
+ case Direction.Up:
156
+ position = {
157
+ minX: map.worldX + padding,
158
+ maxX: map.worldX + map.widthPx - padding,
159
+ minY: map.worldY - padding - 1,
160
+ maxY: map.worldY - padding
161
+ }
162
+ break;
163
+ case Direction.Right:
164
+ position = {
165
+ minX: map.worldX + map.widthPx + padding,
166
+ maxX: map.worldX + map.widthPx + padding + 1,
167
+ minY: map.worldY + padding,
168
+ maxY: map.worldY + map.heightPx - padding
169
+ }
170
+ break;
171
+ case Direction.Down:
172
+ position = {
173
+ minX: map.worldX + padding,
174
+ maxX: map.worldX + map.widthPx - padding,
175
+ minY: map.worldY + map.heightPx + padding,
176
+ maxY: map.worldY + map.heightPx + padding + 1
177
+ }
178
+ break;
179
+ case Direction.Left:
180
+ position = {
181
+ minX: map.worldX - padding,
182
+ maxX: map.worldX - padding - 1,
183
+ minY: map.worldY + padding,
184
+ maxY: map.worldY + map.heightPx - padding
185
+ }
186
+ break;
187
+ }
188
+
189
+ }
190
+ else if (point.x) {
191
+ position = {
192
+ minX: point.x,
193
+ maxX: point.x,
194
+ minY: point.y,
195
+ maxY: point.y
196
+ }
197
+ }
198
+ else {
199
+ position = search as PositionBox
200
+ }
201
+ const result = this.mapsTree.search(position)
202
+ return result.map(ret => ret.map)
203
+ }
204
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ *
3
+ * Pre-made GUIs already exist. For example, the command `player.showText()` displays the rpg-dialog component. It is up to you to customize the component or take advantage of the `@rpgjs/default-gui` module which already contains ready-made components
4
+ *
5
+ * @title Prebuilt GUI
6
+ * @enum {string}
7
+ *
8
+ * PrebuiltGui.Dialog | rpg-dialog
9
+ * PrebuiltGui.MainMenu | rpg-main-menu
10
+ * PrebuiltGui.Shop | rpg-shop
11
+ * PrebuiltGui.Disconnect | rpg-disconnect
12
+ * PrebuiltGui.Gameover | rpg-gameover
13
+ * PrebuiltGui.Save | rpg-save
14
+ * PrebuiltGui.Controls | rpg-controls
15
+ * PrebuiltGui.Notification | rpg-notification
16
+ * @memberof PrebuiltGui
17
+ * */
18
+ export enum PrebuiltGui {
19
+ Dialog = 'rpg-dialog',
20
+ MainMenu = 'rpg-main-menu',
21
+ Shop = 'rpg-shop',
22
+ Disconnect = 'rpg-disconnect',
23
+ Gameover = 'rpg-gameover',
24
+ Save = 'rpg-save',
25
+ Controls = 'rpg-controls',
26
+ Notification = 'rpg-notification'
27
+ }
package/src/index.ts ADDED
@@ -0,0 +1,24 @@
1
+ import AbstractObject from './Player';
2
+ export { LiteralDirection, RpgCommonPlayer } from './Player'
3
+ export { AbstractObject }
4
+ export { RpgCommonEvent } from './Event'
5
+ export { RpgCommonMap } from './Map'
6
+ export { RpgCommonGame, GameSide } from './Game'
7
+ export { EventEmitter } from './EventEmitter'
8
+ export { PrebuiltGui } from './gui/PrebuiltGui'
9
+ export *as Utils from './Utils'
10
+ export { RpgPlugin, Plugin, HookServer, HookClient } from './Plugin'
11
+ export * as TransportIo from './transports/io'
12
+ export { Input, Control } from '@rpgjs/types'
13
+ export { Hit } from './Hit'
14
+ export { Scheduler } from './Scheduler'
15
+ export { RpgModule, loadModules, ModuleType } from './Module'
16
+ export * as MockIo from './transports/io'
17
+ export * as Logger from './Logger';
18
+ export { RpgShape, ShapePositioning } from './Shape'
19
+ export { VirtualGrid } from './VirtualGrid'
20
+ export { RpgCommonWorldMaps } from './WorldMaps'
21
+ export { Vector2d } from './Vector2d'
22
+ export { Direction } from '@rpgjs/types'
23
+ export { transitionColor } from './Color'
24
+ export { DefaultInput } from './DefaultInput'
@@ -0,0 +1,91 @@
1
+ class MockIo {
2
+ events: Map<string, any> = new Map()
3
+
4
+ on(name: string, value) {
5
+ this.events.set(name, value)
6
+ }
7
+
8
+ off(name: string) {
9
+ this.events.delete(name)
10
+ }
11
+
12
+ once(name: string, value) {
13
+ this.on(name, value)
14
+ }
15
+
16
+ _trigger(name: string, data, client?) {
17
+ const fn = this.events.get(name)
18
+ if (fn) fn(data, client)
19
+ }
20
+ }
21
+
22
+ class MockSocket {
23
+ id: string
24
+
25
+ constructor(private io: any, public handshake) {
26
+ this.id = ''+Math.random()
27
+ }
28
+
29
+ on(name: string, value) {
30
+ this.io.on(name, value, this.id)
31
+ return this
32
+ }
33
+
34
+ once(name: string, value) {
35
+ this.io.once(name, value, this.id)
36
+ return this
37
+ }
38
+
39
+ emit(name: string, data) {
40
+ this.io.emit(name, data, this.id)
41
+ }
42
+
43
+ removeAllListeners(name: string) {
44
+ return this.off(name)
45
+ }
46
+
47
+ off(name: string) {
48
+ this.io.off(name, this.id)
49
+ }
50
+ }
51
+
52
+ class MockClientIo extends MockIo {
53
+ id: string = ''
54
+
55
+ connection(handshake: any) {
56
+ serverIo.connection(this, handshake)
57
+ this._trigger('connect', undefined)
58
+ return this
59
+ }
60
+
61
+ emit(name: string, data) {
62
+ serverIo._trigger(name, data, this)
63
+ return this
64
+ }
65
+
66
+ disconnect() {
67
+ this.emit('disconnect', undefined)
68
+ }
69
+ }
70
+
71
+ class MockServerIo extends MockIo {
72
+ private clients: Map<string, MockClientIo> = new Map()
73
+
74
+ connection(client, handshake) {
75
+ const socket = new MockSocket(this, handshake)
76
+ this.clients.set(socket.id, client)
77
+ client.id = socket.id
78
+ this._trigger('connection', socket)
79
+ }
80
+
81
+ emit(name: string, data, id) {
82
+ this.clients.get(id)?._trigger(name, data)
83
+ }
84
+
85
+ clear() {
86
+ this.clients.clear()
87
+ }
88
+ }
89
+
90
+ export const serverIo = new MockServerIo()
91
+ export const ClientIo = MockClientIo