From fe570c9117926707d7bbd550cba2fa07bca9e747 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 9 Feb 2022 10:17:31 +0100 Subject: [PATCH 1/8] moveTo object position --- front/src/Phaser/Game/GameMap.ts | 4 +++ front/src/Phaser/Game/GameScene.ts | 49 ++++++++++++++++++------------ maps/tests/move_to.json | 33 ++++++++++++++++++-- 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 7e9a486d..8e377ae7 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -323,6 +323,10 @@ export class GameMap { throw new Error("No possible position found"); } + public getObjectWithName(name: string): ITiledMapObject | undefined { + return this.tiledObjects.find((object) => object.name === name); + } + private getLayersByKey(key: number): Array { return this.flatLayers.filter((flatLayer) => flatLayer.type === "tilelayer" && flatLayer.data[key] !== 0); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 9b758a45..44992d85 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -568,6 +568,8 @@ export class GameScene extends DirtyScene { this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted + this.tryMovePlayerWithMoveToParameter(); + this.cameraManager = new CameraManager( this, { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, @@ -1460,9 +1462,9 @@ ${escapedMessage} }); iframeListener.registerAnswerer("movePlayerTo", async (message) => { - const index = this.getGameMap().getTileIndexAt(message.x, message.y); - const startTile = this.getGameMap().getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y); - const path = await this.getPathfindingManager().findPath(startTile, index, true, true); + const startTileIndex = this.getGameMap().getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y); + const destinationTileIndex = this.getGameMap().getTileIndexAt(message.x, message.y); + const path = await this.getPathfindingManager().findPath(startTileIndex, destinationTileIndex, true, true); path.shift(); if (path.length === 0) { throw new Error("no path available"); @@ -1626,6 +1628,31 @@ ${escapedMessage} this.MapPlayersByKey.clear(); } + private tryMovePlayerWithMoveToParameter(): void { + const moveToParam = urlManager.getHashParameter("moveTo"); + if (moveToParam) { + try { + const destinationObject = this.gameMap.getObjectWithName(moveToParam); + let endPos; + if (destinationObject) { + endPos = this.gameMap.getTileIndexAt(destinationObject.x, destinationObject.y); + } else { + endPos = this.gameMap.getRandomPositionFromLayer(moveToParam); + } + this.pathfindingManager + .findPath(this.gameMap.getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y), endPos) + .then((path) => { + if (path && path.length > 0) { + this.CurrentPlayer.setPathToFollow(path).catch((reason) => console.warn(reason)); + } + }) + .catch((reason) => console.warn(reason)); + } catch (err) { + console.warn(`Cannot proceed with moveTo command:\n\t-> ${err}`); + } + } + } + private getExitUrl(layer: ITiledMapLayer): string | undefined { return this.getProperty(layer, GameMapProperties.EXIT_URL) as string | undefined; } @@ -1748,22 +1775,6 @@ ${escapedMessage} this.connection?.emitEmoteEvent(emoteKey); analyticsClient.launchEmote(emoteKey); }); - const moveToParam = urlManager.getHashParameter("moveTo"); - if (moveToParam) { - try { - const endPos = this.gameMap.getRandomPositionFromLayer(moveToParam); - this.pathfindingManager - .findPath(this.gameMap.getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y), endPos) - .then((path) => { - if (path && path.length > 0) { - this.CurrentPlayer.setPathToFollow(path).catch((reason) => console.warn(reason)); - } - }) - .catch((reason) => console.warn(reason)); - } catch (err) { - console.warn(`Cannot proceed with moveTo command:\n\t-> ${err}`); - } - } } catch (err) { if (err instanceof TextureError) { gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene()); diff --git a/maps/tests/move_to.json b/maps/tests/move_to.json index 796a9d46..6776bd6b 100644 --- a/maps/tests/move_to.json +++ b/maps/tests/move_to.json @@ -3,7 +3,7 @@ "infinite":false, "layers":[ { - "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "height":10, "id":1, "name":"floor", @@ -204,6 +204,35 @@ "width":92.7120717279925, "x":233.848901257569, "y":135.845612785282 + }, + { + "height":0, + "id":9, + "name":"destination", + "point":true, + "rotation":0, + "type":"", + "visible":true, + "width":0, + "x":207.918025151374, + "y":243.31625523987 + }, + { + "height":45.0829063809967, + "id":10, + "name":"", + "rotation":0, + "text": + { + "halign":"center", + "text":"destination object", + "wrap":true + }, + "type":"", + "visible":true, + "width":83, + "x":167.26, + "y":254.682580344667 }], "opacity":1, "type":"objectgroup", @@ -212,7 +241,7 @@ "y":0 }], "nextlayerid":11, - "nextobjectid":9, + "nextobjectid":11, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.7.2", From b565080312f02ee51ba22f7f84327a18b130ad77 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 9 Feb 2022 10:52:44 +0100 Subject: [PATCH 2/8] parse x and y position from moveTo param --- front/src/Phaser/Game/GameScene.ts | 14 ++++++++++---- front/src/Utils/StringUtils.ts | 12 ++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 front/src/Utils/StringUtils.ts diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 44992d85..8d13cb7b 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -92,6 +92,7 @@ import { MapStore } from "../../Stores/Utils/MapStore"; import { followUsersColorStore } from "../../Stores/FollowStore"; import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler"; import { locale } from "../../i18n/i18n-svelte"; +import { StringUtils } from "../../Utils/StringUtils"; export interface GameSceneInitInterface { initPosition: PointInterface | null; reconnecting: boolean; @@ -1632,12 +1633,17 @@ ${escapedMessage} const moveToParam = urlManager.getHashParameter("moveTo"); if (moveToParam) { try { - const destinationObject = this.gameMap.getObjectWithName(moveToParam); let endPos; - if (destinationObject) { - endPos = this.gameMap.getTileIndexAt(destinationObject.x, destinationObject.y); + const posFromParam = StringUtils.parsePointFromParam(moveToParam); + if (posFromParam) { + endPos = this.gameMap.getTileIndexAt(posFromParam.x, posFromParam.y); } else { - endPos = this.gameMap.getRandomPositionFromLayer(moveToParam); + const destinationObject = this.gameMap.getObjectWithName(moveToParam); + if (destinationObject) { + endPos = this.gameMap.getTileIndexAt(destinationObject.x, destinationObject.y); + } else { + endPos = this.gameMap.getRandomPositionFromLayer(moveToParam); + } } this.pathfindingManager .findPath(this.gameMap.getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y), endPos) diff --git a/front/src/Utils/StringUtils.ts b/front/src/Utils/StringUtils.ts new file mode 100644 index 00000000..1f168c15 --- /dev/null +++ b/front/src/Utils/StringUtils.ts @@ -0,0 +1,12 @@ +export class StringUtils { + public static parsePointFromParam(param: string, separator: string = ","): { x: number; y: number } | undefined { + const values = param.split(separator).map((val) => parseInt(val)); + if (values.length !== 2) { + return; + } + if (isNaN(values[0]) || isNaN(values[1])) { + return; + } + return { x: values[0], y: values[1] }; + } +} From 71e18d1838e8b5dd54589e283cc2213039ab6ddd Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 9 Feb 2022 11:05:43 +0100 Subject: [PATCH 3/8] update moveTo test map --- maps/tests/move_to.json | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/maps/tests/move_to.json b/maps/tests/move_to.json index 6776bd6b..0801831a 100644 --- a/maps/tests/move_to.json +++ b/maps/tests/move_to.json @@ -233,6 +233,42 @@ "width":83, "x":167.26, "y":254.682580344667 + }, + { + "height":19.6921, + "id":11, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "pixelsize":13, + "text":"...#start&moveTo=destination", + "wrap":true + }, + "type":"", + "visible":true, + "width":202.260327899394, + "x":32.2652715416861, + "y":148.51445302748 + }, + { + "height":19.6921, + "id":12, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "pixelsize":13, + "text":"...#start2&moveTo=200,100", + "wrap":true + }, + "type":"", + "visible":true, + "width":202.26, + "x":32.2654354913834, + "y":169.008165183978 }], "opacity":1, "type":"objectgroup", @@ -241,7 +277,7 @@ "y":0 }], "nextlayerid":11, - "nextobjectid":11, + "nextobjectid":13, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.7.2", From 9cccdca3dc5d52a1590c55df57f816448d932696 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 9 Feb 2022 11:09:20 +0100 Subject: [PATCH 4/8] docs update --- docs/maps/entry-exit.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/maps/entry-exit.md b/docs/maps/entry-exit.md index 2040beb3..25e530de 100644 --- a/docs/maps/entry-exit.md +++ b/docs/maps/entry-exit.md @@ -82,7 +82,11 @@ We are able to direct a Woka to the desired place immediately after spawn. To ma ``` .../my_map.json#moveTo=meeting-room&start ``` +*...or even like this!* +``` +.../my_map.json#start&moveTo=200,100 +``` -For this to work, moveTo must be equal to the layer name of interest. This layer should have at least one tile defined. In case of layer having many tiles, user will go to one of them, randomly selected. +For this to work, moveTo must be equal to the x and y position, layer name, or object name of interest. Layer should have at least one tile defined. In case of layer having many tiles, user will go to one of them, randomly selected. ![](images/moveTo-layer-example.png) \ No newline at end of file From c13672c9dca959b1a260d28fe5dd2d36e7efdc7c Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 9 Feb 2022 13:03:14 +0100 Subject: [PATCH 5/8] updated invitation link creator --- front/src/Components/Menu/GuestSubMenu.svelte | 50 +++++++++++++- front/src/Phaser/Game/GameScene.ts | 3 + .../Phaser/Game/StartPositionCalculator.ts | 67 ++++++++++++------- front/src/Stores/StartLayerNamesStore.ts | 6 ++ 4 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 front/src/Stores/StartLayerNamesStore.ts diff --git a/front/src/Components/Menu/GuestSubMenu.svelte b/front/src/Components/Menu/GuestSubMenu.svelte index a0cd94d7..34fba1af 100644 --- a/front/src/Components/Menu/GuestSubMenu.svelte +++ b/front/src/Components/Menu/GuestSubMenu.svelte @@ -1,5 +1,12 @@