@rpgjs/server 5.0.0-alpha.4 → 5.0.0-alpha.41
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/Gui/DialogGui.d.ts +5 -0
- package/dist/Gui/GameoverGui.d.ts +23 -0
- package/dist/Gui/Gui.d.ts +6 -0
- package/dist/Gui/MenuGui.d.ts +22 -3
- package/dist/Gui/NotificationGui.d.ts +1 -2
- package/dist/Gui/SaveLoadGui.d.ts +13 -0
- package/dist/Gui/ShopGui.d.ts +28 -3
- package/dist/Gui/TitleGui.d.ts +23 -0
- package/dist/Gui/index.d.ts +10 -1
- package/dist/Player/BattleManager.d.ts +34 -12
- package/dist/Player/ClassManager.d.ts +46 -13
- package/dist/Player/ComponentManager.d.ts +123 -0
- package/dist/Player/Components.d.ts +345 -0
- package/dist/Player/EffectManager.d.ts +86 -0
- package/dist/Player/ElementManager.d.ts +104 -0
- package/dist/Player/GoldManager.d.ts +22 -0
- package/dist/Player/GuiManager.d.ts +259 -0
- package/dist/Player/ItemFixture.d.ts +6 -0
- package/dist/Player/ItemManager.d.ts +450 -9
- package/dist/Player/MoveManager.d.ts +324 -69
- package/dist/Player/ParameterManager.d.ts +344 -14
- package/dist/Player/Player.d.ts +460 -8
- package/dist/Player/SkillManager.d.ts +197 -15
- package/dist/Player/StateManager.d.ts +89 -25
- package/dist/Player/VariableManager.d.ts +74 -0
- package/dist/RpgServer.d.ts +502 -64
- package/dist/RpgServerEngine.d.ts +2 -1
- package/dist/decorators/event.d.ts +46 -0
- package/dist/decorators/map.d.ts +287 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +21653 -20900
- package/dist/index.js.map +1 -1
- package/dist/logs/log.d.ts +2 -3
- package/dist/module.d.ts +43 -1
- package/dist/presets/index.d.ts +0 -9
- package/dist/rooms/BaseRoom.d.ts +132 -0
- package/dist/rooms/lobby.d.ts +10 -2
- package/dist/rooms/map.d.ts +1236 -17
- package/dist/services/save.d.ts +43 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/localStorage.d.ts +23 -0
- package/package.json +14 -10
- package/src/Gui/DialogGui.ts +19 -4
- package/src/Gui/GameoverGui.ts +39 -0
- package/src/Gui/Gui.ts +23 -1
- package/src/Gui/MenuGui.ts +155 -6
- package/src/Gui/NotificationGui.ts +1 -2
- package/src/Gui/SaveLoadGui.ts +60 -0
- package/src/Gui/ShopGui.ts +146 -16
- package/src/Gui/TitleGui.ts +39 -0
- package/src/Gui/index.ts +15 -2
- package/src/Player/BattleManager.ts +91 -49
- package/src/Player/ClassManager.ts +118 -50
- package/src/Player/ComponentManager.ts +425 -19
- package/src/Player/Components.ts +380 -0
- package/src/Player/EffectManager.ts +81 -44
- package/src/Player/ElementManager.ts +109 -86
- package/src/Player/GoldManager.ts +32 -35
- package/src/Player/GuiManager.ts +308 -150
- package/src/Player/ItemFixture.ts +4 -5
- package/src/Player/ItemManager.ts +774 -355
- package/src/Player/MoveManager.ts +1544 -774
- package/src/Player/ParameterManager.ts +546 -104
- package/src/Player/Player.ts +1163 -88
- package/src/Player/SkillManager.ts +520 -195
- package/src/Player/StateManager.ts +170 -182
- package/src/Player/VariableManager.ts +101 -63
- package/src/RpgServer.ts +525 -63
- package/src/core/context.ts +1 -0
- package/src/decorators/event.ts +61 -0
- package/src/decorators/map.ts +327 -0
- package/src/index.ts +11 -1
- package/src/logs/log.ts +10 -3
- package/src/module.ts +126 -3
- package/src/presets/index.ts +1 -10
- package/src/rooms/BaseRoom.ts +232 -0
- package/src/rooms/lobby.ts +25 -7
- package/src/rooms/map.ts +2502 -194
- package/src/services/save.ts +147 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/localStorage.ts +76 -0
- package/tests/battle.spec.ts +375 -0
- package/tests/change-map.spec.ts +72 -0
- package/tests/class.spec.ts +274 -0
- package/tests/effect.spec.ts +219 -0
- package/tests/element.spec.ts +221 -0
- package/tests/event.spec.ts +80 -0
- package/tests/gold.spec.ts +99 -0
- package/tests/item.spec.ts +609 -0
- package/tests/module.spec.ts +38 -0
- package/tests/move.spec.ts +601 -0
- package/tests/player-param.spec.ts +28 -0
- package/tests/prediction-reconciliation.spec.ts +182 -0
- package/tests/random-move.spec.ts +65 -0
- package/tests/skill.spec.ts +658 -0
- package/tests/state.spec.ts +467 -0
- package/tests/variable.spec.ts +185 -0
- package/tests/world-maps.spec.ts +896 -0
- package/vite.config.ts +16 -0
- package/dist/Player/Event.d.ts +0 -0
- package/src/Player/Event.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isInstanceOf, isString, type Constructor } from "@rpgjs/common";
|
|
1
|
+
import { isInstanceOf, isString, PlayerCtor, type Constructor } from "@rpgjs/common";
|
|
2
2
|
import { RpgCommonPlayer, Matter, SeekAvoid } from "@rpgjs/common";
|
|
3
3
|
import { signal, type WritableArraySignal } from "@signe/reactive";
|
|
4
4
|
import { ATK, PDEF, SDEF } from "../presets";
|
|
@@ -13,111 +13,112 @@ interface StateManagerDependencies {
|
|
|
13
13
|
removeState(stateClass: StateClass | string, chance?: number): void;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
* Interface defining what MoveManager adds to a class
|
|
18
|
-
*/
|
|
19
|
-
export interface IStateManager {
|
|
20
|
-
statesDefense: { rate: number; state: any }[];
|
|
21
|
-
statesEfficiency: WritableArraySignal<any[]>;
|
|
22
|
-
applyStates(
|
|
23
|
-
player: RpgPlayer,
|
|
24
|
-
states: { addStates?: any[]; removeStates?: any[] }
|
|
25
|
-
): void;
|
|
26
|
-
getState(stateClass: StateClass | string): any;
|
|
27
|
-
addState(stateClass: StateClass | string, chance?: number): object | null;
|
|
28
|
-
removeState(stateClass: StateClass | string, chance?: number): void;
|
|
29
|
-
}
|
|
16
|
+
|
|
30
17
|
|
|
31
18
|
type StateClass = { new (...args: any[]) };
|
|
32
19
|
|
|
33
20
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
21
|
+
* State Manager Mixin
|
|
22
|
+
*
|
|
23
|
+
* Provides state management capabilities to any class. This mixin handles
|
|
24
|
+
* player states (buffs/debuffs), state defense from equipment, and state
|
|
25
|
+
* efficiency modifiers. It manages the complete state system including
|
|
26
|
+
* application, removal, and resistance mechanics.
|
|
27
|
+
*
|
|
28
|
+
* @param Base - The base class to extend with state management
|
|
29
|
+
* @returns Extended class with state management methods
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* class MyPlayer extends WithStateManager(BasePlayer) {
|
|
34
|
+
* constructor() {
|
|
35
|
+
* super();
|
|
36
|
+
* // State system is automatically initialized
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* const player = new MyPlayer();
|
|
41
|
+
* player.addState(Paralyze);
|
|
42
|
+
* console.log(player.getState(Paralyze));
|
|
43
|
+
* ```
|
|
40
44
|
*/
|
|
41
|
-
export function WithStateManager<
|
|
42
|
-
|
|
43
|
-
>(Base: TBase): Constructor<IStateManager> & TBase {
|
|
44
|
-
return class extends Base implements IStateManager {
|
|
45
|
+
export function WithStateManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
46
|
+
return class extends Base {
|
|
45
47
|
_statesEfficiency = signal<any[]>([]);
|
|
46
48
|
|
|
49
|
+
private _getStateMap(required: boolean = true) {
|
|
50
|
+
// Use this.map directly to support both RpgMap and LobbyRoom
|
|
51
|
+
const map = (this as any).getCurrentMap?.() || (this as any).map;
|
|
52
|
+
if (required && (!map || !map.database)) {
|
|
53
|
+
throw new Error('Player must be on a map to resolve states');
|
|
54
|
+
}
|
|
55
|
+
return map;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private _resolveStateInput(
|
|
59
|
+
stateInput: StateClass | string,
|
|
60
|
+
databaseByIdOverride?: (id: string) => any
|
|
61
|
+
) {
|
|
62
|
+
if (isString(stateInput)) {
|
|
63
|
+
return databaseByIdOverride
|
|
64
|
+
? databaseByIdOverride(stateInput)
|
|
65
|
+
: (this as any).databaseById(stateInput);
|
|
66
|
+
}
|
|
67
|
+
return stateInput;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private _createStateInstance(stateClass: StateClass) {
|
|
71
|
+
return new (stateClass as StateClass)();
|
|
72
|
+
}
|
|
73
|
+
|
|
47
74
|
/**
|
|
48
|
-
*
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
* @State({
|
|
55
|
-
* name: 'Paralyze'
|
|
56
|
-
* })
|
|
57
|
-
* class Paralyze {}
|
|
58
|
-
*
|
|
59
|
-
* @Armor({
|
|
60
|
-
* name: 'Shield',
|
|
61
|
-
* statesDefense: [{ rate: 1, state: Paralyze }]
|
|
62
|
-
* })
|
|
63
|
-
* class Shield {}
|
|
64
|
-
*
|
|
65
|
-
* @Armor({
|
|
66
|
-
* name: 'FireShield',
|
|
67
|
-
* statesDefense: [{ rate: 0.5, state: Paralyze }]
|
|
68
|
-
* })
|
|
69
|
-
* class FireShield {}
|
|
70
|
-
*
|
|
71
|
-
* player.addItem(Shield)
|
|
72
|
-
* player.addItem(FireShield)
|
|
73
|
-
* player.equip(Shield)
|
|
74
|
-
* player.equip(FireShield)
|
|
75
|
-
*
|
|
76
|
-
* console.log(player.statesDefense) // [{ rate: 1, state: instance of Paralyze }]
|
|
77
|
-
* ```
|
|
78
|
-
* @title Get States Defense
|
|
79
|
-
* @prop {Array<{ rate: number, state: StateClass}>} player.statesDefense
|
|
80
|
-
* @readonly
|
|
81
|
-
* @memberof StateManager
|
|
82
|
-
* */
|
|
83
|
-
get statesDefense(): { rate: number; state: any }[] {
|
|
84
|
-
return this.getFeature("statesDefense", "state");
|
|
75
|
+
* Create a state instance without side effects.
|
|
76
|
+
*/
|
|
77
|
+
createStateInstance(stateInput: StateClass | string) {
|
|
78
|
+
const stateClass = this._resolveStateInput(stateInput);
|
|
79
|
+
const instance = this._createStateInstance(stateClass as StateClass);
|
|
80
|
+
return { stateClass, instance };
|
|
85
81
|
}
|
|
86
82
|
|
|
87
83
|
/**
|
|
88
|
-
*
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
84
|
+
* Resolve state snapshot entries into state instances without side effects.
|
|
85
|
+
*/
|
|
86
|
+
resolveStatesSnapshot(snapshot: { states?: any[] }, mapOverride?: any) {
|
|
87
|
+
if (!snapshot || !Array.isArray(snapshot.states)) {
|
|
88
|
+
return snapshot;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const map = mapOverride ?? this._getStateMap(false);
|
|
92
|
+
if (!map || !map.database) {
|
|
93
|
+
return snapshot;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const databaseByIdOverride = (id: string) => {
|
|
97
|
+
const data = map.database()[id];
|
|
98
|
+
if (!data) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`The ID=${id} data is not found in the database. Add the data in the property "database"`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return data;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const states = snapshot.states.map((entry: any) => {
|
|
107
|
+
const stateId = isString(entry) ? entry : entry?.id;
|
|
108
|
+
if (!stateId) {
|
|
109
|
+
return entry;
|
|
110
|
+
}
|
|
111
|
+
const stateClass = this._resolveStateInput(stateId, databaseByIdOverride);
|
|
112
|
+
return this._createStateInstance(stateClass as StateClass);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return { ...snapshot, states };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get statesDefense(): { rate: number; state: any }[] {
|
|
119
|
+
return (this as any).getFeature("statesDefense", "state");
|
|
120
|
+
}
|
|
121
|
+
|
|
121
122
|
get statesEfficiency() {
|
|
122
123
|
return this._statesEfficiency;
|
|
123
124
|
}
|
|
@@ -127,37 +128,23 @@ export function WithStateManager<
|
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
applyStates(
|
|
130
|
-
player: RpgPlayer
|
|
131
|
+
player: RpgPlayer,
|
|
131
132
|
{ addStates, removeStates }
|
|
132
133
|
) {
|
|
133
134
|
if (addStates) {
|
|
134
135
|
for (let { state, rate } of addStates) {
|
|
135
|
-
player.addState(state, rate);
|
|
136
|
+
(player as any).addState(state, rate);
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
139
|
if (removeStates) {
|
|
139
140
|
for (let { state, rate } of removeStates) {
|
|
140
|
-
player.removeState(state, rate);
|
|
141
|
+
(player as any).removeState(state, rate);
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
/**
|
|
146
|
-
* Get a state to the player. Returns `null` if the state is not present on the player
|
|
147
|
-
* ```ts
|
|
148
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
149
|
-
*
|
|
150
|
-
* player.getState(Paralyze)
|
|
151
|
-
* ```
|
|
152
|
-
*
|
|
153
|
-
* @title Get State
|
|
154
|
-
* @method player.getState(stateClass)
|
|
155
|
-
* @param {StateClass | string} stateClass or state id
|
|
156
|
-
* @returns {instance of StateClass | null}
|
|
157
|
-
* @memberof StateManager
|
|
158
|
-
*/
|
|
159
146
|
getState(stateClass: StateClass | string) {
|
|
160
|
-
if (isString(stateClass)) stateClass = this.databaseById(stateClass);
|
|
147
|
+
if (isString(stateClass)) stateClass = (this as any).databaseById(stateClass);
|
|
161
148
|
return this.states().find((state) => {
|
|
162
149
|
if (isString(stateClass)) {
|
|
163
150
|
return state.id == stateClass;
|
|
@@ -166,46 +153,17 @@ export function WithStateManager<
|
|
|
166
153
|
});
|
|
167
154
|
}
|
|
168
155
|
|
|
169
|
-
/**
|
|
170
|
-
* Adds a state to the player. Set the chance between 0 and 1 that the state can apply
|
|
171
|
-
* ```ts
|
|
172
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
173
|
-
*
|
|
174
|
-
* try {
|
|
175
|
-
* player.addState(Paralyze)
|
|
176
|
-
* }
|
|
177
|
-
* catch (err) {
|
|
178
|
-
* console.log(err)
|
|
179
|
-
* }
|
|
180
|
-
* ```
|
|
181
|
-
*
|
|
182
|
-
* @title Add State
|
|
183
|
-
* @method player.addState(stateClass,chance=1)
|
|
184
|
-
* @param {StateClass | string} stateClass state class or state id
|
|
185
|
-
* @param {number} [chance] 1 by default
|
|
186
|
-
* @throws {StateLog} addFailed
|
|
187
|
-
* If the chance to add the state has failed (defined with the `chance` param)
|
|
188
|
-
* ```
|
|
189
|
-
* {
|
|
190
|
-
* id: ADD_STATE_FAILED,
|
|
191
|
-
* msg: '...'
|
|
192
|
-
* }
|
|
193
|
-
* ```
|
|
194
|
-
* @returns {instance of StateClass}
|
|
195
|
-
* @memberof StateManager
|
|
196
|
-
* @todo
|
|
197
|
-
*/
|
|
198
156
|
addState(stateClass: StateClass | string, chance = 1): object | null {
|
|
199
157
|
const state = this.getState(stateClass);
|
|
200
158
|
if (isString(stateClass)) {
|
|
201
|
-
stateClass = this.databaseById(stateClass);
|
|
159
|
+
stateClass = (this as any).databaseById(stateClass);
|
|
202
160
|
}
|
|
203
161
|
if (!state) {
|
|
204
162
|
if (Math.random() > chance) {
|
|
205
163
|
throw StateLog.addFailed(stateClass);
|
|
206
164
|
}
|
|
207
165
|
//const efficiency = this.findStateEfficiency(stateClass)
|
|
208
|
-
const instance =
|
|
166
|
+
const instance = this._createStateInstance(stateClass as StateClass);
|
|
209
167
|
this.states().push(instance);
|
|
210
168
|
this.applyStates(<any>this, instance);
|
|
211
169
|
return instance;
|
|
@@ -213,42 +171,6 @@ export function WithStateManager<
|
|
|
213
171
|
return null;
|
|
214
172
|
}
|
|
215
173
|
|
|
216
|
-
/**
|
|
217
|
-
* Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
|
|
218
|
-
* ```ts
|
|
219
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
220
|
-
*
|
|
221
|
-
* try {
|
|
222
|
-
* player.removeState(Paralyze)
|
|
223
|
-
* }
|
|
224
|
-
* catch (err) {
|
|
225
|
-
* console.log(err)
|
|
226
|
-
* }
|
|
227
|
-
* ```
|
|
228
|
-
*
|
|
229
|
-
* @title Remove State
|
|
230
|
-
* @method player.removeState(stateClass,chance=1)
|
|
231
|
-
* @param {StateClass|string} stateClass class state or state id
|
|
232
|
-
* @param {number} [chance] 1 by default
|
|
233
|
-
* @throws {StateLog} removeFailed
|
|
234
|
-
* If the chance to remove the state has failed (defined with the `chance` param)
|
|
235
|
-
* ```
|
|
236
|
-
* {
|
|
237
|
-
* id: REMOVE_STATE_FAILED,
|
|
238
|
-
* msg: '...'
|
|
239
|
-
* }
|
|
240
|
-
* ```
|
|
241
|
-
* @throws {StateLog} notApplied
|
|
242
|
-
* If the status does not exist
|
|
243
|
-
* ```
|
|
244
|
-
* {
|
|
245
|
-
* id: STATE_NOT_APPLIED,
|
|
246
|
-
* msg: '...'
|
|
247
|
-
* }
|
|
248
|
-
* ```
|
|
249
|
-
* @returns {instance of StateClass}
|
|
250
|
-
* @memberof StateManager
|
|
251
|
-
*/
|
|
252
174
|
removeState(stateClass: StateClass | string, chance = 1) {
|
|
253
175
|
const index = this.states().findIndex((state) => {
|
|
254
176
|
if (isString(stateClass)) {
|
|
@@ -266,10 +188,76 @@ export function WithStateManager<
|
|
|
266
188
|
}
|
|
267
189
|
}
|
|
268
190
|
|
|
269
|
-
|
|
191
|
+
findStateEfficiency(stateClass) {
|
|
270
192
|
return this.statesEfficiency().find((state) =>
|
|
271
193
|
isInstanceOf(state.state, stateClass)
|
|
272
194
|
);
|
|
273
195
|
}
|
|
274
|
-
};
|
|
196
|
+
} as unknown as TBase;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Interface for State Manager functionality
|
|
201
|
+
*
|
|
202
|
+
* Provides state management capabilities including state defense, efficiency modifiers,
|
|
203
|
+
* and state application/removal. This interface defines the public API of the StateManager mixin.
|
|
204
|
+
*/
|
|
205
|
+
export interface IStateManager {
|
|
206
|
+
/**
|
|
207
|
+
* Gets the defensive capabilities against various states from equipped items
|
|
208
|
+
*
|
|
209
|
+
* @returns Array of state defense objects with rate and state properties
|
|
210
|
+
*/
|
|
211
|
+
statesDefense: { rate: number; state: any }[];
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Manages the player's state efficiency modifiers
|
|
215
|
+
*
|
|
216
|
+
* @returns Signal containing array of state efficiency objects
|
|
217
|
+
*/
|
|
218
|
+
statesEfficiency: any;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Apply states to a player from skill or item effects
|
|
222
|
+
*
|
|
223
|
+
* @param player - The target player to apply states to
|
|
224
|
+
* @param states - Object containing arrays of states to add or remove
|
|
225
|
+
*/
|
|
226
|
+
applyStates(player: RpgPlayer, states: { addStates?: Array<{ state: any; rate: number }>; removeStates?: Array<{ state: any; rate: number }> }): void;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get a state to the player. Returns null if the state is not present
|
|
230
|
+
*
|
|
231
|
+
* @param stateClass - The state class constructor or state ID to search for
|
|
232
|
+
* @returns The state instance if found, null otherwise
|
|
233
|
+
*/
|
|
234
|
+
getState(stateClass: StateClass | string): any | null;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Adds a state to the player
|
|
238
|
+
*
|
|
239
|
+
* @param stateClass - The state class constructor or state ID to apply
|
|
240
|
+
* @param chance - Probability of successful application (0-1, default 1)
|
|
241
|
+
* @returns The state instance if successfully applied, null if already present
|
|
242
|
+
* @throws StateLog.addFailed if the chance roll fails
|
|
243
|
+
*/
|
|
244
|
+
addState(stateClass: StateClass | string, chance?: number): object | null;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Remove a state to the player
|
|
248
|
+
*
|
|
249
|
+
* @param stateClass - The state class constructor or state ID to remove
|
|
250
|
+
* @param chance - Probability of successful removal (0-1, default 1)
|
|
251
|
+
* @throws StateLog.removeFailed if the chance roll fails
|
|
252
|
+
* @throws StateLog.notApplied if the state is not currently active
|
|
253
|
+
*/
|
|
254
|
+
removeState(stateClass: StateClass | string, chance?: number): void;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Find state efficiency modifier for a specific state class
|
|
258
|
+
*
|
|
259
|
+
* @param stateClass - The state class to find efficiency for
|
|
260
|
+
* @returns The efficiency object if found, undefined otherwise
|
|
261
|
+
*/
|
|
262
|
+
findStateEfficiency(stateClass: any): any | undefined;
|
|
275
263
|
}
|
|
@@ -1,75 +1,113 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Constructor, PlayerCtor } from "@rpgjs/common";
|
|
2
|
+
import { signal } from "@signe/reactive";
|
|
3
|
+
import { type } from "@signe/sync";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
6
|
+
* Variable Manager Mixin
|
|
7
|
+
*
|
|
8
|
+
* Provides variable management capabilities to any class. Variables are key-value
|
|
9
|
+
* pairs that can store any type of data associated with the player, such as
|
|
10
|
+
* quest progress, game flags, inventory state, and custom game data.
|
|
11
|
+
*
|
|
12
|
+
* @param Base - The base class to extend with variable management
|
|
13
|
+
* @returns Extended class with variable management methods
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* class MyPlayer extends WithVariableManager(BasePlayer) {
|
|
18
|
+
* constructor() {
|
|
19
|
+
* super();
|
|
20
|
+
* // Variables are automatically initialized
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
15
23
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
24
|
+
* const player = new MyPlayer();
|
|
25
|
+
* player.setVariable('questCompleted', true);
|
|
26
|
+
* ```
|
|
18
27
|
*/
|
|
19
|
-
export function WithVariableManager<TBase extends
|
|
20
|
-
return class extends Base
|
|
21
|
-
variables
|
|
28
|
+
export function WithVariableManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
29
|
+
return class extends Base {
|
|
30
|
+
variables = type(signal<Record<string, any>>({}) as any, 'variables', { persist: true }, this as any);
|
|
31
|
+
|
|
32
|
+
setVariable(key: string, val: any): void {
|
|
33
|
+
this.variables()[key] = val;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getVariable<U = any>(key: string): U | undefined {
|
|
37
|
+
return this.variables()[key];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
removeVariable(key: string): boolean {
|
|
41
|
+
delete this.variables()[key];
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
* ```ts
|
|
27
|
-
* player.setVariable('OPEN_CHEST', true)
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @title Set variable
|
|
31
|
-
* @method player.setVariable(key,val)
|
|
32
|
-
* @param {string} key
|
|
33
|
-
* @param {any} val
|
|
34
|
-
* @returns {void}
|
|
35
|
-
* @memberof VariableManager
|
|
36
|
-
* */
|
|
37
|
-
setVariable(key: string, val) {
|
|
38
|
-
this.variables.set(key, val)
|
|
45
|
+
hasVariable(key: string): boolean {
|
|
46
|
+
return key in this.variables();
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
* ```ts
|
|
45
|
-
* const val = player.getVariable('OPEN_CHEST')
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @title Get variable
|
|
49
|
-
* @method player.setVariable(key,val)
|
|
50
|
-
* @param {string} key
|
|
51
|
-
* @returns {any}
|
|
52
|
-
* @memberof VariableManager
|
|
53
|
-
* */
|
|
54
|
-
getVariable(key: string) {
|
|
55
|
-
return this.variables.get(key)
|
|
49
|
+
getVariableKeys(): string[] {
|
|
50
|
+
return Object.keys(this.variables());
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
*
|
|
61
|
-
* ```ts
|
|
62
|
-
* player.removeVariable('OPEN_CHEST')
|
|
63
|
-
* ```
|
|
64
|
-
*
|
|
65
|
-
* @title Remove variable
|
|
66
|
-
* @method player.removeVariable(key)
|
|
67
|
-
* @param {string} key
|
|
68
|
-
* @returns {boolean} true if a variable existed and has been removed, or false if the variable does not exist.
|
|
69
|
-
* @memberof VariableManager
|
|
70
|
-
* */
|
|
71
|
-
removeVariable(key: string) {
|
|
72
|
-
return this.variables.delete(key)
|
|
53
|
+
clearVariables(): void {
|
|
54
|
+
this.variables.set({});
|
|
73
55
|
}
|
|
74
|
-
};
|
|
56
|
+
} as unknown as TBase;
|
|
75
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Interface for Variable Manager functionality
|
|
61
|
+
*
|
|
62
|
+
* Provides variable management capabilities including storing, retrieving, and managing
|
|
63
|
+
* key-value pairs for player-specific data. This interface defines the public API
|
|
64
|
+
* of the VariableManager mixin.
|
|
65
|
+
*/
|
|
66
|
+
export interface IVariableManager {
|
|
67
|
+
/** Map storing all player variables */
|
|
68
|
+
variables: Map<string, any>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Assign a variable to the player
|
|
72
|
+
*
|
|
73
|
+
* @param key - The variable identifier
|
|
74
|
+
* @param val - The value to store
|
|
75
|
+
*/
|
|
76
|
+
setVariable(key: string, val: any): void;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get a variable value
|
|
80
|
+
*
|
|
81
|
+
* @param key - The variable identifier to retrieve
|
|
82
|
+
* @returns The stored value or undefined if not found
|
|
83
|
+
*/
|
|
84
|
+
getVariable<U = any>(key: string): U | undefined;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Remove a variable
|
|
88
|
+
*
|
|
89
|
+
* @param key - The variable identifier to remove
|
|
90
|
+
* @returns true if a variable existed and has been removed, false otherwise
|
|
91
|
+
*/
|
|
92
|
+
removeVariable(key: string): boolean;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Check if a variable exists
|
|
96
|
+
*
|
|
97
|
+
* @param key - The variable identifier to check
|
|
98
|
+
* @returns true if the variable exists, false otherwise
|
|
99
|
+
*/
|
|
100
|
+
hasVariable(key: string): boolean;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get all variable keys
|
|
104
|
+
*
|
|
105
|
+
* @returns Array of all variable keys
|
|
106
|
+
*/
|
|
107
|
+
getVariableKeys(): string[];
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Clear all variables
|
|
111
|
+
*/
|
|
112
|
+
clearVariables(): void;
|
|
113
|
+
}
|