@rpgjs/server 5.0.0-alpha.1 → 5.0.0-alpha.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/dist/Player/BattleManager.d.ts +32 -22
- package/dist/Player/ClassManager.d.ts +31 -18
- package/dist/Player/ComponentManager.d.ts +60 -0
- package/dist/Player/EffectManager.d.ts +40 -0
- package/dist/Player/ElementManager.d.ts +31 -0
- package/dist/Player/GoldManager.d.ts +22 -0
- package/dist/Player/GuiManager.d.ts +176 -0
- package/dist/Player/ItemFixture.d.ts +6 -0
- package/dist/Player/ItemManager.d.ts +27 -13
- package/dist/Player/MoveManager.d.ts +31 -43
- package/dist/Player/ParameterManager.d.ts +27 -19
- package/dist/Player/Player.d.ts +123 -8
- package/dist/Player/SkillManager.d.ts +27 -19
- package/dist/Player/StateManager.d.ts +28 -35
- package/dist/Player/VariableManager.d.ts +30 -0
- package/dist/RpgServer.d.ts +224 -1
- package/dist/index.js +1097 -636
- package/dist/index.js.map +1 -1
- package/dist/rooms/map.d.ts +70 -1
- package/package.json +8 -8
- package/src/Player/BattleManager.ts +97 -38
- package/src/Player/ClassManager.ts +95 -35
- package/src/Player/ComponentManager.ts +64 -20
- package/src/Player/EffectManager.ts +110 -27
- package/src/Player/ElementManager.ts +126 -25
- package/src/Player/GoldManager.ts +32 -35
- package/src/Player/GuiManager.ts +187 -140
- package/src/Player/ItemFixture.ts +4 -5
- package/src/Player/ItemManager.ts +39 -26
- package/src/Player/MoveManager.ts +40 -31
- package/src/Player/ParameterManager.ts +35 -25
- package/src/Player/Player.ts +184 -39
- package/src/Player/SkillManager.ts +44 -23
- package/src/Player/StateManager.ts +210 -95
- package/src/Player/VariableManager.ts +180 -48
- package/src/RpgServer.ts +232 -1
- package/src/core/context.ts +1 -0
- package/src/rooms/map.ts +76 -8
- package/dist/Player/Event.d.ts +0 -0
- package/src/Player/Event.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -26158,7 +26158,7 @@ function WithMoveManager(Base) {
|
|
|
26158
26158
|
return class extends Base {
|
|
26159
26159
|
constructor() {
|
|
26160
26160
|
super(...arguments);
|
|
26161
|
-
//
|
|
26161
|
+
// Properties for infinite route management
|
|
26162
26162
|
this._infiniteRoutes = null;
|
|
26163
26163
|
this._finishRoute = null;
|
|
26164
26164
|
this._isInfiniteRouteActive = false;
|
|
@@ -26962,123 +26962,16 @@ class NotificationGui extends Gui {
|
|
|
26962
26962
|
}
|
|
26963
26963
|
|
|
26964
26964
|
function WithGuiManager(Base) {
|
|
26965
|
-
|
|
26965
|
+
class GuiManagerMixin extends Base {
|
|
26966
26966
|
constructor() {
|
|
26967
26967
|
super(...arguments);
|
|
26968
26968
|
this._gui = {};
|
|
26969
26969
|
}
|
|
26970
|
-
/**
|
|
26971
|
-
* Show a text. This is a graphical interface already built. Opens the GUI named `rpg-dialog`
|
|
26972
|
-
*
|
|
26973
|
-
* ```ts
|
|
26974
|
-
* player.showText('Hello World')
|
|
26975
|
-
* ```
|
|
26976
|
-
*
|
|
26977
|
-
* The method returns a promise. It is resolved when the dialog box is closed.
|
|
26978
|
-
*
|
|
26979
|
-
* ```ts
|
|
26980
|
-
* await player.showText('Hello World')
|
|
26981
|
-
* // dialog box is closed, then ...
|
|
26982
|
-
* ```
|
|
26983
|
-
*
|
|
26984
|
-
* **Option: position**
|
|
26985
|
-
*
|
|
26986
|
-
* You can define how the dialog box is displayed:
|
|
26987
|
-
* - top
|
|
26988
|
-
* - middle
|
|
26989
|
-
* - bottom
|
|
26990
|
-
*
|
|
26991
|
-
* (bottom by default)
|
|
26992
|
-
*
|
|
26993
|
-
* ```ts
|
|
26994
|
-
* player.showText('Hello World', {
|
|
26995
|
-
* position: 'top'
|
|
26996
|
-
* })
|
|
26997
|
-
* ```
|
|
26998
|
-
*
|
|
26999
|
-
* **Option: fullWidth**
|
|
27000
|
-
*
|
|
27001
|
-
* `boolean` (true by default)
|
|
27002
|
-
*
|
|
27003
|
-
* Indicate that the dialog box will take the full width of the screen.
|
|
27004
|
-
*
|
|
27005
|
-
* ```ts
|
|
27006
|
-
* player.showText('Hello World', {
|
|
27007
|
-
* fullWidth: true
|
|
27008
|
-
* })
|
|
27009
|
-
* ```
|
|
27010
|
-
*
|
|
27011
|
-
* **Option: autoClose**
|
|
27012
|
-
*
|
|
27013
|
-
* `boolean` (false by default)
|
|
27014
|
-
*
|
|
27015
|
-
* If false, the user will have to press Enter to close the dialog box.
|
|
27016
|
-
*
|
|
27017
|
-
* ```ts
|
|
27018
|
-
* player.showText('Hello World', {
|
|
27019
|
-
* autoClose: true
|
|
27020
|
-
* })
|
|
27021
|
-
* ```
|
|
27022
|
-
*
|
|
27023
|
-
* **Option: typewriterEffect**
|
|
27024
|
-
*
|
|
27025
|
-
* `boolean` (true by default)
|
|
27026
|
-
*
|
|
27027
|
-
* Performs a typewriter effect
|
|
27028
|
-
*
|
|
27029
|
-
* ```ts
|
|
27030
|
-
* player.showText('Hello World', {
|
|
27031
|
-
* typewriterEffect: false
|
|
27032
|
-
* })
|
|
27033
|
-
* ```
|
|
27034
|
-
*
|
|
27035
|
-
* **Option: talkWith**
|
|
27036
|
-
*
|
|
27037
|
-
* `RpgPlayer` (nothing by default)
|
|
27038
|
-
*
|
|
27039
|
-
* If you specify the event or another player, the other player will stop his or her movement and look in the player's direction.
|
|
27040
|
-
*
|
|
27041
|
-
* ```ts
|
|
27042
|
-
* // Code in an event
|
|
27043
|
-
* player.showText('Hello World', {
|
|
27044
|
-
* talkWith: this
|
|
27045
|
-
* })
|
|
27046
|
-
* ```
|
|
27047
|
-
*
|
|
27048
|
-
* @title Show Text
|
|
27049
|
-
* @method player.showText(text,options)
|
|
27050
|
-
* @param {string} text
|
|
27051
|
-
* @param {object} [options] the different options, see usage below
|
|
27052
|
-
* @returns {Promise}
|
|
27053
|
-
* @memberof GuiManager
|
|
27054
|
-
*/
|
|
27055
26970
|
showText(msg, options = {}) {
|
|
27056
26971
|
const gui = new DialogGui(this);
|
|
27057
26972
|
this._gui[gui.id] = gui;
|
|
27058
26973
|
return gui.openDialog(msg, options);
|
|
27059
26974
|
}
|
|
27060
|
-
/**
|
|
27061
|
-
* Shows a dialog box with a choice. Opens the GUI named `rpg-dialog`
|
|
27062
|
-
*
|
|
27063
|
-
* ```ts
|
|
27064
|
-
* const choice = await player.showChoices('What color do you prefer?', [
|
|
27065
|
-
* { text: 'Black', value: 'black' },
|
|
27066
|
-
* { text: 'Rather the blue', value: 'blue' },
|
|
27067
|
-
* { text: 'I don\'t have a preference!', value: 'none' }
|
|
27068
|
-
* ])
|
|
27069
|
-
*
|
|
27070
|
-
* // If the player selects the first
|
|
27071
|
-
* console.log(choice) // { text: 'Black', value: 'black' }
|
|
27072
|
-
* ```
|
|
27073
|
-
*
|
|
27074
|
-
* @title Show Choices
|
|
27075
|
-
* @method player.showChoices(text,choices)
|
|
27076
|
-
* @param {string} text
|
|
27077
|
-
* @param {Array<{ text: string, value: any }>} choices
|
|
27078
|
-
* @param {object} [options] Same options as the openDialog method
|
|
27079
|
-
* @returns {Promise<Choice | null>}
|
|
27080
|
-
* @memberof GuiManager
|
|
27081
|
-
*/
|
|
27082
26975
|
showChoices(msg, choices, options) {
|
|
27083
26976
|
return this.showText(msg, {
|
|
27084
26977
|
choices,
|
|
@@ -27088,19 +26981,6 @@ function WithGuiManager(Base) {
|
|
|
27088
26981
|
return choices[indexSelected];
|
|
27089
26982
|
});
|
|
27090
26983
|
}
|
|
27091
|
-
/**
|
|
27092
|
-
* Displays a notification . Opens the GUI named `rpg-notification`
|
|
27093
|
-
*
|
|
27094
|
-
* @title Displays a notification
|
|
27095
|
-
* @method player.showNotification()
|
|
27096
|
-
* @param {string} message - The message to display in the notification
|
|
27097
|
-
* @param {object} options - An object containing options for the notification
|
|
27098
|
-
* @param {number} options.time - The time to display the notification for (in ms). Default: 2000ms
|
|
27099
|
-
* @param {string} options.icon - The icon to display in the notification. Put the identifier of the spritesheet (defined on the client side)
|
|
27100
|
-
* @param {string} options.sound - The sound to play when the notification is shown. Set the sound ID (defined on the client side)
|
|
27101
|
-
* @returns {void}
|
|
27102
|
-
* @memberof GuiManager
|
|
27103
|
-
*/
|
|
27104
26984
|
showNotification(message, options = {}) {
|
|
27105
26985
|
const gui = new NotificationGui(this);
|
|
27106
26986
|
this._gui[gui.id] = gui;
|
|
@@ -27110,14 +26990,6 @@ function WithGuiManager(Base) {
|
|
|
27110
26990
|
};
|
|
27111
26991
|
return gui.open(data);
|
|
27112
26992
|
}
|
|
27113
|
-
/**
|
|
27114
|
-
* Calls main menu. Opens the GUI named `rpg-main-menu`
|
|
27115
|
-
*
|
|
27116
|
-
* @title Call Main Menu
|
|
27117
|
-
* @method player.callMainMenu()
|
|
27118
|
-
* @returns {void}
|
|
27119
|
-
* @memberof GuiManager
|
|
27120
|
-
*/
|
|
27121
26993
|
callMainMenu() {
|
|
27122
26994
|
const gui = new MenuGui(this);
|
|
27123
26995
|
this._gui[gui.id] = gui;
|
|
@@ -27250,23 +27122,12 @@ function WithGuiManager(Base) {
|
|
|
27250
27122
|
const _players = players || this;
|
|
27251
27123
|
this._attachedGui(_players, false);
|
|
27252
27124
|
}
|
|
27253
|
-
}
|
|
27125
|
+
}
|
|
27126
|
+
return GuiManagerMixin;
|
|
27254
27127
|
}
|
|
27255
27128
|
|
|
27256
27129
|
function WithGoldManager(Base) {
|
|
27257
27130
|
return class extends Base {
|
|
27258
|
-
/**
|
|
27259
|
-
* You can change the game money
|
|
27260
|
-
*
|
|
27261
|
-
* ```ts
|
|
27262
|
-
* player.gold += 100
|
|
27263
|
-
* ```
|
|
27264
|
-
*
|
|
27265
|
-
* @title Change Gold
|
|
27266
|
-
* @prop {number} player.gold
|
|
27267
|
-
* @default 0
|
|
27268
|
-
* @memberof GoldManager
|
|
27269
|
-
* */
|
|
27270
27131
|
set gold(val) {
|
|
27271
27132
|
if (val < 0) {
|
|
27272
27133
|
val = 0;
|
|
@@ -27288,52 +27149,168 @@ function WithVariableManager(Base) {
|
|
|
27288
27149
|
/**
|
|
27289
27150
|
* Assign a variable to the player
|
|
27290
27151
|
*
|
|
27152
|
+
* Stores a key-value pair in the player's variable map. This is useful for
|
|
27153
|
+
* tracking game state, quest progress, flags, and other player-specific data.
|
|
27154
|
+
* The variable system provides a flexible way to store any type of data
|
|
27155
|
+
* associated with the player that persists throughout the game session.
|
|
27156
|
+
*
|
|
27157
|
+
* @param key - The variable identifier (string key to reference the variable)
|
|
27158
|
+
* @param val - The value to store (can be any type: boolean, number, string, object, array)
|
|
27159
|
+
* @returns void
|
|
27160
|
+
*
|
|
27161
|
+
* @example
|
|
27291
27162
|
* ```ts
|
|
27292
|
-
*
|
|
27163
|
+
* // Set different types of variables
|
|
27164
|
+
* player.setVariable('CHEST_OPENED', true);
|
|
27165
|
+
* player.setVariable('playerLevel', 5);
|
|
27166
|
+
* player.setVariable('questProgress', { step: 1, completed: false });
|
|
27167
|
+
* player.setVariable('inventory', ['sword', 'potion', 'key']);
|
|
27168
|
+
* player.setVariable('lastSaveTime', new Date().toISOString());
|
|
27293
27169
|
* ```
|
|
27294
|
-
|
|
27295
|
-
* @title Set variable
|
|
27296
|
-
* @method player.setVariable(key,val)
|
|
27297
|
-
* @param {string} key
|
|
27298
|
-
* @param {any} val
|
|
27299
|
-
* @returns {void}
|
|
27300
|
-
* @memberof VariableManager
|
|
27301
|
-
* */
|
|
27170
|
+
*/
|
|
27302
27171
|
setVariable(key, val) {
|
|
27303
27172
|
this.variables.set(key, val);
|
|
27304
27173
|
}
|
|
27305
27174
|
/**
|
|
27306
|
-
* Get a variable
|
|
27175
|
+
* Get a variable value
|
|
27176
|
+
*
|
|
27177
|
+
* Retrieves the value associated with the given key from the player's variables.
|
|
27178
|
+
* Returns undefined if the variable doesn't exist. This method is type-safe
|
|
27179
|
+
* and can be used with generic types for better TypeScript support.
|
|
27180
|
+
*
|
|
27181
|
+
* @param key - The variable identifier to retrieve
|
|
27182
|
+
* @returns The stored value or undefined if not found
|
|
27307
27183
|
*
|
|
27184
|
+
* @example
|
|
27308
27185
|
* ```ts
|
|
27309
|
-
*
|
|
27310
|
-
*
|
|
27186
|
+
* // Get variables with type inference
|
|
27187
|
+
* const hasKey = player.getVariable('CHEST_OPENED'); // boolean | undefined
|
|
27188
|
+
* const level = player.getVariable('playerLevel'); // number | undefined
|
|
27189
|
+
* const quest = player.getVariable('questProgress'); // object | undefined
|
|
27190
|
+
* const missing = player.getVariable('nonexistent'); // undefined
|
|
27311
27191
|
*
|
|
27312
|
-
*
|
|
27313
|
-
*
|
|
27314
|
-
*
|
|
27315
|
-
*
|
|
27316
|
-
|
|
27317
|
-
* */
|
|
27192
|
+
* // Use with default values
|
|
27193
|
+
* const level = player.getVariable('playerLevel') ?? 1;
|
|
27194
|
+
* const isChestOpened = player.getVariable('CHEST_OPENED') ?? false;
|
|
27195
|
+
* ```
|
|
27196
|
+
*/
|
|
27318
27197
|
getVariable(key) {
|
|
27319
27198
|
return this.variables.get(key);
|
|
27320
27199
|
}
|
|
27321
27200
|
/**
|
|
27322
27201
|
* Remove a variable
|
|
27323
27202
|
*
|
|
27203
|
+
* Deletes a variable from the player's variable map. This is useful for
|
|
27204
|
+
* cleaning up temporary flags, resetting certain game states, or managing
|
|
27205
|
+
* memory by removing unused variables. The method returns a boolean indicating
|
|
27206
|
+
* whether the variable existed and was successfully removed.
|
|
27207
|
+
*
|
|
27208
|
+
* @param key - The variable identifier to remove
|
|
27209
|
+
* @returns true if a variable existed and has been removed, false if the variable does not exist
|
|
27210
|
+
*
|
|
27211
|
+
* @example
|
|
27324
27212
|
* ```ts
|
|
27325
|
-
*
|
|
27326
|
-
*
|
|
27213
|
+
* // Remove variables and check if they existed
|
|
27214
|
+
* const removed = player.removeVariable('CHEST_OPENED'); // true if existed
|
|
27215
|
+
* const notFound = player.removeVariable('nonexistent'); // false
|
|
27327
27216
|
*
|
|
27328
|
-
*
|
|
27329
|
-
*
|
|
27330
|
-
*
|
|
27331
|
-
*
|
|
27332
|
-
*
|
|
27333
|
-
*
|
|
27217
|
+
* // Clean up temporary variables
|
|
27218
|
+
* player.removeVariable('tempQuestFlag');
|
|
27219
|
+
* player.removeVariable('battleTempData');
|
|
27220
|
+
*
|
|
27221
|
+
* // Conditional removal
|
|
27222
|
+
* if (player.getVariable('questCompleted')) {
|
|
27223
|
+
* player.removeVariable('questProgress');
|
|
27224
|
+
* }
|
|
27225
|
+
* ```
|
|
27226
|
+
*/
|
|
27334
27227
|
removeVariable(key) {
|
|
27335
27228
|
return this.variables.delete(key);
|
|
27336
27229
|
}
|
|
27230
|
+
/**
|
|
27231
|
+
* Check if a variable exists
|
|
27232
|
+
*
|
|
27233
|
+
* Determines whether a variable with the given key exists in the player's
|
|
27234
|
+
* variable map, regardless of its value (including falsy values like false, 0, '').
|
|
27235
|
+
* This is useful when you need to distinguish between a variable that doesn't
|
|
27236
|
+
* exist and one that has a falsy value.
|
|
27237
|
+
*
|
|
27238
|
+
* @param key - The variable identifier to check
|
|
27239
|
+
* @returns true if the variable exists, false otherwise
|
|
27240
|
+
*
|
|
27241
|
+
* @example
|
|
27242
|
+
* ```ts
|
|
27243
|
+
* // Check variable existence
|
|
27244
|
+
* player.setVariable('flag', false);
|
|
27245
|
+
* player.hasVariable('flag'); // true (even though value is false)
|
|
27246
|
+
* player.hasVariable('missing'); // false
|
|
27247
|
+
*
|
|
27248
|
+
* // Use in conditional logic
|
|
27249
|
+
* if (player.hasVariable('questStarted')) {
|
|
27250
|
+
* // Quest has been started, check progress
|
|
27251
|
+
* const progress = player.getVariable('questProgress');
|
|
27252
|
+
* } else {
|
|
27253
|
+
* // Quest not started yet
|
|
27254
|
+
* player.setVariable('questStarted', true);
|
|
27255
|
+
* }
|
|
27256
|
+
* ```
|
|
27257
|
+
*/
|
|
27258
|
+
hasVariable(key) {
|
|
27259
|
+
return this.variables.has(key);
|
|
27260
|
+
}
|
|
27261
|
+
/**
|
|
27262
|
+
* Get all variable keys
|
|
27263
|
+
*
|
|
27264
|
+
* Returns an array of all variable keys currently stored for this player.
|
|
27265
|
+
* This is useful for debugging, serialization, or iterating over all variables.
|
|
27266
|
+
* The keys are returned in insertion order.
|
|
27267
|
+
*
|
|
27268
|
+
* @returns Array of all variable keys
|
|
27269
|
+
*
|
|
27270
|
+
* @example
|
|
27271
|
+
* ```ts
|
|
27272
|
+
* // Get all variable keys
|
|
27273
|
+
* const keys = player.getVariableKeys();
|
|
27274
|
+
* console.log('Player has variables:', keys);
|
|
27275
|
+
*
|
|
27276
|
+
* // Iterate over all variables
|
|
27277
|
+
* keys.forEach(key => {
|
|
27278
|
+
* const value = player.getVariable(key);
|
|
27279
|
+
* console.log(`${key}: ${value}`);
|
|
27280
|
+
* });
|
|
27281
|
+
*
|
|
27282
|
+
* // Filter specific variable types
|
|
27283
|
+
* const questKeys = keys.filter(key => key.startsWith('quest_'));
|
|
27284
|
+
* ```
|
|
27285
|
+
*/
|
|
27286
|
+
getVariableKeys() {
|
|
27287
|
+
return Array.from(this.variables.keys());
|
|
27288
|
+
}
|
|
27289
|
+
/**
|
|
27290
|
+
* Clear all variables
|
|
27291
|
+
*
|
|
27292
|
+
* Removes all variables from the player's variable map. This is useful for
|
|
27293
|
+
* resetting the player state, cleaning up before saving, or starting fresh.
|
|
27294
|
+
* Use with caution as this operation cannot be undone.
|
|
27295
|
+
*
|
|
27296
|
+
* @returns void
|
|
27297
|
+
*
|
|
27298
|
+
* @example
|
|
27299
|
+
* ```ts
|
|
27300
|
+
* // Clear all variables (use with caution)
|
|
27301
|
+
* player.clearVariables();
|
|
27302
|
+
*
|
|
27303
|
+
* // Clear variables conditionally
|
|
27304
|
+
* if (gameReset) {
|
|
27305
|
+
* player.clearVariables();
|
|
27306
|
+
* // Re-initialize essential variables
|
|
27307
|
+
* player.setVariable('gameStarted', true);
|
|
27308
|
+
* }
|
|
27309
|
+
* ```
|
|
27310
|
+
*/
|
|
27311
|
+
clearVariables() {
|
|
27312
|
+
this.variables.clear();
|
|
27313
|
+
}
|
|
27337
27314
|
};
|
|
27338
27315
|
}
|
|
27339
27316
|
|
|
@@ -27886,278 +27863,53 @@ class StateLog {
|
|
|
27886
27863
|
}
|
|
27887
27864
|
}
|
|
27888
27865
|
|
|
27889
|
-
function
|
|
27866
|
+
function WithItemManager(Base) {
|
|
27890
27867
|
return class extends Base {
|
|
27891
|
-
constructor() {
|
|
27892
|
-
super(...arguments);
|
|
27893
|
-
this._statesEfficiency = signal$2([]);
|
|
27894
|
-
}
|
|
27895
27868
|
/**
|
|
27896
|
-
*
|
|
27897
|
-
*
|
|
27869
|
+
* Retrieves the information of an object: the number and the instance
|
|
27870
|
+
* @title Get Item
|
|
27871
|
+
* @method player.getItem(itemClass)
|
|
27872
|
+
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
27873
|
+
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
27874
|
+
* @memberof ItemManager
|
|
27875
|
+
* @example
|
|
27898
27876
|
*
|
|
27899
27877
|
* ```ts
|
|
27900
|
-
* import
|
|
27901
|
-
*
|
|
27902
|
-
* @State({
|
|
27903
|
-
* name: 'Paralyze'
|
|
27904
|
-
* })
|
|
27905
|
-
* class Paralyze {}
|
|
27906
|
-
*
|
|
27907
|
-
* @Armor({
|
|
27908
|
-
* name: 'Shield',
|
|
27909
|
-
* statesDefense: [{ rate: 1, state: Paralyze }]
|
|
27910
|
-
* })
|
|
27911
|
-
* class Shield {}
|
|
27912
|
-
*
|
|
27913
|
-
* @Armor({
|
|
27914
|
-
* name: 'FireShield',
|
|
27915
|
-
* statesDefense: [{ rate: 0.5, state: Paralyze }]
|
|
27916
|
-
* })
|
|
27917
|
-
* class FireShield {}
|
|
27918
|
-
*
|
|
27919
|
-
* player.addItem(Shield)
|
|
27920
|
-
* player.addItem(FireShield)
|
|
27921
|
-
* player.equip(Shield)
|
|
27922
|
-
* player.equip(FireShield)
|
|
27878
|
+
* import Potion from 'your-database/potion'
|
|
27923
27879
|
*
|
|
27924
|
-
*
|
|
27925
|
-
*
|
|
27926
|
-
*
|
|
27927
|
-
*
|
|
27928
|
-
|
|
27929
|
-
|
|
27930
|
-
|
|
27931
|
-
|
|
27932
|
-
return this.getFeature("statesDefense", "state");
|
|
27880
|
+
* player.addItem(Potion, 5)
|
|
27881
|
+
* const inventory = player.getItem(Potion)
|
|
27882
|
+
* console.log(inventory) // { nb: 5, item: <instance of Potion> }
|
|
27883
|
+
* ```
|
|
27884
|
+
*/
|
|
27885
|
+
getItem(itemClass) {
|
|
27886
|
+
const index = this._getItemIndex(itemClass);
|
|
27887
|
+
return this.items()[index];
|
|
27933
27888
|
}
|
|
27934
27889
|
/**
|
|
27935
|
-
*
|
|
27936
|
-
*
|
|
27937
|
-
*
|
|
27938
|
-
*
|
|
27939
|
-
*
|
|
27940
|
-
* @
|
|
27941
|
-
*
|
|
27942
|
-
* })
|
|
27943
|
-
* class Paralyze {}
|
|
27944
|
-
*
|
|
27945
|
-
* @State({
|
|
27946
|
-
* name: 'Sleep'
|
|
27947
|
-
* })
|
|
27948
|
-
* class Sleep {}
|
|
27949
|
-
*
|
|
27950
|
-
* @Class({
|
|
27951
|
-
* name: 'Fighter',
|
|
27952
|
-
* statesEfficiency: [{ rate: 1, state: Paralyze }]
|
|
27953
|
-
* })
|
|
27954
|
-
* class Hero {}
|
|
27955
|
-
*
|
|
27956
|
-
* player.setClass(Hero)
|
|
27957
|
-
*
|
|
27958
|
-
* console.log(player.statesEfficiency) // [{ rate: 1, instance of Paralyze }]
|
|
27959
|
-
*
|
|
27960
|
-
* player.statesEfficiency = [{ rate: 2, state: Sleep }]
|
|
27890
|
+
* Check if the player has the item in his inventory.
|
|
27891
|
+
* @title Has Item
|
|
27892
|
+
* @method player.hasItem(itemClass)
|
|
27893
|
+
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
27894
|
+
* @returns {boolean}
|
|
27895
|
+
* @memberof ItemManager
|
|
27896
|
+
* @example
|
|
27961
27897
|
*
|
|
27962
|
-
* console.log(player.statesEfficiency) // [{ rate: 1, state: instance of Paralyze }, { rate: 2, state: instance of Sleep }]
|
|
27963
|
-
* ```
|
|
27964
|
-
* @title Set/Get States Efficiency
|
|
27965
|
-
* @prop {Array<{ rate: number, state: StateClass}>} player.statesEfficiency
|
|
27966
|
-
* @memberof StateManager
|
|
27967
|
-
* */
|
|
27968
|
-
get statesEfficiency() {
|
|
27969
|
-
return this._statesEfficiency;
|
|
27970
|
-
}
|
|
27971
|
-
set statesEfficiency(val) {
|
|
27972
|
-
this._statesEfficiency = val;
|
|
27973
|
-
}
|
|
27974
|
-
applyStates(player, { addStates, removeStates }) {
|
|
27975
|
-
if (addStates) {
|
|
27976
|
-
for (let { state, rate } of addStates) {
|
|
27977
|
-
player.addState(state, rate);
|
|
27978
|
-
}
|
|
27979
|
-
}
|
|
27980
|
-
if (removeStates) {
|
|
27981
|
-
for (let { state, rate } of removeStates) {
|
|
27982
|
-
player.removeState(state, rate);
|
|
27983
|
-
}
|
|
27984
|
-
}
|
|
27985
|
-
}
|
|
27986
|
-
/**
|
|
27987
|
-
* Get a state to the player. Returns `null` if the state is not present on the player
|
|
27988
27898
|
* ```ts
|
|
27989
|
-
* import
|
|
27899
|
+
* import Potion from 'your-database/potion'
|
|
27990
27900
|
*
|
|
27991
|
-
* player.
|
|
27901
|
+
* player.hasItem(Potion) // false
|
|
27992
27902
|
* ```
|
|
27993
|
-
*
|
|
27994
|
-
* @title Get State
|
|
27995
|
-
* @method player.getState(stateClass)
|
|
27996
|
-
* @param {StateClass | string} stateClass or state id
|
|
27997
|
-
* @returns {instance of StateClass | null}
|
|
27998
|
-
* @memberof StateManager
|
|
27999
27903
|
*/
|
|
28000
|
-
|
|
28001
|
-
|
|
28002
|
-
|
|
28003
|
-
|
|
28004
|
-
|
|
27904
|
+
hasItem(itemClass) {
|
|
27905
|
+
return !!this.getItem(itemClass);
|
|
27906
|
+
}
|
|
27907
|
+
_getItemIndex(itemClass) {
|
|
27908
|
+
return this.items().findIndex((it) => {
|
|
27909
|
+
if (isString(itemClass)) {
|
|
27910
|
+
return it.id() == itemClass;
|
|
28005
27911
|
}
|
|
28006
|
-
return isInstanceOf(
|
|
28007
|
-
});
|
|
28008
|
-
}
|
|
28009
|
-
/**
|
|
28010
|
-
* Adds a state to the player. Set the chance between 0 and 1 that the state can apply
|
|
28011
|
-
* ```ts
|
|
28012
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
28013
|
-
*
|
|
28014
|
-
* try {
|
|
28015
|
-
* player.addState(Paralyze)
|
|
28016
|
-
* }
|
|
28017
|
-
* catch (err) {
|
|
28018
|
-
* console.log(err)
|
|
28019
|
-
* }
|
|
28020
|
-
* ```
|
|
28021
|
-
*
|
|
28022
|
-
* @title Add State
|
|
28023
|
-
* @method player.addState(stateClass,chance=1)
|
|
28024
|
-
* @param {StateClass | string} stateClass state class or state id
|
|
28025
|
-
* @param {number} [chance] 1 by default
|
|
28026
|
-
* @throws {StateLog} addFailed
|
|
28027
|
-
* If the chance to add the state has failed (defined with the `chance` param)
|
|
28028
|
-
* ```
|
|
28029
|
-
* {
|
|
28030
|
-
* id: ADD_STATE_FAILED,
|
|
28031
|
-
* msg: '...'
|
|
28032
|
-
* }
|
|
28033
|
-
* ```
|
|
28034
|
-
* @returns {instance of StateClass}
|
|
28035
|
-
* @memberof StateManager
|
|
28036
|
-
* @todo
|
|
28037
|
-
*/
|
|
28038
|
-
addState(stateClass, chance = 1) {
|
|
28039
|
-
const state = this.getState(stateClass);
|
|
28040
|
-
if (isString(stateClass)) {
|
|
28041
|
-
stateClass = this.databaseById(stateClass);
|
|
28042
|
-
}
|
|
28043
|
-
if (!state) {
|
|
28044
|
-
if (Math.random() > chance) {
|
|
28045
|
-
throw StateLog.addFailed(stateClass);
|
|
28046
|
-
}
|
|
28047
|
-
const instance = new stateClass();
|
|
28048
|
-
this.states().push(instance);
|
|
28049
|
-
this.applyStates(this, instance);
|
|
28050
|
-
return instance;
|
|
28051
|
-
}
|
|
28052
|
-
return null;
|
|
28053
|
-
}
|
|
28054
|
-
/**
|
|
28055
|
-
* Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
|
|
28056
|
-
* ```ts
|
|
28057
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
28058
|
-
*
|
|
28059
|
-
* try {
|
|
28060
|
-
* player.removeState(Paralyze)
|
|
28061
|
-
* }
|
|
28062
|
-
* catch (err) {
|
|
28063
|
-
* console.log(err)
|
|
28064
|
-
* }
|
|
28065
|
-
* ```
|
|
28066
|
-
*
|
|
28067
|
-
* @title Remove State
|
|
28068
|
-
* @method player.removeState(stateClass,chance=1)
|
|
28069
|
-
* @param {StateClass|string} stateClass class state or state id
|
|
28070
|
-
* @param {number} [chance] 1 by default
|
|
28071
|
-
* @throws {StateLog} removeFailed
|
|
28072
|
-
* If the chance to remove the state has failed (defined with the `chance` param)
|
|
28073
|
-
* ```
|
|
28074
|
-
* {
|
|
28075
|
-
* id: REMOVE_STATE_FAILED,
|
|
28076
|
-
* msg: '...'
|
|
28077
|
-
* }
|
|
28078
|
-
* ```
|
|
28079
|
-
* @throws {StateLog} notApplied
|
|
28080
|
-
* If the status does not exist
|
|
28081
|
-
* ```
|
|
28082
|
-
* {
|
|
28083
|
-
* id: STATE_NOT_APPLIED,
|
|
28084
|
-
* msg: '...'
|
|
28085
|
-
* }
|
|
28086
|
-
* ```
|
|
28087
|
-
* @returns {instance of StateClass}
|
|
28088
|
-
* @memberof StateManager
|
|
28089
|
-
*/
|
|
28090
|
-
removeState(stateClass, chance = 1) {
|
|
28091
|
-
const index = this.states().findIndex((state) => {
|
|
28092
|
-
if (isString(stateClass)) {
|
|
28093
|
-
return state.id == stateClass;
|
|
28094
|
-
}
|
|
28095
|
-
return isInstanceOf(state, stateClass);
|
|
28096
|
-
});
|
|
28097
|
-
if (index != -1) {
|
|
28098
|
-
if (Math.random() > chance) {
|
|
28099
|
-
throw StateLog.removeFailed(stateClass);
|
|
28100
|
-
}
|
|
28101
|
-
this.states().splice(index, 1);
|
|
28102
|
-
} else {
|
|
28103
|
-
throw StateLog.notApplied(stateClass);
|
|
28104
|
-
}
|
|
28105
|
-
}
|
|
28106
|
-
findStateEfficiency(stateClass) {
|
|
28107
|
-
return this.statesEfficiency().find(
|
|
28108
|
-
(state) => isInstanceOf(state.state, stateClass)
|
|
28109
|
-
);
|
|
28110
|
-
}
|
|
28111
|
-
};
|
|
28112
|
-
}
|
|
28113
|
-
|
|
28114
|
-
function WithItemManager(Base) {
|
|
28115
|
-
return class extends Base {
|
|
28116
|
-
/**
|
|
28117
|
-
* Retrieves the information of an object: the number and the instance
|
|
28118
|
-
* @title Get Item
|
|
28119
|
-
* @method player.getItem(itemClass)
|
|
28120
|
-
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
28121
|
-
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
28122
|
-
* @memberof ItemManager
|
|
28123
|
-
* @example
|
|
28124
|
-
*
|
|
28125
|
-
* ```ts
|
|
28126
|
-
* import Potion from 'your-database/potion'
|
|
28127
|
-
*
|
|
28128
|
-
* player.addItem(Potion, 5)
|
|
28129
|
-
* const inventory = player.getItem(Potion)
|
|
28130
|
-
* console.log(inventory) // { nb: 5, item: <instance of Potion> }
|
|
28131
|
-
* ```
|
|
28132
|
-
*/
|
|
28133
|
-
getItem(itemClass) {
|
|
28134
|
-
const index = this._getItemIndex(itemClass);
|
|
28135
|
-
return this.items()[index];
|
|
28136
|
-
}
|
|
28137
|
-
/**
|
|
28138
|
-
* Check if the player has the item in his inventory.
|
|
28139
|
-
* @title Has Item
|
|
28140
|
-
* @method player.hasItem(itemClass)
|
|
28141
|
-
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
28142
|
-
* @returns {boolean}
|
|
28143
|
-
* @memberof ItemManager
|
|
28144
|
-
* @example
|
|
28145
|
-
*
|
|
28146
|
-
* ```ts
|
|
28147
|
-
* import Potion from 'your-database/potion'
|
|
28148
|
-
*
|
|
28149
|
-
* player.hasItem(Potion) // false
|
|
28150
|
-
* ```
|
|
28151
|
-
*/
|
|
28152
|
-
hasItem(itemClass) {
|
|
28153
|
-
return !!this.getItem(itemClass);
|
|
28154
|
-
}
|
|
28155
|
-
_getItemIndex(itemClass) {
|
|
28156
|
-
return this.items().findIndex((it) => {
|
|
28157
|
-
if (isString(itemClass)) {
|
|
28158
|
-
return it.id() == itemClass;
|
|
28159
|
-
}
|
|
28160
|
-
return isInstanceOf(it, itemClass);
|
|
27912
|
+
return isInstanceOf(it, itemClass);
|
|
28161
27913
|
});
|
|
28162
27914
|
}
|
|
28163
27915
|
/**
|
|
@@ -28582,31 +28334,68 @@ var Effect = /* @__PURE__ */ ((Effect2) => {
|
|
|
28582
28334
|
function WithEffectManager(Base) {
|
|
28583
28335
|
return class extends Base {
|
|
28584
28336
|
/**
|
|
28337
|
+
* Check if the player has a specific effect
|
|
28338
|
+
*
|
|
28339
|
+
* Determines whether the player currently has the specified effect active.
|
|
28340
|
+
* This includes effects from states, equipment, and temporary conditions.
|
|
28341
|
+
* The effect system provides a flexible way to apply various gameplay
|
|
28342
|
+
* restrictions and enhancements to the player.
|
|
28343
|
+
*
|
|
28344
|
+
* @param effect - The effect identifier to check for
|
|
28345
|
+
* @returns true if the player has the effect, false otherwise
|
|
28346
|
+
*
|
|
28347
|
+
* @example
|
|
28585
28348
|
* ```ts
|
|
28586
28349
|
* import { Effect } from '@rpgjs/database'
|
|
28587
28350
|
*
|
|
28588
|
-
*
|
|
28351
|
+
* // Check for skill restriction
|
|
28352
|
+
* const cannotUseSkills = player.hasEffect(Effect.CAN_NOT_SKILL);
|
|
28353
|
+
* if (cannotUseSkills) {
|
|
28354
|
+
* console.log('Player cannot use skills right now');
|
|
28355
|
+
* }
|
|
28356
|
+
*
|
|
28357
|
+
* // Check for guard effect
|
|
28358
|
+
* const isGuarding = player.hasEffect(Effect.GUARD);
|
|
28359
|
+
* if (isGuarding) {
|
|
28360
|
+
* console.log('Player is in guard stance');
|
|
28361
|
+
* }
|
|
28362
|
+
*
|
|
28363
|
+
* // Check for cost reduction
|
|
28364
|
+
* const halfCost = player.hasEffect(Effect.HALF_SP_COST);
|
|
28365
|
+
* const actualCost = skillCost / (halfCost ? 2 : 1);
|
|
28589
28366
|
* ```
|
|
28590
|
-
|
|
28591
|
-
* @title Has Effect
|
|
28592
|
-
* @method player.hasEffect(effect)
|
|
28593
|
-
* @param {string} effect
|
|
28594
|
-
* @returns {boolean}
|
|
28595
|
-
* @memberof EffectManager
|
|
28596
|
-
* */
|
|
28367
|
+
*/
|
|
28597
28368
|
hasEffect(effect) {
|
|
28598
28369
|
return this.effects.includes(effect);
|
|
28599
28370
|
}
|
|
28600
28371
|
/**
|
|
28601
28372
|
* Retrieves a array of effects assigned to the player, state effects and effects of weapons and armors equipped with the player's own weapons.
|
|
28602
28373
|
*
|
|
28374
|
+
* Gets all currently active effects on the player from multiple sources:
|
|
28375
|
+
* - Direct effects assigned to the player
|
|
28376
|
+
* - Effects from active states (buffs/debuffs)
|
|
28377
|
+
* - Effects from equipped weapons and armor
|
|
28378
|
+
* The returned array contains unique effects without duplicates.
|
|
28379
|
+
*
|
|
28380
|
+
* @returns Array of all active effects on the player
|
|
28381
|
+
*
|
|
28382
|
+
* @example
|
|
28603
28383
|
* ```ts
|
|
28604
|
-
*
|
|
28384
|
+
* // Get all active effects
|
|
28385
|
+
* console.log(player.effects); // ['GUARD', 'HALF_SP_COST', ...]
|
|
28386
|
+
*
|
|
28387
|
+
* // Check multiple effects
|
|
28388
|
+
* const effects = player.effects;
|
|
28389
|
+
* const hasRestrictions = effects.some(effect =>
|
|
28390
|
+
* effect.startsWith('CAN_NOT_')
|
|
28391
|
+
* );
|
|
28392
|
+
*
|
|
28393
|
+
* // Count beneficial effects
|
|
28394
|
+
* const beneficialEffects = effects.filter(effect =>
|
|
28395
|
+
* ['GUARD', 'SUPER_GUARD', 'HALF_SP_COST'].includes(effect)
|
|
28396
|
+
* );
|
|
28605
28397
|
* ```
|
|
28606
|
-
|
|
28607
|
-
* @prop {Array<Effect>} player.effects
|
|
28608
|
-
* @memberof EffectManager
|
|
28609
|
-
* */
|
|
28398
|
+
*/
|
|
28610
28399
|
get effects() {
|
|
28611
28400
|
const getEffects = (prop) => {
|
|
28612
28401
|
return arrayFlat(this[prop]().map((el) => el.effects || []));
|
|
@@ -28620,113 +28409,243 @@ function WithEffectManager(Base) {
|
|
|
28620
28409
|
/**
|
|
28621
28410
|
* 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.
|
|
28622
28411
|
*
|
|
28412
|
+
* Sets the direct effects on the player. This only affects the player's own effects
|
|
28413
|
+
* and does not modify effects from states or equipment. The total effects will be
|
|
28414
|
+
* the combination of these direct effects plus any effects from states and equipment.
|
|
28415
|
+
*
|
|
28416
|
+
* @param val - Array of effect identifiers to assign to the player
|
|
28417
|
+
*
|
|
28418
|
+
* @example
|
|
28623
28419
|
* ```ts
|
|
28624
28420
|
* import { Effect } from '@rpgjs/database'
|
|
28625
28421
|
*
|
|
28626
|
-
* player
|
|
28422
|
+
* // Set direct player effects
|
|
28423
|
+
* player.effects = [Effect.CAN_NOT_SKILL];
|
|
28424
|
+
*
|
|
28425
|
+
* // Add multiple effects
|
|
28426
|
+
* player.effects = [
|
|
28427
|
+
* Effect.GUARD,
|
|
28428
|
+
* Effect.HALF_SP_COST,
|
|
28429
|
+
* Effect.CAN_NOT_ITEM
|
|
28430
|
+
* ];
|
|
28431
|
+
*
|
|
28432
|
+
* // Clear direct effects (equipment/state effects remain)
|
|
28433
|
+
* player.effects = [];
|
|
28434
|
+
*
|
|
28435
|
+
* // Temporary effect application
|
|
28436
|
+
* const originalEffects = player.effects;
|
|
28437
|
+
* player.effects = [...originalEffects, Effect.SUPER_GUARD];
|
|
28438
|
+
* // Later restore
|
|
28439
|
+
* player.effects = originalEffects;
|
|
28627
28440
|
* ```
|
|
28628
|
-
|
|
28629
|
-
* @prop {Array<Effect>} player.effects
|
|
28630
|
-
* @memberof EffectManager
|
|
28631
|
-
* */
|
|
28441
|
+
*/
|
|
28632
28442
|
set effects(val) {
|
|
28633
28443
|
this._effects.set(val);
|
|
28634
28444
|
}
|
|
28635
28445
|
};
|
|
28636
28446
|
}
|
|
28637
28447
|
|
|
28638
|
-
function
|
|
28448
|
+
function WithElementManager(Base) {
|
|
28639
28449
|
return class extends Base {
|
|
28450
|
+
constructor() {
|
|
28451
|
+
super(...arguments);
|
|
28452
|
+
this._elementsEfficiency = [];
|
|
28453
|
+
}
|
|
28640
28454
|
/**
|
|
28641
|
-
*
|
|
28455
|
+
* Recovers the player's elements defense on inventory. This list is generated from the `elementsDefense` property defined on the weapons or armors equipped.
|
|
28456
|
+
* If several items have the same element, only the highest rate will be taken into account.
|
|
28642
28457
|
*
|
|
28643
|
-
*
|
|
28644
|
-
* The
|
|
28458
|
+
* Gets the defensive capabilities against various elements from equipped items.
|
|
28459
|
+
* The system automatically consolidates multiple defensive items, keeping only
|
|
28460
|
+
* the highest protection rate for each element type. This provides a comprehensive
|
|
28461
|
+
* view of the player's elemental resistances from all equipped gear.
|
|
28462
|
+
*
|
|
28463
|
+
* @returns Array of element defense objects with rate and element properties
|
|
28464
|
+
*
|
|
28465
|
+
* @example
|
|
28466
|
+
* ```ts
|
|
28467
|
+
* import { Armor } from '@rpgjs/server'
|
|
28468
|
+
*
|
|
28469
|
+
* enum Elements {
|
|
28470
|
+
* Fire = 'fire'
|
|
28471
|
+
* }
|
|
28472
|
+
*
|
|
28473
|
+
* @Armor({
|
|
28474
|
+
* name: 'Shield',
|
|
28475
|
+
* elementsDefense: [{ rate: 1, element: Elements.Fire }]
|
|
28476
|
+
* })
|
|
28477
|
+
* class Shield {}
|
|
28478
|
+
*
|
|
28479
|
+
* @Armor({
|
|
28480
|
+
* name: 'FireShield',
|
|
28481
|
+
* elementsDefense: [{ rate: 0.5, element: Elements.Fire }]
|
|
28482
|
+
* })
|
|
28483
|
+
* class FireShield {}
|
|
28484
|
+
*
|
|
28485
|
+
* player.addItem(Shield)
|
|
28486
|
+
* player.addItem(FireShield)
|
|
28487
|
+
* player.equip(Shield)
|
|
28488
|
+
* player.equip(FireShield)
|
|
28489
|
+
*
|
|
28490
|
+
* console.log(player.elementsDefense) // [{ rate: 1, element: 'fire' }]
|
|
28491
|
+
*
|
|
28492
|
+
* // Check specific element defense
|
|
28493
|
+
* const fireDefense = player.elementsDefense.find(def => def.element === 'fire');
|
|
28494
|
+
* if (fireDefense) {
|
|
28495
|
+
* console.log(`Fire defense rate: ${fireDefense.rate}`);
|
|
28496
|
+
* }
|
|
28497
|
+
* ```
|
|
28498
|
+
*/
|
|
28499
|
+
get elementsDefense() {
|
|
28500
|
+
return this.getFeature("elementsDefense", "element");
|
|
28501
|
+
}
|
|
28502
|
+
/**
|
|
28503
|
+
* Set or retrieves all the elements where the player is vulnerable or not.
|
|
28645
28504
|
*
|
|
28505
|
+
* Manages the player's elemental efficiency modifiers, which determine how
|
|
28506
|
+
* effective different elements are against this player. Values greater than 1
|
|
28507
|
+
* indicate vulnerability, while values less than 1 indicate resistance.
|
|
28508
|
+
* This combines both class-based efficiency and player-specific modifiers.
|
|
28509
|
+
*
|
|
28510
|
+
* @returns Array of element efficiency objects with rate and element properties
|
|
28511
|
+
*
|
|
28512
|
+
* @example
|
|
28646
28513
|
* ```ts
|
|
28647
|
-
*
|
|
28514
|
+
* import { Class } from '@rpgjs/server'
|
|
28515
|
+
*
|
|
28516
|
+
* enum Elements {
|
|
28517
|
+
* Fire = 'fire',
|
|
28518
|
+
* Ice = 'ice'
|
|
28519
|
+
* }
|
|
28520
|
+
*
|
|
28521
|
+
* @Class({
|
|
28522
|
+
* name: 'Fighter',
|
|
28523
|
+
* elementsEfficiency: [{ rate: 1, element: Elements.Fire }]
|
|
28524
|
+
* })
|
|
28525
|
+
* class Hero {}
|
|
28526
|
+
*
|
|
28527
|
+
* player.setClass(Hero)
|
|
28528
|
+
*
|
|
28529
|
+
* console.log(player.elementsEfficiency) // [{ rate: 1, element: 'fire' }]
|
|
28530
|
+
*
|
|
28531
|
+
* player.elementsEfficiency = [{ rate: 2, element: Elements.Ice }]
|
|
28532
|
+
*
|
|
28533
|
+
* console.log(player.elementsEfficiency) // [{ rate: 1, element: 'fire' }, { rate: 2, element: 'ice' }]
|
|
28534
|
+
*
|
|
28535
|
+
* // Check for vulnerabilities
|
|
28536
|
+
* const vulnerabilities = player.elementsEfficiency.filter(eff => eff.rate > 1);
|
|
28537
|
+
* console.log('Vulnerable to:', vulnerabilities.map(v => v.element));
|
|
28538
|
+
*
|
|
28539
|
+
* // Check for resistances
|
|
28540
|
+
* const resistances = player.elementsEfficiency.filter(eff => eff.rate < 1);
|
|
28541
|
+
* console.log('Resistant to:', resistances.map(r => r.element));
|
|
28648
28542
|
* ```
|
|
28543
|
+
*/
|
|
28544
|
+
get elementsEfficiency() {
|
|
28545
|
+
if (this._class()) {
|
|
28546
|
+
return [
|
|
28547
|
+
...this._elementsEfficiency,
|
|
28548
|
+
...this._class()?.elementsEfficiency || []
|
|
28549
|
+
];
|
|
28550
|
+
}
|
|
28551
|
+
return this._elementsEfficiency;
|
|
28552
|
+
}
|
|
28553
|
+
set elementsEfficiency(val) {
|
|
28554
|
+
this._elementsEfficiency = val;
|
|
28555
|
+
}
|
|
28556
|
+
/**
|
|
28557
|
+
* Retrieves a array of elements assigned to the player and the elements of the weapons / armor equipped
|
|
28649
28558
|
*
|
|
28650
|
-
*
|
|
28651
|
-
*
|
|
28652
|
-
*
|
|
28653
|
-
*
|
|
28654
|
-
* @returns
|
|
28655
|
-
*
|
|
28656
|
-
*
|
|
28657
|
-
|
|
28658
|
-
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
fn = this.getFormulas("damageSkill");
|
|
28680
|
-
if (!fn) {
|
|
28681
|
-
throw new Error("Skill Formulas not exists");
|
|
28682
|
-
}
|
|
28683
|
-
damage = fn(paramA, paramB, skill);
|
|
28684
|
-
} else {
|
|
28685
|
-
fn = this.getFormulas("damagePhysic");
|
|
28686
|
-
if (!fn) {
|
|
28687
|
-
throw new Error("Physic Formulas not exists");
|
|
28688
|
-
}
|
|
28689
|
-
damage = fn(paramA, paramB);
|
|
28690
|
-
const coef = this.coefficientElements(attackerPlayer);
|
|
28691
|
-
if (coef >= 2) {
|
|
28692
|
-
elementVulnerable = true;
|
|
28693
|
-
}
|
|
28694
|
-
damage *= coef;
|
|
28695
|
-
fn = this.getFormulas("damageCritical");
|
|
28696
|
-
if (fn) {
|
|
28697
|
-
let newDamage = fn(damage, paramA, paramB);
|
|
28698
|
-
if (damage != newDamage) {
|
|
28699
|
-
critical = true;
|
|
28700
|
-
}
|
|
28701
|
-
damage = newDamage;
|
|
28559
|
+
* Gets all offensive elements available to the player from equipped weapons and armor.
|
|
28560
|
+
* This determines what elemental damage types the player can deal in combat.
|
|
28561
|
+
* The system automatically combines elements from all equipped items and removes duplicates.
|
|
28562
|
+
*
|
|
28563
|
+
* @returns Array of element objects with rate and element properties for offensive capabilities
|
|
28564
|
+
*
|
|
28565
|
+
* @example
|
|
28566
|
+
* ```ts
|
|
28567
|
+
* // Get all offensive elements
|
|
28568
|
+
* console.log(player.elements); // [{ rate: 1.5, element: 'fire' }, { rate: 1.2, element: 'ice' }]
|
|
28569
|
+
*
|
|
28570
|
+
* // Check if player can deal fire damage
|
|
28571
|
+
* const hasFireElement = player.elements.some(el => el.element === 'fire');
|
|
28572
|
+
* if (hasFireElement) {
|
|
28573
|
+
* console.log('Player can deal fire damage');
|
|
28574
|
+
* }
|
|
28575
|
+
*
|
|
28576
|
+
* // Get strongest element
|
|
28577
|
+
* const strongestElement = player.elements.reduce((max, current) =>
|
|
28578
|
+
* current.rate > max.rate ? current : max
|
|
28579
|
+
* );
|
|
28580
|
+
* console.log(`Strongest element: ${strongestElement.element} (${strongestElement.rate})`);
|
|
28581
|
+
* ```
|
|
28582
|
+
*/
|
|
28583
|
+
get elements() {
|
|
28584
|
+
let elements = [];
|
|
28585
|
+
for (let item of this.equipments()) {
|
|
28586
|
+
if (item.elements) {
|
|
28587
|
+
elements = [...elements, ...item.elements];
|
|
28702
28588
|
}
|
|
28703
28589
|
}
|
|
28704
|
-
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28590
|
+
return arrayUniq(elements);
|
|
28591
|
+
}
|
|
28592
|
+
/**
|
|
28593
|
+
* Calculate elemental damage coefficient against another player
|
|
28594
|
+
*
|
|
28595
|
+
* Determines the damage multiplier when this player attacks another player,
|
|
28596
|
+
* taking into account the attacker's offensive elements, the defender's
|
|
28597
|
+
* elemental efficiency, and elemental defense from equipment. This is used
|
|
28598
|
+
* in the battle system to calculate elemental damage modifiers.
|
|
28599
|
+
*
|
|
28600
|
+
* @param otherPlayer - The target player to calculate coefficient against
|
|
28601
|
+
* @returns Numerical coefficient to multiply base damage by
|
|
28602
|
+
*
|
|
28603
|
+
* @example
|
|
28604
|
+
* ```ts
|
|
28605
|
+
* // Calculate elemental damage coefficient
|
|
28606
|
+
* const firePlayer = new MyPlayer();
|
|
28607
|
+
* const icePlayer = new MyPlayer();
|
|
28608
|
+
*
|
|
28609
|
+
* // Fire player attacks ice player (assuming ice is weak to fire)
|
|
28610
|
+
* const coefficient = icePlayer.coefficientElements(firePlayer);
|
|
28611
|
+
* console.log(`Damage multiplier: ${coefficient}`); // e.g., 2.0 for double damage
|
|
28612
|
+
*
|
|
28613
|
+
* // Use in damage calculation
|
|
28614
|
+
* const baseDamage = 100;
|
|
28615
|
+
* const finalDamage = baseDamage * coefficient;
|
|
28616
|
+
* console.log(`Final damage: ${finalDamage}`);
|
|
28617
|
+
*
|
|
28618
|
+
* // Check for elemental advantage
|
|
28619
|
+
* if (coefficient > 1) {
|
|
28620
|
+
* console.log('Attacker has elemental advantage!');
|
|
28621
|
+
* } else if (coefficient < 1) {
|
|
28622
|
+
* console.log('Defender resists this element');
|
|
28623
|
+
* }
|
|
28624
|
+
* ```
|
|
28625
|
+
*/
|
|
28626
|
+
coefficientElements(otherPlayer) {
|
|
28627
|
+
const atkPlayerElements = otherPlayer.elements;
|
|
28628
|
+
const playerElements = this.elementsEfficiency;
|
|
28629
|
+
let coefficient = 1;
|
|
28630
|
+
for (let atkElement of atkPlayerElements) {
|
|
28631
|
+
const elementPlayer = playerElements.find(
|
|
28632
|
+
(el) => el.element == atkElement.element
|
|
28633
|
+
);
|
|
28634
|
+
const elementPlayerDef = this.elementsDefense.find(
|
|
28635
|
+
(el) => el.element == atkElement.element
|
|
28636
|
+
);
|
|
28637
|
+
if (!elementPlayer) continue;
|
|
28638
|
+
const fn = this.getFormulas("coefficientElements");
|
|
28639
|
+
if (!fn) {
|
|
28640
|
+
return coefficient;
|
|
28712
28641
|
}
|
|
28642
|
+
coefficient += fn(
|
|
28643
|
+
atkElement,
|
|
28644
|
+
elementPlayer,
|
|
28645
|
+
elementPlayerDef || { rate: 0 }
|
|
28646
|
+
);
|
|
28713
28647
|
}
|
|
28714
|
-
|
|
28715
|
-
damage /= 4;
|
|
28716
|
-
superGuard = true;
|
|
28717
|
-
}
|
|
28718
|
-
this.hp -= damage;
|
|
28719
|
-
return {
|
|
28720
|
-
damage,
|
|
28721
|
-
critical,
|
|
28722
|
-
elementVulnerable,
|
|
28723
|
-
guard,
|
|
28724
|
-
superGuard
|
|
28725
|
-
};
|
|
28726
|
-
}
|
|
28727
|
-
getFormulas(name) {
|
|
28728
|
-
const map = this.getCurrentMap();
|
|
28729
|
-
return map.damageFormulas[name];
|
|
28648
|
+
return coefficient;
|
|
28730
28649
|
}
|
|
28731
28650
|
};
|
|
28732
28651
|
}
|
|
@@ -28945,23 +28864,176 @@ function WithSkillManager(Base) {
|
|
|
28945
28864
|
};
|
|
28946
28865
|
}
|
|
28947
28866
|
|
|
28867
|
+
function WithBattleManager(Base) {
|
|
28868
|
+
return class extends Base {
|
|
28869
|
+
/**
|
|
28870
|
+
* Apply damage. Player will lose HP. the `attackerPlayer` parameter is the other player, the one who attacks.
|
|
28871
|
+
*
|
|
28872
|
+
* If you don't set the skill parameter, it will be a physical attack.
|
|
28873
|
+
* The attack formula is already defined but you can customize it in the server options.
|
|
28874
|
+
* This method handles all aspects of damage calculation including critical hits,
|
|
28875
|
+
* elemental vulnerabilities, guard effects, and applies the final damage to HP.
|
|
28876
|
+
*
|
|
28877
|
+
* @param attackerPlayer - The attacking player who deals the damage
|
|
28878
|
+
* @param skill - Optional skill object for magical attacks, if not provided uses physical attack
|
|
28879
|
+
* @returns Object containing damage details and special effects that occurred
|
|
28880
|
+
*
|
|
28881
|
+
* @example
|
|
28882
|
+
* ```ts
|
|
28883
|
+
* // Physical attack
|
|
28884
|
+
* const result = player.applyDamage(attackerPlayer);
|
|
28885
|
+
* console.log(`Physical damage: ${result.damage}, Critical: ${result.critical}`);
|
|
28886
|
+
*
|
|
28887
|
+
* // Magical attack with skill
|
|
28888
|
+
* const fireSkill = { id: 'fire', power: 50, element: 'fire' };
|
|
28889
|
+
* const magicResult = player.applyDamage(attackerPlayer, fireSkill);
|
|
28890
|
+
* console.log(`Magic damage: ${magicResult.damage}, Vulnerable: ${magicResult.elementVulnerable}`);
|
|
28891
|
+
*
|
|
28892
|
+
* // Check for guard effects
|
|
28893
|
+
* if (result.guard) {
|
|
28894
|
+
* console.log('Attack was partially blocked!');
|
|
28895
|
+
* }
|
|
28896
|
+
* if (result.superGuard) {
|
|
28897
|
+
* console.log('Attack was heavily reduced by super guard!');
|
|
28898
|
+
* }
|
|
28899
|
+
* ```
|
|
28900
|
+
*/
|
|
28901
|
+
applyDamage(attackerPlayer, skill) {
|
|
28902
|
+
const getParam = (player) => {
|
|
28903
|
+
const params = {};
|
|
28904
|
+
this.parameters.forEach((val, key) => {
|
|
28905
|
+
params[key] = player.param[key];
|
|
28906
|
+
});
|
|
28907
|
+
return {
|
|
28908
|
+
[ATK]: player.atk,
|
|
28909
|
+
[PDEF]: player.pdef,
|
|
28910
|
+
[SDEF]: player.sdef,
|
|
28911
|
+
...params
|
|
28912
|
+
};
|
|
28913
|
+
};
|
|
28914
|
+
let damage = 0, fn;
|
|
28915
|
+
let critical = false;
|
|
28916
|
+
let guard = false;
|
|
28917
|
+
let superGuard = false;
|
|
28918
|
+
let elementVulnerable = false;
|
|
28919
|
+
const paramA = getParam(attackerPlayer);
|
|
28920
|
+
const paramB = getParam(this);
|
|
28921
|
+
console.log(paramA, paramB);
|
|
28922
|
+
if (skill) {
|
|
28923
|
+
fn = this.getFormulas("damageSkill");
|
|
28924
|
+
if (!fn) {
|
|
28925
|
+
throw new Error("Skill Formulas not exists");
|
|
28926
|
+
}
|
|
28927
|
+
damage = fn(paramA, paramB, skill);
|
|
28928
|
+
} else {
|
|
28929
|
+
fn = this.getFormulas("damagePhysic");
|
|
28930
|
+
if (!fn) {
|
|
28931
|
+
throw new Error("Physic Formulas not exists");
|
|
28932
|
+
}
|
|
28933
|
+
damage = fn(paramA, paramB);
|
|
28934
|
+
const coef = this.coefficientElements(attackerPlayer);
|
|
28935
|
+
if (coef >= 2) {
|
|
28936
|
+
elementVulnerable = true;
|
|
28937
|
+
}
|
|
28938
|
+
damage *= coef;
|
|
28939
|
+
fn = this.getFormulas("damageCritical");
|
|
28940
|
+
if (fn) {
|
|
28941
|
+
let newDamage = fn(damage, paramA, paramB);
|
|
28942
|
+
if (damage != newDamage) {
|
|
28943
|
+
critical = true;
|
|
28944
|
+
}
|
|
28945
|
+
damage = newDamage;
|
|
28946
|
+
}
|
|
28947
|
+
}
|
|
28948
|
+
if (this.hasEffect(Effect.GUARD)) {
|
|
28949
|
+
fn = this.getFormulas("damageGuard");
|
|
28950
|
+
if (fn) {
|
|
28951
|
+
let newDamage = fn(damage, paramA, paramB);
|
|
28952
|
+
if (damage != newDamage) {
|
|
28953
|
+
guard = true;
|
|
28954
|
+
}
|
|
28955
|
+
damage = newDamage;
|
|
28956
|
+
}
|
|
28957
|
+
}
|
|
28958
|
+
if (this.hasEffect(Effect.SUPER_GUARD)) {
|
|
28959
|
+
damage /= 4;
|
|
28960
|
+
superGuard = true;
|
|
28961
|
+
}
|
|
28962
|
+
this.hp -= damage;
|
|
28963
|
+
return {
|
|
28964
|
+
damage,
|
|
28965
|
+
critical,
|
|
28966
|
+
elementVulnerable,
|
|
28967
|
+
guard,
|
|
28968
|
+
superGuard
|
|
28969
|
+
};
|
|
28970
|
+
}
|
|
28971
|
+
/**
|
|
28972
|
+
* Get damage formulas from the current map
|
|
28973
|
+
*
|
|
28974
|
+
* Retrieves the damage calculation formulas defined in the current map's configuration.
|
|
28975
|
+
* These formulas are used to calculate different types of damage including physical,
|
|
28976
|
+
* magical, critical hits, and guard effects. The formulas provide flexibility in
|
|
28977
|
+
* customizing the battle system's damage calculations.
|
|
28978
|
+
*
|
|
28979
|
+
* @param name - The name of the formula to retrieve (e.g., 'damagePhysic', 'damageSkill')
|
|
28980
|
+
* @returns The formula function or undefined if not found
|
|
28981
|
+
*
|
|
28982
|
+
* @example
|
|
28983
|
+
* ```ts
|
|
28984
|
+
* // Get physical damage formula
|
|
28985
|
+
* const physicFormula = player.getFormulas('damagePhysic');
|
|
28986
|
+
* if (physicFormula) {
|
|
28987
|
+
* const damage = physicFormula(attackerParams, defenderParams);
|
|
28988
|
+
* }
|
|
28989
|
+
*
|
|
28990
|
+
* // Get critical damage formula
|
|
28991
|
+
* const criticalFormula = player.getFormulas('damageCritical');
|
|
28992
|
+
* if (criticalFormula) {
|
|
28993
|
+
* const criticalDamage = criticalFormula(baseDamage, attackerParams, defenderParams);
|
|
28994
|
+
* }
|
|
28995
|
+
* ```
|
|
28996
|
+
*/
|
|
28997
|
+
getFormulas(name) {
|
|
28998
|
+
const map = this.getCurrentMap();
|
|
28999
|
+
return map.damageFormulas[name];
|
|
29000
|
+
}
|
|
29001
|
+
};
|
|
29002
|
+
}
|
|
29003
|
+
|
|
28948
29004
|
function WithClassManager(Base) {
|
|
28949
29005
|
return class extends Base {
|
|
28950
29006
|
/**
|
|
28951
29007
|
* Assign a class to the player
|
|
28952
29008
|
*
|
|
29009
|
+
* Sets the player's class, which defines their combat abilities, stat growth,
|
|
29010
|
+
* and available skills. The class system provides the foundation for character
|
|
29011
|
+
* progression and specialization. When a class is set, it automatically triggers
|
|
29012
|
+
* the class's onSet method for any additional initialization.
|
|
29013
|
+
*
|
|
29014
|
+
* @param _class - The class constructor or class ID to assign to the player
|
|
29015
|
+
* @returns The instantiated class object
|
|
29016
|
+
*
|
|
29017
|
+
* @example
|
|
28953
29018
|
* ```ts
|
|
28954
29019
|
* import { Fighter } from 'my-database/classes/fighter'
|
|
28955
29020
|
*
|
|
28956
|
-
*
|
|
29021
|
+
* // Set class using constructor
|
|
29022
|
+
* const fighterClass = player.setClass(Fighter);
|
|
29023
|
+
* console.log('Class set:', fighterClass.name);
|
|
29024
|
+
*
|
|
29025
|
+
* // Set class using string ID
|
|
29026
|
+
* player.setClass('fighter');
|
|
29027
|
+
*
|
|
29028
|
+
* // Class affects available skills and stats
|
|
29029
|
+
* console.log('Available skills:', player.skills);
|
|
29030
|
+
* console.log('Class bonuses applied to stats');
|
|
29031
|
+
*
|
|
29032
|
+
* // Class determines level progression
|
|
29033
|
+
* player.level = 5;
|
|
29034
|
+
* // Skills may be automatically learned based on class definition
|
|
28957
29035
|
* ```
|
|
28958
|
-
|
|
28959
|
-
* @title Set Class
|
|
28960
|
-
* @method player.setClass(ClassClass)
|
|
28961
|
-
* @param {ClassClass | string} class class or id
|
|
28962
|
-
* @returns {instance of ClassClass}
|
|
28963
|
-
* @memberof ClassManager
|
|
28964
|
-
* */
|
|
29036
|
+
*/
|
|
28965
29037
|
setClass(_class) {
|
|
28966
29038
|
if (isString(_class)) _class = this.databaseById(_class);
|
|
28967
29039
|
const classInstance = new _class();
|
|
@@ -28971,18 +29043,39 @@ function WithClassManager(Base) {
|
|
|
28971
29043
|
/**
|
|
28972
29044
|
* Allows to give a set of already defined properties to the player (default equipment, or a list of skills to learn according to the level)
|
|
28973
29045
|
*
|
|
29046
|
+
* Sets up the player as a specific actor archetype, which includes predefined
|
|
29047
|
+
* characteristics like starting equipment, parameters, level ranges, and associated class.
|
|
29048
|
+
* This is typically used for creating pre-configured character templates or NPCs
|
|
29049
|
+
* with specific roles and equipment loadouts.
|
|
29050
|
+
*
|
|
29051
|
+
* @param actorClass - The actor constructor or actor ID to assign to the player
|
|
29052
|
+
* @returns The instantiated actor object
|
|
29053
|
+
*
|
|
29054
|
+
* @example
|
|
28974
29055
|
* ```ts
|
|
28975
29056
|
* import { Hero } from 'my-database/classes/hero'
|
|
28976
29057
|
*
|
|
28977
|
-
* player
|
|
29058
|
+
* // Set up player as Hero actor
|
|
29059
|
+
* const heroActor = player.setActor(Hero);
|
|
29060
|
+
* console.log('Actor configured:', heroActor.name);
|
|
29061
|
+
*
|
|
29062
|
+
* // Actor automatically sets up:
|
|
29063
|
+
* // - Starting equipment (sword, armor, etc.)
|
|
29064
|
+
* console.log('Starting equipment:', player.equipments());
|
|
29065
|
+
*
|
|
29066
|
+
* // - Parameter ranges and growth
|
|
29067
|
+
* console.log('Level range:', player.initialLevel, '-', player.finalLevel);
|
|
29068
|
+
*
|
|
29069
|
+
* // - Associated class
|
|
29070
|
+
* console.log('Assigned class:', player.class);
|
|
29071
|
+
*
|
|
29072
|
+
* // - Experience curve
|
|
29073
|
+
* console.log('EXP curve:', player.expCurve);
|
|
29074
|
+
*
|
|
29075
|
+
* // Actor setup is comprehensive
|
|
29076
|
+
* player.setActor('hero'); // Can also use string ID
|
|
28978
29077
|
* ```
|
|
28979
|
-
|
|
28980
|
-
* @title Set Actor
|
|
28981
|
-
* @method player.setActor(ActorClass)
|
|
28982
|
-
* @param {ActorClass | string} actorClass actor class or id
|
|
28983
|
-
* @returns {instance of ActorClass}
|
|
28984
|
-
* @memberof ClassManager
|
|
28985
|
-
* */
|
|
29078
|
+
*/
|
|
28986
29079
|
setActor(actorClass) {
|
|
28987
29080
|
if (isString(actorClass)) actorClass = this.databaseById(actorClass);
|
|
28988
29081
|
const actor = new actorClass();
|
|
@@ -29003,32 +29096,41 @@ function WithClassManager(Base) {
|
|
|
29003
29096
|
};
|
|
29004
29097
|
}
|
|
29005
29098
|
|
|
29006
|
-
function
|
|
29099
|
+
function WithStateManager(Base) {
|
|
29007
29100
|
return class extends Base {
|
|
29008
29101
|
constructor() {
|
|
29009
29102
|
super(...arguments);
|
|
29010
|
-
this.
|
|
29103
|
+
this._statesEfficiency = signal$2([]);
|
|
29011
29104
|
}
|
|
29012
29105
|
/**
|
|
29013
|
-
* Recovers the player's
|
|
29106
|
+
* Recovers the player's states defense on inventory. This list is generated from the `statesDefense` property defined on the weapons or armors equipped.
|
|
29014
29107
|
* If several items have the same element, only the highest rate will be taken into account.
|
|
29015
29108
|
*
|
|
29109
|
+
* Gets the defensive capabilities against various states from equipped items.
|
|
29110
|
+
* The system automatically consolidates multiple defensive items, keeping only
|
|
29111
|
+
* the highest protection rate for each state type. This provides comprehensive
|
|
29112
|
+
* protection against debuffs and negative status effects.
|
|
29113
|
+
*
|
|
29114
|
+
* @returns Array of state defense objects with rate and state properties
|
|
29115
|
+
*
|
|
29116
|
+
* @example
|
|
29016
29117
|
* ```ts
|
|
29017
|
-
* import { Armor } from '@rpgjs/server'
|
|
29118
|
+
* import { Armor, State } from '@rpgjs/server'
|
|
29018
29119
|
*
|
|
29019
|
-
*
|
|
29020
|
-
*
|
|
29021
|
-
* }
|
|
29120
|
+
* @State({
|
|
29121
|
+
* name: 'Paralyze'
|
|
29122
|
+
* })
|
|
29123
|
+
* class Paralyze {}
|
|
29022
29124
|
*
|
|
29023
29125
|
* @Armor({
|
|
29024
29126
|
* name: 'Shield',
|
|
29025
|
-
*
|
|
29127
|
+
* statesDefense: [{ rate: 1, state: Paralyze }]
|
|
29026
29128
|
* })
|
|
29027
29129
|
* class Shield {}
|
|
29028
29130
|
*
|
|
29029
29131
|
* @Armor({
|
|
29030
29132
|
* name: 'FireShield',
|
|
29031
|
-
*
|
|
29133
|
+
* statesDefense: [{ rate: 0.5, state: Paralyze }]
|
|
29032
29134
|
* })
|
|
29033
29135
|
* class FireShield {}
|
|
29034
29136
|
*
|
|
@@ -29037,100 +29139,291 @@ function WithElementManager(Base) {
|
|
|
29037
29139
|
* player.equip(Shield)
|
|
29038
29140
|
* player.equip(FireShield)
|
|
29039
29141
|
*
|
|
29040
|
-
* console.log(player.
|
|
29142
|
+
* console.log(player.statesDefense) // [{ rate: 1, state: instance of Paralyze }]
|
|
29143
|
+
*
|
|
29144
|
+
* // Check specific state defense
|
|
29145
|
+
* const paralyzeDefense = player.statesDefense.find(def => def.state instanceof Paralyze);
|
|
29146
|
+
* if (paralyzeDefense) {
|
|
29147
|
+
* console.log(`Paralyze defense rate: ${paralyzeDefense.rate}`);
|
|
29148
|
+
* }
|
|
29041
29149
|
* ```
|
|
29042
|
-
|
|
29043
|
-
|
|
29044
|
-
|
|
29045
|
-
* @memberof ElementManager
|
|
29046
|
-
* */
|
|
29047
|
-
get elementsDefense() {
|
|
29048
|
-
return this.getFeature("elementsDefense", "element");
|
|
29150
|
+
*/
|
|
29151
|
+
get statesDefense() {
|
|
29152
|
+
return this.getFeature("statesDefense", "state");
|
|
29049
29153
|
}
|
|
29050
29154
|
/**
|
|
29051
|
-
* Set or retrieves all the
|
|
29155
|
+
* Set or retrieves all the states where the player is vulnerable or not.
|
|
29052
29156
|
*
|
|
29157
|
+
* Manages the player's state efficiency modifiers, which determine how
|
|
29158
|
+
* effective different states are against this player. Values greater than 1
|
|
29159
|
+
* indicate vulnerability, while values less than 1 indicate resistance.
|
|
29160
|
+
* This combines both class-based efficiency and player-specific modifiers.
|
|
29161
|
+
*
|
|
29162
|
+
* @returns Array of state efficiency objects with rate and state properties
|
|
29163
|
+
*
|
|
29164
|
+
* @example
|
|
29053
29165
|
* ```ts
|
|
29054
|
-
* import { Class } from '@rpgjs/server'
|
|
29166
|
+
* import { Class, State } from '@rpgjs/server'
|
|
29167
|
+
*
|
|
29168
|
+
* @State({
|
|
29169
|
+
* name: 'Paralyze'
|
|
29170
|
+
* })
|
|
29171
|
+
* class Paralyze {}
|
|
29055
29172
|
*
|
|
29056
|
-
*
|
|
29057
|
-
*
|
|
29058
|
-
*
|
|
29059
|
-
* }
|
|
29173
|
+
* @State({
|
|
29174
|
+
* name: 'Sleep'
|
|
29175
|
+
* })
|
|
29176
|
+
* class Sleep {}
|
|
29060
29177
|
*
|
|
29061
29178
|
* @Class({
|
|
29062
29179
|
* name: 'Fighter',
|
|
29063
|
-
*
|
|
29180
|
+
* statesEfficiency: [{ rate: 1, state: Paralyze }]
|
|
29064
29181
|
* })
|
|
29065
29182
|
* class Hero {}
|
|
29066
29183
|
*
|
|
29067
29184
|
* player.setClass(Hero)
|
|
29068
29185
|
*
|
|
29069
|
-
* console.log(player.
|
|
29186
|
+
* console.log(player.statesEfficiency) // [{ rate: 1, instance of Paralyze }]
|
|
29070
29187
|
*
|
|
29071
|
-
* player.
|
|
29188
|
+
* player.statesEfficiency = [{ rate: 2, state: Sleep }]
|
|
29072
29189
|
*
|
|
29073
|
-
* console.log(player.
|
|
29190
|
+
* console.log(player.statesEfficiency) // [{ rate: 1, state: instance of Paralyze }, { rate: 2, state: instance of Sleep }]
|
|
29191
|
+
*
|
|
29192
|
+
* // Check for vulnerabilities
|
|
29193
|
+
* const vulnerabilities = player.statesEfficiency.filter(eff => eff.rate > 1);
|
|
29194
|
+
* console.log('Vulnerable to states:', vulnerabilities.map(v => v.state.name));
|
|
29195
|
+
*
|
|
29196
|
+
* // Check for resistances
|
|
29197
|
+
* const resistances = player.statesEfficiency.filter(eff => eff.rate < 1);
|
|
29198
|
+
* console.log('Resistant to states:', resistances.map(r => r.state.name));
|
|
29074
29199
|
* ```
|
|
29075
|
-
|
|
29076
|
-
|
|
29077
|
-
|
|
29078
|
-
* */
|
|
29079
|
-
get elementsEfficiency() {
|
|
29080
|
-
if (this._class) {
|
|
29081
|
-
return [
|
|
29082
|
-
...this._elementsEfficiency,
|
|
29083
|
-
...this._class()?.elementsEfficiency || []
|
|
29084
|
-
];
|
|
29085
|
-
}
|
|
29086
|
-
return this._elementsEfficiency;
|
|
29200
|
+
*/
|
|
29201
|
+
get statesEfficiency() {
|
|
29202
|
+
return this._statesEfficiency;
|
|
29087
29203
|
}
|
|
29088
|
-
set
|
|
29089
|
-
this.
|
|
29204
|
+
set statesEfficiency(val) {
|
|
29205
|
+
this._statesEfficiency = val;
|
|
29090
29206
|
}
|
|
29091
29207
|
/**
|
|
29092
|
-
*
|
|
29208
|
+
* Apply states to a player from skill or item effects
|
|
29209
|
+
*
|
|
29210
|
+
* Processes state application and removal based on skill or item effects.
|
|
29211
|
+
* This method handles both adding beneficial states and removing negative ones,
|
|
29212
|
+
* with proper chance calculation and resistance checks.
|
|
29213
|
+
*
|
|
29214
|
+
* @param player - The target player to apply states to
|
|
29215
|
+
* @param states - Object containing arrays of states to add or remove
|
|
29216
|
+
*
|
|
29217
|
+
* @example
|
|
29218
|
+
* ```ts
|
|
29219
|
+
* // Apply states from a healing skill
|
|
29220
|
+
* const healingStates = {
|
|
29221
|
+
* addStates: [{ state: Regeneration, rate: 0.8 }],
|
|
29222
|
+
* removeStates: [{ state: Poison, rate: 1.0 }]
|
|
29223
|
+
* };
|
|
29224
|
+
* player.applyStates(targetPlayer, healingStates);
|
|
29225
|
+
*
|
|
29226
|
+
* // Apply debuff from an enemy attack
|
|
29227
|
+
* const debuffStates = {
|
|
29228
|
+
* addStates: [
|
|
29229
|
+
* { state: Paralyze, rate: 0.3 },
|
|
29230
|
+
* { state: Slow, rate: 0.5 }
|
|
29231
|
+
* ]
|
|
29232
|
+
* };
|
|
29233
|
+
* player.applyStates(targetPlayer, debuffStates);
|
|
29234
|
+
* ```
|
|
29235
|
+
*/
|
|
29236
|
+
applyStates(player, { addStates, removeStates }) {
|
|
29237
|
+
if (addStates) {
|
|
29238
|
+
for (let { state, rate } of addStates) {
|
|
29239
|
+
player.addState(state, rate);
|
|
29240
|
+
}
|
|
29241
|
+
}
|
|
29242
|
+
if (removeStates) {
|
|
29243
|
+
for (let { state, rate } of removeStates) {
|
|
29244
|
+
player.removeState(state, rate);
|
|
29245
|
+
}
|
|
29246
|
+
}
|
|
29247
|
+
}
|
|
29248
|
+
/**
|
|
29249
|
+
* Get a state to the player. Returns `null` if the state is not present on the player
|
|
29250
|
+
*
|
|
29251
|
+
* Retrieves a specific state instance from the player's active states.
|
|
29252
|
+
* This is useful for checking state properties, duration, or performing
|
|
29253
|
+
* state-specific operations. Returns null if the state is not currently active.
|
|
29254
|
+
*
|
|
29255
|
+
* @param stateClass - The state class constructor or state ID to search for
|
|
29256
|
+
* @returns The state instance if found, null otherwise
|
|
29257
|
+
*
|
|
29258
|
+
* @example
|
|
29259
|
+
* ```ts
|
|
29260
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29093
29261
|
*
|
|
29262
|
+
* // Check if player has a specific state
|
|
29263
|
+
* const paralyzeState = player.getState(Paralyze);
|
|
29264
|
+
* if (paralyzeState) {
|
|
29265
|
+
* console.log('Player is paralyzed');
|
|
29266
|
+
* console.log('Remaining duration:', paralyzeState.duration);
|
|
29267
|
+
* }
|
|
29268
|
+
*
|
|
29269
|
+
* // Check using string ID
|
|
29270
|
+
* const poisonState = player.getState('poison');
|
|
29271
|
+
* if (poisonState) {
|
|
29272
|
+
* console.log('Player is poisoned');
|
|
29273
|
+
* }
|
|
29274
|
+
*
|
|
29275
|
+
* // Use in conditional logic
|
|
29276
|
+
* if (player.getState(Sleep)) {
|
|
29277
|
+
* console.log('Player cannot act while sleeping');
|
|
29278
|
+
* return; // Skip player turn
|
|
29279
|
+
* }
|
|
29280
|
+
* ```
|
|
29281
|
+
*/
|
|
29282
|
+
getState(stateClass) {
|
|
29283
|
+
if (isString(stateClass)) stateClass = this.databaseById(stateClass);
|
|
29284
|
+
return this.states().find((state) => {
|
|
29285
|
+
if (isString(stateClass)) {
|
|
29286
|
+
return state.id == stateClass;
|
|
29287
|
+
}
|
|
29288
|
+
return isInstanceOf(state, stateClass);
|
|
29289
|
+
});
|
|
29290
|
+
}
|
|
29291
|
+
/**
|
|
29292
|
+
* Adds a state to the player. Set the chance between 0 and 1 that the state can apply
|
|
29293
|
+
*
|
|
29294
|
+
* Attempts to apply a state to the player with a specified success chance.
|
|
29295
|
+
* The method considers state resistance, efficiency modifiers, and random chance
|
|
29296
|
+
* to determine if the state is successfully applied. If successful, the state
|
|
29297
|
+
* is added to the player's active states list.
|
|
29298
|
+
*
|
|
29299
|
+
* @param stateClass - The state class constructor or state ID to apply
|
|
29300
|
+
* @param chance - Probability of successful application (0-1, default 1)
|
|
29301
|
+
* @returns The state instance if successfully applied, null if already present
|
|
29302
|
+
* @throws StateLog.addFailed if the chance roll fails
|
|
29303
|
+
*
|
|
29304
|
+
* @example
|
|
29094
29305
|
* ```ts
|
|
29095
|
-
*
|
|
29306
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29307
|
+
*
|
|
29308
|
+
* try {
|
|
29309
|
+
* // Attempt to apply paralyze with 100% chance
|
|
29310
|
+
* const state = player.addState(Paralyze);
|
|
29311
|
+
* if (state) {
|
|
29312
|
+
* console.log('Paralyze applied successfully');
|
|
29313
|
+
* }
|
|
29314
|
+
* } catch (err) {
|
|
29315
|
+
* console.log('Failed to apply paralyze:', err.msg);
|
|
29316
|
+
* }
|
|
29317
|
+
*
|
|
29318
|
+
* // Apply with reduced chance
|
|
29319
|
+
* try {
|
|
29320
|
+
* player.addState(Poison, 0.3); // 30% chance
|
|
29321
|
+
* } catch (err) {
|
|
29322
|
+
* console.log('Poison application failed');
|
|
29323
|
+
* }
|
|
29324
|
+
*
|
|
29325
|
+
* // Apply multiple states with different chances
|
|
29326
|
+
* const debuffs = [
|
|
29327
|
+
* { state: Slow, chance: 0.8 },
|
|
29328
|
+
* { state: Weak, chance: 0.6 }
|
|
29329
|
+
* ];
|
|
29330
|
+
* debuffs.forEach(({ state, chance }) => {
|
|
29331
|
+
* try {
|
|
29332
|
+
* player.addState(state, chance);
|
|
29333
|
+
* } catch (err) {
|
|
29334
|
+
* // Handle failed applications
|
|
29335
|
+
* }
|
|
29336
|
+
* });
|
|
29096
29337
|
* ```
|
|
29097
|
-
|
|
29098
|
-
|
|
29099
|
-
|
|
29100
|
-
|
|
29101
|
-
|
|
29102
|
-
|
|
29103
|
-
|
|
29104
|
-
|
|
29105
|
-
|
|
29106
|
-
elements = [...elements, ...item.elements];
|
|
29338
|
+
*/
|
|
29339
|
+
addState(stateClass, chance = 1) {
|
|
29340
|
+
const state = this.getState(stateClass);
|
|
29341
|
+
if (isString(stateClass)) {
|
|
29342
|
+
stateClass = this.databaseById(stateClass);
|
|
29343
|
+
}
|
|
29344
|
+
if (!state) {
|
|
29345
|
+
if (Math.random() > chance) {
|
|
29346
|
+
throw StateLog.addFailed(stateClass);
|
|
29107
29347
|
}
|
|
29348
|
+
const instance = new stateClass();
|
|
29349
|
+
this.states().push(instance);
|
|
29350
|
+
this.applyStates(this, instance);
|
|
29351
|
+
return instance;
|
|
29108
29352
|
}
|
|
29109
|
-
return
|
|
29353
|
+
return null;
|
|
29110
29354
|
}
|
|
29111
|
-
|
|
29112
|
-
|
|
29113
|
-
|
|
29114
|
-
|
|
29115
|
-
|
|
29116
|
-
|
|
29117
|
-
|
|
29118
|
-
|
|
29119
|
-
|
|
29120
|
-
|
|
29121
|
-
|
|
29122
|
-
|
|
29123
|
-
|
|
29124
|
-
|
|
29125
|
-
|
|
29355
|
+
/**
|
|
29356
|
+
* Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
|
|
29357
|
+
*
|
|
29358
|
+
* Attempts to remove a state from the player with a specified success chance.
|
|
29359
|
+
* This is useful for cure spells, items, or time-based state removal.
|
|
29360
|
+
* The method considers removal resistance and random chance.
|
|
29361
|
+
*
|
|
29362
|
+
* @param stateClass - The state class constructor or state ID to remove
|
|
29363
|
+
* @param chance - Probability of successful removal (0-1, default 1)
|
|
29364
|
+
* @throws StateLog.removeFailed if the chance roll fails
|
|
29365
|
+
* @throws StateLog.notApplied if the state is not currently active
|
|
29366
|
+
*
|
|
29367
|
+
* @example
|
|
29368
|
+
* ```ts
|
|
29369
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29370
|
+
*
|
|
29371
|
+
* try {
|
|
29372
|
+
* // Attempt to remove paralyze with 100% chance
|
|
29373
|
+
* player.removeState(Paralyze);
|
|
29374
|
+
* console.log('Paralyze removed successfully');
|
|
29375
|
+
* } catch (err) {
|
|
29376
|
+
* if (err.id === 'STATE_NOT_APPLIED') {
|
|
29377
|
+
* console.log('Player was not paralyzed');
|
|
29378
|
+
* } else {
|
|
29379
|
+
* console.log('Failed to remove paralyze:', err.msg);
|
|
29380
|
+
* }
|
|
29381
|
+
* }
|
|
29382
|
+
*
|
|
29383
|
+
* // Remove with reduced chance (for weak cure spells)
|
|
29384
|
+
* try {
|
|
29385
|
+
* player.removeState(Poison, 0.7); // 70% chance
|
|
29386
|
+
* } catch (err) {
|
|
29387
|
+
* console.log('Cure failed');
|
|
29388
|
+
* }
|
|
29389
|
+
*
|
|
29390
|
+
* // Remove all negative states (cure-all effect)
|
|
29391
|
+
* const negativeStates = [Poison, Paralyze, Sleep, Slow];
|
|
29392
|
+
* negativeStates.forEach(state => {
|
|
29393
|
+
* try {
|
|
29394
|
+
* player.removeState(state);
|
|
29395
|
+
* } catch (err) {
|
|
29396
|
+
* // State wasn't active, continue
|
|
29397
|
+
* }
|
|
29398
|
+
* });
|
|
29399
|
+
* ```
|
|
29400
|
+
*/
|
|
29401
|
+
removeState(stateClass, chance = 1) {
|
|
29402
|
+
const index = this.states().findIndex((state) => {
|
|
29403
|
+
if (isString(stateClass)) {
|
|
29404
|
+
return state.id == stateClass;
|
|
29126
29405
|
}
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
|
|
29131
|
-
|
|
29406
|
+
return isInstanceOf(state, stateClass);
|
|
29407
|
+
});
|
|
29408
|
+
if (index != -1) {
|
|
29409
|
+
if (Math.random() > chance) {
|
|
29410
|
+
throw StateLog.removeFailed(stateClass);
|
|
29411
|
+
}
|
|
29412
|
+
this.states().splice(index, 1);
|
|
29413
|
+
} else {
|
|
29414
|
+
throw StateLog.notApplied(stateClass);
|
|
29132
29415
|
}
|
|
29133
|
-
|
|
29416
|
+
}
|
|
29417
|
+
/**
|
|
29418
|
+
* Find state efficiency modifier for a specific state class
|
|
29419
|
+
*
|
|
29420
|
+
* @param stateClass - The state class to find efficiency for
|
|
29421
|
+
* @returns The efficiency object if found, undefined otherwise
|
|
29422
|
+
*/
|
|
29423
|
+
findStateEfficiency(stateClass) {
|
|
29424
|
+
return this.statesEfficiency().find(
|
|
29425
|
+
(state) => isInstanceOf(state.state, stateClass)
|
|
29426
|
+
);
|
|
29134
29427
|
}
|
|
29135
29428
|
};
|
|
29136
29429
|
}
|
|
@@ -29147,23 +29440,23 @@ var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
|
29147
29440
|
function combinePlayerMixins(mixins) {
|
|
29148
29441
|
return (Base) => mixins.reduce((ExtendedClass, mixin) => mixin(ExtendedClass), Base);
|
|
29149
29442
|
}
|
|
29150
|
-
const
|
|
29443
|
+
const BasicPlayerMixins = combinePlayerMixins([
|
|
29151
29444
|
WithComponentManager,
|
|
29152
29445
|
WithEffectManager,
|
|
29153
29446
|
WithGuiManager,
|
|
29154
29447
|
WithMoveManager,
|
|
29155
29448
|
WithGoldManager,
|
|
29156
|
-
WithVariableManager,
|
|
29157
29449
|
WithParameterManager,
|
|
29158
29450
|
WithItemFixture,
|
|
29159
|
-
WithStateManager,
|
|
29160
29451
|
WithItemManager,
|
|
29161
|
-
|
|
29452
|
+
WithElementManager,
|
|
29453
|
+
WithVariableManager,
|
|
29454
|
+
WithStateManager,
|
|
29162
29455
|
WithClassManager,
|
|
29163
|
-
|
|
29164
|
-
|
|
29456
|
+
WithSkillManager,
|
|
29457
|
+
WithBattleManager
|
|
29165
29458
|
]);
|
|
29166
|
-
const _RpgPlayer = class _RpgPlayer extends
|
|
29459
|
+
const _RpgPlayer = class _RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
|
|
29167
29460
|
constructor() {
|
|
29168
29461
|
super();
|
|
29169
29462
|
this.map = null;
|
|
@@ -29232,7 +29525,47 @@ const _RpgPlayer = class _RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
29232
29525
|
value
|
|
29233
29526
|
});
|
|
29234
29527
|
}
|
|
29235
|
-
|
|
29528
|
+
/**
|
|
29529
|
+
* Set the current animation of the player's sprite
|
|
29530
|
+
*
|
|
29531
|
+
* This method changes the animation state of the player's current sprite.
|
|
29532
|
+
* It's used to trigger character animations like attack, skill, or custom movements.
|
|
29533
|
+
* When `nbTimes` is set to a finite number, the animation will play that many times
|
|
29534
|
+
* before returning to the previous animation state.
|
|
29535
|
+
*
|
|
29536
|
+
* @param animationName - The name of the animation to play (e.g., 'attack', 'skill', 'walk')
|
|
29537
|
+
* @param nbTimes - Number of times to repeat the animation (default: Infinity for continuous)
|
|
29538
|
+
*
|
|
29539
|
+
* @example
|
|
29540
|
+
* ```ts
|
|
29541
|
+
* // Set continuous walk animation
|
|
29542
|
+
* player.setAnimation('walk');
|
|
29543
|
+
*
|
|
29544
|
+
* // Play attack animation 3 times then return to previous state
|
|
29545
|
+
* player.setAnimation('attack', 3);
|
|
29546
|
+
*
|
|
29547
|
+
* // Play skill animation once
|
|
29548
|
+
* player.setAnimation('skill', 1);
|
|
29549
|
+
*
|
|
29550
|
+
* // Set idle/stand animation
|
|
29551
|
+
* player.setAnimation('stand');
|
|
29552
|
+
* ```
|
|
29553
|
+
*/
|
|
29554
|
+
setAnimation(animationName, nbTimes = Infinity) {
|
|
29555
|
+
const map = this.getCurrentMap();
|
|
29556
|
+
if (!map) return;
|
|
29557
|
+
if (nbTimes === Infinity) {
|
|
29558
|
+
this.animationName.set(animationName);
|
|
29559
|
+
} else {
|
|
29560
|
+
map.$broadcast({
|
|
29561
|
+
type: "setAnimation",
|
|
29562
|
+
value: {
|
|
29563
|
+
animationName,
|
|
29564
|
+
nbTimes,
|
|
29565
|
+
object: this.id
|
|
29566
|
+
}
|
|
29567
|
+
});
|
|
29568
|
+
}
|
|
29236
29569
|
}
|
|
29237
29570
|
/**
|
|
29238
29571
|
* Run the change detection cycle. Normally, as soon as a hook is called in a class, the cycle is started. But you can start it manually
|
|
@@ -29302,11 +29635,35 @@ const _RpgPlayer = class _RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
29302
29635
|
}
|
|
29303
29636
|
);
|
|
29304
29637
|
}
|
|
29305
|
-
|
|
29638
|
+
/**
|
|
29639
|
+
* Show a temporary component animation on this player
|
|
29640
|
+
*
|
|
29641
|
+
* This method broadcasts a component animation to all clients, allowing
|
|
29642
|
+
* temporary visual effects like hit indicators, spell effects, or status animations
|
|
29643
|
+
* to be displayed on the player.
|
|
29644
|
+
*
|
|
29645
|
+
* @param id - The ID of the component animation to display
|
|
29646
|
+
* @param params - Parameters to pass to the component animation
|
|
29647
|
+
*
|
|
29648
|
+
* @example
|
|
29649
|
+
* ```ts
|
|
29650
|
+
* // Show a hit animation with damage text
|
|
29651
|
+
* player.showComponentAnimation("hit", {
|
|
29652
|
+
* text: "150",
|
|
29653
|
+
* color: "red"
|
|
29654
|
+
* });
|
|
29655
|
+
*
|
|
29656
|
+
* // Show a heal animation
|
|
29657
|
+
* player.showComponentAnimation("heal", {
|
|
29658
|
+
* amount: 50
|
|
29659
|
+
* });
|
|
29660
|
+
* ```
|
|
29661
|
+
*/
|
|
29662
|
+
showComponentAnimation(id, params) {
|
|
29306
29663
|
const map = this.getCurrentMap();
|
|
29307
29664
|
if (!map) return;
|
|
29308
29665
|
map.$broadcast({
|
|
29309
|
-
type: "
|
|
29666
|
+
type: "showComponentAnimation",
|
|
29310
29667
|
value: {
|
|
29311
29668
|
id,
|
|
29312
29669
|
params,
|
|
@@ -29314,8 +29671,45 @@ const _RpgPlayer = class _RpgPlayer extends PlayerMixins(RpgCommonPlayer) {
|
|
|
29314
29671
|
}
|
|
29315
29672
|
});
|
|
29316
29673
|
}
|
|
29674
|
+
/**
|
|
29675
|
+
* Display a spritesheet animation on the player
|
|
29676
|
+
*
|
|
29677
|
+
* This method displays a temporary visual animation using a spritesheet.
|
|
29678
|
+
* The animation can either be displayed as an overlay on the player or replace
|
|
29679
|
+
* the player's current graphic temporarily. This is useful for spell effects,
|
|
29680
|
+
* transformations, or other visual feedback that uses predefined spritesheets.
|
|
29681
|
+
*
|
|
29682
|
+
* @param graphic - The ID of the spritesheet to use for the animation
|
|
29683
|
+
* @param animationName - The name of the animation within the spritesheet (default: 'default')
|
|
29684
|
+
* @param replaceGraphic - Whether to replace the player's sprite with the animation (default: false)
|
|
29685
|
+
*
|
|
29686
|
+
* @example
|
|
29687
|
+
* ```ts
|
|
29688
|
+
* // Show explosion animation as overlay on player
|
|
29689
|
+
* player.showAnimation("explosion");
|
|
29690
|
+
*
|
|
29691
|
+
* // Show specific spell effect animation
|
|
29692
|
+
* player.showAnimation("spell-effects", "fireball");
|
|
29693
|
+
*
|
|
29694
|
+
* // Transform player graphic temporarily with animation
|
|
29695
|
+
* player.showAnimation("transformation", "werewolf", true);
|
|
29696
|
+
*
|
|
29697
|
+
* // Show healing effect on player
|
|
29698
|
+
* player.showAnimation("healing-effects", "holy-light");
|
|
29699
|
+
* ```
|
|
29700
|
+
*/
|
|
29701
|
+
showAnimation(graphic, animationName = "default", replaceGraphic = false) {
|
|
29702
|
+
if (replaceGraphic) {
|
|
29703
|
+
this.setAnimation(animationName, 1);
|
|
29704
|
+
return;
|
|
29705
|
+
}
|
|
29706
|
+
this.showComponentAnimation("animation", {
|
|
29707
|
+
graphic,
|
|
29708
|
+
animationName
|
|
29709
|
+
});
|
|
29710
|
+
}
|
|
29317
29711
|
showHit(text) {
|
|
29318
|
-
this.
|
|
29712
|
+
this.showComponentAnimation("hit", {
|
|
29319
29713
|
text,
|
|
29320
29714
|
direction: this.direction()
|
|
29321
29715
|
});
|
|
@@ -29343,6 +29737,7 @@ class RpgEvent extends RpgPlayer {
|
|
|
29343
29737
|
}
|
|
29344
29738
|
|
|
29345
29739
|
const context$1 = new Context();
|
|
29740
|
+
context$1["side"] = "server";
|
|
29346
29741
|
|
|
29347
29742
|
var __defProp$1 = Object.defineProperty;
|
|
29348
29743
|
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
@@ -29533,18 +29928,84 @@ let RpgMap = class extends RpgCommonMap {
|
|
|
29533
29928
|
removeEvent(eventId) {
|
|
29534
29929
|
delete this.events()[eventId];
|
|
29535
29930
|
}
|
|
29536
|
-
|
|
29931
|
+
/**
|
|
29932
|
+
* Display a component animation at a specific position on the map
|
|
29933
|
+
*
|
|
29934
|
+
* This method broadcasts a component animation to all clients connected to the map,
|
|
29935
|
+
* allowing temporary visual effects to be displayed at any location on the map.
|
|
29936
|
+
* Component animations are custom Canvas Engine components that can display
|
|
29937
|
+
* complex effects with custom logic and parameters.
|
|
29938
|
+
*
|
|
29939
|
+
* @param id - The ID of the component animation to display
|
|
29940
|
+
* @param position - The x, y coordinates where to display the animation
|
|
29941
|
+
* @param params - Parameters to pass to the component animation
|
|
29942
|
+
*
|
|
29943
|
+
* @example
|
|
29944
|
+
* ```ts
|
|
29945
|
+
* // Show explosion at specific coordinates
|
|
29946
|
+
* map.showComponentAnimation("explosion", { x: 300, y: 400 }, {
|
|
29947
|
+
* intensity: 2.5,
|
|
29948
|
+
* duration: 1500
|
|
29949
|
+
* });
|
|
29950
|
+
*
|
|
29951
|
+
* // Show area damage effect
|
|
29952
|
+
* map.showComponentAnimation("area-damage", { x: player.x, y: player.y }, {
|
|
29953
|
+
* radius: 100,
|
|
29954
|
+
* color: "red",
|
|
29955
|
+
* damage: 50
|
|
29956
|
+
* });
|
|
29957
|
+
*
|
|
29958
|
+
* // Show treasure spawn effect
|
|
29959
|
+
* map.showComponentAnimation("treasure-spawn", { x: 150, y: 200 }, {
|
|
29960
|
+
* sparkle: true,
|
|
29961
|
+
* sound: "treasure-appear"
|
|
29962
|
+
* });
|
|
29963
|
+
* ```
|
|
29964
|
+
*/
|
|
29965
|
+
showComponentAnimation(id, position, params) {
|
|
29537
29966
|
this.$broadcast({
|
|
29538
|
-
type: "
|
|
29967
|
+
type: "showComponentAnimation",
|
|
29539
29968
|
value: {
|
|
29540
|
-
id
|
|
29541
|
-
params
|
|
29542
|
-
|
|
29543
|
-
},
|
|
29544
|
-
object: object.id
|
|
29969
|
+
id,
|
|
29970
|
+
params,
|
|
29971
|
+
position
|
|
29545
29972
|
}
|
|
29546
29973
|
});
|
|
29547
29974
|
}
|
|
29975
|
+
/**
|
|
29976
|
+
* Display a spritesheet animation at a specific position on the map
|
|
29977
|
+
*
|
|
29978
|
+
* This method displays a temporary visual animation using a spritesheet at any
|
|
29979
|
+
* location on the map. It's a convenience method that internally uses showComponentAnimation
|
|
29980
|
+
* with the built-in 'animation' component. This is useful for spell effects, environmental
|
|
29981
|
+
* animations, or any visual feedback that uses predefined spritesheets.
|
|
29982
|
+
*
|
|
29983
|
+
* @param position - The x, y coordinates where to display the animation
|
|
29984
|
+
* @param graphic - The ID of the spritesheet to use for the animation
|
|
29985
|
+
* @param animationName - The name of the animation within the spritesheet (default: 'default')
|
|
29986
|
+
*
|
|
29987
|
+
* @example
|
|
29988
|
+
* ```ts
|
|
29989
|
+
* // Show explosion at specific coordinates
|
|
29990
|
+
* map.showAnimation({ x: 100, y: 200 }, "explosion");
|
|
29991
|
+
*
|
|
29992
|
+
* // Show spell effect at player position
|
|
29993
|
+
* const playerPos = { x: player.x, y: player.y };
|
|
29994
|
+
* map.showAnimation(playerPos, "spell-effects", "lightning");
|
|
29995
|
+
*
|
|
29996
|
+
* // Show environmental effect
|
|
29997
|
+
* map.showAnimation({ x: 300, y: 150 }, "nature-effects", "wind-gust");
|
|
29998
|
+
*
|
|
29999
|
+
* // Show portal opening animation
|
|
30000
|
+
* map.showAnimation({ x: 500, y: 400 }, "portals", "opening");
|
|
30001
|
+
* ```
|
|
30002
|
+
*/
|
|
30003
|
+
showAnimation(position, graphic, animationName = "default") {
|
|
30004
|
+
this.showComponentAnimation("animation", position, {
|
|
30005
|
+
graphic,
|
|
30006
|
+
animationName
|
|
30007
|
+
});
|
|
30008
|
+
}
|
|
29548
30009
|
};
|
|
29549
30010
|
__decorateClass$1([
|
|
29550
30011
|
users$1(RpgPlayer)
|