diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index 1ee7d1fb..6a76f870 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -17,6 +17,7 @@ import type { LayerEvent } from './LayerEvent'; import type { SetPropertyEvent } from "./setPropertyEvent"; import type { TagEvent } from "./TagEvent"; import type { TilesetEvent } from "./TilesetEvent"; +import type { UpdateTileEvent } from "./UpdateTileEvent"; export interface TypedMessageEvent extends MessageEvent { data: T @@ -43,7 +44,8 @@ export type IframeEventMap = { setProperty: SetPropertyEvent getDataLayer: undefined getTag: undefined - tilsetEvent: TilesetEvent + tilesetEvent: TilesetEvent + updateTileEvent: UpdateTileEvent } export interface IframeEvent { type: T; diff --git a/front/src/Api/Events/UpdateTileEvent.ts b/front/src/Api/Events/UpdateTileEvent.ts new file mode 100644 index 00000000..5817622c --- /dev/null +++ b/front/src/Api/Events/UpdateTileEvent.ts @@ -0,0 +1,15 @@ +import * as tg from "generic-type-guard"; + + +export const isUpdateTileEvent = tg.isArray( + new tg.IsInterface().withProperties({ + x: tg.isNumber, + y: tg.isNumber, + tile: tg.isUnion(tg.isNumber, tg.isString), + layer: tg.isString + }).get() +); +/** + * A message sent from the game to the iFrame when a user enters or leaves a zone marked with the "zone" property. + */ +export type UpdateTileEvent = tg.GuardedType; \ No newline at end of file diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 8af0949f..2406e92d 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -21,6 +21,7 @@ import { isMenuItemRegisterEvent } from './Events/MenuItemRegisterEvent'; import type { MenuItemClickedEvent } from './Events/MenuItemClickedEvent'; import type { TagEvent } from "./Events/TagEvent"; import { isTilesetEvent, TilesetEvent } from "./Events/TilesetEvent"; +import { isUpdateTileEvent, UpdateTileEvent } from './Events/UpdateTileEvent'; /** @@ -35,12 +36,6 @@ class IframeListener { private readonly _openPopupStream: Subject = new Subject(); public readonly openPopupStream = this._openPopupStream.asObservable(); - private readonly _openTabStream: Subject = new Subject(); - public readonly openTabStream = this._openTabStream.asObservable(); - - private readonly _goToPageStream: Subject = new Subject(); - public readonly goToPageStream = this._goToPageStream.asObservable(); - private readonly _openCoWebSiteStream: Subject = new Subject(); public readonly openCoWebSiteStream = this._openCoWebSiteStream.asObservable(); @@ -86,6 +81,9 @@ class IframeListener { private readonly _tilesetLoaderStream: Subject = new Subject(); public readonly tilesetLoaderStream = this._tilesetLoaderStream.asObservable(); + private readonly _updateTileStream: Subject = new Subject(); + public readonly updateTileStream = this._updateTileStream.asObservable(); + private readonly iframes = new Set(); private readonly scripts = new Map(); private sendPlayerMove: boolean = false; @@ -156,8 +154,10 @@ class IframeListener { this._registerMenuCommandStream.next(payload.data.menutItem) } else if (payload.type == "getTag") { this._tagListStream.next(); - } else if (payload.type == "tilsetEvent" && isTilesetEvent(payload.data)) { + } else if (payload.type == "tilesetEvent" && isTilesetEvent(payload.data)) { this._tilesetLoaderStream.next(payload.data); + } else if (payload.type == "updateTileEvent" && isUpdateTileEvent(payload.data)) { + this._updateTileStream.next(payload.data) } } }, false); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 120bb303..33013454 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1,4 +1,4 @@ -import {gameManager} from "./GameManager"; +import { gameManager } from "./GameManager"; import type { GroupCreatedUpdatedMessageInterface, MessageUserJoined, @@ -80,6 +80,7 @@ import CanvasTexture = Phaser.Textures.CanvasTexture; import GameObject = Phaser.GameObjects.GameObject; import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR; import DOMElement = Phaser.GameObjects.DOMElement; +import EVENT_TYPE = Phaser.Scenes.Events import type { Subscription } from "rxjs"; import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream"; import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; @@ -185,7 +186,7 @@ export class GameScene extends DirtyScene implements CenterListener { private characterLayers!: string[]; private companion!: string | null; private messageSubscription: Subscription | null = null; - private popUpElements : Map = new Map(); + private popUpElements: Map = new Map(); private originalMapUrl: string | undefined; private pinchManager: PinchManager | undefined; private physicsEnabled: boolean = true; @@ -910,12 +911,33 @@ ${escapedMessage} iframeListener.sendUserTagList({list: this.connection.getAllTag()}); })) +/* this.iframeSubscriptionList.push(iframeListener.tilesetLoaderStream.subscribe((tileset) => { //this.load.tilemapTiledJSON('logo', tileset.imgUrl); this.load.image('logo', tileset.imgUrl); this.Terrains.push(this.Map.addTilesetImage(tileset.name, tileset.imgUrl, tileset.tilewidth, tileset.tileheight, tileset.margin, tileset.spacing)); this.gameMap.addTerrain(this.Terrains[this.Terrains.length - 1]); })) +*/ + + this.iframeSubscriptionList.push(iframeListener.updateTileStream.subscribe(event => { + for (const eventTile of event) { + const layer = this.gameMap.findPhaserLayer(eventTile.layer); + if (layer) { + const tile = layer.getTileAt(eventTile.x, eventTile.y) + if (typeof eventTile.tile == "string") { + const tileIndex = this.getIndexForTileType(eventTile.tile); + if (tileIndex) { + tile.index = tileIndex + } else { + return + } + } else { + tile.index = eventTile.tile + } + } + } + })) } @@ -945,6 +967,19 @@ ${escapedMessage} } + private getIndexForTileType(tileType: string): number | null { + for (const tileset of this.mapFile.tilesets) { + if (tileset.tiles) { + for (const tilesetTile of tileset.tiles) { + if (tilesetTile.type == tileType) { + return tileset.firstgid + tilesetTile.id + } + } + } + } + return null + } + private getMapDirUrl(): string { return this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/')); } @@ -952,8 +987,8 @@ ${escapedMessage} private onMapExit(exitKey: string) { if (this.mapTransitioning) return; this.mapTransitioning = true; - const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance); - if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey); + const { roomId, hash } = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance); + if (!roomId) throw new Error('Could not find the room from its exit key: ' + exitKey); urlManager.pushStartLayerNameToUrl(hash); const menuScene: MenuScene = this.scene.get(MenuSceneName) as MenuScene menuScene.reset() @@ -1155,7 +1190,7 @@ ${escapedMessage} this.physics.add.collider(this.CurrentPlayer, phaserLayer, (object1: GameObject, object2: GameObject) => { //this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name) }); - phaserLayer.setCollisionByProperty({collides: true}); + phaserLayer.setCollisionByProperty({ collides: true }); if (DEBUG_MODE) { //debug code to see the collision hitbox of the object in the top layer phaserLayer.renderDebug(this.add.graphics(), { diff --git a/front/src/Phaser/Map/ITiledMap.ts b/front/src/Phaser/Map/ITiledMap.ts index d381e9d4..2f5d45bc 100644 --- a/front/src/Phaser/Map/ITiledMap.ts +++ b/front/src/Phaser/Map/ITiledMap.ts @@ -36,7 +36,7 @@ export interface ITiledMap { export interface ITiledMapLayerProperty { name: string; type: string; - value: string|boolean|number|undefined; + value: string | boolean | number | undefined; } /*export interface ITiledMapLayerBooleanProperty { @@ -65,7 +65,7 @@ export interface ITiledMapGroupLayer { export interface ITiledMapTileLayer { id?: number, - data: number[]|string; + data: number[] | string; height: number; name: string; opacity: number; @@ -117,7 +117,7 @@ export interface ITiledMapObject { gid: number; height: number; name: string; - properties: {[key: string]: string}; + properties: { [key: string]: string }; rotation: number; type: string; visible: boolean; @@ -133,12 +133,12 @@ export interface ITiledMapObject { /** * Polygon points */ - polygon: {x: number, y: number}[]; + polygon: { x: number, y: number }[]; /** * Polyline points */ - polyline: {x: number, y: number}[]; + polyline: { x: number, y: number }[]; text?: ITiledText } @@ -152,7 +152,7 @@ export interface ITiledText { underline?: boolean, italic?: boolean, strikeout?: boolean, - halign?: "center"|"right"|"justify"|"left" + halign?: "center" | "right" | "justify" | "left" } export interface ITiledTileSet { @@ -163,14 +163,14 @@ export interface ITiledTileSet { imagewidth: number; margin: number; name: string; - properties: {[key: string]: string}; + properties: { [key: string]: string }; spacing: number; tilecount: number; tileheight: number; tilewidth: number; transparentcolor: string; terrains: ITiledMapTerrain[]; - tiles: {[key: string]: { terrain: number[] }}; + tiles: Array; /** * Refers to external tileset file (should be JSON) @@ -178,6 +178,11 @@ export interface ITiledTileSet { source: string; } +export interface ITile { + id: number, + type?: string +} + export interface ITiledMapTerrain { name: string; tile: number; diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts index 5a3336a4..f253c48d 100644 --- a/front/src/iframe_api.ts +++ b/front/src/iframe_api.ts @@ -26,8 +26,6 @@ interface WorkAdventureApi { onEnterZone(name: string, callback: () => void): void; onLeaveZone(name: string, callback: () => void): void; openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup; - openTab(url: string): void; - goToPage(url: string): void; openCoWebSite(url: string): void; closeCoWebSite(): void; disablePlayerControls() : void; @@ -167,7 +165,7 @@ window.WA = { loadTileset(name: string, imgUrl : string, tilewidth : number, tileheight : number, margin : number, spacing : number): void { postToParent({ - type: "tilsetEvent", + type: "updateTileEvent", data: { name: name, imgUrl: imgUrl, @@ -276,24 +274,6 @@ window.WA = { window.parent.postMessage({ 'type': 'removeBubble' }, '*'); }, - openTab(url: string): void { - window.parent.postMessage({ - "type": 'openTab', - "data": { - url - } as OpenTabEvent - }, '*'); - }, - - goToPage(url: string): void { - window.parent.postMessage({ - "type": 'goToPage', - "data": { - url - } as GoToPageEvent - }, '*'); - }, - openCoWebSite(url: string): void { window.parent.postMessage({ "type": 'openCoWebSite',