@rpgjs/server 4.0.0-beta.9 → 4.0.0-rc.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.
- package/CHANGELOG.md +32 -0
- package/lib/Game/EventManager.d.ts +53 -0
- package/lib/Game/EventManager.js +93 -0
- package/lib/Game/EventManager.js.map +1 -0
- package/lib/Game/Map.d.ts +6 -30
- package/lib/Game/Map.js +26 -61
- package/lib/Game/Map.js.map +1 -1
- package/lib/Gui/MenuGui.js +2 -2
- package/lib/Gui/MenuGui.js.map +1 -1
- package/lib/Player/BattleManager.d.ts +5 -5
- package/lib/Player/BattleManager.js +8 -7
- package/lib/Player/BattleManager.js.map +1 -1
- package/lib/Player/ClassManager.d.ts +11 -4
- package/lib/Player/ClassManager.js +7 -3
- package/lib/Player/ClassManager.js.map +1 -1
- package/lib/Player/EffectManager.d.ts +2 -2
- package/lib/Player/EffectManager.js +6 -6
- package/lib/Player/EffectManager.js.map +1 -1
- package/lib/Player/ElementManager.d.ts +4 -1
- package/lib/Player/ElementManager.js.map +1 -1
- package/lib/Player/ItemManager.d.ts +21 -0
- package/lib/Player/ItemManager.js +22 -1
- package/lib/Player/ItemManager.js.map +1 -1
- package/lib/Player/MoveManager.js +27 -14
- package/lib/Player/MoveManager.js.map +1 -1
- package/lib/Player/ParameterManager.d.ts +2 -1
- package/lib/Player/ParameterManager.js +15 -4
- package/lib/Player/ParameterManager.js.map +1 -1
- package/lib/Player/Player.d.ts +150 -54
- package/lib/Player/Player.js +142 -58
- package/lib/Player/Player.js.map +1 -1
- package/lib/Player/SkillManager.d.ts +13 -8
- package/lib/Player/SkillManager.js +14 -12
- package/lib/Player/SkillManager.js.map +1 -1
- package/lib/Player/StateManager.d.ts +11 -6
- package/lib/Player/StateManager.js +21 -6
- package/lib/Player/StateManager.js.map +1 -1
- package/lib/RpgServer.d.ts +42 -2
- package/lib/Scenes/Map.d.ts +3 -0
- package/lib/Scenes/Map.js +4 -0
- package/lib/Scenes/Map.js.map +1 -1
- package/lib/decorators/event.d.ts +1 -1
- package/lib/decorators/event.js +2 -1
- package/lib/decorators/event.js.map +1 -1
- package/lib/decorators/map.d.ts +5 -2
- package/lib/decorators/map.js.map +1 -1
- package/lib/express/server.js +5 -1
- package/lib/express/server.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/models/Item.d.ts +1 -1
- package/lib/server.d.ts +3 -6
- package/lib/server.js +9 -8
- package/lib/server.js.map +1 -1
- package/package.json +8 -7
- package/src/Game/EventManager.ts +110 -0
- package/src/Game/Map.ts +37 -69
- package/src/Gui/MenuGui.ts +3 -3
- package/src/Player/BattleManager.ts +10 -9
- package/src/Player/ClassManager.ts +13 -7
- package/src/Player/EffectManager.ts +6 -5
- package/src/Player/ElementManager.ts +4 -1
- package/src/Player/ItemManager.ts +47 -26
- package/src/Player/MoveManager.ts +35 -15
- package/src/Player/ParameterManager.ts +19 -8
- package/src/Player/Player.ts +170 -57
- package/src/Player/SkillManager.ts +23 -21
- package/src/Player/StateManager.ts +30 -11
- package/src/RpgServer.ts +42 -2
- package/src/Scenes/Map.ts +4 -0
- package/src/decorators/event.ts +2 -1
- package/src/decorators/map.ts +5 -2
- package/src/express/server.ts +9 -3
- package/src/index.ts +10 -8
- package/src/models/Item.ts +1 -1
- package/src/server.ts +11 -8
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { PlayerType } from "@rpgjs/types"
|
|
2
|
+
import { RpgEvent, RpgPlayer } from "../Player/Player"
|
|
3
|
+
import { RpgMap } from "./Map"
|
|
4
|
+
|
|
5
|
+
export type EventsList = {
|
|
6
|
+
[playerId: string]: RpgEvent
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export enum EventMode {
|
|
10
|
+
Shared = 'shared',
|
|
11
|
+
Scenario = 'scenario'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ⚠️ Please note that the event system can be on the player or on the card.
|
|
16
|
+
* On player, it's Scenario mode
|
|
17
|
+
* On-map: Shared mode
|
|
18
|
+
* So this here is either RpgMap or RpgPlayer
|
|
19
|
+
* You can check the mode with the mode cleanup on the retrieved event
|
|
20
|
+
*/
|
|
21
|
+
export class EventManager {
|
|
22
|
+
/**
|
|
23
|
+
* @title event list
|
|
24
|
+
* @prop { { [eventId: string]: RpgEvent } } [events]
|
|
25
|
+
* @memberof Map
|
|
26
|
+
* */
|
|
27
|
+
public events: EventsList
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get Event in current map
|
|
31
|
+
* @title Get Event
|
|
32
|
+
* @since 3.0.0-beta.7
|
|
33
|
+
* @method map.getEvent(eventId)
|
|
34
|
+
* @param {string} eventId Event Id
|
|
35
|
+
* @returns {RpgEvent | undefined}
|
|
36
|
+
* @memberof Map
|
|
37
|
+
*/
|
|
38
|
+
getEvent<T extends RpgEvent>(eventId: string): T | undefined {
|
|
39
|
+
return this.events[eventId] as T
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getEventByName<T extends RpgEvent>(eventName: string): T | undefined {
|
|
43
|
+
const events = Object.keys(this.events)
|
|
44
|
+
const key = events.find(key => this.events[key].name == eventName)
|
|
45
|
+
if (!key) return
|
|
46
|
+
return this.events[key] as T
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Removes an event from the map. Returns false if the event is not found
|
|
51
|
+
*
|
|
52
|
+
* Deletion of an event forced to be performed at the end of several aynschronous notions
|
|
53
|
+
*
|
|
54
|
+
* @title Remove Event
|
|
55
|
+
* @since 3.0.0-beta.4
|
|
56
|
+
* @method map.removeEvent(eventId)
|
|
57
|
+
* @param {string} eventId Event Name
|
|
58
|
+
* @returns {boolean}
|
|
59
|
+
* @memberof Map
|
|
60
|
+
*/
|
|
61
|
+
removeEvent(eventId: string): boolean {
|
|
62
|
+
if (!this.events[eventId]) return false
|
|
63
|
+
const mode = this.events[eventId].mode
|
|
64
|
+
this.removeObject(this.events[eventId], mode)
|
|
65
|
+
delete this.events[eventId]
|
|
66
|
+
// Change the state of the packet that will be sent to the client, adding the deleted flag to indicate to the client that the event has been deleted.
|
|
67
|
+
if (mode == EventMode.Scenario) {
|
|
68
|
+
this.getCurrentMap()?.$setCurrentState(`users.${this.id}.events.${eventId}.deleted`, true)
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.$setCurrentState(`events.${eventId}.deleted`, true)
|
|
72
|
+
}
|
|
73
|
+
return true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// @internal
|
|
77
|
+
removeObject(object: RpgPlayer | RpgEvent, mode: EventMode = EventMode.Shared) {
|
|
78
|
+
const map = this.getCurrentMap()
|
|
79
|
+
if (!map) return
|
|
80
|
+
map.getShapes().forEach(shape => shape.out(object))
|
|
81
|
+
const events: RpgPlayer[] = Object.values(map.game.world.getObjectsOfGroup(map.id, object))
|
|
82
|
+
for (let event of events) {
|
|
83
|
+
object.getShapes().forEach(shape => shape.out(event))
|
|
84
|
+
event.getShapes().forEach(shape => shape.out(object))
|
|
85
|
+
}
|
|
86
|
+
object._destroy$.next()
|
|
87
|
+
object._destroy$.complete()
|
|
88
|
+
// force RXJS, close subject. TODO: avoid this
|
|
89
|
+
if (object.type != PlayerType.Player) object._destroy$['_closed'] = true
|
|
90
|
+
map.grid.clearObjectInCells(object.id)
|
|
91
|
+
for (let playerId in map.players) {
|
|
92
|
+
if (object.id == playerId) continue
|
|
93
|
+
const otherPlayer = map.players[playerId]
|
|
94
|
+
if (otherPlayer.following?.id == object.id) {
|
|
95
|
+
otherPlayer.cameraFollow(otherPlayer)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// last player before removed of this map
|
|
99
|
+
if (map.nbPlayers === 1 && object.type === PlayerType.Player) {
|
|
100
|
+
// clear cache for this map
|
|
101
|
+
map.remove(true)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface EventManager {
|
|
107
|
+
getCurrentMap(): RpgMap | null
|
|
108
|
+
id: string
|
|
109
|
+
$setCurrentState: (path: string, value: any) => void;
|
|
110
|
+
}
|
package/src/Game/Map.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { RpgCommonMap, Utils, RpgShape, RpgCommonGame, AbstractObject } from '@rpgjs/common'
|
|
2
2
|
import { TiledParserFile, TiledParser, TiledTileset } from '@rpgjs/tiled'
|
|
3
3
|
import { EventOptions } from '../decorators/event'
|
|
4
|
-
import { RpgPlayer,
|
|
4
|
+
import { RpgPlayer, RpgEvent, RpgClassEvent } from '../Player/Player'
|
|
5
5
|
import { Move } from '../Player/MoveManager'
|
|
6
6
|
import { RpgServerEngine } from '../server'
|
|
7
7
|
import { Observable } from 'rxjs'
|
|
8
8
|
import path from 'path'
|
|
9
|
-
import { HitBox, MovingHitbox, Position } from '@rpgjs/types'
|
|
9
|
+
import { HitBox, MovingHitbox, PlayerType, Position } from '@rpgjs/types'
|
|
10
10
|
import { World } from 'simple-room'
|
|
11
|
+
import { EventManager, EventMode } from './EventManager'
|
|
11
12
|
|
|
12
13
|
export type EventPosOption = {
|
|
13
14
|
x: number,
|
|
@@ -63,15 +64,9 @@ export class RpgMap extends RpgCommonMap {
|
|
|
63
64
|
public _events: EventOption[]
|
|
64
65
|
public file: any
|
|
65
66
|
|
|
66
|
-
/**
|
|
67
|
-
* @title event list
|
|
68
|
-
* @prop { { [eventId: string]: RpgEvent } } [events]
|
|
69
|
-
* @memberof Map
|
|
70
|
-
* */
|
|
71
|
-
public events: EventsList = {}
|
|
72
|
-
|
|
73
67
|
constructor(private _server: RpgServerEngine) {
|
|
74
68
|
super()
|
|
69
|
+
this.events = {}
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
// alias of users property in simple-room package
|
|
@@ -237,7 +232,16 @@ export class RpgMap extends RpgCommonMap {
|
|
|
237
232
|
this.removeObject(player)
|
|
238
233
|
}
|
|
239
234
|
|
|
240
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Loads common events onto the game map.
|
|
237
|
+
*
|
|
238
|
+
* @private
|
|
239
|
+
* @param {RpgClassEvent<RpgEvent>[]} commonEvents - An array of common events to load.
|
|
240
|
+
* @param {RpgPlayer} [player] - The player instance on which to create the dynamic events. If not provided, the function will use the current instance.
|
|
241
|
+
* @returns {void}
|
|
242
|
+
*/
|
|
243
|
+
// @internal
|
|
244
|
+
loadCommonEvents(commonEvents: RpgClassEvent<RpgEvent>[], player?: RpgPlayer) {
|
|
241
245
|
let events: EventPosOption[] = []
|
|
242
246
|
this.getShapes().forEach(shape => {
|
|
243
247
|
const findEvent = commonEvents.find(event => event._name == shape.name)
|
|
@@ -248,8 +252,14 @@ export class RpgMap extends RpgCommonMap {
|
|
|
248
252
|
y,
|
|
249
253
|
event: findEvent
|
|
250
254
|
})
|
|
251
|
-
})
|
|
252
|
-
|
|
255
|
+
});
|
|
256
|
+
if (player) {
|
|
257
|
+
player.createDynamicEvent(events, false)
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
this.createDynamicEvent(events)
|
|
261
|
+
}
|
|
262
|
+
|
|
253
263
|
}
|
|
254
264
|
|
|
255
265
|
// TODO
|
|
@@ -350,7 +360,7 @@ export class RpgMap extends RpgCommonMap {
|
|
|
350
360
|
const events = this.createEvents(eventsList as EventPosOption[], EventMode.Shared)
|
|
351
361
|
let ret = {}
|
|
352
362
|
for (let key in events) {
|
|
353
|
-
this.events[key] = events[key]
|
|
363
|
+
this.events[key] = events[key] as any
|
|
354
364
|
this.events[key].updateInVirtualGrid()
|
|
355
365
|
this.events[key].execMethod('onInit')
|
|
356
366
|
// force to get Proxy object to sync with client
|
|
@@ -359,35 +369,6 @@ export class RpgMap extends RpgCommonMap {
|
|
|
359
369
|
return ret
|
|
360
370
|
}
|
|
361
371
|
|
|
362
|
-
/**
|
|
363
|
-
* Get Event in current map
|
|
364
|
-
* @title Get Event
|
|
365
|
-
* @since 3.0.0-beta.7
|
|
366
|
-
* @method map.getEvent(eventId)
|
|
367
|
-
* @param {string} eventId Event Id
|
|
368
|
-
* @returns {RpgEvent | undefined}
|
|
369
|
-
* @memberof Map
|
|
370
|
-
*/
|
|
371
|
-
getEvent<T extends RpgEvent>(eventId: string): T | undefined {
|
|
372
|
-
return this.events[eventId] as T
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Removes an event from the map. Returns false if the event is not found
|
|
377
|
-
* @title Remove Event
|
|
378
|
-
* @since 3.0.0-beta.4
|
|
379
|
-
* @method map.removeEvent(eventId)
|
|
380
|
-
* @param {string} eventId Event Name
|
|
381
|
-
* @returns {boolean}
|
|
382
|
-
* @memberof Map
|
|
383
|
-
*/
|
|
384
|
-
removeEvent(eventId: string): boolean {
|
|
385
|
-
if (!this.events[eventId]) return false
|
|
386
|
-
this.removeObject(this.events[eventId])
|
|
387
|
-
delete this.events[eventId]
|
|
388
|
-
return true
|
|
389
|
-
}
|
|
390
|
-
|
|
391
372
|
createEvent(obj: EventPosOption, mode: EventMode, shape?: RpgShape): RpgEvent | null {
|
|
392
373
|
let event: any, position: Position | undefined
|
|
393
374
|
|
|
@@ -397,7 +378,7 @@ export class RpgMap extends RpgCommonMap {
|
|
|
397
378
|
}
|
|
398
379
|
else {
|
|
399
380
|
event = obj.event
|
|
400
|
-
position = { x: obj.x, y: obj.y, z: 0 }
|
|
381
|
+
position = { x: obj.x, y: obj.y, z: obj.z ?? 0 }
|
|
401
382
|
}
|
|
402
383
|
|
|
403
384
|
// The event is ignored if the mode is different.
|
|
@@ -433,30 +414,6 @@ export class RpgMap extends RpgCommonMap {
|
|
|
433
414
|
return events
|
|
434
415
|
}
|
|
435
416
|
|
|
436
|
-
private removeObject(object: RpgPlayer | RpgEvent) {
|
|
437
|
-
this.getShapes().forEach(shape => shape.out(object))
|
|
438
|
-
const events: RpgPlayer[] = Object.values(this.game.world.getObjectsOfGroup(this.id, object))
|
|
439
|
-
for (let event of events) {
|
|
440
|
-
object.getShapes().forEach(shape => shape.out(event))
|
|
441
|
-
event.getShapes().forEach(shape => shape.out(object))
|
|
442
|
-
}
|
|
443
|
-
object._destroy$.next()
|
|
444
|
-
object._destroy$.complete()
|
|
445
|
-
this.grid.clearObjectInCells(object.id)
|
|
446
|
-
for (let playerId in this.players) {
|
|
447
|
-
if (object.id == playerId) continue
|
|
448
|
-
const otherPlayer = this.players[playerId]
|
|
449
|
-
if (otherPlayer.following?.id == object.id) {
|
|
450
|
-
otherPlayer.cameraFollow(otherPlayer)
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
// last player before removed of this map
|
|
454
|
-
if (this.nbPlayers === 1 && object.type === 'player') {
|
|
455
|
-
// clear cache for this map
|
|
456
|
-
this.remove(true)
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
417
|
/**
|
|
461
418
|
* Allows to create a temporary hitbox on the map that can have a movement
|
|
462
419
|
For example, you can use it to explode a bomb and find all the affected players, or during a sword strike, you can create a moving hitbox and find the affected players again
|
|
@@ -501,13 +458,24 @@ For example, you can use it to explode a bomb and find all the affected players,
|
|
|
501
458
|
setSync(schema: any) {
|
|
502
459
|
return this.$setSchema(schema)
|
|
503
460
|
}
|
|
461
|
+
|
|
462
|
+
// Reflects itself. Just for compatibility with the EventManager class
|
|
463
|
+
getCurrentMap() {
|
|
464
|
+
return this
|
|
465
|
+
}
|
|
504
466
|
}
|
|
505
467
|
|
|
506
|
-
export interface RpgMap {
|
|
468
|
+
export interface RpgMap extends EventManager {
|
|
507
469
|
sounds: string[]
|
|
508
470
|
$schema: any
|
|
509
471
|
$setSchema: (schema: any) => void
|
|
510
472
|
$patchSchema: (schema: any) => void
|
|
511
473
|
$snapshotUser: (userId: string) => any
|
|
512
474
|
onLoad()
|
|
513
|
-
|
|
475
|
+
$setCurrentState: (path: string, value: any) => void;
|
|
476
|
+
id: string
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
Utils.applyMixins(RpgMap, [
|
|
480
|
+
EventManager
|
|
481
|
+
])
|
package/src/Gui/MenuGui.ts
CHANGED
|
@@ -11,11 +11,11 @@ export class MenuGui extends Gui implements IGui {
|
|
|
11
11
|
open() {
|
|
12
12
|
this.on('useItem', (id) => {
|
|
13
13
|
try {
|
|
14
|
-
|
|
14
|
+
this.player.useItem(id)
|
|
15
15
|
this.player.syncChanges()
|
|
16
16
|
}
|
|
17
|
-
catch (err) {
|
|
18
|
-
|
|
17
|
+
catch (err: any) {
|
|
18
|
+
this.player.showNotification(err.msg)
|
|
19
19
|
}
|
|
20
20
|
})
|
|
21
21
|
return super.open('', {
|
|
@@ -18,30 +18,30 @@ const {
|
|
|
18
18
|
export class BattleManager {
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Apply damage. Player will lose HP. the `
|
|
21
|
+
* Apply damage. Player will lose HP. the `attackerPlayer` parameter is the other player, the one who attacks.
|
|
22
22
|
*
|
|
23
23
|
* If you don't set the skill parameter, it will be a physical attack.
|
|
24
24
|
* The attack formula is already defined but you can customize it in the server options
|
|
25
25
|
*
|
|
26
26
|
* ```ts
|
|
27
|
-
* player.applyDamage(
|
|
27
|
+
* player.applyDamage(attackerPlayer) // returns { damage: number }
|
|
28
28
|
* ```
|
|
29
29
|
*
|
|
30
30
|
* @title Apply Damage
|
|
31
|
-
* @method player.applyDamage(
|
|
32
|
-
* @param {RpgPlayer}
|
|
31
|
+
* @method player.applyDamage(attackerPlayer,skill)
|
|
32
|
+
* @param {RpgPlayer} attackerPlayer The attacking player
|
|
33
33
|
* @param {any} [skill]
|
|
34
34
|
* @returns {object}
|
|
35
35
|
* @memberof BattleManager
|
|
36
36
|
* */
|
|
37
|
-
applyDamage(
|
|
37
|
+
applyDamage(attackerPlayer: RpgPlayer, skill?: any): {
|
|
38
38
|
damage: number,
|
|
39
39
|
critical: boolean,
|
|
40
40
|
elementVulnerable: boolean,
|
|
41
41
|
guard: boolean,
|
|
42
42
|
superGuard: boolean
|
|
43
43
|
} {
|
|
44
|
-
const getParam = (player) => {
|
|
44
|
+
const getParam = (player: RpgPlayer) => {
|
|
45
45
|
const params = {}
|
|
46
46
|
this.parameters.forEach((val, key) => {
|
|
47
47
|
params[key] = player.param[key]
|
|
@@ -58,8 +58,8 @@ export class BattleManager {
|
|
|
58
58
|
let guard = false
|
|
59
59
|
let superGuard = false
|
|
60
60
|
let elementVulnerable = false
|
|
61
|
-
const paramA = getParam(
|
|
62
|
-
const paramB = getParam(this)
|
|
61
|
+
const paramA = getParam(attackerPlayer)
|
|
62
|
+
const paramB = getParam(<any>this)
|
|
63
63
|
if (skill) {
|
|
64
64
|
fn = this.getFormulas('damageSkill')
|
|
65
65
|
if (!fn) {
|
|
@@ -73,7 +73,7 @@ export class BattleManager {
|
|
|
73
73
|
throw new Error('Physic Formulas not exists')
|
|
74
74
|
}
|
|
75
75
|
damage = fn(paramA, paramB)
|
|
76
|
-
const coef = this.coefficientElements(
|
|
76
|
+
const coef = this.coefficientElements(attackerPlayer)
|
|
77
77
|
if (coef >= 2) {
|
|
78
78
|
elementVulnerable = true
|
|
79
79
|
}
|
|
@@ -99,6 +99,7 @@ export class BattleManager {
|
|
|
99
99
|
}
|
|
100
100
|
if (this.hasEffect(Effect.SUPER_GUARD)) {
|
|
101
101
|
damage /= 4
|
|
102
|
+
superGuard = true
|
|
102
103
|
}
|
|
103
104
|
this.hp -= damage
|
|
104
105
|
return {
|
|
@@ -3,9 +3,13 @@ import { ParameterManager } from './ParameterManager'
|
|
|
3
3
|
import { ItemManager } from './ItemManager'
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
-
applyMixins
|
|
6
|
+
applyMixins,
|
|
7
|
+
isString
|
|
7
8
|
} = Utils
|
|
8
9
|
|
|
10
|
+
type ClassClass = { new(...args: any[]) }
|
|
11
|
+
type ActorClass = { new(...args: any[]) }
|
|
12
|
+
|
|
9
13
|
export class ClassManager {
|
|
10
14
|
|
|
11
15
|
_class: any
|
|
@@ -21,12 +25,13 @@ export class ClassManager {
|
|
|
21
25
|
*
|
|
22
26
|
* @title Set Class
|
|
23
27
|
* @method player.setClass(ClassClass)
|
|
24
|
-
* @param {ClassClass} class
|
|
28
|
+
* @param {ClassClass} class class or id
|
|
25
29
|
* @returns {instance of ClassClass}
|
|
26
30
|
* @memberof ClassManager
|
|
27
31
|
* */
|
|
28
|
-
setClass(_class) {
|
|
29
|
-
|
|
32
|
+
setClass(_class: ClassClass | string) {
|
|
33
|
+
if (isString(_class)) _class = this.databaseById(_class)
|
|
34
|
+
this._class = new (_class as ClassClass)()
|
|
30
35
|
this['execMethod']('onSet', [this], this._class)
|
|
31
36
|
return this._class
|
|
32
37
|
}
|
|
@@ -42,12 +47,13 @@ export class ClassManager {
|
|
|
42
47
|
*
|
|
43
48
|
* @title Set Actor
|
|
44
49
|
* @method player.setActor(ActorClass)
|
|
45
|
-
* @param {ActorClass} actorClass
|
|
50
|
+
* @param {ActorClass} actorClass actor class or id
|
|
46
51
|
* @returns {instance of ActorClass}
|
|
47
52
|
* @memberof ClassManager
|
|
48
53
|
* */
|
|
49
|
-
setActor(actorClass) {
|
|
50
|
-
|
|
54
|
+
setActor(actorClass: ActorClass | string) {
|
|
55
|
+
if (isString(actorClass)) actorClass = this.databaseById(actorClass)
|
|
56
|
+
const actor = new (actorClass as ActorClass)()
|
|
51
57
|
this.name = actor.name
|
|
52
58
|
this.initialLevel = actor.initialLevel
|
|
53
59
|
this.finalLevel = actor.finalLevel
|
|
@@ -4,6 +4,7 @@ import { ParameterManager } from './ParameterManager'
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
MAXHP,
|
|
7
|
+
MAXSP
|
|
7
8
|
} from '../presets'
|
|
8
9
|
|
|
9
10
|
const {
|
|
@@ -22,19 +23,19 @@ export class EffectManager {
|
|
|
22
23
|
this.hp += item.hpValue
|
|
23
24
|
}
|
|
24
25
|
if (item.hpRate) {
|
|
25
|
-
this.hp += this.param[MAXHP]
|
|
26
|
+
this.hp += this.param[MAXHP] * item.hpRate
|
|
26
27
|
}
|
|
27
28
|
if (item.spValue) {
|
|
28
|
-
this.sp += item.
|
|
29
|
+
this.sp += item.spValue
|
|
29
30
|
}
|
|
30
31
|
if (item.spRate) {
|
|
31
|
-
this.sp += this.param[
|
|
32
|
+
this.sp += this.param[MAXSP] * item.spRate
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* ```ts
|
|
37
|
-
* import { Effect } from '@rpgjs/
|
|
38
|
+
* import { Effect } from '@rpgjs/database'
|
|
38
39
|
*
|
|
39
40
|
* const bool = player.hasEffect(Effect.CAN_NOT_SKILL)
|
|
40
41
|
* ```
|
|
@@ -75,7 +76,7 @@ export class EffectManager {
|
|
|
75
76
|
* Assigns effects to the player. If you give a array, it does not change the effects of the player's states and armor/weapons equipped.
|
|
76
77
|
*
|
|
77
78
|
* ```ts
|
|
78
|
-
* import { Effect } from '@rpgjs/
|
|
79
|
+
* import { Effect } from '@rpgjs/database'
|
|
79
80
|
*
|
|
80
81
|
* player.effects = [Effect.CAN_NOT_SKILL]
|
|
81
82
|
* ```
|
|
@@ -101,7 +101,10 @@ export class ElementManager extends ItemFixture {
|
|
|
101
101
|
* @readonly
|
|
102
102
|
* @memberof ElementManager
|
|
103
103
|
* */
|
|
104
|
-
get elements() {
|
|
104
|
+
get elements(): {
|
|
105
|
+
rate: number,
|
|
106
|
+
element: string
|
|
107
|
+
}[] {
|
|
105
108
|
let elements: any = []
|
|
106
109
|
for (let item of this.equipments) {
|
|
107
110
|
if (item.elements) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Utils }
|
|
1
|
+
import { Utils } from '@rpgjs/common'
|
|
2
2
|
import { Effect, ItemOptions } from '@rpgjs/database'
|
|
3
3
|
import { ItemLog } from '../logs'
|
|
4
4
|
import { ItemModel } from '../models/Item'
|
|
@@ -6,43 +6,43 @@ import { EffectManager } from './EffectManager'
|
|
|
6
6
|
import { GoldManager } from './GoldManager'
|
|
7
7
|
import { StateManager } from './StateManager'
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
10
|
ATK,
|
|
11
11
|
PDEF,
|
|
12
12
|
SDEF
|
|
13
13
|
} from '../presets'
|
|
14
14
|
|
|
15
|
-
const {
|
|
16
|
-
isString,
|
|
15
|
+
const {
|
|
16
|
+
isString,
|
|
17
17
|
isInstanceOf,
|
|
18
18
|
applyMixins
|
|
19
19
|
} = Utils
|
|
20
20
|
|
|
21
21
|
type ItemClass = { new(...args: any[]), price?: number, _type?: string }
|
|
22
|
-
type Inventory =
|
|
22
|
+
type Inventory = { nb: number, item: ItemModel }
|
|
23
23
|
|
|
24
24
|
export class ItemManager {
|
|
25
25
|
|
|
26
26
|
items: Inventory[]
|
|
27
27
|
equipments: ItemModel[] = []
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the information of an object: the number and the instance
|
|
31
|
+
* @title Get Item
|
|
32
|
+
* @method player.getItem(itemClass)
|
|
33
|
+
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
34
|
+
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
35
|
+
* @memberof ItemManager
|
|
36
|
+
* @example
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import Potion from 'your-database/potion'
|
|
40
|
+
*
|
|
41
|
+
* player.addItem(Potion, 5)
|
|
42
|
+
* const inventory = player.getItem(Potion)
|
|
43
|
+
* console.log(inventory) // { nb: 5, item: <instance of Potion> }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
46
|
getItem(itemClass: ItemClass | string): Inventory {
|
|
47
47
|
const index: number = this._getItemIndex(itemClass)
|
|
48
48
|
return this.items[index]
|
|
@@ -281,9 +281,9 @@ export class ItemManager {
|
|
|
281
281
|
this.gold += (ItemClass.price / 2) * nbToSell
|
|
282
282
|
this.removeItem(ItemClass, nbToSell)
|
|
283
283
|
return inventory
|
|
284
|
-
}
|
|
284
|
+
}
|
|
285
285
|
|
|
286
|
-
private getParamItem(name) {
|
|
286
|
+
private getParamItem(name: string): number {
|
|
287
287
|
let nb = 0
|
|
288
288
|
for (let item of this.equipments) {
|
|
289
289
|
nb += item[name] || 0
|
|
@@ -296,14 +296,35 @@ export class ItemManager {
|
|
|
296
296
|
return nb
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
+
/**
|
|
300
|
+
* recover the attack sum of items equipped on the player.
|
|
301
|
+
*
|
|
302
|
+
* @title Get the player's attack
|
|
303
|
+
* @prop {number} player.atk
|
|
304
|
+
* @memberof ItemManager
|
|
305
|
+
*/
|
|
299
306
|
get atk(): number {
|
|
300
307
|
return this.getParamItem(ATK)
|
|
301
308
|
}
|
|
302
309
|
|
|
310
|
+
/**
|
|
311
|
+
* recover the physic defense sum of items equipped on the player.
|
|
312
|
+
*
|
|
313
|
+
* @title Get the player's pdef
|
|
314
|
+
* @prop {number} player.pdef
|
|
315
|
+
* @memberof ItemManager
|
|
316
|
+
*/
|
|
303
317
|
get pdef(): number {
|
|
304
318
|
return this.getParamItem(PDEF)
|
|
305
319
|
}
|
|
306
320
|
|
|
321
|
+
/**
|
|
322
|
+
* recover the skill defense sum of items equipped on the player.
|
|
323
|
+
*
|
|
324
|
+
* @title Get the player's sdef
|
|
325
|
+
* @prop {number} player.sdef
|
|
326
|
+
* @memberof ItemManager
|
|
327
|
+
*/
|
|
307
328
|
get sdef(): number {
|
|
308
329
|
return this.getParamItem(SDEF)
|
|
309
330
|
}
|
|
@@ -381,7 +402,7 @@ export class ItemManager {
|
|
|
381
402
|
if (item.consumable === false) {
|
|
382
403
|
throw ItemLog.notUseItem(itemClass)
|
|
383
404
|
}
|
|
384
|
-
const hitRate = item.hitRate
|
|
405
|
+
const hitRate = item.hitRate ?? 1
|
|
385
406
|
if (Math.random() > hitRate) {
|
|
386
407
|
this.removeItem(itemClass)
|
|
387
408
|
this['execMethod']('onUseFailed', [this], item)
|