@rpgjs/server 5.0.0-alpha.18 → 5.0.0-alpha.19
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/dist/Player/ItemManager.d.ts +140 -0
- package/dist/decorators/event.d.ts +46 -0
- package/dist/decorators/map.d.ts +177 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +766 -209
- package/dist/index.js.map +1 -1
- package/dist/rooms/map.d.ts +51 -1
- package/package.json +9 -9
- package/src/Player/ItemManager.ts +331 -29
- package/src/decorators/event.ts +61 -0
- package/src/decorators/map.ts +198 -0
- package/src/index.ts +1 -1
- package/src/rooms/map.ts +72 -2
|
@@ -1,4 +1,144 @@
|
|
|
1
1
|
import { PlayerCtor } from '@rpgjs/common';
|
|
2
|
+
import { RpgPlayer } from './Player';
|
|
3
|
+
/**
|
|
4
|
+
* Interface defining the hooks that can be implemented on item classes or objects
|
|
5
|
+
*
|
|
6
|
+
* These hooks are called at specific moments during the item lifecycle:
|
|
7
|
+
* - `onAdd`: When the item is added to the player's inventory
|
|
8
|
+
* - `onUse`: When the item is successfully used
|
|
9
|
+
* - `onUseFailed`: When the item usage fails (e.g., chance roll failed)
|
|
10
|
+
* - `onRemove`: When the item is removed from the inventory
|
|
11
|
+
* - `onEquip`: When the item is equipped or unequipped
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const itemHooks: ItemHooks = {
|
|
16
|
+
* onAdd(player) {
|
|
17
|
+
* console.log('Item added to inventory');
|
|
18
|
+
* },
|
|
19
|
+
* onUse(player) {
|
|
20
|
+
* player.hp += 100;
|
|
21
|
+
* }
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export interface ItemHooks {
|
|
26
|
+
/**
|
|
27
|
+
* Called when the item is added to the player's inventory
|
|
28
|
+
*
|
|
29
|
+
* @param player - The player receiving the item
|
|
30
|
+
*/
|
|
31
|
+
onAdd?: (player: RpgPlayer) => void | Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Called when the item is successfully used
|
|
34
|
+
*
|
|
35
|
+
* @param player - The player using the item
|
|
36
|
+
*/
|
|
37
|
+
onUse?: (player: RpgPlayer) => void | Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Called when the item usage fails (e.g., chance roll failed)
|
|
40
|
+
*
|
|
41
|
+
* @param player - The player attempting to use the item
|
|
42
|
+
*/
|
|
43
|
+
onUseFailed?: (player: RpgPlayer) => void | Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Called when the item is removed from the inventory
|
|
46
|
+
*
|
|
47
|
+
* @param player - The player losing the item
|
|
48
|
+
*/
|
|
49
|
+
onRemove?: (player: RpgPlayer) => void | Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Called when the item is equipped or unequipped
|
|
52
|
+
*
|
|
53
|
+
* @param player - The player equipping/unequipping the item
|
|
54
|
+
* @param equip - true if equipping, false if unequipping
|
|
55
|
+
*/
|
|
56
|
+
onEquip?: (player: RpgPlayer, equip: boolean) => void | Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Base properties that can be included in an item object
|
|
60
|
+
*
|
|
61
|
+
* This interface defines the common properties that items can have.
|
|
62
|
+
* Use this as a base and extend it with specific item types.
|
|
63
|
+
*
|
|
64
|
+
* @template T - Additional properties specific to the item type
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* interface PotionData extends ItemData {
|
|
69
|
+
* hpValue: number;
|
|
70
|
+
* mpValue: number;
|
|
71
|
+
* }
|
|
72
|
+
*
|
|
73
|
+
* const potion: ItemObject<PotionData> = {
|
|
74
|
+
* name: 'Health Potion',
|
|
75
|
+
* description: 'Restores 100 HP',
|
|
76
|
+
* price: 200,
|
|
77
|
+
* hpValue: 100,
|
|
78
|
+
* mpValue: 0,
|
|
79
|
+
* onUse(player) {
|
|
80
|
+
* player.hp += this.hpValue;
|
|
81
|
+
* }
|
|
82
|
+
* };
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export interface ItemData {
|
|
86
|
+
/** Item name */
|
|
87
|
+
name?: string;
|
|
88
|
+
/** Item description */
|
|
89
|
+
description?: string;
|
|
90
|
+
/** Item price */
|
|
91
|
+
price?: number;
|
|
92
|
+
/** HP value restored when used */
|
|
93
|
+
hpValue?: number;
|
|
94
|
+
/** MP/SP value restored when used */
|
|
95
|
+
mpValue?: number;
|
|
96
|
+
/** Chance to successfully use the item (0-1) */
|
|
97
|
+
hitRate?: number;
|
|
98
|
+
/** Whether the item is consumable */
|
|
99
|
+
consumable?: boolean;
|
|
100
|
+
/** States to add when used */
|
|
101
|
+
addStates?: any[];
|
|
102
|
+
/** States to remove when used */
|
|
103
|
+
removeStates?: any[];
|
|
104
|
+
/** Elemental properties */
|
|
105
|
+
elements?: any[];
|
|
106
|
+
/** Parameter modifiers */
|
|
107
|
+
paramsModifier?: Record<string, any>;
|
|
108
|
+
/** Item type (for equipment validation) */
|
|
109
|
+
_type?: 'item' | 'weapon' | 'armor';
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Item object type that combines data properties with hooks
|
|
113
|
+
*
|
|
114
|
+
* This type allows you to create item objects directly without needing a class.
|
|
115
|
+
* The object can contain both item data properties and lifecycle hooks.
|
|
116
|
+
*
|
|
117
|
+
* @template T - Additional properties specific to the item type (extends ItemData)
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const potion: ItemObject = {
|
|
122
|
+
* name: 'Health Potion',
|
|
123
|
+
* description: 'Restores 100 HP',
|
|
124
|
+
* price: 200,
|
|
125
|
+
* hpValue: 100,
|
|
126
|
+
* consumable: true,
|
|
127
|
+
* onAdd(player) {
|
|
128
|
+
* console.log('Potion added!');
|
|
129
|
+
* },
|
|
130
|
+
* onUse(player) {
|
|
131
|
+
* player.hp += 100;
|
|
132
|
+
* }
|
|
133
|
+
* };
|
|
134
|
+
*
|
|
135
|
+
* player.addItem(potion);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export type ItemObject<T extends ItemData = ItemData> = T & ItemHooks & {
|
|
139
|
+
/** Item identifier (required if not using class or string) */
|
|
140
|
+
id?: string;
|
|
141
|
+
};
|
|
2
142
|
/**
|
|
3
143
|
* Item Manager Mixin
|
|
4
144
|
*
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare enum EventMode {
|
|
2
|
+
Shared = "shared",
|
|
3
|
+
Scenario = "scenario"
|
|
4
|
+
}
|
|
5
|
+
export interface EventOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The mode of the event, shared evening or scenario
|
|
8
|
+
*
|
|
9
|
+
* The scenario mode allows you to have events specific to the player. Thus, the graphics, the positions of the event will be different for each player. Beware of performance! The event is duplicated by each player.
|
|
10
|
+
*
|
|
11
|
+
* `shared` mode by default
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { RpgEvent, EventData, RpgPlayer, EventMode } from '@rpgjs/server'
|
|
15
|
+
* @EventData({
|
|
16
|
+
* name: 'EV-1',
|
|
17
|
+
* mode: EventMode.Scenario // or EventMode.Shared
|
|
18
|
+
* })
|
|
19
|
+
* export class CharaEvent extends RpgEvent { }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @prop {string} [mode] Either "shared" or "scenario".
|
|
23
|
+
* @memberof EventData
|
|
24
|
+
* */
|
|
25
|
+
mode?: EventMode;
|
|
26
|
+
width?: number;
|
|
27
|
+
height?: number;
|
|
28
|
+
/**
|
|
29
|
+
* The hitbox of the event. By default, this is the size of the tile of the map
|
|
30
|
+
*
|
|
31
|
+
* @prop { { width: number, height: number }} [hitbox]
|
|
32
|
+
* @memberof EventData
|
|
33
|
+
* */
|
|
34
|
+
hitbox?: {
|
|
35
|
+
width?: number;
|
|
36
|
+
height?: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Name of the event. This is its identifier. it allows you to retrieve an event and place it on the map
|
|
40
|
+
*
|
|
41
|
+
* @prop {string} name
|
|
42
|
+
* @memberof EventData
|
|
43
|
+
* */
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function EventData(options: EventOptions): (target: any) => void;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export interface MapOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Map identifier. Allows to go to the map (for example with player.changeMap())
|
|
4
|
+
*
|
|
5
|
+
* @prop {string} [id]
|
|
6
|
+
* @memberof MapData
|
|
7
|
+
* */
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* the path to the .tmx file (Tiled Map Editor)
|
|
11
|
+
*
|
|
12
|
+
* Remember to use `require()` function
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { MapData, RpgMap } from '@rpgjs/server'
|
|
16
|
+
*
|
|
17
|
+
* @MapData({
|
|
18
|
+
* id: 'town',
|
|
19
|
+
* file: require('./tmx/town.tmx')
|
|
20
|
+
* })
|
|
21
|
+
* class TownMap extends RpgMap { }
|
|
22
|
+
* ```
|
|
23
|
+
* @prop {string} file
|
|
24
|
+
* @memberof MapData
|
|
25
|
+
* */
|
|
26
|
+
file: any;
|
|
27
|
+
/**
|
|
28
|
+
* The name of the map.
|
|
29
|
+
* @prop {string} [name]
|
|
30
|
+
* @memberof MapData
|
|
31
|
+
* */
|
|
32
|
+
name?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Map events. This is an array containing `RpgEvent` classes.
|
|
35
|
+
* You can also give an object that will indicate the positions of the event on the map.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { MapData, RpgMap, EventData, RpgEvent } from '@rpgjs/server'
|
|
39
|
+
*
|
|
40
|
+
* @EventData({
|
|
41
|
+
* name: 'Ev-1'
|
|
42
|
+
* })
|
|
43
|
+
* class NpcEvent extends RpgEvent { }
|
|
44
|
+
*
|
|
45
|
+
* @MapData({
|
|
46
|
+
* id: 'medieval',
|
|
47
|
+
* file: require('./tmx/town.tmx'),
|
|
48
|
+
* events: [NpcEvent]
|
|
49
|
+
* })
|
|
50
|
+
* class TownMap extends RpgMap {}
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* If the positions are not defined, the event will be placed on a Tiled Map Editor shape ([/guide/create-event.html#position-the-event-on-the-map](Guide)). Otherwise, it will be placed at `{x:0, y:0 }`
|
|
54
|
+
*
|
|
55
|
+
* You can give positions:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* events: [{ event: NpcEvent, x: 10, y: 30 }]
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @prop {Class of RpgEvent[] | { event: Class RpgEvent, x: number, y: number }} [events]
|
|
62
|
+
* @memberof MapData
|
|
63
|
+
* */
|
|
64
|
+
events?: {
|
|
65
|
+
event: any;
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
}[] | any[];
|
|
69
|
+
/**
|
|
70
|
+
* The sounds that will be played when the map is open. Sounds must be defined on the client side. Then, put the name of the sound identifier
|
|
71
|
+
*
|
|
72
|
+
* So, it is possible to play several sounds (in loop or not) on the card. You can put a background music (BGM) and a background noise (BGS) for example
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* sounds: ['my-bgm', 'my-bgs']
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* And client side:
|
|
79
|
+
*
|
|
80
|
+
* ```ts
|
|
81
|
+
* import { Sound } from '@rpgjs/client'
|
|
82
|
+
*
|
|
83
|
+
* @Sound({
|
|
84
|
+
* sounds: {
|
|
85
|
+
* 'my-bgm': require('./assets/bgm.ogg'),
|
|
86
|
+
* 'my-bgs': require('./assets/bgs.ogg')
|
|
87
|
+
* },
|
|
88
|
+
* loop: true
|
|
89
|
+
* })
|
|
90
|
+
* export class Sounds {}
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* See [https://docs.rpgjs.dev/classes/sound.html#properties](RpgSound Decorator)
|
|
94
|
+
*
|
|
95
|
+
* @prop {Array<string>} [sounds]
|
|
96
|
+
* @memberof MapData
|
|
97
|
+
* */
|
|
98
|
+
sounds?: string[];
|
|
99
|
+
/**
|
|
100
|
+
* Specify which properties will be synchronized with the client. On the client side, you can retrieve the values synchronized with the valueChanges property on the scene
|
|
101
|
+
*
|
|
102
|
+
* You must create the schema:
|
|
103
|
+
*
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { MapData, RpgMap } from '@rpgjs/server'
|
|
106
|
+
*
|
|
107
|
+
* @MapData({
|
|
108
|
+
* id: 'medieval',
|
|
109
|
+
* file: require('./tmx/town.tmx'),
|
|
110
|
+
* syncSchema: {
|
|
111
|
+
* count: Number
|
|
112
|
+
* }
|
|
113
|
+
* })
|
|
114
|
+
* export class TownMap extends RpgMap {
|
|
115
|
+
* count: number = 0
|
|
116
|
+
*
|
|
117
|
+
* onLoad() {}
|
|
118
|
+
*
|
|
119
|
+
* onJoin() {
|
|
120
|
+
* this.count++
|
|
121
|
+
* }
|
|
122
|
+
*
|
|
123
|
+
* onLeave(player) {
|
|
124
|
+
* super.onLeave(player)
|
|
125
|
+
* this.count--
|
|
126
|
+
* }
|
|
127
|
+
* }
|
|
128
|
+
*
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* If you want to change the scheme of players and events, consider overwriting the existing scheme
|
|
132
|
+
*
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { MapData, RpgMap, RpgPlayer } from '@rpgjs/server'
|
|
135
|
+
*
|
|
136
|
+
*
|
|
137
|
+
* declare module '@rpgjs/server' {
|
|
138
|
+
* export interface RpgPlayer {
|
|
139
|
+
* customProp: string
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
*
|
|
143
|
+
* @MapData({
|
|
144
|
+
* id: 'medieval',
|
|
145
|
+
* file: require('./tmx/town.tmx'),
|
|
146
|
+
* syncSchema: {
|
|
147
|
+
* users: [
|
|
148
|
+
* {
|
|
149
|
+
* customProp: String,
|
|
150
|
+
* ...RpgPlayer.schemas
|
|
151
|
+
* }
|
|
152
|
+
* ]
|
|
153
|
+
* }
|
|
154
|
+
* })
|
|
155
|
+
* export class TownMap extends RpgMap {}
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* The properties are called `users` and `events`. Their scheme is identical and defined in `RpgPlayer.schemas`. To write schematics, refer to the [documentation of the simple-room](https://github.com/RSamaium/simple-room) module
|
|
159
|
+
*
|
|
160
|
+
* @prop {object} [syncSchema]
|
|
161
|
+
* @memberof MapData
|
|
162
|
+
* */
|
|
163
|
+
syncSchema?: any;
|
|
164
|
+
/**
|
|
165
|
+
* Decreases the RAM of the map. In this case, some instructions will be different.
|
|
166
|
+
*
|
|
167
|
+
* `map.getTileByIndex()` will not return all tiles of an index but only the tile of the highest layer
|
|
168
|
+
*
|
|
169
|
+
* > You can also use the `low-memory` property in Tiled maps
|
|
170
|
+
*
|
|
171
|
+
* @prop {boolean} [lowMemory=false]
|
|
172
|
+
* @since 3.1.0
|
|
173
|
+
* @memberof MapData
|
|
174
|
+
* */
|
|
175
|
+
lowMemory?: boolean;
|
|
176
|
+
}
|
|
177
|
+
export declare function MapData(options: MapOptions): (target: any) => void;
|
package/dist/index.d.ts
CHANGED