From 16a73d4de65675ecfdf2e349a85cd0034762cae7 Mon Sep 17 00:00:00 2001 From: _Bastler <_Bastler@bstly.de> Date: Wed, 24 Nov 2021 14:32:45 +0100 Subject: [PATCH] getMapProperty --- front/src/Api/Events/GetPropertyEvent.ts | 13 +++++++++ front/src/Api/Events/IframeEvent.ts | 5 ++++ front/src/Api/iframe/room.ts | 11 +++++++ front/src/Phaser/Game/GameMap.ts | 16 ++++++++++ front/src/Phaser/Game/GameScene.ts | 37 ++++++++++++++---------- 5 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 front/src/Api/Events/GetPropertyEvent.ts diff --git a/front/src/Api/Events/GetPropertyEvent.ts b/front/src/Api/Events/GetPropertyEvent.ts new file mode 100644 index 00000000..a4db7ea4 --- /dev/null +++ b/front/src/Api/Events/GetPropertyEvent.ts @@ -0,0 +1,13 @@ +import * as tg from "generic-type-guard"; + +export const isGetPropertyEvent = new tg.IsInterface() + .withProperties({ + layerName: tg.isString, + propertyName: tg.isString, + propertyValue: tg.isUnion(tg.isString, tg.isUnion(tg.isNumber, tg.isUnion(tg.isBoolean, tg.isUndefined))), + }) + .get(); +/** + * A message sent from the iFrame to the game to change the value of the property of the layer + */ +export type GetPropertyEvent = tg.GuardedType; diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index abb492c5..64a3891e 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -30,6 +30,7 @@ import type { import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent"; import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent"; import type { ChangeLayerEvent } from "./ChangeLayerEvent"; +import { isGetPropertyEvent } from "./GetPropertyEvent"; export interface TypedMessageEvent extends MessageEvent { data: T; @@ -103,6 +104,10 @@ export const iframeQueryMapTypeGuards = { query: tg.isUndefined, answer: isGameStateEvent, }, + getProperty: { + query: isGetPropertyEvent, + answer: isGetPropertyEvent, + }, getMapData: { query: tg.isUndefined, answer: isMapDataEvent, diff --git a/front/src/Api/iframe/room.ts b/front/src/Api/iframe/room.ts index 5eeadffe..60efc5b6 100644 --- a/front/src/Api/iframe/room.ts +++ b/front/src/Api/iframe/room.ts @@ -130,6 +130,17 @@ export class WorkadventureRoomCommands extends IframeApiContribution { + const event = await queryWorkadventure({ + type: "getProperty", data: { + layerName: layerName, + propertyName: propertyName, + propertyValue : undefined, + } + }); + return event.propertyValue; + } + async getTiledMap(): Promise { const event = await queryWorkadventure({ type: "getMapData", data: undefined }); return event.data as ITiledMap; diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 17740874..5f1b1704 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -323,6 +323,22 @@ export class GameMap { return this.tileNameMap.get(tile); } + public getLayerProperty( + layerName: string, + propertyName: string + ) : string | number | undefined | boolean { + const layer = this.findLayer(layerName); + if (layer === undefined) { + console.warn('Could not find layer "' + layerName + '" when calling setProperty'); + return; + } + if (layer.properties === undefined) { + layer.properties = []; + } + const property = layer.properties.find((property) => property.name === propertyName); + return property?.value; + } + public setLayerProperty( layerName: string, propertyName: string, diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 20778838..4814440c 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -270,7 +270,7 @@ export class GameScene extends DirtyScene { // So if we are in https, we can still try to load a HTTP local resource (can be useful for testing purposes) // 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]; + const host = url.host.split(":")[ 0 ]; if ( window.location.protocol === "https:" && file.src === this.MapUrlFile && @@ -326,8 +326,8 @@ export class GameScene extends DirtyScene { //eslint-disable-next-line @typescript-eslint/no-explicit-any (this.load as any).rexWebFont({ custom: { - families: ["Press Start 2P"], - urls: ["/resources/fonts/fonts.css"], + families: [ "Press Start 2P" ], + urls: [ "/resources/fonts/fonts.css" ], testString: "abcdefg", }, }); @@ -373,7 +373,7 @@ export class GameScene extends DirtyScene { } } - for (const [itemType, objectsOfType] of this.objectsByType) { + for (const [ itemType, objectsOfType ] of this.objectsByType) { // 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; @@ -404,7 +404,7 @@ export class GameScene extends DirtyScene { // TODO: we should pass here a factory to create sprites (maybe?) // Do we have a state for this object? - const state = roomJoinedAnswer.items[object.id]; + const state = roomJoinedAnswer.items[ object.id ]; const actionableItem = itemFactory.factory(this, object, state); this.actionableItems.set(actionableItem.getId(), actionableItem); @@ -634,7 +634,7 @@ export class GameScene extends DirtyScene { } }); - Promise.all([this.connectionAnswerPromise as Promise, ...scriptPromises]).then(() => { + Promise.all([ this.connectionAnswerPromise as Promise, ...scriptPromises ]).then(() => { this.scene.wake(); }); } @@ -722,8 +722,8 @@ export class GameScene extends DirtyScene { if (item === undefined) { console.warn( 'Received an event about object "' + - message.itemId + - '" but cannot find this item on the map.' + message.itemId + + '" but cannot find this item on the map.' ); return; } @@ -931,8 +931,8 @@ export class GameScene extends DirtyScene { } 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." + openPopupEvent.targetObject + + "'. The first parameter of WA.openPopup() must be the name of a rectangle object in your map." ); return; } @@ -1151,6 +1151,11 @@ export class GameScene extends DirtyScene { }); }); + iframeListener.registerAnswerer("getProperty", (data) => { + data.propertyValue = this.gameMap.getLayerProperty(data.layerName, data.propertyName); + return data; + }); + iframeListener.registerAnswerer("getMapData", () => { return { data: this.gameMap.getMap(), @@ -1191,7 +1196,7 @@ export class GameScene extends DirtyScene { const jsonTilesetDir = eventTileset.url.substr(0, eventTileset.url.lastIndexOf("/")); //Initialise the firstgid to 1 because if there is no tileset in the tilemap, the firstgid will be 1 let newFirstgid = 1; - const lastTileset = this.mapFile.tilesets[this.mapFile.tilesets.length - 1]; + const lastTileset = this.mapFile.tilesets[ this.mapFile.tilesets.length - 1 ]; if (lastTileset) { //If there is at least one tileset in the tilemap then calculate the firstgid of the new tileset newFirstgid = lastTileset.firstgid + lastTileset.tilecount; @@ -1291,14 +1296,14 @@ export class GameScene extends DirtyScene { if (phaserLayers === []) { console.warn( 'Could not find layer with name that contains "' + - layerName + - '" when calling WA.hideLayer / WA.showLayer' + layerName + + '" when calling WA.hideLayer / WA.showLayer' ); return; } for (let i = 0; i < phaserLayers.length; i++) { - phaserLayers[i].setVisible(visible); - phaserLayers[i].setCollisionByProperty({ collides: true }, visible); + phaserLayers[ i ].setVisible(visible); + phaserLayers[ i ].setCollisionByProperty({ collides: true }, visible); } } this.markDirty(); @@ -1904,7 +1909,7 @@ export class GameScene extends DirtyScene { const silent = this.gameMap.getCurrentProperties().get("silent"); this.connection?.setSilent(!!silent); mediaManager.showGameOverlay(); - } + } analyticsClient.enteredJitsi(roomName, this.room.id);