From 58ab9a74220d85d844f41c0986e86c543a068063 Mon Sep 17 00:00:00 2001
From: keshav2010 <sharmakeshav15157@gmail.com>
Date: Mon, 29 Apr 2024 00:44:07 +0530
Subject: [PATCH] added spinner when creating room, some code changes

---
 gameserver/commands/OnSoldierAttackCommand.ts | 34 +++++-----
 gameserver/commands/OnSoldierMoveCommand.ts   | 37 +++++-----
 package-lock.json                             | 16 ++---
 package.json                                  |  2 +-
 public/game.ts                                |  1 +
 public/scenes/BaseScene.ts                    | 44 +++---------
 public/scenes/GameScene.ts                    |  9 +--
 public/scenes/MenuScene.ts                    | 67 +++++++++++++------
 public/soldiers/BaseSoldier.ts                | 20 +++---
 9 files changed, 114 insertions(+), 116 deletions(-)

diff --git a/gameserver/commands/OnSoldierAttackCommand.ts b/gameserver/commands/OnSoldierAttackCommand.ts
index 48f9161..37cad91 100644
--- a/gameserver/commands/OnSoldierAttackCommand.ts
+++ b/gameserver/commands/OnSoldierAttackCommand.ts
@@ -17,21 +17,25 @@ export class OnSoldierAttackCommand extends Command<
     targetPlayerId: string;
     targetUnitId: string;
   }>) {
-    const attacker = this.state.getPlayer(client.id);
-    const victim = this.state.getPlayer(message.targetPlayerId);
-    if (!attacker || !victim) {
-      return;
-    }
-    const targetSoldier = victim.getSoldier(message.targetUnitId);
-    if (!targetSoldier) {
-      return;
-    }
+    try {
+      const attacker = this.state.getPlayer(client.id);
+      const victim = this.state.getPlayer(message.targetPlayerId);
+      if (!attacker || !victim) {
+        return;
+      }
+      const targetSoldier = victim.getSoldier(message.targetUnitId);
+      if (!targetSoldier) {
+        return;
+      }
 
-    const attackerUnits = attacker
-      .getAllSoldiers()
-      .filter((soldier) => message.soldiers.includes(soldier.id));
-    attackerUnits.forEach((unit: SoldierState) => {
-      unit.attackUnit(targetSoldier, gameManager!);
-    });
+      const attackerUnits = attacker
+        .getAllSoldiers()
+        .filter((soldier) => message.soldiers.includes(soldier.id));
+      attackerUnits.forEach((unit: SoldierState) => {
+        unit.attackUnit(targetSoldier, gameManager!);
+      });
+    } catch (error) {
+      console.error(error);
+    }
   }
 }
diff --git a/gameserver/commands/OnSoldierMoveCommand.ts b/gameserver/commands/OnSoldierMoveCommand.ts
index 930f4bf..d7862c2 100644
--- a/gameserver/commands/OnSoldierMoveCommand.ts
+++ b/gameserver/commands/OnSoldierMoveCommand.ts
@@ -17,21 +17,26 @@ export class OnSoldierMoveCommand extends Command<SessionRoom, CommandPayload> {
     expectedPositionX: number;
     expectedPositionY: number;
   }>) {
-    const sceneSize = gameManager?.scene.getDimension();
-    if (!sceneSize) return;
-
-    const soldierObjects = message.soldierIds
-      .map((id) => this.state.getPlayer(client.sessionId)?.getSoldier(id))
-      .filter(Boolean) as SoldierState[];
-    if (soldierObjects.length === 0) return;
-    const offset = 96;
-    const gridFormation = new GroupFormation(
-      soldierObjects,
-      offset,
-      new SAT.Box(new SAT.Vector(), sceneSize.x, sceneSize.y)
-    );
-    gridFormation.calculatePositions(
-      new SAT.Vector(message.expectedPositionX, message.expectedPositionY)
-    );
+    try {
+      const sceneSize = gameManager?.scene.getDimension();
+      if (!sceneSize) {
+        throw new Error(`sceneSize not found`);
+      }
+      const soldierObjects = message.soldierIds
+        .map((id) => this.state.getPlayer(client.sessionId)?.getSoldier(id))
+        .filter(Boolean) as SoldierState[];
+      if (soldierObjects.length === 0) return;
+      const offset = 96;
+      const gridFormation = new GroupFormation(
+        soldierObjects,
+        offset,
+        new SAT.Box(new SAT.Vector(), sceneSize.x, sceneSize.y)
+      );
+      gridFormation.calculatePositions(
+        new SAT.Vector(message.expectedPositionX, message.expectedPositionY)
+      );
+    } catch (error) {
+      console.error(error);
+    }
   }
 }
