@rpgjs/server 5.0.0-alpha.5 → 5.0.0-alpha.7
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 +30 -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 +31 -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 +43 -6
- 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/index.js +984 -536
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/Player/BattleManager.ts +97 -38
- package/src/Player/ClassManager.ts +95 -35
- package/src/Player/ComponentManager.ts +63 -21
- 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 +36 -13
- 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 +75 -35
- package/src/Player/SkillManager.ts +44 -23
- package/src/Player/StateManager.ts +210 -95
- package/src/Player/VariableManager.ts +180 -48
package/dist/index.js
CHANGED
|
@@ -25651,6 +25651,34 @@ var PrebuiltGui = /* @__PURE__ */ ((PrebuiltGui2) => {
|
|
|
25651
25651
|
|
|
25652
25652
|
function WithComponentManager(Base) {
|
|
25653
25653
|
return class extends Base {
|
|
25654
|
+
/**
|
|
25655
|
+
* Set the graphic(s) for this player
|
|
25656
|
+
*
|
|
25657
|
+
* Allows setting either a single graphic or multiple graphics for the player.
|
|
25658
|
+
* When multiple graphics are provided, they are used for animation sequences.
|
|
25659
|
+
* The graphics system provides flexible visual representation that can be
|
|
25660
|
+
* dynamically changed during gameplay for different states, equipment, or animations.
|
|
25661
|
+
*
|
|
25662
|
+
* @param graphic - Single graphic name or array of graphic names for animation sequences
|
|
25663
|
+
* @returns void
|
|
25664
|
+
*
|
|
25665
|
+
* @example
|
|
25666
|
+
* ```ts
|
|
25667
|
+
* // Set a single graphic for static representation
|
|
25668
|
+
* player.setGraphic("hero");
|
|
25669
|
+
*
|
|
25670
|
+
* // Set multiple graphics for animation sequences
|
|
25671
|
+
* player.setGraphic(["hero_idle", "hero_walk", "hero_run"]);
|
|
25672
|
+
*
|
|
25673
|
+
* // Dynamic graphic changes based on equipment
|
|
25674
|
+
* if (player.hasArmor('platemail')) {
|
|
25675
|
+
* player.setGraphic("hero_armored");
|
|
25676
|
+
* }
|
|
25677
|
+
*
|
|
25678
|
+
* // Animation sequences for different actions
|
|
25679
|
+
* player.setGraphic(["mage_cast_1", "mage_cast_2", "mage_cast_3"]);
|
|
25680
|
+
* ```
|
|
25681
|
+
*/
|
|
25654
25682
|
setGraphic(graphic) {
|
|
25655
25683
|
if (Array.isArray(graphic)) {
|
|
25656
25684
|
this.graphics.set(graphic);
|
|
@@ -26158,7 +26186,7 @@ function WithMoveManager(Base) {
|
|
|
26158
26186
|
return class extends Base {
|
|
26159
26187
|
constructor() {
|
|
26160
26188
|
super(...arguments);
|
|
26161
|
-
//
|
|
26189
|
+
// Properties for infinite route management
|
|
26162
26190
|
this._infiniteRoutes = null;
|
|
26163
26191
|
this._finishRoute = null;
|
|
26164
26192
|
this._isInfiniteRouteActive = false;
|
|
@@ -27255,18 +27283,6 @@ function WithGuiManager(Base) {
|
|
|
27255
27283
|
|
|
27256
27284
|
function WithGoldManager(Base) {
|
|
27257
27285
|
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
27286
|
set gold(val) {
|
|
27271
27287
|
if (val < 0) {
|
|
27272
27288
|
val = 0;
|
|
@@ -27288,52 +27304,168 @@ function WithVariableManager(Base) {
|
|
|
27288
27304
|
/**
|
|
27289
27305
|
* Assign a variable to the player
|
|
27290
27306
|
*
|
|
27307
|
+
* Stores a key-value pair in the player's variable map. This is useful for
|
|
27308
|
+
* tracking game state, quest progress, flags, and other player-specific data.
|
|
27309
|
+
* The variable system provides a flexible way to store any type of data
|
|
27310
|
+
* associated with the player that persists throughout the game session.
|
|
27311
|
+
*
|
|
27312
|
+
* @param key - The variable identifier (string key to reference the variable)
|
|
27313
|
+
* @param val - The value to store (can be any type: boolean, number, string, object, array)
|
|
27314
|
+
* @returns void
|
|
27315
|
+
*
|
|
27316
|
+
* @example
|
|
27291
27317
|
* ```ts
|
|
27292
|
-
*
|
|
27318
|
+
* // Set different types of variables
|
|
27319
|
+
* player.setVariable('CHEST_OPENED', true);
|
|
27320
|
+
* player.setVariable('playerLevel', 5);
|
|
27321
|
+
* player.setVariable('questProgress', { step: 1, completed: false });
|
|
27322
|
+
* player.setVariable('inventory', ['sword', 'potion', 'key']);
|
|
27323
|
+
* player.setVariable('lastSaveTime', new Date().toISOString());
|
|
27293
27324
|
* ```
|
|
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
|
-
* */
|
|
27325
|
+
*/
|
|
27302
27326
|
setVariable(key, val) {
|
|
27303
27327
|
this.variables.set(key, val);
|
|
27304
27328
|
}
|
|
27305
27329
|
/**
|
|
27306
|
-
* Get a variable
|
|
27330
|
+
* Get a variable value
|
|
27331
|
+
*
|
|
27332
|
+
* Retrieves the value associated with the given key from the player's variables.
|
|
27333
|
+
* Returns undefined if the variable doesn't exist. This method is type-safe
|
|
27334
|
+
* and can be used with generic types for better TypeScript support.
|
|
27335
|
+
*
|
|
27336
|
+
* @param key - The variable identifier to retrieve
|
|
27337
|
+
* @returns The stored value or undefined if not found
|
|
27307
27338
|
*
|
|
27339
|
+
* @example
|
|
27308
27340
|
* ```ts
|
|
27309
|
-
*
|
|
27310
|
-
*
|
|
27341
|
+
* // Get variables with type inference
|
|
27342
|
+
* const hasKey = player.getVariable('CHEST_OPENED'); // boolean | undefined
|
|
27343
|
+
* const level = player.getVariable('playerLevel'); // number | undefined
|
|
27344
|
+
* const quest = player.getVariable('questProgress'); // object | undefined
|
|
27345
|
+
* const missing = player.getVariable('nonexistent'); // undefined
|
|
27311
27346
|
*
|
|
27312
|
-
*
|
|
27313
|
-
*
|
|
27314
|
-
*
|
|
27315
|
-
*
|
|
27316
|
-
|
|
27317
|
-
* */
|
|
27347
|
+
* // Use with default values
|
|
27348
|
+
* const level = player.getVariable('playerLevel') ?? 1;
|
|
27349
|
+
* const isChestOpened = player.getVariable('CHEST_OPENED') ?? false;
|
|
27350
|
+
* ```
|
|
27351
|
+
*/
|
|
27318
27352
|
getVariable(key) {
|
|
27319
27353
|
return this.variables.get(key);
|
|
27320
27354
|
}
|
|
27321
27355
|
/**
|
|
27322
27356
|
* Remove a variable
|
|
27323
27357
|
*
|
|
27358
|
+
* Deletes a variable from the player's variable map. This is useful for
|
|
27359
|
+
* cleaning up temporary flags, resetting certain game states, or managing
|
|
27360
|
+
* memory by removing unused variables. The method returns a boolean indicating
|
|
27361
|
+
* whether the variable existed and was successfully removed.
|
|
27362
|
+
*
|
|
27363
|
+
* @param key - The variable identifier to remove
|
|
27364
|
+
* @returns true if a variable existed and has been removed, false if the variable does not exist
|
|
27365
|
+
*
|
|
27366
|
+
* @example
|
|
27324
27367
|
* ```ts
|
|
27325
|
-
*
|
|
27326
|
-
*
|
|
27368
|
+
* // Remove variables and check if they existed
|
|
27369
|
+
* const removed = player.removeVariable('CHEST_OPENED'); // true if existed
|
|
27370
|
+
* const notFound = player.removeVariable('nonexistent'); // false
|
|
27327
27371
|
*
|
|
27328
|
-
*
|
|
27329
|
-
*
|
|
27330
|
-
*
|
|
27331
|
-
*
|
|
27332
|
-
*
|
|
27333
|
-
*
|
|
27372
|
+
* // Clean up temporary variables
|
|
27373
|
+
* player.removeVariable('tempQuestFlag');
|
|
27374
|
+
* player.removeVariable('battleTempData');
|
|
27375
|
+
*
|
|
27376
|
+
* // Conditional removal
|
|
27377
|
+
* if (player.getVariable('questCompleted')) {
|
|
27378
|
+
* player.removeVariable('questProgress');
|
|
27379
|
+
* }
|
|
27380
|
+
* ```
|
|
27381
|
+
*/
|
|
27334
27382
|
removeVariable(key) {
|
|
27335
27383
|
return this.variables.delete(key);
|
|
27336
27384
|
}
|
|
27385
|
+
/**
|
|
27386
|
+
* Check if a variable exists
|
|
27387
|
+
*
|
|
27388
|
+
* Determines whether a variable with the given key exists in the player's
|
|
27389
|
+
* variable map, regardless of its value (including falsy values like false, 0, '').
|
|
27390
|
+
* This is useful when you need to distinguish between a variable that doesn't
|
|
27391
|
+
* exist and one that has a falsy value.
|
|
27392
|
+
*
|
|
27393
|
+
* @param key - The variable identifier to check
|
|
27394
|
+
* @returns true if the variable exists, false otherwise
|
|
27395
|
+
*
|
|
27396
|
+
* @example
|
|
27397
|
+
* ```ts
|
|
27398
|
+
* // Check variable existence
|
|
27399
|
+
* player.setVariable('flag', false);
|
|
27400
|
+
* player.hasVariable('flag'); // true (even though value is false)
|
|
27401
|
+
* player.hasVariable('missing'); // false
|
|
27402
|
+
*
|
|
27403
|
+
* // Use in conditional logic
|
|
27404
|
+
* if (player.hasVariable('questStarted')) {
|
|
27405
|
+
* // Quest has been started, check progress
|
|
27406
|
+
* const progress = player.getVariable('questProgress');
|
|
27407
|
+
* } else {
|
|
27408
|
+
* // Quest not started yet
|
|
27409
|
+
* player.setVariable('questStarted', true);
|
|
27410
|
+
* }
|
|
27411
|
+
* ```
|
|
27412
|
+
*/
|
|
27413
|
+
hasVariable(key) {
|
|
27414
|
+
return this.variables.has(key);
|
|
27415
|
+
}
|
|
27416
|
+
/**
|
|
27417
|
+
* Get all variable keys
|
|
27418
|
+
*
|
|
27419
|
+
* Returns an array of all variable keys currently stored for this player.
|
|
27420
|
+
* This is useful for debugging, serialization, or iterating over all variables.
|
|
27421
|
+
* The keys are returned in insertion order.
|
|
27422
|
+
*
|
|
27423
|
+
* @returns Array of all variable keys
|
|
27424
|
+
*
|
|
27425
|
+
* @example
|
|
27426
|
+
* ```ts
|
|
27427
|
+
* // Get all variable keys
|
|
27428
|
+
* const keys = player.getVariableKeys();
|
|
27429
|
+
* console.log('Player has variables:', keys);
|
|
27430
|
+
*
|
|
27431
|
+
* // Iterate over all variables
|
|
27432
|
+
* keys.forEach(key => {
|
|
27433
|
+
* const value = player.getVariable(key);
|
|
27434
|
+
* console.log(`${key}: ${value}`);
|
|
27435
|
+
* });
|
|
27436
|
+
*
|
|
27437
|
+
* // Filter specific variable types
|
|
27438
|
+
* const questKeys = keys.filter(key => key.startsWith('quest_'));
|
|
27439
|
+
* ```
|
|
27440
|
+
*/
|
|
27441
|
+
getVariableKeys() {
|
|
27442
|
+
return Array.from(this.variables.keys());
|
|
27443
|
+
}
|
|
27444
|
+
/**
|
|
27445
|
+
* Clear all variables
|
|
27446
|
+
*
|
|
27447
|
+
* Removes all variables from the player's variable map. This is useful for
|
|
27448
|
+
* resetting the player state, cleaning up before saving, or starting fresh.
|
|
27449
|
+
* Use with caution as this operation cannot be undone.
|
|
27450
|
+
*
|
|
27451
|
+
* @returns void
|
|
27452
|
+
*
|
|
27453
|
+
* @example
|
|
27454
|
+
* ```ts
|
|
27455
|
+
* // Clear all variables (use with caution)
|
|
27456
|
+
* player.clearVariables();
|
|
27457
|
+
*
|
|
27458
|
+
* // Clear variables conditionally
|
|
27459
|
+
* if (gameReset) {
|
|
27460
|
+
* player.clearVariables();
|
|
27461
|
+
* // Re-initialize essential variables
|
|
27462
|
+
* player.setVariable('gameStarted', true);
|
|
27463
|
+
* }
|
|
27464
|
+
* ```
|
|
27465
|
+
*/
|
|
27466
|
+
clearVariables() {
|
|
27467
|
+
this.variables.clear();
|
|
27468
|
+
}
|
|
27337
27469
|
};
|
|
27338
27470
|
}
|
|
27339
27471
|
|
|
@@ -27886,328 +28018,103 @@ class StateLog {
|
|
|
27886
28018
|
}
|
|
27887
28019
|
}
|
|
27888
28020
|
|
|
27889
|
-
function
|
|
28021
|
+
function WithItemManager(Base) {
|
|
27890
28022
|
return class extends Base {
|
|
27891
|
-
constructor() {
|
|
27892
|
-
super(...arguments);
|
|
27893
|
-
this._statesEfficiency = signal$2([]);
|
|
27894
|
-
}
|
|
27895
28023
|
/**
|
|
27896
|
-
*
|
|
27897
|
-
*
|
|
28024
|
+
* Retrieves the information of an object: the number and the instance
|
|
28025
|
+
* @title Get Item
|
|
28026
|
+
* @method player.getItem(itemClass)
|
|
28027
|
+
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
28028
|
+
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
28029
|
+
* @memberof ItemManager
|
|
28030
|
+
* @example
|
|
27898
28031
|
*
|
|
27899
28032
|
* ```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)
|
|
28033
|
+
* import Potion from 'your-database/potion'
|
|
27923
28034
|
*
|
|
27924
|
-
*
|
|
27925
|
-
*
|
|
27926
|
-
*
|
|
27927
|
-
*
|
|
27928
|
-
|
|
27929
|
-
|
|
27930
|
-
|
|
27931
|
-
|
|
27932
|
-
return this.getFeature("statesDefense", "state");
|
|
28035
|
+
* player.addItem(Potion, 5)
|
|
28036
|
+
* const inventory = player.getItem(Potion)
|
|
28037
|
+
* console.log(inventory) // { nb: 5, item: <instance of Potion> }
|
|
28038
|
+
* ```
|
|
28039
|
+
*/
|
|
28040
|
+
getItem(itemClass) {
|
|
28041
|
+
const index = this._getItemIndex(itemClass);
|
|
28042
|
+
return this.items()[index];
|
|
27933
28043
|
}
|
|
27934
28044
|
/**
|
|
27935
|
-
*
|
|
28045
|
+
* Check if the player has the item in his inventory.
|
|
28046
|
+
* @title Has Item
|
|
28047
|
+
* @method player.hasItem(itemClass)
|
|
28048
|
+
* @param {ItemClass | string} itemClass Identifier of the object if the parameter is a string
|
|
28049
|
+
* @returns {boolean}
|
|
28050
|
+
* @memberof ItemManager
|
|
28051
|
+
* @example
|
|
27936
28052
|
*
|
|
27937
28053
|
* ```ts
|
|
27938
|
-
* import
|
|
27939
|
-
*
|
|
27940
|
-
* @State({
|
|
27941
|
-
* name: 'Paralyze'
|
|
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 }]
|
|
28054
|
+
* import Potion from 'your-database/potion'
|
|
27961
28055
|
*
|
|
27962
|
-
*
|
|
27963
|
-
*
|
|
27964
|
-
|
|
27965
|
-
|
|
27966
|
-
|
|
27967
|
-
* */
|
|
27968
|
-
get statesEfficiency() {
|
|
27969
|
-
return this._statesEfficiency;
|
|
27970
|
-
}
|
|
27971
|
-
set statesEfficiency(val) {
|
|
27972
|
-
this._statesEfficiency = val;
|
|
28056
|
+
* player.hasItem(Potion) // false
|
|
28057
|
+
* ```
|
|
28058
|
+
*/
|
|
28059
|
+
hasItem(itemClass) {
|
|
28060
|
+
return !!this.getItem(itemClass);
|
|
27973
28061
|
}
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27977
|
-
|
|
27978
|
-
}
|
|
27979
|
-
}
|
|
27980
|
-
if (removeStates) {
|
|
27981
|
-
for (let { state, rate } of removeStates) {
|
|
27982
|
-
player.removeState(state, rate);
|
|
28062
|
+
_getItemIndex(itemClass) {
|
|
28063
|
+
return this.items().findIndex((it) => {
|
|
28064
|
+
if (isString(itemClass)) {
|
|
28065
|
+
return it.id() == itemClass;
|
|
27983
28066
|
}
|
|
27984
|
-
|
|
28067
|
+
return isInstanceOf(it, itemClass);
|
|
28068
|
+
});
|
|
27985
28069
|
}
|
|
27986
28070
|
/**
|
|
27987
|
-
*
|
|
27988
|
-
* ```ts
|
|
27989
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
28071
|
+
* Add an item in the player's inventory. You can give more than one by specifying `nb`
|
|
27990
28072
|
*
|
|
27991
|
-
*
|
|
27992
|
-
*
|
|
28073
|
+
* `onAdd()` method is called on the ItemClass
|
|
28074
|
+
*
|
|
28075
|
+
* @title Add Item
|
|
28076
|
+
* @method player.addItem(item,nb=1)
|
|
28077
|
+
* @param {ItemClass} itemClass
|
|
28078
|
+
* @param {number} [nb] Default 1
|
|
28079
|
+
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
28080
|
+
* @memberof ItemManager
|
|
28081
|
+
* @example
|
|
27993
28082
|
*
|
|
27994
|
-
*
|
|
27995
|
-
*
|
|
27996
|
-
*
|
|
27997
|
-
*
|
|
27998
|
-
* @memberof StateManager
|
|
28083
|
+
* ```ts
|
|
28084
|
+
* import Potion from 'your-database/potion'
|
|
28085
|
+
* player.addItem(Potion, 5)
|
|
28086
|
+
* ```
|
|
27999
28087
|
*/
|
|
28000
|
-
|
|
28001
|
-
|
|
28002
|
-
|
|
28003
|
-
|
|
28004
|
-
|
|
28005
|
-
|
|
28006
|
-
|
|
28007
|
-
}
|
|
28088
|
+
addItem(itemId, nb = 1) {
|
|
28089
|
+
const data = this.databaseById(itemId);
|
|
28090
|
+
const item = this.items().find((it) => it.id() == itemId);
|
|
28091
|
+
let instance;
|
|
28092
|
+
if (item) {
|
|
28093
|
+
instance = item;
|
|
28094
|
+
instance.quantity.update((it) => it + nb);
|
|
28095
|
+
} else {
|
|
28096
|
+
instance = new Item(data);
|
|
28097
|
+
instance.id.set(itemId);
|
|
28098
|
+
this.items().push(instance);
|
|
28099
|
+
}
|
|
28100
|
+
this["execMethod"]("onAdd", [this], instance);
|
|
28101
|
+
return instance;
|
|
28008
28102
|
}
|
|
28009
28103
|
/**
|
|
28010
|
-
*
|
|
28011
|
-
* ```ts
|
|
28012
|
-
* import Paralyze from 'your-database/states/paralyze'
|
|
28104
|
+
* Deletes an item. Decreases the value `nb`. If the number falls to 0, then the item is removed from the inventory. The method then returns `undefined`
|
|
28013
28105
|
*
|
|
28014
|
-
*
|
|
28015
|
-
* player.addState(Paralyze)
|
|
28016
|
-
* }
|
|
28017
|
-
* catch (err) {
|
|
28018
|
-
* console.log(err)
|
|
28019
|
-
* }
|
|
28020
|
-
* ```
|
|
28106
|
+
* `onRemove()` method is called on the ItemClass
|
|
28021
28107
|
*
|
|
28022
|
-
* @title
|
|
28023
|
-
* @method player.
|
|
28024
|
-
* @param {
|
|
28025
|
-
* @param {number} [
|
|
28026
|
-
* @
|
|
28027
|
-
*
|
|
28108
|
+
* @title Remove Item
|
|
28109
|
+
* @method player.removeItem(item,nb=1)
|
|
28110
|
+
* @param {ItemClass | string} itemClass string is item id
|
|
28111
|
+
* @param {number} [nb] Default 1
|
|
28112
|
+
* @returns {{ nb: number, item: instance of ItemClass } | undefined}
|
|
28113
|
+
* @throws {ItemLog} notInInventory
|
|
28114
|
+
* If the object is not in the inventory, an exception is raised
|
|
28028
28115
|
* ```
|
|
28029
28116
|
* {
|
|
28030
|
-
* id:
|
|
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);
|
|
28161
|
-
});
|
|
28162
|
-
}
|
|
28163
|
-
/**
|
|
28164
|
-
* Add an item in the player's inventory. You can give more than one by specifying `nb`
|
|
28165
|
-
*
|
|
28166
|
-
* `onAdd()` method is called on the ItemClass
|
|
28167
|
-
*
|
|
28168
|
-
* @title Add Item
|
|
28169
|
-
* @method player.addItem(item,nb=1)
|
|
28170
|
-
* @param {ItemClass} itemClass
|
|
28171
|
-
* @param {number} [nb] Default 1
|
|
28172
|
-
* @returns {{ nb: number, item: instance of ItemClass }}
|
|
28173
|
-
* @memberof ItemManager
|
|
28174
|
-
* @example
|
|
28175
|
-
*
|
|
28176
|
-
* ```ts
|
|
28177
|
-
* import Potion from 'your-database/potion'
|
|
28178
|
-
* player.addItem(Potion, 5)
|
|
28179
|
-
* ```
|
|
28180
|
-
*/
|
|
28181
|
-
addItem(itemId, nb = 1) {
|
|
28182
|
-
const data = this.databaseById(itemId);
|
|
28183
|
-
const item = this.items().find((it) => it.id() == itemId);
|
|
28184
|
-
let instance;
|
|
28185
|
-
if (item) {
|
|
28186
|
-
instance = item;
|
|
28187
|
-
instance.quantity.update((it) => it + nb);
|
|
28188
|
-
} else {
|
|
28189
|
-
instance = new Item(data);
|
|
28190
|
-
instance.id.set(itemId);
|
|
28191
|
-
this.items().push(instance);
|
|
28192
|
-
}
|
|
28193
|
-
this["execMethod"]("onAdd", [this], instance);
|
|
28194
|
-
return instance;
|
|
28195
|
-
}
|
|
28196
|
-
/**
|
|
28197
|
-
* Deletes an item. Decreases the value `nb`. If the number falls to 0, then the item is removed from the inventory. The method then returns `undefined`
|
|
28198
|
-
*
|
|
28199
|
-
* `onRemove()` method is called on the ItemClass
|
|
28200
|
-
*
|
|
28201
|
-
* @title Remove Item
|
|
28202
|
-
* @method player.removeItem(item,nb=1)
|
|
28203
|
-
* @param {ItemClass | string} itemClass string is item id
|
|
28204
|
-
* @param {number} [nb] Default 1
|
|
28205
|
-
* @returns {{ nb: number, item: instance of ItemClass } | undefined}
|
|
28206
|
-
* @throws {ItemLog} notInInventory
|
|
28207
|
-
* If the object is not in the inventory, an exception is raised
|
|
28208
|
-
* ```
|
|
28209
|
-
* {
|
|
28210
|
-
* id: ITEM_NOT_INVENTORY,
|
|
28117
|
+
* id: ITEM_NOT_INVENTORY,
|
|
28211
28118
|
* msg: '...'
|
|
28212
28119
|
* }
|
|
28213
28120
|
* ```
|
|
@@ -28582,31 +28489,68 @@ var Effect = /* @__PURE__ */ ((Effect2) => {
|
|
|
28582
28489
|
function WithEffectManager(Base) {
|
|
28583
28490
|
return class extends Base {
|
|
28584
28491
|
/**
|
|
28492
|
+
* Check if the player has a specific effect
|
|
28493
|
+
*
|
|
28494
|
+
* Determines whether the player currently has the specified effect active.
|
|
28495
|
+
* This includes effects from states, equipment, and temporary conditions.
|
|
28496
|
+
* The effect system provides a flexible way to apply various gameplay
|
|
28497
|
+
* restrictions and enhancements to the player.
|
|
28498
|
+
*
|
|
28499
|
+
* @param effect - The effect identifier to check for
|
|
28500
|
+
* @returns true if the player has the effect, false otherwise
|
|
28501
|
+
*
|
|
28502
|
+
* @example
|
|
28585
28503
|
* ```ts
|
|
28586
28504
|
* import { Effect } from '@rpgjs/database'
|
|
28587
28505
|
*
|
|
28588
|
-
*
|
|
28506
|
+
* // Check for skill restriction
|
|
28507
|
+
* const cannotUseSkills = player.hasEffect(Effect.CAN_NOT_SKILL);
|
|
28508
|
+
* if (cannotUseSkills) {
|
|
28509
|
+
* console.log('Player cannot use skills right now');
|
|
28510
|
+
* }
|
|
28511
|
+
*
|
|
28512
|
+
* // Check for guard effect
|
|
28513
|
+
* const isGuarding = player.hasEffect(Effect.GUARD);
|
|
28514
|
+
* if (isGuarding) {
|
|
28515
|
+
* console.log('Player is in guard stance');
|
|
28516
|
+
* }
|
|
28517
|
+
*
|
|
28518
|
+
* // Check for cost reduction
|
|
28519
|
+
* const halfCost = player.hasEffect(Effect.HALF_SP_COST);
|
|
28520
|
+
* const actualCost = skillCost / (halfCost ? 2 : 1);
|
|
28589
28521
|
* ```
|
|
28590
|
-
|
|
28591
|
-
* @title Has Effect
|
|
28592
|
-
* @method player.hasEffect(effect)
|
|
28593
|
-
* @param {string} effect
|
|
28594
|
-
* @returns {boolean}
|
|
28595
|
-
* @memberof EffectManager
|
|
28596
|
-
* */
|
|
28522
|
+
*/
|
|
28597
28523
|
hasEffect(effect) {
|
|
28598
28524
|
return this.effects.includes(effect);
|
|
28599
28525
|
}
|
|
28600
28526
|
/**
|
|
28601
28527
|
* 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
28528
|
*
|
|
28529
|
+
* Gets all currently active effects on the player from multiple sources:
|
|
28530
|
+
* - Direct effects assigned to the player
|
|
28531
|
+
* - Effects from active states (buffs/debuffs)
|
|
28532
|
+
* - Effects from equipped weapons and armor
|
|
28533
|
+
* The returned array contains unique effects without duplicates.
|
|
28534
|
+
*
|
|
28535
|
+
* @returns Array of all active effects on the player
|
|
28536
|
+
*
|
|
28537
|
+
* @example
|
|
28603
28538
|
* ```ts
|
|
28604
|
-
*
|
|
28539
|
+
* // Get all active effects
|
|
28540
|
+
* console.log(player.effects); // ['GUARD', 'HALF_SP_COST', ...]
|
|
28541
|
+
*
|
|
28542
|
+
* // Check multiple effects
|
|
28543
|
+
* const effects = player.effects;
|
|
28544
|
+
* const hasRestrictions = effects.some(effect =>
|
|
28545
|
+
* effect.startsWith('CAN_NOT_')
|
|
28546
|
+
* );
|
|
28547
|
+
*
|
|
28548
|
+
* // Count beneficial effects
|
|
28549
|
+
* const beneficialEffects = effects.filter(effect =>
|
|
28550
|
+
* ['GUARD', 'SUPER_GUARD', 'HALF_SP_COST'].includes(effect)
|
|
28551
|
+
* );
|
|
28605
28552
|
* ```
|
|
28606
|
-
|
|
28607
|
-
* @prop {Array<Effect>} player.effects
|
|
28608
|
-
* @memberof EffectManager
|
|
28609
|
-
* */
|
|
28553
|
+
*/
|
|
28610
28554
|
get effects() {
|
|
28611
28555
|
const getEffects = (prop) => {
|
|
28612
28556
|
return arrayFlat(this[prop]().map((el) => el.effects || []));
|
|
@@ -28620,113 +28564,243 @@ function WithEffectManager(Base) {
|
|
|
28620
28564
|
/**
|
|
28621
28565
|
* 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
28566
|
*
|
|
28567
|
+
* Sets the direct effects on the player. This only affects the player's own effects
|
|
28568
|
+
* and does not modify effects from states or equipment. The total effects will be
|
|
28569
|
+
* the combination of these direct effects plus any effects from states and equipment.
|
|
28570
|
+
*
|
|
28571
|
+
* @param val - Array of effect identifiers to assign to the player
|
|
28572
|
+
*
|
|
28573
|
+
* @example
|
|
28623
28574
|
* ```ts
|
|
28624
28575
|
* import { Effect } from '@rpgjs/database'
|
|
28625
28576
|
*
|
|
28626
|
-
* player
|
|
28577
|
+
* // Set direct player effects
|
|
28578
|
+
* player.effects = [Effect.CAN_NOT_SKILL];
|
|
28579
|
+
*
|
|
28580
|
+
* // Add multiple effects
|
|
28581
|
+
* player.effects = [
|
|
28582
|
+
* Effect.GUARD,
|
|
28583
|
+
* Effect.HALF_SP_COST,
|
|
28584
|
+
* Effect.CAN_NOT_ITEM
|
|
28585
|
+
* ];
|
|
28586
|
+
*
|
|
28587
|
+
* // Clear direct effects (equipment/state effects remain)
|
|
28588
|
+
* player.effects = [];
|
|
28589
|
+
*
|
|
28590
|
+
* // Temporary effect application
|
|
28591
|
+
* const originalEffects = player.effects;
|
|
28592
|
+
* player.effects = [...originalEffects, Effect.SUPER_GUARD];
|
|
28593
|
+
* // Later restore
|
|
28594
|
+
* player.effects = originalEffects;
|
|
28627
28595
|
* ```
|
|
28628
|
-
|
|
28629
|
-
* @prop {Array<Effect>} player.effects
|
|
28630
|
-
* @memberof EffectManager
|
|
28631
|
-
* */
|
|
28596
|
+
*/
|
|
28632
28597
|
set effects(val) {
|
|
28633
28598
|
this._effects.set(val);
|
|
28634
28599
|
}
|
|
28635
28600
|
};
|
|
28636
28601
|
}
|
|
28637
28602
|
|
|
28638
|
-
function
|
|
28603
|
+
function WithElementManager(Base) {
|
|
28639
28604
|
return class extends Base {
|
|
28605
|
+
constructor() {
|
|
28606
|
+
super(...arguments);
|
|
28607
|
+
this._elementsEfficiency = [];
|
|
28608
|
+
}
|
|
28640
28609
|
/**
|
|
28641
|
-
*
|
|
28642
|
-
*
|
|
28643
|
-
* If you don't set the skill parameter, it will be a physical attack.
|
|
28644
|
-
* The attack formula is already defined but you can customize it in the server options
|
|
28610
|
+
* Recovers the player's elements defense on inventory. This list is generated from the `elementsDefense` property defined on the weapons or armors equipped.
|
|
28611
|
+
* If several items have the same element, only the highest rate will be taken into account.
|
|
28645
28612
|
*
|
|
28613
|
+
* Gets the defensive capabilities against various elements from equipped items.
|
|
28614
|
+
* The system automatically consolidates multiple defensive items, keeping only
|
|
28615
|
+
* the highest protection rate for each element type. This provides a comprehensive
|
|
28616
|
+
* view of the player's elemental resistances from all equipped gear.
|
|
28617
|
+
*
|
|
28618
|
+
* @returns Array of element defense objects with rate and element properties
|
|
28619
|
+
*
|
|
28620
|
+
* @example
|
|
28646
28621
|
* ```ts
|
|
28647
|
-
*
|
|
28622
|
+
* import { Armor } from '@rpgjs/server'
|
|
28623
|
+
*
|
|
28624
|
+
* enum Elements {
|
|
28625
|
+
* Fire = 'fire'
|
|
28626
|
+
* }
|
|
28627
|
+
*
|
|
28628
|
+
* @Armor({
|
|
28629
|
+
* name: 'Shield',
|
|
28630
|
+
* elementsDefense: [{ rate: 1, element: Elements.Fire }]
|
|
28631
|
+
* })
|
|
28632
|
+
* class Shield {}
|
|
28633
|
+
*
|
|
28634
|
+
* @Armor({
|
|
28635
|
+
* name: 'FireShield',
|
|
28636
|
+
* elementsDefense: [{ rate: 0.5, element: Elements.Fire }]
|
|
28637
|
+
* })
|
|
28638
|
+
* class FireShield {}
|
|
28639
|
+
*
|
|
28640
|
+
* player.addItem(Shield)
|
|
28641
|
+
* player.addItem(FireShield)
|
|
28642
|
+
* player.equip(Shield)
|
|
28643
|
+
* player.equip(FireShield)
|
|
28644
|
+
*
|
|
28645
|
+
* console.log(player.elementsDefense) // [{ rate: 1, element: 'fire' }]
|
|
28646
|
+
*
|
|
28647
|
+
* // Check specific element defense
|
|
28648
|
+
* const fireDefense = player.elementsDefense.find(def => def.element === 'fire');
|
|
28649
|
+
* if (fireDefense) {
|
|
28650
|
+
* console.log(`Fire defense rate: ${fireDefense.rate}`);
|
|
28651
|
+
* }
|
|
28648
28652
|
* ```
|
|
28653
|
+
*/
|
|
28654
|
+
get elementsDefense() {
|
|
28655
|
+
return this.getFeature("elementsDefense", "element");
|
|
28656
|
+
}
|
|
28657
|
+
/**
|
|
28658
|
+
* Set or retrieves all the elements where the player is vulnerable or not.
|
|
28649
28659
|
*
|
|
28650
|
-
*
|
|
28651
|
-
*
|
|
28652
|
-
*
|
|
28653
|
-
*
|
|
28654
|
-
*
|
|
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
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
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;
|
|
28702
|
-
}
|
|
28660
|
+
* Manages the player's elemental efficiency modifiers, which determine how
|
|
28661
|
+
* effective different elements are against this player. Values greater than 1
|
|
28662
|
+
* indicate vulnerability, while values less than 1 indicate resistance.
|
|
28663
|
+
* This combines both class-based efficiency and player-specific modifiers.
|
|
28664
|
+
*
|
|
28665
|
+
* @returns Array of element efficiency objects with rate and element properties
|
|
28666
|
+
*
|
|
28667
|
+
* @example
|
|
28668
|
+
* ```ts
|
|
28669
|
+
* import { Class } from '@rpgjs/server'
|
|
28670
|
+
*
|
|
28671
|
+
* enum Elements {
|
|
28672
|
+
* Fire = 'fire',
|
|
28673
|
+
* Ice = 'ice'
|
|
28674
|
+
* }
|
|
28675
|
+
*
|
|
28676
|
+
* @Class({
|
|
28677
|
+
* name: 'Fighter',
|
|
28678
|
+
* elementsEfficiency: [{ rate: 1, element: Elements.Fire }]
|
|
28679
|
+
* })
|
|
28680
|
+
* class Hero {}
|
|
28681
|
+
*
|
|
28682
|
+
* player.setClass(Hero)
|
|
28683
|
+
*
|
|
28684
|
+
* console.log(player.elementsEfficiency) // [{ rate: 1, element: 'fire' }]
|
|
28685
|
+
*
|
|
28686
|
+
* player.elementsEfficiency = [{ rate: 2, element: Elements.Ice }]
|
|
28687
|
+
*
|
|
28688
|
+
* console.log(player.elementsEfficiency) // [{ rate: 1, element: 'fire' }, { rate: 2, element: 'ice' }]
|
|
28689
|
+
*
|
|
28690
|
+
* // Check for vulnerabilities
|
|
28691
|
+
* const vulnerabilities = player.elementsEfficiency.filter(eff => eff.rate > 1);
|
|
28692
|
+
* console.log('Vulnerable to:', vulnerabilities.map(v => v.element));
|
|
28693
|
+
*
|
|
28694
|
+
* // Check for resistances
|
|
28695
|
+
* const resistances = player.elementsEfficiency.filter(eff => eff.rate < 1);
|
|
28696
|
+
* console.log('Resistant to:', resistances.map(r => r.element));
|
|
28697
|
+
* ```
|
|
28698
|
+
*/
|
|
28699
|
+
get elementsEfficiency() {
|
|
28700
|
+
if (this._class()) {
|
|
28701
|
+
return [
|
|
28702
|
+
...this._elementsEfficiency,
|
|
28703
|
+
...this._class()?.elementsEfficiency || []
|
|
28704
|
+
];
|
|
28703
28705
|
}
|
|
28704
|
-
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28706
|
+
return this._elementsEfficiency;
|
|
28707
|
+
}
|
|
28708
|
+
set elementsEfficiency(val) {
|
|
28709
|
+
this._elementsEfficiency = val;
|
|
28710
|
+
}
|
|
28711
|
+
/**
|
|
28712
|
+
* Retrieves a array of elements assigned to the player and the elements of the weapons / armor equipped
|
|
28713
|
+
*
|
|
28714
|
+
* Gets all offensive elements available to the player from equipped weapons and armor.
|
|
28715
|
+
* This determines what elemental damage types the player can deal in combat.
|
|
28716
|
+
* The system automatically combines elements from all equipped items and removes duplicates.
|
|
28717
|
+
*
|
|
28718
|
+
* @returns Array of element objects with rate and element properties for offensive capabilities
|
|
28719
|
+
*
|
|
28720
|
+
* @example
|
|
28721
|
+
* ```ts
|
|
28722
|
+
* // Get all offensive elements
|
|
28723
|
+
* console.log(player.elements); // [{ rate: 1.5, element: 'fire' }, { rate: 1.2, element: 'ice' }]
|
|
28724
|
+
*
|
|
28725
|
+
* // Check if player can deal fire damage
|
|
28726
|
+
* const hasFireElement = player.elements.some(el => el.element === 'fire');
|
|
28727
|
+
* if (hasFireElement) {
|
|
28728
|
+
* console.log('Player can deal fire damage');
|
|
28729
|
+
* }
|
|
28730
|
+
*
|
|
28731
|
+
* // Get strongest element
|
|
28732
|
+
* const strongestElement = player.elements.reduce((max, current) =>
|
|
28733
|
+
* current.rate > max.rate ? current : max
|
|
28734
|
+
* );
|
|
28735
|
+
* console.log(`Strongest element: ${strongestElement.element} (${strongestElement.rate})`);
|
|
28736
|
+
* ```
|
|
28737
|
+
*/
|
|
28738
|
+
get elements() {
|
|
28739
|
+
let elements = [];
|
|
28740
|
+
for (let item of this.equipments()) {
|
|
28741
|
+
if (item.elements) {
|
|
28742
|
+
elements = [...elements, ...item.elements];
|
|
28712
28743
|
}
|
|
28713
28744
|
}
|
|
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
|
-
};
|
|
28745
|
+
return arrayUniq(elements);
|
|
28726
28746
|
}
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
|
|
28747
|
+
/**
|
|
28748
|
+
* Calculate elemental damage coefficient against another player
|
|
28749
|
+
*
|
|
28750
|
+
* Determines the damage multiplier when this player attacks another player,
|
|
28751
|
+
* taking into account the attacker's offensive elements, the defender's
|
|
28752
|
+
* elemental efficiency, and elemental defense from equipment. This is used
|
|
28753
|
+
* in the battle system to calculate elemental damage modifiers.
|
|
28754
|
+
*
|
|
28755
|
+
* @param otherPlayer - The target player to calculate coefficient against
|
|
28756
|
+
* @returns Numerical coefficient to multiply base damage by
|
|
28757
|
+
*
|
|
28758
|
+
* @example
|
|
28759
|
+
* ```ts
|
|
28760
|
+
* // Calculate elemental damage coefficient
|
|
28761
|
+
* const firePlayer = new MyPlayer();
|
|
28762
|
+
* const icePlayer = new MyPlayer();
|
|
28763
|
+
*
|
|
28764
|
+
* // Fire player attacks ice player (assuming ice is weak to fire)
|
|
28765
|
+
* const coefficient = icePlayer.coefficientElements(firePlayer);
|
|
28766
|
+
* console.log(`Damage multiplier: ${coefficient}`); // e.g., 2.0 for double damage
|
|
28767
|
+
*
|
|
28768
|
+
* // Use in damage calculation
|
|
28769
|
+
* const baseDamage = 100;
|
|
28770
|
+
* const finalDamage = baseDamage * coefficient;
|
|
28771
|
+
* console.log(`Final damage: ${finalDamage}`);
|
|
28772
|
+
*
|
|
28773
|
+
* // Check for elemental advantage
|
|
28774
|
+
* if (coefficient > 1) {
|
|
28775
|
+
* console.log('Attacker has elemental advantage!');
|
|
28776
|
+
* } else if (coefficient < 1) {
|
|
28777
|
+
* console.log('Defender resists this element');
|
|
28778
|
+
* }
|
|
28779
|
+
* ```
|
|
28780
|
+
*/
|
|
28781
|
+
coefficientElements(otherPlayer) {
|
|
28782
|
+
const atkPlayerElements = otherPlayer.elements;
|
|
28783
|
+
const playerElements = this.elementsEfficiency;
|
|
28784
|
+
let coefficient = 1;
|
|
28785
|
+
for (let atkElement of atkPlayerElements) {
|
|
28786
|
+
const elementPlayer = playerElements.find(
|
|
28787
|
+
(el) => el.element == atkElement.element
|
|
28788
|
+
);
|
|
28789
|
+
const elementPlayerDef = this.elementsDefense.find(
|
|
28790
|
+
(el) => el.element == atkElement.element
|
|
28791
|
+
);
|
|
28792
|
+
if (!elementPlayer) continue;
|
|
28793
|
+
const fn = this.getFormulas("coefficientElements");
|
|
28794
|
+
if (!fn) {
|
|
28795
|
+
return coefficient;
|
|
28796
|
+
}
|
|
28797
|
+
coefficient += fn(
|
|
28798
|
+
atkElement,
|
|
28799
|
+
elementPlayer,
|
|
28800
|
+
elementPlayerDef || { rate: 0 }
|
|
28801
|
+
);
|
|
28802
|
+
}
|
|
28803
|
+
return coefficient;
|
|
28730
28804
|
}
|
|
28731
28805
|
};
|
|
28732
28806
|
}
|
|
@@ -28945,23 +29019,176 @@ function WithSkillManager(Base) {
|
|
|
28945
29019
|
};
|
|
28946
29020
|
}
|
|
28947
29021
|
|
|
29022
|
+
function WithBattleManager(Base) {
|
|
29023
|
+
return class extends Base {
|
|
29024
|
+
/**
|
|
29025
|
+
* Apply damage. Player will lose HP. the `attackerPlayer` parameter is the other player, the one who attacks.
|
|
29026
|
+
*
|
|
29027
|
+
* If you don't set the skill parameter, it will be a physical attack.
|
|
29028
|
+
* The attack formula is already defined but you can customize it in the server options.
|
|
29029
|
+
* This method handles all aspects of damage calculation including critical hits,
|
|
29030
|
+
* elemental vulnerabilities, guard effects, and applies the final damage to HP.
|
|
29031
|
+
*
|
|
29032
|
+
* @param attackerPlayer - The attacking player who deals the damage
|
|
29033
|
+
* @param skill - Optional skill object for magical attacks, if not provided uses physical attack
|
|
29034
|
+
* @returns Object containing damage details and special effects that occurred
|
|
29035
|
+
*
|
|
29036
|
+
* @example
|
|
29037
|
+
* ```ts
|
|
29038
|
+
* // Physical attack
|
|
29039
|
+
* const result = player.applyDamage(attackerPlayer);
|
|
29040
|
+
* console.log(`Physical damage: ${result.damage}, Critical: ${result.critical}`);
|
|
29041
|
+
*
|
|
29042
|
+
* // Magical attack with skill
|
|
29043
|
+
* const fireSkill = { id: 'fire', power: 50, element: 'fire' };
|
|
29044
|
+
* const magicResult = player.applyDamage(attackerPlayer, fireSkill);
|
|
29045
|
+
* console.log(`Magic damage: ${magicResult.damage}, Vulnerable: ${magicResult.elementVulnerable}`);
|
|
29046
|
+
*
|
|
29047
|
+
* // Check for guard effects
|
|
29048
|
+
* if (result.guard) {
|
|
29049
|
+
* console.log('Attack was partially blocked!');
|
|
29050
|
+
* }
|
|
29051
|
+
* if (result.superGuard) {
|
|
29052
|
+
* console.log('Attack was heavily reduced by super guard!');
|
|
29053
|
+
* }
|
|
29054
|
+
* ```
|
|
29055
|
+
*/
|
|
29056
|
+
applyDamage(attackerPlayer, skill) {
|
|
29057
|
+
const getParam = (player) => {
|
|
29058
|
+
const params = {};
|
|
29059
|
+
this.parameters.forEach((val, key) => {
|
|
29060
|
+
params[key] = player.param[key];
|
|
29061
|
+
});
|
|
29062
|
+
return {
|
|
29063
|
+
[ATK]: player.atk,
|
|
29064
|
+
[PDEF]: player.pdef,
|
|
29065
|
+
[SDEF]: player.sdef,
|
|
29066
|
+
...params
|
|
29067
|
+
};
|
|
29068
|
+
};
|
|
29069
|
+
let damage = 0, fn;
|
|
29070
|
+
let critical = false;
|
|
29071
|
+
let guard = false;
|
|
29072
|
+
let superGuard = false;
|
|
29073
|
+
let elementVulnerable = false;
|
|
29074
|
+
const paramA = getParam(attackerPlayer);
|
|
29075
|
+
const paramB = getParam(this);
|
|
29076
|
+
console.log(paramA, paramB);
|
|
29077
|
+
if (skill) {
|
|
29078
|
+
fn = this.getFormulas("damageSkill");
|
|
29079
|
+
if (!fn) {
|
|
29080
|
+
throw new Error("Skill Formulas not exists");
|
|
29081
|
+
}
|
|
29082
|
+
damage = fn(paramA, paramB, skill);
|
|
29083
|
+
} else {
|
|
29084
|
+
fn = this.getFormulas("damagePhysic");
|
|
29085
|
+
if (!fn) {
|
|
29086
|
+
throw new Error("Physic Formulas not exists");
|
|
29087
|
+
}
|
|
29088
|
+
damage = fn(paramA, paramB);
|
|
29089
|
+
const coef = this.coefficientElements(attackerPlayer);
|
|
29090
|
+
if (coef >= 2) {
|
|
29091
|
+
elementVulnerable = true;
|
|
29092
|
+
}
|
|
29093
|
+
damage *= coef;
|
|
29094
|
+
fn = this.getFormulas("damageCritical");
|
|
29095
|
+
if (fn) {
|
|
29096
|
+
let newDamage = fn(damage, paramA, paramB);
|
|
29097
|
+
if (damage != newDamage) {
|
|
29098
|
+
critical = true;
|
|
29099
|
+
}
|
|
29100
|
+
damage = newDamage;
|
|
29101
|
+
}
|
|
29102
|
+
}
|
|
29103
|
+
if (this.hasEffect(Effect.GUARD)) {
|
|
29104
|
+
fn = this.getFormulas("damageGuard");
|
|
29105
|
+
if (fn) {
|
|
29106
|
+
let newDamage = fn(damage, paramA, paramB);
|
|
29107
|
+
if (damage != newDamage) {
|
|
29108
|
+
guard = true;
|
|
29109
|
+
}
|
|
29110
|
+
damage = newDamage;
|
|
29111
|
+
}
|
|
29112
|
+
}
|
|
29113
|
+
if (this.hasEffect(Effect.SUPER_GUARD)) {
|
|
29114
|
+
damage /= 4;
|
|
29115
|
+
superGuard = true;
|
|
29116
|
+
}
|
|
29117
|
+
this.hp -= damage;
|
|
29118
|
+
return {
|
|
29119
|
+
damage,
|
|
29120
|
+
critical,
|
|
29121
|
+
elementVulnerable,
|
|
29122
|
+
guard,
|
|
29123
|
+
superGuard
|
|
29124
|
+
};
|
|
29125
|
+
}
|
|
29126
|
+
/**
|
|
29127
|
+
* Get damage formulas from the current map
|
|
29128
|
+
*
|
|
29129
|
+
* Retrieves the damage calculation formulas defined in the current map's configuration.
|
|
29130
|
+
* These formulas are used to calculate different types of damage including physical,
|
|
29131
|
+
* magical, critical hits, and guard effects. The formulas provide flexibility in
|
|
29132
|
+
* customizing the battle system's damage calculations.
|
|
29133
|
+
*
|
|
29134
|
+
* @param name - The name of the formula to retrieve (e.g., 'damagePhysic', 'damageSkill')
|
|
29135
|
+
* @returns The formula function or undefined if not found
|
|
29136
|
+
*
|
|
29137
|
+
* @example
|
|
29138
|
+
* ```ts
|
|
29139
|
+
* // Get physical damage formula
|
|
29140
|
+
* const physicFormula = player.getFormulas('damagePhysic');
|
|
29141
|
+
* if (physicFormula) {
|
|
29142
|
+
* const damage = physicFormula(attackerParams, defenderParams);
|
|
29143
|
+
* }
|
|
29144
|
+
*
|
|
29145
|
+
* // Get critical damage formula
|
|
29146
|
+
* const criticalFormula = player.getFormulas('damageCritical');
|
|
29147
|
+
* if (criticalFormula) {
|
|
29148
|
+
* const criticalDamage = criticalFormula(baseDamage, attackerParams, defenderParams);
|
|
29149
|
+
* }
|
|
29150
|
+
* ```
|
|
29151
|
+
*/
|
|
29152
|
+
getFormulas(name) {
|
|
29153
|
+
const map = this.getCurrentMap();
|
|
29154
|
+
return map.damageFormulas[name];
|
|
29155
|
+
}
|
|
29156
|
+
};
|
|
29157
|
+
}
|
|
29158
|
+
|
|
28948
29159
|
function WithClassManager(Base) {
|
|
28949
29160
|
return class extends Base {
|
|
28950
29161
|
/**
|
|
28951
29162
|
* Assign a class to the player
|
|
28952
29163
|
*
|
|
29164
|
+
* Sets the player's class, which defines their combat abilities, stat growth,
|
|
29165
|
+
* and available skills. The class system provides the foundation for character
|
|
29166
|
+
* progression and specialization. When a class is set, it automatically triggers
|
|
29167
|
+
* the class's onSet method for any additional initialization.
|
|
29168
|
+
*
|
|
29169
|
+
* @param _class - The class constructor or class ID to assign to the player
|
|
29170
|
+
* @returns The instantiated class object
|
|
29171
|
+
*
|
|
29172
|
+
* @example
|
|
28953
29173
|
* ```ts
|
|
28954
29174
|
* import { Fighter } from 'my-database/classes/fighter'
|
|
28955
29175
|
*
|
|
28956
|
-
*
|
|
29176
|
+
* // Set class using constructor
|
|
29177
|
+
* const fighterClass = player.setClass(Fighter);
|
|
29178
|
+
* console.log('Class set:', fighterClass.name);
|
|
29179
|
+
*
|
|
29180
|
+
* // Set class using string ID
|
|
29181
|
+
* player.setClass('fighter');
|
|
29182
|
+
*
|
|
29183
|
+
* // Class affects available skills and stats
|
|
29184
|
+
* console.log('Available skills:', player.skills);
|
|
29185
|
+
* console.log('Class bonuses applied to stats');
|
|
29186
|
+
*
|
|
29187
|
+
* // Class determines level progression
|
|
29188
|
+
* player.level = 5;
|
|
29189
|
+
* // Skills may be automatically learned based on class definition
|
|
28957
29190
|
* ```
|
|
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
|
-
* */
|
|
29191
|
+
*/
|
|
28965
29192
|
setClass(_class) {
|
|
28966
29193
|
if (isString(_class)) _class = this.databaseById(_class);
|
|
28967
29194
|
const classInstance = new _class();
|
|
@@ -28971,18 +29198,39 @@ function WithClassManager(Base) {
|
|
|
28971
29198
|
/**
|
|
28972
29199
|
* 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
29200
|
*
|
|
29201
|
+
* Sets up the player as a specific actor archetype, which includes predefined
|
|
29202
|
+
* characteristics like starting equipment, parameters, level ranges, and associated class.
|
|
29203
|
+
* This is typically used for creating pre-configured character templates or NPCs
|
|
29204
|
+
* with specific roles and equipment loadouts.
|
|
29205
|
+
*
|
|
29206
|
+
* @param actorClass - The actor constructor or actor ID to assign to the player
|
|
29207
|
+
* @returns The instantiated actor object
|
|
29208
|
+
*
|
|
29209
|
+
* @example
|
|
28974
29210
|
* ```ts
|
|
28975
29211
|
* import { Hero } from 'my-database/classes/hero'
|
|
28976
29212
|
*
|
|
28977
|
-
* player
|
|
29213
|
+
* // Set up player as Hero actor
|
|
29214
|
+
* const heroActor = player.setActor(Hero);
|
|
29215
|
+
* console.log('Actor configured:', heroActor.name);
|
|
29216
|
+
*
|
|
29217
|
+
* // Actor automatically sets up:
|
|
29218
|
+
* // - Starting equipment (sword, armor, etc.)
|
|
29219
|
+
* console.log('Starting equipment:', player.equipments());
|
|
29220
|
+
*
|
|
29221
|
+
* // - Parameter ranges and growth
|
|
29222
|
+
* console.log('Level range:', player.initialLevel, '-', player.finalLevel);
|
|
29223
|
+
*
|
|
29224
|
+
* // - Associated class
|
|
29225
|
+
* console.log('Assigned class:', player.class);
|
|
29226
|
+
*
|
|
29227
|
+
* // - Experience curve
|
|
29228
|
+
* console.log('EXP curve:', player.expCurve);
|
|
29229
|
+
*
|
|
29230
|
+
* // Actor setup is comprehensive
|
|
29231
|
+
* player.setActor('hero'); // Can also use string ID
|
|
28978
29232
|
* ```
|
|
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
|
-
* */
|
|
29233
|
+
*/
|
|
28986
29234
|
setActor(actorClass) {
|
|
28987
29235
|
if (isString(actorClass)) actorClass = this.databaseById(actorClass);
|
|
28988
29236
|
const actor = new actorClass();
|
|
@@ -29003,32 +29251,41 @@ function WithClassManager(Base) {
|
|
|
29003
29251
|
};
|
|
29004
29252
|
}
|
|
29005
29253
|
|
|
29006
|
-
function
|
|
29254
|
+
function WithStateManager(Base) {
|
|
29007
29255
|
return class extends Base {
|
|
29008
29256
|
constructor() {
|
|
29009
29257
|
super(...arguments);
|
|
29010
|
-
this.
|
|
29258
|
+
this._statesEfficiency = signal$2([]);
|
|
29011
29259
|
}
|
|
29012
29260
|
/**
|
|
29013
|
-
* Recovers the player's
|
|
29261
|
+
* Recovers the player's states defense on inventory. This list is generated from the `statesDefense` property defined on the weapons or armors equipped.
|
|
29014
29262
|
* If several items have the same element, only the highest rate will be taken into account.
|
|
29015
29263
|
*
|
|
29264
|
+
* Gets the defensive capabilities against various states from equipped items.
|
|
29265
|
+
* The system automatically consolidates multiple defensive items, keeping only
|
|
29266
|
+
* the highest protection rate for each state type. This provides comprehensive
|
|
29267
|
+
* protection against debuffs and negative status effects.
|
|
29268
|
+
*
|
|
29269
|
+
* @returns Array of state defense objects with rate and state properties
|
|
29270
|
+
*
|
|
29271
|
+
* @example
|
|
29016
29272
|
* ```ts
|
|
29017
|
-
* import { Armor } from '@rpgjs/server'
|
|
29273
|
+
* import { Armor, State } from '@rpgjs/server'
|
|
29018
29274
|
*
|
|
29019
|
-
*
|
|
29020
|
-
*
|
|
29021
|
-
* }
|
|
29275
|
+
* @State({
|
|
29276
|
+
* name: 'Paralyze'
|
|
29277
|
+
* })
|
|
29278
|
+
* class Paralyze {}
|
|
29022
29279
|
*
|
|
29023
29280
|
* @Armor({
|
|
29024
29281
|
* name: 'Shield',
|
|
29025
|
-
*
|
|
29282
|
+
* statesDefense: [{ rate: 1, state: Paralyze }]
|
|
29026
29283
|
* })
|
|
29027
29284
|
* class Shield {}
|
|
29028
29285
|
*
|
|
29029
29286
|
* @Armor({
|
|
29030
29287
|
* name: 'FireShield',
|
|
29031
|
-
*
|
|
29288
|
+
* statesDefense: [{ rate: 0.5, state: Paralyze }]
|
|
29032
29289
|
* })
|
|
29033
29290
|
* class FireShield {}
|
|
29034
29291
|
*
|
|
@@ -29037,100 +29294,291 @@ function WithElementManager(Base) {
|
|
|
29037
29294
|
* player.equip(Shield)
|
|
29038
29295
|
* player.equip(FireShield)
|
|
29039
29296
|
*
|
|
29040
|
-
* console.log(player.
|
|
29297
|
+
* console.log(player.statesDefense) // [{ rate: 1, state: instance of Paralyze }]
|
|
29298
|
+
*
|
|
29299
|
+
* // Check specific state defense
|
|
29300
|
+
* const paralyzeDefense = player.statesDefense.find(def => def.state instanceof Paralyze);
|
|
29301
|
+
* if (paralyzeDefense) {
|
|
29302
|
+
* console.log(`Paralyze defense rate: ${paralyzeDefense.rate}`);
|
|
29303
|
+
* }
|
|
29041
29304
|
* ```
|
|
29042
|
-
|
|
29043
|
-
|
|
29044
|
-
|
|
29045
|
-
* @memberof ElementManager
|
|
29046
|
-
* */
|
|
29047
|
-
get elementsDefense() {
|
|
29048
|
-
return this.getFeature("elementsDefense", "element");
|
|
29305
|
+
*/
|
|
29306
|
+
get statesDefense() {
|
|
29307
|
+
return this.getFeature("statesDefense", "state");
|
|
29049
29308
|
}
|
|
29050
29309
|
/**
|
|
29051
|
-
* Set or retrieves all the
|
|
29310
|
+
* Set or retrieves all the states where the player is vulnerable or not.
|
|
29052
29311
|
*
|
|
29312
|
+
* Manages the player's state efficiency modifiers, which determine how
|
|
29313
|
+
* effective different states are against this player. Values greater than 1
|
|
29314
|
+
* indicate vulnerability, while values less than 1 indicate resistance.
|
|
29315
|
+
* This combines both class-based efficiency and player-specific modifiers.
|
|
29316
|
+
*
|
|
29317
|
+
* @returns Array of state efficiency objects with rate and state properties
|
|
29318
|
+
*
|
|
29319
|
+
* @example
|
|
29053
29320
|
* ```ts
|
|
29054
|
-
* import { Class } from '@rpgjs/server'
|
|
29321
|
+
* import { Class, State } from '@rpgjs/server'
|
|
29055
29322
|
*
|
|
29056
|
-
*
|
|
29057
|
-
*
|
|
29058
|
-
*
|
|
29059
|
-
* }
|
|
29323
|
+
* @State({
|
|
29324
|
+
* name: 'Paralyze'
|
|
29325
|
+
* })
|
|
29326
|
+
* class Paralyze {}
|
|
29327
|
+
*
|
|
29328
|
+
* @State({
|
|
29329
|
+
* name: 'Sleep'
|
|
29330
|
+
* })
|
|
29331
|
+
* class Sleep {}
|
|
29060
29332
|
*
|
|
29061
29333
|
* @Class({
|
|
29062
29334
|
* name: 'Fighter',
|
|
29063
|
-
*
|
|
29335
|
+
* statesEfficiency: [{ rate: 1, state: Paralyze }]
|
|
29064
29336
|
* })
|
|
29065
29337
|
* class Hero {}
|
|
29066
29338
|
*
|
|
29067
29339
|
* player.setClass(Hero)
|
|
29068
29340
|
*
|
|
29069
|
-
* console.log(player.
|
|
29341
|
+
* console.log(player.statesEfficiency) // [{ rate: 1, instance of Paralyze }]
|
|
29070
29342
|
*
|
|
29071
|
-
* player.
|
|
29343
|
+
* player.statesEfficiency = [{ rate: 2, state: Sleep }]
|
|
29072
29344
|
*
|
|
29073
|
-
* console.log(player.
|
|
29345
|
+
* console.log(player.statesEfficiency) // [{ rate: 1, state: instance of Paralyze }, { rate: 2, state: instance of Sleep }]
|
|
29346
|
+
*
|
|
29347
|
+
* // Check for vulnerabilities
|
|
29348
|
+
* const vulnerabilities = player.statesEfficiency.filter(eff => eff.rate > 1);
|
|
29349
|
+
* console.log('Vulnerable to states:', vulnerabilities.map(v => v.state.name));
|
|
29350
|
+
*
|
|
29351
|
+
* // Check for resistances
|
|
29352
|
+
* const resistances = player.statesEfficiency.filter(eff => eff.rate < 1);
|
|
29353
|
+
* console.log('Resistant to states:', resistances.map(r => r.state.name));
|
|
29074
29354
|
* ```
|
|
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;
|
|
29355
|
+
*/
|
|
29356
|
+
get statesEfficiency() {
|
|
29357
|
+
return this._statesEfficiency;
|
|
29087
29358
|
}
|
|
29088
|
-
set
|
|
29089
|
-
this.
|
|
29359
|
+
set statesEfficiency(val) {
|
|
29360
|
+
this._statesEfficiency = val;
|
|
29090
29361
|
}
|
|
29091
29362
|
/**
|
|
29092
|
-
*
|
|
29363
|
+
* Apply states to a player from skill or item effects
|
|
29364
|
+
*
|
|
29365
|
+
* Processes state application and removal based on skill or item effects.
|
|
29366
|
+
* This method handles both adding beneficial states and removing negative ones,
|
|
29367
|
+
* with proper chance calculation and resistance checks.
|
|
29368
|
+
*
|
|
29369
|
+
* @param player - The target player to apply states to
|
|
29370
|
+
* @param states - Object containing arrays of states to add or remove
|
|
29371
|
+
*
|
|
29372
|
+
* @example
|
|
29373
|
+
* ```ts
|
|
29374
|
+
* // Apply states from a healing skill
|
|
29375
|
+
* const healingStates = {
|
|
29376
|
+
* addStates: [{ state: Regeneration, rate: 0.8 }],
|
|
29377
|
+
* removeStates: [{ state: Poison, rate: 1.0 }]
|
|
29378
|
+
* };
|
|
29379
|
+
* player.applyStates(targetPlayer, healingStates);
|
|
29380
|
+
*
|
|
29381
|
+
* // Apply debuff from an enemy attack
|
|
29382
|
+
* const debuffStates = {
|
|
29383
|
+
* addStates: [
|
|
29384
|
+
* { state: Paralyze, rate: 0.3 },
|
|
29385
|
+
* { state: Slow, rate: 0.5 }
|
|
29386
|
+
* ]
|
|
29387
|
+
* };
|
|
29388
|
+
* player.applyStates(targetPlayer, debuffStates);
|
|
29389
|
+
* ```
|
|
29390
|
+
*/
|
|
29391
|
+
applyStates(player, { addStates, removeStates }) {
|
|
29392
|
+
if (addStates) {
|
|
29393
|
+
for (let { state, rate } of addStates) {
|
|
29394
|
+
player.addState(state, rate);
|
|
29395
|
+
}
|
|
29396
|
+
}
|
|
29397
|
+
if (removeStates) {
|
|
29398
|
+
for (let { state, rate } of removeStates) {
|
|
29399
|
+
player.removeState(state, rate);
|
|
29400
|
+
}
|
|
29401
|
+
}
|
|
29402
|
+
}
|
|
29403
|
+
/**
|
|
29404
|
+
* Get a state to the player. Returns `null` if the state is not present on the player
|
|
29405
|
+
*
|
|
29406
|
+
* Retrieves a specific state instance from the player's active states.
|
|
29407
|
+
* This is useful for checking state properties, duration, or performing
|
|
29408
|
+
* state-specific operations. Returns null if the state is not currently active.
|
|
29409
|
+
*
|
|
29410
|
+
* @param stateClass - The state class constructor or state ID to search for
|
|
29411
|
+
* @returns The state instance if found, null otherwise
|
|
29412
|
+
*
|
|
29413
|
+
* @example
|
|
29414
|
+
* ```ts
|
|
29415
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29093
29416
|
*
|
|
29417
|
+
* // Check if player has a specific state
|
|
29418
|
+
* const paralyzeState = player.getState(Paralyze);
|
|
29419
|
+
* if (paralyzeState) {
|
|
29420
|
+
* console.log('Player is paralyzed');
|
|
29421
|
+
* console.log('Remaining duration:', paralyzeState.duration);
|
|
29422
|
+
* }
|
|
29423
|
+
*
|
|
29424
|
+
* // Check using string ID
|
|
29425
|
+
* const poisonState = player.getState('poison');
|
|
29426
|
+
* if (poisonState) {
|
|
29427
|
+
* console.log('Player is poisoned');
|
|
29428
|
+
* }
|
|
29429
|
+
*
|
|
29430
|
+
* // Use in conditional logic
|
|
29431
|
+
* if (player.getState(Sleep)) {
|
|
29432
|
+
* console.log('Player cannot act while sleeping');
|
|
29433
|
+
* return; // Skip player turn
|
|
29434
|
+
* }
|
|
29435
|
+
* ```
|
|
29436
|
+
*/
|
|
29437
|
+
getState(stateClass) {
|
|
29438
|
+
if (isString(stateClass)) stateClass = this.databaseById(stateClass);
|
|
29439
|
+
return this.states().find((state) => {
|
|
29440
|
+
if (isString(stateClass)) {
|
|
29441
|
+
return state.id == stateClass;
|
|
29442
|
+
}
|
|
29443
|
+
return isInstanceOf(state, stateClass);
|
|
29444
|
+
});
|
|
29445
|
+
}
|
|
29446
|
+
/**
|
|
29447
|
+
* Adds a state to the player. Set the chance between 0 and 1 that the state can apply
|
|
29448
|
+
*
|
|
29449
|
+
* Attempts to apply a state to the player with a specified success chance.
|
|
29450
|
+
* The method considers state resistance, efficiency modifiers, and random chance
|
|
29451
|
+
* to determine if the state is successfully applied. If successful, the state
|
|
29452
|
+
* is added to the player's active states list.
|
|
29453
|
+
*
|
|
29454
|
+
* @param stateClass - The state class constructor or state ID to apply
|
|
29455
|
+
* @param chance - Probability of successful application (0-1, default 1)
|
|
29456
|
+
* @returns The state instance if successfully applied, null if already present
|
|
29457
|
+
* @throws StateLog.addFailed if the chance roll fails
|
|
29458
|
+
*
|
|
29459
|
+
* @example
|
|
29094
29460
|
* ```ts
|
|
29095
|
-
*
|
|
29461
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29462
|
+
*
|
|
29463
|
+
* try {
|
|
29464
|
+
* // Attempt to apply paralyze with 100% chance
|
|
29465
|
+
* const state = player.addState(Paralyze);
|
|
29466
|
+
* if (state) {
|
|
29467
|
+
* console.log('Paralyze applied successfully');
|
|
29468
|
+
* }
|
|
29469
|
+
* } catch (err) {
|
|
29470
|
+
* console.log('Failed to apply paralyze:', err.msg);
|
|
29471
|
+
* }
|
|
29472
|
+
*
|
|
29473
|
+
* // Apply with reduced chance
|
|
29474
|
+
* try {
|
|
29475
|
+
* player.addState(Poison, 0.3); // 30% chance
|
|
29476
|
+
* } catch (err) {
|
|
29477
|
+
* console.log('Poison application failed');
|
|
29478
|
+
* }
|
|
29479
|
+
*
|
|
29480
|
+
* // Apply multiple states with different chances
|
|
29481
|
+
* const debuffs = [
|
|
29482
|
+
* { state: Slow, chance: 0.8 },
|
|
29483
|
+
* { state: Weak, chance: 0.6 }
|
|
29484
|
+
* ];
|
|
29485
|
+
* debuffs.forEach(({ state, chance }) => {
|
|
29486
|
+
* try {
|
|
29487
|
+
* player.addState(state, chance);
|
|
29488
|
+
* } catch (err) {
|
|
29489
|
+
* // Handle failed applications
|
|
29490
|
+
* }
|
|
29491
|
+
* });
|
|
29096
29492
|
* ```
|
|
29097
|
-
|
|
29098
|
-
|
|
29099
|
-
|
|
29100
|
-
|
|
29101
|
-
|
|
29102
|
-
|
|
29103
|
-
|
|
29104
|
-
|
|
29105
|
-
|
|
29106
|
-
elements = [...elements, ...item.elements];
|
|
29493
|
+
*/
|
|
29494
|
+
addState(stateClass, chance = 1) {
|
|
29495
|
+
const state = this.getState(stateClass);
|
|
29496
|
+
if (isString(stateClass)) {
|
|
29497
|
+
stateClass = this.databaseById(stateClass);
|
|
29498
|
+
}
|
|
29499
|
+
if (!state) {
|
|
29500
|
+
if (Math.random() > chance) {
|
|
29501
|
+
throw StateLog.addFailed(stateClass);
|
|
29107
29502
|
}
|
|
29503
|
+
const instance = new stateClass();
|
|
29504
|
+
this.states().push(instance);
|
|
29505
|
+
this.applyStates(this, instance);
|
|
29506
|
+
return instance;
|
|
29108
29507
|
}
|
|
29109
|
-
return
|
|
29508
|
+
return null;
|
|
29110
29509
|
}
|
|
29111
|
-
|
|
29112
|
-
|
|
29113
|
-
|
|
29114
|
-
|
|
29115
|
-
|
|
29116
|
-
|
|
29117
|
-
|
|
29118
|
-
|
|
29119
|
-
|
|
29120
|
-
|
|
29121
|
-
|
|
29122
|
-
|
|
29123
|
-
|
|
29124
|
-
|
|
29125
|
-
|
|
29510
|
+
/**
|
|
29511
|
+
* Remove a state to the player. Set the chance between 0 and 1 that the state can be removed
|
|
29512
|
+
*
|
|
29513
|
+
* Attempts to remove a state from the player with a specified success chance.
|
|
29514
|
+
* This is useful for cure spells, items, or time-based state removal.
|
|
29515
|
+
* The method considers removal resistance and random chance.
|
|
29516
|
+
*
|
|
29517
|
+
* @param stateClass - The state class constructor or state ID to remove
|
|
29518
|
+
* @param chance - Probability of successful removal (0-1, default 1)
|
|
29519
|
+
* @throws StateLog.removeFailed if the chance roll fails
|
|
29520
|
+
* @throws StateLog.notApplied if the state is not currently active
|
|
29521
|
+
*
|
|
29522
|
+
* @example
|
|
29523
|
+
* ```ts
|
|
29524
|
+
* import Paralyze from 'your-database/states/paralyze'
|
|
29525
|
+
*
|
|
29526
|
+
* try {
|
|
29527
|
+
* // Attempt to remove paralyze with 100% chance
|
|
29528
|
+
* player.removeState(Paralyze);
|
|
29529
|
+
* console.log('Paralyze removed successfully');
|
|
29530
|
+
* } catch (err) {
|
|
29531
|
+
* if (err.id === 'STATE_NOT_APPLIED') {
|
|
29532
|
+
* console.log('Player was not paralyzed');
|
|
29533
|
+
* } else {
|
|
29534
|
+
* console.log('Failed to remove paralyze:', err.msg);
|
|
29535
|
+
* }
|
|
29536
|
+
* }
|
|
29537
|
+
*
|
|
29538
|
+
* // Remove with reduced chance (for weak cure spells)
|
|
29539
|
+
* try {
|
|
29540
|
+
* player.removeState(Poison, 0.7); // 70% chance
|
|
29541
|
+
* } catch (err) {
|
|
29542
|
+
* console.log('Cure failed');
|
|
29543
|
+
* }
|
|
29544
|
+
*
|
|
29545
|
+
* // Remove all negative states (cure-all effect)
|
|
29546
|
+
* const negativeStates = [Poison, Paralyze, Sleep, Slow];
|
|
29547
|
+
* negativeStates.forEach(state => {
|
|
29548
|
+
* try {
|
|
29549
|
+
* player.removeState(state);
|
|
29550
|
+
* } catch (err) {
|
|
29551
|
+
* // State wasn't active, continue
|
|
29552
|
+
* }
|
|
29553
|
+
* });
|
|
29554
|
+
* ```
|
|
29555
|
+
*/
|
|
29556
|
+
removeState(stateClass, chance = 1) {
|
|
29557
|
+
const index = this.states().findIndex((state) => {
|
|
29558
|
+
if (isString(stateClass)) {
|
|
29559
|
+
return state.id == stateClass;
|
|
29126
29560
|
}
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
|
|
29131
|
-
|
|
29561
|
+
return isInstanceOf(state, stateClass);
|
|
29562
|
+
});
|
|
29563
|
+
if (index != -1) {
|
|
29564
|
+
if (Math.random() > chance) {
|
|
29565
|
+
throw StateLog.removeFailed(stateClass);
|
|
29566
|
+
}
|
|
29567
|
+
this.states().splice(index, 1);
|
|
29568
|
+
} else {
|
|
29569
|
+
throw StateLog.notApplied(stateClass);
|
|
29132
29570
|
}
|
|
29133
|
-
|
|
29571
|
+
}
|
|
29572
|
+
/**
|
|
29573
|
+
* Find state efficiency modifier for a specific state class
|
|
29574
|
+
*
|
|
29575
|
+
* @param stateClass - The state class to find efficiency for
|
|
29576
|
+
* @returns The efficiency object if found, undefined otherwise
|
|
29577
|
+
*/
|
|
29578
|
+
findStateEfficiency(stateClass) {
|
|
29579
|
+
return this.statesEfficiency().find(
|
|
29580
|
+
(state) => isInstanceOf(state.state, stateClass)
|
|
29581
|
+
);
|
|
29134
29582
|
}
|
|
29135
29583
|
};
|
|
29136
29584
|
}
|
|
@@ -29147,23 +29595,23 @@ var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
|
29147
29595
|
function combinePlayerMixins(mixins) {
|
|
29148
29596
|
return (Base) => mixins.reduce((ExtendedClass, mixin) => mixin(ExtendedClass), Base);
|
|
29149
29597
|
}
|
|
29150
|
-
const
|
|
29598
|
+
const BasicPlayerMixins = combinePlayerMixins([
|
|
29151
29599
|
WithComponentManager,
|
|
29152
29600
|
WithEffectManager,
|
|
29153
29601
|
WithGuiManager,
|
|
29154
29602
|
WithMoveManager,
|
|
29155
29603
|
WithGoldManager,
|
|
29156
|
-
WithVariableManager,
|
|
29157
29604
|
WithParameterManager,
|
|
29158
29605
|
WithItemFixture,
|
|
29159
|
-
WithStateManager,
|
|
29160
29606
|
WithItemManager,
|
|
29161
|
-
|
|
29607
|
+
WithElementManager,
|
|
29608
|
+
WithVariableManager,
|
|
29609
|
+
WithStateManager,
|
|
29162
29610
|
WithClassManager,
|
|
29163
|
-
|
|
29164
|
-
|
|
29611
|
+
WithSkillManager,
|
|
29612
|
+
WithBattleManager
|
|
29165
29613
|
]);
|
|
29166
|
-
const _RpgPlayer = class _RpgPlayer extends
|
|
29614
|
+
const _RpgPlayer = class _RpgPlayer extends BasicPlayerMixins(RpgCommonPlayer) {
|
|
29167
29615
|
constructor() {
|
|
29168
29616
|
super();
|
|
29169
29617
|
this.map = null;
|