diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 06f3b391..5521d8f2 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1,9 +1,9 @@ -import {Queue} from 'queue-typescript'; -import type {Subscription} from "rxjs"; -import {GlobalMessageManager} from "../../Administration/GlobalMessageManager"; -import {userMessageManager} from "../../Administration/UserMessageManager"; -import {iframeListener} from "../../Api/IframeListener"; -import {connectionManager} from "../../Connexion/ConnectionManager"; +import { Queue } from 'queue-typescript'; +import type { Subscription } from "rxjs"; +import { GlobalMessageManager } from "../../Administration/GlobalMessageManager"; +import { userMessageManager } from "../../Administration/UserMessageManager"; +import { iframeListener } from "../../Api/IframeListener"; +import { connectionManager } from "../../Connexion/ConnectionManager"; import type { GroupCreatedUpdatedMessageInterface, MessageUserJoined, @@ -14,25 +14,25 @@ import type { PositionInterface, RoomJoinedMessageInterface } from "../../Connexion/ConnexionModels"; -import {localUserStore} from "../../Connexion/LocalUserStore"; -import {Room} from "../../Connexion/Room"; -import type {RoomConnection} from "../../Connexion/RoomConnection"; -import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream"; +import { localUserStore } from "../../Connexion/LocalUserStore"; +import { Room } from "../../Connexion/Room"; +import type { RoomConnection } from "../../Connexion/RoomConnection"; +import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream"; import { DEBUG_MODE, JITSI_PRIVATE_MODE, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; -import {TextureError} from "../../Exception/TextureError"; -import type {UserMovedMessage} from "../../Messages/generated/messages_pb"; -import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils"; -import {touchScreenManager} from "../../Touch/TouchScreenManager"; -import {urlManager} from "../../Url/UrlManager"; -import {audioManager} from "../../WebRtc/AudioManager"; -import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager"; -import {HtmlUtils} from "../../WebRtc/HtmlUtils"; -import {jitsiFactory} from "../../WebRtc/JitsiFactory"; +import { TextureError } from "../../Exception/TextureError"; +import type { UserMovedMessage } from "../../Messages/generated/messages_pb"; +import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils"; +import { touchScreenManager } from "../../Touch/TouchScreenManager"; +import { urlManager } from "../../Url/UrlManager"; +import { audioManager } from "../../WebRtc/AudioManager"; +import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager"; +import { HtmlUtils } from "../../WebRtc/HtmlUtils"; +import { jitsiFactory } from "../../WebRtc/JitsiFactory"; import { AUDIO_LOOP_PROPERTY, AUDIO_VOLUME_PROPERTY, Box, @@ -43,44 +43,43 @@ import { TRIGGER_WEBSITE_PROPERTIES, WEBSITE_MESSAGE_PROPERTIES } from "../../WebRtc/LayoutManager"; -import {mediaManager} from "../../WebRtc/MediaManager"; -import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; -import {lazyLoadCompanionResource} from "../Companion/CompanionTexturesLoadingManager"; -import {ChatModeIcon} from "../Components/ChatModeIcon"; -import {addLoader} from "../Components/Loader"; -import {joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey} from "../Components/MobileJoystick"; -import {OpenChatIcon, openChatIconName} from "../Components/OpenChatIcon"; -import {PresentationModeIcon} from "../Components/PresentationModeIcon"; -import {TextUtils} from "../Components/TextUtils"; -import {lazyLoadPlayerCharacterTextures, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager"; -import {RemotePlayer} from "../Entity/RemotePlayer"; -import type {ActionableItem} from "../Items/ActionableItem"; -import type {ItemFactoryInterface} from "../Items/ItemFactoryInterface"; -import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCharacterScene"; +import { mediaManager } from "../../WebRtc/MediaManager"; +import { SimplePeer, UserSimplePeerInterface } from "../../WebRtc/SimplePeer"; +import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; +import { ChatModeIcon } from "../Components/ChatModeIcon"; +import { addLoader } from "../Components/Loader"; +import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; +import { OpenChatIcon, openChatIconName } from "../Components/OpenChatIcon"; +import { PresentationModeIcon } from "../Components/PresentationModeIcon"; +import { TextUtils } from "../Components/TextUtils"; +import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager"; +import { RemotePlayer } from "../Entity/RemotePlayer"; +import type { ActionableItem } from "../Items/ActionableItem"; +import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface"; +import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene"; import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapObject, ITiledMapTileLayer, - ITiledTileSet -} from "../Map/ITiledMap"; -import {MenuScene, MenuSceneName} from '../Menu/MenuScene'; -import {PlayerAnimationDirections} from "../Player/Animation"; -import {hasMovedEventName, Player, requestEmoteEventName} from "../Player/Player"; -import {ErrorSceneName} from "../Reconnecting/ErrorScene"; -import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; -import {waScaleManager} from "../Services/WaScaleManager"; -import {PinchManager} from "../UserInput/PinchManager"; -import {UserInputManager} from "../UserInput/UserInputManager"; -import type {AddPlayerInterface} from "./AddPlayerInterface"; -import {DEPTH_OVERLAY_INDEX} from "./DepthIndexes"; -import {DirtyScene} from "./DirtyScene"; -import {EmoteManager} from "./EmoteManager"; -import {gameManager} from "./GameManager"; -import {GameMap} from "./GameMap"; -import {PlayerMovement} from "./PlayerMovement"; -import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator"; + ITiledTileSet } from "../Map/ITiledMap"; +import { MenuScene, MenuSceneName } from '../Menu/MenuScene'; +import { PlayerAnimationDirections } from "../Player/Animation"; +import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player"; +import { ErrorSceneName } from "../Reconnecting/ErrorScene"; +import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene"; +import { waScaleManager } from "../Services/WaScaleManager"; +import { PinchManager } from "../UserInput/PinchManager"; +import { UserInputManager } from "../UserInput/UserInputManager"; +import type { AddPlayerInterface } from "./AddPlayerInterface"; +import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; +import { DirtyScene } from "./DirtyScene"; +import { EmoteManager } from "./EmoteManager"; +import { gameManager } from "./GameManager"; +import { GameMap } from "./GameMap"; +import { PlayerMovement } from "./PlayerMovement"; +import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator"; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; import CanvasTexture = Phaser.Textures.CanvasTexture; @@ -90,7 +89,7 @@ import DOMElement = Phaser.GameObjects.DOMElement; import EVENT_TYPE = Phaser.Scenes.Events import RenderTexture = Phaser.GameObjects.RenderTexture; import Tilemap = Phaser.Tilemaps.Tilemap; -import type {HasPlayerMovedEvent} from '../../Api/Events/HasPlayerMovedEvent'; +import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent'; import AnimatedTiles from "phaser-animated-tiles"; import {soundManager} from "./SoundManager"; @@ -218,14 +217,14 @@ export class GameScene extends DirtyScene { preload(): void { const localUser = localUserStore.getLocalUser(); const textures = localUser?.textures; - if(textures) { - for(const texture of textures) { + if (textures) { + for (const texture of textures) { loadCustomTexture(this.load, texture); } } this.load.image(openChatIconName, 'resources/objects/talk.png'); - if(touchScreenManager.supportTouchScreen) { + if (touchScreenManager.supportTouchScreen) { this.load.image(joystickBaseKey, joystickBaseImg); this.load.image(joystickThumbKey, joystickThumbImg); } @@ -234,9 +233,9 @@ export class GameScene extends DirtyScene { //this.load.audio('audio-report-message', '/resources/objects/report-message.mp3'); this.sound.pauseOnBlur = false; - this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => { + this.load.on(FILE_LOAD_ERROR, (file: { src: string }) => { // If we happen to be in HTTP and we are trying to load a URL in HTTPS only... (this happens only in dev environments) - if(window.location.protocol === 'http:' && file.src === this.MapUrlFile && file.src.startsWith('http:') && this.originalMapUrl === undefined) { + if (window.location.protocol === 'http:' && file.src === this.MapUrlFile && file.src.startsWith('http:') && this.originalMapUrl === undefined) { this.originalMapUrl = this.MapUrlFile; this.MapUrlFile = this.MapUrlFile.replace('http://', 'https://'); this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); @@ -250,7 +249,7 @@ export class GameScene extends DirtyScene { // See https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure const url = new URL(file.src); const host = url.host.split(':')[0]; - if(window.location.protocol === 'https:' && file.src === this.MapUrlFile && (host === '127.0.0.1' || host === 'localhost' || host.endsWith('.localhost')) && this.originalMapUrl === undefined) { + if (window.location.protocol === 'https:' && file.src === this.MapUrlFile && (host === '127.0.0.1' || host === 'localhost' || host.endsWith('.localhost')) && this.originalMapUrl === undefined) { this.originalMapUrl = this.MapUrlFile; this.MapUrlFile = this.MapUrlFile.replace('https://', 'http://'); this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); @@ -274,7 +273,7 @@ export class GameScene extends DirtyScene { this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); // If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered. // In this case, we check in the cache to see if the map is here and trigger the event manually. - if(this.cache.tilemap.exists(this.MapUrlFile)) { + if (this.cache.tilemap.exists(this.MapUrlFile)) { const data = this.cache.tilemap.get(this.MapUrlFile); this.onMapLoad(data); } @@ -301,7 +300,7 @@ export class GameScene extends DirtyScene { this.mapFile = data.data; const url = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/')); this.mapFile.tilesets.forEach((tileset) => { - if(typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') { + if (typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') { console.warn("Don't know how to handle tileset ", tileset) return; } @@ -312,15 +311,15 @@ export class GameScene extends DirtyScene { // Scan the object layers for objects to load and load them. const objects = new Map(); - for(const layer of this.mapFile.layers) { - if(layer.type === 'objectgroup') { - for(const object of layer.objects) { + for (const layer of this.mapFile.layers) { + if (layer.type === 'objectgroup') { + for (const object of layer.objects) { let objectsOfType: ITiledMapObject[] | undefined; - if(!objects.has(object.type)) { + if (!objects.has(object.type)) { objectsOfType = new Array(); } else { objectsOfType = objects.get(object.type); - if(objectsOfType === undefined) { + if (objectsOfType === undefined) { throw new Error('Unexpected object type not found'); } } @@ -330,12 +329,12 @@ export class GameScene extends DirtyScene { } } - for(const [itemType, objectsOfType] of objects) { + for (const [itemType, objectsOfType] of objects) { // FIXME: we would ideally need for the loader to WAIT for the import to be performed, which means writing our own loader plugin. let itemFactory: ItemFactoryInterface; - switch(itemType) { + switch (itemType) { case 'computer': { const module = await import('../Items/Computer/computer'); itemFactory = module.default; @@ -357,7 +356,7 @@ export class GameScene extends DirtyScene { const roomJoinedAnswer = await this.connectionAnswerPromise; - for(const object of objectsOfType) { + for (const object of objectsOfType) { // TODO: we should pass here a factory to create sprites (maybe?) // Do we have a state for this object? @@ -372,17 +371,17 @@ export class GameScene extends DirtyScene { // Now, let's load the script, if any const scripts = this.getScriptUrls(this.mapFile); - for(const script of scripts) { + for (const script of scripts) { iframeListener.registerScript(script); } } //hook initialisation init(initData: GameSceneInitInterface) { - if(initData.initPosition !== undefined) { + if (initData.initPosition !== undefined) { this.initPosition = initData.initPosition; //todo: still used? } - if(initData.initPosition !== undefined) { + if (initData.initPosition !== undefined) { this.isReconnecting = initData.reconnecting; } } @@ -395,14 +394,14 @@ export class GameScene extends DirtyScene { urlManager.pushRoomIdToUrl(this.room); this.startLayerName = urlManager.getStartLayerNameFromUrl(); - if(touchScreenManager.supportTouchScreen) { + if (touchScreenManager.supportTouchScreen) { this.pinchManager = new PinchManager(this); } this.messageSubscription = worldFullMessageStream.stream.subscribe((message) => this.showWorldFullError(message)) const playerName = gameManager.getPlayerName(); - if(!playerName) { + if (!playerName) { throw 'playerName is not set'; } this.playerName = playerName; @@ -421,21 +420,21 @@ export class GameScene extends DirtyScene { //add layer on map this.gameMap = new GameMap(this.mapFile, this.Map, this.Terrains); - for(const layer of this.gameMap.flatLayers) { - if(layer.type === 'tilelayer') { + for (const layer of this.gameMap.flatLayers) { + if (layer.type === 'tilelayer') { const exitSceneUrl = this.getExitSceneUrl(layer); - if(exitSceneUrl !== undefined) { + if (exitSceneUrl !== undefined) { this.loadNextGame(exitSceneUrl); } const exitUrl = this.getExitUrl(layer); - if(exitUrl !== undefined) { + if (exitUrl !== undefined) { this.loadNextGame(exitUrl); } } - if(layer.type === 'objectgroup') { - for(const object of layer.objects) { - if(object.text) { + if (layer.type === 'objectgroup') { + for (const object of layer.objects) { + if (object.text) { TextUtils.createTextFromITiledMapObject(this, object); } } @@ -452,14 +451,14 @@ export class GameScene extends DirtyScene { this.Objects = new Array(); //initialise list of other player - this.MapPlayers = this.physics.add.group({immovable: true}); + this.MapPlayers = this.physics.add.group({ immovable: true }); //create input to move this.userInputManager = new UserInputManager(this); mediaManager.setUserInputManager(this.userInputManager); - if(localUserStore.getFullscreen()) { + if (localUserStore.getFullscreen()) { document.querySelector('body')?.requestFullscreen(); } @@ -475,16 +474,16 @@ export class GameScene extends DirtyScene { this.initCirclesCanvas(); // Let's pause the scene if the connection is not established yet - if(!this.room.isDisconnected()) { - if(this.isReconnecting) { + if (!this.room.isDisconnected()) { + if (this.isReconnecting) { setTimeout(() => { this.scene.sleep(); this.scene.launch(ReconnectingSceneName); }, 0); - } else if(this.connection === undefined) { + } else if (this.connection === undefined) { // Let's wait 1 second before printing the "connecting" screen to avoid blinking setTimeout(() => { - if(this.connection === undefined) { + if (this.connection === undefined) { this.scene.sleep(); this.scene.launch(ReconnectingSceneName); } @@ -509,7 +508,7 @@ export class GameScene extends DirtyScene { this.listenToIframeEvents(); - if(!this.room.isDisconnected()) { + if (!this.room.isDisconnected()) { this.connect(); } @@ -518,11 +517,11 @@ export class GameScene extends DirtyScene { let oldPeerNumber = 0; this.peerStoreUnsubscribe = peerStore.subscribe((peers) => { const newPeerNumber = peers.size; - if(newPeerNumber > oldPeerNumber) { + if (newPeerNumber > oldPeerNumber) { this.sound.play('audio-webrtc-in', { volume: 0.2 }); - } else if(newPeerNumber < oldPeerNumber) { + } else if (newPeerNumber < oldPeerNumber) { this.sound.play('audio-webrtc-out', { volume: 0.2 }); @@ -569,7 +568,7 @@ export class GameScene extends DirtyScene { this.connection.onUserMoved((message: UserMovedMessage) => { const position = message.getPosition(); - if(position === undefined) { + if (position === undefined) { throw new Error('Position missing from UserMovedMessage'); } @@ -592,7 +591,7 @@ export class GameScene extends DirtyScene { this.connection.onGroupDeleted((groupId: number) => { try { this.deleteGroup(groupId); - } catch(e) { + } catch (e) { console.error(e); } }) @@ -618,7 +617,7 @@ export class GameScene extends DirtyScene { this.connection.onActionableEvent((message => { const item = this.actionableItems.get(message.itemId); - if(item === undefined) { + if (item === undefined) { console.warn('Received an event about object "' + message.itemId + '" but cannot find this item on the map.'); return; } @@ -647,7 +646,7 @@ export class GameScene extends DirtyScene { audioManager.decreaseVolume(); }, onDisconnect(userId: number) { - if(self.simplePeer.getNbConnections() === 0) { + if (self.simplePeer.getNbConnections() === 0) { self.openChatIcon.setVisible(false); audioManager.restoreVolume(); } @@ -678,12 +677,12 @@ export class GameScene extends DirtyScene { private initCirclesCanvas(): void { // Let's generate the circle for the group delimiter let circleElement = Object.values(this.textures.list).find((object: Texture) => object.key === 'circleSprite-white'); - if(circleElement) { + if (circleElement) { this.textures.remove('circleSprite-white'); } circleElement = Object.values(this.textures.list).find((object: Texture) => object.key === 'circleSprite-red'); - if(circleElement) { + if (circleElement) { this.textures.remove('circleSprite-red'); } @@ -712,7 +711,7 @@ export class GameScene extends DirtyScene { private safeParseJSONstring(jsonString: string | undefined, propertyName: string) { try { return jsonString ? JSON.parse(jsonString) : {}; - } catch(e) { + } catch (e) { console.warn('Invalid JSON found in property "' + propertyName + '" of the map:' + jsonString, e); return {} } @@ -720,13 +719,13 @@ export class GameScene extends DirtyScene { private triggerOnMapLayerPropertyChange() { this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => { - if(newValue) this.onMapExit(newValue as string); + if (newValue) this.onMapExit(newValue as string); }); this.gameMap.onPropertyChange('exitUrl', (newValue, oldValue) => { - if(newValue) this.onMapExit(newValue as string); + if (newValue) this.onMapExit(newValue as string); }); this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue, allProps) => { - if(newValue === undefined) { + if (newValue === undefined) { layoutManager.removeActionButton('openWebsite', this.userInputManager); coWebsiteManager.closeCoWebsite(); } else { @@ -736,9 +735,9 @@ export class GameScene extends DirtyScene { }; const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); - if(openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { + if (openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES); - if(message === undefined) { + if (message === undefined) { message = 'Press SPACE or touch here to open web site'; } layoutManager.addActionButton('openWebsite', message.toString(), () => { @@ -750,14 +749,14 @@ export class GameScene extends DirtyScene { } }); this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => { - if(newValue === undefined) { + if (newValue === undefined) { layoutManager.removeActionButton('jitsiRoom', this.userInputManager); this.stopJitsi(); } else { const openJitsiRoomFunction = () => { const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance); const jitsiUrl = allProps.get("jitsiUrl") as string | undefined; - if(JITSI_PRIVATE_MODE && !jitsiUrl) { + if (JITSI_PRIVATE_MODE && !jitsiUrl) { const adminTag = allProps.get("jitsiRoomAdminTag") as string | undefined; this.connection?.emitQueryJitsiJwtMessage(roomName, adminTag); @@ -768,9 +767,9 @@ export class GameScene extends DirtyScene { } const jitsiTriggerValue = allProps.get(TRIGGER_JITSI_PROPERTIES); - if(jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { + if (jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { let message = allProps.get(JITSI_MESSAGE_PROPERTIES); - if(message === undefined) { + if (message === undefined) { message = 'Press SPACE or touch here to enter Jitsi Meet room'; } layoutManager.addActionButton('jitsiRoom', message.toString(), () => { @@ -782,7 +781,7 @@ export class GameScene extends DirtyScene { } }); this.gameMap.onPropertyChange('silent', (newValue, oldValue) => { - if(newValue === undefined || newValue === false || newValue === '') { + if (newValue === undefined || newValue === false || newValue === '') { this.connection?.setSilent(false); } else { this.connection?.setSilent(true); @@ -799,7 +798,7 @@ export class GameScene extends DirtyScene { }); this.gameMap.onPropertyChange('zone', (newValue, oldValue) => { - if(newValue === undefined || newValue === false || newValue === '') { + if (newValue === undefined || newValue === false || newValue === '') { iframeListener.sendLeaveEvent(oldValue as string); } else { @@ -814,7 +813,7 @@ export class GameScene extends DirtyScene { let objectLayerSquare: ITiledMapObject; const targetObjectData = this.getObjectLayerData(openPopupEvent.targetObject); - if(targetObjectData !== undefined) { + if (targetObjectData !== undefined) { objectLayerSquare = targetObjectData; } else { console.error("Error while opening a popup. Cannot find an object on the map with name '" + openPopupEvent.targetObject + "'. The first parameter of WA.openPopup() must be the name of a rectangle object in your map."); @@ -830,7 +829,7 @@ export class GameScene extends DirtyScene { const buttonContainer = `
`; html += buttonContainer; let id = 0; - for(const button of openPopupEvent.buttons) { + for (const button of openPopupEvent.buttons) { html += ``; id++; } @@ -848,7 +847,7 @@ export class GameScene extends DirtyScene { }, 100); id = 0; - for(const button of openPopupEvent.buttons) { + for (const button of openPopupEvent.buttons) { const button = HtmlUtils.getElementByIdOrFail(`popup-${openPopupEvent.popupId}-${id}`); const btnId = id; button.onclick = () => { @@ -872,7 +871,7 @@ export class GameScene extends DirtyScene { this.iframeSubscriptionList.push(iframeListener.closePopupStream.subscribe((closePopupEvent) => { const popUpElement = this.popUpElements.get(closePopupEvent.popupId); - if(popUpElement === undefined) { + if (popUpElement === undefined) { console.error('Could not close popup with ID ', closePopupEvent.popupId, '. Maybe it has already been closed?'); } @@ -951,7 +950,7 @@ export class GameScene extends DirtyScene { this.setLayerVisibility(layerEvent.name, true); })); - this.iframeSubscriptionList.push(iframeListener.hideLayerStream.subscribe((layerEvent) => { + this.iframeSubscriptionList.push(iframeListener.hideLayerStream.subscribe((layerEvent)=>{ this.setLayerVisibility(layerEvent.name, false); })); @@ -978,22 +977,22 @@ export class GameScene extends DirtyScene { private setPropertyLayer(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void { const layer = this.gameMap.findLayer(layerName); - if(layer === undefined) { + if (layer === undefined) { console.warn('Could not find layer "' + layerName + '" when calling setProperty'); return; } - const property = (layer.properties as ITiledMapLayerProperty[])?.find((property) => property.name === propertyName); - if(property === undefined) { - layer.properties = []; - layer.properties.push({name: propertyName, type: typeof propertyValue, value: propertyValue}); - return; - } - property.value = propertyValue; + const property = (layer.properties as ITiledMapLayerProperty[])?.find((property) => property.name === propertyName); + if (property === undefined) { + layer.properties = []; + layer.properties.push({name : propertyName, type : typeof propertyValue, value : propertyValue}); + return; + } + property.value = propertyValue; } private setLayerVisibility(layerName: string, visible: boolean): void { const phaserLayer = this.gameMap.findPhaserLayer(layerName); - if(phaserLayer === undefined) { + if (phaserLayer === undefined) { console.warn('Could not find layer "' + layerName + '" when calling WA.hideLayer / WA.showLayer'); return; } @@ -1007,15 +1006,15 @@ export class GameScene extends DirtyScene { } private onMapExit(exitKey: string) { - if(this.mapTransitioning) return; + if (this.mapTransitioning) return; this.mapTransitioning = true; - const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance); - if(!roomId) throw new Error('Could not find the room from its exit key: ' + exitKey); + const { roomId, hash } = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance); + if (!roomId) throw new Error('Could not find the room from its exit key: ' + exitKey); urlManager.pushStartLayerNameToUrl(hash); const menuScene: MenuScene = this.scene.get(MenuSceneName) as MenuScene menuScene.reset() - if(roomId !== this.scene.key) { - if(this.scene.get(roomId) === null) { + if (roomId !== this.scene.key) { + if (this.scene.get(roomId) === null) { console.error("next room not loaded", exitKey); return; } @@ -1037,7 +1036,7 @@ export class GameScene extends DirtyScene { coWebsiteManager.closeCoWebsite(); // Stop the script, if any const scripts = this.getScriptUrls(this.mapFile); - for(const script of scripts) { + for (const script of scripts) { iframeListener.unregisterScript(script); } @@ -1056,7 +1055,7 @@ export class GameScene extends DirtyScene { mediaManager.hideGameOverlay(); - for(const iframeEvents of this.iframeSubscriptionList) { + for (const iframeEvents of this.iframeSubscriptionList) { iframeEvents.unsubscribe(); } } @@ -1065,7 +1064,7 @@ export class GameScene extends DirtyScene { this.MapPlayersByKey.forEach((player: RemotePlayer) => { player.destroy(); - if(player.companion) { + if (player.companion) { player.companion.destroy(); } @@ -1076,21 +1075,21 @@ export class GameScene extends DirtyScene { private initStartXAndStartY() { // If there is an init position passed - if(this.initPosition !== null) { + if (this.initPosition !== null) { this.startX = this.initPosition.x; this.startY = this.initPosition.y; } else { // Now, let's find the start layer - if(this.startLayerName) { + if (this.startLayerName) { this.initPositionFromLayerName(this.startLayerName); } - if(this.startX === undefined) { + if (this.startX === undefined) { // If we have no start layer specified or if the hash passed does not exist, let's go with the default start position. this.initPositionFromLayerName(defaultStartLayerName); } } // Still no start position? Something is wrong with the map, we need a "start" layer. - if(this.startX === undefined) { + if (this.startX === undefined) { console.warn('This map is missing a layer named "start" that contains the available default start positions.'); // Let's start in the middle of the map this.startX = this.mapFile.width * 16; @@ -1099,8 +1098,8 @@ export class GameScene extends DirtyScene { } private initPositionFromLayerName(layerName: string) { - for(const layer of this.gameMap.flatLayers) { - if((layerName === layer.name || layer.name.endsWith('/' + layerName)) && layer.type === 'tilelayer' && (layerName === defaultStartLayerName || this.isStartLayer(layer))) { + for (const layer of this.gameMap.flatLayers) { + if ((layerName === layer.name || layer.name.endsWith('/' + layerName)) && layer.type === 'tilelayer' && (layerName === defaultStartLayerName || this.isStartLayer(layer))) { const startPosition = this.startUser(layer); this.startX = startPosition.x + this.mapFile.tilewidth / 2; this.startY = startPosition.y + this.mapFile.tileheight / 2; @@ -1130,11 +1129,11 @@ export class GameScene extends DirtyScene { private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined { const properties: ITiledMapLayerProperty[] | undefined = layer.properties; - if(!properties) { + if (!properties) { return undefined; } const obj = properties.find((property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()); - if(obj === undefined) { + if (obj === undefined) { return undefined; } return obj.value; @@ -1142,36 +1141,36 @@ export class GameScene extends DirtyScene { private getProperties(layer: ITiledMapLayer | ITiledMap, name: string): (string | number | boolean | undefined)[] { const properties: ITiledMapLayerProperty[] | undefined = layer.properties; - if(!properties) { + if (!properties) { return []; } return properties.filter((property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()).map((property) => property.value); } //todo: push that into the gameManager - private loadNextGame(exitSceneIdentifier: string): Promise { - const {roomId, hash} = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance); + private loadNextGame(exitSceneIdentifier: string) : Promise{ + const { roomId, hash } = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance); const room = new Room(roomId); - return gameManager.loadMap(room, this.scene).catch(() => {}); + return gameManager.loadMap(room, this.scene).catch(() => { }); } private startUser(layer: ITiledMapTileLayer): PositionInterface { const tiles = layer.data; - if(typeof (tiles) === 'string') { + if (typeof (tiles) === 'string') { throw new Error('The content of a JSON map must be filled as a JSON array, not as a string'); } const possibleStartPositions: PositionInterface[] = []; tiles.forEach((objectKey: number, key: number) => { - if(objectKey === 0) { + if (objectKey === 0) { return; } const y = Math.floor(key / layer.width); const x = key % layer.width; - possibleStartPositions.push({x: x * this.mapFile.tilewidth, y: y * this.mapFile.tilewidth}); + possibleStartPositions.push({ x: x * this.mapFile.tilewidth, y: y * this.mapFile.tilewidth }); }); // Get a value at random amongst allowed values - if(possibleStartPositions.length === 0) { + if (possibleStartPositions.length === 0) { console.warn('The start layer "' + layer.name + '" for this map is empty.'); return { x: 0, @@ -1191,12 +1190,12 @@ export class GameScene extends DirtyScene { createCollisionWithPlayer() { //add collision layer - for(const phaserLayer of this.gameMap.phaserLayers) { + for (const phaserLayer of this.gameMap.phaserLayers) { this.physics.add.collider(this.CurrentPlayer, phaserLayer, (object1: GameObject, object2: GameObject) => { //this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name) }); phaserLayer.setCollisionByProperty({collides: true}); - if(DEBUG_MODE) { + if (DEBUG_MODE) { //debug code to see the collision hitbox of the object in the top layer phaserLayer.renderDebug(this.add.graphics(), { tileColor: null, //non-colliding tiles @@ -1225,7 +1224,7 @@ export class GameScene extends DirtyScene { this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); this.CurrentPlayer.on('pointerdown', (pointer: Phaser.Input.Pointer) => { - if(pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) { + if (pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) { return; //we don't want the menu to open when pinching on a touch screen. } this.emoteManager.getMenuImages().then((emoteMenuElements) => this.CurrentPlayer.openOrCloseEmoteMenu(emoteMenuElements)) @@ -1233,8 +1232,8 @@ export class GameScene extends DirtyScene { this.CurrentPlayer.on(requestEmoteEventName, (emoteKey: string) => { this.connection?.emitEmoteEvent(emoteKey); }) - } catch(err) { - if(err instanceof TextureError) { + } catch (err) { + if (err instanceof TextureError) { gameManager.leaveGame(this, SelectCharacterSceneName, new SelectCharacterScene()); } throw err; @@ -1245,24 +1244,24 @@ export class GameScene extends DirtyScene { } pushPlayerPosition(event: HasPlayerMovedEvent) { - if(this.lastMoveEventSent === event) { + if (this.lastMoveEventSent === event) { return; } // If the player is not moving, let's send the info right now. - if(event.moving === false) { + if (event.moving === false) { this.doPushPlayerPosition(event); return; } // If the player is moving, and if it changed direction, let's send an event - if(event.direction !== this.lastMoveEventSent.direction) { + if (event.direction !== this.lastMoveEventSent.direction) { this.doPushPlayerPosition(event); return; } // If more than 200ms happened since last event sent - if(this.currentTick - this.lastSentTick >= POSITION_DELAY) { + if (this.currentTick - this.lastSentTick >= POSITION_DELAY) { this.doPushPlayerPosition(event); return; } @@ -1277,7 +1276,7 @@ export class GameScene extends DirtyScene { private outlineItem(event: HasPlayerMovedEvent): void { let x = event.x; let y = event.y; - switch(event.direction) { + switch (event.direction) { case PlayerAnimationDirections.Up: y -= 32; break; @@ -1296,15 +1295,15 @@ export class GameScene extends DirtyScene { let shortestDistance: number = Infinity; let selectedItem: ActionableItem | null = null; - for(const item of this.actionableItems.values()) { + for (const item of this.actionableItems.values()) { const distance = item.actionableDistance(x, y); - if(distance !== null && distance < shortestDistance) { + if (distance !== null && distance < shortestDistance) { shortestDistance = distance; selectedItem = item; } } - if(this.outlinedItem === selectedItem) { + if (this.outlinedItem === selectedItem) { return; } @@ -1336,10 +1335,10 @@ export class GameScene extends DirtyScene { this.CurrentPlayer.moveUser(delta); // Let's handle all events - while(this.pendingEvents.length !== 0) { + while (this.pendingEvents.length !== 0) { this.dirty = true; const event = this.pendingEvents.dequeue(); - switch(event.type) { + switch (event.type) { case "InitUserPositionEvent": this.doInitUsersPosition(event.event); break; @@ -1365,7 +1364,7 @@ export class GameScene extends DirtyScene { updatedPlayersPositions.forEach((moveEvent: HasPlayerMovedEvent, userId: number) => { this.dirty = true; const player: RemotePlayer | undefined = this.MapPlayersByKey.get(userId); - if(player === undefined) { + if (player === undefined) { throw new Error('Cannot find player with ID "' + userId + '"'); } player.updatePosition(moveEvent); @@ -1390,7 +1389,7 @@ export class GameScene extends DirtyScene { this.removeAllRemotePlayers(); // load map usersPosition.forEach((userPosition: MessageUserPositionInterface) => { - if(userPosition.userId === currentPlayerId) { + if (userPosition.userId === currentPlayerId) { return; } this.addPlayer(userPosition); @@ -1409,7 +1408,7 @@ export class GameScene extends DirtyScene { private doAddPlayer(addPlayerData: AddPlayerInterface): void { //check if exist player, if exist, move position - if(this.MapPlayersByKey.has(addPlayerData.userId)) { + if (this.MapPlayersByKey.has(addPlayerData.userId)) { this.updatePlayerPosition({ userId: addPlayerData.userId, position: addPlayerData.position @@ -1448,12 +1447,12 @@ export class GameScene extends DirtyScene { private doRemovePlayer(userId: number) { const player = this.MapPlayersByKey.get(userId); - if(player === undefined) { + if (player === undefined) { console.error('Cannot find user with id ', userId); } else { player.destroy(); - if(player.companion) { + if (player.companion) { player.companion.destroy(); } @@ -1472,7 +1471,7 @@ export class GameScene extends DirtyScene { private doUpdatePlayerPosition(message: MessageUserMovedInterface): void { const player: RemotePlayer | undefined = this.MapPlayersByKey.get(message.userId); - if(player === undefined) { + if (player === undefined) { //throw new Error('Cannot find player with ID "' + message.userId +'"'); console.error('Cannot update position of player with ID "' + message.userId + '": player not found'); return; @@ -1480,7 +1479,7 @@ export class GameScene extends DirtyScene { // We do not update the player position directly (because it is sent only every 200ms). // Instead we use the PlayersPositionInterpolator that will do a smooth animation over the next 200ms. - const playerMovement = new PlayerMovement({x: player.x, y: player.y}, this.currentTick, message.position, this.currentTick + POSITION_DELAY); + const playerMovement = new PlayerMovement({ x: player.x, y: player.y }, this.currentTick, message.position, this.currentTick + POSITION_DELAY); this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement); } @@ -1518,7 +1517,7 @@ export class GameScene extends DirtyScene { doDeleteGroup(groupId: number): void { const group = this.groups.get(groupId); - if(!group) { + if (!group) { return; } group.destroy(); @@ -1548,10 +1547,10 @@ export class GameScene extends DirtyScene { }); } private getObjectLayerData(objectName: string): ITiledMapObject | undefined { - for(const layer of this.mapFile.layers) { - if(layer.type === 'objectgroup' && layer.name === 'floorLayer') { - for(const object of layer.objects) { - if(object.name === objectName) { + for (const layer of this.mapFile.layers) { + if (layer.type === 'objectgroup' && layer.name === 'floorLayer') { + for (const object of layer.objects) { + if (object.name === objectName) { return object; } } @@ -1650,7 +1649,7 @@ export class GameScene extends DirtyScene { this.scene.remove(ReconnectingSceneName); this.userInputManager.disableControls(); //FIX ME to use status code - if(message == undefined) { + if (message == undefined) { this.scene.start(ErrorSceneName, { title: 'Connection rejected', subTitle: 'The world you are trying to join is full. Try again later.',