2021-07-02 11:31:44 +02:00
|
|
|
import {Observable, Subject} from "rxjs";
|
2021-06-23 20:19:38 +02:00
|
|
|
|
|
|
|
import { isDataLayerEvent } from "../Events/DataLayerEvent";
|
2021-06-25 18:14:40 +02:00
|
|
|
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
2021-06-23 20:19:38 +02:00
|
|
|
import { isGameStateEvent } from "../Events/GameStateEvent";
|
|
|
|
|
2021-07-02 16:41:24 +02:00
|
|
|
import {IframeApiContribution, queryWorkadventure, sendToWorkadventure} from "./IframeApiContribution";
|
2021-06-21 11:48:39 +02:00
|
|
|
import { apiCallback } from "./registeredCallbacks";
|
2021-07-02 11:31:44 +02:00
|
|
|
import type {LayerEvent} from "../Events/LayerEvent";
|
|
|
|
import type {SetPropertyEvent} from "../Events/setPropertyEvent";
|
|
|
|
import {isSetVariableEvent, SetVariableEvent} from "../Events/SetVariableEvent";
|
2021-06-23 20:19:38 +02:00
|
|
|
|
2021-06-25 18:14:40 +02:00
|
|
|
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
|
|
|
|
import type { DataLayerEvent } from "../Events/DataLayerEvent";
|
2021-06-23 20:19:38 +02:00
|
|
|
import type { GameStateEvent } from "../Events/GameStateEvent";
|
2021-05-25 13:47:41 +02:00
|
|
|
|
2021-05-28 00:24:08 +02:00
|
|
|
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
|
|
|
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
2021-06-23 11:32:11 +02:00
|
|
|
const dataLayerResolver = new Subject<DataLayerEvent>();
|
|
|
|
const stateResolvers = new Subject<GameStateEvent>();
|
2021-07-02 11:31:44 +02:00
|
|
|
const setVariableResolvers = new Subject<SetVariableEvent>();
|
|
|
|
const variables = new Map<string, unknown>();
|
|
|
|
const variableSubscribers = new Map<string, Subject<unknown>>();
|
2021-06-23 11:32:11 +02:00
|
|
|
|
2021-07-02 16:41:24 +02:00
|
|
|
let immutableDataPromise: Promise<GameStateEvent> | undefined = undefined;
|
2021-06-23 11:32:11 +02:00
|
|
|
|
|
|
|
interface Room {
|
2021-06-25 18:14:40 +02:00
|
|
|
id: string;
|
|
|
|
mapUrl: string;
|
|
|
|
map: ITiledMap;
|
|
|
|
startLayer: string | null;
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
interface User {
|
2021-06-25 18:14:40 +02:00
|
|
|
id: string | undefined;
|
|
|
|
nickName: string | null;
|
|
|
|
tags: string[];
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
|
2021-06-23 12:02:29 +02:00
|
|
|
interface TileDescriptor {
|
2021-07-02 14:35:28 +02:00
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
tile: number | string;
|
|
|
|
layer: string;
|
2021-06-23 12:02:29 +02:00
|
|
|
}
|
|
|
|
|
2021-06-23 11:32:11 +02:00
|
|
|
function getGameState(): Promise<GameStateEvent> {
|
2021-07-02 16:41:24 +02:00
|
|
|
if (immutableDataPromise === undefined) {
|
|
|
|
immutableDataPromise = queryWorkadventure({ type: "getState", data: undefined });
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
2021-07-02 16:41:24 +02:00
|
|
|
return immutableDataPromise;
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function getDataLayer(): Promise<DataLayerEvent> {
|
|
|
|
return new Promise<DataLayerEvent>((resolver, thrower) => {
|
|
|
|
dataLayerResolver.subscribe(resolver);
|
2021-06-25 18:14:40 +02:00
|
|
|
sendToWorkadventure({ type: "getDataLayer", data: null });
|
|
|
|
});
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
2021-05-25 13:47:41 +02:00
|
|
|
|
2021-07-02 11:31:44 +02:00
|
|
|
setVariableResolvers.subscribe((event) => {
|
|
|
|
variables.set(event.key, event.value);
|
|
|
|
const subject = variableSubscribers.get(event.key);
|
|
|
|
if (subject !== undefined) {
|
|
|
|
subject.next(event.value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-06-30 10:15:55 +02:00
|
|
|
export class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomCommands> {
|
2021-05-28 00:24:08 +02:00
|
|
|
callbacks = [
|
|
|
|
apiCallback({
|
|
|
|
callback: (payloadData: EnterLeaveEvent) => {
|
|
|
|
enterStreams.get(payloadData.name)?.next();
|
|
|
|
},
|
|
|
|
type: "enterEvent",
|
2021-06-25 18:14:40 +02:00
|
|
|
typeChecker: isEnterLeaveEvent,
|
2021-05-28 00:24:08 +02:00
|
|
|
}),
|
|
|
|
apiCallback({
|
|
|
|
type: "leaveEvent",
|
|
|
|
typeChecker: isEnterLeaveEvent,
|
|
|
|
callback: (payloadData) => {
|
|
|
|
leaveStreams.get(payloadData.name)?.next();
|
2021-06-25 18:14:40 +02:00
|
|
|
},
|
2021-06-23 11:32:11 +02:00
|
|
|
}),
|
|
|
|
apiCallback({
|
|
|
|
type: "dataLayer",
|
|
|
|
typeChecker: isDataLayerEvent,
|
|
|
|
callback: (payloadData) => {
|
|
|
|
dataLayerResolver.next(payloadData);
|
2021-06-25 18:14:40 +02:00
|
|
|
},
|
2021-06-23 11:32:11 +02:00
|
|
|
}),
|
2021-07-02 11:31:44 +02:00
|
|
|
apiCallback({
|
|
|
|
type: "setVariable",
|
|
|
|
typeChecker: isSetVariableEvent,
|
|
|
|
callback: (payloadData) => {
|
|
|
|
setVariableResolvers.next(payloadData);
|
|
|
|
}
|
|
|
|
}),
|
2021-06-25 18:14:40 +02:00
|
|
|
];
|
2021-05-25 13:47:41 +02:00
|
|
|
|
2021-05-28 00:24:08 +02:00
|
|
|
onEnterZone(name: string, callback: () => void): void {
|
|
|
|
let subject = enterStreams.get(name);
|
|
|
|
if (subject === undefined) {
|
|
|
|
subject = new Subject<EnterLeaveEvent>();
|
|
|
|
enterStreams.set(name, subject);
|
|
|
|
}
|
|
|
|
subject.subscribe(callback);
|
|
|
|
}
|
|
|
|
onLeaveZone(name: string, callback: () => void): void {
|
|
|
|
let subject = leaveStreams.get(name);
|
|
|
|
if (subject === undefined) {
|
|
|
|
subject = new Subject<EnterLeaveEvent>();
|
|
|
|
leaveStreams.set(name, subject);
|
|
|
|
}
|
|
|
|
subject.subscribe(callback);
|
|
|
|
}
|
2021-06-23 11:32:11 +02:00
|
|
|
showLayer(layerName: string): void {
|
2021-06-25 18:14:40 +02:00
|
|
|
sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
hideLayer(layerName: string): void {
|
2021-06-25 18:14:40 +02:00
|
|
|
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
|
|
|
|
sendToWorkadventure({
|
2021-06-25 18:14:40 +02:00
|
|
|
type: "setProperty",
|
2021-06-23 11:32:11 +02:00
|
|
|
data: {
|
2021-06-25 18:14:40 +02:00
|
|
|
layerName: layerName,
|
|
|
|
propertyName: propertyName,
|
|
|
|
propertyValue: propertyValue,
|
|
|
|
},
|
|
|
|
});
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
getCurrentRoom(): Promise<Room> {
|
|
|
|
return getGameState().then((gameState) => {
|
2021-06-25 18:14:40 +02:00
|
|
|
return getDataLayer().then((mapJson) => {
|
|
|
|
return {
|
|
|
|
id: gameState.roomId,
|
|
|
|
map: mapJson.data as ITiledMap,
|
|
|
|
mapUrl: gameState.mapUrl,
|
|
|
|
startLayer: gameState.startLayerName,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
|
|
|
getCurrentUser(): Promise<User> {
|
|
|
|
return getGameState().then((gameState) => {
|
2021-06-25 18:14:40 +02:00
|
|
|
return { id: gameState.uuid, nickName: gameState.nickname, tags: gameState.tags };
|
|
|
|
});
|
2021-06-23 11:32:11 +02:00
|
|
|
}
|
2021-06-28 14:58:49 +02:00
|
|
|
setTiles(tiles: TileDescriptor[]) {
|
2021-06-23 12:02:29 +02:00
|
|
|
sendToWorkadventure({
|
2021-07-02 14:35:28 +02:00
|
|
|
type: "setTiles",
|
|
|
|
data: tiles,
|
|
|
|
});
|
2021-06-23 12:02:29 +02:00
|
|
|
}
|
2021-07-02 11:31:44 +02:00
|
|
|
|
|
|
|
saveVariable(key : string, value : unknown): void {
|
|
|
|
variables.set(key, value);
|
|
|
|
sendToWorkadventure({
|
|
|
|
type: 'setVariable',
|
|
|
|
data: {
|
|
|
|
key,
|
|
|
|
value
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
loadVariable(key: string): unknown {
|
|
|
|
return variables.get(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
onVariableChange(key: string): Observable<unknown> {
|
|
|
|
let subject = variableSubscribers.get(key);
|
|
|
|
if (subject === undefined) {
|
|
|
|
subject = new Subject<unknown>();
|
|
|
|
variableSubscribers.set(key, subject);
|
|
|
|
}
|
|
|
|
return subject.asObservable();
|
|
|
|
}
|
2021-05-28 00:24:08 +02:00
|
|
|
}
|
2021-05-25 13:47:41 +02:00
|
|
|
|
2021-06-18 17:22:56 +02:00
|
|
|
export default new WorkadventureRoomCommands();
|