@hytopia.com/examples 1.0.48 → 1.0.50
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 +38 -3
- 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,
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
ITEM_SPAWNS,
|
|
19
19
|
ITEM_SPAWNS_AT_START,
|
|
20
20
|
ITEM_SPAWN_ITEMS,
|
|
21
|
-
MINIMUM_PLAYERS_TO_START,
|
|
22
21
|
SPAWN_REGION_AABB,
|
|
23
22
|
RANK_WIN_EXP,
|
|
24
23
|
} from '../gameConfig';
|
|
@@ -26,6 +25,7 @@ import {
|
|
|
26
25
|
import GamePlayerEntity from './GamePlayerEntity';
|
|
27
26
|
import ChestEntity from './ChestEntity';
|
|
28
27
|
import ItemFactory from './ItemFactory';
|
|
28
|
+
import BotPlayerEntity from './BotPlayerEntity';
|
|
29
29
|
|
|
30
30
|
export default class GameManager {
|
|
31
31
|
public static readonly instance = new GameManager();
|
|
@@ -54,6 +54,7 @@ export default class GameManager {
|
|
|
54
54
|
this.world = world;
|
|
55
55
|
this._spawnBedrock(world);
|
|
56
56
|
this._waitForPlayersToStart();
|
|
57
|
+
BotPlayerEntity.setWorldActive(world, false);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
@@ -67,6 +68,7 @@ export default class GameManager {
|
|
|
67
68
|
|
|
68
69
|
// Set game as active
|
|
69
70
|
this._gameActive = true;
|
|
71
|
+
BotPlayerEntity.setWorldActive(this.world, true);
|
|
70
72
|
this._gameStartAt = Date.now();
|
|
71
73
|
|
|
72
74
|
// Spawn initial game elements
|
|
@@ -86,6 +88,7 @@ export default class GameManager {
|
|
|
86
88
|
|
|
87
89
|
// Sync UI for all players
|
|
88
90
|
this._syncAllPlayersUI();
|
|
91
|
+
this.onPlayerPopulationChanged();
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
/**
|
|
@@ -95,9 +98,11 @@ export default class GameManager {
|
|
|
95
98
|
if (!this.world || !this._gameActive) return;
|
|
96
99
|
|
|
97
100
|
this._gameActive = false;
|
|
101
|
+
BotPlayerEntity.setWorldActive(this.world, false);
|
|
98
102
|
this.world.chatManager.sendBroadcastMessage('Game over! Starting the next round in 10 seconds...', 'FF0000');
|
|
99
103
|
|
|
100
104
|
this._identifyWinningPlayer();
|
|
105
|
+
this.refreshPlayerCount();
|
|
101
106
|
|
|
102
107
|
// Clear any existing restart timer
|
|
103
108
|
if (this._restartTimer) {
|
|
@@ -129,6 +134,8 @@ export default class GameManager {
|
|
|
129
134
|
|
|
130
135
|
// Load player's data
|
|
131
136
|
playerEntity.loadPersistedData();
|
|
137
|
+
|
|
138
|
+
this.onPlayerPopulationChanged();
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
/**
|
|
@@ -246,6 +253,25 @@ export default class GameManager {
|
|
|
246
253
|
|
|
247
254
|
// Reset leaderboard
|
|
248
255
|
this.resetLeaderboard();
|
|
256
|
+
|
|
257
|
+
this.onPlayerPopulationChanged();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public refreshPlayerCount(): void {
|
|
261
|
+
if (!this.world) return;
|
|
262
|
+
|
|
263
|
+
this.playerCount = this.world.entityManager.getAllPlayerEntities().length;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
public onPlayerPopulationChanged(): void {
|
|
267
|
+
this._syncBots();
|
|
268
|
+
this.refreshPlayerCount();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private _syncBots(): void {
|
|
272
|
+
if (!this.world) return;
|
|
273
|
+
|
|
274
|
+
BotPlayerEntity.ensureForWorld(this.world);
|
|
249
275
|
}
|
|
250
276
|
|
|
251
277
|
public _identifyWinningPlayer() {
|
|
@@ -422,12 +448,21 @@ export default class GameManager {
|
|
|
422
448
|
private _waitForPlayersToStart() {
|
|
423
449
|
if (!this.world) return;
|
|
424
450
|
|
|
425
|
-
const connectedPlayers =
|
|
451
|
+
const connectedPlayers = this._getHumanPlayerCount();
|
|
426
452
|
|
|
427
|
-
if (connectedPlayers >=
|
|
453
|
+
if (connectedPlayers >= 1) {
|
|
428
454
|
this.startGame();
|
|
429
455
|
} else {
|
|
430
456
|
setTimeout(() => this._waitForPlayersToStart(), 1000);
|
|
431
457
|
}
|
|
432
458
|
}
|
|
459
|
+
|
|
460
|
+
private _getHumanPlayerCount(): number {
|
|
461
|
+
if (!this.world) return 0;
|
|
462
|
+
|
|
463
|
+
return this.world.entityManager
|
|
464
|
+
.getAllPlayerEntities()
|
|
465
|
+
.filter(entity => !(entity instanceof BotPlayerEntity))
|
|
466
|
+
.length;
|
|
467
|
+
}
|
|
433
468
|
}
|
|
@@ -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":[]}}
|