@hytopia.com/examples 1.0.48 → 1.0.49
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/hygrounds/assets/ui/index.html +11 -8
- package/hygrounds/classes/BotPlayerEntity.ts +1455 -0
- package/hygrounds/classes/ChestEntity.ts +6 -0
- package/hygrounds/classes/GameManager.ts +42 -2
- package/hygrounds/classes/GamePlayerEntity.ts +12 -2
- package/hygrounds/classes/GunEntity.ts +29 -0
- package/hygrounds/index.ts +10 -2
- package/package.json +1 -1
- package/frontiers-rpg-game/dev/persistence/player-player-12.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-13.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-15.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-16.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-4.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-5.json +0 -1
- package/frontiers-rpg-game/dev/persistence/player-player-8.json +0 -1
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Entity,
|
|
6
6
|
ModelEntityOptions,
|
|
7
7
|
QuaternionLike,
|
|
8
|
+
RigidBodyType,
|
|
8
9
|
SceneUI,
|
|
9
10
|
Vector3Like,
|
|
10
11
|
World,
|
|
@@ -24,6 +25,7 @@ export default class ChestEntity extends Entity {
|
|
|
24
25
|
modelScale: 1,
|
|
25
26
|
name: 'Item Chest',
|
|
26
27
|
rigidBodyOptions: {
|
|
28
|
+
type: RigidBodyType.DYNAMIC,
|
|
27
29
|
additionalMass: 10000,
|
|
28
30
|
enabledPositions: { x: false, y: true, z: false },
|
|
29
31
|
enabledRotations: { x: false, y: false, z: false },
|
|
@@ -83,6 +85,10 @@ export default class ChestEntity extends Entity {
|
|
|
83
85
|
this._labelSceneUI.load(world);
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
public get isOpened(): boolean {
|
|
89
|
+
return this._opened;
|
|
90
|
+
}
|
|
91
|
+
|
|
86
92
|
private _createLabelUI(): SceneUI {
|
|
87
93
|
return new SceneUI({
|
|
88
94
|
attachedToEntity: this,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import GamePlayerEntity from './GamePlayerEntity';
|
|
27
27
|
import ChestEntity from './ChestEntity';
|
|
28
28
|
import ItemFactory from './ItemFactory';
|
|
29
|
+
import BotPlayerEntity from './BotPlayerEntity';
|
|
29
30
|
|
|
30
31
|
export default class GameManager {
|
|
31
32
|
public static readonly instance = new GameManager();
|
|
@@ -54,6 +55,7 @@ export default class GameManager {
|
|
|
54
55
|
this.world = world;
|
|
55
56
|
this._spawnBedrock(world);
|
|
56
57
|
this._waitForPlayersToStart();
|
|
58
|
+
BotPlayerEntity.setWorldActive(world, false);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/**
|
|
@@ -67,6 +69,7 @@ export default class GameManager {
|
|
|
67
69
|
|
|
68
70
|
// Set game as active
|
|
69
71
|
this._gameActive = true;
|
|
72
|
+
BotPlayerEntity.setWorldActive(this.world, true);
|
|
70
73
|
this._gameStartAt = Date.now();
|
|
71
74
|
|
|
72
75
|
// Spawn initial game elements
|
|
@@ -86,6 +89,7 @@ export default class GameManager {
|
|
|
86
89
|
|
|
87
90
|
// Sync UI for all players
|
|
88
91
|
this._syncAllPlayersUI();
|
|
92
|
+
this.onPlayerPopulationChanged();
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
/**
|
|
@@ -95,10 +99,14 @@ export default class GameManager {
|
|
|
95
99
|
if (!this.world || !this._gameActive) return;
|
|
96
100
|
|
|
97
101
|
this._gameActive = false;
|
|
102
|
+
BotPlayerEntity.setWorldActive(this.world, false);
|
|
98
103
|
this.world.chatManager.sendBroadcastMessage('Game over! Starting the next round in 10 seconds...', 'FF0000');
|
|
99
104
|
|
|
100
105
|
this._identifyWinningPlayer();
|
|
101
106
|
|
|
107
|
+
BotPlayerEntity.despawnAll(this.world);
|
|
108
|
+
this.refreshPlayerCount();
|
|
109
|
+
|
|
102
110
|
// Clear any existing restart timer
|
|
103
111
|
if (this._restartTimer) {
|
|
104
112
|
clearTimeout(this._restartTimer);
|
|
@@ -129,6 +137,8 @@ export default class GameManager {
|
|
|
129
137
|
|
|
130
138
|
// Load player's data
|
|
131
139
|
playerEntity.loadPersistedData();
|
|
140
|
+
|
|
141
|
+
this.onPlayerPopulationChanged();
|
|
132
142
|
}
|
|
133
143
|
|
|
134
144
|
/**
|
|
@@ -204,6 +214,8 @@ export default class GameManager {
|
|
|
204
214
|
private _cleanup() {
|
|
205
215
|
if (!this.world) return;
|
|
206
216
|
|
|
217
|
+
BotPlayerEntity.despawnAll(this.world);
|
|
218
|
+
|
|
207
219
|
// Reset map to initial state
|
|
208
220
|
this.world.loadMap(worldMap);
|
|
209
221
|
this._spawnBedrock(this.world);
|
|
@@ -246,6 +258,25 @@ export default class GameManager {
|
|
|
246
258
|
|
|
247
259
|
// Reset leaderboard
|
|
248
260
|
this.resetLeaderboard();
|
|
261
|
+
|
|
262
|
+
this.onPlayerPopulationChanged();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public refreshPlayerCount(): void {
|
|
266
|
+
if (!this.world) return;
|
|
267
|
+
|
|
268
|
+
this.playerCount = this.world.entityManager.getAllPlayerEntities().length;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
public onPlayerPopulationChanged(): void {
|
|
272
|
+
this._syncBots();
|
|
273
|
+
this.refreshPlayerCount();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private _syncBots(): void {
|
|
277
|
+
if (!this.world) return;
|
|
278
|
+
|
|
279
|
+
BotPlayerEntity.ensureForWorld(this.world);
|
|
249
280
|
}
|
|
250
281
|
|
|
251
282
|
public _identifyWinningPlayer() {
|
|
@@ -422,12 +453,21 @@ export default class GameManager {
|
|
|
422
453
|
private _waitForPlayersToStart() {
|
|
423
454
|
if (!this.world) return;
|
|
424
455
|
|
|
425
|
-
const connectedPlayers =
|
|
456
|
+
const connectedPlayers = this._getHumanPlayerCount();
|
|
426
457
|
|
|
427
|
-
if (connectedPlayers >=
|
|
458
|
+
if (connectedPlayers >= 1) {
|
|
428
459
|
this.startGame();
|
|
429
460
|
} else {
|
|
430
461
|
setTimeout(() => this._waitForPlayersToStart(), 1000);
|
|
431
462
|
}
|
|
432
463
|
}
|
|
464
|
+
|
|
465
|
+
private _getHumanPlayerCount(): number {
|
|
466
|
+
if (!this.world) return 0;
|
|
467
|
+
|
|
468
|
+
return this.world.entityManager
|
|
469
|
+
.getAllPlayerEntities()
|
|
470
|
+
.filter(entity => !(entity instanceof BotPlayerEntity))
|
|
471
|
+
.length;
|
|
472
|
+
}
|
|
433
473
|
}
|
|
@@ -79,6 +79,16 @@ export default class GamePlayerEntity extends DefaultPlayerEntity {
|
|
|
79
79
|
|
|
80
80
|
public get isDead(): boolean { return this._dead; }
|
|
81
81
|
|
|
82
|
+
/** The currently active inventory item, if any. */
|
|
83
|
+
public get activeInventoryItem(): ItemEntity | undefined {
|
|
84
|
+
return this._inventory[this._inventoryActiveSlotIndex];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** A snapshot of the inventory items. */
|
|
88
|
+
public get inventoryItems(): ReadonlyArray<ItemEntity | undefined> {
|
|
89
|
+
return this._inventory.slice();
|
|
90
|
+
}
|
|
91
|
+
|
|
82
92
|
public constructor(player: Player) {
|
|
83
93
|
super({
|
|
84
94
|
player,
|
|
@@ -88,7 +98,7 @@ export default class GamePlayerEntity extends DefaultPlayerEntity {
|
|
|
88
98
|
});
|
|
89
99
|
|
|
90
100
|
this._setupPlayerController();
|
|
91
|
-
this.
|
|
101
|
+
this.setupPlayerUI();
|
|
92
102
|
this._setupPlayerCamera();
|
|
93
103
|
this._setupPlayerHeadshotCollider();
|
|
94
104
|
|
|
@@ -396,7 +406,7 @@ export default class GamePlayerEntity extends DefaultPlayerEntity {
|
|
|
396
406
|
pickaxe.pickup(this);
|
|
397
407
|
}
|
|
398
408
|
|
|
399
|
-
|
|
409
|
+
public setupPlayerUI(): void {
|
|
400
410
|
this.nametagSceneUI.setViewDistance(8); // lessen view distance so you only see player names when close
|
|
401
411
|
this.player.ui.load('ui/index.html');
|
|
402
412
|
|
|
@@ -185,6 +185,35 @@ export default abstract class GunEntity extends ItemEntity {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/** The amount of ammo currently in the clip. */
|
|
189
|
+
public getClipAmmo(): number {
|
|
190
|
+
return this.ammo;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** The remaining reserve ammo for this gun. */
|
|
194
|
+
public getReserveAmmo(): number {
|
|
195
|
+
return this.totalAmmo;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Whether the gun has ammo available in the clip or reserves. */
|
|
199
|
+
public hasUsableAmmo(): boolean {
|
|
200
|
+
return this.ammo > 0 || this.totalAmmo > 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public getReloadTimeMs(): number {
|
|
204
|
+
return this.reloadTimeMs;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** The effective range (in blocks) of the gun. */
|
|
208
|
+
public getEffectiveRange(): number {
|
|
209
|
+
return this.range;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Whether the gun is currently reloading. */
|
|
213
|
+
public isReloading(): boolean {
|
|
214
|
+
return this._reloading;
|
|
215
|
+
}
|
|
216
|
+
|
|
188
217
|
private _createMuzzleFlash(): void {
|
|
189
218
|
if (!this.isSpawned || !this.world) return;
|
|
190
219
|
|
package/hygrounds/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import GameManager from './classes/GameManager';
|
|
7
7
|
|
|
8
8
|
import worldMap from './assets/map.json' with { type: 'json' } ;
|
|
9
|
+
import GamePlayerEntity from './classes/GamePlayerEntity';
|
|
9
10
|
|
|
10
11
|
startServer(world => {
|
|
11
12
|
// Load the game map
|
|
@@ -20,7 +21,6 @@ startServer(world => {
|
|
|
20
21
|
// Handle player joining the game
|
|
21
22
|
world.on(PlayerEvent.JOINED_WORLD, ({ player }) => {
|
|
22
23
|
GameManager.instance.spawnPlayerEntity(player);
|
|
23
|
-
GameManager.instance.playerCount++;
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
// Handle player leaving the game
|
|
@@ -30,7 +30,15 @@ startServer(world => {
|
|
|
30
30
|
.getPlayerEntitiesByPlayer(player)
|
|
31
31
|
.forEach(entity => entity.despawn());
|
|
32
32
|
|
|
33
|
-
GameManager.instance.
|
|
33
|
+
GameManager.instance.onPlayerPopulationChanged();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
world.on(PlayerEvent.RECONNECTED_WORLD, ({ player }) => {
|
|
37
|
+
world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => {
|
|
38
|
+
if (entity instanceof GamePlayerEntity) {
|
|
39
|
+
entity.setupPlayerUI();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
34
42
|
});
|
|
35
43
|
});
|
|
36
44
|
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":31,"health":92,"currentRegionId":"hearthwilds","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":249,"y":22,"z":-89},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"__version":11,"health":100,"currentRegionId":"stalkhaven","currentRegionSpawnFacingAngle":90,"currentRegionSpawnPoint":{"x":32,"y":2,"z":1},"skillExperience":[],"backpack":{"items":[]},"hotbar":{"items":[{"position":0,"itemId":"toy_sword"}]},"questLog":{"quests":[]},"storage":{"items":[]},"wearables":{"items":[]}}
|