@rpgjs/server 5.0.0-alpha.40 → 5.0.0-alpha.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { MapOptions } from './decorators/map';
2
2
  import { RpgPlayer, RpgEvent } from './Player/Player';
3
3
  import { RpgMap } from './rooms/map';
4
4
  import { RpgServerEngine } from './RpgServerEngine';
5
- import { WorldMapConfig, RpgShape } from '../../common/src';
5
+ import { WorldMapConfig, RpgShape, MapPhysicsInitContext, MapPhysicsEntityContext } from '../../common/src';
6
6
  type RpgClassMap<T> = new () => T;
7
7
  type RpgClassEvent<T> = RpgEvent;
8
8
  type MatchMakerOption = any;
@@ -546,6 +546,44 @@ export interface RpgMapHooks {
546
546
  * ```
547
547
  */
548
548
  onLeave?: (player: RpgPlayer, map: RpgMap) => any;
549
+ /**
550
+ * Called when the map physics world is initialized.
551
+ *
552
+ * This hook runs each time `loadPhysic()` prepares the physics world, after static
553
+ * map hitboxes are created and before dynamic player/event bodies are hydrated.
554
+ *
555
+ * @param {RpgMap} map - The map instance
556
+ * @param {MapPhysicsInitContext} context - Physics initialization context
557
+ * @returns {any}
558
+ * @memberof RpgMapHooks
559
+ */
560
+ onPhysicsInit?: (map: RpgMap, context: MapPhysicsInitContext) => any;
561
+ /**
562
+ * Called when a dynamic character physics body is added to the map.
563
+ *
564
+ * @param {RpgMap} map - The map instance
565
+ * @param {MapPhysicsEntityContext} context - Added entity context
566
+ * @returns {any}
567
+ * @memberof RpgMapHooks
568
+ */
569
+ onPhysicsEntityAdd?: (map: RpgMap, context: MapPhysicsEntityContext) => any;
570
+ /**
571
+ * Called when a dynamic character physics body is removed from the map.
572
+ *
573
+ * @param {RpgMap} map - The map instance
574
+ * @param {MapPhysicsEntityContext} context - Removed entity context
575
+ * @returns {any}
576
+ * @memberof RpgMapHooks
577
+ */
578
+ onPhysicsEntityRemove?: (map: RpgMap, context: MapPhysicsEntityContext) => any;
579
+ /**
580
+ * Called when the map physics world is reset (before reload).
581
+ *
582
+ * @param {RpgMap} map - The map instance
583
+ * @returns {any}
584
+ * @memberof RpgMapHooks
585
+ */
586
+ onPhysicsReset?: (map: RpgMap) => any;
549
587
  }
550
588
  export interface RpgServer {
551
589
  /**
package/dist/index.js CHANGED
@@ -16127,6 +16127,7 @@ class RpgCommonMap {
16127
16127
  }
16128
16128
  this.clearAll();
16129
16129
  this.moveManager.clearAll();
16130
+ this.emitPhysicsReset();
16130
16131
  this.physicsAccumulatorMs = 0;
16131
16132
  }
16132
16133
  /**
@@ -16136,6 +16137,14 @@ class RpgCommonMap {
16136
16137
  clearAll() {
16137
16138
  const entities = this.physic.getEntities();
16138
16139
  for (const entity of entities) {
16140
+ const owner = entity.owner;
16141
+ if (owner) {
16142
+ this.emitPhysicsEntityRemove({
16143
+ owner,
16144
+ entity,
16145
+ kind: this.resolvePhysicsEntityKind(owner, entity.uuid)
16146
+ });
16147
+ }
16139
16148
  this.physic.removeEntity(entity);
16140
16149
  }
16141
16150
  this.physic.getMovementManager().clearAll();
@@ -16161,10 +16170,11 @@ class RpgCommonMap {
16161
16170
  this.addStaticHitbox(staticHitbox.id ?? generateShortUUID$1(), staticHitbox.points);
16162
16171
  }
16163
16172
  }
16173
+ this.emitPhysicsInit({ mapData });
16164
16174
  this.playersSubscription = this.players.observable.subscribe(
16165
16175
  ({ value: player, type, key }) => {
16166
16176
  if (type === "remove") {
16167
- this.removeHitbox(key);
16177
+ this.removeHitbox(key, player, "hero");
16168
16178
  return;
16169
16179
  }
16170
16180
  if (type == "reset") {
@@ -16204,7 +16214,7 @@ class RpgCommonMap {
16204
16214
  if (eventObj && typeof eventObj._movementUnsubscribe === "function") {
16205
16215
  eventObj._movementUnsubscribe();
16206
16216
  }
16207
- this.removeHitbox(key);
16217
+ this.removeHitbox(key, event, "npc");
16208
16218
  } else if (type === "update") {
16209
16219
  event.id = event.id ?? key;
16210
16220
  if (!this.getBody(key)) {
@@ -16457,6 +16467,14 @@ class RpgCommonMap {
16457
16467
  isStatic: options?.isStatic,
16458
16468
  mass: options?.mass
16459
16469
  });
16470
+ const entity = this.getBody(owner.id);
16471
+ if (entity) {
16472
+ this.emitPhysicsEntityAdd({
16473
+ owner,
16474
+ entity,
16475
+ kind
16476
+ });
16477
+ }
16460
16478
  }
16461
16479
  updateCharacterHitbox(owner) {
16462
16480
  if (!owner?.id) return;
@@ -16497,6 +16515,32 @@ class RpgCommonMap {
16497
16515
  }
16498
16516
  return false;
16499
16517
  }
16518
+ resolvePhysicsEntityKind(owner, id) {
16519
+ if (typeof owner?.isEvent === "function") {
16520
+ try {
16521
+ if (owner.isEvent()) {
16522
+ return "npc";
16523
+ }
16524
+ } catch {
16525
+ }
16526
+ }
16527
+ const ownerId = typeof owner?.id === "string" ? owner.id : id;
16528
+ if (ownerId && this.players()?.[ownerId]) {
16529
+ return "hero";
16530
+ }
16531
+ if (ownerId && this.events()?.[ownerId]) {
16532
+ return "npc";
16533
+ }
16534
+ return "generic";
16535
+ }
16536
+ emitPhysicsInit(_context) {
16537
+ }
16538
+ emitPhysicsEntityAdd(_context) {
16539
+ }
16540
+ emitPhysicsEntityRemove(_context) {
16541
+ }
16542
+ emitPhysicsReset() {
16543
+ }
16500
16544
  withPhysicsSync(run) {
16501
16545
  this.physicsSyncDepth += 1;
16502
16546
  try {
@@ -16975,11 +17019,19 @@ class RpgCommonMap {
16975
17019
  * Remove a hitbox from the physics world
16976
17020
  * @private
16977
17021
  */
16978
- removeHitbox(id) {
17022
+ removeHitbox(id, owner, kind) {
16979
17023
  const entity = this.physic.getEntityByUUID(id);
16980
17024
  if (!entity) {
16981
17025
  return false;
16982
17026
  }
17027
+ const resolvedOwner = owner ?? entity.owner;
17028
+ if (resolvedOwner) {
17029
+ this.emitPhysicsEntityRemove({
17030
+ owner: resolvedOwner,
17031
+ entity,
17032
+ kind: kind ?? this.resolvePhysicsEntityKind(resolvedOwner, id)
17033
+ });
17034
+ }
16983
17035
  this.physic.removeEntity(entity);
16984
17036
  return true;
16985
17037
  }
@@ -28001,6 +28053,18 @@ let RpgMap = class extends RpgCommonMap {
28001
28053
  onStart() {
28002
28054
  return BaseRoom.prototype.onStart.call(this);
28003
28055
  }
28056
+ emitPhysicsInit(context2) {
28057
+ this.hooks.callHooks("server-map-onPhysicsInit", this, context2).subscribe();
28058
+ }
28059
+ emitPhysicsEntityAdd(context2) {
28060
+ this.hooks.callHooks("server-map-onPhysicsEntityAdd", this, context2).subscribe();
28061
+ }
28062
+ emitPhysicsEntityRemove(context2) {
28063
+ this.hooks.callHooks("server-map-onPhysicsEntityRemove", this, context2).subscribe();
28064
+ }
28065
+ emitPhysicsReset() {
28066
+ this.hooks.callHooks("server-map-onPhysicsReset", this).subscribe();
28067
+ }
28004
28068
  isPositiveNumber(value) {
28005
28069
  return typeof value === "number" && Number.isFinite(value) && value > 0;
28006
28070
  }