Cowebsite properties manage by layer and not by property index

This commit is contained in:
Alexis Faizeau 2021-10-29 16:47:19 +02:00
parent 934e24f837
commit f4df12e5ff

View File

@ -1,15 +1,32 @@
import type { GameScene } from "./GameScene"; import type { GameScene } from "./GameScene";
import type { GameMap } from "./GameMap"; import type { GameMap } from "./GameMap";
import { scriptUtils } from "../../Api/ScriptUtils"; import { scriptUtils } from "../../Api/ScriptUtils";
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager"; import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
import { get } from 'svelte/store';
import { import {
ON_ACTION_TRIGGER_BUTTON, ON_ACTION_TRIGGER_BUTTON,
TRIGGER_WEBSITE_PROPERTIES, TRIGGER_WEBSITE_PROPERTIES,
WEBSITE_MESSAGE_PROPERTIES, WEBSITE_MESSAGE_PROPERTIES,
} from "../../WebRtc/LayoutManager"; } from "../../WebRtc/LayoutManager";
import type { ITiledMapLayer } from "../Map/ITiledMap";
enum OpenCoWebsiteState {
LOADING,
OPENED,
MUST_BE_CLOSE,
}
interface OpenCoWebsite {
coWebsite: CoWebsite | undefined,
state: OpenCoWebsiteState
}
export class GameMapPropertiesListener { export class GameMapPropertiesListener {
private coWebsitesOpenByLayer = new Map<ITiledMapLayer, OpenCoWebsite>();
private coWebsitesActionTriggerByLayer = new Map<ITiledMapLayer, string>();
constructor(private scene: GameScene, private gameMap: GameMap) {} constructor(private scene: GameScene, private gameMap: GameMap) {}
register() { register() {
@ -36,42 +53,178 @@ export class GameMapPropertiesListener {
} }
} }
}); });
this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => {
const handler = async () => { // Open a new co-website by the property.
if (newValue === undefined || newValue !== oldValue) { this.gameMap.onEnterLayer((newLayers) => {
layoutManagerActionStore.removeAction("openWebsite"); const handler = () => {
await coWebsiteManager.closeCoWebsites(); newLayers.forEach(layer => {
if (!layer.properties) {
return;
} }
if (newValue !== undefined) { let openWebsiteProperty: string | undefined;
let allowApiProperty: boolean | undefined;
let websitePolicyProperty: string | undefined;
let websiteWidthProperty: number | undefined;
let websitePositionProperty: number | undefined;
let websiteTriggerProperty: string | undefined;
let websiteTriggerMessageProperty: string | undefined;
layer.properties.forEach(property => {
switch(property.name) {
case 'openWebsite':
openWebsiteProperty = property.value as string | undefined;
break;
case 'openWebsiteAllowApi':
allowApiProperty = property.value as boolean | undefined;
break;
case 'openWebsitePolicy':
websitePolicyProperty = property.value as string | undefined;
break;
case 'openWebsiteWidth':
websiteWidthProperty = property.value as number | undefined;
break;
case 'openWebsitePosition':
websitePositionProperty = property.value as number | undefined;
break;
case TRIGGER_WEBSITE_PROPERTIES:
websiteTriggerProperty = property.value as string | undefined;
break;
case WEBSITE_MESSAGE_PROPERTIES:
websiteTriggerMessageProperty = property.value as string | undefined;
break;
}
});
if (!openWebsiteProperty) {
return;
}
const actionUuid = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
if (this.coWebsitesOpenByLayer.has(layer)) {
return;
}
this.coWebsitesOpenByLayer.set(layer, {
coWebsite: undefined,
state: OpenCoWebsiteState.LOADING,
});
const openWebsiteFunction = () => { const openWebsiteFunction = () => {
coWebsiteManager.loadCoWebsite( coWebsiteManager.loadCoWebsite(
newValue as string, openWebsiteProperty as string,
this.scene.MapUrlFile, this.scene.MapUrlFile,
allProps.get("openWebsiteAllowApi") as boolean | undefined, allowApiProperty,
allProps.get("openWebsitePolicy") as string | undefined, websitePolicyProperty,
allProps.get("openWebsiteWidth") as number | undefined websiteWidthProperty,
); websitePositionProperty,
).then(coWebsite => {
layoutManagerActionStore.removeAction("openWebsite"); const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
}; if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); coWebsiteManager.closeCoWebsite(coWebsite);
if (openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { this.coWebsitesOpenByLayer.delete(layer);
let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES); this.coWebsitesActionTriggerByLayer.delete(layer);
if (message === undefined) { } else {
message = "Press SPACE or touch here to open web site"; this.coWebsitesOpenByLayer.set(layer, {
coWebsite,
state: OpenCoWebsiteState.OPENED
});
} }
});
layoutManagerActionStore.removeAction(actionUuid);
};
if (websiteTriggerProperty && websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON) {
if (!websiteTriggerMessageProperty) {
websiteTriggerMessageProperty = "Press SPACE or touch here to open web site";
}
this.coWebsitesActionTriggerByLayer.set(layer, actionUuid);
layoutManagerActionStore.addAction({ layoutManagerActionStore.addAction({
uuid: "openWebsite", uuid: actionUuid,
type: "message", type: "message",
message: message, message: websiteTriggerMessageProperty,
callback: () => openWebsiteFunction(), callback: () => openWebsiteFunction(),
userInputManager: this.scene.userInputManager, userInputManager: this.scene.userInputManager,
}); });
} else { } else {
openWebsiteFunction(); openWebsiteFunction();
} }
});
};
handler();
});
// Close opened co-websites on leave the layer who contain the property.
this.gameMap.onLeaveLayer((oldLayers) => {
const handler = () => {
oldLayers.forEach(layer => {
if (!layer.properties) {
return;
} }
let openWebsiteProperty: string | undefined;
let websiteTriggerProperty: string | undefined;
layer.properties.forEach(property => {
switch(property.name) {
case 'openWebsite':
openWebsiteProperty = property.value as string | undefined;
break;
case TRIGGER_WEBSITE_PROPERTIES:
websiteTriggerProperty = property.value as string | undefined;
break;
}
});
if (!openWebsiteProperty) {
return;
}
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
if (!coWebsiteOpen) {
return;
}
if (coWebsiteOpen.state === OpenCoWebsiteState.LOADING) {
coWebsiteOpen.state = OpenCoWebsiteState.MUST_BE_CLOSE;
return;
}
if (coWebsiteOpen.state !== OpenCoWebsiteState.OPENED) {
return;
}
if (coWebsiteOpen.coWebsite !== undefined) {
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite);
}
this.coWebsitesOpenByLayer.delete(layer);
if (!websiteTriggerProperty) {
return;
}
const actionStore = get(layoutManagerActionStore);
const actionTriggerUuid = this.coWebsitesActionTriggerByLayer.get(layer);
if (!actionTriggerUuid) {
return;
}
const action = actionStore && actionStore.length > 0 ?
actionStore.find(action => action.uuid === actionTriggerUuid) : undefined;
if (action) {
layoutManagerActionStore.removeAction(actionTriggerUuid);
}
});
}; };
handler(); handler();