diff --git a/package-lock.json b/package-lock.json
index 61fb5ea..462e706 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,7 +31,7 @@
         "npx": "^10.2.2",
         "phaser": "^3.70.0",
         "phaser-ui-tools": "^2.0.0-beta",
-        "phaser3-rex-plugins": "^1.1.82",
+        "phaser3-rex-plugins": "^1.80.2",
         "quadtree-lib": "^1.0.9",
         "sat": "^0.9.0",
         "socket.io": "^4.4.1",
@@ -4324,9 +4324,9 @@
       }
     },
     "node_modules/i18next-http-backend": {
-      "version": "2.4.3",
-      "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.4.3.tgz",
-      "integrity": "sha512-jo2M03O6n1/DNb51WSQ8PsQ0xEELzLZRdYUTbf17mLw3rVwnJF9hwNgMXvEFSxxb+N8dT+o0vtigA6s5mGWyPA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.1.tgz",
+      "integrity": "sha512-+rNX1tghdVxdfjfPt0bI1sNg5ahGW9kA7OboG7b4t03Fp69NdDlRIze6yXhIbN8rbHxJ8IP4dzRm/okZ15lkQg==",
       "dependencies": {
         "cross-fetch": "4.0.0"
       }
@@ -10569,13 +10569,13 @@
       "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
     },
     "node_modules/phaser3-rex-plugins": {
-      "version": "1.60.10",
-      "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.60.10.tgz",
-      "integrity": "sha512-BiwFPPGSIvPG1jMLCjMd3Im7UrjPmU9103BF//5q9ns/QVbLl54XwoHoR4FYx+iCQEYsUV53x9ABGVPlNETyDQ==",
+      "version": "1.80.2",
+      "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.2.tgz",
+      "integrity": "sha512-ZPA4c47WQRU6rqLdlOFizGU+ljtP4C2blhcpbYSsNMqNRHD7o8vRBEzEhl8w6CMGvcy+eVoA6v10cyL4eIZARw==",
       "dependencies": {
         "eventemitter3": "^3.1.2",
         "i18next": "^22.5.1",
-        "i18next-http-backend": "^2.4.1",
+        "i18next-http-backend": "^2.5.0",
         "js-yaml": "^4.1.0",
         "mustache": "^4.2.0",
         "papaparse": "^5.4.1",
diff --git a/package.json b/package.json
index ecc9865..c21a7ab 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
     "npx": "^10.2.2",
     "phaser": "^3.70.0",
     "phaser-ui-tools": "^2.0.0-beta",
-    "phaser3-rex-plugins": "^1.1.82",
+    "phaser3-rex-plugins": "^1.80.2",
     "quadtree-lib": "^1.0.9",
     "sat": "^0.9.0",
     "socket.io": "^4.4.1",
diff --git a/public/game.ts b/public/game.ts
index ebb4889..26c08f2 100644
--- a/public/game.ts
+++ b/public/game.ts
@@ -7,6 +7,7 @@ import { PlayerStatisticHUD } from "./scenes/PlayerStatisticHUD";
 import { SessionLobbyScene } from "./scenes/SessionLobbyScene";
 import { SessionBrowserScene } from "./scenes/SessionBrowserScene";
 import SpinnerPlugin from "phaser3-rex-plugins/templates/spinner/spinner-plugin.js";
+
 import Phaser from "phaser";
 const config = {
   type: Phaser.WEBGL,
diff --git a/public/scenes/BaseScene.ts b/public/scenes/BaseScene.ts
index 8742b1b..2dc2741 100644
--- a/public/scenes/BaseScene.ts
+++ b/public/scenes/BaseScene.ts
@@ -4,17 +4,13 @@ import { NetworkManager } from "../NetworkManager";
 import { ClientStateManager } from "../ClientStateManager";
 import CONSTANT from "../constant";
 import { nanoid } from "nanoid";
+interface Destroyable {
+  destroy: Function;
+}
+type ManagedTypes = Destroyable;
 
 export class BaseScene extends Phaser.Scene {
-  objectSet: Map<
-    string,
-    | Phaser.GameObjects.Graphics
-    | PlayerCastle
-    | Phaser.Cameras.Controls.SmoothedKeyControl
-    | Phaser.GameObjects.Text
-    | Phaser.GameObjects.DOMElement
-    | Phaser.GameObjects.Image
-  >;
+  objectSet: Map<string, ManagedTypes>;
   registeredInputEvents: Set<string>;
   registeredSceneEvents: Set<string>;
 
@@ -73,29 +69,13 @@ export class BaseScene extends Phaser.Scene {
     }
   }
 
-  AddObject<
-    T extends
-      | Phaser.GameObjects.Graphics
-      | PlayerCastle
-      | Phaser.Cameras.Controls.SmoothedKeyControl
-      | Phaser.GameObjects.Text
-      | Phaser.GameObjects.DOMElement
-      | Phaser.GameObjects.Image
-  >(newObject: T, key?: string): T {
+  AddObject<T extends ManagedTypes>(newObject: T, key?: string): T {
     let mKey = nanoid();
     this.objectSet.set(key || mKey, newObject);
     return newObject;
   }
 
-  GetObject<
-    T extends
-      | Phaser.GameObjects.Graphics
-      | PlayerCastle
-      | Phaser.Cameras.Controls.SmoothedKeyControl
-      | Phaser.GameObjects.Text
-      | Phaser.GameObjects.DOMElement
-      | Phaser.GameObjects.Image
-  >(key: string) {
+  GetObject<T extends ManagedTypes>(key: string) {
     return this.objectSet.get(key) as T | undefined;
   }
 
@@ -124,15 +104,7 @@ export class BaseScene extends Phaser.Scene {
   }
 
   // Recursively destroy an object, including any children if it's a group
-  DestroyObject<
-    T extends
-      | Phaser.GameObjects.Graphics
-      | PlayerCastle
-      | Phaser.GameObjects.Text
-      | Phaser.GameObjects.DOMElement
-      | Phaser.GameObjects.Image
-      | Phaser.Cameras.Controls.SmoothedKeyControl
-  >(obj: T) {
+  DestroyObject<T extends ManagedTypes>(obj: T) {
     if ((obj as any)?.type === "Group") obj.destroy(true);
     else obj.destroy();
   }
diff --git a/public/scenes/GameScene.ts b/public/scenes/GameScene.ts
index 5a4aa24..8f8cd02 100644
--- a/public/scenes/GameScene.ts
+++ b/public/scenes/GameScene.ts
@@ -9,6 +9,8 @@ import SessionStateClientHelpers from "../helpers/SessionStateClientHelpers";
 import { BaseSoldier } from "../soldiers/BaseSoldier";
 import { Spearman } from "../soldiers/Spearman";
 import { BaseScene } from "./BaseScene";
+import SpinnerPlugin from "phaser3-rex-plugins/templates/spinner/spinner-plugin.js";
+
 import $ from "jquery";
 
 var selectorColor = 0xffff00;
@@ -56,7 +58,7 @@ export class GameScene extends BaseScene {
   canvasWidth: number;
   canvasHeight: number;
   controls?: Phaser.Cameras.Controls.SmoothedKeyControl;
-
+  rexSpinner: SpinnerPlugin.Spinner | undefined;
   constructor() {
     super(CONSTANT.SCENES.GAME);
     this.canvasWidth = 1962;
@@ -88,10 +90,6 @@ export class GameScene extends BaseScene {
       [ownerPlayer.colorR, ownerPlayer.colorG, ownerPlayer.colorB],
       ownerPlayer.id
     );
-    spearmen.setData("serverPosition", {
-      x: soldier.currentPositionX,
-      y: soldier.currentPositionY,
-    });
     const playerSoldiersGameObject = this.data.get(
       "playerSoldiersGameObject"
     ) as Map<PlayerId, soldierIdToPhaserMap>;
@@ -207,7 +205,6 @@ export class GameScene extends BaseScene {
 
   create() {
     networkManager = this.registry.get("networkManager") as NetworkManager;
-
     const stylus = this.add.graphics();
     stylus.setDepth(9999);
 
diff --git a/public/scenes/MenuScene.ts b/public/scenes/MenuScene.ts
index a1c554b..e513657 100644
--- a/public/scenes/MenuScene.ts
+++ b/public/scenes/MenuScene.ts
@@ -2,8 +2,12 @@ import CONSTANT from "../constant";
 import { BaseScene } from "./BaseScene";
 import { NetworkManager } from "../NetworkManager";
 import { addBackgroundImage } from "../helpers/addBackgroundImage";
+import SpinnerPlugin from "phaser3-rex-plugins/templates/spinner/spinner-plugin.js";
+
 const URL = `${window.location.host}`;
+
 export class MenuScene extends BaseScene {
+  rexSpinner: SpinnerPlugin | undefined;
   constructor() {
     super(CONSTANT.SCENES.MENU);
     console.log(URL);
@@ -15,8 +19,24 @@ export class MenuScene extends BaseScene {
     this.scene.bringToTop();
     this.load.html("playerForm", "../html/menu-form.html");
     this.load.image("background", "../assets/background.png");
+    this.load.scenePlugin({
+      key: "rexSpinner",
+      url: SpinnerPlugin,
+      sceneKey: "rexSpinner",
+    });
   }
   create() {
+    const spinner = this.rexSpinner!.add.spinner({
+      width: 80,
+      height: 80,
+      duration: 500,
+      x: 80,
+      y: 80,
+    });
+    spinner.setDepth(9999);
+    spinner.setVisible(false);
+    this.AddObject(spinner, "obj_spinner");
+    
     let networkManager = this.registry.get("networkManager") as NetworkManager;
     addBackgroundImage(this, "background");
     this.AddObject(this.add.text(100, 20, "War.IO"), "obj_introText");
@@ -35,11 +55,13 @@ export class MenuScene extends BaseScene {
     let playBtn = playerForm.getChildByName("btnJoin");
     let createSessionBtn = playerForm.getChildByName("btnCreate");
     const tutorialBtn = playerForm.getChildByName("btnTutorial");
-    
+
     let inputField = playerForm.getChildByName("nameInput");
 
     inputField?.addEventListener("input", (event) => {
-      var inputName = playerForm.getChildByName("nameInput") as Element & { value: string };
+      var inputName = <Element & { value: string }>(
+        playerForm.getChildByName("nameInput")
+      );
       if (!inputName) return;
       if (inputName.value !== "") {
         let name = inputName.value.trim().replace(" ", "-");
@@ -54,7 +76,7 @@ export class MenuScene extends BaseScene {
       event.stopPropagation();
       this.scene.start(CONSTANT.SCENES.TUTORIAL);
     });
-    
+
     playerForm.addListener("click");
     playerForm.on("click", function (event: any) {
       event.stopPropagation();
@@ -66,12 +88,17 @@ export class MenuScene extends BaseScene {
     });
 
     createSessionBtn?.addEventListener("pointerdown", async (event) => {
-      event.stopPropagation();
-      await this.onCreateSessionClick();
+      try {
+        event.stopPropagation();
+
+        await this.onCreateSessionClick();
+      } catch (error) {
+        console.log(error);
+      }
     });
 
     this.AddSceneEvent("shutdown", (data: any) => {
-      console.log("shutdown ", data.config.key);
+      console.log(`[shutdown]: ${data.config.key}`);
       this.Destroy();
     });
 
@@ -86,7 +113,9 @@ export class MenuScene extends BaseScene {
     const networkManager = this.registry.get(
       "networkManager"
     ) as NetworkManager;
-    var inputName = playerForm.getChildByName("nameInput") as Element & { value: string };
+    var inputName = <Element & { value: string }>(
+      playerForm.getChildByName("nameInput")
+    );
     if (inputName?.nodeValue !== "") {
       let name = inputName?.value.trim().replace(" ", "-");
       networkManager.setPlayerName(name || "");
@@ -109,7 +138,7 @@ export class MenuScene extends BaseScene {
         this.scene.start(CONSTANT.SCENES.MENU);
       };
       //join session
-      await(
+      await (
         this.registry.get("networkManager") as NetworkManager
       ).connectGameServer(`${URL}/${sessionId}`);
     } catch (err) {
@@ -130,29 +159,23 @@ export class MenuScene extends BaseScene {
         "obj_playerForm"
       )?.getChildByName("nameInput") as Element & { value: string })!.value;
       const sessions = await networkManager.getAvailableSession();
-      console.log('available sessions ', sessions);
-    }
-    catch(error) {
-
-    }
+      console.log("available sessions ", sessions);
+    } catch (error) {}
   }
   async onCreateSessionClick() {
     try {
-      const networkManager = this.registry.get(
-        "networkManager"
-      ) as NetworkManager;
+      const networkManager = <NetworkManager>(
+        this.registry.get("networkManager")
+      );
+      const spinner = <SpinnerPlugin.Spinner>this.GetObject("obj_spinner");
+      spinner.setVisible(true);
       if (!networkManager) {
         throw new Error("NetworkManager is not defined");
       }
-
       const playerName = (this.GetObject<Phaser.GameObjects.DOMElement>(
         "obj_playerForm"
       )?.getChildByName("nameInput") as Element & { value: string })!.value;
-      await networkManager?.hostAndJoinSession(
-        `${playerName}`
-      );
-
-      console.log("[client id] : ", networkManager?.getClientId());
+      await networkManager?.hostAndJoinSession(`${playerName}`);
       this.scene.start(CONSTANT.SCENES.SESSIONLOBBY);
     } catch (error) {
       console.log(error);
diff --git a/public/soldiers/BaseSoldier.ts b/public/soldiers/BaseSoldier.ts
index b055574..65c0bb5 100644
--- a/public/soldiers/BaseSoldier.ts
+++ b/public/soldiers/BaseSoldier.ts
@@ -1,6 +1,7 @@
 import CONSTANTS from "../constant";
 import SessionStateClientHelpers from "../helpers/SessionStateClientHelpers";
 import LoadingBar from "../LoadingBar";
+import SAT from 'sat';
 import { NetworkManager } from "../NetworkManager";
 const GAMEEVENTS = CONSTANTS.GAMEEVENTS;
 class BackgroundHighlight extends Phaser.GameObjects.Graphics {
@@ -49,7 +50,7 @@ class BackgroundHighlight extends Phaser.GameObjects.Graphics {
   }
 }
 export class BaseSoldier extends Phaser.GameObjects.Sprite {
-  id: string;
+  readonly id: string;
   initialParam: any;
   color: number[];
   expectedPositionX: number;
@@ -58,6 +59,7 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite {
   highlightBackground: BackgroundHighlight;
   DEBUGTEXT: Phaser.GameObjects.Text;
   playerId: string | null;
+
   /**
    * @param {*} scene
    * @param {number} x
@@ -81,7 +83,6 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite {
     scene.add.existing(this);
     this.setInteractive();
     this.id = id;
-    console.log("BASESOLDIER ", this.id);
     this.playerId = playerId;
 
     scene.events.on("update", this.update, this);
@@ -123,7 +124,7 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite {
     const networkManager = this?.scene?.registry?.get(
       "networkManager"
     ) as NetworkManager;
-    if(!networkManager) {
+    if (!networkManager) {
       console.log(
         `Could not find network-manager for soldier :${this.id}, most likely is deleted from scene (value of scene : ${this.scene})`
       );
@@ -131,15 +132,10 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite {
     }
 
     const session = networkManager.getState();
-    const clientId = networkManager.getClientId()
-    if(!session || !clientId) 
-      return;
-    const playerState = SessionStateClientHelpers.getPlayer(
-      session,
-      clientId
-    );
-    if(!playerState)
-        return;
+    const clientId = networkManager.getClientId();
+    if (!session || !clientId) return;
+    const playerState = SessionStateClientHelpers.getPlayer(session, clientId);
+    if (!playerState) return;
 
     const soldierState = SessionStateClientHelpers.getSoldier(
       session,