@rpgjs/server 5.0.0-alpha.31 → 5.0.0-alpha.32
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/RpgServer.d.ts +2 -2
- package/dist/index.js +96 -42
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/Gui/MenuGui.ts +1 -1
- package/src/Player/MoveManager.ts +98 -48
- package/src/Player/ParameterManager.ts +1 -3
- package/src/RpgServer.ts +2 -2
- package/src/module.ts +12 -6
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.32",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"publishConfig": {
|
|
@@ -11,9 +11,9 @@
|
|
|
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.32",
|
|
15
|
+
"@rpgjs/physic": "5.0.0-alpha.32",
|
|
16
|
+
"@rpgjs/testing": "5.0.0-alpha.32",
|
|
17
17
|
"@rpgjs/database": "^4.3.0",
|
|
18
18
|
"@signe/di": "^2.8.2",
|
|
19
19
|
"@signe/reactive": "^2.8.2",
|
package/src/Gui/MenuGui.ts
CHANGED
|
@@ -119,7 +119,7 @@ export class MenuGui extends Gui {
|
|
|
119
119
|
}))
|
|
120
120
|
const saveLoad = this.buildSaveLoad(options)
|
|
121
121
|
|
|
122
|
-
return { menus, items, equips: menuEquips, skills, saveLoad, playerStats: buildStats() }
|
|
122
|
+
return { menus, items, equips: menuEquips, skills, saveLoad, playerStats: buildStats(), expForNextlevel: player.expForNextlevel }
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
private refreshMenu(clientActionId?: string) {
|
|
@@ -1183,6 +1183,9 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1183
1183
|
private readonly onStuck?: MoveRoutesOptions['onStuck'];
|
|
1184
1184
|
private readonly stuckTimeout: number;
|
|
1185
1185
|
private readonly stuckThreshold: number;
|
|
1186
|
+
private remainingDistance = 0;
|
|
1187
|
+
private segmentDirection: Direction | null = null;
|
|
1188
|
+
private segmentStep = 0;
|
|
1186
1189
|
|
|
1187
1190
|
// Frequency wait state
|
|
1188
1191
|
private waitingForFrequency = false;
|
|
@@ -1224,6 +1227,9 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1224
1227
|
// Reset frequency wait state when processing a new route
|
|
1225
1228
|
this.waitingForFrequency = false;
|
|
1226
1229
|
this.frequencyWaitStartTime = 0;
|
|
1230
|
+
this.remainingDistance = 0;
|
|
1231
|
+
this.segmentDirection = null;
|
|
1232
|
+
this.segmentStep = 0;
|
|
1227
1233
|
|
|
1228
1234
|
// Check if we've completed all routes
|
|
1229
1235
|
if (this.routeIndex >= this.routes.length) {
|
|
@@ -1328,52 +1334,15 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1328
1334
|
}
|
|
1329
1335
|
}
|
|
1330
1336
|
|
|
1331
|
-
//
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
case Direction.Right:
|
|
1337
|
-
case 'right' as any:
|
|
1338
|
-
targetTopLeftX = currentTopLeftX + distance;
|
|
1339
|
-
break;
|
|
1340
|
-
case Direction.Left:
|
|
1341
|
-
case 'left' as any:
|
|
1342
|
-
targetTopLeftX = currentTopLeftX - distance;
|
|
1343
|
-
break;
|
|
1344
|
-
case Direction.Down:
|
|
1345
|
-
case 'down' as any:
|
|
1346
|
-
targetTopLeftY = currentTopLeftY + distance;
|
|
1347
|
-
break;
|
|
1348
|
-
case Direction.Up:
|
|
1349
|
-
case 'up' as any:
|
|
1350
|
-
targetTopLeftY = currentTopLeftY - distance;
|
|
1351
|
-
break;
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
// Convert target top-left to center position for physics engine
|
|
1355
|
-
// Get entity to access hitbox dimensions
|
|
1356
|
-
const entity = map.physic.getEntityByUUID(this.player.id);
|
|
1357
|
-
if (!entity) {
|
|
1358
|
-
this.finished = true;
|
|
1359
|
-
this.onComplete(false);
|
|
1360
|
-
return;
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
// Get hitbox dimensions for conversion
|
|
1364
|
-
const hitbox = this.player.hitbox();
|
|
1365
|
-
const hitboxWidth = hitbox?.w ?? 32;
|
|
1366
|
-
const hitboxHeight = hitbox?.h ?? 32;
|
|
1367
|
-
|
|
1368
|
-
// Convert top-left to center: center = topLeft + (size / 2)
|
|
1369
|
-
const targetX = targetTopLeftX + hitboxWidth / 2;
|
|
1370
|
-
const targetY = targetTopLeftY + hitboxHeight / 2;
|
|
1371
|
-
|
|
1372
|
-
this.currentTarget = { x: targetX, y: targetY }; // Center position for physics engine
|
|
1373
|
-
this.currentTargetTopLeft = { x: targetTopLeftX, y: targetTopLeftY }; // Top-left position for player.x() comparison
|
|
1374
|
-
this.currentDirection = { x: 0, y: 0 };
|
|
1337
|
+
// Prepare segmented movement (per tile)
|
|
1338
|
+
this.remainingDistance = distance;
|
|
1339
|
+
this.segmentDirection = moveDirection;
|
|
1340
|
+
this.segmentStep = this.getTileStepDistance(playerSpeed);
|
|
1341
|
+
this.setNextSegmentTarget(currentTopLeftX, currentTopLeftY);
|
|
1375
1342
|
|
|
1376
|
-
|
|
1343
|
+
if (this.currentTargetTopLeft) {
|
|
1344
|
+
this.debugLog(`MOVE direction=${moveDirection} from=(${currentTopLeftX.toFixed(1)}, ${currentTopLeftY.toFixed(1)}) to=(${this.currentTargetTopLeft.x.toFixed(1)}, ${this.currentTargetTopLeft.y.toFixed(1)}) dist=${distance.toFixed(1)}`);
|
|
1345
|
+
}
|
|
1377
1346
|
|
|
1378
1347
|
// Reset stuck detection when starting a new movement
|
|
1379
1348
|
this.lastPosition = null;
|
|
@@ -1420,7 +1389,13 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1420
1389
|
|
|
1421
1390
|
if (frequencyMs > 0 && Date.now() - this.frequencyWaitStartTime >= frequencyMs * this.ratioFrequency) {
|
|
1422
1391
|
this.waitingForFrequency = false;
|
|
1423
|
-
this.
|
|
1392
|
+
if (this.remainingDistance > 0) {
|
|
1393
|
+
const currentTopLeftX = this.player.x();
|
|
1394
|
+
const currentTopLeftY = this.player.y();
|
|
1395
|
+
this.setNextSegmentTarget(currentTopLeftX, currentTopLeftY);
|
|
1396
|
+
} else {
|
|
1397
|
+
this.processNextRoute();
|
|
1398
|
+
}
|
|
1424
1399
|
}
|
|
1425
1400
|
return;
|
|
1426
1401
|
}
|
|
@@ -1478,12 +1453,16 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1478
1453
|
this.lastDistanceToTarget = null;
|
|
1479
1454
|
this.stuckCheckInitialized = false;
|
|
1480
1455
|
|
|
1481
|
-
// Wait for frequency before processing next route
|
|
1456
|
+
// Wait for frequency before processing next route or segment
|
|
1482
1457
|
if (!this.finished) {
|
|
1483
1458
|
const playerFrequency = this.player.frequency;
|
|
1484
1459
|
if (playerFrequency && playerFrequency > 0) {
|
|
1485
1460
|
this.waitingForFrequency = true;
|
|
1486
1461
|
this.frequencyWaitStartTime = Date.now();
|
|
1462
|
+
} else if (this.remainingDistance > 0) {
|
|
1463
|
+
const nextTopLeftX = this.player.x();
|
|
1464
|
+
const nextTopLeftY = this.player.y();
|
|
1465
|
+
this.setNextSegmentTarget(nextTopLeftX, nextTopLeftY);
|
|
1487
1466
|
} else {
|
|
1488
1467
|
// No frequency delay, process immediately
|
|
1489
1468
|
this.processNextRoute();
|
|
@@ -1510,12 +1489,16 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1510
1489
|
this.lastDistanceToTarget = null;
|
|
1511
1490
|
this.stuckCheckInitialized = false;
|
|
1512
1491
|
|
|
1513
|
-
// Wait for frequency before processing next route
|
|
1492
|
+
// Wait for frequency before processing next route or segment
|
|
1514
1493
|
if (!this.finished) {
|
|
1515
1494
|
const playerFrequency = player.frequency;
|
|
1516
1495
|
if (playerFrequency && playerFrequency > 0) {
|
|
1517
1496
|
this.waitingForFrequency = true;
|
|
1518
1497
|
this.frequencyWaitStartTime = Date.now();
|
|
1498
|
+
} else if (this.remainingDistance > 0) {
|
|
1499
|
+
const nextTopLeftX = this.player.x();
|
|
1500
|
+
const nextTopLeftY = this.player.y();
|
|
1501
|
+
this.setNextSegmentTarget(nextTopLeftX, nextTopLeftY);
|
|
1519
1502
|
} else {
|
|
1520
1503
|
// No frequency delay, process immediately
|
|
1521
1504
|
this.processNextRoute();
|
|
@@ -1628,6 +1611,10 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1628
1611
|
if (playerFrequency && playerFrequency > 0) {
|
|
1629
1612
|
this.waitingForFrequency = true;
|
|
1630
1613
|
this.frequencyWaitStartTime = Date.now();
|
|
1614
|
+
} else if (this.remainingDistance > 0) {
|
|
1615
|
+
const nextTopLeftX = this.player.x();
|
|
1616
|
+
const nextTopLeftY = this.player.y();
|
|
1617
|
+
this.setNextSegmentTarget(nextTopLeftX, nextTopLeftY);
|
|
1631
1618
|
} else {
|
|
1632
1619
|
// No frequency delay, process immediately
|
|
1633
1620
|
this.processNextRoute();
|
|
@@ -1657,6 +1644,69 @@ export function WithMoveManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
1657
1644
|
onFinished(): void {
|
|
1658
1645
|
this.onComplete(true);
|
|
1659
1646
|
}
|
|
1647
|
+
|
|
1648
|
+
private getTileStepDistance(playerSpeed: number): number {
|
|
1649
|
+
if (!Number.isFinite(playerSpeed) || playerSpeed <= 0) {
|
|
1650
|
+
return this.tileSize;
|
|
1651
|
+
}
|
|
1652
|
+
const stepsPerTile = Math.max(1, Math.floor(this.tileSize / playerSpeed));
|
|
1653
|
+
return stepsPerTile * playerSpeed;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
private setNextSegmentTarget(currentTopLeftX: number, currentTopLeftY: number): void {
|
|
1657
|
+
if (!this.segmentDirection || this.remainingDistance <= 0) {
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
const map = this.player.getCurrentMap() as any;
|
|
1662
|
+
if (!map) {
|
|
1663
|
+
this.finished = true;
|
|
1664
|
+
this.onComplete(false);
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
const entity = map.physic.getEntityByUUID(this.player.id);
|
|
1669
|
+
if (!entity) {
|
|
1670
|
+
this.finished = true;
|
|
1671
|
+
this.onComplete(false);
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
const segmentDistance = Math.min(this.segmentStep || this.remainingDistance, this.remainingDistance);
|
|
1676
|
+
let targetTopLeftX = currentTopLeftX;
|
|
1677
|
+
let targetTopLeftY = currentTopLeftY;
|
|
1678
|
+
|
|
1679
|
+
switch (this.segmentDirection) {
|
|
1680
|
+
case Direction.Right:
|
|
1681
|
+
case 'right' as any:
|
|
1682
|
+
targetTopLeftX = currentTopLeftX + segmentDistance;
|
|
1683
|
+
break;
|
|
1684
|
+
case Direction.Left:
|
|
1685
|
+
case 'left' as any:
|
|
1686
|
+
targetTopLeftX = currentTopLeftX - segmentDistance;
|
|
1687
|
+
break;
|
|
1688
|
+
case Direction.Down:
|
|
1689
|
+
case 'down' as any:
|
|
1690
|
+
targetTopLeftY = currentTopLeftY + segmentDistance;
|
|
1691
|
+
break;
|
|
1692
|
+
case Direction.Up:
|
|
1693
|
+
case 'up' as any:
|
|
1694
|
+
targetTopLeftY = currentTopLeftY - segmentDistance;
|
|
1695
|
+
break;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
const hitbox = this.player.hitbox();
|
|
1699
|
+
const hitboxWidth = hitbox?.w ?? 32;
|
|
1700
|
+
const hitboxHeight = hitbox?.h ?? 32;
|
|
1701
|
+
|
|
1702
|
+
const targetX = targetTopLeftX + hitboxWidth / 2;
|
|
1703
|
+
const targetY = targetTopLeftY + hitboxHeight / 2;
|
|
1704
|
+
|
|
1705
|
+
this.currentTarget = { x: targetX, y: targetY };
|
|
1706
|
+
this.currentTargetTopLeft = { x: targetTopLeftX, y: targetTopLeftY };
|
|
1707
|
+
this.currentDirection = { x: 0, y: 0 };
|
|
1708
|
+
this.remainingDistance -= segmentDistance;
|
|
1709
|
+
}
|
|
1660
1710
|
}
|
|
1661
1711
|
|
|
1662
1712
|
// Create and add the route movement strategy
|
|
@@ -434,13 +434,12 @@ export function WithParameterManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
434
434
|
_param = type(computed(() => {
|
|
435
435
|
const obj = {}
|
|
436
436
|
const parameters = this._parametersSignal()
|
|
437
|
+
const allModifiers = this._getAggregatedModifiers()
|
|
437
438
|
const level = this._level()
|
|
438
439
|
|
|
439
440
|
for (const [name, paramConfig] of Object.entries(parameters)) {
|
|
440
441
|
let curveVal = Math.floor((paramConfig.end - paramConfig.start) * ((level - 1) / (this.finalLevel - this.initialLevel))) + paramConfig.start
|
|
441
442
|
|
|
442
|
-
// Apply modifiers from equipment, states, etc.
|
|
443
|
-
const allModifiers = this._getAggregatedModifiers()
|
|
444
443
|
const modifier = allModifiers[name]
|
|
445
444
|
if (modifier) {
|
|
446
445
|
if (modifier.rate) curveVal *= modifier.rate
|
|
@@ -691,7 +690,6 @@ export function WithParameterManager<TBase extends PlayerCtor>(Base: TBase) {
|
|
|
691
690
|
get level(): number {
|
|
692
691
|
return this._level()
|
|
693
692
|
}
|
|
694
|
-
|
|
695
693
|
/**
|
|
696
694
|
* ```ts
|
|
697
695
|
* console.log(player.expForNextlevel) // 150
|
package/src/RpgServer.ts
CHANGED
|
@@ -696,10 +696,10 @@ export interface RpgServer {
|
|
|
696
696
|
* })
|
|
697
697
|
* ```
|
|
698
698
|
*
|
|
699
|
-
* @prop { { [dataName]: data } } [database]
|
|
699
|
+
* @prop { { [dataName]: data } | (engine: RpgMap) => { [dataName]: data } | Promise<{ [dataName]: data }> } [database]
|
|
700
700
|
* @memberof RpgServer
|
|
701
701
|
* */
|
|
702
|
-
database?: object | any[],
|
|
702
|
+
database?: object | any[] | ((engine: RpgMap) => object | any[] | Promise<object | any[]>),
|
|
703
703
|
|
|
704
704
|
/**
|
|
705
705
|
* Array of all maps. Each element can be either a class (decorated with `@MapData` or not) or a `MapOptions` object
|
package/src/module.ts
CHANGED
|
@@ -127,14 +127,20 @@ export function provideServerModules(modules: RpgServerModule[]): FactoryProvide
|
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
|
-
if (module.database
|
|
131
|
-
const database =
|
|
130
|
+
if (module.database) {
|
|
131
|
+
const database = module.database;
|
|
132
132
|
module = {
|
|
133
133
|
...module,
|
|
134
134
|
databaseHooks: {
|
|
135
|
-
load: (engine: RpgMap) => {
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
load: async (engine: RpgMap) => {
|
|
136
|
+
const data = typeof database === 'function'
|
|
137
|
+
? await database(engine)
|
|
138
|
+
: database;
|
|
139
|
+
if (!data || typeof data !== 'object') {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
for (const key in data) {
|
|
143
|
+
engine.addInDatabase(key, data[key]);
|
|
138
144
|
}
|
|
139
145
|
},
|
|
140
146
|
}
|
|
@@ -145,4 +151,4 @@ export function provideServerModules(modules: RpgServerModule[]): FactoryProvide
|
|
|
145
151
|
return modules
|
|
146
152
|
});
|
|
147
153
|
}
|
|
148
|
-
|
|
154
|
+
|