Adding support for default variables values
This commit is contained in:
parent
abd53b6251
commit
c30de8c6db
@ -88,13 +88,11 @@ export type IframeQueryMap = {
|
||||
getState: {
|
||||
query: undefined,
|
||||
answer: GameStateEvent,
|
||||
callback: () => GameStateEvent|PromiseLike<GameStateEvent>
|
||||
},
|
||||
getMapData: {
|
||||
query: undefined,
|
||||
answer: MapDataEvent,
|
||||
callback: () => MapDataEvent|PromiseLike<GameStateEvent>
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export interface IframeQuery<T extends keyof IframeQueryMap> {
|
||||
|
@ -1,18 +1,12 @@
|
||||
import {Observable, Subject} from "rxjs";
|
||||
|
||||
import { isMapDataEvent } from "../Events/MapDataEvent";
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
||||
import { isGameStateEvent } from "../Events/GameStateEvent";
|
||||
|
||||
import {IframeApiContribution, queryWorkadventure, sendToWorkadventure} from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import type {LayerEvent} from "../Events/LayerEvent";
|
||||
import type {SetPropertyEvent} from "../Events/setPropertyEvent";
|
||||
import {isSetVariableEvent, SetVariableEvent} from "../Events/SetVariableEvent";
|
||||
|
||||
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
|
||||
import type { MapDataEvent } from "../Events/MapDataEvent";
|
||||
import type { GameStateEvent } from "../Events/GameStateEvent";
|
||||
|
||||
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
@ -39,6 +33,16 @@ export const setMapURL = (url: string) => {
|
||||
mapURL = url;
|
||||
}
|
||||
|
||||
export const initVariables = (_variables: Map<string, unknown>): void => {
|
||||
for (const [name, value] of _variables.entries()) {
|
||||
// In case the user already decided to put values in the variables (before onInit), let's make sure onInit does not override this.
|
||||
if (!variables.has(name)) {
|
||||
variables.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setVariableResolvers.subscribe((event) => {
|
||||
variables.set(event.key, event.value);
|
||||
const subject = variableSubscribers.get(event.key);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty } from "../Map/ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiledMap";
|
||||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
||||
@ -19,7 +19,7 @@ export class GameMap {
|
||||
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||
private tileNameMap = new Map<string, number>();
|
||||
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapLayerProperty> } = {};
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {};
|
||||
public readonly flatLayers: ITiledMapLayer[];
|
||||
public readonly phaserLayers: TilemapLayer[] = [];
|
||||
|
||||
@ -61,7 +61,7 @@ export class GameMap {
|
||||
}
|
||||
}
|
||||
|
||||
public getPropertiesForIndex(index: number): Array<ITiledMapLayerProperty> {
|
||||
public getPropertiesForIndex(index: number): Array<ITiledMapProperty> {
|
||||
if (this.tileSetPropertyMap[index]) {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
@ -151,7 +151,7 @@ export class GameMap {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
private getTileProperty(index: number): Array<ITiledMapLayerProperty> {
|
||||
private getTileProperty(index: number): Array<ITiledMapProperty> {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectC
|
||||
import type {
|
||||
ITiledMap,
|
||||
ITiledMapLayer,
|
||||
ITiledMapLayerProperty,
|
||||
ITiledMapProperty,
|
||||
ITiledMapObject,
|
||||
ITiledTileSet,
|
||||
} from "../Map/ITiledMap";
|
||||
@ -1197,12 +1197,12 @@ ${escapedMessage}
|
||||
}
|
||||
|
||||
private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return undefined;
|
||||
}
|
||||
const obj = properties.find(
|
||||
(property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
(property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
);
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
@ -1211,12 +1211,12 @@ ${escapedMessage}
|
||||
}
|
||||
|
||||
private getProperties(layer: ITiledMapLayer | ITiledMap, name: string): (string | number | boolean | undefined)[] {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return [];
|
||||
}
|
||||
return properties
|
||||
.filter((property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase())
|
||||
.filter((property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase())
|
||||
.map((property) => property.value);
|
||||
}
|
||||
|
||||
|
@ -5,18 +5,28 @@ import type {RoomConnection} from "../../Connexion/RoomConnection";
|
||||
import {iframeListener} from "../../Api/IframeListener";
|
||||
import type {Subscription} from "rxjs";
|
||||
import type {GameMap} from "./GameMap";
|
||||
import type {ITiledMapObject} from "../Map/ITiledMap";
|
||||
import type {ITile, ITiledMapObject} from "../Map/ITiledMap";
|
||||
import type {Var} from "svelte/types/compiler/interfaces";
|
||||
|
||||
interface Variable {
|
||||
defaultValue: unknown
|
||||
}
|
||||
|
||||
export class SharedVariablesManager {
|
||||
private _variables = new Map<string, unknown>();
|
||||
private iframeListenerSubscription: Subscription;
|
||||
private variableObjects: Map<string, ITiledMapObject>;
|
||||
private variableObjects: Map<string, Variable>;
|
||||
|
||||
constructor(private roomConnection: RoomConnection, private gameMap: GameMap) {
|
||||
// We initialize the list of variable object at room start. The objects cannot be edited later
|
||||
// (otherwise, this would cause a security issue if the scripting API can edit this list of objects)
|
||||
this.variableObjects = SharedVariablesManager.findVariablesInMap(gameMap);
|
||||
|
||||
// Let's initialize default values
|
||||
for (const [name, variableObject] of this.variableObjects.entries()) {
|
||||
this._variables.set(name, variableObject.defaultValue);
|
||||
}
|
||||
|
||||
// When a variable is modified from an iFrame
|
||||
this.iframeListenerSubscription = iframeListener.setVariableStream.subscribe((event) => {
|
||||
const key = event.key;
|
||||
@ -33,14 +43,14 @@ export class SharedVariablesManager {
|
||||
});
|
||||
}
|
||||
|
||||
private static findVariablesInMap(gameMap: GameMap): Map<string, ITiledMapObject> {
|
||||
const objects = new Map<string, ITiledMapObject>();
|
||||
private static findVariablesInMap(gameMap: GameMap): Map<string, Variable> {
|
||||
const objects = new Map<string, Variable>();
|
||||
for (const layer of gameMap.getMap().layers) {
|
||||
if (layer.type === 'objectgroup') {
|
||||
for (const object of layer.objects) {
|
||||
if (object.type === 'variable') {
|
||||
// We store a copy of the object (to make it immutable)
|
||||
objects.set(object.name, {...object});
|
||||
objects.set(object.name, this.iTiledObjectToVariable(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,6 +58,21 @@ export class SharedVariablesManager {
|
||||
return objects;
|
||||
}
|
||||
|
||||
private static iTiledObjectToVariable(object: ITiledMapObject): Variable {
|
||||
const variable: Variable = {
|
||||
defaultValue: undefined
|
||||
};
|
||||
|
||||
if (object.properties) {
|
||||
for (const property of object.properties) {
|
||||
if (property.name === 'default') {
|
||||
variable.defaultValue = property.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.iframeListenerSubscription.unsubscribe();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapTileLayer } from "../Map/ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapTileLayer } from "../Map/ITiledMap";
|
||||
import type { GameMap } from "./GameMap";
|
||||
|
||||
const defaultStartLayerName = "start";
|
||||
@ -112,12 +112,12 @@ export class StartPositionCalculator {
|
||||
}
|
||||
|
||||
private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return undefined;
|
||||
}
|
||||
const obj = properties.find(
|
||||
(property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
(property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
);
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
|
@ -16,7 +16,7 @@ export interface ITiledMap {
|
||||
* Map orientation (orthogonal)
|
||||
*/
|
||||
orientation: string;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
|
||||
/**
|
||||
* Render order (right-down)
|
||||
@ -33,7 +33,7 @@ export interface ITiledMap {
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface ITiledMapLayerProperty {
|
||||
export interface ITiledMapProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
value: string | boolean | number | undefined;
|
||||
@ -51,7 +51,7 @@ export interface ITiledMapGroupLayer {
|
||||
id?: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
|
||||
type: "group";
|
||||
visible: boolean;
|
||||
@ -69,7 +69,7 @@ export interface ITiledMapTileLayer {
|
||||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
encoding?: string;
|
||||
compression?: string;
|
||||
|
||||
@ -91,7 +91,7 @@ export interface ITiledMapObjectLayer {
|
||||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
encoding?: string;
|
||||
compression?: string;
|
||||
|
||||
@ -117,7 +117,7 @@ export interface ITiledMapObject {
|
||||
gid: number;
|
||||
height: number;
|
||||
name: string;
|
||||
properties: { [key: string]: string };
|
||||
properties?: ITiledMapProperty[];
|
||||
rotation: number;
|
||||
type: string;
|
||||
visible: boolean;
|
||||
@ -163,7 +163,7 @@ export interface ITiledTileSet {
|
||||
imagewidth: number;
|
||||
margin: number;
|
||||
name: string;
|
||||
properties: { [key: string]: string };
|
||||
properties?: ITiledMapProperty[];
|
||||
spacing: number;
|
||||
tilecount: number;
|
||||
tileheight: number;
|
||||
@ -182,7 +182,7 @@ export interface ITile {
|
||||
id: number;
|
||||
type?: string;
|
||||
|
||||
properties?: Array<ITiledMapLayerProperty>;
|
||||
properties?: ITiledMapProperty[];
|
||||
}
|
||||
|
||||
export interface ITiledMapTerrain {
|
||||
|
@ -11,7 +11,7 @@ import nav from "./Api/iframe/nav";
|
||||
import controls from "./Api/iframe/controls";
|
||||
import ui from "./Api/iframe/ui";
|
||||
import sound from "./Api/iframe/sound";
|
||||
import room, {setMapURL, setRoomId} from "./Api/iframe/room";
|
||||
import room, {initVariables, setMapURL, setRoomId} from "./Api/iframe/room";
|
||||
import player, {setPlayerName, setTags, setUuid} from "./Api/iframe/player";
|
||||
import type { ButtonDescriptor } from "./Api/iframe/Ui/ButtonDescriptor";
|
||||
import type { Popup } from "./Api/iframe/Ui/Popup";
|
||||
@ -29,6 +29,7 @@ const initPromise = new Promise<void>((resolve) => {
|
||||
setMapURL(state.mapUrl);
|
||||
setTags(state.tags);
|
||||
setUuid(state.uuid);
|
||||
initVariables(state.variables as Map<string, unknown>);
|
||||
resolve();
|
||||
}));
|
||||
});
|
||||
|
@ -1,11 +1,13 @@
|
||||
WA.onInit().then(() => {
|
||||
console.log('Trying to read variable "doorOpened" whose default property is true. This should display "true".');
|
||||
console.log('doorOpened', WA.room.loadVariable('doorOpened'));
|
||||
|
||||
console.log('Trying to set variable "not_exists". This should display an error in the console.')
|
||||
WA.room.saveVariable('not_exists', 'foo');
|
||||
|
||||
console.log('Trying to set variable "config". This should work.');
|
||||
WA.room.saveVariable('config', {'foo': 'bar'});
|
||||
|
||||
console.log('Trying to read variable "config". This should display a {"foo": "bar"} object.');
|
||||
console.log(WA.room.loadVariable('config'));
|
||||
console.log('Trying to set variable "not_exists". This should display an error in the console.')
|
||||
WA.room.saveVariable('not_exists', 'foo');
|
||||
|
||||
console.log('Trying to set variable "config". This should work.');
|
||||
WA.room.saveVariable('config', {'foo': 'bar'});
|
||||
|
||||
console.log('Trying to read variable "config". This should display a {"foo": "bar"} object.');
|
||||
console.log(WA.room.loadVariable('config'));
|
||||
});
|
||||
|
@ -72,6 +72,24 @@
|
||||
"template":"config.tx",
|
||||
"x":57.5,
|
||||
"y":111
|
||||
},
|
||||
{
|
||||
"height":0,
|
||||
"id":6,
|
||||
"name":"doorOpened",
|
||||
"point":true,
|
||||
"properties":[
|
||||
{
|
||||
"name":"default",
|
||||
"type":"bool",
|
||||
"value":true
|
||||
}],
|
||||
"rotation":0,
|
||||
"type":"variable",
|
||||
"visible":true,
|
||||
"width":0,
|
||||
"x":131.38069962269,
|
||||
"y":106.004988169086
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
@ -80,7 +98,7 @@
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":8,
|
||||
"nextobjectid":6,
|
||||
"nextobjectid":8,
|
||||
"orientation":"orthogonal",
|
||||
"properties":[
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user