@rpgjs/server 5.0.0-alpha.32 → 5.0.0-alpha.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Gui/ShopGui.d.ts +5 -1
- package/dist/Player/ItemManager.d.ts +8 -9
- package/dist/index.js +19 -12
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/Gui/ShopGui.ts +4 -3
- package/src/Player/ClassManager.ts +7 -4
- package/src/Player/ItemManager.ts +21 -18
- package/tests/item.spec.ts +19 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpgjs/server",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.33",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"publishConfig": {
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"description": "",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@rpgjs/common": "5.0.0-alpha.
|
|
15
|
-
"@rpgjs/physic": "5.0.0-alpha.
|
|
16
|
-
"@rpgjs/testing": "5.0.0-alpha.
|
|
14
|
+
"@rpgjs/common": "5.0.0-alpha.33",
|
|
15
|
+
"@rpgjs/physic": "5.0.0-alpha.33",
|
|
16
|
+
"@rpgjs/testing": "5.0.0-alpha.33",
|
|
17
17
|
"@rpgjs/database": "^4.3.0",
|
|
18
|
-
"@signe/di": "^2.8.
|
|
19
|
-
"@signe/reactive": "^2.8.
|
|
20
|
-
"@signe/room": "^2.8.
|
|
21
|
-
"@signe/sync": "^2.8.
|
|
18
|
+
"@signe/di": "^2.8.3",
|
|
19
|
+
"@signe/reactive": "^2.8.3",
|
|
20
|
+
"@signe/room": "^2.8.3",
|
|
21
|
+
"@signe/sync": "^2.8.3",
|
|
22
22
|
"rxjs": "^7.8.2",
|
|
23
23
|
"zod": "^4.3.5"
|
|
24
24
|
},
|
package/src/Gui/ShopGui.ts
CHANGED
|
@@ -3,9 +3,10 @@ import { Gui } from './Gui'
|
|
|
3
3
|
import { RpgPlayer } from '../Player/Player'
|
|
4
4
|
|
|
5
5
|
export type ShopSellList = Record<string, number> | Array<{ id: string; multiplier: number }>
|
|
6
|
+
export type ShopItemInput = string | { id?: string; [key: string]: any }
|
|
6
7
|
|
|
7
8
|
export interface ShopGuiOptions {
|
|
8
|
-
items:
|
|
9
|
+
items: ShopItemInput[]
|
|
9
10
|
sell?: ShopSellList
|
|
10
11
|
sellMultiplier?: number
|
|
11
12
|
message?: string
|
|
@@ -16,7 +17,7 @@ export interface ShopGuiOptions {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export class ShopGui extends Gui {
|
|
19
|
-
private itemsInput:
|
|
20
|
+
private itemsInput: ShopItemInput[] = []
|
|
20
21
|
private sellMultipliers: Record<string, number> = {}
|
|
21
22
|
private baseSellMultiplier = 0.5
|
|
22
23
|
private messageInput?: string
|
|
@@ -65,7 +66,7 @@ export class ShopGui extends Gui {
|
|
|
65
66
|
return undefined
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
const buildItemData = (item, overrides: { price?: number; quantity?: number } = {}) => {
|
|
69
|
+
const buildItemData = (item: ShopItemInput, overrides: { price?: number; quantity?: number } = {}) => {
|
|
69
70
|
const rawId = typeof item === 'string'
|
|
70
71
|
? item
|
|
71
72
|
: (typeof item?.id === 'function' ? item.id() : (item?.id ?? item?.name))
|
|
@@ -6,8 +6,8 @@ type ActorClass = any;
|
|
|
6
6
|
interface PlayerWithMixins extends RpgCommonPlayer {
|
|
7
7
|
databaseById(id: string): any;
|
|
8
8
|
addParameter(name: string, { start, end }: { start: number, end: number }): void;
|
|
9
|
-
addItem(item: any):
|
|
10
|
-
equip(
|
|
9
|
+
addItem(item: any): any;
|
|
10
|
+
equip(itemId: string, equip?: boolean | 'auto'): void;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -108,8 +108,11 @@ export function WithClassManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
108
108
|
(this as any).addParameter(param, actor.parameters[param]);
|
|
109
109
|
}
|
|
110
110
|
for (let item of actor.startingEquipment) {
|
|
111
|
-
(this as any).addItem(item);
|
|
112
|
-
|
|
111
|
+
const inventory = (this as any).addItem(item);
|
|
112
|
+
const itemId = inventory?.id?.();
|
|
113
|
+
if (itemId) {
|
|
114
|
+
(this as any).equip(itemId, true);
|
|
115
|
+
}
|
|
113
116
|
}
|
|
114
117
|
if (actor.class) this.setClass(actor.class);
|
|
115
118
|
(this as any)["execMethod"]("onSet", [this], actor);
|
|
@@ -581,15 +581,19 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
581
581
|
}
|
|
582
582
|
|
|
583
583
|
equip(
|
|
584
|
-
|
|
585
|
-
equip: boolean = true
|
|
584
|
+
itemId: string,
|
|
585
|
+
equip: boolean | 'auto' = true
|
|
586
586
|
): void {
|
|
587
|
-
const
|
|
588
|
-
const
|
|
587
|
+
const autoAdd = equip === 'auto';
|
|
588
|
+
const equipState = equip === 'auto' ? true : equip;
|
|
589
|
+
const data = (this as any).databaseById(itemId);
|
|
590
|
+
let inventory: Item = this.getItem(itemId);
|
|
591
|
+
if (!inventory && autoAdd) {
|
|
592
|
+
inventory = this.addItem(itemId, 1);
|
|
593
|
+
}
|
|
589
594
|
if (!inventory) {
|
|
590
595
|
throw ItemLog.notInInventory(itemId);
|
|
591
596
|
}
|
|
592
|
-
const data = (this as any).databaseById(itemId);
|
|
593
597
|
if (data._type == "item") {
|
|
594
598
|
throw ItemLog.invalidToEquiped(itemId);
|
|
595
599
|
}
|
|
@@ -607,11 +611,11 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
607
611
|
|
|
608
612
|
const item = inventory;
|
|
609
613
|
|
|
610
|
-
if ((item as any).equipped &&
|
|
614
|
+
if ((item as any).equipped && equipState) {
|
|
611
615
|
throw ItemLog.isAlreadyEquiped(itemId);
|
|
612
616
|
}
|
|
613
|
-
(item as any).equipped =
|
|
614
|
-
if (!
|
|
617
|
+
(item as any).equipped = equipState;
|
|
618
|
+
if (!equipState) {
|
|
615
619
|
const index = this.equipments().findIndex((it) => it.id() == item.id());
|
|
616
620
|
this.equipments().splice(index, 1);
|
|
617
621
|
} else {
|
|
@@ -619,7 +623,7 @@ export function WithItemManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
619
623
|
}
|
|
620
624
|
// Call onEquip hook - use stored instance if available
|
|
621
625
|
const hookTarget = (item as any)._itemInstance || item;
|
|
622
|
-
this["execMethod"]("onEquip", [this,
|
|
626
|
+
this["execMethod"]("onEquip", [this, equipState], hookTarget);
|
|
623
627
|
}
|
|
624
628
|
} as unknown as TBase;
|
|
625
629
|
}
|
|
@@ -852,12 +856,13 @@ export interface IItemManager {
|
|
|
852
856
|
/**
|
|
853
857
|
* Equips a weapon or armor on a player
|
|
854
858
|
*
|
|
855
|
-
* Think first to add the item in the inventory with the `addItem()` method before equipping the item
|
|
859
|
+
* Think first to add the item in the inventory with the `addItem()` method before equipping the item,
|
|
860
|
+
* or pass `"auto"` to add the item if it is missing and equip it.
|
|
856
861
|
*
|
|
857
862
|
* The `onEquip()` method is called on the ItemClass when the item is equipped or unequipped.
|
|
858
863
|
*
|
|
859
|
-
* @param
|
|
860
|
-
* @param equip - Equip the item if `true`, unequip if `false` (default: `true`)
|
|
864
|
+
* @param itemId - Item identifier to resolve from the database
|
|
865
|
+
* @param equip - Equip the item if `true`, unequip if `false`, or `"auto"` to add then equip (default: `true`)
|
|
861
866
|
* @throws {Object} ItemLog.notInInventory - If the item is not in the inventory
|
|
862
867
|
* - `id`: `ITEM_NOT_INVENTORY`
|
|
863
868
|
* - `msg`: Error message
|
|
@@ -870,19 +875,17 @@ export interface IItemManager {
|
|
|
870
875
|
*
|
|
871
876
|
* @example
|
|
872
877
|
* ```ts
|
|
873
|
-
* import Sword from 'your-database/sword'
|
|
874
|
-
*
|
|
875
878
|
* try {
|
|
876
|
-
* player.addItem(
|
|
877
|
-
* player.equip(
|
|
879
|
+
* player.addItem('sword')
|
|
880
|
+
* player.equip('sword')
|
|
878
881
|
* // Later, unequip it
|
|
879
|
-
* player.equip(
|
|
882
|
+
* player.equip('sword', false)
|
|
880
883
|
* } catch (err) {
|
|
881
884
|
* console.log(err)
|
|
882
885
|
* }
|
|
883
886
|
* ```
|
|
884
887
|
*/
|
|
885
|
-
equip(
|
|
888
|
+
equip(itemId: string, equip?: boolean | 'auto'): void;
|
|
886
889
|
|
|
887
890
|
/**
|
|
888
891
|
* Get the player's attack (sum of items equipped)
|
package/tests/item.spec.ts
CHANGED
|
@@ -385,6 +385,24 @@ describe("Item Management - Equipment", () => {
|
|
|
385
385
|
expect((item as any).equipped).toBe(true);
|
|
386
386
|
});
|
|
387
387
|
|
|
388
|
+
test("should auto add and equip item", () => {
|
|
389
|
+
player.equip("TestSword", "auto");
|
|
390
|
+
const item = player.getItem("TestSword");
|
|
391
|
+
expect(item).toBeDefined();
|
|
392
|
+
expect(item?.quantity()).toBe(1);
|
|
393
|
+
expect((item as any).equipped).toBe(true);
|
|
394
|
+
expect(player.equipments().some((eq) => eq.id() === "TestSword")).toBe(
|
|
395
|
+
true
|
|
396
|
+
);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test("should not add duplicate when auto equipping existing item", () => {
|
|
400
|
+
player.addItem("TestSword", 2);
|
|
401
|
+
player.equip("TestSword", "auto");
|
|
402
|
+
const item = player.getItem("TestSword");
|
|
403
|
+
expect(item?.quantity()).toBe(2);
|
|
404
|
+
});
|
|
405
|
+
|
|
388
406
|
test("should throw error when equipping non-existent item", () => {
|
|
389
407
|
expect(() => {
|
|
390
408
|
player.equip("TestSword", true);
|
|
@@ -588,4 +606,4 @@ describe("Item Management - Edge Cases", () => {
|
|
|
588
606
|
expect(player.getItem("TestSword")?.quantity()).toBe(1);
|
|
589
607
|
expect(player.getItem("TestArmor")?.quantity()).toBe(2);
|
|
590
608
|
});
|
|
591
|
-
});
|
|
609
|
+
});
|