From eecf831ca516ba530d55ebdfb32f1bc57472f4ca Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 1 Dec 2021 14:48:14 +0100 Subject: [PATCH 01/38] detecting zoe enter and leave events --- back/src/Services/VariablesManager.ts | 1 - front/src/Phaser/Game/GameMap.ts | 118 ++- front/src/Phaser/Game/GameScene.ts | 22 + .../src/Phaser/Game/SharedVariablesManager.ts | 2 +- front/src/Phaser/Items/Computer/computer.ts | 1 - front/src/Utils/MathUtils.ts | 27 + maps/starter/map.json | 702 +++++++++--------- 7 files changed, 526 insertions(+), 347 deletions(-) create mode 100644 front/src/Utils/MathUtils.ts diff --git a/back/src/Services/VariablesManager.ts b/back/src/Services/VariablesManager.ts index 00aac3dc..d11cb26f 100644 --- a/back/src/Services/VariablesManager.ts +++ b/back/src/Services/VariablesManager.ts @@ -5,7 +5,6 @@ import { ITiledMap, ITiledMapLayer, ITiledMapObject, - ITiledMapObjectLayer, } from "@workadventure/tiled-map-type-guard/dist"; import { User } from "_Model/User"; import { variablesRepository } from "./Repository/VariablesRepository"; diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 8fe0e329..db9b652e 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,8 +1,9 @@ -import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiledMap"; +import type { ITiledMap, ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer, ITiledMapProperty } from "../Map/ITiledMap"; import { flattenGroupLayersMap } from "../Map/LayersFlattener"; import TilemapLayer = Phaser.Tilemaps.TilemapLayer; import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; import { GameMapProperties } from "./GameMapProperties"; +import { MathUtils } from '../../Utils/MathUtils'; export type PropertyChangeCallback = ( newValue: string | number | boolean | undefined, @@ -15,23 +16,46 @@ export type layerChangeCallback = ( allLayersOnNewPosition: Array ) => void; +export type zoneChangeCallback = ( + zonesChangedByAction: Array, + allZonesOnNewPosition: Array +) => void; + /** * A wrapper around a ITiledMap interface to provide additional capabilities. * It is used to handle layer properties. */ export class GameMap { - // oldKey is the index of the previous tile. + /** + * oldKey is the index of the previous tile. + */ private oldKey: number | undefined; - // key is the index of the current tile. + /** + * key is the index of the current tile. + */ private key: number | undefined; + /** + * oldPosition is the previous position of the player. + */ + private oldPosition: { x: number, y: number } | undefined; + /** + * position is the current position of the player. + */ + private position: { x: number, y: number } | undefined; + private lastProperties = new Map(); private propertiesChangeCallbacks = new Map>(); + private enterLayerCallbacks = Array(); private leaveLayerCallbacks = Array(); + private enterZoneCallbacks = Array(); + private leaveZoneCallbacks = Array(); + private tileNameMap = new Map(); private tileSetPropertyMap: { [tile_index: number]: Array } = {}; public readonly flatLayers: ITiledMapLayer[]; + public readonly tiledObjects: ITiledMapObject[]; public readonly phaserLayers: TilemapLayer[] = []; public exitUrls: Array = []; @@ -44,6 +68,8 @@ export class GameMap { terrains: Array ) { this.flatLayers = flattenGroupLayersMap(map); + this.tiledObjects = this.getObjectsFromLayers(this.flatLayers); + let depth = -2; for (const layer of this.flatLayers) { if (layer.type === "tilelayer") { @@ -88,6 +114,9 @@ export class GameMap { * This will trigger events if properties are changing. */ public setPosition(x: number, y: number) { + this.oldPosition = this.position; + this.position = { x, y }; + this.oldKey = this.key; const xMap = Math.floor(x / this.map.tilewidth); @@ -102,6 +131,7 @@ export class GameMap { this.triggerAllProperties(); this.triggerLayersChange(); + this.triggerZonesChange(); } private triggerAllProperties(): void { @@ -126,7 +156,7 @@ export class GameMap { } } - private triggerLayersChange() { + private triggerLayersChange(): void { const layersByOldKey = this.oldKey ? this.getLayersByKey(this.oldKey) : []; const layersByNewKey = this.key ? this.getLayersByKey(this.key) : []; @@ -155,6 +185,54 @@ export class GameMap { } } + /** + * We user Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. + */ + private triggerZonesChange(): void { + const zones = this.tiledObjects.filter(object => object.type === "zone"); + + // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys + const zonesByOldPosition = this.oldPosition ? + zones.filter((zone) => { + if (!this.oldPosition) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); + }) : []; + + const zonesByNewPosition = this.position ? + zones.filter((zone) => { + if (!this.position) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.position, zone); + }) : []; + + const enterZones = new Set(zonesByNewPosition); + const leaveZones = new Set(zonesByOldPosition); + + enterZones.forEach((zone) => { + if (leaveZones.has(zone)) { + leaveZones.delete(zone); + enterZones.delete(zone); + } + }); + + if (enterZones.size > 0) { + const zonesArray = Array.from(enterZones); + for (const callback of this.enterZoneCallbacks) { + callback(zonesArray, zonesByNewPosition); + } + } + + if (leaveZones.size > 0) { + const zonesArray = Array.from(leaveZones); + for (const callback of this.leaveZoneCallbacks) { + callback(zonesArray, zonesByNewPosition); + } + } + } + public getCurrentProperties(): Map { return this.lastProperties; } @@ -251,6 +329,20 @@ export class GameMap { this.leaveLayerCallbacks.push(callback); } + /** + * Registers a callback called when the user moves inside another zone. + */ + public onEnterZone(callback: zoneChangeCallback) { + this.enterZoneCallbacks.push(callback); + } + + /** + * Registers a callback called when the user moves outside another zone. + */ + public onLeaveZone(callback: zoneChangeCallback) { + this.leaveZoneCallbacks.push(callback); + } + public findLayer(layerName: string): ITiledMapLayer | undefined { return this.flatLayers.find((layer) => layer.name === layerName); } @@ -362,4 +454,22 @@ export class GameMap { this.trigger(oldPropName, oldPropValue, undefined, emptyProps); } } + + private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] { + const objects: ITiledMapObject[] = []; + + const objectLayers = layers.filter(layer => layer.type === "objectgroup"); + for (const objectLayer of objectLayers) { + if (this.isOfTypeITiledMapObjectLayer(objectLayer)) { + objects.push(...objectLayer.objects); + } + } + + return objects; + } + + // NOTE: Simple typeguard for Objects Layer. + private isOfTypeITiledMapObjectLayer(obj: ITiledMapLayer): obj is ITiledMapObjectLayer { + return (obj as ITiledMapObjectLayer).objects !== undefined; + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d9bb8186..8bf0f13e 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -778,6 +778,28 @@ export class GameScene extends DirtyScene { iframeListener.sendLeaveLayerEvent(layer.name); }); }); + + this.gameMap.onEnterZone((zones) => { + console.log('enter zones'); + console.log(zones); + // zones.forEach((zone) => { + // iframeListener.sendEnterLayerEvent(zone.name); + // }); + }); + + this.gameMap.onLeaveZone((zones) => { + console.log('leave zones'); + console.log(zones); + // zones.forEach((zone) => { + // iframeListener.sendEnterLayerEvent(zone.name); + // }); + }); + + // this.gameMap.onLeaveLayer((layers) => { + // layers.forEach((layer) => { + // iframeListener.sendLeaveLayerEvent(layer.name); + // }); + // }); }); } diff --git a/front/src/Phaser/Game/SharedVariablesManager.ts b/front/src/Phaser/Game/SharedVariablesManager.ts index 8f913765..5b5867dc 100644 --- a/front/src/Phaser/Game/SharedVariablesManager.ts +++ b/front/src/Phaser/Game/SharedVariablesManager.ts @@ -1,7 +1,7 @@ import type { RoomConnection } from "../../Connexion/RoomConnection"; import { iframeListener } from "../../Api/IframeListener"; import type { GameMap } from "./GameMap"; -import type { ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer } from "../Map/ITiledMap"; +import type { ITiledMapLayer, ITiledMapObject } from "../Map/ITiledMap"; import { GameMapProperties } from "./GameMapProperties"; interface Variable { diff --git a/front/src/Phaser/Items/Computer/computer.ts b/front/src/Phaser/Items/Computer/computer.ts index 4665c546..41fb6fc4 100644 --- a/front/src/Phaser/Items/Computer/computer.ts +++ b/front/src/Phaser/Items/Computer/computer.ts @@ -1,5 +1,4 @@ import * as Phaser from "phaser"; -import { Scene } from "phaser"; import Sprite = Phaser.GameObjects.Sprite; import type { ITiledMapObject } from "../../Map/ITiledMap"; import type { ItemFactoryInterface } from "../ItemFactoryInterface"; diff --git a/front/src/Utils/MathUtils.ts b/front/src/Utils/MathUtils.ts new file mode 100644 index 00000000..098b86b4 --- /dev/null +++ b/front/src/Utils/MathUtils.ts @@ -0,0 +1,27 @@ + +export class MathUtils { + + /** + * + * @param p Position to check. + * @param r Rectangle to check the overlap against. + * @returns true is overlapping + */ + public static isOverlappingWithRectangle( + p: { x: number, y: number}, + r: { x: number, y: number, width: number, height: number}, + ): boolean { + return (this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height)); + } + + /** + * + * @param value Value to check + * @param min inclusive min value + * @param max inclusive max value + * @returns true if value is in + */ + public static isBetween(value: number, min: number, max: number): boolean { + return (value >= min) && (value <= max); + } +} \ No newline at end of file diff --git a/maps/starter/map.json b/maps/starter/map.json index 8d93c66e..31d81b19 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -1,341 +1,363 @@ -{ "compressionlevel":-1, - "height":17, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":6, - "name":"start", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":7, - "name":"collisions", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":29, - "name":"jitsiMeetingRoom", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"MeetingRoom" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":38, - "name":"jitsiChillzone", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"ChillZone" - }, - { - "name":"jitsiTrigger", - "type":"string", - "value":"onaction" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":23, - "name":"clockZone", - "opacity":1, - "properties":[ - { - "name":"zone", - "type":"string", - "value":"clock" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], - "height":17, - "id":4, - "name":"floor", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], - "height":17, - "id":9, - "name":"walls", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":1, - "name":"furniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":33, - "name":"aboveFurniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "draworder":"topdown", - "id":2, - "name":"floorLayer", - "objects":[ - { - "height":64, - "id":4, - "name":"clockPopup", - "rotation":0, - "type":"", - "visible":true, - "width":128, - "x":512, - "y":0 - }], - "opacity":1, - "type":"objectgroup", - "visible":true, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":3, - "name":"abovePlayer1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":27, - "name":"abovePlayer2", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":28, - "name":"abovePlayer3", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }], - "nextlayerid":39, - "nextobjectid":9, - "orientation":"orthogonal", - "properties":[ - { - "name":"mapCopyright", - "type":"string", - "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" - }, - { - "name":"mapDescription", - "type":"string", - "value":"A perfect virtual office to get started with WorkAdventure!" - }, - { - "name":"mapImage", - "type":"string", - "value":"map.png" - }, - { - "name":"mapLink", - "type":"string", - "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" - }, - { - "name":"mapName", - "type":"string", - "value":"Starter kit" - }, - { - "name":"script", - "type":"string", - "value":"..\/dist\/script.js" - }], - "renderorder":"right-down", - "tiledversion":"1.7.0", - "tileheight":32, - "tilesets":[ - { - "columns":10, - "firstgid":1, - "image":"..\/assets\/tileset5_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset5_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":10, - "firstgid":101, - "image":"..\/assets\/tileset6_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset6_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":201, - "image":"..\/assets\/tileset1.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":322, - "image":"..\/assets\/tileset1-repositioning.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1-repositioning", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":6, - "firstgid":443, - "image":"..\/assets\/Special_Zones.png", - "imageheight":64, - "imagewidth":192, - "margin":0, - "name":"Special_Zones", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":12, - "tileheight":32, - "tiles":[ - { - "id":0, - "properties":[ - { - "name":"collides", - "type":"bool", - "value":true - }] - }], - "tilewidth":32 - }], - "tilewidth":32, - "type":"map", - "version":"1.6", - "width":31 +{ "compressionlevel":-1, + "height":17, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":6, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":7, + "name":"collisions", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":29, + "name":"jitsiMeetingRoom", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"MeetingRoom" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":38, + "name":"jitsiChillzone", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"ChillZone" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":23, + "name":"clockZone", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"clock" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "height":17, + "id":4, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], + "height":17, + "id":9, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":1, + "name":"furniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":33, + "name":"aboveFurniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":2, + "name":"floorLayer", + "objects":[ + { + "height":64, + "id":4, + "name":"clockPopup", + "rotation":0, + "type":"", + "visible":true, + "width":128, + "x":512, + "y":0 + }, + { + "height":128, + "id":9, + "name":"chillZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Chilling Room" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":192, + "x":32, + "y":96 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":3, + "name":"abovePlayer1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":27, + "name":"abovePlayer2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":28, + "name":"abovePlayer3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }], + "nextlayerid":39, + "nextobjectid":11, + "orientation":"orthogonal", + "properties":[ + { + "name":"mapCopyright", + "type":"string", + "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" + }, + { + "name":"mapDescription", + "type":"string", + "value":"A perfect virtual office to get started with WorkAdventure!" + }, + { + "name":"mapImage", + "type":"string", + "value":"map.png" + }, + { + "name":"mapLink", + "type":"string", + "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" + }, + { + "name":"mapName", + "type":"string", + "value":"Starter kit" + }, + { + "name":"script", + "type":"string", + "value":"..\/dist\/script.js" + }], + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":32, + "tilesets":[ + { + "columns":10, + "firstgid":1, + "image":"..\/assets\/tileset5_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset5_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":10, + "firstgid":101, + "image":"..\/assets\/tileset6_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset6_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":201, + "image":"..\/assets\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":322, + "image":"..\/assets\/tileset1-repositioning.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1-repositioning", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":6, + "firstgid":443, + "image":"..\/assets\/Special_Zones.png", + "imageheight":64, + "imagewidth":192, + "margin":0, + "name":"Special_Zones", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":12, + "tileheight":32, + "tiles":[ + { + "id":0, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":31 } \ No newline at end of file From dd79f7d0f4b7bf7d79a81c30d03398da5a7a8d2f Mon Sep 17 00:00:00 2001 From: Valdo Romao Date: Wed, 1 Dec 2021 15:38:34 +0000 Subject: [PATCH 02/38] Added the user-room token created from admin when we access a room --- back/src/Services/SocketManager.ts | 1 + docs/maps/api-player.md | 23 +++++++++++++++++++ front/src/Api/Events/GameStateEvent.ts | 1 + front/src/Api/iframe/player.ts | 13 +++++++++++ front/src/Connexion/RoomConnection.ts | 6 +++++ front/src/Phaser/Game/GameScene.ts | 1 + front/src/iframe_api.ts | 5 ++-- maps/tests/Metadata/getCurrentRoom.js | 1 + messages/protos/messages.proto | 2 ++ pusher/src/Controller/IoSocketController.ts | 5 ++++ .../src/Model/Websocket/ExSocketInterface.ts | 1 + pusher/src/Services/AdminApi.ts | 1 + pusher/src/Services/SocketManager.ts | 5 ++++ 13 files changed, 63 insertions(+), 2 deletions(-) diff --git a/back/src/Services/SocketManager.ts b/back/src/Services/SocketManager.ts index 5efae800..8989df75 100644 --- a/back/src/Services/SocketManager.ts +++ b/back/src/Services/SocketManager.ts @@ -97,6 +97,7 @@ export class SocketManager { } const roomJoinedMessage = new RoomJoinedMessage(); roomJoinedMessage.setTagList(joinRoomMessage.getTagList()); + roomJoinedMessage.setUserroomtoken(joinRoomMessage.getUserroomtoken()); for (const [itemId, item] of room.getItemsState().entries()) { const itemStateMessage = new ItemStateMessage(); diff --git a/docs/maps/api-player.md b/docs/maps/api-player.md index 39a13d9e..cb2910c7 100644 --- a/docs/maps/api-player.md +++ b/docs/maps/api-player.md @@ -58,6 +58,29 @@ WA.onInit().then(() => { }) ``` +### Get the user-room token of the player + +``` +WA.player.userRoomToken: string; +``` + +The user-room token is available from the `WA.player.userRoomToken` property. +This token is generated in WorkAdventure and contains information such as the player's room ID and its associated membership ID. + +{.alert.alert-warn} +This token is used when you change your logo using a configured variable. +Indeed, to change your logo you need to perform an upload in order to get a file URL. This type of actions must be validated on our side. +If you are using a self-hosted version of WorkAdventure you will not have the possibility to perform actions that depends on the user-room token, unless you create an API that support it. + +{.alert.alert-info} +You need to wait for the end of the initialization before accessing `WA.player.userRoomToken` + +```typescript +WA.onInit().then(() => { + console.log('Token: ', WA.player.userRoomToken); +}) +``` + ### Listen to player movement ``` WA.player.onPlayerMove(callback: HasPlayerMovedEventCallback): void; diff --git a/front/src/Api/Events/GameStateEvent.ts b/front/src/Api/Events/GameStateEvent.ts index 112c2880..1f0f36ed 100644 --- a/front/src/Api/Events/GameStateEvent.ts +++ b/front/src/Api/Events/GameStateEvent.ts @@ -9,6 +9,7 @@ export const isGameStateEvent = new tg.IsInterface() startLayerName: tg.isUnion(tg.isString, tg.isNull), tags: tg.isArray(tg.isString), variables: tg.isObject, + userRoomToken: tg.isUnion(tg.isString, tg.isUndefined), }) .get(); /** diff --git a/front/src/Api/iframe/player.ts b/front/src/Api/iframe/player.ts index 078a1926..ed1b59d8 100644 --- a/front/src/Api/iframe/player.ts +++ b/front/src/Api/iframe/player.ts @@ -20,6 +20,12 @@ export const setTags = (_tags: string[]) => { let uuid: string | undefined; +let userRoomToken: string | undefined; + +export const setUserRoomToken = (token: string | undefined) => { + userRoomToken = token; +}; + export const setUuid = (_uuid: string | undefined) => { uuid = _uuid; }; @@ -67,6 +73,13 @@ export class WorkadventurePlayerCommands extends IframeApiContribution any) = null; // eslint-disable-line @typescript-eslint/no-explicit-any private closed: boolean = false; private tags: string[] = []; + private _userRoomToken: string | undefined; // eslint-disable-next-line @typescript-eslint/no-explicit-any public static setWebsocketFactory(websocketFactory: (url: string) => any): void { @@ -211,6 +212,7 @@ export class RoomConnection implements RoomConnection { this.userId = roomJoinedMessage.getCurrentuserid(); this.tags = roomJoinedMessage.getTagList(); + this._userRoomToken = roomJoinedMessage.getUserroomtoken(); this.dispatch(EventMessage.CONNECT, { connection: this, @@ -710,4 +712,8 @@ export class RoomConnection implements RoomConnection { public getAllTags(): string[] { return this.tags; } + + public get userRoomToken(): string | undefined { + return this._userRoomToken; + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d9bb8186..8a2de5cd 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1165,6 +1165,7 @@ ${escapedMessage} roomId: this.roomUrl, tags: this.connection ? this.connection.getAllTags() : [], variables: this.sharedVariablesManager.variables, + userRoomToken: this.connection ? this.connection.userRoomToken : '' }; }); this.iframeSubscriptionList.push( diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts index dcd10fdc..93415b0d 100644 --- a/front/src/iframe_api.ts +++ b/front/src/iframe_api.ts @@ -15,11 +15,11 @@ import ui from "./Api/iframe/ui"; import sound from "./Api/iframe/sound"; import room, { setMapURL, setRoomId } from "./Api/iframe/room"; import state, { initVariables } from "./Api/iframe/state"; -import player, { setPlayerName, setTags, setUuid } from "./Api/iframe/player"; +import player, { setPlayerName, setTags, setUserRoomToken, setUuid } from "./Api/iframe/player"; import type { ButtonDescriptor } from "./Api/iframe/Ui/ButtonDescriptor"; import type { Popup } from "./Api/iframe/Ui/Popup"; import type { Sound } from "./Api/iframe/Sound/Sound"; -import { answerPromises, queryWorkadventure, sendToWorkadventure } from "./Api/iframe/IframeApiContribution"; +import { answerPromises, queryWorkadventure } from "./Api/iframe/IframeApiContribution"; // Notify WorkAdventure that we are ready to receive data const initPromise = queryWorkadventure({ @@ -32,6 +32,7 @@ const initPromise = queryWorkadventure({ setTags(state.tags); setUuid(state.uuid); initVariables(state.variables as Map); + setUserRoomToken(state.userRoomToken); }); const wa = { diff --git a/maps/tests/Metadata/getCurrentRoom.js b/maps/tests/Metadata/getCurrentRoom.js index df3a995c..fa8e0226 100644 --- a/maps/tests/Metadata/getCurrentRoom.js +++ b/maps/tests/Metadata/getCurrentRoom.js @@ -4,6 +4,7 @@ WA.onInit().then(() => { console.log('Player name: ', WA.player.name); console.log('Player id: ', WA.player.id); console.log('Player tags: ', WA.player.tags); + console.log('Player token: ', WA.player.userRoomToken); }); WA.room.getTiledMap().then((data) => { diff --git a/messages/protos/messages.proto b/messages/protos/messages.proto index 76f4f5ad..38952903 100644 --- a/messages/protos/messages.proto +++ b/messages/protos/messages.proto @@ -198,6 +198,7 @@ message RoomJoinedMessage { int32 currentUserId = 4; repeated string tag = 5; repeated VariableMessage variable = 6; + string userRoomToken = 7; } message WebRtcStartMessage { @@ -297,6 +298,7 @@ message JoinRoomMessage { string IPAddress = 7; CompanionMessage companion = 8; string visitCardUrl = 9; + string userRoomToken = 10; } message UserJoinedZoneMessage { diff --git a/pusher/src/Controller/IoSocketController.ts b/pusher/src/Controller/IoSocketController.ts index 35fd08d5..3c369969 100644 --- a/pusher/src/Controller/IoSocketController.ts +++ b/pusher/src/Controller/IoSocketController.ts @@ -186,6 +186,7 @@ export class IoSocketController { let memberTags: string[] = []; let memberVisitCardUrl: string | null = null; let memberMessages: unknown; + let memberUserRoomToken: string | undefined; let memberTextures: CharacterTexture[] = []; const room = await socketManager.getOrCreateRoom(roomId); let userData: FetchMemberDataByUuidResponse = { @@ -196,6 +197,7 @@ export class IoSocketController { textures: [], messages: [], anonymous: true, + userRoomToken: undefined, }; if (ADMIN_API_URL) { try { @@ -232,6 +234,8 @@ export class IoSocketController { memberTags = userData.tags; memberVisitCardUrl = userData.visitCardUrl; memberTextures = userData.textures; + memberUserRoomToken = userData.userRoomToken; + if ( room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags)) @@ -281,6 +285,7 @@ export class IoSocketController { messages: memberMessages, tags: memberTags, visitCardUrl: memberVisitCardUrl, + userRoomToken: memberUserRoomToken, textures: memberTextures, position: { x: x, diff --git a/pusher/src/Model/Websocket/ExSocketInterface.ts b/pusher/src/Model/Websocket/ExSocketInterface.ts index ff5ed211..411d88fa 100644 --- a/pusher/src/Model/Websocket/ExSocketInterface.ts +++ b/pusher/src/Model/Websocket/ExSocketInterface.ts @@ -44,4 +44,5 @@ export interface ExSocketInterface extends WebSocket, Identificable { textures: CharacterTexture[]; backConnection: BackConnection; listenedZones: Set; + userRoomToken: string | undefined; } diff --git a/pusher/src/Services/AdminApi.ts b/pusher/src/Services/AdminApi.ts index 416b9cb6..bc3b2172 100644 --- a/pusher/src/Services/AdminApi.ts +++ b/pusher/src/Services/AdminApi.ts @@ -29,6 +29,7 @@ export interface FetchMemberDataByUuidResponse { textures: CharacterTexture[]; messages: unknown[]; anonymous?: boolean; + userRoomToken: string | undefined; } class AdminApi { diff --git a/pusher/src/Services/SocketManager.ts b/pusher/src/Services/SocketManager.ts index 1761f1bd..f3cfd95a 100644 --- a/pusher/src/Services/SocketManager.ts +++ b/pusher/src/Services/SocketManager.ts @@ -151,6 +151,11 @@ export class SocketManager implements ZoneEventListener { joinRoomMessage.setName(client.name); joinRoomMessage.setPositionmessage(ProtobufUtils.toPositionMessage(client.position)); joinRoomMessage.setTagList(client.tags); + + if (client.userRoomToken) { + joinRoomMessage.setUserroomtoken(client.userRoomToken); + } + if (client.visitCardUrl) { joinRoomMessage.setVisitcardurl(client.visitCardUrl); } From 67fc6e8cd2ab19b7df903baa8d8a4657b7424c38 Mon Sep 17 00:00:00 2001 From: Valdo Romao Date: Wed, 1 Dec 2021 17:59:56 +0000 Subject: [PATCH 03/38] Fixed missing definition in FetchMemberDataByUuidResponse --- pusher/src/Controller/AuthenticateController.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 47d35fab..1079c093 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -287,6 +287,7 @@ export class AuthenticateController extends BaseController { messages: [], visitCardUrl: null, textures: [], + userRoomToken: undefined }; try { data = await adminApi.fetchMemberDataByUuid(email, playUri, IPAddress); From 4cff230256cde114efe1eb97da08e854676d1312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 1 Dec 2021 10:12:07 +0100 Subject: [PATCH 04/38] Creating only one WS connection to pusher from admin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also: migration to Typescript 4.5 and µWebsockets 1.20.4 --- pusher/package.json | 6 +- pusher/src/Controller/AdminController.ts | 4 +- pusher/src/Controller/InvalidTokenError.ts | 9 + pusher/src/Controller/IoSocketController.ts | 214 ++++++++++++------ .../Model/Websocket/Admin/AdminMessages.ts | 30 +++ pusher/src/Services/JWTTokenManager.ts | 8 +- pusher/src/Services/SocketManager.ts | 6 + pusher/yarn.lock | 16 +- 8 files changed, 206 insertions(+), 87 deletions(-) create mode 100644 pusher/src/Controller/InvalidTokenError.ts create mode 100644 pusher/src/Model/Websocket/Admin/AdminMessages.ts diff --git a/pusher/package.json b/pusher/package.json index dacbfd72..bbef80fa 100644 --- a/pusher/package.json +++ b/pusher/package.json @@ -52,7 +52,7 @@ "openid-client": "^4.7.4", "prom-client": "^12.0.0", "query-string": "^6.13.3", - "uWebSockets.js": "uNetworking/uWebSockets.js#v18.5.0", + "uWebSockets.js": "uNetworking/uWebSockets.js#v20.4.0", "uuidv4": "^6.0.7" }, "devDependencies": { @@ -71,8 +71,8 @@ "jasmine": "^3.5.0", "lint-staged": "^11.0.0", "prettier": "^2.3.1", - "ts-node-dev": "^1.0.0-pre.44", - "typescript": "^3.8.3" + "ts-node-dev": "^1.1.8", + "typescript": "^4.5.2" }, "lint-staged": { "*.ts": [ diff --git a/pusher/src/Controller/AdminController.ts b/pusher/src/Controller/AdminController.ts index ec1bd067..bf514fa0 100644 --- a/pusher/src/Controller/AdminController.ts +++ b/pusher/src/Controller/AdminController.ts @@ -44,7 +44,7 @@ export class AdminController extends BaseController { const roomId: string = body.roomId; await apiClientRepository.getClient(roomId).then((roomClient) => { - return new Promise((res, rej) => { + return new Promise((res, rej) => { const roomMessage = new RefreshRoomPromptMessage(); roomMessage.setRoomid(roomId); @@ -101,7 +101,7 @@ export class AdminController extends BaseController { await Promise.all( targets.map((roomId) => { return apiClientRepository.getClient(roomId).then((roomClient) => { - return new Promise((res, rej) => { + return new Promise((res, rej) => { if (type === "message") { const roomMessage = new AdminRoomMessage(); roomMessage.setMessage(text); diff --git a/pusher/src/Controller/InvalidTokenError.ts b/pusher/src/Controller/InvalidTokenError.ts new file mode 100644 index 00000000..2d0c066d --- /dev/null +++ b/pusher/src/Controller/InvalidTokenError.ts @@ -0,0 +1,9 @@ +/** + * Errors related to variable handling. + */ +export class InvalidTokenError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, InvalidTokenError.prototype); + } +} diff --git a/pusher/src/Controller/IoSocketController.ts b/pusher/src/Controller/IoSocketController.ts index 35fd08d5..4c09638a 100644 --- a/pusher/src/Controller/IoSocketController.ts +++ b/pusher/src/Controller/IoSocketController.ts @@ -22,14 +22,17 @@ import { import { UserMovesMessage } from "../Messages/generated/messages_pb"; import { TemplatedApp } from "uWebSockets.js"; import { parse } from "query-string"; -import { jwtTokenManager, tokenInvalidException } from "../Services/JWTTokenManager"; +import { AdminSocketTokenData, jwtTokenManager, tokenInvalidException } from "../Services/JWTTokenManager"; import { adminApi, FetchMemberDataByUuidResponse } from "../Services/AdminApi"; import { SocketManager, socketManager } from "../Services/SocketManager"; import { emitInBatch } from "../Services/IoSocketHelpers"; -import { ADMIN_SOCKETS_TOKEN, ADMIN_API_URL, DISABLE_ANONYMOUS, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable"; +import { ADMIN_API_URL, DISABLE_ANONYMOUS, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable"; import { Zone } from "_Model/Zone"; import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface"; import { CharacterTexture } from "../Services/AdminApi/CharacterTexture"; +import { isAdminMessageInterface } from "../Model/Websocket/Admin/AdminMessages"; +import Axios from "axios"; +import { InvalidTokenError } from "../Controller/InvalidTokenError"; export class IoSocketController { private nextUserId: number = 1; @@ -42,59 +45,108 @@ export class IoSocketController { adminRoomSocket() { this.app.ws("/admin/rooms", { upgrade: (res, req, context) => { - const query = parse(req.getQuery()); const websocketKey = req.getHeader("sec-websocket-key"); const websocketProtocol = req.getHeader("sec-websocket-protocol"); const websocketExtensions = req.getHeader("sec-websocket-extensions"); - const token = query.token; - let authorizedRoomIds: string[]; - try { - const data = jwtTokenManager.verifyAdminSocketToken(token as string); - authorizedRoomIds = data.authorizedRoomIds; - } catch (e) { - console.error("Admin access refused for token: " + token); - res.writeStatus("401 Unauthorized").end("Incorrect token"); - return; - } - const roomId = query.roomId; - if (typeof roomId !== "string" || !authorizedRoomIds.includes(roomId)) { - console.error("Invalid room id"); - res.writeStatus("403 Bad Request").end("Invalid room id"); - return; - } - res.upgrade({ roomId }, websocketKey, websocketProtocol, websocketExtensions, context); + res.upgrade({}, websocketKey, websocketProtocol, websocketExtensions, context); }, open: (ws) => { - console.log("Admin socket connect for room: " + ws.roomId); + console.log("Admin socket connect to client on " + Buffer.from(ws.getRemoteAddressAsText()).toString()); ws.disconnecting = false; - - socketManager.handleAdminRoom(ws as ExAdminSocketInterface, ws.roomId as string); }, message: (ws, arrayBuffer, isBinary): void => { try { - //TODO refactor message type and data - const message: { event: string; message: { type: string; message: unknown; userUuid: string } } = - JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(arrayBuffer))); + const message = JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(arrayBuffer))); - if (message.event === "user-message") { - const messageToEmit = message.message as { message: string; type: string; userUuid: string }; - if (messageToEmit.type === "banned") { - socketManager.emitBan( - messageToEmit.userUuid, - messageToEmit.message, - messageToEmit.type, - ws.roomId as string + if (!isAdminMessageInterface(message)) { + console.error("Invalid message received.", message); + ws.send( + JSON.stringify({ + type: "Error", + data: { + message: "Invalid message received! The connection has been closed.", + }, + }) + ); + ws.close(); + return; + } + + const token = message.jwt; + + let data: AdminSocketTokenData; + + try { + data = jwtTokenManager.verifyAdminSocketToken(token); + } catch (e) { + console.error("Admin socket access refused for token: " + token, e); + ws.send( + JSON.stringify({ + type: "Error", + data: { + message: "Admin socket access refused! The connection has been closed.", + }, + }) + ); + ws.close(); + return; + } + + const authorizedRoomIds = data.authorizedRoomIds; + + if (message.event === "listen") { + const notAuthorizedRoom = message.roomIds.filter( + (roomId) => !authorizedRoomIds.includes(roomId) + ); + + if (notAuthorizedRoom.length > 0) { + const errorMessage = `Admin socket refused for client on ${Buffer.from( + ws.getRemoteAddressAsText() + ).toString()} listening of : \n${JSON.stringify(notAuthorizedRoom)}`; + console.error(); + ws.send( + JSON.stringify({ + type: "Error", + data: { + message: errorMessage, + }, + }) ); + ws.close(); + return; } - if (messageToEmit.type === "ban") { - socketManager.emitSendUserMessage( - messageToEmit.userUuid, - messageToEmit.message, - messageToEmit.type, - ws.roomId as string - ); + + for (const roomId of message.roomIds) { + socketManager + .handleAdminRoom(ws as ExAdminSocketInterface, roomId) + .catch((e) => console.error(e)); } + } else if (message.event === "user-message") { + const messageToEmit = message.message; + // Get roomIds of the world where we want broadcast the message + const roomIds = authorizedRoomIds.filter( + (authorizeRoomId) => authorizeRoomId.split("/")[5] === message.world + ); + + for (const roomId of roomIds) { + if (messageToEmit.type === "banned") { + socketManager + .emitBan(messageToEmit.userUuid, messageToEmit.message, messageToEmit.type, roomId) + .catch((error) => console.error(error)); + } else if (messageToEmit.type === "ban") { + socketManager + .emitSendUserMessage( + messageToEmit.userUuid, + messageToEmit.message, + messageToEmit.type, + roomId + ) + .catch((error) => console.error(error)); + } + } + } else { + const tmp: never = message.event; } } catch (err) { console.error(err); @@ -202,28 +254,30 @@ export class IoSocketController { try { userData = await adminApi.fetchMemberDataByUuid(userIdentifier, roomId, IPAddress); } catch (err) { - if (err?.response?.status == 404) { - // If we get an HTTP 404, the token is invalid. Let's perform an anonymous login! + if (Axios.isAxiosError(err)) { + if (err?.response?.status == 404) { + // If we get an HTTP 404, the token is invalid. Let's perform an anonymous login! - console.warn( - 'Cannot find user with email "' + - (userIdentifier || "anonymous") + - '". Performing an anonymous login instead.' - ); - } else if (err?.response?.status == 403) { - // If we get an HTTP 403, the world is full. We need to broadcast a special error to the client. - // we finish immediately the upgrade then we will close the socket as soon as it starts opening. - return res.upgrade( - { - rejected: true, - message: err?.response?.data.message, - status: err?.response?.status, - }, - websocketKey, - websocketProtocol, - websocketExtensions, - context - ); + console.warn( + 'Cannot find user with email "' + + (userIdentifier || "anonymous") + + '". Performing an anonymous login instead.' + ); + } else if (err?.response?.status == 403) { + // If we get an HTTP 403, the world is full. We need to broadcast a special error to the client. + // we finish immediately the upgrade then we will close the socket as soon as it starts opening. + return res.upgrade( + { + rejected: true, + message: err?.response?.data.message, + status: err?.response?.status, + }, + websocketKey, + websocketProtocol, + websocketExtensions, + context + ); + } } else { throw err; } @@ -302,17 +356,31 @@ export class IoSocketController { context ); } catch (e) { - res.upgrade( - { - rejected: true, - reason: e.reason || null, - message: e.message ? e.message : "500 Internal Server Error", - }, - websocketKey, - websocketProtocol, - websocketExtensions, - context - ); + if (e instanceof Error) { + res.upgrade( + { + rejected: true, + reason: e instanceof InvalidTokenError ? tokenInvalidException : null, + message: e.message, + }, + websocketKey, + websocketProtocol, + websocketExtensions, + context + ); + } else { + res.upgrade( + { + rejected: true, + reason: null, + message: "500 Internal Server Error", + }, + websocketKey, + websocketProtocol, + websocketExtensions, + context + ); + } } })(); }, diff --git a/pusher/src/Model/Websocket/Admin/AdminMessages.ts b/pusher/src/Model/Websocket/Admin/AdminMessages.ts new file mode 100644 index 00000000..1d64899a --- /dev/null +++ b/pusher/src/Model/Websocket/Admin/AdminMessages.ts @@ -0,0 +1,30 @@ +import * as tg from "generic-type-guard"; + +export const isBanBannedAdminMessageInterface = new tg.IsInterface() + .withProperties({ + type: tg.isSingletonStringUnion("ban", "banned"), + message: tg.isString, + userUuid: tg.isString, + }) + .get(); + +export const isUserMessageAdminMessageInterface = new tg.IsInterface() + .withProperties({ + event: tg.isSingletonString("user-message"), + message: isBanBannedAdminMessageInterface, + world: tg.isString, + jwt: tg.isString, + }) + .get(); + +export const isListenRoomsMessageInterface = new tg.IsInterface() + .withProperties({ + event: tg.isSingletonString("listen"), + roomIds: tg.isArray(tg.isString), + jwt: tg.isString, + }) + .get(); + +export const isAdminMessageInterface = tg.isUnion(isUserMessageAdminMessageInterface, isListenRoomsMessageInterface); + +export type AdminMessageInterface = tg.GuardedType; diff --git a/pusher/src/Services/JWTTokenManager.ts b/pusher/src/Services/JWTTokenManager.ts index 40b5b824..ddd5b715 100644 --- a/pusher/src/Services/JWTTokenManager.ts +++ b/pusher/src/Services/JWTTokenManager.ts @@ -3,6 +3,7 @@ import { uuid } from "uuidv4"; import Jwt, { verify } from "jsonwebtoken"; import { TokenInterface } from "../Controller/AuthenticateController"; import { adminApi, AdminBannedData } from "../Services/AdminApi"; +import { InvalidTokenError } from "../Controller/InvalidTokenError"; export interface AuthTokenData { identifier: string; //will be a email if logged in or an uuid if anonymous @@ -26,7 +27,12 @@ class JWTTokenManager { try { return Jwt.verify(token, SECRET_KEY, { ignoreExpiration }) as AuthTokenData; } catch (e) { - throw { reason: tokenInvalidException, message: e.message }; + if (e instanceof Error) { + // FIXME: we are loosing the stacktrace here. + throw new InvalidTokenError(e.message); + } else { + throw e; + } } } } diff --git a/pusher/src/Services/SocketManager.ts b/pusher/src/Services/SocketManager.ts index 1761f1bd..083840e4 100644 --- a/pusher/src/Services/SocketManager.ts +++ b/pusher/src/Services/SocketManager.ts @@ -132,6 +132,12 @@ export class SocketManager implements ZoneEventListener { const message = new AdminPusherToBackMessage(); message.setSubscribetoroom(roomId); + console.log( + `Admin socket handle room ${roomId} connections for a client on ${Buffer.from( + client.getRemoteAddressAsText() + ).toString()}` + ); + adminRoomStream.write(message); } diff --git a/pusher/yarn.lock b/pusher/yarn.lock index 820575aa..ead3a9cc 100644 --- a/pusher/yarn.lock +++ b/pusher/yarn.lock @@ -2270,7 +2270,7 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -ts-node-dev@^1.0.0-pre.44: +ts-node-dev@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-1.1.8.tgz#95520d8ab9d45fffa854d6668e2f8f9286241066" integrity sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg== @@ -2337,14 +2337,14 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@^3.8.3: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== +typescript@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" + integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== -uWebSockets.js@uNetworking/uWebSockets.js#v18.5.0: - version "18.5.0" - resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/9b1605d2db82981cafe69dbe356e10ce412f5805" +uWebSockets.js@uNetworking/uWebSockets.js#v20.4.0: + version "20.4.0" + resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/65f39bdff763be3883e6cf18e433dd4fec155845" uri-js@^4.2.2: version "4.4.1" From 85bf2fe70d55f17f9dae011119a78021d6be26d3 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 13:20:40 +0100 Subject: [PATCH 05/38] camera zoom using scaleManager zooming. WIP --- front/src/Phaser/Game/CameraManager.ts | 70 +++++++++++++++++++++ front/src/Phaser/Game/GameMap.ts | 1 + front/src/Phaser/Game/GameScene.ts | 59 +++++++++-------- front/src/Phaser/Services/WaScaleManager.ts | 2 +- front/src/types.ts | 31 +++++++++ maps/starter/map.json | 26 +++++++- 6 files changed, 155 insertions(+), 34 deletions(-) create mode 100644 front/src/Phaser/Game/CameraManager.ts diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts new file mode 100644 index 00000000..595867be --- /dev/null +++ b/front/src/Phaser/Game/CameraManager.ts @@ -0,0 +1,70 @@ +import { Easing } from '../../types'; +import { HtmlUtils } from '../../WebRtc/HtmlUtils'; +import type { Box } from '../../WebRtc/LayoutManager'; +import type { WaScaleManager } from '../Services/WaScaleManager'; +import type { GameScene } from './GameScene'; + +export class CameraManager extends Phaser.Events.EventEmitter { + + private scene: GameScene; + private camera: Phaser.Cameras.Scene2D.Camera; + private waScaleManager: WaScaleManager; + + private cameraBounds: { x: number, y: number }; + + constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { + super(); + this.scene = scene; + + this.camera = scene.cameras.main; + this.cameraBounds = cameraBounds; + + this.waScaleManager = waScaleManager; + + this.initCamera(); + } + + public getCamera(): Phaser.Cameras.Scene2D.Camera { + return this.camera; + } + + public changeCameraFocus(focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000): void { + const maxZoomModifier = 2.84; // How to get max zoom value? + const currentZoomModifier = this.waScaleManager.zoomModifier; + const zoomModifierChange = maxZoomModifier - currentZoomModifier; + this.camera.stopFollow(); + this.camera.pan( + focusOn.x + focusOn.width * 0.5, + focusOn.y + focusOn.height * 0.5, + duration, + Easing.SineEaseOut, false, (camera, progress, x, y) => { + this.scene.setZoomModifierTo(currentZoomModifier + progress * zoomModifierChange); + }); + } + + public startFollow(target: object | Phaser.GameObjects.GameObject): void { + this.camera.startFollow(target, true); + } + + /** + * Updates the offset of the character compared to the center of the screen according to the layout manager + * (tries to put the character in the center of the remaining space if there is a discussion going on. + */ + public updateCameraOffset(array: Box): void { + const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart; + const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart; + + const game = HtmlUtils.querySelectorOrFail("#game canvas"); + // Let's put this in Game coordinates by applying the zoom level: + + this.camera.setFollowOffset( + ((xCenter - game.offsetWidth / 2) * window.devicePixelRatio) / this.scene.scale.zoom, + ((yCenter - game.offsetHeight / 2) * window.devicePixelRatio) / this.scene.scale.zoom + ); + } + + private initCamera() { + this.camera = this.scene.cameras.main; + this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); + } +} \ No newline at end of file diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index db9b652e..85a1a0e0 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -192,6 +192,7 @@ export class GameMap { const zones = this.tiledObjects.filter(object => object.type === "zone"); // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys + // TODO: Change this to an array with currently occupied sone instead of doing elimination process const zonesByOldPosition = this.oldPosition ? zones.filter((zone) => { if (!this.oldPosition) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8bf0f13e..d596fa56 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -60,6 +60,7 @@ import { PinchManager } from "../UserInput/PinchManager"; import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; import { waScaleManager } from "../Services/WaScaleManager"; import { EmoteManager } from "./EmoteManager"; +import { CameraManager } from './CameraManager'; import EVENT_TYPE = Phaser.Scenes.Events; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; @@ -198,6 +199,7 @@ export class GameScene extends DirtyScene { private pinchManager: PinchManager | undefined; private mapTransitioning: boolean = false; //used to prevent transitions happening at the same time. private emoteManager!: EmoteManager; + private cameraManager!: CameraManager; private preloading: boolean = true; private startPositionCalculator!: StartPositionCalculator; private sharedVariablesManager!: SharedVariablesManager; @@ -549,7 +551,9 @@ export class GameScene extends DirtyScene { this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted - this.initCamera(); + this.cameraManager = new CameraManager(this, { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, waScaleManager); + biggestAvailableAreaStore.recompute(); + this.cameraManager.startFollow(this.CurrentPlayer); this.animatedTiles.init(this.Map); this.events.on("tileanimationupdate", () => (this.dirty = true)); @@ -590,7 +594,7 @@ export class GameScene extends DirtyScene { // From now, this game scene will be notified of reposition events this.biggestAvailableAreaStoreUnsubscribe = biggestAvailableAreaStore.subscribe((box) => - this.updateCameraOffset(box) + this.cameraManager.updateCameraOffset(box) ); new GameMapPropertiesListener(this, this.gameMap).register(); @@ -643,7 +647,7 @@ export class GameScene extends DirtyScene { * Initializes the connection to Pusher. */ private connect(): void { - const camera = this.cameras.main; + const camera = this.cameraManager.getCamera(); connectionManager .connectToRoomSocket( @@ -779,17 +783,30 @@ export class GameScene extends DirtyScene { }); }); + // P.H. TODO: Send those events to the iframe? this.gameMap.onEnterZone((zones) => { - console.log('enter zones'); - console.log(zones); + for (const zone of zones) { + for (const property of zone.properties ?? []) { + if (property.name === 'focusable' && property.value === true) { + this.cameraManager.changeCameraFocus(zone); + break; + } + } + } // zones.forEach((zone) => { // iframeListener.sendEnterLayerEvent(zone.name); // }); }); this.gameMap.onLeaveZone((zones) => { - console.log('leave zones'); - console.log(zones); + for (const zone of zones) { + for (const property of zone.properties ?? []) { + if (property.name === 'focusable' && property.value === true) { + this.cameraManager.startFollow(this.CurrentPlayer); + break; + } + } + } // zones.forEach((zone) => { // iframeListener.sendEnterLayerEvent(zone.name); // }); @@ -1478,13 +1495,6 @@ ${escapedMessage} } } - //todo: in a dedicated class/function? - initCamera() { - this.cameras.main.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels); - this.cameras.main.startFollow(this.CurrentPlayer, true); - biggestAvailableAreaStore.recompute(); - } - createCollisionWithPlayer() { //add collision layer for (const phaserLayer of this.gameMap.phaserLayers) { @@ -1876,23 +1886,6 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } - /** - * Updates the offset of the character compared to the center of the screen according to the layout manager - * (tries to put the character in the center of the remaining space if there is a discussion going on. - */ - private updateCameraOffset(array: Box): void { - const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart; - const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart; - - const game = HtmlUtils.querySelectorOrFail("#game canvas"); - // Let's put this in Game coordinates by applying the zoom level: - - this.cameras.main.setFollowOffset( - ((xCenter - game.offsetWidth / 2) * window.devicePixelRatio) / this.scale.zoom, - ((yCenter - game.offsetHeight / 2) * window.devicePixelRatio) / this.scale.zoom - ); - } - public startJitsi(roomName: string, jwt?: string): void { const allProps = this.gameMap.getCurrentProperties(); const jitsiConfig = this.safeParseJSONstring( @@ -1965,6 +1958,10 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } + public setZoomModifierTo(value: number): void { + waScaleManager.zoomModifier = value; + } + public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) { const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey); diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 5ceaeb71..3fb1d29b 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -5,7 +5,7 @@ import type { Game } from "../Game/Game"; import { ResizableScene } from "../Login/ResizableScene"; import { HtmlUtils } from "../../WebRtc/HtmlUtils"; -class WaScaleManager { +export class WaScaleManager { private hdpiManager: HdpiManager; private scaleManager!: ScaleManager; private game!: Game; diff --git a/front/src/types.ts b/front/src/types.ts index d957a2c2..409070e5 100644 --- a/front/src/types.ts +++ b/front/src/types.ts @@ -21,3 +21,34 @@ export interface IVirtualJoystick extends Phaser.GameObjects.GameObject { visible: boolean; createCursorKeys: () => CursorKeys; } + +export enum Easing { + Linear = "Linear", + QuadEaseIn = "Quad.easeIn", + CubicEaseIn = "Cubic.easeIn", + QuartEaseIn = "Quart.easeIn", + QuintEaseIn = "Quint.easeIn", + SineEaseIn = "Sine.easeIn", + ExpoEaseIn = "Expo.easeIn", + CircEaseIn = "Circ.easeIn", + BackEaseIn = "Back.easeIn", + BounceEaseIn = "Bounce.easeIn", + QuadEaseOut = "Quad.easeOut", + CubicEaseOut = "Cubic.easeOut", + QuartEaseOut = "Quart.easeOut", + QuintEaseOut = "Quint.easeOut", + SineEaseOut = "Sine.easeOut", + ExpoEaseOut = "Expo.easeOut", + CircEaseOut = "Circ.easeOut", + BackEaseOut = "Back.easeOut", + BounceEaseOut = "Bounce.easeOut", + QuadEaseInOut = "Quad.easeInOut", + CubicEaseInOut = "Cubic.easeInOut", + QuartEaseInOut = "Quart.easeInOut", + QuintEaseInOut = "Quint.easeInOut", + SineEaseInOut = "Sine.easeInOut", + ExpoEaseInOut = "Expo.easeInOut", + CircEaseInOut = "Circ.easeInOut", + BackEaseInOut = "Back.easeInOut", + BounceEaseInOut = "Bounce.easeInOut" +} diff --git a/maps/starter/map.json b/maps/starter/map.json index 31d81b19..2ef0516d 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -86,7 +86,7 @@ "y":0 }, { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], "height":17, "id":4, "name":"floor", @@ -170,6 +170,28 @@ "width":192, "x":32, "y":96 + }, + { + "height":64, + "id":11, + "name":"coffeeZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Coffee Time!" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":64, + "x":64, + "y":288 }], "opacity":1, "type":"objectgroup", @@ -214,7 +236,7 @@ "y":0 }], "nextlayerid":39, - "nextobjectid":11, + "nextobjectid":12, "orientation":"orthogonal", "properties":[ { From d0cd7b08067024941907af7711abc6cb6100d318 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 13:41:52 +0100 Subject: [PATCH 06/38] locking zooming via player input --- front/src/Phaser/Game/CameraManager.ts | 8 +++++++- front/src/Phaser/Game/GameScene.ts | 3 +++ front/src/Phaser/Services/WaScaleManager.ts | 10 ++++++++++ maps/starter/map.json | 12 ++++++------ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 595867be..e900a059 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -28,7 +28,11 @@ export class CameraManager extends Phaser.Events.EventEmitter { return this.camera; } - public changeCameraFocus(focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000): void { + public changeCameraFocus( + focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, + ): void { + this.waScaleManager.saveZoom(); + this.waScaleManager.lockZoomingViaPlayerInput(); const maxZoomModifier = 2.84; // How to get max zoom value? const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = maxZoomModifier - currentZoomModifier; @@ -43,6 +47,8 @@ export class CameraManager extends Phaser.Events.EventEmitter { } public startFollow(target: object | Phaser.GameObjects.GameObject): void { + this.waScaleManager.lockZoomingViaPlayerInput(false); + this.waScaleManager.restoreZoom(); this.camera.startFollow(target, true); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d596fa56..4afd0383 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1954,6 +1954,9 @@ ${escapedMessage} } zoomByFactor(zoomFactor: number) { + if (waScaleManager.isZoomingViaPlayerInputLocked()) { + return; + } waScaleManager.zoomModifier *= zoomFactor; biggestAvailableAreaStore.recompute(); } diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 3fb1d29b..f8aeba2d 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -12,6 +12,8 @@ export class WaScaleManager { private actualZoom: number = 1; private _saveZoom: number = 1; + private zoomingViaPlayerInputLocked: boolean = false; + public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); } @@ -21,6 +23,14 @@ export class WaScaleManager { this.game = game; } + public isZoomingViaPlayerInputLocked(): boolean { + return this.zoomingViaPlayerInputLocked; + } + + public lockZoomingViaPlayerInput(lock: boolean = true): void { + this.zoomingViaPlayerInputLocked = lock; + } + public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); diff --git a/maps/starter/map.json b/maps/starter/map.json index 2ef0516d..2627a79e 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -172,14 +172,14 @@ "y":96 }, { - "height":64, + "height":352, "id":11, - "name":"coffeeZone", + "name":"meetingZone", "properties":[ { "name":"display_name", "type":"string", - "value":"Coffee Time!" + "value":"Brainstorm Zone!" }, { "name":"focusable", @@ -189,9 +189,9 @@ "rotation":0, "type":"zone", "visible":true, - "width":64, - "x":64, - "y":288 + "width":224, + "x":736, + "y":96 }], "opacity":1, "type":"objectgroup", From c09609f70c2cfa51cfabfb3028212f2637d22761 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 14:44:13 +0100 Subject: [PATCH 07/38] some more tweaks with smooth zooming control --- front/src/Phaser/Game/CameraManager.ts | 52 +++++++++++++++++++-- front/src/Phaser/Game/GameScene.ts | 6 +-- front/src/Phaser/Services/WaScaleManager.ts | 14 ++---- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index e900a059..45621e1c 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -1,16 +1,26 @@ import { Easing } from '../../types'; import { HtmlUtils } from '../../WebRtc/HtmlUtils'; import type { Box } from '../../WebRtc/LayoutManager'; +import type { Player } from '../Player/Player'; import type { WaScaleManager } from '../Services/WaScaleManager'; import type { GameScene } from './GameScene'; +export enum CameraMode { + Free = 'Free', + Follow = 'Follow', + Focus = 'Focus', +} + export class CameraManager extends Phaser.Events.EventEmitter { private scene: GameScene; private camera: Phaser.Cameras.Scene2D.Camera; + private cameraBounds: { x: number, y: number }; private waScaleManager: WaScaleManager; - private cameraBounds: { x: number, y: number }; + private cameraMode: CameraMode = CameraMode.Free; + + private restoreZoomTween?: Phaser.Tweens.Tween; constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { super(); @@ -28,11 +38,13 @@ export class CameraManager extends Phaser.Events.EventEmitter { return this.camera; } - public changeCameraFocus( + public enterFocusMode( focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, ): void { + this.setCameraMode(CameraMode.Focus); this.waScaleManager.saveZoom(); - this.waScaleManager.lockZoomingViaPlayerInput(); + + this.restoreZoomTween?.stop(); const maxZoomModifier = 2.84; // How to get max zoom value? const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = maxZoomModifier - currentZoomModifier; @@ -46,9 +58,15 @@ export class CameraManager extends Phaser.Events.EventEmitter { }); } + public leaveFocusMode(player: Player): void { + // We are forcing camera.pan to kill previous pan animation on EnterFocusMode + this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true); + this.startFollow(player); + this.restoreZoom(); + } + public startFollow(target: object | Phaser.GameObjects.GameObject): void { - this.waScaleManager.lockZoomingViaPlayerInput(false); - this.waScaleManager.restoreZoom(); + this.setCameraMode(CameraMode.Follow); this.camera.startFollow(target, true); } @@ -69,6 +87,30 @@ export class CameraManager extends Phaser.Events.EventEmitter { ); } + public isCameraLocked(): boolean { + return this.cameraMode === CameraMode.Focus; + } + + private setCameraMode(mode: CameraMode): void { + if (this.cameraMode === mode) { + return; + } + this.cameraMode = mode; + } + + private restoreZoom(): void { + this.restoreZoomTween?.stop(); + this.restoreZoomTween = this.scene.tweens.addCounter({ + from: this.waScaleManager.zoomModifier, + to: this.waScaleManager.getSaveZoom(), + duration: 1000, + ease: Easing.SineEaseOut, + onUpdate: (tween: Phaser.Tweens.Tween) => { + this.waScaleManager.zoomModifier = tween.getValue(); + } + }); + } + private initCamera() { this.camera = this.scene.cameras.main; this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4afd0383..90297272 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -788,7 +788,7 @@ export class GameScene extends DirtyScene { for (const zone of zones) { for (const property of zone.properties ?? []) { if (property.name === 'focusable' && property.value === true) { - this.cameraManager.changeCameraFocus(zone); + this.cameraManager.enterFocusMode(zone); break; } } @@ -802,7 +802,7 @@ export class GameScene extends DirtyScene { for (const zone of zones) { for (const property of zone.properties ?? []) { if (property.name === 'focusable' && property.value === true) { - this.cameraManager.startFollow(this.CurrentPlayer); + this.cameraManager.leaveFocusMode(this.CurrentPlayer); break; } } @@ -1954,7 +1954,7 @@ ${escapedMessage} } zoomByFactor(zoomFactor: number) { - if (waScaleManager.isZoomingViaPlayerInputLocked()) { + if (this.cameraManager.isCameraLocked()) { return; } waScaleManager.zoomModifier *= zoomFactor; diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index f8aeba2d..ee2ca9ea 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -12,8 +12,6 @@ export class WaScaleManager { private actualZoom: number = 1; private _saveZoom: number = 1; - private zoomingViaPlayerInputLocked: boolean = false; - public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); } @@ -23,14 +21,6 @@ export class WaScaleManager { this.game = game; } - public isZoomingViaPlayerInputLocked(): boolean { - return this.zoomingViaPlayerInputLocked; - } - - public lockZoomingViaPlayerInput(lock: boolean = true): void { - this.zoomingViaPlayerInputLocked = lock; - } - public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); @@ -82,6 +72,10 @@ export class WaScaleManager { this._saveZoom = this.hdpiManager.zoomModifier; } + public getSaveZoom(): number { + return this._saveZoom; + } + public restoreZoom(): void { this.hdpiManager.zoomModifier = this._saveZoom; this.applyNewSize(); From 3e3a04d50ed0da07489a226fbdc77cac15d13648 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 17:46:09 +0100 Subject: [PATCH 08/38] working with zoom modifier calculating per zone --- front/src/Phaser/Game/CameraManager.ts | 6 +++--- front/src/Phaser/Game/GameScene.ts | 4 ---- front/src/Phaser/Services/WaScaleManager.ts | 18 ++++++++++++++---- maps/starter/map.json | 6 +++--- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 45621e1c..d8c385e6 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -45,16 +45,16 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.waScaleManager.saveZoom(); this.restoreZoomTween?.stop(); - const maxZoomModifier = 2.84; // How to get max zoom value? + const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(focusOn.width, focusOn.height); const currentZoomModifier = this.waScaleManager.zoomModifier; - const zoomModifierChange = maxZoomModifier - currentZoomModifier; + const zoomModifierChange = targetZoomModifier - currentZoomModifier; this.camera.stopFollow(); this.camera.pan( focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5, duration, Easing.SineEaseOut, false, (camera, progress, x, y) => { - this.scene.setZoomModifierTo(currentZoomModifier + progress * zoomModifierChange); + this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange; }); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 90297272..b04788e3 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1961,10 +1961,6 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } - public setZoomModifierTo(value: number): void { - waScaleManager.zoomModifier = value; - } - public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) { const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey); diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index ee2ca9ea..838f82d2 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -24,10 +24,7 @@ export class WaScaleManager { public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); - let devicePixelRatio = 1; - if (window.devicePixelRatio) { - devicePixelRatio = window.devicePixelRatio; - } + const devicePixelRatio = window.devicePixelRatio ?? 1; const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({ width: width * devicePixelRatio, @@ -59,6 +56,19 @@ export class WaScaleManager { this.game.markDirty(); } + public getTargetZoomModifierFor(viewportWidth: number, viewportHeight: number) { + const { width: gameWidth, height: gameHeight } = coWebsiteManager.getGameSize(); + const devicePixelRatio = window.devicePixelRatio ?? 1; + + const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({ + width: gameWidth * devicePixelRatio, + height: gameHeight * devicePixelRatio, + }); + // P.H. Note: Dunno where this magic 2 comes from + // Always return lowest possible value. Need to add MAX ZOOM MODIFIER value into this. + return Math.min(realSize.width / viewportWidth / 2, realSize.height / viewportHeight / 2); + } + public get zoomModifier(): number { return this.hdpiManager.zoomModifier; } diff --git a/maps/starter/map.json b/maps/starter/map.json index 2627a79e..fd0b984e 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -86,7 +86,7 @@ "y":0 }, { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], "height":17, "id":4, "name":"floor", @@ -172,7 +172,7 @@ "y":96 }, { - "height":352, + "height":416, "id":11, "name":"meetingZone", "properties":[ @@ -191,7 +191,7 @@ "visible":true, "width":224, "x":736, - "y":96 + "y":32 }], "opacity":1, "type":"objectgroup", From e792b75ad35e97080605cc0db4e40f43b28cecd0 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 18:11:22 +0100 Subject: [PATCH 09/38] issues with zone triggering fixed --- front/src/Phaser/Game/GameMap.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 85a1a0e0..b2fab07d 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -116,22 +116,22 @@ export class GameMap { public setPosition(x: number, y: number) { this.oldPosition = this.position; this.position = { x, y }; - + this.triggerZonesChange(); + this.oldKey = this.key; - + const xMap = Math.floor(x / this.map.tilewidth); const yMap = Math.floor(y / this.map.tileheight); const key = xMap + yMap * this.map.width; - + if (key === this.key) { return; } - + this.key = key; - + this.triggerAllProperties(); this.triggerLayersChange(); - this.triggerZonesChange(); } private triggerAllProperties(): void { From 831d238be7982c896073d85867f8fbb04599a73d Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 3 Dec 2021 10:11:16 +0100 Subject: [PATCH 10/38] ran prettier --- front/src/Phaser/Game/CameraManager.ts | 37 ++++++++------- front/src/Phaser/Game/GameMap.ts | 62 +++++++++++++++----------- front/src/Phaser/Game/GameScene.ts | 12 +++-- front/src/Utils/MathUtils.ts | 16 +++---- front/src/types.ts | 2 +- 5 files changed, 71 insertions(+), 58 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index d8c385e6..00006a7d 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -1,28 +1,27 @@ -import { Easing } from '../../types'; -import { HtmlUtils } from '../../WebRtc/HtmlUtils'; -import type { Box } from '../../WebRtc/LayoutManager'; -import type { Player } from '../Player/Player'; -import type { WaScaleManager } from '../Services/WaScaleManager'; -import type { GameScene } from './GameScene'; +import { Easing } from "../../types"; +import { HtmlUtils } from "../../WebRtc/HtmlUtils"; +import type { Box } from "../../WebRtc/LayoutManager"; +import type { Player } from "../Player/Player"; +import type { WaScaleManager } from "../Services/WaScaleManager"; +import type { GameScene } from "./GameScene"; export enum CameraMode { - Free = 'Free', - Follow = 'Follow', - Focus = 'Focus', + Free = "Free", + Follow = "Follow", + Focus = "Focus", } export class CameraManager extends Phaser.Events.EventEmitter { - private scene: GameScene; private camera: Phaser.Cameras.Scene2D.Camera; - private cameraBounds: { x: number, y: number }; + private cameraBounds: { x: number; y: number }; private waScaleManager: WaScaleManager; private cameraMode: CameraMode = CameraMode.Free; private restoreZoomTween?: Phaser.Tweens.Tween; - constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { + constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) { super(); this.scene = scene; @@ -39,7 +38,8 @@ export class CameraManager extends Phaser.Events.EventEmitter { } public enterFocusMode( - focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, + focusOn: { x: number; y: number; width: number; height: number }, + duration: number = 1000 ): void { this.setCameraMode(CameraMode.Focus); this.waScaleManager.saveZoom(); @@ -53,9 +53,12 @@ export class CameraManager extends Phaser.Events.EventEmitter { focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5, duration, - Easing.SineEaseOut, false, (camera, progress, x, y) => { + Easing.SineEaseOut, + false, + (camera, progress, x, y) => { this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange; - }); + } + ); } public leaveFocusMode(player: Player): void { @@ -107,7 +110,7 @@ export class CameraManager extends Phaser.Events.EventEmitter { ease: Easing.SineEaseOut, onUpdate: (tween: Phaser.Tweens.Tween) => { this.waScaleManager.zoomModifier = tween.getValue(); - } + }, }); } @@ -115,4 +118,4 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.camera = this.scene.cameras.main; this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); } -} \ No newline at end of file +} diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index b2fab07d..40588923 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,9 +1,15 @@ -import type { ITiledMap, ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer, ITiledMapProperty } from "../Map/ITiledMap"; +import type { + ITiledMap, + ITiledMapLayer, + ITiledMapObject, + ITiledMapObjectLayer, + ITiledMapProperty, +} from "../Map/ITiledMap"; import { flattenGroupLayersMap } from "../Map/LayersFlattener"; import TilemapLayer = Phaser.Tilemaps.TilemapLayer; import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; import { GameMapProperties } from "./GameMapProperties"; -import { MathUtils } from '../../Utils/MathUtils'; +import { MathUtils } from "../../Utils/MathUtils"; export type PropertyChangeCallback = ( newValue: string | number | boolean | undefined, @@ -28,20 +34,20 @@ export type zoneChangeCallback = ( export class GameMap { /** * oldKey is the index of the previous tile. - */ + */ private oldKey: number | undefined; /** * key is the index of the current tile. - */ + */ private key: number | undefined; /** * oldPosition is the previous position of the player. */ - private oldPosition: { x: number, y: number } | undefined; + private oldPosition: { x: number; y: number } | undefined; /** * position is the current position of the player. */ - private position: { x: number, y: number } | undefined; + private position: { x: number; y: number } | undefined; private lastProperties = new Map(); private propertiesChangeCallbacks = new Map>(); @@ -117,19 +123,19 @@ export class GameMap { this.oldPosition = this.position; this.position = { x, y }; this.triggerZonesChange(); - + this.oldKey = this.key; - + const xMap = Math.floor(x / this.map.tilewidth); const yMap = Math.floor(y / this.map.tileheight); const key = xMap + yMap * this.map.width; - + if (key === this.key) { return; } - + this.key = key; - + this.triggerAllProperties(); this.triggerLayersChange(); } @@ -189,25 +195,27 @@ export class GameMap { * We user Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. */ private triggerZonesChange(): void { - const zones = this.tiledObjects.filter(object => object.type === "zone"); + const zones = this.tiledObjects.filter((object) => object.type === "zone"); // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys // TODO: Change this to an array with currently occupied sone instead of doing elimination process - const zonesByOldPosition = this.oldPosition ? - zones.filter((zone) => { - if (!this.oldPosition) { - return false; - } - return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); - }) : []; + const zonesByOldPosition = this.oldPosition + ? zones.filter((zone) => { + if (!this.oldPosition) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); + }) + : []; - const zonesByNewPosition = this.position ? - zones.filter((zone) => { - if (!this.position) { - return false; - } - return MathUtils.isOverlappingWithRectangle(this.position, zone); - }) : []; + const zonesByNewPosition = this.position + ? zones.filter((zone) => { + if (!this.position) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.position, zone); + }) + : []; const enterZones = new Set(zonesByNewPosition); const leaveZones = new Set(zonesByOldPosition); @@ -459,7 +467,7 @@ export class GameMap { private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] { const objects: ITiledMapObject[] = []; - const objectLayers = layers.filter(layer => layer.type === "objectgroup"); + const objectLayers = layers.filter((layer) => layer.type === "objectgroup"); for (const objectLayer of objectLayers) { if (this.isOfTypeITiledMapObjectLayer(objectLayer)) { objects.push(...objectLayer.objects); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index b04788e3..78b56327 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -60,7 +60,7 @@ import { PinchManager } from "../UserInput/PinchManager"; import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; import { waScaleManager } from "../Services/WaScaleManager"; import { EmoteManager } from "./EmoteManager"; -import { CameraManager } from './CameraManager'; +import { CameraManager } from "./CameraManager"; import EVENT_TYPE = Phaser.Scenes.Events; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; @@ -551,7 +551,11 @@ export class GameScene extends DirtyScene { this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted - this.cameraManager = new CameraManager(this, { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, waScaleManager); + this.cameraManager = new CameraManager( + this, + { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, + waScaleManager + ); biggestAvailableAreaStore.recompute(); this.cameraManager.startFollow(this.CurrentPlayer); @@ -787,7 +791,7 @@ export class GameScene extends DirtyScene { this.gameMap.onEnterZone((zones) => { for (const zone of zones) { for (const property of zone.properties ?? []) { - if (property.name === 'focusable' && property.value === true) { + if (property.name === "focusable" && property.value === true) { this.cameraManager.enterFocusMode(zone); break; } @@ -801,7 +805,7 @@ export class GameScene extends DirtyScene { this.gameMap.onLeaveZone((zones) => { for (const zone of zones) { for (const property of zone.properties ?? []) { - if (property.name === 'focusable' && property.value === true) { + if (property.name === "focusable" && property.value === true) { this.cameraManager.leaveFocusMode(this.CurrentPlayer); break; } diff --git a/front/src/Utils/MathUtils.ts b/front/src/Utils/MathUtils.ts index 098b86b4..aea3bb11 100644 --- a/front/src/Utils/MathUtils.ts +++ b/front/src/Utils/MathUtils.ts @@ -1,27 +1,25 @@ - export class MathUtils { - /** - * + * * @param p Position to check. * @param r Rectangle to check the overlap against. * @returns true is overlapping */ public static isOverlappingWithRectangle( - p: { x: number, y: number}, - r: { x: number, y: number, width: number, height: number}, + p: { x: number; y: number }, + r: { x: number; y: number; width: number; height: number } ): boolean { - return (this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height)); + return this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height); } /** - * + * * @param value Value to check * @param min inclusive min value * @param max inclusive max value * @returns true if value is in */ public static isBetween(value: number, min: number, max: number): boolean { - return (value >= min) && (value <= max); + return value >= min && value <= max; } -} \ No newline at end of file +} diff --git a/front/src/types.ts b/front/src/types.ts index 409070e5..d1ff3475 100644 --- a/front/src/types.ts +++ b/front/src/types.ts @@ -50,5 +50,5 @@ export enum Easing { ExpoEaseInOut = "Expo.easeInOut", CircEaseInOut = "Circ.easeInOut", BackEaseInOut = "Back.easeInOut", - BounceEaseInOut = "Bounce.easeInOut" + BounceEaseInOut = "Bounce.easeInOut", } From eb95e2e4839c5a00bd146bb43ac576e5110fee6e Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 1 Dec 2021 14:48:14 +0100 Subject: [PATCH 11/38] detecting zoe enter and leave events --- back/src/Services/VariablesManager.ts | 1 - front/src/Phaser/Game/GameMap.ts | 118 ++- front/src/Phaser/Game/GameScene.ts | 22 + .../src/Phaser/Game/SharedVariablesManager.ts | 2 +- front/src/Phaser/Items/Computer/computer.ts | 1 - front/src/Utils/MathUtils.ts | 27 + maps/starter/map.json | 702 +++++++++--------- 7 files changed, 526 insertions(+), 347 deletions(-) create mode 100644 front/src/Utils/MathUtils.ts diff --git a/back/src/Services/VariablesManager.ts b/back/src/Services/VariablesManager.ts index 00aac3dc..d11cb26f 100644 --- a/back/src/Services/VariablesManager.ts +++ b/back/src/Services/VariablesManager.ts @@ -5,7 +5,6 @@ import { ITiledMap, ITiledMapLayer, ITiledMapObject, - ITiledMapObjectLayer, } from "@workadventure/tiled-map-type-guard/dist"; import { User } from "_Model/User"; import { variablesRepository } from "./Repository/VariablesRepository"; diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 8fe0e329..db9b652e 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,8 +1,9 @@ -import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiledMap"; +import type { ITiledMap, ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer, ITiledMapProperty } from "../Map/ITiledMap"; import { flattenGroupLayersMap } from "../Map/LayersFlattener"; import TilemapLayer = Phaser.Tilemaps.TilemapLayer; import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; import { GameMapProperties } from "./GameMapProperties"; +import { MathUtils } from '../../Utils/MathUtils'; export type PropertyChangeCallback = ( newValue: string | number | boolean | undefined, @@ -15,23 +16,46 @@ export type layerChangeCallback = ( allLayersOnNewPosition: Array ) => void; +export type zoneChangeCallback = ( + zonesChangedByAction: Array, + allZonesOnNewPosition: Array +) => void; + /** * A wrapper around a ITiledMap interface to provide additional capabilities. * It is used to handle layer properties. */ export class GameMap { - // oldKey is the index of the previous tile. + /** + * oldKey is the index of the previous tile. + */ private oldKey: number | undefined; - // key is the index of the current tile. + /** + * key is the index of the current tile. + */ private key: number | undefined; + /** + * oldPosition is the previous position of the player. + */ + private oldPosition: { x: number, y: number } | undefined; + /** + * position is the current position of the player. + */ + private position: { x: number, y: number } | undefined; + private lastProperties = new Map(); private propertiesChangeCallbacks = new Map>(); + private enterLayerCallbacks = Array(); private leaveLayerCallbacks = Array(); + private enterZoneCallbacks = Array(); + private leaveZoneCallbacks = Array(); + private tileNameMap = new Map(); private tileSetPropertyMap: { [tile_index: number]: Array } = {}; public readonly flatLayers: ITiledMapLayer[]; + public readonly tiledObjects: ITiledMapObject[]; public readonly phaserLayers: TilemapLayer[] = []; public exitUrls: Array = []; @@ -44,6 +68,8 @@ export class GameMap { terrains: Array ) { this.flatLayers = flattenGroupLayersMap(map); + this.tiledObjects = this.getObjectsFromLayers(this.flatLayers); + let depth = -2; for (const layer of this.flatLayers) { if (layer.type === "tilelayer") { @@ -88,6 +114,9 @@ export class GameMap { * This will trigger events if properties are changing. */ public setPosition(x: number, y: number) { + this.oldPosition = this.position; + this.position = { x, y }; + this.oldKey = this.key; const xMap = Math.floor(x / this.map.tilewidth); @@ -102,6 +131,7 @@ export class GameMap { this.triggerAllProperties(); this.triggerLayersChange(); + this.triggerZonesChange(); } private triggerAllProperties(): void { @@ -126,7 +156,7 @@ export class GameMap { } } - private triggerLayersChange() { + private triggerLayersChange(): void { const layersByOldKey = this.oldKey ? this.getLayersByKey(this.oldKey) : []; const layersByNewKey = this.key ? this.getLayersByKey(this.key) : []; @@ -155,6 +185,54 @@ export class GameMap { } } + /** + * We user Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. + */ + private triggerZonesChange(): void { + const zones = this.tiledObjects.filter(object => object.type === "zone"); + + // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys + const zonesByOldPosition = this.oldPosition ? + zones.filter((zone) => { + if (!this.oldPosition) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); + }) : []; + + const zonesByNewPosition = this.position ? + zones.filter((zone) => { + if (!this.position) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.position, zone); + }) : []; + + const enterZones = new Set(zonesByNewPosition); + const leaveZones = new Set(zonesByOldPosition); + + enterZones.forEach((zone) => { + if (leaveZones.has(zone)) { + leaveZones.delete(zone); + enterZones.delete(zone); + } + }); + + if (enterZones.size > 0) { + const zonesArray = Array.from(enterZones); + for (const callback of this.enterZoneCallbacks) { + callback(zonesArray, zonesByNewPosition); + } + } + + if (leaveZones.size > 0) { + const zonesArray = Array.from(leaveZones); + for (const callback of this.leaveZoneCallbacks) { + callback(zonesArray, zonesByNewPosition); + } + } + } + public getCurrentProperties(): Map { return this.lastProperties; } @@ -251,6 +329,20 @@ export class GameMap { this.leaveLayerCallbacks.push(callback); } + /** + * Registers a callback called when the user moves inside another zone. + */ + public onEnterZone(callback: zoneChangeCallback) { + this.enterZoneCallbacks.push(callback); + } + + /** + * Registers a callback called when the user moves outside another zone. + */ + public onLeaveZone(callback: zoneChangeCallback) { + this.leaveZoneCallbacks.push(callback); + } + public findLayer(layerName: string): ITiledMapLayer | undefined { return this.flatLayers.find((layer) => layer.name === layerName); } @@ -362,4 +454,22 @@ export class GameMap { this.trigger(oldPropName, oldPropValue, undefined, emptyProps); } } + + private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] { + const objects: ITiledMapObject[] = []; + + const objectLayers = layers.filter(layer => layer.type === "objectgroup"); + for (const objectLayer of objectLayers) { + if (this.isOfTypeITiledMapObjectLayer(objectLayer)) { + objects.push(...objectLayer.objects); + } + } + + return objects; + } + + // NOTE: Simple typeguard for Objects Layer. + private isOfTypeITiledMapObjectLayer(obj: ITiledMapLayer): obj is ITiledMapObjectLayer { + return (obj as ITiledMapObjectLayer).objects !== undefined; + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d9bb8186..8bf0f13e 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -778,6 +778,28 @@ export class GameScene extends DirtyScene { iframeListener.sendLeaveLayerEvent(layer.name); }); }); + + this.gameMap.onEnterZone((zones) => { + console.log('enter zones'); + console.log(zones); + // zones.forEach((zone) => { + // iframeListener.sendEnterLayerEvent(zone.name); + // }); + }); + + this.gameMap.onLeaveZone((zones) => { + console.log('leave zones'); + console.log(zones); + // zones.forEach((zone) => { + // iframeListener.sendEnterLayerEvent(zone.name); + // }); + }); + + // this.gameMap.onLeaveLayer((layers) => { + // layers.forEach((layer) => { + // iframeListener.sendLeaveLayerEvent(layer.name); + // }); + // }); }); } diff --git a/front/src/Phaser/Game/SharedVariablesManager.ts b/front/src/Phaser/Game/SharedVariablesManager.ts index 8f913765..5b5867dc 100644 --- a/front/src/Phaser/Game/SharedVariablesManager.ts +++ b/front/src/Phaser/Game/SharedVariablesManager.ts @@ -1,7 +1,7 @@ import type { RoomConnection } from "../../Connexion/RoomConnection"; import { iframeListener } from "../../Api/IframeListener"; import type { GameMap } from "./GameMap"; -import type { ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer } from "../Map/ITiledMap"; +import type { ITiledMapLayer, ITiledMapObject } from "../Map/ITiledMap"; import { GameMapProperties } from "./GameMapProperties"; interface Variable { diff --git a/front/src/Phaser/Items/Computer/computer.ts b/front/src/Phaser/Items/Computer/computer.ts index 4665c546..41fb6fc4 100644 --- a/front/src/Phaser/Items/Computer/computer.ts +++ b/front/src/Phaser/Items/Computer/computer.ts @@ -1,5 +1,4 @@ import * as Phaser from "phaser"; -import { Scene } from "phaser"; import Sprite = Phaser.GameObjects.Sprite; import type { ITiledMapObject } from "../../Map/ITiledMap"; import type { ItemFactoryInterface } from "../ItemFactoryInterface"; diff --git a/front/src/Utils/MathUtils.ts b/front/src/Utils/MathUtils.ts new file mode 100644 index 00000000..098b86b4 --- /dev/null +++ b/front/src/Utils/MathUtils.ts @@ -0,0 +1,27 @@ + +export class MathUtils { + + /** + * + * @param p Position to check. + * @param r Rectangle to check the overlap against. + * @returns true is overlapping + */ + public static isOverlappingWithRectangle( + p: { x: number, y: number}, + r: { x: number, y: number, width: number, height: number}, + ): boolean { + return (this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height)); + } + + /** + * + * @param value Value to check + * @param min inclusive min value + * @param max inclusive max value + * @returns true if value is in + */ + public static isBetween(value: number, min: number, max: number): boolean { + return (value >= min) && (value <= max); + } +} \ No newline at end of file diff --git a/maps/starter/map.json b/maps/starter/map.json index 8d93c66e..31d81b19 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -1,341 +1,363 @@ -{ "compressionlevel":-1, - "height":17, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":6, - "name":"start", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":7, - "name":"collisions", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":29, - "name":"jitsiMeetingRoom", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"MeetingRoom" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":38, - "name":"jitsiChillzone", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"ChillZone" - }, - { - "name":"jitsiTrigger", - "type":"string", - "value":"onaction" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":23, - "name":"clockZone", - "opacity":1, - "properties":[ - { - "name":"zone", - "type":"string", - "value":"clock" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], - "height":17, - "id":4, - "name":"floor", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], - "height":17, - "id":9, - "name":"walls", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":1, - "name":"furniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":33, - "name":"aboveFurniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "draworder":"topdown", - "id":2, - "name":"floorLayer", - "objects":[ - { - "height":64, - "id":4, - "name":"clockPopup", - "rotation":0, - "type":"", - "visible":true, - "width":128, - "x":512, - "y":0 - }], - "opacity":1, - "type":"objectgroup", - "visible":true, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":3, - "name":"abovePlayer1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":27, - "name":"abovePlayer2", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":28, - "name":"abovePlayer3", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }], - "nextlayerid":39, - "nextobjectid":9, - "orientation":"orthogonal", - "properties":[ - { - "name":"mapCopyright", - "type":"string", - "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" - }, - { - "name":"mapDescription", - "type":"string", - "value":"A perfect virtual office to get started with WorkAdventure!" - }, - { - "name":"mapImage", - "type":"string", - "value":"map.png" - }, - { - "name":"mapLink", - "type":"string", - "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" - }, - { - "name":"mapName", - "type":"string", - "value":"Starter kit" - }, - { - "name":"script", - "type":"string", - "value":"..\/dist\/script.js" - }], - "renderorder":"right-down", - "tiledversion":"1.7.0", - "tileheight":32, - "tilesets":[ - { - "columns":10, - "firstgid":1, - "image":"..\/assets\/tileset5_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset5_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":10, - "firstgid":101, - "image":"..\/assets\/tileset6_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset6_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":201, - "image":"..\/assets\/tileset1.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":322, - "image":"..\/assets\/tileset1-repositioning.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1-repositioning", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":6, - "firstgid":443, - "image":"..\/assets\/Special_Zones.png", - "imageheight":64, - "imagewidth":192, - "margin":0, - "name":"Special_Zones", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":12, - "tileheight":32, - "tiles":[ - { - "id":0, - "properties":[ - { - "name":"collides", - "type":"bool", - "value":true - }] - }], - "tilewidth":32 - }], - "tilewidth":32, - "type":"map", - "version":"1.6", - "width":31 +{ "compressionlevel":-1, + "height":17, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":6, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":7, + "name":"collisions", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":29, + "name":"jitsiMeetingRoom", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"MeetingRoom" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":38, + "name":"jitsiChillzone", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"ChillZone" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":23, + "name":"clockZone", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"clock" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "height":17, + "id":4, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], + "height":17, + "id":9, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":1, + "name":"furniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":33, + "name":"aboveFurniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":2, + "name":"floorLayer", + "objects":[ + { + "height":64, + "id":4, + "name":"clockPopup", + "rotation":0, + "type":"", + "visible":true, + "width":128, + "x":512, + "y":0 + }, + { + "height":128, + "id":9, + "name":"chillZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Chilling Room" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":192, + "x":32, + "y":96 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":3, + "name":"abovePlayer1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":27, + "name":"abovePlayer2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":28, + "name":"abovePlayer3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }], + "nextlayerid":39, + "nextobjectid":11, + "orientation":"orthogonal", + "properties":[ + { + "name":"mapCopyright", + "type":"string", + "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" + }, + { + "name":"mapDescription", + "type":"string", + "value":"A perfect virtual office to get started with WorkAdventure!" + }, + { + "name":"mapImage", + "type":"string", + "value":"map.png" + }, + { + "name":"mapLink", + "type":"string", + "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" + }, + { + "name":"mapName", + "type":"string", + "value":"Starter kit" + }, + { + "name":"script", + "type":"string", + "value":"..\/dist\/script.js" + }], + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":32, + "tilesets":[ + { + "columns":10, + "firstgid":1, + "image":"..\/assets\/tileset5_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset5_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":10, + "firstgid":101, + "image":"..\/assets\/tileset6_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset6_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":201, + "image":"..\/assets\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":322, + "image":"..\/assets\/tileset1-repositioning.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1-repositioning", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":6, + "firstgid":443, + "image":"..\/assets\/Special_Zones.png", + "imageheight":64, + "imagewidth":192, + "margin":0, + "name":"Special_Zones", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":12, + "tileheight":32, + "tiles":[ + { + "id":0, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":31 } \ No newline at end of file From ef3a7513e2b296c02c4c4a96a4328cbcb4e53eba Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 13:20:40 +0100 Subject: [PATCH 12/38] camera zoom using scaleManager zooming. WIP --- front/src/Phaser/Game/CameraManager.ts | 70 +++++++++++++++++++++ front/src/Phaser/Game/GameMap.ts | 1 + front/src/Phaser/Game/GameScene.ts | 59 +++++++++-------- front/src/Phaser/Services/WaScaleManager.ts | 2 +- front/src/types.ts | 31 +++++++++ maps/starter/map.json | 26 +++++++- 6 files changed, 155 insertions(+), 34 deletions(-) create mode 100644 front/src/Phaser/Game/CameraManager.ts diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts new file mode 100644 index 00000000..595867be --- /dev/null +++ b/front/src/Phaser/Game/CameraManager.ts @@ -0,0 +1,70 @@ +import { Easing } from '../../types'; +import { HtmlUtils } from '../../WebRtc/HtmlUtils'; +import type { Box } from '../../WebRtc/LayoutManager'; +import type { WaScaleManager } from '../Services/WaScaleManager'; +import type { GameScene } from './GameScene'; + +export class CameraManager extends Phaser.Events.EventEmitter { + + private scene: GameScene; + private camera: Phaser.Cameras.Scene2D.Camera; + private waScaleManager: WaScaleManager; + + private cameraBounds: { x: number, y: number }; + + constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { + super(); + this.scene = scene; + + this.camera = scene.cameras.main; + this.cameraBounds = cameraBounds; + + this.waScaleManager = waScaleManager; + + this.initCamera(); + } + + public getCamera(): Phaser.Cameras.Scene2D.Camera { + return this.camera; + } + + public changeCameraFocus(focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000): void { + const maxZoomModifier = 2.84; // How to get max zoom value? + const currentZoomModifier = this.waScaleManager.zoomModifier; + const zoomModifierChange = maxZoomModifier - currentZoomModifier; + this.camera.stopFollow(); + this.camera.pan( + focusOn.x + focusOn.width * 0.5, + focusOn.y + focusOn.height * 0.5, + duration, + Easing.SineEaseOut, false, (camera, progress, x, y) => { + this.scene.setZoomModifierTo(currentZoomModifier + progress * zoomModifierChange); + }); + } + + public startFollow(target: object | Phaser.GameObjects.GameObject): void { + this.camera.startFollow(target, true); + } + + /** + * Updates the offset of the character compared to the center of the screen according to the layout manager + * (tries to put the character in the center of the remaining space if there is a discussion going on. + */ + public updateCameraOffset(array: Box): void { + const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart; + const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart; + + const game = HtmlUtils.querySelectorOrFail("#game canvas"); + // Let's put this in Game coordinates by applying the zoom level: + + this.camera.setFollowOffset( + ((xCenter - game.offsetWidth / 2) * window.devicePixelRatio) / this.scene.scale.zoom, + ((yCenter - game.offsetHeight / 2) * window.devicePixelRatio) / this.scene.scale.zoom + ); + } + + private initCamera() { + this.camera = this.scene.cameras.main; + this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); + } +} \ No newline at end of file diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index db9b652e..85a1a0e0 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -192,6 +192,7 @@ export class GameMap { const zones = this.tiledObjects.filter(object => object.type === "zone"); // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys + // TODO: Change this to an array with currently occupied sone instead of doing elimination process const zonesByOldPosition = this.oldPosition ? zones.filter((zone) => { if (!this.oldPosition) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8bf0f13e..d596fa56 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -60,6 +60,7 @@ import { PinchManager } from "../UserInput/PinchManager"; import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; import { waScaleManager } from "../Services/WaScaleManager"; import { EmoteManager } from "./EmoteManager"; +import { CameraManager } from './CameraManager'; import EVENT_TYPE = Phaser.Scenes.Events; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; @@ -198,6 +199,7 @@ export class GameScene extends DirtyScene { private pinchManager: PinchManager | undefined; private mapTransitioning: boolean = false; //used to prevent transitions happening at the same time. private emoteManager!: EmoteManager; + private cameraManager!: CameraManager; private preloading: boolean = true; private startPositionCalculator!: StartPositionCalculator; private sharedVariablesManager!: SharedVariablesManager; @@ -549,7 +551,9 @@ export class GameScene extends DirtyScene { this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted - this.initCamera(); + this.cameraManager = new CameraManager(this, { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, waScaleManager); + biggestAvailableAreaStore.recompute(); + this.cameraManager.startFollow(this.CurrentPlayer); this.animatedTiles.init(this.Map); this.events.on("tileanimationupdate", () => (this.dirty = true)); @@ -590,7 +594,7 @@ export class GameScene extends DirtyScene { // From now, this game scene will be notified of reposition events this.biggestAvailableAreaStoreUnsubscribe = biggestAvailableAreaStore.subscribe((box) => - this.updateCameraOffset(box) + this.cameraManager.updateCameraOffset(box) ); new GameMapPropertiesListener(this, this.gameMap).register(); @@ -643,7 +647,7 @@ export class GameScene extends DirtyScene { * Initializes the connection to Pusher. */ private connect(): void { - const camera = this.cameras.main; + const camera = this.cameraManager.getCamera(); connectionManager .connectToRoomSocket( @@ -779,17 +783,30 @@ export class GameScene extends DirtyScene { }); }); + // P.H. TODO: Send those events to the iframe? this.gameMap.onEnterZone((zones) => { - console.log('enter zones'); - console.log(zones); + for (const zone of zones) { + for (const property of zone.properties ?? []) { + if (property.name === 'focusable' && property.value === true) { + this.cameraManager.changeCameraFocus(zone); + break; + } + } + } // zones.forEach((zone) => { // iframeListener.sendEnterLayerEvent(zone.name); // }); }); this.gameMap.onLeaveZone((zones) => { - console.log('leave zones'); - console.log(zones); + for (const zone of zones) { + for (const property of zone.properties ?? []) { + if (property.name === 'focusable' && property.value === true) { + this.cameraManager.startFollow(this.CurrentPlayer); + break; + } + } + } // zones.forEach((zone) => { // iframeListener.sendEnterLayerEvent(zone.name); // }); @@ -1478,13 +1495,6 @@ ${escapedMessage} } } - //todo: in a dedicated class/function? - initCamera() { - this.cameras.main.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels); - this.cameras.main.startFollow(this.CurrentPlayer, true); - biggestAvailableAreaStore.recompute(); - } - createCollisionWithPlayer() { //add collision layer for (const phaserLayer of this.gameMap.phaserLayers) { @@ -1876,23 +1886,6 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } - /** - * Updates the offset of the character compared to the center of the screen according to the layout manager - * (tries to put the character in the center of the remaining space if there is a discussion going on. - */ - private updateCameraOffset(array: Box): void { - const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart; - const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart; - - const game = HtmlUtils.querySelectorOrFail("#game canvas"); - // Let's put this in Game coordinates by applying the zoom level: - - this.cameras.main.setFollowOffset( - ((xCenter - game.offsetWidth / 2) * window.devicePixelRatio) / this.scale.zoom, - ((yCenter - game.offsetHeight / 2) * window.devicePixelRatio) / this.scale.zoom - ); - } - public startJitsi(roomName: string, jwt?: string): void { const allProps = this.gameMap.getCurrentProperties(); const jitsiConfig = this.safeParseJSONstring( @@ -1965,6 +1958,10 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } + public setZoomModifierTo(value: number): void { + waScaleManager.zoomModifier = value; + } + public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) { const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey); diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 5ceaeb71..3fb1d29b 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -5,7 +5,7 @@ import type { Game } from "../Game/Game"; import { ResizableScene } from "../Login/ResizableScene"; import { HtmlUtils } from "../../WebRtc/HtmlUtils"; -class WaScaleManager { +export class WaScaleManager { private hdpiManager: HdpiManager; private scaleManager!: ScaleManager; private game!: Game; diff --git a/front/src/types.ts b/front/src/types.ts index d957a2c2..409070e5 100644 --- a/front/src/types.ts +++ b/front/src/types.ts @@ -21,3 +21,34 @@ export interface IVirtualJoystick extends Phaser.GameObjects.GameObject { visible: boolean; createCursorKeys: () => CursorKeys; } + +export enum Easing { + Linear = "Linear", + QuadEaseIn = "Quad.easeIn", + CubicEaseIn = "Cubic.easeIn", + QuartEaseIn = "Quart.easeIn", + QuintEaseIn = "Quint.easeIn", + SineEaseIn = "Sine.easeIn", + ExpoEaseIn = "Expo.easeIn", + CircEaseIn = "Circ.easeIn", + BackEaseIn = "Back.easeIn", + BounceEaseIn = "Bounce.easeIn", + QuadEaseOut = "Quad.easeOut", + CubicEaseOut = "Cubic.easeOut", + QuartEaseOut = "Quart.easeOut", + QuintEaseOut = "Quint.easeOut", + SineEaseOut = "Sine.easeOut", + ExpoEaseOut = "Expo.easeOut", + CircEaseOut = "Circ.easeOut", + BackEaseOut = "Back.easeOut", + BounceEaseOut = "Bounce.easeOut", + QuadEaseInOut = "Quad.easeInOut", + CubicEaseInOut = "Cubic.easeInOut", + QuartEaseInOut = "Quart.easeInOut", + QuintEaseInOut = "Quint.easeInOut", + SineEaseInOut = "Sine.easeInOut", + ExpoEaseInOut = "Expo.easeInOut", + CircEaseInOut = "Circ.easeInOut", + BackEaseInOut = "Back.easeInOut", + BounceEaseInOut = "Bounce.easeInOut" +} diff --git a/maps/starter/map.json b/maps/starter/map.json index 31d81b19..2ef0516d 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -86,7 +86,7 @@ "y":0 }, { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], "height":17, "id":4, "name":"floor", @@ -170,6 +170,28 @@ "width":192, "x":32, "y":96 + }, + { + "height":64, + "id":11, + "name":"coffeeZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Coffee Time!" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":64, + "x":64, + "y":288 }], "opacity":1, "type":"objectgroup", @@ -214,7 +236,7 @@ "y":0 }], "nextlayerid":39, - "nextobjectid":11, + "nextobjectid":12, "orientation":"orthogonal", "properties":[ { From 092daa245f91094a576862a55ebb1c1fe19c0cc5 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 13:41:52 +0100 Subject: [PATCH 13/38] locking zooming via player input --- front/src/Phaser/Game/CameraManager.ts | 8 +++++++- front/src/Phaser/Game/GameScene.ts | 3 +++ front/src/Phaser/Services/WaScaleManager.ts | 10 ++++++++++ maps/starter/map.json | 12 ++++++------ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 595867be..e900a059 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -28,7 +28,11 @@ export class CameraManager extends Phaser.Events.EventEmitter { return this.camera; } - public changeCameraFocus(focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000): void { + public changeCameraFocus( + focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, + ): void { + this.waScaleManager.saveZoom(); + this.waScaleManager.lockZoomingViaPlayerInput(); const maxZoomModifier = 2.84; // How to get max zoom value? const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = maxZoomModifier - currentZoomModifier; @@ -43,6 +47,8 @@ export class CameraManager extends Phaser.Events.EventEmitter { } public startFollow(target: object | Phaser.GameObjects.GameObject): void { + this.waScaleManager.lockZoomingViaPlayerInput(false); + this.waScaleManager.restoreZoom(); this.camera.startFollow(target, true); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d596fa56..4afd0383 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1954,6 +1954,9 @@ ${escapedMessage} } zoomByFactor(zoomFactor: number) { + if (waScaleManager.isZoomingViaPlayerInputLocked()) { + return; + } waScaleManager.zoomModifier *= zoomFactor; biggestAvailableAreaStore.recompute(); } diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 3fb1d29b..f8aeba2d 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -12,6 +12,8 @@ export class WaScaleManager { private actualZoom: number = 1; private _saveZoom: number = 1; + private zoomingViaPlayerInputLocked: boolean = false; + public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); } @@ -21,6 +23,14 @@ export class WaScaleManager { this.game = game; } + public isZoomingViaPlayerInputLocked(): boolean { + return this.zoomingViaPlayerInputLocked; + } + + public lockZoomingViaPlayerInput(lock: boolean = true): void { + this.zoomingViaPlayerInputLocked = lock; + } + public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); diff --git a/maps/starter/map.json b/maps/starter/map.json index 2ef0516d..2627a79e 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -172,14 +172,14 @@ "y":96 }, { - "height":64, + "height":352, "id":11, - "name":"coffeeZone", + "name":"meetingZone", "properties":[ { "name":"display_name", "type":"string", - "value":"Coffee Time!" + "value":"Brainstorm Zone!" }, { "name":"focusable", @@ -189,9 +189,9 @@ "rotation":0, "type":"zone", "visible":true, - "width":64, - "x":64, - "y":288 + "width":224, + "x":736, + "y":96 }], "opacity":1, "type":"objectgroup", From ddaa81a7acc6f6078c73248875eb6e62b38bc8d5 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 14:44:13 +0100 Subject: [PATCH 14/38] some more tweaks with smooth zooming control --- front/src/Phaser/Game/CameraManager.ts | 52 +++++++++++++++++++-- front/src/Phaser/Game/GameScene.ts | 6 +-- front/src/Phaser/Services/WaScaleManager.ts | 14 ++---- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index e900a059..45621e1c 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -1,16 +1,26 @@ import { Easing } from '../../types'; import { HtmlUtils } from '../../WebRtc/HtmlUtils'; import type { Box } from '../../WebRtc/LayoutManager'; +import type { Player } from '../Player/Player'; import type { WaScaleManager } from '../Services/WaScaleManager'; import type { GameScene } from './GameScene'; +export enum CameraMode { + Free = 'Free', + Follow = 'Follow', + Focus = 'Focus', +} + export class CameraManager extends Phaser.Events.EventEmitter { private scene: GameScene; private camera: Phaser.Cameras.Scene2D.Camera; + private cameraBounds: { x: number, y: number }; private waScaleManager: WaScaleManager; - private cameraBounds: { x: number, y: number }; + private cameraMode: CameraMode = CameraMode.Free; + + private restoreZoomTween?: Phaser.Tweens.Tween; constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { super(); @@ -28,11 +38,13 @@ export class CameraManager extends Phaser.Events.EventEmitter { return this.camera; } - public changeCameraFocus( + public enterFocusMode( focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, ): void { + this.setCameraMode(CameraMode.Focus); this.waScaleManager.saveZoom(); - this.waScaleManager.lockZoomingViaPlayerInput(); + + this.restoreZoomTween?.stop(); const maxZoomModifier = 2.84; // How to get max zoom value? const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = maxZoomModifier - currentZoomModifier; @@ -46,9 +58,15 @@ export class CameraManager extends Phaser.Events.EventEmitter { }); } + public leaveFocusMode(player: Player): void { + // We are forcing camera.pan to kill previous pan animation on EnterFocusMode + this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true); + this.startFollow(player); + this.restoreZoom(); + } + public startFollow(target: object | Phaser.GameObjects.GameObject): void { - this.waScaleManager.lockZoomingViaPlayerInput(false); - this.waScaleManager.restoreZoom(); + this.setCameraMode(CameraMode.Follow); this.camera.startFollow(target, true); } @@ -69,6 +87,30 @@ export class CameraManager extends Phaser.Events.EventEmitter { ); } + public isCameraLocked(): boolean { + return this.cameraMode === CameraMode.Focus; + } + + private setCameraMode(mode: CameraMode): void { + if (this.cameraMode === mode) { + return; + } + this.cameraMode = mode; + } + + private restoreZoom(): void { + this.restoreZoomTween?.stop(); + this.restoreZoomTween = this.scene.tweens.addCounter({ + from: this.waScaleManager.zoomModifier, + to: this.waScaleManager.getSaveZoom(), + duration: 1000, + ease: Easing.SineEaseOut, + onUpdate: (tween: Phaser.Tweens.Tween) => { + this.waScaleManager.zoomModifier = tween.getValue(); + } + }); + } + private initCamera() { this.camera = this.scene.cameras.main; this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4afd0383..90297272 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -788,7 +788,7 @@ export class GameScene extends DirtyScene { for (const zone of zones) { for (const property of zone.properties ?? []) { if (property.name === 'focusable' && property.value === true) { - this.cameraManager.changeCameraFocus(zone); + this.cameraManager.enterFocusMode(zone); break; } } @@ -802,7 +802,7 @@ export class GameScene extends DirtyScene { for (const zone of zones) { for (const property of zone.properties ?? []) { if (property.name === 'focusable' && property.value === true) { - this.cameraManager.startFollow(this.CurrentPlayer); + this.cameraManager.leaveFocusMode(this.CurrentPlayer); break; } } @@ -1954,7 +1954,7 @@ ${escapedMessage} } zoomByFactor(zoomFactor: number) { - if (waScaleManager.isZoomingViaPlayerInputLocked()) { + if (this.cameraManager.isCameraLocked()) { return; } waScaleManager.zoomModifier *= zoomFactor; diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index f8aeba2d..ee2ca9ea 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -12,8 +12,6 @@ export class WaScaleManager { private actualZoom: number = 1; private _saveZoom: number = 1; - private zoomingViaPlayerInputLocked: boolean = false; - public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); } @@ -23,14 +21,6 @@ export class WaScaleManager { this.game = game; } - public isZoomingViaPlayerInputLocked(): boolean { - return this.zoomingViaPlayerInputLocked; - } - - public lockZoomingViaPlayerInput(lock: boolean = true): void { - this.zoomingViaPlayerInputLocked = lock; - } - public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); @@ -82,6 +72,10 @@ export class WaScaleManager { this._saveZoom = this.hdpiManager.zoomModifier; } + public getSaveZoom(): number { + return this._saveZoom; + } + public restoreZoom(): void { this.hdpiManager.zoomModifier = this._saveZoom; this.applyNewSize(); From 37949eda5323d8043714cbfc8edb815d05a9ef96 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 17:46:09 +0100 Subject: [PATCH 15/38] working with zoom modifier calculating per zone --- front/src/Phaser/Game/CameraManager.ts | 6 +++--- front/src/Phaser/Game/GameScene.ts | 4 ---- front/src/Phaser/Services/WaScaleManager.ts | 18 ++++++++++++++---- maps/starter/map.json | 6 +++--- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 45621e1c..d8c385e6 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -45,16 +45,16 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.waScaleManager.saveZoom(); this.restoreZoomTween?.stop(); - const maxZoomModifier = 2.84; // How to get max zoom value? + const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(focusOn.width, focusOn.height); const currentZoomModifier = this.waScaleManager.zoomModifier; - const zoomModifierChange = maxZoomModifier - currentZoomModifier; + const zoomModifierChange = targetZoomModifier - currentZoomModifier; this.camera.stopFollow(); this.camera.pan( focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5, duration, Easing.SineEaseOut, false, (camera, progress, x, y) => { - this.scene.setZoomModifierTo(currentZoomModifier + progress * zoomModifierChange); + this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange; }); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 90297272..b04788e3 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1961,10 +1961,6 @@ ${escapedMessage} biggestAvailableAreaStore.recompute(); } - public setZoomModifierTo(value: number): void { - waScaleManager.zoomModifier = value; - } - public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) { const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey); diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index ee2ca9ea..838f82d2 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -24,10 +24,7 @@ export class WaScaleManager { public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); - let devicePixelRatio = 1; - if (window.devicePixelRatio) { - devicePixelRatio = window.devicePixelRatio; - } + const devicePixelRatio = window.devicePixelRatio ?? 1; const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({ width: width * devicePixelRatio, @@ -59,6 +56,19 @@ export class WaScaleManager { this.game.markDirty(); } + public getTargetZoomModifierFor(viewportWidth: number, viewportHeight: number) { + const { width: gameWidth, height: gameHeight } = coWebsiteManager.getGameSize(); + const devicePixelRatio = window.devicePixelRatio ?? 1; + + const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({ + width: gameWidth * devicePixelRatio, + height: gameHeight * devicePixelRatio, + }); + // P.H. Note: Dunno where this magic 2 comes from + // Always return lowest possible value. Need to add MAX ZOOM MODIFIER value into this. + return Math.min(realSize.width / viewportWidth / 2, realSize.height / viewportHeight / 2); + } + public get zoomModifier(): number { return this.hdpiManager.zoomModifier; } diff --git a/maps/starter/map.json b/maps/starter/map.json index 2627a79e..fd0b984e 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -86,7 +86,7 @@ "y":0 }, { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 212, 212, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], "height":17, "id":4, "name":"floor", @@ -172,7 +172,7 @@ "y":96 }, { - "height":352, + "height":416, "id":11, "name":"meetingZone", "properties":[ @@ -191,7 +191,7 @@ "visible":true, "width":224, "x":736, - "y":96 + "y":32 }], "opacity":1, "type":"objectgroup", From a1a83775d6332fcfb1ae8abb27cceaed560e74ba Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Thu, 2 Dec 2021 18:11:22 +0100 Subject: [PATCH 16/38] issues with zone triggering fixed --- front/src/Phaser/Game/GameMap.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 85a1a0e0..b2fab07d 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -116,22 +116,22 @@ export class GameMap { public setPosition(x: number, y: number) { this.oldPosition = this.position; this.position = { x, y }; - + this.triggerZonesChange(); + this.oldKey = this.key; - + const xMap = Math.floor(x / this.map.tilewidth); const yMap = Math.floor(y / this.map.tileheight); const key = xMap + yMap * this.map.width; - + if (key === this.key) { return; } - + this.key = key; - + this.triggerAllProperties(); this.triggerLayersChange(); - this.triggerZonesChange(); } private triggerAllProperties(): void { From 4bc21a95c57d2e9d7dad95274fa853c61b036449 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 3 Dec 2021 10:11:16 +0100 Subject: [PATCH 17/38] ran prettier --- front/src/Phaser/Game/CameraManager.ts | 37 ++++++++------- front/src/Phaser/Game/GameMap.ts | 62 +++++++++++++++----------- front/src/Phaser/Game/GameScene.ts | 12 +++-- front/src/Utils/MathUtils.ts | 16 +++---- front/src/types.ts | 2 +- 5 files changed, 71 insertions(+), 58 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index d8c385e6..00006a7d 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -1,28 +1,27 @@ -import { Easing } from '../../types'; -import { HtmlUtils } from '../../WebRtc/HtmlUtils'; -import type { Box } from '../../WebRtc/LayoutManager'; -import type { Player } from '../Player/Player'; -import type { WaScaleManager } from '../Services/WaScaleManager'; -import type { GameScene } from './GameScene'; +import { Easing } from "../../types"; +import { HtmlUtils } from "../../WebRtc/HtmlUtils"; +import type { Box } from "../../WebRtc/LayoutManager"; +import type { Player } from "../Player/Player"; +import type { WaScaleManager } from "../Services/WaScaleManager"; +import type { GameScene } from "./GameScene"; export enum CameraMode { - Free = 'Free', - Follow = 'Follow', - Focus = 'Focus', + Free = "Free", + Follow = "Follow", + Focus = "Focus", } export class CameraManager extends Phaser.Events.EventEmitter { - private scene: GameScene; private camera: Phaser.Cameras.Scene2D.Camera; - private cameraBounds: { x: number, y: number }; + private cameraBounds: { x: number; y: number }; private waScaleManager: WaScaleManager; private cameraMode: CameraMode = CameraMode.Free; private restoreZoomTween?: Phaser.Tweens.Tween; - constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { + constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) { super(); this.scene = scene; @@ -39,7 +38,8 @@ export class CameraManager extends Phaser.Events.EventEmitter { } public enterFocusMode( - focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, + focusOn: { x: number; y: number; width: number; height: number }, + duration: number = 1000 ): void { this.setCameraMode(CameraMode.Focus); this.waScaleManager.saveZoom(); @@ -53,9 +53,12 @@ export class CameraManager extends Phaser.Events.EventEmitter { focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5, duration, - Easing.SineEaseOut, false, (camera, progress, x, y) => { + Easing.SineEaseOut, + false, + (camera, progress, x, y) => { this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange; - }); + } + ); } public leaveFocusMode(player: Player): void { @@ -107,7 +110,7 @@ export class CameraManager extends Phaser.Events.EventEmitter { ease: Easing.SineEaseOut, onUpdate: (tween: Phaser.Tweens.Tween) => { this.waScaleManager.zoomModifier = tween.getValue(); - } + }, }); } @@ -115,4 +118,4 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.camera = this.scene.cameras.main; this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); } -} \ No newline at end of file +} diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index b2fab07d..40588923 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,9 +1,15 @@ -import type { ITiledMap, ITiledMapLayer, ITiledMapObject, ITiledMapObjectLayer, ITiledMapProperty } from "../Map/ITiledMap"; +import type { + ITiledMap, + ITiledMapLayer, + ITiledMapObject, + ITiledMapObjectLayer, + ITiledMapProperty, +} from "../Map/ITiledMap"; import { flattenGroupLayersMap } from "../Map/LayersFlattener"; import TilemapLayer = Phaser.Tilemaps.TilemapLayer; import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; import { GameMapProperties } from "./GameMapProperties"; -import { MathUtils } from '../../Utils/MathUtils'; +import { MathUtils } from "../../Utils/MathUtils"; export type PropertyChangeCallback = ( newValue: string | number | boolean | undefined, @@ -28,20 +34,20 @@ export type zoneChangeCallback = ( export class GameMap { /** * oldKey is the index of the previous tile. - */ + */ private oldKey: number | undefined; /** * key is the index of the current tile. - */ + */ private key: number | undefined; /** * oldPosition is the previous position of the player. */ - private oldPosition: { x: number, y: number } | undefined; + private oldPosition: { x: number; y: number } | undefined; /** * position is the current position of the player. */ - private position: { x: number, y: number } | undefined; + private position: { x: number; y: number } | undefined; private lastProperties = new Map(); private propertiesChangeCallbacks = new Map>(); @@ -117,19 +123,19 @@ export class GameMap { this.oldPosition = this.position; this.position = { x, y }; this.triggerZonesChange(); - + this.oldKey = this.key; - + const xMap = Math.floor(x / this.map.tilewidth); const yMap = Math.floor(y / this.map.tileheight); const key = xMap + yMap * this.map.width; - + if (key === this.key) { return; } - + this.key = key; - + this.triggerAllProperties(); this.triggerLayersChange(); } @@ -189,25 +195,27 @@ export class GameMap { * We user Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. */ private triggerZonesChange(): void { - const zones = this.tiledObjects.filter(object => object.type === "zone"); + const zones = this.tiledObjects.filter((object) => object.type === "zone"); // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys // TODO: Change this to an array with currently occupied sone instead of doing elimination process - const zonesByOldPosition = this.oldPosition ? - zones.filter((zone) => { - if (!this.oldPosition) { - return false; - } - return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); - }) : []; + const zonesByOldPosition = this.oldPosition + ? zones.filter((zone) => { + if (!this.oldPosition) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.oldPosition, zone); + }) + : []; - const zonesByNewPosition = this.position ? - zones.filter((zone) => { - if (!this.position) { - return false; - } - return MathUtils.isOverlappingWithRectangle(this.position, zone); - }) : []; + const zonesByNewPosition = this.position + ? zones.filter((zone) => { + if (!this.position) { + return false; + } + return MathUtils.isOverlappingWithRectangle(this.position, zone); + }) + : []; const enterZones = new Set(zonesByNewPosition); const leaveZones = new Set(zonesByOldPosition); @@ -459,7 +467,7 @@ export class GameMap { private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] { const objects: ITiledMapObject[] = []; - const objectLayers = layers.filter(layer => layer.type === "objectgroup"); + const objectLayers = layers.filter((layer) => layer.type === "objectgroup"); for (const objectLayer of objectLayers) { if (this.isOfTypeITiledMapObjectLayer(objectLayer)) { objects.push(...objectLayer.objects); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index b04788e3..78b56327 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -60,7 +60,7 @@ import { PinchManager } from "../UserInput/PinchManager"; import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; import { waScaleManager } from "../Services/WaScaleManager"; import { EmoteManager } from "./EmoteManager"; -import { CameraManager } from './CameraManager'; +import { CameraManager } from "./CameraManager"; import EVENT_TYPE = Phaser.Scenes.Events; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; @@ -551,7 +551,11 @@ export class GameScene extends DirtyScene { this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted - this.cameraManager = new CameraManager(this, { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, waScaleManager); + this.cameraManager = new CameraManager( + this, + { x: this.Map.widthInPixels, y: this.Map.heightInPixels }, + waScaleManager + ); biggestAvailableAreaStore.recompute(); this.cameraManager.startFollow(this.CurrentPlayer); @@ -787,7 +791,7 @@ export class GameScene extends DirtyScene { this.gameMap.onEnterZone((zones) => { for (const zone of zones) { for (const property of zone.properties ?? []) { - if (property.name === 'focusable' && property.value === true) { + if (property.name === "focusable" && property.value === true) { this.cameraManager.enterFocusMode(zone); break; } @@ -801,7 +805,7 @@ export class GameScene extends DirtyScene { this.gameMap.onLeaveZone((zones) => { for (const zone of zones) { for (const property of zone.properties ?? []) { - if (property.name === 'focusable' && property.value === true) { + if (property.name === "focusable" && property.value === true) { this.cameraManager.leaveFocusMode(this.CurrentPlayer); break; } diff --git a/front/src/Utils/MathUtils.ts b/front/src/Utils/MathUtils.ts index 098b86b4..aea3bb11 100644 --- a/front/src/Utils/MathUtils.ts +++ b/front/src/Utils/MathUtils.ts @@ -1,27 +1,25 @@ - export class MathUtils { - /** - * + * * @param p Position to check. * @param r Rectangle to check the overlap against. * @returns true is overlapping */ public static isOverlappingWithRectangle( - p: { x: number, y: number}, - r: { x: number, y: number, width: number, height: number}, + p: { x: number; y: number }, + r: { x: number; y: number; width: number; height: number } ): boolean { - return (this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height)); + return this.isBetween(p.x, r.x, r.x + r.width) && this.isBetween(p.y, r.y, r.y + r.height); } /** - * + * * @param value Value to check * @param min inclusive min value * @param max inclusive max value * @returns true if value is in */ public static isBetween(value: number, min: number, max: number): boolean { - return (value >= min) && (value <= max); + return value >= min && value <= max; } -} \ No newline at end of file +} diff --git a/front/src/types.ts b/front/src/types.ts index 409070e5..d1ff3475 100644 --- a/front/src/types.ts +++ b/front/src/types.ts @@ -50,5 +50,5 @@ export enum Easing { ExpoEaseInOut = "Expo.easeInOut", CircEaseInOut = "Circ.easeInOut", BackEaseInOut = "Back.easeInOut", - BounceEaseInOut = "Bounce.easeInOut" + BounceEaseInOut = "Bounce.easeInOut", } From 9a81aa83f1e37cb827d98fdf5fe4f9d9f8872815 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Sat, 4 Dec 2021 17:24:39 +0100 Subject: [PATCH 18/38] added test map for focusable zones feature --- maps/tests/focusable_zone_map.json | 425 +++++++++++++++++++++++++++++ maps/tests/index.html | 8 + 2 files changed, 433 insertions(+) create mode 100644 maps/tests/focusable_zone_map.json diff --git a/maps/tests/focusable_zone_map.json b/maps/tests/focusable_zone_map.json new file mode 100644 index 00000000..b747d7a0 --- /dev/null +++ b/maps/tests/focusable_zone_map.json @@ -0,0 +1,425 @@ +{ "compressionlevel":-1, + "height":17, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":6, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":7, + "name":"collisions", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":29, + "name":"jitsiMeetingRoom", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"MeetingRoom" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":38, + "name":"jitsiChillzone", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"ChillZone" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":23, + "name":"clockZone", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"clock" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "height":17, + "id":4, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], + "height":17, + "id":9, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":1, + "name":"furniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":33, + "name":"aboveFurniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":2, + "name":"floorLayer", + "objects":[ + { + "height":64, + "id":4, + "name":"clockPopup", + "rotation":0, + "type":"", + "visible":true, + "width":128, + "x":512, + "y":0 + }, + { + "height":128, + "id":9, + "name":"chillZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Chilling Room" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":192, + "x":32, + "y":96 + }, + { + "height":416, + "id":11, + "name":"meetingZone", + "properties":[ + { + "name":"display_name", + "type":"string", + "value":"Brainstorm Zone!" + }, + { + "name":"focusable", + "type":"bool", + "value":true + }], + "rotation":0, + "type":"zone", + "visible":true, + "width":224, + "x":736, + "y":32 + }, + { + "height":66.6667, + "id":12, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "halign":"center", + "pixelsize":11, + "text":"Step inside to focus on the chilling zone", + "valign":"center", + "wrap":true + }, + "type":"", + "visible":true, + "width":155.104, + "x":52.6352863978128, + "y":125.784444486216 + }, + { + "height":66.6667, + "id":13, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "halign":"center", + "pixelsize":11, + "text":"Camera should show the whole zone. Zoom in before entering", + "valign":"center", + "wrap":true + }, + "type":"", + "visible":true, + "width":155.104, + "x":770.473518341308, + "y":126.688522863978 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":3, + "name":"abovePlayer1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":27, + "name":"abovePlayer2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":28, + "name":"abovePlayer3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }], + "nextlayerid":39, + "nextobjectid":14, + "orientation":"orthogonal", + "properties":[ + { + "name":"mapCopyright", + "type":"string", + "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" + }, + { + "name":"mapDescription", + "type":"string", + "value":"A perfect virtual office to get started with WorkAdventure!" + }, + { + "name":"mapImage", + "type":"string", + "value":"map.png" + }, + { + "name":"mapLink", + "type":"string", + "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" + }, + { + "name":"mapName", + "type":"string", + "value":"Starter kit" + }, + { + "name":"script", + "type":"string", + "value":"..\/dist\/script.js" + }], + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":32, + "tilesets":[ + { + "columns":10, + "firstgid":1, + "image":"..\/assets\/tileset5_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset5_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":10, + "firstgid":101, + "image":"..\/assets\/tileset6_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset6_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":201, + "image":"..\/assets\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":322, + "image":"..\/assets\/tileset1-repositioning.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1-repositioning", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":6, + "firstgid":443, + "image":"..\/assets\/Special_Zones.png", + "imageheight":64, + "imagewidth":192, + "margin":0, + "name":"Special_Zones", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":12, + "tileheight":32, + "tiles":[ + { + "id":0, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":31 +} \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 068136ed..c920c876 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -104,6 +104,14 @@ Testing Emoji + + + Success Failure Pending + + + Focusable Zones + +

Iframe API

From d6be8bc71bc4d8f4414b0e98f49ea9031ff17c76 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Sat, 4 Dec 2021 17:26:23 +0100 Subject: [PATCH 19/38] revert changes made to the starter/map.json --- maps/starter/map.json | 724 ++++++++++++++++++++---------------------- 1 file changed, 340 insertions(+), 384 deletions(-) diff --git a/maps/starter/map.json b/maps/starter/map.json index fd0b984e..8d93c66e 100644 --- a/maps/starter/map.json +++ b/maps/starter/map.json @@ -1,385 +1,341 @@ -{ "compressionlevel":-1, - "height":17, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":6, - "name":"start", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":7, - "name":"collisions", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":29, - "name":"jitsiMeetingRoom", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"MeetingRoom" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":38, - "name":"jitsiChillzone", - "opacity":1, - "properties":[ - { - "name":"jitsiRoom", - "type":"string", - "value":"ChillZone" - }, - { - "name":"jitsiTrigger", - "type":"string", - "value":"onaction" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":23, - "name":"clockZone", - "opacity":1, - "properties":[ - { - "name":"zone", - "type":"string", - "value":"clock" - }], - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], - "height":17, - "id":4, - "name":"floor", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], - "height":17, - "id":9, - "name":"walls", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":1, - "name":"furniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":33, - "name":"aboveFurniture", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "draworder":"topdown", - "id":2, - "name":"floorLayer", - "objects":[ - { - "height":64, - "id":4, - "name":"clockPopup", - "rotation":0, - "type":"", - "visible":true, - "width":128, - "x":512, - "y":0 - }, - { - "height":128, - "id":9, - "name":"chillZone", - "properties":[ - { - "name":"display_name", - "type":"string", - "value":"Chilling Room" - }, - { - "name":"focusable", - "type":"bool", - "value":true - }], - "rotation":0, - "type":"zone", - "visible":true, - "width":192, - "x":32, - "y":96 - }, - { - "height":416, - "id":11, - "name":"meetingZone", - "properties":[ - { - "name":"display_name", - "type":"string", - "value":"Brainstorm Zone!" - }, - { - "name":"focusable", - "type":"bool", - "value":true - }], - "rotation":0, - "type":"zone", - "visible":true, - "width":224, - "x":736, - "y":32 - }], - "opacity":1, - "type":"objectgroup", - "visible":true, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":3, - "name":"abovePlayer1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":27, - "name":"abovePlayer2", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":17, - "id":28, - "name":"abovePlayer3", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":31, - "x":0, - "y":0 - }], - "nextlayerid":39, - "nextobjectid":12, - "orientation":"orthogonal", - "properties":[ - { - "name":"mapCopyright", - "type":"string", - "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" - }, - { - "name":"mapDescription", - "type":"string", - "value":"A perfect virtual office to get started with WorkAdventure!" - }, - { - "name":"mapImage", - "type":"string", - "value":"map.png" - }, - { - "name":"mapLink", - "type":"string", - "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" - }, - { - "name":"mapName", - "type":"string", - "value":"Starter kit" - }, - { - "name":"script", - "type":"string", - "value":"..\/dist\/script.js" - }], - "renderorder":"right-down", - "tiledversion":"1.7.2", - "tileheight":32, - "tilesets":[ - { - "columns":10, - "firstgid":1, - "image":"..\/assets\/tileset5_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset5_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":10, - "firstgid":101, - "image":"..\/assets\/tileset6_export.png", - "imageheight":320, - "imagewidth":320, - "margin":0, - "name":"tileset6_export", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":100, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":201, - "image":"..\/assets\/tileset1.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":11, - "firstgid":322, - "image":"..\/assets\/tileset1-repositioning.png", - "imageheight":352, - "imagewidth":352, - "margin":0, - "name":"tileset1-repositioning", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":121, - "tileheight":32, - "tilewidth":32 - }, - { - "columns":6, - "firstgid":443, - "image":"..\/assets\/Special_Zones.png", - "imageheight":64, - "imagewidth":192, - "margin":0, - "name":"Special_Zones", - "properties":[ - { - "name":"tilesetCopyright", - "type":"string", - "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" - }], - "spacing":0, - "tilecount":12, - "tileheight":32, - "tiles":[ - { - "id":0, - "properties":[ - { - "name":"collides", - "type":"bool", - "value":true - }] - }], - "tilewidth":32 - }], - "tilewidth":32, - "type":"map", - "version":"1.6", - "width":31 +{ "compressionlevel":-1, + "height":17, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":6, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":7, + "name":"collisions", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":29, + "name":"jitsiMeetingRoom", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"MeetingRoom" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454, 454, 454, 454, 454, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":38, + "name":"jitsiChillzone", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"ChillZone" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":23, + "name":"clockZone", + "opacity":1, + "properties":[ + { + "name":"zone", + "type":"string", + "value":"clock" + }], + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 223, 223, 223, 223, 223, 223, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201], + "height":17, + "id":4, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[49, 58, 58, 58, 58, 58, 58, 42, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 42, 57, 57, 57, 57, 57, 57, 57, 50, 45, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 45, 63, 63, 63, 63, 63, 63, 63, 45, 45, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 45, 73, 73, 73, 73, 73, 73, 73, 45, 45, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 45, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 32, 58, 58, 58, 58, 58, 58, 58, 60, 83, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 84, 93, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 94], + "height":17, + "id":9, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 293, 0, 107, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 107, 0, 0, 128, 1, 2, 3, 0, 0, 0, 0, 304, 296, 297, 296, 297, 304, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 315, 307, 308, 307, 308, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 243, 0, 0, 0, 0, 2147483943, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 283, 283, 0, 2147483954, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 340, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 0, 0, 0, 0, 0, 325, 340, 340, 326, 0, 0, 325, 340, 340, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 351, 351, 0, 0, 0, 0, 0, 0, 325, 273, 275, 326, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 333, 334, 333, 334, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 345, 344, 345, 344, 345, 0, 0, 0, 0, 0, 0, 0, 325, 2147483923, 275, 326, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 220, 220, 220, 220, 218, 0, 0, 0, 0, 0, 0, 0, 0, 284, 286, 0, 0, 0, 0, 438, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 336, 335, 336, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 347, 346, 347, 346, 347, 0, 2147483811, 2147483810, 2147483809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":1, + "name":"furniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 2147483909, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 231, 231, 231, 231, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":33, + "name":"aboveFurniture", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":2, + "name":"floorLayer", + "objects":[ + { + "height":64, + "id":4, + "name":"clockPopup", + "rotation":0, + "type":"", + "visible":true, + "width":128, + "x":512, + "y":0 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 209, 209, 209, 209, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483801, 2147483800, 2147483799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":3, + "name":"abovePlayer1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 399, 400, 399, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, 410, 411, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":27, + "name":"abovePlayer2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 401, 402, 401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 413, 412, 413, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":17, + "id":28, + "name":"abovePlayer3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":31, + "x":0, + "y":0 + }], + "nextlayerid":39, + "nextobjectid":9, + "orientation":"orthogonal", + "properties":[ + { + "name":"mapCopyright", + "type":"string", + "value":"Credits: Valdo Romao https:\/\/www.linkedin.com\/in\/valdo-romao\/ \nLicense: CC-BY-SA 3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)" + }, + { + "name":"mapDescription", + "type":"string", + "value":"A perfect virtual office to get started with WorkAdventure!" + }, + { + "name":"mapImage", + "type":"string", + "value":"map.png" + }, + { + "name":"mapLink", + "type":"string", + "value":"https:\/\/thecodingmachine.github.io\/workadventure-map-starter-kit\/map.json" + }, + { + "name":"mapName", + "type":"string", + "value":"Starter kit" + }, + { + "name":"script", + "type":"string", + "value":"..\/dist\/script.js" + }], + "renderorder":"right-down", + "tiledversion":"1.7.0", + "tileheight":32, + "tilesets":[ + { + "columns":10, + "firstgid":1, + "image":"..\/assets\/tileset5_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset5_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":10, + "firstgid":101, + "image":"..\/assets\/tileset6_export.png", + "imageheight":320, + "imagewidth":320, + "margin":0, + "name":"tileset6_export", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":100, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":201, + "image":"..\/assets\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":11, + "firstgid":322, + "image":"..\/assets\/tileset1-repositioning.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1-repositioning", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }, + { + "columns":6, + "firstgid":443, + "image":"..\/assets\/Special_Zones.png", + "imageheight":64, + "imagewidth":192, + "margin":0, + "name":"Special_Zones", + "properties":[ + { + "name":"tilesetCopyright", + "type":"string", + "value":"\u00a9 2021 WorkAdventure \nLicence: WORKADVENTURE SPECIFIC RESOURCES LICENSE (see LICENSE.assets file)" + }], + "spacing":0, + "tilecount":12, + "tileheight":32, + "tiles":[ + { + "id":0, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":31 } \ No newline at end of file From 3d3ca45921ece3d2a32261673620f345c9a3c7b1 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Mon, 6 Dec 2021 11:37:55 +0100 Subject: [PATCH 20/38] ran prettier for back --- back/src/Services/VariablesManager.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/back/src/Services/VariablesManager.ts b/back/src/Services/VariablesManager.ts index d11cb26f..6ec1cc3a 100644 --- a/back/src/Services/VariablesManager.ts +++ b/back/src/Services/VariablesManager.ts @@ -1,11 +1,7 @@ /** * Handles variables shared between the scripting API and the server. */ -import { - ITiledMap, - ITiledMapLayer, - ITiledMapObject, -} from "@workadventure/tiled-map-type-guard/dist"; +import { ITiledMap, ITiledMapLayer, ITiledMapObject } from "@workadventure/tiled-map-type-guard/dist"; import { User } from "_Model/User"; import { variablesRepository } from "./Repository/VariablesRepository"; import { redisClient } from "./RedisClient"; From b00d24dbf7d2ba62cdc3c6e518bd881c3a6abe0a Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 7 Dec 2021 12:48:08 +0100 Subject: [PATCH 21/38] refocusing on target (if any) in case of an external resize --- front/src/Phaser/Game/CameraManager.ts | 10 +++++++ front/src/Phaser/Services/HdpiManager.ts | 2 +- front/src/Phaser/Services/WaScaleManager.ts | 30 +++++++++++++++++---- front/src/WebRtc/CoWebsiteManager.ts | 1 + front/src/index.ts | 2 ++ 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 00006a7d..15fa76c2 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -31,6 +31,14 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.waScaleManager = waScaleManager; this.initCamera(); + + this.scene.game.events.on("wa-scale-manager:refresh-focus-on-target", () => { + const focusOn = this.waScaleManager.getFocusTarget(); + if (!focusOn) { + return; + } + this.camera.centerOn(focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5); + }); } public getCamera(): Phaser.Cameras.Scene2D.Camera { @@ -43,6 +51,7 @@ export class CameraManager extends Phaser.Events.EventEmitter { ): void { this.setCameraMode(CameraMode.Focus); this.waScaleManager.saveZoom(); + this.waScaleManager.setFocusTarget(focusOn); this.restoreZoomTween?.stop(); const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(focusOn.width, focusOn.height); @@ -62,6 +71,7 @@ export class CameraManager extends Phaser.Events.EventEmitter { } public leaveFocusMode(player: Player): void { + this.waScaleManager.setFocusTarget(); // We are forcing camera.pan to kill previous pan animation on EnterFocusMode this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true); this.startFollow(player); diff --git a/front/src/Phaser/Services/HdpiManager.ts b/front/src/Phaser/Services/HdpiManager.ts index 116f6816..9c4e9af4 100644 --- a/front/src/Phaser/Services/HdpiManager.ts +++ b/front/src/Phaser/Services/HdpiManager.ts @@ -94,7 +94,7 @@ export class HdpiManager { /** * We only accept integer but we make an exception for 1.5 */ - private getOptimalZoomLevel(realPixelNumber: number): number { + public getOptimalZoomLevel(realPixelNumber: number): number { const result = Math.sqrt(realPixelNumber / this.minRecommendedGamePixelsNumber); if (1.5 <= result && result < 2) { return 1.5; diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 838f82d2..574f3b99 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -12,6 +12,8 @@ export class WaScaleManager { private actualZoom: number = 1; private _saveZoom: number = 1; + private focusTarget?: { x: number; y: number; width: number; height: number }; + public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); } @@ -23,15 +25,14 @@ export class WaScaleManager { public applyNewSize() { const { width, height } = coWebsiteManager.getGameSize(); - const devicePixelRatio = window.devicePixelRatio ?? 1; - const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({ width: width * devicePixelRatio, height: height * devicePixelRatio, }); this.actualZoom = realSize.width / gameSize.width / devicePixelRatio; + this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio); this.scaleManager.resize(gameSize.width, gameSize.height); @@ -56,6 +57,25 @@ export class WaScaleManager { this.game.markDirty(); } + /** + * Use this in case of resizing while focusing on something + */ + public refreshFocusOnTarget(): void { + if (!this.focusTarget) { + return; + } + this.zoomModifier = this.getTargetZoomModifierFor(this.focusTarget.width, this.focusTarget.height); + this.game.events.emit("wa-scale-manager:refresh-focus-on-target"); + } + + public setFocusTarget(targetDimensions?: { x: number; y: number; width: number; height: number }): void { + this.focusTarget = targetDimensions; + } + + public getFocusTarget(): { x: number; y: number; width: number; height: number } | undefined { + return this.focusTarget; + } + public getTargetZoomModifierFor(viewportWidth: number, viewportHeight: number) { const { width: gameWidth, height: gameHeight } = coWebsiteManager.getGameSize(); const devicePixelRatio = window.devicePixelRatio ?? 1; @@ -64,9 +84,9 @@ export class WaScaleManager { width: gameWidth * devicePixelRatio, height: gameHeight * devicePixelRatio, }); - // P.H. Note: Dunno where this magic 2 comes from - // Always return lowest possible value. Need to add MAX ZOOM MODIFIER value into this. - return Math.min(realSize.width / viewportWidth / 2, realSize.height / viewportHeight / 2); + const desiredZoom = Math.min(realSize.width / viewportWidth, realSize.height / viewportHeight); + const realPixelNumber = gameWidth * devicePixelRatio * gameHeight * devicePixelRatio; + return desiredZoom / (this.hdpiManager.getOptimalZoomLevel(realPixelNumber) || 1); } public get zoomModifier(): number { diff --git a/front/src/WebRtc/CoWebsiteManager.ts b/front/src/WebRtc/CoWebsiteManager.ts index 09de4b41..7a003604 100644 --- a/front/src/WebRtc/CoWebsiteManager.ts +++ b/front/src/WebRtc/CoWebsiteManager.ts @@ -642,6 +642,7 @@ class CoWebsiteManager { private fire(): void { this._onResize.next(); waScaleManager.applyNewSize(); + waScaleManager.refreshFocusOnTarget(); } private fullscreen(): void { diff --git a/front/src/index.ts b/front/src/index.ts index 3cb8d048..a2064cd8 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -144,10 +144,12 @@ window.addEventListener("resize", function (event) { coWebsiteManager.resetStyleMain(); waScaleManager.applyNewSize(); + waScaleManager.refreshFocusOnTarget(); }); coWebsiteManager.onResize.subscribe(() => { waScaleManager.applyNewSize(); + waScaleManager.refreshFocusOnTarget(); }); iframeListener.init(); From 29ccb52c931be933fb0928b4addb72a2d0720977 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 7 Dec 2021 13:18:36 +0100 Subject: [PATCH 22/38] cleanup --- front/src/Phaser/Game/CameraManager.ts | 25 +++++++++++++++------ front/src/Phaser/Game/GameScene.ts | 1 + front/src/Phaser/Services/WaScaleManager.ts | 6 +---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 15fa76c2..c4e4b382 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -32,13 +32,12 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.initCamera(); - this.scene.game.events.on("wa-scale-manager:refresh-focus-on-target", () => { - const focusOn = this.waScaleManager.getFocusTarget(); - if (!focusOn) { - return; - } - this.camera.centerOn(focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5); - }); + this.bindEventHandlers(); + } + + public destroy(): void { + this.scene.game.events.off("wa-scale-manager:refresh-focus-on-target"); + super.destroy(); } public getCamera(): Phaser.Cameras.Scene2D.Camera { @@ -128,4 +127,16 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.camera = this.scene.cameras.main; this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); } + + private bindEventHandlers(): void { + this.scene.game.events.on( + "wa-scale-manager:refresh-focus-on-target", + (focusOn: { x: number; y: number; width: number; height: number }) => { + if (!focusOn) { + return; + } + this.camera.centerOn(focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5); + } + ); + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 78b56327..47967037 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1410,6 +1410,7 @@ ${escapedMessage} this.userInputManager.destroy(); this.pinchManager?.destroy(); this.emoteManager.destroy(); + this.cameraManager.destroy(); this.peerStoreUnsubscribe(); this.emoteUnsubscribe(); this.emoteMenuUnsubscribe(); diff --git a/front/src/Phaser/Services/WaScaleManager.ts b/front/src/Phaser/Services/WaScaleManager.ts index 574f3b99..447b6a1f 100644 --- a/front/src/Phaser/Services/WaScaleManager.ts +++ b/front/src/Phaser/Services/WaScaleManager.ts @@ -65,17 +65,13 @@ export class WaScaleManager { return; } this.zoomModifier = this.getTargetZoomModifierFor(this.focusTarget.width, this.focusTarget.height); - this.game.events.emit("wa-scale-manager:refresh-focus-on-target"); + this.game.events.emit("wa-scale-manager:refresh-focus-on-target", this.focusTarget); } public setFocusTarget(targetDimensions?: { x: number; y: number; width: number; height: number }): void { this.focusTarget = targetDimensions; } - public getFocusTarget(): { x: number; y: number; width: number; height: number } | undefined { - return this.focusTarget; - } - public getTargetZoomModifierFor(viewportWidth: number, viewportHeight: number) { const { width: gameWidth, height: gameHeight } = coWebsiteManager.getGameSize(); const devicePixelRatio = window.devicePixelRatio ?? 1; From 957ba8f8c7c0072bcd8e9353fb32a8e49b1bbe3e Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 7 Dec 2021 17:03:51 +0100 Subject: [PATCH 23/38] more subtle start follow player by camera. wip --- front/src/Phaser/Game/CameraManager.ts | 32 +++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index c4e4b382..20ce05a4 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -73,13 +73,29 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.waScaleManager.setFocusTarget(); // We are forcing camera.pan to kill previous pan animation on EnterFocusMode this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true); - this.startFollow(player); - this.restoreZoom(); + this.startFollow(player, 1000); + this.restoreZoom(1000); } - public startFollow(target: object | Phaser.GameObjects.GameObject): void { + public startFollow(target: object | Phaser.GameObjects.GameObject, duration: number = 0): void { this.setCameraMode(CameraMode.Follow); - this.camera.startFollow(target, true); + if (duration === 0) { + this.camera.startFollow(target, true); + return; + } + // duck typing hack + this.camera.pan( + (target as { x: number; y: number }).x, + (target as { x: number; y: number }).y, + duration, + Easing.Linear, + true, + (camera, progress) => { + if (progress === 1) { + this.camera.startFollow(target, true); + } + } + ); } /** @@ -110,12 +126,16 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.cameraMode = mode; } - private restoreZoom(): void { + private restoreZoom(duration: number = 0): void { + if (duration === 0) { + this.waScaleManager.zoomModifier = this.waScaleManager.getSaveZoom(); + return; + } this.restoreZoomTween?.stop(); this.restoreZoomTween = this.scene.tweens.addCounter({ from: this.waScaleManager.zoomModifier, to: this.waScaleManager.getSaveZoom(), - duration: 1000, + duration, ease: Easing.SineEaseOut, onUpdate: (tween: Phaser.Tweens.Tween) => { this.waScaleManager.zoomModifier = tween.getValue(); From ff77a182629e473724c712c89116e8f949193bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 8 Dec 2021 10:58:53 +0100 Subject: [PATCH 24/38] Don't retry Axios if a token decryption failed If a token decryption failed, it will emit a HTTP 500. We should not retry Axios in this case but rather fail. Note: a token decryption failed should not throw a HTTP 500 but another error code (HTTP 401?) So maybe this fix is plainly wrong. --- front/src/Connexion/AxiosUtils.ts | 6 ++++++ messages/protos/messages.proto | 3 +++ 2 files changed, 9 insertions(+) diff --git a/front/src/Connexion/AxiosUtils.ts b/front/src/Connexion/AxiosUtils.ts index 9d50ce4f..f4cd160f 100644 --- a/front/src/Connexion/AxiosUtils.ts +++ b/front/src/Connexion/AxiosUtils.ts @@ -13,6 +13,12 @@ axiosWithRetry.defaults.raxConfig = { maxRetryAfter: 60_000, + statusCodesToRetry: [ + [100, 199], + [429, 429], + [501, 599], + ], + // You can detect when a retry is happening, and figure out how many // retry attempts have been made onRetryAttempt: (err) => { diff --git a/messages/protos/messages.proto b/messages/protos/messages.proto index 5b319feb..7a4d74d9 100644 --- a/messages/protos/messages.proto +++ b/messages/protos/messages.proto @@ -259,6 +259,9 @@ message BanUserMessage{ string message = 2; } +/** + * Messages going from back and pusher to the front + */ message ServerToClientMessage { oneof message { BatchMessage batchMessage = 1; From 082b33cf0211e946b36603766651d051e89ba0e3 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 8 Dec 2021 11:31:49 +0100 Subject: [PATCH 25/38] more subtle zone leaving camera work --- front/src/Phaser/Game/CameraManager.ts | 39 +++++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 20ce05a4..04ff208c 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -20,6 +20,9 @@ export class CameraManager extends Phaser.Events.EventEmitter { private cameraMode: CameraMode = CameraMode.Free; private restoreZoomTween?: Phaser.Tweens.Tween; + private startFollowTween?: Phaser.Tweens.Tween; + + private cameraFollowTarget?: { x: number; y: number }; constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) { super(); @@ -53,16 +56,18 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.waScaleManager.setFocusTarget(focusOn); this.restoreZoomTween?.stop(); + this.startFollowTween?.stop(); const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(focusOn.width, focusOn.height); const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = targetZoomModifier - currentZoomModifier; this.camera.stopFollow(); + this.cameraFollowTarget = undefined; this.camera.pan( focusOn.x + focusOn.width * 0.5, focusOn.y + focusOn.height * 0.5, duration, Easing.SineEaseOut, - false, + true, (camera, progress, x, y) => { this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange; } @@ -71,31 +76,37 @@ export class CameraManager extends Phaser.Events.EventEmitter { public leaveFocusMode(player: Player): void { this.waScaleManager.setFocusTarget(); - // We are forcing camera.pan to kill previous pan animation on EnterFocusMode - this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true); this.startFollow(player, 1000); this.restoreZoom(1000); } public startFollow(target: object | Phaser.GameObjects.GameObject, duration: number = 0): void { + this.cameraFollowTarget = target as { x: number; y: number }; this.setCameraMode(CameraMode.Follow); if (duration === 0) { this.camera.startFollow(target, true); return; } - // duck typing hack - this.camera.pan( - (target as { x: number; y: number }).x, - (target as { x: number; y: number }).y, + const oldPos = { x: this.camera.scrollX, y: this.camera.scrollY }; + this.startFollowTween = this.scene.tweens.addCounter({ + from: 0, + to: 1, duration, - Easing.Linear, - true, - (camera, progress) => { - if (progress === 1) { - this.camera.startFollow(target, true); + ease: Easing.SineEaseOut, + onUpdate: (tween: Phaser.Tweens.Tween) => { + if (!this.cameraFollowTarget) { + return; } - } - ); + const shiftX = + (this.cameraFollowTarget.x - this.camera.worldView.width * 0.5 - oldPos.x) * tween.getValue(); + const shiftY = + (this.cameraFollowTarget.y - this.camera.worldView.height * 0.5 - oldPos.y) * tween.getValue(); + this.camera.setScroll(oldPos.x + shiftX, oldPos.y + shiftY); + }, + onComplete: () => { + this.camera.startFollow(target, true); + }, + }); } /** From 03cf5c05ff4d1d05ef1864c98fa5afb2291e88ea Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 8 Dec 2021 13:03:25 +0100 Subject: [PATCH 26/38] added zoom_margin optional property for zone definition --- front/src/Phaser/Game/CameraManager.ts | 11 ++++++++--- front/src/Phaser/Game/GameScene.ts | 19 +++++++++---------- maps/tests/focusable_zone_map.json | 10 ++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/front/src/Phaser/Game/CameraManager.ts b/front/src/Phaser/Game/CameraManager.ts index 04ff208c..19c4821a 100644 --- a/front/src/Phaser/Game/CameraManager.ts +++ b/front/src/Phaser/Game/CameraManager.ts @@ -49,6 +49,7 @@ export class CameraManager extends Phaser.Events.EventEmitter { public enterFocusMode( focusOn: { x: number; y: number; width: number; height: number }, + margin: number = 0, duration: number = 1000 ): void { this.setCameraMode(CameraMode.Focus); @@ -57,14 +58,18 @@ export class CameraManager extends Phaser.Events.EventEmitter { this.restoreZoomTween?.stop(); this.startFollowTween?.stop(); - const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(focusOn.width, focusOn.height); + const marginMult = 1 + margin; + const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor( + focusOn.width * marginMult, + focusOn.height * marginMult + ); const currentZoomModifier = this.waScaleManager.zoomModifier; const zoomModifierChange = targetZoomModifier - currentZoomModifier; this.camera.stopFollow(); this.cameraFollowTarget = undefined; this.camera.pan( - focusOn.x + focusOn.width * 0.5, - focusOn.y + focusOn.height * 0.5, + focusOn.x + focusOn.width * 0.5 * marginMult, + focusOn.y + focusOn.height * 0.5 * marginMult, duration, Easing.SineEaseOut, true, diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index aff4acc1..c1e5c1a2 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -791,11 +791,11 @@ export class GameScene extends DirtyScene { // P.H. TODO: Send those events to the iframe? this.gameMap.onEnterZone((zones) => { for (const zone of zones) { - for (const property of zone.properties ?? []) { - if (property.name === "focusable" && property.value === true) { - this.cameraManager.enterFocusMode(zone); - break; - } + const focusable = zone.properties?.find((property) => property.name === "focusable"); + if (focusable && focusable.value === true) { + const zoomMargin = zone.properties?.find((property) => property.name === "zoom_margin"); + this.cameraManager.enterFocusMode(zone, Number(zoomMargin?.value)); + break; } } // zones.forEach((zone) => { @@ -805,11 +805,10 @@ export class GameScene extends DirtyScene { this.gameMap.onLeaveZone((zones) => { for (const zone of zones) { - for (const property of zone.properties ?? []) { - if (property.name === "focusable" && property.value === true) { - this.cameraManager.leaveFocusMode(this.CurrentPlayer); - break; - } + const focusable = zone.properties?.find((property) => property.name === "focusable"); + if (focusable && focusable.value === true) { + this.cameraManager.leaveFocusMode(this.CurrentPlayer); + break; } } // zones.forEach((zone) => { diff --git a/maps/tests/focusable_zone_map.json b/maps/tests/focusable_zone_map.json index b747d7a0..469b8c6d 100644 --- a/maps/tests/focusable_zone_map.json +++ b/maps/tests/focusable_zone_map.json @@ -163,6 +163,11 @@ "name":"focusable", "type":"bool", "value":true + }, + { + "name":"zoom_margin", + "type":"float", + "value":0.5 }], "rotation":0, "type":"zone", @@ -185,6 +190,11 @@ "name":"focusable", "type":"bool", "value":true + }, + { + "name":"zoom_margin", + "type":"float", + "value":0 }], "rotation":0, "type":"zone", From 4d473480cf0c159e1e5872b498d03a699a585d29 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 8 Dec 2021 13:18:06 +0100 Subject: [PATCH 27/38] enter and leave zone events --- front/src/Api/Events/ChangeZoneEvent.ts | 11 +++++++++++ front/src/Api/Events/IframeEvent.ts | 3 +++ front/src/Api/IframeListener.ts | 19 +++++++++++++++++++ front/src/Phaser/Game/GameMap.ts | 3 --- front/src/Phaser/Game/GameScene.ts | 12 ++++++------ 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 front/src/Api/Events/ChangeZoneEvent.ts diff --git a/front/src/Api/Events/ChangeZoneEvent.ts b/front/src/Api/Events/ChangeZoneEvent.ts new file mode 100644 index 00000000..d88e9a09 --- /dev/null +++ b/front/src/Api/Events/ChangeZoneEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isChangeZoneEvent = new tg.IsInterface() + .withProperties({ + name: tg.isString, + }) + .get(); +/** + * A message sent from the game to the iFrame when a user enters or leaves a layer. + */ +export type ChangeZoneEvent = tg.GuardedType; diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index 081008c4..c338ddbe 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -28,6 +28,7 @@ import type { MessageReferenceEvent } from "./ui/TriggerActionMessageEvent"; import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent"; import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent"; import type { ChangeLayerEvent } from "./ChangeLayerEvent"; +import type { ChangeZoneEvent } from "./ChangeZoneEvent"; export interface TypedMessageEvent extends MessageEvent { data: T; @@ -76,6 +77,8 @@ export interface IframeResponseEventMap { leaveEvent: EnterLeaveEvent; enterLayerEvent: ChangeLayerEvent; leaveLayerEvent: ChangeLayerEvent; + enterZoneEvent: ChangeZoneEvent; + leaveZoneEvent: ChangeZoneEvent; buttonClickedEvent: ButtonClickedEvent; hasPlayerMoved: HasPlayerMovedEvent; menuItemClicked: MenuItemClickedEvent; diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 3db35984..67b49344 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -31,6 +31,7 @@ import type { SetVariableEvent } from "./Events/SetVariableEvent"; import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent"; import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore"; import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent"; +import type { ChangeZoneEvent } from "./Events/ChangeZoneEvent"; type AnswererCallback = ( query: IframeQueryMap[T]["query"], @@ -414,6 +415,24 @@ class IframeListener { }); } + sendEnterZoneEvent(zoneName: string) { + this.postMessage({ + type: "enterZoneEvent", + data: { + name: zoneName, + } as ChangeZoneEvent, + }); + } + + sendLeaveZoneEvent(zoneName: string) { + this.postMessage({ + type: "leaveZoneEvent", + data: { + name: zoneName, + } as ChangeZoneEvent, + }); + } + hasPlayerMoved(event: HasPlayerMovedEvent) { if (this.sendPlayerMove) { this.postMessage({ diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 40588923..557083a9 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -196,9 +196,6 @@ export class GameMap { */ private triggerZonesChange(): void { const zones = this.tiledObjects.filter((object) => object.type === "zone"); - - // P.H. NOTE: We could also get all of the zones and add properties of occupied tiles to them, so we could later on check collision by using tileKeys - // TODO: Change this to an array with currently occupied sone instead of doing elimination process const zonesByOldPosition = this.oldPosition ? zones.filter((zone) => { if (!this.oldPosition) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index c1e5c1a2..39ed5467 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -798,9 +798,9 @@ export class GameScene extends DirtyScene { break; } } - // zones.forEach((zone) => { - // iframeListener.sendEnterLayerEvent(zone.name); - // }); + zones.forEach((zone) => { + iframeListener.sendEnterZoneEvent(zone.name); + }); }); this.gameMap.onLeaveZone((zones) => { @@ -811,9 +811,9 @@ export class GameScene extends DirtyScene { break; } } - // zones.forEach((zone) => { - // iframeListener.sendEnterLayerEvent(zone.name); - // }); + zones.forEach((zone) => { + iframeListener.sendLeaveZoneEvent(zone.name); + }); }); // this.gameMap.onLeaveLayer((layers) => { From b12fb228afc8a978f60f1289b5243a22b5989762 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 8 Dec 2021 13:25:54 +0100 Subject: [PATCH 28/38] fixed typos --- front/src/Api/Events/ChangeZoneEvent.ts | 2 +- front/src/Phaser/Game/GameScene.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/front/src/Api/Events/ChangeZoneEvent.ts b/front/src/Api/Events/ChangeZoneEvent.ts index d88e9a09..e7ca3668 100644 --- a/front/src/Api/Events/ChangeZoneEvent.ts +++ b/front/src/Api/Events/ChangeZoneEvent.ts @@ -6,6 +6,6 @@ export const isChangeZoneEvent = new tg.IsInterface() }) .get(); /** - * A message sent from the game to the iFrame when a user enters or leaves a layer. + * A message sent from the game to the iFrame when a user enters or leaves a zone. */ export type ChangeZoneEvent = tg.GuardedType; diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 39ed5467..8635b25b 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -788,7 +788,6 @@ export class GameScene extends DirtyScene { }); }); - // P.H. TODO: Send those events to the iframe? this.gameMap.onEnterZone((zones) => { for (const zone of zones) { const focusable = zone.properties?.find((property) => property.name === "focusable"); From 598c7412a250de5e74ac81ae38c83e81ad5ff57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 8 Dec 2021 14:46:23 +0100 Subject: [PATCH 29/38] When sending an invalid token, the HTTP API from the Pusher now returns a 401 instead of an HTTP 500. --- front/src/Connexion/Room.ts | 7 ++++--- pusher/src/Controller/MapController.ts | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index 4b6d82a4..044d8d67 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -116,11 +116,12 @@ export class Room { this._contactPage = data.contactPage || CONTACT_URL; return new MapDetail(data.mapUrl, data.textures); } catch (e) { - console.error("Error => getMapDetail", e, e.response); - //TODO fix me and manage Error class - if (e.response?.data === "Token decrypted error") { + if (axios.isAxiosError(e) && e.response?.status == 401 && e.response?.data === "Token decrypted error") { + console.warn("JWT token sent could not be decrypted. Maybe it expired?"); localUserStore.setAuthToken(null); window.location.assign("/login"); + } else { + console.error("Error => getMapDetail", e, e.response); } throw e; } diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index 7f76ff9e..23eef566 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -8,6 +8,7 @@ import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetail import { socketManager } from "../Services/SocketManager"; import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager"; import { v4 } from "uuid"; +import { InvalidTokenError } from "./InvalidTokenError"; export class MapController extends BaseController { constructor(private App: TemplatedApp) { @@ -85,11 +86,15 @@ export class MapController extends BaseController { userId = authTokenData.identifier; console.info("JWT expire, but decoded", userId); } catch (e) { - // The token was not good, redirect user on login page - res.writeStatus("500"); - res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); - res.end("Token decrypted error"); - return; + if (e instanceof InvalidTokenError) { + // The token was not good, redirect user on login page + res.writeStatus("401 Unauthorized"); + res.writeHeader("Access-Control-Allow-Origin", FRONT_URL); + res.end("Token decrypted error"); + return; + } else { + return this.errorToResponse(e, res); + } } } } From 0cb17c7fd1a9f815cd8d564d14047d2c2ada771a Mon Sep 17 00:00:00 2001 From: TabascoEye Date: Wed, 8 Dec 2021 16:41:22 +0100 Subject: [PATCH 30/38] adding map properties to documentation * screenshot of the result of the map properties * first try at documenting map properties --- docs/maps/images/mapProperties.png | Bin 0 -> 133628 bytes docs/maps/wa-maps.md | 16 ++++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 docs/maps/images/mapProperties.png diff --git a/docs/maps/images/mapProperties.png b/docs/maps/images/mapProperties.png new file mode 100644 index 0000000000000000000000000000000000000000..d4001da46d3f91869fcd65b3ae51f62fc08e2227 GIT binary patch literal 133628 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%0AJi!hm;fT1sVu>Hko%!18S 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 Date: Thu, 9 Dec 2021 10:57:27 +0100 Subject: [PATCH 31/38] Developer documentation regarding scripting API This PR adds a first developer documentation regarding how to extend the scripting API. --- CONTRIBUTING.md | 4 + docs/dev/README.md | 16 ++ docs/dev/contributing-to-scripting-api.md | 276 ++++++++++++++++++++++ docs/dev/images/scripting_1.svg | 1 + docs/dev/images/scripting_2.svg | 1 + 5 files changed, 298 insertions(+) create mode 100644 docs/dev/README.md create mode 100644 docs/dev/contributing-to-scripting-api.md create mode 100644 docs/dev/images/scripting_1.svg create mode 100644 docs/dev/images/scripting_2.svg diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5d406cf..b504d46a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,6 +10,10 @@ We love to receive contributions from our community — you! There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into WorkAdventure itself. +## Developer documentation + +Documentation targeted at developers can be found in the [`/docs/dev`](docs/dev/) + ## Using the issue tracker First things first: **Do NOT report security vulnerabilities in public issues!**. diff --git a/docs/dev/README.md b/docs/dev/README.md new file mode 100644 index 00000000..d05c4884 --- /dev/null +++ b/docs/dev/README.md @@ -0,0 +1,16 @@ +# Developer documentation + +This (work in progress) documentation provides a number of "how-to" guides explaining how to work on the WorkAdventure +code. + +This documentation is targeted at developers looking to open Pull Requests on WorkAdventure. + +If you "only" want to design dynamic maps, please refer instead to the [scripting API documentation](https://workadventu.re/map-building/scripting.md). + +## Contributing + +Check out the [contributing guide](../../CONTRIBUTING.md) + +## Front documentation + +- [How to add new functions in the scripting API](contributing-to-scripting-api.md) diff --git a/docs/dev/contributing-to-scripting-api.md b/docs/dev/contributing-to-scripting-api.md new file mode 100644 index 00000000..8d716010 --- /dev/null +++ b/docs/dev/contributing-to-scripting-api.md @@ -0,0 +1,276 @@ +# How to add new functions in the scripting API + +This documentation is intended at contributors who want to participate in the development of WorkAdventure itself. +Before reading this, please be sure you are familiar with the [scripting API](https://workadventu.re/map-building/scripting.md). + +The [scripting API](https://workadventu.re/map-building/scripting.md) allows map developers to add dynamic features in their maps. + +## Why extend the scripting API? + +The philosophy behind WorkAdventure is to build a platform that is as open as possible. Part of this strategy is to +offer map developers the ability to turn a WorkAdventures map into something unexpected, using the API. For instance, +you could use it to develop games (we have seen a PacMan and a mine-sweeper on WorkAdventure!) + +We started working on the WorkAdventure scripting API with this in mind, but at some point, maybe you will find that +a feature is missing in the API. This article is here to explain to you how to add this feature. + +## How to extend the scripting API? + +Extending the scripting API means modifying the core of WorkAdventure. You can of course run these +modifications on your self-hosted instance. +But if you want to share it with the wider community, I strongly encourage you to start by [opening an issue](https://github.com/thecodingmachine/workadventure/issues) +on GitHub before starting the development. Check with the core maintainers that they are willing to merge your idea +before starting developing it. Once a new function makes it into the scripting API, it is very difficult to make it +evolve (or to deprecate), so the design of the function you add needs to be carefully considered. + +## How does it work? + +Scripts are executed in the browser, inside an iframe. + +![](images/scripting_1.svg) + +The iframe allows WorkAdventure to isolate the script in a sandbox. Because the iframe is sandbox (or on a different +domain than the WorkAdventure server), scripts cannot directly manipulate the DOM of WorkAdventure. They also cannot +directly access Phaser objects (Phaser is the game engine used in WorkAdventure). This is by-design. Since anyone +can contribute a map, we cannot allow anyone to run any code in the scope of the WorkAdventure server (that would be +a huge XSS security flaw). + +Instead, the only way the script can interact with WorkAdventure is by sending messages using the +[postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). + +![](images/scripting_2.svg) + +We want to make life easy for map developers. So instead of asking them to directly send messages using the postMessage +API, we provide a nice library that does this work for them. This library is what we call the "Scripting API" (we sometimes +refer to it as the "Client API"). + +The scripting API provides the global `WA` object. + +## A simple example + +So let's take an example with a sample script: + +```typescript +WA.chat.sendChatMessage('Hello world!', 'John Doe'); +``` + +When this script is called, the scripting API is dispatching a JSON message to WorkAdventure. + +In our case, the `sendChatMessage` function looks like this: + +**src/Api/iframe/chat.ts** +```typescript + sendChatMessage(message: string, author: string) { + sendToWorkadventure({ + type: "chat", + data: { + message: message, + author: author, + }, + }); + } +``` + +The `sendToWorkadventure` function is a utility function that dispatches the message to the main frame. + +In WorkAdventure, the message is received in the [`IframeListener` listener class](http://github.com/thecodingmachine/workadventure/blob/1e6ce4dec8697340e2c91798864b94da9528b482/front/src/Api/IframeListener.ts#L200-L203). +This class is in charge of analyzing the JSON messages received and dispatching them to the right place in the WorkAdventure application. + +The message callback implemented in `IframeListener` is a giant (and disgusting) `if` statement branching to the correct +part of the code depending on the `type` property. + +**src/Api/IframeListener.ts** +```typescript +// ... + } else if (payload.type === "setProperty" && isSetPropertyEvent(payload.data)) { + this._setPropertyStream.next(payload.data); + } else if (payload.type === "chat" && isChatEvent(payload.data)) { + scriptUtils.sendAnonymousChat(payload.data); + } else if (payload.type === "openPopup" && isOpenPopupEvent(payload.data)) { + this._openPopupStream.next(payload.data); + } else if (payload.type === "closePopup" && isClosePopupEvent(payload.data)) { +// ... +``` + +In this particular case, we call `scriptUtils.sendAnonymousChat` that is doing the work of displaying the chat message. + +## Scripting API entry point + +The `WA` object originates from the scripting API. This script is hosted on the front server, at `https://[front_WA_server]/iframe_api.js.`. + +The entry point for this script is the file `front/src/iframe_api.ts`. +All the other files dedicated to the iframe API are located in the `src/Api/iframe` directory. + +## Utility functions to exchange messages + +In the example above, we already saw you can easily send a message from the iframe to WorkAdventure using the +[`sendToWorkadventure`](http://github.com/thecodingmachine/workadventure/blob/ab075ef6f4974766a3e2de12a230ac4df0954b58/front/src/Api/iframe/IframeApiContribution.ts#L11-L13) utility function. + +Of course, messaging can go the other way around and WorkAdventure can also send messages to the iframes. +We use the [`IFrameListener.postMessage`](http://github.com/thecodingmachine/workadventure/blob/ab075ef6f4974766a3e2de12a230ac4df0954b58/front/src/Api/IframeListener.ts#L455-L459) function for this. + +Finally, there is a last type of utility function (a quite powerful one). It is quite common to need to call a function +from the iframe in WorkAdventure, and to expect a response. For those use cases, the iframe API comes with a +[`queryWorkadventure`](http://github.com/thecodingmachine/workadventure/blob/ab075ef6f4974766a3e2de12a230ac4df0954b58/front/src/Api/iframe/IframeApiContribution.ts#L30-L49) utility function. + +## Types + +The JSON messages sent over the postMessage API are strictly defined using Typescript types. +Those types are not defined using classical Typescript interfaces. + +Indeed, Typescript interfaces only exist at compilation time but cannot be enforced on runtime. The postMessage API +is an entry point to WorkAdventure, and as with any entry point, data must be checked (otherwise, a hacker could +send specially crafted JSON packages to try to hack WA). + +In WorkAdventure, we use the [generic-type-guard](https://github.com/mscharley/generic-type-guard) package. This package +allows us to create interfaces AND custom type guards in one go. + +Let's go back at our example. Let's have a look at the JSON message sent when we want to send a chat message from the API: + +```typescript +sendToWorkadventure({ + type: "chat", + data: { + message: message, + author: author, + }, +}); +``` + +The "data" part of the message is defined in `front/src/Api/Events/ChatEvent.ts`: + +```typescript +import * as tg from "generic-type-guard"; + +export const isChatEvent = new tg.IsInterface() + .withProperties({ + message: tg.isString, + author: tg.isString, + }) + .get(); +/** + * A message sent from the iFrame to the game to add a message in the chat. + */ +export type ChatEvent = tg.GuardedType; +``` + +Using the generic-type-guard library, we start by writing a type guard function (`isChatEvent`). +From this type guard, the library can automatically generate the `ChatEvent` type that we can refer in our code. + +The advantage of this technique is that, **at runtime**, WorkAdventure can verify that the JSON message received +over the postMessage API is indeed correctly formatted. + +If you are not familiar with Typescript type guards, you can read [an introduction to type guards in the Typescript documentation](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards). + +### Typing one way messages + +For "one-way" messages (from the iframe to WorkAdventure), the `sendToWorkadventure` method expects the passed +object to be of type `IframeEvent`. + +Note: I'd like here to thank @jonnytest1 for helping set up this type system. It rocks ;) + +The `IFrameEvent` type is defined in `front/src/Api/Events/IframeEvent.ts`: + +```typescript +export type IframeEventMap = { + loadPage: LoadPageEvent; + chat: ChatEvent; + openPopup: OpenPopupEvent; + closePopup: ClosePopupEvent; + openTab: OpenTabEvent; + // ... + // All the possible messages go here + // The key goes into the "type" JSON property + // ... +}; +export interface IframeEvent { + type: T; + data: IframeEventMap[T]; +} +``` + +Similarly, if you want to type messages from WorkAdventure to the iframe, there is a very similar `IframeResponseEvent`. + +```typescript +export interface IframeResponseEventMap { + userInputChat: UserInputChatEvent; + enterEvent: EnterLeaveEvent; + leaveEvent: EnterLeaveEvent; + // ... + // All the possible messages go here + // The key goes into the "type" JSON property + // ... +} +export interface IframeResponseEvent { + type: T; + data: IframeResponseEventMap[T]; +} +``` + +### Typing queries (messages with answers) + +If you want to add a new "query" (if you are using the `queryWorkadventure` utility function), you will need to +define the type of the query and the type of the response. + +The signature of `queryWorkadventure` is: + +```typescript +function queryWorkadventure( + content: IframeQuery +): Promise +``` + +Yes, that's a bit cryptic. Hopefully, all you need to know is that to add a new query, you need to edit the `iframeQueryMapTypeGuards` +array in `front/src/Api/Events/IframeEvent.ts`: + +```typescript +export const iframeQueryMapTypeGuards = { + openCoWebsite: { + query: isOpenCoWebsiteEvent, + answer: isCoWebsite, + }, + getCoWebsites: { + query: tg.isUndefined, + answer: tg.isArray(isCoWebsite), + }, + // ... + // the `query` key points to the type guard of the query + // the `answer` key points to the type guard of the response +}; +``` + +### Responding to a query on the WorkAdventure side + +In the WorkAdventure code, each possible query should be handled by what we call an "answerer". + +Registering an answerer happens using the `iframeListener.registerAnswerer()` method. + +Here is a sample: + +```typescript +iframeListener.registerAnswerer("openCoWebsite", (openCoWebsiteEvent, source) => { + // ... + + return /*...*/; +}); +``` + +The `registerAnswerer` callback is passed the event, and should return a response (or a promise to the response) in the expected format +(the one you defined in the `answer` key of `iframeQueryMapTypeGuards`). + +Important: + +- there can be only one answerer registered for a given query type. +- if the answerer is not valid any more, you need to unregister the answerer using `iframeListener.unregisterAnswerer`. + + +## sendToWorkadventure VS queryWorkadventure + +- `sendToWorkadventure` is used to send messages one way from the iframe to WorkAdventure. No response is expected. In particular + if an error happens in WorkAdventure, the iframe will not be notified. +- `queryWorkadventure` is used to send queries that expect an answer. If an error happens in WorkAdventure (i.e. if an + exception is raised), the exception will be propagated to the iframe. + +Because `queryWorkadventure` handles exceptions properly, it can be interesting to use `queryWorkadventure` instead +of `sendToWorkadventure`, even for "one-way" messages. The return message type is simply `undefined` in this case. + diff --git a/docs/dev/images/scripting_1.svg b/docs/dev/images/scripting_1.svg new file mode 100644 index 00000000..cae529f3 --- /dev/null +++ b/docs/dev/images/scripting_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/dev/images/scripting_2.svg b/docs/dev/images/scripting_2.svg new file mode 100644 index 00000000..a07294f4 --- /dev/null +++ b/docs/dev/images/scripting_2.svg @@ -0,0 +1 @@ + \ No newline at end of file From 525ca16968b3a7f84e16d701443fefe37e2648f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 9 Dec 2021 18:08:04 +0100 Subject: [PATCH 32/38] Adding a reference to awesome-workadventure in CONTRIBUTING --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b504d46a..b3361333 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,6 +10,10 @@ We love to receive contributions from our community — you! There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into WorkAdventure itself. +## Contributing external resources + +You can share your work on maps / articles / videos related to WorkAdventure on our [awesome-workadventure](https://github.com/workadventure/awesome-workadventure) list. + ## Developer documentation Documentation targeted at developers can be found in the [`/docs/dev`](docs/dev/) From ac2a7e367293aff2eb6e65383fc96b0574aa985e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 9 Dec 2021 18:10:30 +0100 Subject: [PATCH 33/38] Adding a reference to awesome-workadventure in README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 427c514c..21871991 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ In WorkAdventure you can move around your office and talk to your colleagues (us See more features for your virtual office: https://workadventu.re/virtual-office +## Community resources + +Check out resources developed by the WorkAdventure community at [awesome-workadventure](https://github.com/workadventure/awesome-workadventure) + ## Setting up a development environment Install Docker. From dbbfdfb66bc21b762d68b0a178197a2fe886d9b4 Mon Sep 17 00:00:00 2001 From: Valdo Romao Date: Mon, 13 Dec 2021 16:08:44 +0000 Subject: [PATCH 34/38] Updated API doc --- docs/maps/api-player.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/maps/api-player.md b/docs/maps/api-player.md index cb2910c7..9af0b1c2 100644 --- a/docs/maps/api-player.md +++ b/docs/maps/api-player.md @@ -65,12 +65,17 @@ WA.player.userRoomToken: string; ``` The user-room token is available from the `WA.player.userRoomToken` property. -This token is generated in WorkAdventure and contains information such as the player's room ID and its associated membership ID. -{.alert.alert-warn} -This token is used when you change your logo using a configured variable. -Indeed, to change your logo you need to perform an upload in order to get a file URL. This type of actions must be validated on our side. -If you are using a self-hosted version of WorkAdventure you will not have the possibility to perform actions that depends on the user-room token, unless you create an API that support it. +This token can be used by third party services to authenticate a player and prove that the player is in a given room. +The token is generated by the administration panel linked to WorkAdventure. The token is a string and is depending on your implementation of the administration panel. +In WorkAdventure SAAS version, the token is a JWT token that contains information such as the player's room ID and its associated membership ID. + +If you are using the self-hosted version of WorkAdventure and you developed your own administration panel, the token can be anything. +By default, self-hosted versions of WorkAdventure don't come with an administration panel, so the token string will be empty. + +{.alert.alert-info} +A typical use-case for the user-room token is providing logo upload capabilities in a map. +The token can be used as a way to authenticate a WorkAdventure player and ensure he is indeed in the map and authorized to upload a logo. {.alert.alert-info} You need to wait for the end of the initialization before accessing `WA.player.userRoomToken` From 592e07bc4fe97198085ba322980171c0954a1cc5 Mon Sep 17 00:00:00 2001 From: Valdo Romao Date: Mon, 13 Dec 2021 16:19:47 +0000 Subject: [PATCH 35/38] Fixed linter errors --- front/src/Api/iframe/player.ts | 4 +++- front/src/Phaser/Game/GameScene.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/front/src/Api/iframe/player.ts b/front/src/Api/iframe/player.ts index ed1b59d8..c46f3fbc 100644 --- a/front/src/Api/iframe/player.ts +++ b/front/src/Api/iframe/player.ts @@ -76,7 +76,9 @@ export class WorkadventurePlayerCommands extends IframeApiContribution Date: Mon, 13 Dec 2021 16:22:59 +0000 Subject: [PATCH 36/38] Fixed pusher lint error --- pusher/src/Controller/AuthenticateController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 1079c093..8f09cc1a 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -287,7 +287,7 @@ export class AuthenticateController extends BaseController { messages: [], visitCardUrl: null, textures: [], - userRoomToken: undefined + userRoomToken: undefined, }; try { data = await adminApi.fetchMemberDataByUuid(email, playUri, IPAddress); From 0f1378c069c981521f063b6f77dad413fc45f907 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 14 Dec 2021 10:28:41 +0100 Subject: [PATCH 37/38] PR fixes --- front/src/Phaser/Game/GameMap.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 557083a9..6688acb8 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -63,6 +63,7 @@ export class GameMap { public readonly flatLayers: ITiledMapLayer[]; public readonly tiledObjects: ITiledMapObject[]; public readonly phaserLayers: TilemapLayer[] = []; + public readonly zones: ITiledMapObject[] = []; public exitUrls: Array = []; @@ -75,6 +76,7 @@ export class GameMap { ) { this.flatLayers = flattenGroupLayersMap(map); this.tiledObjects = this.getObjectsFromLayers(this.flatLayers); + this.zones = this.tiledObjects.filter((object) => object.type === "zone"); let depth = -2; for (const layer of this.flatLayers) { @@ -192,12 +194,11 @@ export class GameMap { } /** - * We user Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. + * We use Tiled Objects with type "zone" as zones with defined x, y, width and height for easier event triggering. */ private triggerZonesChange(): void { - const zones = this.tiledObjects.filter((object) => object.type === "zone"); const zonesByOldPosition = this.oldPosition - ? zones.filter((zone) => { + ? this.zones.filter((zone) => { if (!this.oldPosition) { return false; } @@ -206,7 +207,7 @@ export class GameMap { : []; const zonesByNewPosition = this.position - ? zones.filter((zone) => { + ? this.zones.filter((zone) => { if (!this.position) { return false; } @@ -466,16 +467,11 @@ export class GameMap { const objectLayers = layers.filter((layer) => layer.type === "objectgroup"); for (const objectLayer of objectLayers) { - if (this.isOfTypeITiledMapObjectLayer(objectLayer)) { + if (objectLayer.type === "objectgroup") { objects.push(...objectLayer.objects); } } return objects; } - - // NOTE: Simple typeguard for Objects Layer. - private isOfTypeITiledMapObjectLayer(obj: ITiledMapLayer): obj is ITiledMapObjectLayer { - return (obj as ITiledMapObjectLayer).objects !== undefined; - } } From 960c247b20d2a9b84e4cf1cb4ea14fd9b8ec4c33 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 14 Dec 2021 12:03:05 +0100 Subject: [PATCH 38/38] added documentation for Focusable Zones --- docs/maps/camera.md | 86 ++++++++++++++++++ docs/maps/images/camera/0_focusable_zone.png | Bin 0 -> 153785 bytes docs/maps/images/camera/1_object_layer.png | Bin 0 -> 8466 bytes docs/maps/images/camera/2_rectangle_zone.png | Bin 0 -> 5143 bytes docs/maps/images/camera/3_define_new_zone.png | Bin 0 -> 31918 bytes .../images/camera/4_click_add_property.png | Bin 0 -> 41213 bytes .../images/camera/5_add_focusable_prop.png | Bin 0 -> 16482 bytes .../images/camera/6_make_sure_checked.png | Bin 0 -> 9358 bytes docs/maps/images/camera/7_add_zoom_margin.png | Bin 0 -> 11558 bytes .../camera/8_optional_zoom_margin_defined.png | Bin 0 -> 2479 bytes docs/maps/images/camera/no_margin.png | Bin 0 -> 156881 bytes docs/maps/images/camera/with_margin.png | Bin 0 -> 52330 bytes docs/maps/menu.php | 6 ++ front/src/Phaser/Game/GameScene.ts | 5 +- maps/tests/focusable_zone_map.json | 35 +------ 15 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 docs/maps/camera.md create mode 100644 docs/maps/images/camera/0_focusable_zone.png create mode 100644 docs/maps/images/camera/1_object_layer.png create mode 100644 docs/maps/images/camera/2_rectangle_zone.png create mode 100644 docs/maps/images/camera/3_define_new_zone.png create mode 100644 docs/maps/images/camera/4_click_add_property.png create mode 100644 docs/maps/images/camera/5_add_focusable_prop.png create mode 100644 docs/maps/images/camera/6_make_sure_checked.png create mode 100644 docs/maps/images/camera/7_add_zoom_margin.png create mode 100644 docs/maps/images/camera/8_optional_zoom_margin_defined.png create mode 100644 docs/maps/images/camera/no_margin.png create mode 100644 docs/maps/images/camera/with_margin.png diff --git a/docs/maps/camera.md b/docs/maps/camera.md new file mode 100644 index 00000000..ac25c843 --- /dev/null +++ b/docs/maps/camera.md @@ -0,0 +1,86 @@ +{.section-title.accent.text-primary} +# Working with camera + +## Focusable Zones + +It is possible to define special regions on the map that can make the camera zoom and center on themselves. We call them "Focusable Zones". When player gets inside, his camera view will be altered - focused, zoomed and locked on defined zone, like this: + +
+ +
+ +### Adding new **Focusable Zone**: + +1. Make sure you are editing an **Object Layer** + +
+ +
+ +2. Select **Insert Rectangle** tool + +
+ +
+ +3. Define new object wherever you want. For example, you can make your chilling room event cosier! + +
+ +
+ +4. Edit this new object and click on **Add Property**, like this: + +
+ +
+ +5. Add a **bool** property of name *focusable*: + +
+ +
+ +6. Make sure it's checked! :) + +
+ +
+ +All should be set up now and your new **Focusable Zone** should be working fine! + +### Defining custom zoom margin: + +If you want, you can add an additional property to control how much should the camera zoom onto focusable zone. + +1. Like before, click on **Add Property** + +
+ +
+ +2. Add a **float** property of name *zoom_margin*: + +
+ +
+ +2. Define how much (in percentage value) should the zoom be decreased: + +
+ +
+ + For example, if you define your zone as a 300x200 rectangle, setting this property to 0.5 *(50%)* means the camera will try to fit within the viewport the entire zone + margin of 50% of its dimensions, so 450x300. + + - No margin defined + +
+ +
+ + - Margin set to **0.35** + +
+ +
\ No newline at end of file diff --git a/docs/maps/images/camera/0_focusable_zone.png b/docs/maps/images/camera/0_focusable_zone.png new file mode 100644 index 0000000000000000000000000000000000000000..8b54f11f2fd331320a13ed925c751b526db1e88b GIT binary patch literal 153785 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 literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/1_object_layer.png b/docs/maps/images/camera/1_object_layer.png new file mode 100644 index 0000000000000000000000000000000000000000..6f57d0ae769b31e891e648264122e6149f5f6284 GIT binary patch literal 8466 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 A`~Uy| literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/2_rectangle_zone.png b/docs/maps/images/camera/2_rectangle_zone.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0b9cdaf6635cb5815e0b5ae2410b9aafd90e14 GIT binary patch literal 5143 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 literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/6_make_sure_checked.png b/docs/maps/images/camera/6_make_sure_checked.png new file mode 100644 index 0000000000000000000000000000000000000000..7fbcdb89a68e1cc6d56d187cadbde6c6d8ce5444 GIT binary patch literal 9358 zcmZ{Kbx<2&yKjQKyHlJ}+@ZKrTnfeA-HQcxcc(bC#T^Qv#e%!LQ{1(1(w@2BId|sX zKQ=pWCfRp)9{I_$QL4(a=qMy800018UQS9K0007^2Neu(h)07McE8j8e?Nnb8tawa2@eBx4Ka7or9xJ|7ttIW(Yby;X;MUcrQSKgxPK+`Gt z>&ABUxGW2Hwy_@8$P_b4dXA}ki@2!rdvT@ zpO?Vzuj^K4e-Jgbw6Nhg*n_rSkxVrw5U`3vy0D5cPgmNeS6AOL;{*i-Z4V?6rhN(K z1s#CaUtjJLL>{fh#6T5at?lfF$HoZo@e3D>{BLGa**e+%AKj_n> z`(7K9ySopn8( z7AJ_nkPbp1QStEv>JnmK_#BoR17BY#{~X9}_s8L?BkNp>A7-!`pxknK{MKaM)FP7l zAu!0nQSsuq(Si!u#2j)&`mzVA+l`)NDBC-gffYmO*@2`OeZ|LTMLT%pf+ zfNUso)E15x6X2I?^vCut8}8J-ClQ4;f;&}#a&G}!93f=Z_Rm%fn=vkk9N-xehDvDI z?v5M`H_1Z14A9HZU@Nbx_C8GJS!oT3qZJ;WP4ZEk4@J);?1BgmODt)i!N+vXsMIm@ zwNh}pB)4hTalvgiHa0$Ips2b`ZeTUSK>?w|SeO$r965(~_`eib3H(bLGH`DAozec#{ggj-A8fEHDR`Tz zhHajCzT;)uk{&`OXlC4n6@1TT4I4SxI}Fp;K5nUtghP*!?x5H&+FvCq<+D;AiqO^qaf!sQO?xwq7SB zbG}j;%PHBEJEtMqr$D36Kdds1ZMp4>F|+Qo*cuy|$~{i6qX;egW1?Z6=5Z`~0}FY< zU3xucq5&si>FsVZdM6aV!k4{=S4FP*S)d9k8Ne;j7IlP{sL1d1&xld?>q`w6*SaWT z(^0AFR&D!%>SyJ_z;|qC3My-A6jr~&N7nPG-aQ2(zZ)n_;f^PQXDvI%8XiX8K=k76GqgWkj*HLmP+&;lY-9r@4~HhYM`^?kON1||NjNdRj;{&G!AQm>V1*7f8} ztkg13^QCx%bhmMy1@#G2_~-ZC;ddJSCcF%uxeHb}c4N8arB_x<1f>@}KL&~~#*;Mm zmk!}ZQs_A+A6^Nj6UTH#d@KlD7gu|+4FE<|35X*xyr(9e*aN>qc4T~W7_pOE!xP}H zd35xbiki3TNudp4Isa(e=PAkb4NvgZ&Atk@CokVnKtot<(6tCt&OnqVgQHIM-jU6Nuo6{K=WiMT%0Dbfav7 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 literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/7_add_zoom_margin.png b/docs/maps/images/camera/7_add_zoom_margin.png new file mode 100644 index 0000000000000000000000000000000000000000..8e3f525660bdcb2c40564bd9e1f165a98e90b57e GIT binary patch literal 11558 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 YA3MQfkIfol@c;k-07*qoM6N<$g7$x=5C8xG literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/8_optional_zoom_margin_defined.png b/docs/maps/images/camera/8_optional_zoom_margin_defined.png new file mode 100644 index 0000000000000000000000000000000000000000..8b41d7d01d9f4b61d99447d5265135e7e20d0441 GIT binary patch literal 2479 zcmV;g2~hTlP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2}DUmK~#8N?VV3d zQ`sKJkG#ZKBop+uCMNL8yn$K?$tWwJkD#KNL|+Tz<|#1&bds4J5)(6Sh_Z1)qDbOG zqX=ZoxG*u$J{G=6py44doUyuqS~Rvo;)33%3!(T-%=?``_fP*(#@@n3exJDbo!>p@ z+;ipp&hLBfy=^yLy?XV;i4z3Lg2BPT#>PfbK-MR>Z{Mz{sK^r~1VIR)`JteoK$H+< zqw@a!d&mzo9u^iBgbzVBDqFX1MZJU|abP?khz7<3f@okoAc%(H`)OP4sn%+Vnet>` z@Ay13SCQR~XWb5Auht0YMLR-kakYq1@cnd(cvxCmdh_OuDCpR^bLW;VTSOrxEEZ&6 z*Wk1$)>_BMxt#%+#5J-p^GWL}$FtPHF(YeF+WSj<(!YvF^{2;H>(K=RFu%fJ$QASB z4?~i}X%j^R$w*qgq=o_THG|t}p{udG_gry88Igro#uQRR!M3Sccr2d zVp^8FzXV}WSy{Q#U;re^Dy&RIW!a(4#5inLiG-f>slybH(y2V@WsCOobC`%?np0b{ zCUzrLx1I&)wAXTn(j;U5s*~0fUBMPzsi#F)3X+>FbESy+$Z)^4u&_{A8JQ1;WXG;_ zYjpziWe( zYpD$@q_Vc|-lg0LrNC6_o0Jom_xY$yl(?dbM_J2_B5nW5*4yTENX*Gi}BaF2mgM(NETl&**tC!^=y(uQhqG(`Cg`TRb;%=Z`3fZn7P!Kj?DV{yPzz4yv8(&41c==l4bE+U9f>(}v60oMaE6cSh6n zZ;i!vc|3>cn0&qep*ta3v(oJrmqW)!^!@0@tooChZ2Eirl_Dl(^XAPvcI?3STRHl> zQpiRG-)}{bL@*u@L<8f2Gd|iy{a^`@ATAzebke_iKCs;P-1FNFtaY3_zbB zMn*>7zJ1H>W!ScDTYY`KC?F<)=Ld`j1JK9Ay?gf#9z4kHWq9!5!O^2fMFBAZsF!j= zUS8f;Y0w`6TQoq-grR>Gf5#r6X&@rXIRZ|Te2$b(6EQzOf8fA@%a<>UGGa;$j0b;5 zo7dA52>jM;7am08=FOW63k$Gq5M{)a7@M`rzbO$Gq6d=0-Me?UZ{L3G*fHTkOo>tP z0CJ_xOQyOT6x9+LXrkhY(&1-SD4Lf!^&&^L6Y9_d0$oQWENZ0?Nr@e-4NFT)5ChMi zJp&t(!-o$aPM$nzu~_&~#GDuv4|Sb^9uFyRAL4S!-_g)r3fc)6YJbtDPV|QR-wiQu zptFuQOv2x*v=nuqYetX9dtI6QQ{C6eMeq%^lkRiz5do)GPSQiv2CL8G$B)mSKY!!K z4NMN}2xIkSUjnR*!p=h*!z&yN{57bV}6dqn^VM1p|)qf*{}k#(eY zu0l^u(-dzJe{5B$si`R`DH$6ZyKvzGCWrMxZsH*u?9IOg0vE|Sn9o%1KvHQVEME+@ zmy0So==4v5?&<|;(@@UI%gbwOYWno))9C0ZCWrMxZsNgSQcAodT)amHu6tRou zTvI#@$OXy@?jO-D|1>CI`o9QANciOx-=)*^!Vdyd_s3X2Ea!+s#9^miLz$$fp`n2r zt*xz?9M%On$`5s&blbp03sv)cm4->)Q!1nk-|AAimpJj~_oST!^{B_caVa|Gvfw z-*v@TV$BA=zhoHt$qgImckkYDdl?D~3-|5YCkluOz<4kWT=hgy@bpX)fX)|A9sEbdXsooYIvu#jl3t{YR)DoYy4LRpimr#)-J!HDP3~@Ag!8 zma)2gB&-RUA$4Vo9k4JfV~9MO3s*_61|T!AK2_t8Z)^Fsh5Z=U3VTLY4TGOQ1SbMq2Kb5G!KYwzQJ8Ckfw__+T%D(M0+yC4 z@-sMx<+>x)zmO2EFf7}viqeSe4E23pp-KE@#p)?aWT*xzMH|DAxn!SXBxog zvDniu29_+P5Hnz~UUGXJWSA*qYkmolM|e(%&i2k&zJ@=4N+%`O|F2o<4$6KK8-30e zPHN}>E%l_yRA2099lGhRRD&_dbJy4yf)lf;J{}S4f5=w!A4 zbaaxC&_!zq$RV+#ecG=|mDM6BFWM!c8=X>qM2>MgnXrs{$#fVP57HHwg{oGLE{2Iz z?_{>M_*5B73n`t3W3|}j*bFtK{n{_*D!>?|qMz6poUYWI|IZ?3l#JBfUn?hsh9SsESSw--}7jV3tPPm1oqDgI#z zr^pZTX}0TtG5kV65gAQ%_WNPN{vSX(Cfvh?z~I*o8yKT*?;=LBvEOf{H<~QHSw9NE z_glXJ*30{?%9<+v8TnY(T~j2K6@oA}V1CdZ0)Td+k0ZF51(+Yc05*?o@qhgzmb|T39+Ln7002ovPDHLkV1jT?vXcM+ literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/no_margin.png b/docs/maps/images/camera/no_margin.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c9dd18baa0196414ac09ba2efda62a710c12a9 GIT binary patch literal 156881 zcmeFa2VB$l_BXDEQJGp93K2wGaiFM0h9V${SgoQ~LTNy_twVnI1MIe|_HDhJuUUB@ zPSOUi_uJ}ur?qas#GN~kon!t}@gI|>Mt-wea?1@T4XLSHW>>9QEq5jC`rJeQW}E94 z1XtZQJ~K&Xsf?OsoQCm*u+8=xCxzFQef*`tJ)qC|WfE82>+Zw8fxf&7^lxJN-&mqRFR4 zv2~jLvWk{Wud@UaX>Rl0daI2d^t^Lw2Rul$S9#1sPV1(kKb?Apvy_tN`(I{xm|cov z8I_n?SxxI%)^THQrl-?7c|Aia^H9C_@+CK={+LEwu@?8>*RPh{4ANQjzPoPgDbjaZ z=-bWB6K$$nlArx>+Hwpr0(56 zSK+r|;)?SB$Q_)uL3Z-06jha^`EKT`T8YzoOsH%|^MPOoslb;K1`2Y&2T3v5yX84a zQlU!NCapto<_%X0qE9MH|7Wr<*_GpUOmDR=&h${Qx^(DEvk)(MD=ZO~x?;<1SG~;} zPS3*jWx`w}*=#rs+weC%c@8@=e@mI%o1(g@au81^-?%Z^cLsaQw0DMZI%+X=@8um? zYSXu(J+3j9SNIA}#Ib1=e#+eD08(egvu6?%InM3LNAc6Q;^fOav(#XTu+&d$;z`fU z7JVCx?W;dKLn)5_1AoJnI6r4t_S~0+4u-40TqIoOKX;M)NM#2}6c3P@(6?q*@^CRy zrb}+xH1BodOgl@^8Wo&0vxX~1In@k9!yiCKH>)?_Mq*tr9eQ7eB6pS$+^JjicY@lc zoOIdM>xyes4Cq9>e&rSVK2AkkG%xNa_YcY>>@fym6+zURb56E zUsfsUGCd-I6jBJHDfb|Vqz2L~7wEJu5w^JNc|}fYZ@WFzR~@sxbW!Zsu|T zj_I7dbKB#igF3C3aEYV(P(BG3#&#jo>z9D)SsaPGfwVP5bNcfIuvPBllH4hOr+?|T za5`{ptA6@&ZU4tz+wVb7p%R(oiEUZe3S4{eYzC{O*REY(v*EyndWQA!;nO2B+yN~!4pes>xy zxfzcBRO5hRAB~}R2a;Z_iO)9*-E|-(2xA`L3LJ^cFJP-rCjc7>|2*#<{l4;NTbyqb z)zzo($I_C&RsC-qiA^4K{L0t(tdIDa z%Avb5Q-eJ9my{!>=H$%rk~{7$w;WT$SSkM2z6&JHDfz3nJ`gAL0kV~*ZL0_aSvk#? z%&w!RpR|p6{dV%~MRkpfXaj9^pN^1u+ua8htgAZ-b;mP~b5z_t4bG}n)aJE^8vOQM z-`Y^UbGL~9(WsWy&h#YBJWQ%RMk2{rEP7X+XQ)1%F?^*)p^pqg)kfT%0=Tcv8K%^! zu7CB`w`Rw$Z>AoIyZH5L?DPHWYH}o-y#t;_#Imv(M{dyw$`yWtsubGFoGR&TdWFCF zP(>Cm+nsZKIVpwljO!XSI;wN!&qPYJ`C9bT=!c^%s}{ZK=R zRLPq>LusJeA;iv#r7tN!pe#muX5DQDMtRR7f^7$9pK_x)T&!V zVtY===cD;qGCh3hU%mB+m?wH9dQ#5@!l%KUj?4Sojr*Aafr%LbVHqczYD=yCqa4j5 zeQYZTQI3X>a@0%ogWF^=~*nWePb?jU_L5+6YNOTFT1aP7v8f^#wkpwm(%Mtr~`km8dH&S6@O zIH%fyl#Y`l%CbOAuVlu9tM8QJ$hM?yr|LrQ%XhqSI^k;cGm49#FhMm)`8Bs;H68Ec z&R~MD%ERmc03u@uZ*|sa#R9qCJzQ~gkeXqfWK93GK<=QHSl9*0{s+6<+M3+vp+CE6 zbk(i0+|KO!VqL;SUU#uB&z9HyhOmswxY}}by6Zac!WyY7lX|%8enue_6j1;OJ#o+I z#EZZB%2Cb{4>W|#^1?4|YQDYXW1* z`?T*4>n9eT%0;WBdjOf-9PlG%^Ro!s0{*Bl1UWbyh7qO%+K=Dwd($57Vn zFG#q(ns-Ujr;9gBD^0!h{5SG@4r;|q_Z5Jl0k*_Pl&xZjVl(V$wg%zMVTUHnVS}(v z%y!s1uan(!ZQjeJYPWB#Ij4m_p3FLtIjJX?r^!<#bbV*avkiQy{ceb*n$7;8JNT_; z=Vda_GPmVN9>cre+vI&afqR%axPkY6e_%d&kfR&ev^UwmE9s(AT*Vn7;nTkQZwX(a za-1Xgut`%IuaU>9;#}l45p_@YUtib)oQl9c$AOKSy!pJQiowc+#MKEC0=9qiJ#Oc& zbYjD*@sAml znMo6dHt7Zw>kd@%S_y;Mx&ss*oy^Gy%qR2|sOECCb1S5WSiI8x{w0jS2J8Nvn*OXR z!qAWjyDIQ0v%esB;1+Z6OwZc$p?LO?GKx?V4`b-m7{tDR z6auIaJ@KOA@6qo$f_s`8P zs(kJ1q@}qdW~@F78DuP*=*?j^qG^hs4_13 z!v@7hRg*5?5OwI=JS3aRtWwiY1kN;a|Kwa=6gQaHVZi&9+?&tr)#Q9K<>YevP1#fv zdi2mh6oC;PP;VVbRvdU~Iii(79|{qFtex1yqJ|upWEb9aV$)o)FWHh z5}n=gZL&|X6(>E4Q*F&Xt~vNbvmbQxa9}C3e`9XfjPXnD*V$&k5u{l99a!$j zZEq)qEOLhFBP;NMbf%IRaWt-N_gTU7lAy^lr* zlx74B^0<2)hn_34!&P(MD<5OoZ#`wQaD)mheh!iYA=yPINK&#EB2*w~%UyGb>gRfF zXK`D2b*AjMJbDYai8f$r(juF~rf@?XhYF(K^Q3zk zM&Rnic~D{3nuTtu|1MlDwm-!U*5&?8;OwULuA+6X^5*p~qV=`8`|EQ%y#rX@{tVMc zgJFuNnVfQ_|4@q~FC({|nKQ63ci>fWU@w{bv|?xmljp4K|74*%@upPh3hM3c4OV62 z>-_FV6NYSadIoctgLUi@gFvQfKS)p;tzS1bk~zrLWS0{-wWb}XGP63fa$2$+cmq|u zAwq|Ia{pCAOJdHzaxzObmz_JL$$hWQ@#b|iIlr2oVB`+Ca}!t`mPsqMpEu>2fZ-m# zo~ur@nMloz)M6lQ2Y$yodAZ}HEq4o|u8d<$rs3BDosv69lG2836gbvfaTeEHwy_dC`lc&frQ;y?($mK+vvMo$|uJPDenmbPAL@Y4N?K_@47)oGA5(eFQ z*K!A{a(kFVAq4hb$NuF6x{YJ+AISr6b36a2;=HDHhdB&P)LhN1SU+*#4n|FlFPB-n z4BM8;eYIfIEw0?ipB(xUxs5OLHZuT~Ik(3#Elcv9_W+AN*L1)mSZg`>?eN!2BLHR7 zLw{{qG}#HfR=Zrf<||YGb=$yobYMNI3K#;z?Kt?e?qE|@PCL2^$Ieg5oaeRyuT0sY z?*6@1oHoZ^N3MZ)?b1_#%V!bUD_yrYg^$a15`*nPFto~^)k|0$LNxx6(`_#>=YcQB zf#pl}OO|~`3dccZV5sVZdLHWtt@E0@KV3aBhch>1Qcq%T7id7DW4AJ_miLj+pGM{y z5&AWUZV-ARX`BIC&q{8VQk*X47nT0<+@D+RE&UnU6o&mgiLmpZk(F^!-^%6`_fhiT zBWvCrU7shq+~ubI0Vd7m+CvSdzf9`!#8B_#va95xVeFpPng#wusGe2GG{}a5|MPoL zeEHHpY}i}Ifo`YZ!pEPHfpL)Ab)gyWjVZ6+ls;tIdd;Eh%zlTyKdlEW=9_6^lVjcR^8sQw<-1D*YNtjC>u5T8oOf$c;nwLDrzXrQ%utm769G4CZ{O$?Ya{Ul984(zw@XL#t?Z z#UH|ot}X`Lk=N{9X}VmpIRXncfGp*H-)aD+6cY6*Oa;9i%@hdmQIZSJskm^w&i)Z3 zZIW*&y*L7sqz~+`+~e|ta0PrpqNpB?xxuoT{@fhOCblf^$kPS`u~%N4+1;8Dz#;?q zc*QwTiuoR6lwWS*H!r79ME*?Y6gB83LzEziLaGd}UGf=I8P z928f8XxJZ88f*zVK2rzd%opi%vV)|g6~5wQbdLjs$Lf&J3RM+rU*+M*fGp9=H;Xy2 zzfL-~vPrU;$!%x$U*%D&hTcZ?ubOY>h)2X7Nzq1^T%hhjkn;}kj>|V^64e>a0m`BG zr_jl++vJTqCYKm_?8KOe4%NyBC$9jZIn4Nte|(3?`17{rJa@2~8?qvjOfB#d#58j(>D_ z#G|fOJ5F&g107&;?kRFA2vwS#0^U$*?#HW+tltT(F9`X`>}J*M>WRQS_x<;+ss-e= zGt%97z8L|mO};Ak0_Zy7lQ+1;UCNF_8QhXYhwdkYW^2lORo)eE-zN*3hjz|4BP;*+ z-QpS9N*Zs7#sd~sOB=XL)0e4qqwCi71Mnc=$f6aZ(S75ie1JN@N-ctD-#KL5707)MyMD zaw`YTpSl8rd{-kLL@$=DbR2+ktN=U9{<70qSvmBTIj-Bt%i$z>za-Fu1cxlt7X-z6J*EzE_GoHl~T|p*2z{qeO8L1ge8v60a{I|!2jCC zL&t5`C7Yv%4on;%`_oty&%^~4jgb{4;3C|mb!<$gbOTLzulLBzjApDZo za0|@C6(irBn0b(;=oT4+Wu;QY@pbpT2}4geIQC2P*yKSwM;`R(ccI zBqoPSW52E96}ku3s@HWaqH*3<)tziRoWY}2@EA0nv}6A($8Hc=8**>IBRiMtPVUY! z?TzBxC-dS>xw$9k-;Zb&1T{#*U?kP|@gEme5Y2K~2Tm6XfOgpOF7o=aav6TGoeaXX zV?(@S8oXPLn*Q{|j)RY~ZeQtcVRC7jLyi?Cv_U@t^Oa-&1u{=Hw>iYL%a!n{Vn~@e zkY@V+nnn+AsDG18<$grZ_^{~l-en+8Il?FPTvIh3Os4xZY-rDJyw>sDkN3Vjjn~oM zn3d(=!EgvsJooRPnpi%hZsA17yxJut=h{Ov0uH?mfJD^t4K@F^O=n4okUFr$a+UVhm(QA7Z$5vU-D+m`3 zqzIzN@+BW}7ElE(o>qfn*|XKv6iZ61YnIYaAXXbPfGEhTAW|X)R4E>Xr{)GYt(*34 zI)?Sp#j1nmF>{*?vz63z5XF%P;$?9S;zBp4r5G&9B_;u{6c=NGz6665qeVqWS5TXF3uxMdNK+dXGW*XKL&>{sl1;r@o_bPMK#v#o)a7wh9zkjl z!}Cm?oNCp^@TJt#zm0p8;+iFP*Bcqt*@AeY;_L1dD7)LB(n$cciZ0RD{5bAWezv;u z81Cu|b4Yi()s1_HOE7P1afEIk5vsU6ug@0%&#|K%CuyGpi7N8RrbP-6@6)ZQsuTyc%@I`-0xDZj^@e(n6{Ah z^0+?#on7X>xcuEqZyJ>tSy{>V)S1m~jTFmw{X=zV4&m3_l+&w&%CbD%8?FRNc^98+ zn$Ez_Tn=h=c?u@*w*RRZv@!ISi#Z^}Qc0R|z{3{&cuy$h!%+;*P4*K@_8y^4>Os|U z6@GQy>Cc(DXBd>Bh&tv>TFYOUAdjlr-3fLKQx$JqmU`W#@@n;wV>@y0UpO|X+S7ge zCq;XUWV7Q>`W4_1MF?3LRTphL$niOKFCOP6u*)h^Zs-nFE}x0hzB0~*7SxFq(g<68 zV)c{l&Ji;~L&rH!KE_zGvmK#EAn){V<6KLMfmn6GiTP%^JqbBXq(J4r@ah;DzBS%H zSNGRZI7KYBBoLfl4vS5^(Si!OeEVq9yXo15ttCHUv9fi||IUisduv~yHC%htVfjwp zRlV|{0JGKl=kHc2E@QNE%ar{xpY&i#)*@7Vgbz*uQyZ`6K8K>9GKELjp zuTQUO%*)@;F^^dZHDexqGcvuE0ViX;dQ7aW65TF)CJ7VgdmlO`~o z3ra6Oww~I$LpHS-)u~<86!|3nm!a=e!26fz7CpQHX^#D5(Pc4YgfG@kgS=48A=*0Z zl>lW^KOj>%h=s}TecSb;#LCy^ZmCe9SluMuz8fqa=rIL4)fU+8LtEwV7$;5cl=W;! zrD|{X*VoyAZ39&v#Lv8YZ*R%NU?G?(y+~!80i1E~O=otHn7tE!J*7y;#d1v7JsuIA z^fiHJoT$6P7p237YB+h6M8FL?1l^5R?Alv;cI236d)C)~7pPS}6IN$9DEBT)1}uKL zkuP-J*`z-;v=#P7-*mC<&x12GQt!BT!~2A@ruC*@nSyx!SW502;_^dUmK9*56+ zZxpSL3o3jJ2d1z_WK+7rN+%0Vqq0hI5c-KG^dIJyM{yqKvKgj7sqz{Z|FMUI7K##g z-h|?nl=sTLX4X*B`9p04&rr8gT+}IkVd_7tDd0ocjoIgctvooFYGL z8G=aILRTmWn^Wj=SJ-wcFoVFd&E^!E_9<(2*0lR~B?JuAF2|If#T)pbxvG6;JGY^h z{OL+oL`zau4O8uRS-5|-;rqXpVzntnv%=HenK@$RanSMZgzHx3Q@1c^zzzFV7W zRprxH#-;=Rjr!-=-*-zM>hyLWPm#MU};HPy=l=RCXXb%xJB&JV2 zL710Ob&4bd+8Kf0uQ8sK{nm5QC2Dx)R`@{!>hvMj2OZr&(O~1Y@zF;68rb7F7QV7$ zT^X7((DgKU45BXpJPu8WgkE-4X$&?ru`IgK_=^j0&S@{Njr8W7L4L%!6(mRKQQtk+ElnfhDQG6Kg)I4u4Z3>ACexxK)(pti=&;PGdimhZH`}JG~F)b1XiL-UV+p zify|vUWcmy5e)E$Vy&wzXf3yYZ5AT02aPyh#xTc60TgBGD`?m>0ACmi5ns&|MHDYF{UXfdA?MqhlO@P9JcForUp>afe zX~#XQo&lxeopT1X;1`yxYo@!>z;_ql^}PSdUAIkwK22y&F=g6vnxYA8YED;G;5+HS z_tbzlfL)0>O)U;X4+yMwQ;d5(93<1hMXAc-`PUaaa<|lmaN9?DBT@Ux^*&)$*@6t8?55`a$6mtO52!a>sFkeg?7jHfl`1}{% z^|KE;PZ1tkjqyH{fBKuYo~jFe6Zv6S6RFgkl_@7thqS;AN6I#CR+<{65n*Ppk~R(d zAx0Vs2&a{ah|EGuF&l9UaLw-nub03xMU}7ifz4qC9F{ikPu?9u*L#AlcUj%?P2LFt z)!&_|Oa-?(XnOP5iIWE>A5DF6qX!!*Sr*-(&Yluo+`0z)fdLh)^=rO^Svk?m(Yy4a z%D4_{hSxF4=fPOk|8@a^~ssYVb zs}gLv1GK;&2!p=_mV3E$$2u`IGVcUQf#(e#e#N2sHyYA!KohB~8RX8(Q$2s&A)!E2 zh938*D891SZ{D#*{XmByU!n|~K##StrHR*XWaB^OHxRHw-acYm8RIKBQ2xG&l8kq*As%mt^kF%+E*r%j7FixsbQzQaSeTz zIzyN#Zk}~CuHD#U=bQg>_S-qb5FovwBCt94xaP`%I`(!589sF6{uqn1j>GiNvSTvz z!`Pm&c=k^F+pkaGkaBO4h{(Hz$Cbt*E| z2{Y?jaIt9<0)&#+&ay_xLQ^@7Czok!Jyv-7-`vJ3_s)X0~T`{gG=< zQ!_D0%ij95{GI+A2vs}fC$6B*_L!=ZfZ^U+R5O@XQD+EtrXC-bSuky$abnPZzp3Bs z!3hJsOp*M{YtoAs4ywcv-uiKS&{%-F54C|Wf8m)lXZW{d_(AhI*N)P*(%6~GJ6Tox zx-$(@2%<9!7QJT!6a!(^&owYvjYiKgFN}Vve=t-;UufK{moYQ#>(fP@!5PPcE$g>p zwqX6zm0mS_w7)(bBANUNACYI75`*C*u(oWaauYu~(o-*dqs)k8ojWH|LpZ8zcECR% z$FVPQqNAR`P>U2I9+^gy-PKL35+n%aos_LUlQ4^;8;p)Sdn^7-Q@ZPRkO7B|^i3&W z*<%>!Fn{0vqgPwu%v0)ZuDMRl{OaNh3@GQ|z+rf^-#rG5jt9xYzG1QwvK*AJzP=|? zojhVWMkl>}S8qWpi*V&)!IHal)6r}8`jI4Y1R^zsyH}h*a05=O29ohWw z7S0AooCY0&s(ekNhp!sa(ke7Wo**S% zk4l?|XB4_k00;DKUSF<^rVI`cVr*9h7}n{Q8xbwGydiA_Z1^+8HY?>TxjWMn`S{y- zQ1R)eH%+=@XK2YkLt_)tborRm+Z%fHJir+nJO6vBP{A)u__zInn8&ZN8%8ThswXHA zYwriO5tL1oqyPh&Z-akt9T&872N6>;hZrxJu;W zjZ4?=l{wBnpV?LaYO&5FTtvx&J1|fKINVY-!)bR5J|3(GB(Q?Wh0i4Urv(f4xI*88 zuoriGF0#7wRz;6#+eEw!Wcg}%3;gHFAru-rWeim*h72VI%e^c01%$?hFEqAi5>_o) zx%X=B*qy3G^6!*w=%VK_cNg)+i##w@Bna1ZN~m2T+B`0SvThOEx)Isd&Ay9A>qwk& zhTz&urSry-a=^_FU(fRS_%nZ=a9jV)*R~qjZ;6&pPQ^QhEtR#O(}_Rz31fGvqsG6} zPS2tP^*`K~Nk|Ct+KHP9p&j~Uy(O}Vhz1)9C(z=ryfdpk8P@~dtHVP*3#2?CS|abp zOYDeWf(-ZADPzdp+Zgksq0)u6>R-o%_zYi&9p=aO<+c8Lge!2Tdi*=3)5D+TT|S_^ z$r{JFC!jJ~>QKrflIB_dFz8XY*+(dnpSj;0s~D26hiH*{HP^Pm!nq!lZ0wW~GUT@u z8zp!E5Two@6XJgq2#AM%LNxZd*Y~4?NY#NAUcH#x=a}7Ndq=@P7>26a ze^k>^Ue}kdH*9|^5zs8CAewd1PS^sAK=JE57R%_f)^U;JHP+tYlCS> z&e!4)-*%W!nofj3$lhs?8Bo}aytBm%?SF(~j~fLPT<+oE{mVUeI;*H5858l5%!4xF z^z!zKfWt1Z$BVBzF*VuSVQvz@R>5*8FIlnR-O7%vx!_JjEANX(V5a83$B^-B+Y-3k zqjNFjl0tau|AWulLj8pxYWspg1fLynLQd1d;;A>l707f8hSc3eG*q>GFAP7ek~_97 z)4Se#Bapwv3!j?f5QhB)Cl3M zFfth>$B4N%GZX}^45(z@nP+(j+oL91`&IAz_WZhcKLEt(sL5lXam&y}3HWdHMvqx) zhGu9Q?!!AC8=-`SB*RkRBuxfuy_dN2z$_$+f8pziV2CqqCTyBQsJDapY|6?6MOAI5o@+ENwWbSaSz5?N=v*$+El= zguLQpC9AUq5D>UG8S;M8XkM&gwDLHzgrKfmI7Sd}hLpJeo`{WF1Rh@WMo2#SFGLY9 z?R79yb~(U7`%L!kX+Qu=Wzs6)Rh+!ZvKX&FPfQ1l!Gv%jUkFX+8n-!Ly)YuL2l(=O zp)q_5IPCWN`9TNjC!j&UjC<(BsIu)L~7V)6cPjMaFzY`abyWY#PMBL z2rmp5Mer6ZDE`d#xXN@Q5$c(Tbdz8 zIAoj>KDSFwMs4wBR#C#|HW|^`YzI6Zn*ZP*kA4I&Y>1}{hsB0n9Kj=6OoZvI0p27( z_led{BtPv-$rzkuOA3ot3HVcrM@)Q$Me7HQ=Jz&2?gnM+$3EgeC{+CSQiNrNAgAsp z>odvg-O7A_dCXKTsu$M2xjQ!b9q4{W7t%i0;1Bl^YeTugIf5Sn&XK&nh_xI?(XiAQ z?Haw#E^pc;dfnuv!^lEOxla@ZsHOQoy|uU+r6CMZ(=ZQ>0z-y9rbF<3^drE@g#eat z)P95`3t*AGjNg0cKF71_CdKCAS(}zPBKD`}BP)X8aJL$7{d?6RV4fzYNN)WEM!l+@C_GPJbNI-5TxL*y^QoB4bb7Ao#u;BuC+gI6igDPa^kQjiO z(}j7*__a*}AF=K+iunrKN zHc6vuf&U@BCG?E5!df;Dvps3TXO6uH2mxQ6qEB7QQ0d6r4ixB8r%37lSWIJN@VPp~ zORP3^>|RDC1bRFKAw{7w4cPeBoO>HO4NFzKiJQ=2RkD zy8Bn>?EM74a$r%t=UwDXd>2?MB3zhPWe_2ZCfJKna!9ETd*Qu~PK-LN3@A3kQKaPg zuY{WRtygPv#wqFp84&2F>_v28O~!ntIvwGA#a=X7h7jydndj4olEz7hh41qhDHR{j z4j}~bkA9kZgMXpHUoQ0j{0k)xWg>l{5FHw|*bh9viOG=#psLt%>$CQdo=|og zUknlkr2|fj9>J@kKF8r_i|Xq)8wM+bvc9ux{#GMc>6+_LthN6YtADTK!4~#nFkWc6 zph8O@8bnZ+iE$uHcy+5V7^1~U;_)(8DFx0)pkjkkWO42~9G6H@^j~11N{+q^oGyR4 z%%6?svi5cEkP^Yepa;$Hs*JGFmA_+|aVo^3;j8TkC*0$seZJayjP#^d{l5hL1yySs z;B>L&BJp}(r=w9SV)OJ;RBClJHi**v2hA!T9`o?|GGPy(=%?pv#norZmp&9Niyt3` zce3BkgVW_N7sTt*yQ{^nGen?R>h*Pab-pmULW`NCpg^3nqXBFVrVZ7R{+uh})2 z*nF{b&s<^gLhF&lOEis&^Gvxm+(~anX8IJf>Wtk4hND^W|IqXM82fW?5t1ANr>#sf@DDQGN2GC%U-z z_8x=byglpf48<7cK9& zqa!b@)JjOxS3A|;w?W}zr}!44q1jCSM~Fxm4d#tdjYPy7r>TO4VRepCrqE=l`G%@4 zf$kHfe-_2hlqm?uaKiXW1W@&yGTrcqGD?Q+X!g}o*v$Wkzt^iTU;O2$hn=$<|Cb1t zR!)tKUtM09C6@ky&dH9A9u#=S(+>l#=AR&^B*G2e>7anBj<7nT7YhW{SxR9|RRlZ? z>!zbfCAdtHz|*kQ^UVE|mHM)S6eF-i4>X24F>@W@saA7`mTDbG(^rK3rlTq-ysRQ@ zqS1>DvzBZG;DpeH87`nAAD;6115?4^zgt;hs zQAJ@AF5zwgs;>Z{^_caDFE^j32`Y_#w^9U5*KwR5kAGcJlYg&)RHbm#%QFoHyins6gVGNVgFPmsjS2gC~SF!y5O*cG=F2 z9{96fTFc(EQMgtIzi#_zX@Q@z%5}Oc3M>oj9eNdnQNYUdn&ab0A)brZgo@~$iinBB zLj+Jz<3^I6pK1#iJ-=4!BR?yf9fbTVtX_o6U}J ze%Ueu^l!N71?ePKps0hO-v*;Q}CiE8Xrh#`4- zzyE>ix!@69_htSn6emn~vHH7wM0h9i2`~Dmj>`PC^Gn$A(m&e__l`LbiOpDLzXwS> zO@`lCHFhe<%h`qnEihTS@wyI+Cw?A-v1%<$3{PRC7yG9p5vnmU#FJ+?uJ1gQ3=tD7 z(Pl{fWhar}88vz;PRP^w1M_q|NLqIb{%g@OtePVQ5nnSbW`q4x+hYFOvGxK(YS13# z;dZZ4fsdg-xl_Pzq#Hez6y)vLV4)L3>bdO=w;vez($u^CL@3C-DFW0N5{xOt9(eL` z&H^mvz0!)=`At*HW-MEZs1H1aWdGWtIeCd_pIBkF6He&%RU!Rs7P1OO+wWr0c1H86 z*dozBQ$FQg|LY~j80mzZpWQk|zda3!*RgDhSC59Z3pDOxsd-_s`=9?}6{up0&i(Ga8p$rCIW&G~i7R7bZZR>vR|Ho|8;HizerMy6rG6EC@sP{Se9eSGR3SH&Yq zK&S!9yzozFyVz!*^2&Y-_OmS#RmrF}B0MWUuO+lT6j*_|hV$S!P#7h~bsbb?Y`&Bn zF-u*fOjs#gDBEFl;ylbVlvUq9Vpd1bP~)vV5qJfj++=vkvM9-CBE#napz2$7R5r4> z2*G;H91EfKq1cjYquv%c4t|fuxuX-UJb`w+UXYvt{A=mT)Pk7H)je z@LUoRzPoc$Ic8k$8z2Y6J{(y$L#xm=g6l)!wZ%mTuY168VEq7EwUc7aoO2cjyNMP9 z3+G>&sx4t)p$=RMs=^dJL%#!F${5aGp*yKe&1#g4p}zuaa=;zc4rNY3Fz-o{J1w|A z6k)Uvf3c&!k;ENe)`j7=RXrt#21T!)UI@wMRkPytNl6wnYj4nE-+6?RY25+9+A&?Q&Zo#Byb zDV{3)=8>^8Y>h9o!N}f0Qpiprg+zTK<{0HOTK0|5`XB)1p#>TO$ANW^j0rnkw5&}i z!nh>G*+Ad<}?AFWVdaCu2PGeJ>8*D8|P?UKQ8OBWlAqP zhw7U!x);(cj7vmNEZCDf|2jP0oe8JcA6X>uRel)lQ24=j4PGMo6Q2}dtMi!}V}*2d z(_)y9N{8`PPYVD6#Y%Gpn1|bhFDv+R20DxW*PlVF3Y8jY+;Q-p%*uf|h0tDw6FVm%`VJJe8Rd&A|UcvU@W8rTX6hlKJCn)In@hd0yJjCwpogGkU8-BH3K${ z75qUvp2>Ep9R2OiR|$K3(udmzB{0q)kI$IhXy{`nixGxZSjpd14296d<&b)tnb?XB z4L3DP7@3ZVc1VMW4 zs@V#`w#Vy{g}5DrY<5)Cw0C(^-IU8sqU0+2W`oP{nF@sTb9B1v-ulC?%IW=9q0k|S z)zMmd%-Tt$zsU1kIGYrb@t^~FST76tpoUB_9!8%Ve&z5g2qQ;Q$T}LEZ1TWarPvq_ z8ZR@h8Lw$mu=)VHHKQ&BB}dv+H)*0f!B~lEJ|ASMcgH|>iz3z@A%Ph^8139R%g06< zqe*I5Q779lUml;oy`i=Hafh33F!(4UrKEy(=KrmWZ7HrQvFzBGV&F@z-?>|YtOj+$ z^TrXUGK|~Ci;L3%5~5g|GZb`H^O4tVlAnfXt5`3X2+3$XxICuT02T$K?-Q_;7e2(pV{IB zCF&U-NtA|+xI{H!y&C5mI)0jp1&W|$f^T>~CsVjght?OW`B-Qmc>i&}{=|=?KYCQ8 zKVb#p`eTIH8?@nM+e={K8HtKd;8ln>lL_<3B-Ozl%MP2=k?Tce;9ss+_Wzda)tI5r z1m7<6s~ml3D`Jmh_4uttY|LB5{h~2d8hXGnq~`bSlr>)R0#_5fAt1_lp-RV#?i{b& z_L#Adk5tFw6exs_&Eu;Ll^@y?RvWC}ii!o;gyA1+W^z|Sb>^^KEIj+!!ZVE-Cwj2A zV)p!>-I-`AX-*+3o}V;~LYm{4aIF1KLsJ|L_-#cyQ7OB1J*JOhjdy~!1?RJ;`Wf`G z)X&EJd^#QT?1Sjr*Wjhy4>w>A9M(feABU@BXKN7QS`Pj&I0@r*&k0fVC^=N04{yad zg8w+6&ToYC7YA3q)a=8m<%9U}Ce{Kcz)Ixn&pTV?f-f0?1;wMHFehD#WH;3lpM95z z*?&v`qM|VGc*)19o>Q{_z+v%pJlDOI?th%$$_KcXsCCKaS z?VN%SPg2coLBvv}8_CrGq`W#7`#fF4*VgxQVe zfrxic38`zwDGCp&j24efn?SiEJwZ1Vn`Gf*Cp#o~XOp!hs8k-SV z>vi2DTdrFv?Yi3juNX$0R`GqOC40mnT|;3xh$v?zR``%U8J$<4Zz_yVIcG zdWJPTSQa%0K^;PwP`>6EtO06Kgj0AvUy;5ZU7kqp9gU80i5+|J5|mlPfE#$Az+ph4 zMf4|tLS=k*Ae^d0{Wzk@7$wF0E!RhuCt6Pp$F%;b*I1|#w<8=TjmWEb9oKv*g;pjMOvFp438XS%4Pwc( zGhy}f(DVXqd7>3Ea7^DeJrtnudYhLY9SGyqdDUOppL)1_=}SKE$#ditIcA4h4|oQ< z+N{A-`!2>x@sqoQ)lt0vFnY2`YUHl0z?J|)|1{HPqfWO{eF7`^`zY<9-%We>$G%_& zBvt?RX}-(hX1!)#r`w%ux8!CD3?+iM6Fz#mJey}%uv>43UuhVpB#N*}r(QMxAi8eo zDGicR6rOHgYT!Q*M*dMie$}AqZj0|?`)(bW?;GliS*hvu>(Zc<^^qzTT29aC(Hl;E z+C(`ojKu5S)>MYN;EHs&Zg1U7Jw9JAr#UCelS}k%tf$&pB&@E&SwvFz`&lw2lTXCA z8>bxjby34&wL26d4278#I5lQ200p!}!rz-e>z036+Lu%NB5MkpLb&`ax#)nO3S2KzT( zx9g?9e5aMJuqj0Af@A*{O$kwnuz4XP*V*R2ujc?F|qsBikdL*RYYEno& z?x804J4|5v?3zUbbok{odCA70QZ!FQogimH*@^YI7)w-mkX(Kg82)q8NZ}8S!tH7& z&D?C>`=wrpv34D-fm2+iGjEmZf{kcaRRZbmYd_uew;c!Femt&bC)w`cMlgxI8~>vE zQMPK$lxe5;hrlSS(+lkiu9aN8va;xP{=p?TfuK1}q^Z-OeTnZh_=pTQ7cCxn>2IJE z4x_bT^2<@qQn}uJP%Up3g8XNrGaChFk$m`Ic-vRb?%?~0sW#`C#oK=}iEMLENL}8O z0>jsC>&e5wj@T9OoKZ^kp~8gJjjs;6DQEhn4)yD$hi-Ch>2h$h_~Dyac^DV{UXHwx)8q(X0*Qw-=E1UV-W)0l(xHaqU0Ra`AFdwCxjGUe}xng6$7mm z51GFZs@(lH<+fyZo~}@~yU+tdQyXzNKB7eb*B5Mx=_aIu6~L*Qn9i8i`ki38sQ-D; z&B7?MO*M95x`U=l%_?fd5r3A8Uu8n--4NBtT+Zp-9;1L(Dxn~tCdxQ+(Ozcp#cPV; zZJ~aAl;L#IdO9mkOZqG49317DB6HNm)gWLRP*qRn)u`uQ&amGRWE9`;qwbVfTgF93 z_>Hnpxw73}fa(Pw54sVuRP8KOBah5WNPVTs#FXL8k%ZJTTA|BABXUV!YkM&qLv`p+ zYBjpXwr&&?ope8vY7HCoCeGT`PFhzDlw(2m-of*Lp{hV1K80}`88G+ezUM6W?}lDpuslJkyX%54_&NQvw4$iqHbM8TSY>ua?K{! ztGQu(NPANofp#zdK`-6WC#l*uV22wEubbXk8_~9!T#~Nfpa;EG+k8s<=2*LKc;lD4 zmw|K1YH$!h1{?NoknZI>fTH90#gKuu5nNm<#oYwVRHx~(5o3`OBxEegj1)eV7jCy2 z*I1z6)En8lU3mDS`j4Av?+$MAyYiv|PIAL?NYmg`s@tHrTvQ zePYK(z&^fTV|zw)$d_OU*NJq6c@;c2k{`_ zyQHpD)qgx@@r5k|kl1$zOdCbN$@5C8Uf=~7{XH_2lxnp{2aw9$&GFGqHzk*BcUu{G zgsY)~q5OVtU9@{7seug-U0QmbQ)|7lt4rWz=>WBw6+X|<6w`)9Lt;XTG`Kd|_-ko{cFFoeUioB3f}`w71ZV%VqJG=W(D z99z9SA{MRGoKhpta%rj8o4yr!Ri}~*433P(Lqwi_A(Hel zI+Wu+>Dwlw_JD5i_0ICnW7V#RLCPy#6&SmCxZD#CFMY+IIG4oPG`_I$3FPXJ57BQX zRXlV_dQfw8yPTHulZGa#vhM8=uBRbj;^ zDmq=%X_RV>o`Y^J^_C&f-$~4HGwsq#|COR@cfw>=x_W!@7zuJDy1yND^F^MJB2I#6 z5)jCEH`sKe$9_6*PT>fpP#2;UuVd&SIc~>)9hXwTZzN;Ainm{08F_cTuUZWaR#Rz- zDOztap9;AE#p`CJU>LP33n&J_3`lC9ESQ>P#fY|8da-_vU+Svn7uB!xBcy;D$+*7> ze1FhwJ`llHe=|3OcM*3(UO278yx|-f+WpZG(5=sU!%esQb0$NB0$50^j}Mn{7ZxY1 z<&!2T!~_G$jaD4YVAgC}H#Us-&U7jWQT3;Jis5(9`0HYFM}V!xhZXN9lr!pBswT`d z@{1D{2RWrcRpb3ql`n5{UAXMpu=J|gB`3Nb9&&K|Q1=387TVp5>RklD)0mRi14v-? z(qDs(Sra=OQN*h+(G3^6_<3z|^`pYABPI7W!$cj)baAJBewW=2Kk17(T?I{Co}<7Gbr4t6c+9t< zt6Lo0BvS;v3$UTJUTStvI#7(o!R=Pji(wN4Fbs6F`;aww&kdXR- zi;y?+ZZBN;`Gjyp?B^n=>Q1Syi+NF9mpW{%G^SvfjlkK{*fxcu0>S!Q$(v;t>x35e zt!e$cJA7~Swex4Wjm8o;p}La?l6*8)Uo zHWvFy-S`O|kaH@NI&8{T%}Pgrj*z?2C&{UQ(H#nIgJZmk{SLXXw$sM5GCg6a z@VUN{{Rq#nw1>&E&vxN^z4RB-_6v<@-X(@-*vJR5dDVsrpXTtbujE~j@;oG*Bd!`) zU$m!h3(*CFANMs_Tf~$w03TI>-r^V4pCbN26)<0vnKE6WX4*+J4?2t&)@qBaKwyXE zJN@_ke}sZju*1e}h|R|K#J{u(#Z0rzE-=lfkb(=CW~A2ZL(v7oFTaf~;d_P%-SyHP zY^kpYD6nkRrG&H2NYJ^*93@28itXcQ`N{6Ak2@TKMekmkck7I-D7nXQ#)|`PE^@Rt(5t;xjM98Sao)*q9`5)|k2UL{j zwzhPn2nbRJ6clR&0V#qgU>i-WXrc%RC`QCV0UIdDPy|sKk;G$(6ct;dG?Aio!2zQI zu>hh-Q^5u^iZaMB^Y8cjrhGFXCg+~}x68WgtmX0Cm3;HQdq4Zx&n_=qApDQV0s#k6 znvF81hjn|`jYi&m#RQDPJy;a@dByhdSfnJOvczEjMr~91)6zaUQk*#}(&elg zG$pdeUzxC0`?hL%nSb%E@Apg3ITHEk&^Xnt@)n8GD)pHTOFWgV=0q4&7_qwD%ZthAd&`f*M;Fa*lu9||Ms(QWOpKe)W%Q9qeDi&UhOZIsre|?*! zWIBbGw2op?f2F7=C#1EbigTlg@hkaRulbhq5w#?fpVK(MHgewQF*6HD0R=UI`<7oW z>hj{0H57H*b36OaQ@h<+@Csx?(We<5^wUqKrYd(_`<%x8k_N9Dvdp(E;jV7o)j8^} zYO7a}Wyp?H%aC&T&+aSLo09_-)TLB7i|ll%Arbcel#L}N`la4WHYVr#wUA2|@6{-L zSabiQQ_O|Xs7VG1^4nu1uN|wYJ1UuN!71_W`!aRcum-pN%2PZRN2r8aPH$9EHB0k< z-=;QOE{)sA9Cbc4YO9>N(V6uU+{p@@o=48T7g>)-aOCstKg4;zn5=6lnc_kl_RhK0 ztCmFje5l=~BH>aTi4#NWY0085elm4CUEBWY75`cat+sprxV4eLn?IhocnWr@-(mSK+%yGNN* zmJ%l;M^(CH7DsEjbx>EvtyM z!|7vXe7qSF>Eu_v660Q3ruNM`*Vgo@$i6UK<9_;kk0==nqbB_YCH6_qltzuB`V#%H z?uB;KX?i~=lh5qBq87T2!hYwRT)RKxkYf1Kbk2ha; zoE3R6OpZD}iDq9^l9X$Ct*I%t*<#`~M^|hAd+-qGe%SFi%e$Q43>HhSyPW~ z7EhmVbx3j2HjVuA3!81XD$kC+?WC|dQ1Zb+gYwA+i@j->A%?P^%naRTaw|$B{X&Uc zG3ivNT=dD>+|M7Q6C-N59F_u{M|Omc=Kb_gs)h_VcuUH@RqQQtRO#pXJrx$)kI_hB zH7Vp_yHl8%6dE~bL6_c(%7=@TsbpF()4BD+yHPft$j)-#X3^gU&Bg9@K1X}}zs#QB zbMxQocf#^qn|3F|>(NP03jOW#smI6Ct3GdGzjCFpk04`Mom@?3YD|y?X>cUZ_K^te z>u7M$heeMA8-i|6FJnD%qcz4;XpI?wU=3R=>L(}ODl3k#|D}qa)Y!EA8ELH_quh_A z{$%pB_*_TEFJmG*uUmG_()65irg`|HN#T0Qp+*-hF+-GW@p?P#W`Vr!%Hrd)`okz2 z3-t{)xV6?-8SWk7#_esLx=2F#>4;5E4yBSDM-BGJ-?Kh1WnLN0Rtu!QFnn0yXthP! zIfo=smqo8iwIsbCRlVb=?Q%m)@SzX4DYO&U*1U+p>@2mGl-4;MyI1ud&!a!m1I>eO zXO*n0iB9y)2M6{1l0!-hN^^=r;KMwX_8^&&kR6p+zQIVwVwS|~`A0o9j$XJi} z58AzMsrmOPuDyHaSCzb_>IXl*eAeq}iIU=G)?{|_<*d)8t@xdBsP;b<_0}WQ_htV` z(_pMNRK8i$&e>0zky}Ikki`Dn09Vl0P}Dc0laoeeCVlzd=tZV~chd#@XEA4RTkJpn z%K3}>zP5ud>q^-PHy09{THUuA$IC@=X_n*K2$wfcrKWW;W70O7ku}THns(4fLu=Wy z$${U?1Ya^f(+pM#ez)MCSfyN}{g(D8m{r;-a3^m`>0|K1pIWyY<;9k?KM=xK^f&`D zK3)`&YI)QCEL}Mj2gn5sEorK{Vvoz;D&$oZOp2{}{BB){(P8X9M63 z`A~3*nvJ{A$;RwWALAb0KdgP%WV=;D8PH=3;Nw3*4?7meab6XM9t=m;LPyH`1LZu# z&+T?LTod#YEzgZIzp@r0SPGf6Go`w3xaBrKV=RzO4KFfaop!45YV9alOv9n@*`9HG zk7P*Hk{Wz16C0D^c6d>G<>9p>}T;Jb6G(x=|=sPEzdqV8*VSGsnGJZd~k+B>sWr-KY|ixP6vZiW6P8@ zmd&-(4N!60f`_aZmFm?yVw7`h+C#1|*<;qh?cgpHH_jb95<$>9Fy?Cci2<-d0iv-( zDMVw^-Z6*&Niv}le46yl7lZiZMqUMJuxj~GTIJJOi23X)zoJH<-p|y3l!|m{(P6MnI zjzmB%W_5YYE|l(%;Xf7!)Ju}a9L{(I?CHGvoFk47#~+X|WRqZK4#JxDG5V6D5;4}) zoD3LVQ?C+hFWDIzypiPJnMF?h{0D-9==d}MH5ZyiJ2-**mS;`QIJQYs=P+hu9Ic`^ zM4TYC{`GEDt?Z4D^SkssrNFBix6CS9Slb@L3rXiIup^;YZL=h8)mXm1<*eLW=7a%a ztz_Xt&HD`CfBVjtUX6WG@o(W!6QqEP_Qp-}+P zC^U6s951eSsA0SBrJ1+U5>RdrUw z?eHkxln>aE2;xm(d&%D5;r+Sm@1dR7AF!y)NB190gGv#TK*m zxjo!UyVQLK6Ib#7665bX)5z^}r`K;Nz^9r+-()W4!V-){QKdk1~ zqd#VmlM6^Dz>{IJn>sc?UJyo3Z(EP+@Hw1!%t9)7w zvDk82?&I8&tibP?%lj5nKTk3%m89>&Sg@=J)VFqWUnQ|m0XHPl#WFdsqeLrSU%o9X|KRc+7f+VlF+aQ3FcN+mBIb9xRN)&Z)(DNW&I3%h@m$B_wXN z$?ceN40uvl3ef+IATC1s0B8lV0mq#J(qcd0BajU&BYH4ZXCkB~RqsgD!{PRs6jxmU z8|@c;o@Cdc$y!C7j?;)i==<+CM8ve#_fNFf@H6}FIZ;{kEE%LX;vD$S z$t4oXS}YmY)_UJVpj9*jEietn(s3Zam~gnwG9=g-h#}+`@`0(A=gv%e1o0oJJ}7J3 zEK_elwu~73g0g%o_%FF7*g2ehoke#@!?^q}f3F1IiEUUm-=~ zuzVo@BL$KHlz3}m(n9b}W5y*8c0F6=1|gHHc8FyAyk7Kry^^Nx&$)?-LjWWWd07)fldn`E#(m3{$5*HEe;at?tA4Wb~e`fA5~L z^dGxt&|jHT`$86A>@={g7N{wfzhXiVYo|-o@;>ZBo{kWqQV}AW+oe~7nYT_2saDez z1Xn!uoa8xO#=^Bp%a2AWnzFskd;juUQV9co=r%0pM56f3$1G+R*% z!-6!NS(yeoIF?OeT#WfTyEy3!b|KlL2g%`<|0SY)>-$#GbNMn{q002DmZ`=bpa|jq zy_~*LVRLRVk6Twhlut^v3~$D`HOhbl+#0e2lw=m~NKuoSjpPta#HtOzsWXn2oD#Dxv z(*au^ZVj{lgk6Y_?I0ON(r+TtoZa(8n*S&sMGn^A=tOaKDF$5@*C7*QfGqokxfg?U zei6(|&2Ak+EMAhCtEIU6eMMVLZCQgT}7>ek;NN5ZZY^fL5c zbZ4Q&k9Nw9qSOWM3Y-@Iixc4QfL+t-u3#DvCO?BA)7)QoPldt(lGBT70z)uo!BpF_ zOHU=KZ?Frg+dY^-Zdpqd$b<7|>$ZM(W<9Rf*;S<1elUqRWFED8l}Zz-6U zVeriw`6w*8LBa!83`n8Jrh)v3v>l16EV4!yCgxRWA+QE zB=dqAZ2)tb9R6P*umYQQO<#j65^f+p9R`FfdeFHB*J1)fQkZPaS@7D)@*Ek?qa<`8 z>F-5pzi1-AC6$=SbFLKiE_}L*Dbw+ zQhOeJF{gG+I{I>H>u)B;n{<_|=rZo>?pbO3#3;J`bkCIY3L;mM#RCXe@t=NzvWfAy zR|lWa1KZr4*{75_2Frur$WR|+1p#Du2Swr!E1`%}?*9ANq>4q0pO!Lj^M9VS+gE?y z(QQl4k2U-73ni{+8R)jBv}xOJXBg}qQMn|!`h=#xn`+E5^!4G@2HB_SmhR5@=NH~Q zxz)5zTPy#Mlk1Tp4U&|6lsl57z#UI+jS1jfxSjN*N##S?B{#;JKI}Xp_{9(6f@13U zg9o4ef-?fY%g%^OY}5!_G)N@1ua_taRWA=2e_mJJdr=H9h>e9H*7;2&C%gC? zf%BU`+}w3xLA;i9^26L$iw}EPM8Ci2|JMo4Ol4W!*6_4x_I8^cmZ3lVHGMv5q@l?T%~PEqYsDV~@X%9)v=_4|wKkcOc4SK9w3RpHdAokR zaN8%Mgr3`UT*-^Nif7cgapsS%5GmDdj##=3c&sHvm#wC~J) z(GvXr0i4fcRZRiaHF&EOUhRGUQs)}B$)m2j+z&|wo<>#lV!Wb(Wk9K-MGfxl#-4vA z9gN=7;$TbID>AFD*cFy~BhK0aNCbk^5tX6-#s&KmW7CKn)JwWd*$O zZF=0xvk6mp0lxuGYsKS%B!HJ^HKC3_(QZLFgDI>lp8D)}{+{By2c)MU_hMz0Y!$O& zR9q2@4j7dQoIX(<*C2DdaYj6X{=r8nAJfY*`r1qq%W_;DI%fGBiO8py7OC0^ivZRS z#~eAfCv2Uwr!K!p^?9tU6R+h0&j4^45~~sb7XvIrEU~-L9mo^JSf@loYannuG7gKyZc_qImc4fo(jS+Z?%@4UoXPP0s zQN>y{TAuT0qxRiQGX`eQILD)ir2_sEH$IkSv=b`V>Ph3~uvo%&ktIRaD__a%_NHxx ze*soNeR@FKgV(-*(`4e6==?eyZ>V_Ii)UhTo_nlh-LNaf(k4He2)i*bm<9zaYfWK& z`QZkds2xOBBu|2lmGldQ!^X;=cv+VCZ|6sExG!ERucIkWj%9#fmY);Ssr^^grVuZ^ zP!)~@nn<#{2q%mGaIAjM4^YrxLiiva6Nl~vG2)OL`b@;#V~<*nyG^`dEg(|R*HL_2 z^oRV;E2*REC|^w>d=M{_g<8lrd|T}r`8@GDd*{OMhgOTa2ckcOU+f|v3-Nx2YMC43Msk%Q{nH@tRX1u3pY*dt^9UJ+a` zSO%K9M1Kgs#EKU^aLgcl5Kjm(Hxf@R#9dT=t>H={RPP%LK$d18f@BdHq+eVjSdUmX@ZbeP|8^T9_L8cbdAGR8 zG{XG7GP5GQb83l|@Ssq&kY|Df=N9?#gc}e|p$wKHkcmzl`iVog$dj@N&iG$4RA%6j zl2a4LtW6IrZwYeY`yNksLrsVT-xJ0N)Lg+AUB1lo|yBG0O8v-fHMDpzQHjNuB!}7lq#>6x7x^h9S_`C(lYw6$qo@ca3BsK za8x10elzYvUs*dtYX2{&uWbCul2e}pXO%bI8yRcll<&#>IaNec$2s^nAxMmVOP7hq zejMmlY)4%m2h8a%XcVM8Ud`|wv}jn%2!wg ze!y$1#Dz&B=MkRrH@N`lG7v@NC!l^=EQ$!7b5he?SH5!!%w~{`itn7?5Oryv3kk|go3 z{+q;n5a*O6I47SL43-t~ul`%)d=TecRxET*0j3X<2Js>An*<%&^S|btDp8$V`B*Es zPQE$;T|LZLt_r8OsyGEYZylap4iz-}5V#V{;omo>J`a|i038U)2VArAY`|dc{h6`1 zhW_P4$4(^YLk1^kmhG>ud=-%$O#Cx!GR<+t7nZ)8)r&zHA! zlr%&{xkp}lxI6tQL2&~}@cH*WA3kSrW@#`tA$ng#-HhCHq;Cv;!_YbWkFbXV`@$SS zTEJ%>LbdVg$0v&dBa8xRl!#~>m_n>?+9j)%TJ3kPO)~Z(OfosZP!#H+z;mXM;i9?1 zBeCJHuaVi#*a27`RtUg~<5K&qZap!$15L(I-G#v=tH6YkNQy;#`;FpcZy4TO;ZRE8 z^zPwedaT&!;McfGZ|eYz8U`&3+FUEB&?-(!Rd)08YbGgA+B=Q0 zxgMq{HSRNn%)a@Axa=m{nvc||fs(Xt4k3FX@DrX)HT}MqVZ8D$&n#1wp~`yeASI$! z$2FH+dN5IO)^FJn_L2aX!qkp6L0sAto#^^nLJTG$%oO{Zgi_ZNd9R4^0bmmC|J)=* zdXompZ~ljy1QIBn@^fx=XY-RN0Y%5^Cb-90hF2flY+12B!dzWB!hFtev;31~NXztG znrhU`YjT53!z2?shu1wIluKkRf~SfEQMx@V#hrSAP&&idJ3d^CrPlLMCjVTav5oKL zf)tk!oNFs)PFnfMz*o6)iG@<7^r_A=n&xI}f1fay<$5kKVI{2)SUAaJF`<$OmB1A7 zN`~khEK0ZWIari#`$nVe-le&>f7&b5q?$=<+vXo4y+|oJbug;rl)=Y@+-gbXNk@$R z-X8R%Jez&eL87W#+Q*x4hLWVhQKG0dfQjNGs{$eScF@$|BmueMr^0w`lUEpf8^6dg zBHz;5yxP=S9r`}N(xxRxdzL-h z92TWsu9^F(EW@&6%#t&qZ9$UR*M%1eLrRSbVwDoHnN85v@R?0aTZ=+cUcsoss)2$T z|AtcIb}c)9dCqfE{He{_@x!M#9@I6y@7Gc%nUiRp4O3dfH5kFmi;oj75-JcbW5tS` z{h=J6vf>vOFuxV(UIY5=waSAUmK82MzkOx<&;3?bd~gkEaM-v%rorhV$*+3?>-p+I zw6I+A)wK@SN&C}P=47Ot)2l6B!rSr?tEMbwsHst9`g&94|# zk;^5AuXQjb&A+TN{}B+GoX0vO^mN>_v5@(42y4+2X-9lTei)pg5mf`-QQ# zkCRe<@IZ2I9qJzrT%}$f9wryNi3T{qV;TIaH2b1x5P|Y&6U*@%_0iiwR)aE6ooTA> z%Ql{w~G8#2R!v{3c>)HQ6XidR%Zt;Lx zMIS&ECFD3VEq4zpSu9$tD8C*=`O_^+m+C3Xj+ynFrB(Ck4Lo|oA4xwg+VBUhG2yKX zUlTf0FzrMrA2+jZfpl3;O#KKJa#NbstV#A;B4_PG& z*3f6}$DS-~Ou;p9@gO=|*ZtK%RF9unXhoY$nttEF*w|n{WMsaFW?1?g!5W6mHFf)a z5Ai4sCZv6Ib`%$M_JN#`%f>`zC1-OP&!GT<|Dij= zhL3U9A;$*c+rm{_qX!j8ruZb%kbl;0vhYjO)eLsKBkN**?QP&TeGq4Fm=i?PvtU(wj6z#>$C3Bn{uIfmiQSb5b zgJDBRWjz&Lt^4Xt`W}o{mnSWQ9am(`!Nzoy9hp69D#Sg0h=%qIvBhAbvn0co1Z&EE zMTMiuT;0Y`MG5~re*V%-vhkD{zUk<$WiQf8PDw&KIT6z8X6XB0VzAk|Iz3bu+U!A^ z%T>4i{NvTlgqZoQZC<9#wc1|+9xKiCoBVnqL1z>w5R?}&GUHFqsj-PGmGx49obD9l zwvjMQVH$R(d48$nHVw@Eo0q+-Ta|H6L>>FaqN*~l^{NAlbWfd%-|%-35Y#q7i9a>Y zT=S@hEC>-J_~}fYq!yY`kq(biS60k*gntF`<@H>wlLPAqoIpYGd9dCetwrM}ZTQQ;H^CYb`KBeR zDa%}S;s31r=m-t=?7RkN_-$p(oHS;w-&ViovaAwVaYZ9YI;f9efRsRN*GBU| z4U2!{1LgH6jl5@I%>Tf%yblD^`rZHE`nm{<8?d&9u*pU>b%5qgw`+7D6!<0(LURD2 zY0NK-;XkfK>A{18o-#<2RC@zQlU0Jy;V4N?xi)uq%LUn5*|Z%XmDI{=!FR*r9A0le zF1q&Hu+wk-#L%G)9hxQ#)c#MmG~g6n?tKmRUqJ58?Jdhd9eEtXu~<_lYVL*^lYX-u zgp9^=JKZ2Ievv5@*R0i140njJh1x;%o-YmD8fxzm^OD0!u&xm0I(v4)PRGPfw7hGs zs7@=@*URNl8A{JyI%?mY{|zZ!>0IeSz?rC$29zq)x1#Ak)D7DGFAo?R9Bd9Fm(0>G zJE30E4vCFdxH*W}(f&|iI64u{$DC@qy&SglC4evjwXwUTssOYFbF66DBMfrj$h=t! zo~OQ*jLq3;9XCORzEK#H$X6p$m)D^qkYB2Ww*6^3Z}wv9=Wl5Z`XC8xxtaL{yLIFX0=^jE5MrS^L>O$fcn#8m59# zS8K5Qa5PLTnkV2>Wc>0VWq<6PU>miVR9JdC(b^omM>_y+-TMO?%pLB=hE=AuHrRA= z-c@FBEvzinye3j^(T@g!F86M->2a}9gMNuQkaczM?GnlndCT<_p_3XGf?|EJXuP3@ zxA>13l7#|_AB|xK$$5A+QU|0_0-@RpI&t7M$o- zRWmIpA?C?-?rix9*aCdIOx29K{gT-kf(`+Ev0iB4m#5TT`!7&n;>J>Yp|5E|irI0| z9_rQr&KG@=nkyPtJii~UC4IJ!b~RIQ@hDe(itXwIhRWAg31{o%Fj=SU1O;-%a!vX5 z0A&HFs6~mOAQI)W9JX{`QcwF1P}SVuD6p_(B2EnXN*-EoDqV)(C9DYio)Yu3_$-@9 z@5Ino4xJ?qNJDmsF9-ey-s7D?)?}}S7J{ppsCLgN*hn+pip|*)!VX~^!pMNC^vjiO`)pCBM;9!?IG z+WUW*6AUvE@B#bNA+*+^z9941TY%+3z&o6H67Xr$4672}^fzD9&Qw!fe*O;RW)Mdw zEQP&Vg9ySf^!cjyADy0;(%d@+h1lsS&#i;_{0>S+C8riP14EmQ@bDy*yWv}xo^(3x z!JCKXt8!1|qj5?Dd%S;{2rIM(VUsXF`ElP=BtkvGrV3GFI?yOJzoeph)Li!LMpbth zmjMQef{eju#M1611C{6)1MFAxo~d;veCxy|SC@(;@~8urXmRSlP8qDtY(H#(EgS{O z`CA{K&EycBX0{lW*^EGK28QEn~zFnGLFi?beC|Ei^&`zwq0A|Hqmdy7ToZ^5#?zx;Ktk<+=`_qK6v4Qg!zR!aM!1tDkNcYQMe`Vgn>aKM&r@O1O+IQ z51v5@AQwGmA;|CGZofJJBo${q?db7k06J*n1N0H)X~0_qx&bC0lECH=OVFTpJP71suWaCuE8wG8A_8+dUmb1>tI*L}v=}LZXa@rH;jL4E zT#S~dWg2$S!UjQZizA3`UK1hvxNR$JE@e#+LN2VMd;aJf2|OQi$G~oD+}zTnpMKNa z&RaZ6z)DgIR8F%T|K9gH+WBb9<> zZXv^kkPF5)!*bA+NC>%tYzQT6C{%rIY|u{Crd87W_55%hv|%DV-!gZx1mvv#-I5bc z<0i@h& zcDgp6eiMln#iPN5-gt=G0=XBbqV0$L6`s8 zcfl{ZWrbLhH#;!lVW4^K27$X8DvtR=a=BStACDHoF&56f`eZlXS3AaBZ6~Sh8#FaT zFX9O4QF`E3xkffT#=>`fQH;xsGY9DkYvw^qYoH&}@L0j9@3*P;qJBPjtzy@**1ud2 z4_|Wr4&s*Tu||RI6rb0UlpWX(68+&Bo1XH)H#aE#9A#FQXoCB7@Wt9RvqlGhoJyE6 z7MZQAB3D9dCe~)d^M{xfpI48+G3T8w=C2X8HnbT#jD;3>t?6u9#s$Tze_>&nI=<|; zt#Ul`Yw9RDl*+u{Z?spm55AxI{q+s=!y905fHRx>#3k;9Y=$oez$$KS7SHcxoh;@< zN=5jALi+J(=~fueV#ldcvPbjrBu{SYP5L}{@f|v%?WF=d!TO(vj1JdB{|%$F6h#&O z_8~00p%<|;4@bq$9cQCPku7QOTEi)`-@WiTiQDMDV*CweCp(Q(8z5?ZW~mz_==ek9y_s~ zZ|$@1QWkB8$vRPF-r!o|5pl^B=I6IU9MMy>dVw*hNd`4OwtOxSpt3rkrKjIqwdk0D zNGhS37Umm5sD0wfJFog+NXS=tw7Hg9Tp;Ypn{hy6_;{LQNmo%h2MK zJ{DsKvm`_#$4&LBoWZhw0tLnA9h5}_he*Sx*~%A5juychBkvr%YA#R4#!+Z$e?C7n zeg+J7!cYgiC^PdCb5rVV>524FN>=dJUaV0a9oS2T$2^Qy1xjxCD?5UhllgUf?3$G5 zE55EtYzRTX-LWYd66+OAmy1?p_{9a!^A+~VAh?eIMSZOotR}_g5WW(3W2S2RFf=B@ zga-{1c%t+WA7x03hPF4$W;KcmI^T%9qYwKAf^P`rUjaXW8YU@>nZ<#3LmGRR(8#qd zH8Sv_I_)GhJwor~gn#kkHoMo)#}w+V0ux-<8Ykm&lRh2)J}1%d+YxN=H&Zf<6^uSi zy(v0GM@aU(HVot3*w0=iRcZjjLw z5{@m?FlykgixE-;d$kZXj;CfQ;Xa`$;u8!#{pi1!l;Ivx-jX!!>v#Huk@bu9DnsYz zSE}2cpWO@v&iB^U5KZFXsH}xyavDykP{5$Tu-D>Rrzp&Z#~c8EdKs-M(eV_Ihk z?r?!(REk+e>;e%So>eaQH`6kFj4Xq72|ed0oLm(&0LfUyldXbN##cUyKHj~>;-+TK zG(_WP)?(va+usq(3MX>U5A`vXHRZ29ofZrwd+#^8> z108|=5IygSPo1Kg578 z)Nm-z1pB;_Q?HX)3%L~y)Gxl=H>1bC>+0mhQoYr&FSUIBBPavBV3y&rE8;*1=4GD` z^wqetJ>O^YsQ@Uk;-0~(;?Rp&zlwL1;{o?G36qvJJEgJnBqXPVTi1+%=Yb4;3$dN- zXzxC3#qLmq>i$|U=wwE2Vi2FOXgkkKm>0u`FX2J+5t%Exv%2u#Zy&QcOAvHH^67_r z1GIc&+1gXeQB>V`%2#I~Pa)VK0i&Hv(L(zCp4Ditcr@&eC!Q=mMdr7A+#MeN(N8N( zH03crYt5_M829m?%P~FoSPY!QMi}n``yW6KEHBGzgaTR9t%mmrO~Se zSvkna{hWG$2?~sx5-oJ+AQq|(ujifi#oh(O-f>FF?M0&mH9GO9Fz=T4nj~=U{NF)K z5+7>AxoxPwR;qK$yG-U~3ke(of!E3zGit381;d!3djj+K`KYK z3F%aK$=mqARV9!LWEHPE>D16Czn1>knjv?ua_}l2B%l8kZy6{0?Se%L+R| z?82iCCG3)E#?6u)0t!_N645ZC(WUH8b z$8&}LB~oH2p%nL8j23~9!0Rp|BU>yd2NV`Tv`0&|!%VQEf@Y^&X~0{;mk}s0yhQM$ zp?2ZpMJHx#dGQy#shxVe0hT6!NJ7iE!~&1O=Y9InNH$~C5|0h8ijX`%R!(f?ldW8M z>KR@!7Ru^w55#CC_y|n$32XT<+{f^zHRU$he^KG81VD&0jX3eBP!+~CZ^OgyBfu;P z^oJj;wvOAM!1*(YRo(%j&b@9dtHv!!_2;vj6R431Lvy0TJV_s&sHdH0Amm0olD(Ybaxf^drIA|~C z@8Ug=i~MP!xuNKt2=I54-}jA$*~7!#O9#n!SQFr#tSfQTd>REq!-nf~xuvB*Bz184L;0~zI5{^fmDu$cl z>p$XJND}@M*x8pTxvlJ-3)8-uou>!MyBUiiuMi33D)bL>A%9?^lnf6x`HIw6d}lhU z1@qe$5?Nx-E}lb1Yt+g|D`ICqd=ulBdaV|ii4JVk;37IqXjc$~$j~VF4PwzJ$n>~9 zW7PsADo<0bTqaU+K|$!MS)KO7qEWFQoKid5s?)=yGyjF!bieA{V$V~glh12Qm#CNc zqpllh-U$5teID$U(HG}!1RwA8#6K~M^L+VZZZF2&=+oKZU+z+S8uJW|*WndEYjd@F zGzblZy&SmP!@wVFH^A#UsoRFb)990XCQF~0s5R=ufrgI!N1xZF2X@9{-ouX^K#T}y+l_e-dN>`u(v5q0hEmZPKF9-D zy!fwuWP{F~!gkImNYbvBf5S8v4Uf1N zFwS5E%p{|RCzGswT1L-%TQSv2SpO$#Yx^+o;bprhsU+8KFe){f%;y~d7B^t_A0?3) z5X>#cJkF}i&_8&^Wp0(H+7EUL679oJ!s1*2%N8;Q=pM7hS*CbT^AFmvqDP{iX?{JK z#7z?&B6=_zr|X_NA#sMy^j?i9OWIB z7faV*4m;yJtO4jPQ;ZscJ|aTaSKfkkM)J|9*AI2FE#BG)8(uh=kR{;PB63@>J|Y}Q zGC&M~#`G87N-sj#{F_Z>5CBUS|M;+ITm3wIgsez&mY&2e}oeg7}9bBFDfoS2S* zWv(N%d$-#-#fl|9ARiJ2wV>EBQWlW24*M>UO5_Qo$a~fwlnhV%k!y1H!}I6If;A-XtDA;FS^+XX4F*8L z%lFRuM)W>rDjyDTSql%vov1Iwwil%x8<@4BZAfI<;FO}zia;-GN!9Qic(RMxseiez zK>6dBBl5e(Y14|jPH9?3%!~d<}ZVc^c--mzkRkOw6H>xvGQpE+IGbG1f+<7=>!(n_-B7fW@6?C{POWt zUDM*p;dzd(Fk&K?W{(zC(bsh!qC_B#3*fmA!%<*fIbA5UPhRU#^Q1TzdmIafegD4e z)6jAxMIPEKaQBMpGlY-#{TaPPh_VcxHNazBzpm}Uu?gQ|rM1kkq+#+jn30I6)kiy= zT2q5=XQ3o+6hJfwGmgNH*9&F)@(;^=(@|$r;5&B=7K0$OR(R1Ir`ESKUS{Rn3l49RD8$F-# z@;D-;@)Hy*X6kCM!RR_kbHLa-V9-icgN++oCGcS2((G+V;ivu~EwVf05akpd2$5LtbT^ z0salZs0gk_E8qx#A*R;~BN+e&yoifJ0zb_107F=?_iMHo`Ha?b3p(Ng`yk{-nRVP; zEgqSjV^4_0#zy<0LYwU9UNW(kG{xCwNm(M{<+_VE4rlu+*sTumeJ}qx` zTz43<%4ZKyI(2rV#9A+@Rt1c~!f-WYe(7Vrl?foaWr?;98sjvkcO-l2SL+}l2jf14 zc$*y$r@qkd>ExVO^KyH8g4&bxd|@fem%WO6H);M0l3`856>hCB=RpINy(UD`>tglh zWTD1K@A6$x>an;{UvVw!`u;nB%;ETQ?yPx3T;S6WFWkci&9A06nHWPiX0Qz{=A$!+ zW)@0VHb8!sx90pE45`S;v=)JUhWNH}gz-Kq8qRw<;y+^w69%b$u}2z8aUMV;U)hO= z71n7BKtd_SGHB1Tf}jPz=^-QZwy2*h5K|%{N3Axkd(d4D)0ps%>3;-thYs;S5V?j9 z@jq~gRrI2jqQR8EkqvUcOxnhPWKO-w<)ZFPco(|{0;O4LQv%(d8Ow=F>RQ946$N%r zE&6c9-dp-yExdwy>&a{VFOQ4%&VVOR`{r?Ld^>v^xL;0mSZ7+n3%Wd?qM5Bb%fVRuKcJ_!dHz8B>o2j?i`$eF()TZsC2J@{6bZJO%*Z?ut(Q;^wR;Mo9}}ga)8{gD z3?O=?6cIqeDx%P{VmP}%a}Na*2h89%sHvtQ1)zq$F6}lh2wgP0NHMDe)gOk3dJ0w0 zyaUX2#1F(1vi6AP;NRv6L!W+Q=+w(68!YxlL-mV?42JZ7rJG7IzgA6>Bmu%~@wLQW zd=5+t>Gi7JeBH72Q^OW$D2w}%Uer^?%}DB^az1jOHBeb=I0;Gfuis=`;#{J>o1|7R z%k1#G8?6=6&Fxtn5Z^N_fIFL4FQM@PbA}Vgt91I^_;n|_oOBWi6$>BjMYTX@=7sXM@G_tOx zTVo395JLl%{Ele8cx|hyYJ$R(U2y|d1us!T;Ro;8{-}JM`-JrvM(<$Es&=68v<@$) zZhk*H{Q|1Xh!ob2nTjQZVP7rtN+>67g%(~&pRy3kM-9@Jq^*wv_vN4g6*N2xeQ#JV zGQWD!>EMu$mNpC-xEd_{Fjlr3Rx@Pa|9cG_p0{QHY5%djgJ9;*RS$PhMjHYNgpnvB zWXBb`QO0NGknEvNEhr6IZq_``eVavpoA($dok;e1nx|gj+xfZ4N#Bipdhotg?%jI# zFN?YKs`;fdi2WX7R{Gw~4cC=fzMj@@!=eQm@S#O=AZRHeKnuICk^QT^x@a%KNtVLM z`3H!KUX)Y*!u7jAVH&uVHf8Z+BR>q zu!?BYGzuykyJ9^r+MVpxAf7rhG?2947%kVri$z8QCB~ZXa5WN(Mg1BfhCY7iv)0;%_vexx5%r`i} zvl+CwOkCaMe9yg~#(A8?@a_9t=-%@$_X3`LU|#JPS=-YaxXSE#PYP<4Z<>M@K>X_hbwNt5n&ZvBk{ zjf_88cI-`Ie%WRT6B%^N+Hr-hhBfdeisy@~wc}7zwcLir2@hW2wGP+jT^zgTKgI-v zOvNX2pyJLZYcPVKNeSD&;5TjnF3+##^yl(v2C!OP1oyG`=tXNGgwnl<*|{1D4aQ6j zOA2aoUpX6Uhx|m#bED)Jy1-~eivM2-_oFSLY$m|{u(|+{@9{Fin!tpj*cqc*6B-ZU zo$OHOE>e?WyJ_(jR1PSB@R|??V3<=YNYzB$reJJgxQ5s(EyM`6IEELt7Wt)FrrxNL zk8=O1HMN$M*0~yH6ezAcjA22=hQFX$oLsrr80*A_og*+?jw|$|+}b)@m);I+%fV;z z(xJNSJ71!xmOsutX`txKtEmq_>=my48=e5;(Uv2hVV)4)Eba-c?E+6YjQTf6NAEiU zH9*vWHDvmtY3%<`re8v36mi#da&ov|itZ;KQeN9SwL%i@k|b1(MM~ZPLZ9-A&XApe zy1jLySnMTwG3c4&|3yizPO;YHGTnPF*xq_#DcNGV@)dgb=3KL+axE$uZcyrSj$iB9 zqsY$=6*uRS2NGWwN<6iWTXy|(0lU(j+nV-B^l=U7dBGEMK#1$tXY1)+qp$f@1}*U; zd@!LLSNJcrEH}!=AYP&vlv3SJ1W;(aRdY{8<0)tlN%K2WMkmR8`+ZniQSBENMM0HA zGugeyl~*&^GVCpU*cng(sYwpq8oy|gbFZ6t^9BL&p`h#S9b|2_k(M@55$&2Jd@7Oj zPennj;`27lb#uF&ldG?6dG^VfC+R@r4#2)H)R;5iWiU8y*g*5(#eea*`-uoM1(ibx zCJ!Eb_VcMAxi8hMqknbt%xdzZy(w|;8+hssv~-974lQ*-@C_>%vq75?_GeOHqYo74 zV5thEDWp_1dwW~EJqsGcK4>wn2qM%#s*O{uWVZjfgw5}R#)@|w3Autpm)`jc@0;t6 zS{D9hgqBeXdc4Ie;RxlQ<~>Fzk0dm5+8_S46rOa0dP-T_w?fYZTGS!$RSO%E03y+n znkYpJS5FvbIb?R9;=hUZ(xi!>m7HlN4Opy|@oAkuv%0=}uDI~gE)+i6Z5AzlTADGI z5^T8^?M&T6m<%GcOStGbzRe4rU$FBmsq%hC7@2Fm@v1) z<`g5UL{U9I_z$R#eVXi{JL$o}nnEqHwqtdDZACr_2E&F9{)J--=rd(_d+A{1rixjy zh+{&R+RB2*@{}~oYXt>gg6x0dQg^fK+I~yjr;^E$AkF{vJGJA(!WNLu?>s8+c;m&yhDpS8W(@$fky3z_S2r+ zYtKI=bidnI^=_B(=mzuN_=2<>&jS+M^j@2IJ!_Kll1`|~ecKb$nX{Yxr6;EAgt=Yj zZqDaMPPe;bjOGt@rS@E^anO__ce(G%4-|*xEoUYxs9T$+PM5v8o8{ANf5?XOaD-~z zYSYqTVG=*w8MY2OAHMssDv~lnT2|f&{_yFfr*0ePiG6RHb5JUk-OYKW;%KIydv&Ko zgWZ1R;prD5wTi=XDx_bw>W%uSm!!O6wpOb5iR2B5o(T$1wGI4SVkXSn)H_efbl$6M z?Zu(R*|1PdK0nqmp)lStE3vAbQB!$2sLJbnQM`YIe!SXFyVle;^TNh@o!4#V58NwR z_v+6|8F!^bZvX7?tL?lwY?Bzx9=U)2mt6kn9HgnxGOXZZ*xetr?!TW`cXXJGbD)G? z;Nc}J>?$42s+doPJ>Jp$+isihUfIM>rwyjlm zyXfnxyx33f>e#;urkmI&nI&TY+wL%F@_H3+8}~hx@rL`E`X$!g|F5v(VPTPZTB$aw zPA7|>X}8xmXGU@-D{$Az@eo7N@dw#<)Ngop?=;sP2Br=k@Q17AVUbEJ+Oj?yX_QIq zZIe3juW4tV9!MW6k$s(^F#P@`0wjITgP%e*IpsMP5J^%x8~btq)u?+osNN8Qs$1n| zzbdas1#RY>cdNXfeF~;06~r?=E4|nsKI)k7wP`h{92l`P9D%CK<$a2^dh$xDPPswN zze$Bf4!=hWOC4?J!iqh|Xxzm|Y}E@JLsOyWchnzkw=Cr(rKC0C4}0~TDu(THqg2hE zqjx62&Ts8&$(#G+bw|QWxoJm-?Q0=~grdW5ZZNukvC-TP5y8R3r9??e8qjoO1&*et zbp>eJ`7%Zp(6k}QZtx30Xc}3c<2Q8hLkHi^7_#{PB-HGNy)n01-p3T>$nd~xs~ON( zjG3@jB+uMule}eiQuU+4`096d>=^wWcC9Cps!mqlJzHax%nG(~T^%?RC>uk+?^Ds| zH=uuT-1EP<_qkBtn=J5X?m+ZXv%`&*C?}~HV2{}7UOPaJB+RZ91e zdy`+2_)@>mi`$`6ZL5DdaWR3$Nnak(cKKu*%O_Me({E`WEUI45+)Zz6BcLV!UvQa^ zmXm*W2ei}=p~u=JG4ED+-D`h&f7fxx=t8||Q)ea2wFx?N$M{iUWH`&=Kk?;}RyGcu z!DsePTj!9YvVNYVk9V_->Y17Gz?fSzB}n&fS-yvLLXo$h>QIvudBptb1|tc{rwW_2 z4H#$1yS{8EKi+GXd<^cOWFLzVnda55C6E2GJ@+bOr^3s3VH0y!^a9ldM8|^?zsq`fwxiBHb{p*WSbR-kH#o-{R>2y-`pV3 zeuvOEet3l4Yzh$;_6?8H^z~xznJ+hq=`n62)_Lhf zw%={OcI)AkW0`WlJ)8U9WpcC%vJb?2!B{%?7^M4kV>G#~6k?Ae*P92JAyzRmo*$0y9cz#Nj}+vlAzo!t@U zo4U5smsA~)>?(eE>P-CX`;2Axdk|n0U{KM}27lalq(n2-MhMgFQPlcHoBEU5cD+1{ zg$cFwnJZM~+7nbZfjuO7J}K>T8<7fWf5L{T2V~Do-vE29xN-s>{pVD=#}!{eZd_frOz_ z3GqHS-F4-C-7}qEhw~zdilsvJM;#oD zRX}*@44`-SmY|Hl^J3dPv%O8Pmtbf%Nd$p+02teqdqA4NT5iijcg`XEt>ex6MU2%u zkF5JG8Da0_XoS7frhY5VNl;Jm_ST+c6R&$+ z!IQ}7!m|o$bT;SAWzex1^wkts%TP6R=WxGce z-4kcN_m1`~#jSFk?Xk=-N2Q|p>T%qrm@^-nJHnWEYY`?fG+x!wZGL+;EIB$j%~!}&-~mF;+$lO|`k~EDxtfU%{{X(be`aA@eFx8Zs{=#SLg) zv$d$c{MaST(fs6+Rc9xm?6SHkv5MQr?Wy9dNd>rrXYbHXiyo zVirDhazY9^WOGQ0`0w}DJbO;FTK`-qo8YZU+-`1X68FO9?RTl{qTa?LlAs!_5?~Ts zC1w9dOxH&p_)B2RkTq8M6Bw(;Kulz>YxGyjiUV=XP7bSfQUC1XDM`pNgE2M<`aG&h zZ)4!}4T&Q9Kk*9HKudf)L)&r*dFi2nbdlN9=KljK56pJ|2hoA#ai-Vn2_WWFZOT2@Kfz38^TXJaBct% z%qdp!pK$R8eJ+WgBMP%HKNo%^gHpW;Pf|P{$JtI-4)G)3?}0?Ndln=4&qel0=r2J# z*s8?PBmA^^16RBv|4GK(5lf}m2BV<;ZI|n9Z2u2X`TB|vV`vPA~HXi3dMkDHNupzZ5~fP{#n@I@T`C_ zTZMgj`U9-%0kSVp{$`a6e;RAWKq<^y|FKB;jtsX3`MBxYw-im6X8kezY?YrVNJ)d$ zEQvV|mChfa(#id@o%0^vdUdw2V{GR%$5tU`Za2eDpyjX6mPl+BHf^w{5B6O(EEt;{ zRO1Pl%8uZBCZUf4e)vIx6hC5VM;WVFm@53+9~3_HLGpuN+0Y5e4xJF5kpDM&S+@%- zXCa>}2=f}qm%=*ITT8L^W)k11h3|5&6XpY&yf`*A*@9~;u+UQNT<;jF}%y!_mEPk+s zx#httO+z2SuelAK#Q#+%5zs0m48mjqi_=C(hv%LsdKY6KWRrY#b`q7-hB`HIO@ju1 zX}Gx=DoERb62`cPK--Sn2q_b#U}Ed%plpi?YYGJ2qyy#~4Fl&Js4jjNFT3DvTFMLIyRjQuT2IS3Hd7D=Uz`DYaNOd`=7U{Bov`vTa zh&dAp)vLRxk2R#H2i>_+z9|FxKa@_rhwf*kQ%?s^IKGL20j=(ad~Q0BsiD>qrk9DA zMQ$6^{IZbn|K&ov9Qr*sHOHvr z>ut(2&Nkzz34n!q0ApP#ye64FGoS;qo~N4x*sU1)CP7!{&^Zm+6F&PvRO0@(_}wd3 z(D!HiwbO0AmtN2x4KQ}2#1Dp?!`$D@Ijmsv{d%1S2INIJb-;SQp7g|=IZ^5pfQmDC z!!pD}8=wyRD7<-@SDaFP2%xv7t>X!)A@IBlzmZ$=WNYVy$bRi|*=D7m3I9C4w1q;n zsVSd4TzGd^hZ<~WxcNPreDRVtj%W6{RkF+wXMk_LyFT02W2}^*8~m$@c0xAfK3Mk#iI4YoY>7W!* zil|6$Qj}h#1(M&lcM`G_;*9s6bMEu}?w#|`oM#@LoxQ)c-u13`mG6JfveZY7Z!BBd z|5>MzxfuymiylsQX+(9?rwO4)gH1rA02p8x>)J3O)D8x|5+LxC8=l(?(ib_I&sbO+4wDiCeX(vx187` zLRQV8X+FJ<-0RSwjCAe=XhvgQKViOP+7!xdqCRnfaucCX94hQ23~<(Fk%rh5*}I=| zgGSe4QbC6zhY^{PsbE^t$o8yX#B?={Vi=TPp@pI8yCW9}(|5Iyd_)+8tesVSx(1ru zgL|goZmkBP1ZPKLPn{KSnK1;_el(%_zhfg%k_Xwy`H{b~kz{Hc0o;~3msYmv(vc#* zYH1(Zebm|CN#IQG>w{gW-I36%oB^_?388KATS=po+xkkMT_{pT+LgH-IY`AhDzG%Ll|kBm1}tnn6v*?)FOucmT3QG>w*6g`B@th|lu5a_wUBq6^LQ zt%o{V9|6J>T0`u=oIl+|K@~_p5~_8M8pDHT(x9yk76l+*J_lO0NRzzN=b%Xh;M6U1 zRb(TEJ?|1N^C5{9(IN?_;>gh*!@LY?x|3#Mi|I}y_Ss@iXr$gCxdl~LG|va+-B4U7 zC;~N56#v&hSgjN*7|0-(hAg(h&6U^a8NieVu@%tb7?-RK$*9Q^F^oHyHw0rM$pOHy z6+j;#BsJy6)j$dgG)e$0{COcKm^WUW>|{POqfj)SE+Q zXvR07CfYlve2X-6ObIQYqmg$QIfRh^MZ&}#T4*7E*icAkPf*mzU4r(=EA`Qt>$UCO+$opc@1xCN> z-Ke5pH9TZWAOSObYuiuA@bgMCmifh^?;_^yJ+bzx2@{ z)}~VZXc6(zBG7TpOK7z}YaKY`2yX-+kH``D+A&JLb}k#sq@o3gqYxVCn+u;I#kJrA zN(pRUAitDLC{2iGOT7-yy@4q-WSQMEG;4R_R;^l5elVYPi4{ytJtj`QK{*_0#+KAQ z0sp=%WeTzqS=zcGs?&-Td%zZn+S$=Nalv3o1A+yk++ykHK9d^0cUpP_D`Lcrc!}}vS~rn4#e=&9A)K6pk(CO1Lxp*cL>3{VKGqa6mxO|J_(Iq z6PZKGq#2mhUX+-CjQ4;RxzuJj+fA6F5~s?*8<$iJ`SIU!Dycy5o&^fFubMFR0W7TA~9qrOu>l12O_5n9Y@V1=bHH=(lx$!Wmm z41qExxz0;nGp)cl%;$QC9nK#>GyGD9_1PL~yM{VQaa|+0>xSPEngFBo&1EJfjLc)XuG7n2Rl~jd zU|8Z2$wtE^(#XKj)=rMj957)x8P(aswl&_hAp>Z;fDKP{dbWuzwwuEt9n2Zhu%>d6 zW_9Ao5QXDGn>lJ%if+8pem&Q)_IxHZX9#5{i$2GBm-N$CijU&RvytYY1s)!R1j1OPcX4W15xSUJhv zNF(jAyG^T+c|r+HT?A~^)gZVel$e2y&%{laFZR8|G)eT0o0Qk#~_$c$)es|J?*htwTJ8!svJ~TL8@?L1|nQ$&!VX7k`>w#{wal zgvf9%kdZ(<2@tBj4uPb(W_NiE)Ra`vx1dCt?|{1n74>KaxpyzF6DNA8oD8g|0Zs;> z^Ov2BF!1^Bax!4Mh>Tl~fwwqI-~UAa)@Eq-4d&!z3nm08__O=msw>2G@VG-opQ`Ku zZmvty<;cAczC|3gLl`Si-k_Gr`R>ALHQgtRnM$5MgImEbKKk(6f9cWS^brNh0H%H~ z=Kz*8qWj`rp0ku7+W-O6;f}_6sRy?giX}#i0Dp*ZZ4eV-7ztb4xC1+szY7epd|#9g&<(&z)oqbzd^?(5cg!elXcaZ+Qf)sEJS@u zVLMHmBQL-}mWugSCQRh>t$wH9&7`r|EE$O%c@Cx?iE#=}B*|b$_~dXHY`3}n5}c|i#FmwZ z=fF`fEG{%4ur+JsbN-JAWZ8Bn*}Y4xt1QGfF8vWT8%Za<9Z_{P*h9} z@kz;;HQGumK#-@EDe;ev5`=;qj*Y4ng06zaB?qv|hyVqI=Zx&6<%Oy&$5UygH#`(x zcswuDuW0GBkuwzs4dRyPzVUrkyW!J zUVdp;A2~N6EN6wO%19UxuYQy=D&O%Knnhzb0{RU zM)1>k6TG32X7319%pUT^ykcTQOw9e9Tjl8jwek}xQP447>Cc`FL{*0OHIii0QIYIs zdc4~*9>lyLg7zTBuizRU1{8Sy?9*3j(y=~TPR=|nh z3m!pLOGJ=&^0CYu`q?9JRrtyF*(FViaO#bG67(|v+LOR)9o}+d^3p{T5zVYgIKaho z{CJ*1DRl6NIP-I7(c%5s!Go=oZ^nKjm+-&_A2`b#Qh@||e*Tdv*hzkV;E1Gwd&ke5 zq-|Eu)eEuwlH~1JPDtAhc!O1*uLsQsKj*iI?AD+TR2}0u-q>S9r~qYYpXUF%V*z4& zkKl|5v|6mBOIv`-pcj2+NqRDK8XPA8##8CuWq(9iRAa^)@ZV(+V2tKEq*OzJGUH=V z(%+C?r8KGm{@|8?H(+4?$4YqXGg7LD3}8uiJX!@6@Cc_=r&b91!Qc(YwCl5A|AG#r zWS!3JLbksNRZxo;8a37lltU7CI=7?6#;ef}Ky4}h*0Vgmtn(Gob*tUDyx zP@S3w1vvcLsr5%&Z~&%12MYW_2ln7;v-tr^CnlBq zmk0nIk%{Dx?d+og{sUwbhb;9SiefgyD-Q^6pip>@(<>Bg&N^T<78i`k2O){{gulut z=atD|KKWh�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 literal 0 HcmV?d00001 diff --git a/docs/maps/images/camera/with_margin.png b/docs/maps/images/camera/with_margin.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd057ea9bc4ef7f7f2ac341760d4fb087795fa4 GIT binary patch literal 52330 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 literal 0 HcmV?d00001 diff --git a/docs/maps/menu.php b/docs/maps/menu.php index 0bf0a7f9..10a2f4c5 100644 --- a/docs/maps/menu.php +++ b/docs/maps/menu.php @@ -51,6 +51,12 @@ return [ 'markdown' => 'maps.website-in-map', 'editUrl' => 'https://github.com/thecodingmachine/workadventure/edit/develop/docs/maps/website-in-map.md', ], + [ + 'title' => 'Camera', + 'url' => '/map-building/camera.md', + 'markdown' => 'maps.camera', + 'editUrl' => 'https://github.com/thecodingmachine/workadventure/edit/develop/docs/maps/camera.md', + ], [ 'title' => 'Variables', 'url' => '/map-building/variables.md', diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8635b25b..5ebca15b 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -793,7 +793,10 @@ export class GameScene extends DirtyScene { const focusable = zone.properties?.find((property) => property.name === "focusable"); if (focusable && focusable.value === true) { const zoomMargin = zone.properties?.find((property) => property.name === "zoom_margin"); - this.cameraManager.enterFocusMode(zone, Number(zoomMargin?.value)); + this.cameraManager.enterFocusMode( + zone, + zoomMargin ? Math.max(0, Number(zoomMargin.value)) : undefined + ); break; } } diff --git a/maps/tests/focusable_zone_map.json b/maps/tests/focusable_zone_map.json index 469b8c6d..8a9aa6af 100644 --- a/maps/tests/focusable_zone_map.json +++ b/maps/tests/focusable_zone_map.json @@ -150,15 +150,10 @@ "y":0 }, { - "height":128, + "height":146.081567555252, "id":9, "name":"chillZone", "properties":[ - { - "name":"display_name", - "type":"string", - "value":"Chilling Room" - }, { "name":"focusable", "type":"bool", @@ -167,14 +162,14 @@ { "name":"zoom_margin", "type":"float", - "value":0.5 + "value":3 }], "rotation":0, "type":"zone", "visible":true, "width":192, "x":32, - "y":96 + "y":77.9184324447482 }, { "height":416, @@ -194,7 +189,7 @@ { "name":"zoom_margin", "type":"float", - "value":0 + "value":0.35 }], "rotation":0, "type":"zone", @@ -203,26 +198,6 @@ "x":736, "y":32 }, - { - "height":66.6667, - "id":12, - "name":"", - "rotation":0, - "text": - { - "fontfamily":"Sans Serif", - "halign":"center", - "pixelsize":11, - "text":"Step inside to focus on the chilling zone", - "valign":"center", - "wrap":true - }, - "type":"", - "visible":true, - "width":155.104, - "x":52.6352863978128, - "y":125.784444486216 - }, { "height":66.6667, "id":13, @@ -286,7 +261,7 @@ "y":0 }], "nextlayerid":39, - "nextobjectid":14, + "nextobjectid":18, "orientation":"orthogonal", "properties":[ {