open website linked from Tiled Object

This commit is contained in:
Piotr 'pwh' Hanusiak 2022-04-12 10:57:38 +02:00
parent 255f4375da
commit 1ca393f3db
3 changed files with 191 additions and 177 deletions

View File

@ -6,7 +6,7 @@ import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
import { localUserStore } from "../../Connexion/LocalUserStore"; import { localUserStore } from "../../Connexion/LocalUserStore";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { ON_ACTION_TRIGGER_BUTTON, ON_ICON_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager"; import { ON_ACTION_TRIGGER_BUTTON, ON_ICON_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager";
import type { ITiledMapLayer } from "../Map/ITiledMap"; import type { ITiledMapLayer, ITiledMapProperty } from "../Map/ITiledMap";
import { GameMapProperties } from "./GameMapProperties"; import { GameMapProperties } from "./GameMapProperties";
import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite"; import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite";
import { SimpleCoWebsite } from "../../WebRtc/CoWebsite/SimpleCoWebsite"; import { SimpleCoWebsite } from "../../WebRtc/CoWebsite/SimpleCoWebsite";
@ -23,9 +23,17 @@ interface OpenCoWebsite {
coWebsite?: CoWebsite; coWebsite?: CoWebsite;
} }
/**
* Either Layer or Object within Objects Layer in Tiled
*/
export interface ITiledPlace {
name: string;
properties?: ITiledMapProperty[];
}
export class GameMapPropertiesListener { export class GameMapPropertiesListener {
private coWebsitesOpenByLayer = new Map<ITiledMapLayer, OpenCoWebsite>(); private coWebsitesOpenByPlace = new Map<ITiledPlace, OpenCoWebsite>();
private coWebsitesActionTriggerByLayer = new Map<ITiledMapLayer, string>(); private coWebsitesActionTriggerByPlace = new Map<ITiledPlace, string>();
constructor(private scene: GameScene, private gameMap: GameMap) {} constructor(private scene: GameScene, private gameMap: GameMap) {}
@ -179,193 +187,196 @@ export class GameMapPropertiesListener {
} }
}); });
// Open a new co-website by the property.
this.gameMap.onEnterLayer((newLayers) => { this.gameMap.onEnterLayer((newLayers) => {
const handler = () => { this.onEnterPlaceHandler(newLayers);
newLayers.forEach((layer) => {
if (!layer.properties) {
return;
}
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 GameMapProperties.OPEN_WEBSITE:
openWebsiteProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_ALLOW_API:
allowApiProperty = property.value as boolean | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_POLICY:
websitePolicyProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_WIDTH:
websiteWidthProperty = property.value as number | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_POSITION:
websitePositionProperty = property.value as number | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER:
websiteTriggerProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER_MESSAGE:
websiteTriggerMessageProperty = property.value as string | undefined;
break;
}
});
if (!openWebsiteProperty) {
return;
}
const actionId = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
if (this.coWebsitesOpenByLayer.has(layer)) {
return;
}
const coWebsiteOpen: OpenCoWebsite = {
actionId: actionId,
};
this.coWebsitesOpenByLayer.set(layer, coWebsiteOpen);
const loadCoWebsiteFunction = (coWebsite: CoWebsite) => {
coWebsiteManager.loadCoWebsite(coWebsite).catch(() => {
console.error("Error during loading a co-website: " + coWebsite.getUrl());
});
layoutManagerActionStore.removeAction(actionId);
};
const openCoWebsiteFunction = () => {
const coWebsite = new SimpleCoWebsite(
new URL(openWebsiteProperty ?? "", this.scene.MapUrlFile),
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
false
);
coWebsiteOpen.coWebsite = coWebsite;
coWebsiteManager.addCoWebsiteToStore(coWebsite, websitePositionProperty);
loadCoWebsiteFunction(coWebsite);
};
if (
localUserStore.getForceCowebsiteTrigger() ||
websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON
) {
if (!websiteTriggerMessageProperty) {
websiteTriggerMessageProperty = get(LL).trigger.cowebsite();
}
this.coWebsitesActionTriggerByLayer.set(layer, actionId);
layoutManagerActionStore.addAction({
uuid: actionId,
type: "message",
message: websiteTriggerMessageProperty,
callback: () => openCoWebsiteFunction(),
userInputManager: this.scene.userInputManager,
});
} else if (websiteTriggerProperty === ON_ICON_TRIGGER_BUTTON) {
const coWebsite = new SimpleCoWebsite(
new URL(openWebsiteProperty ?? "", this.scene.MapUrlFile),
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
false
);
coWebsiteOpen.coWebsite = coWebsite;
coWebsiteManager.addCoWebsiteToStore(coWebsite, websitePositionProperty);
}
if (!websiteTriggerProperty) {
openCoWebsiteFunction();
}
});
};
handler();
}); });
// Close opened co-websites on leave the layer who contain the property.
this.gameMap.onLeaveLayer((oldLayers) => { this.gameMap.onLeaveLayer((oldLayers) => {
const handler = () => { this.onLeavePlaceHandler(oldLayers);
oldLayers.forEach((layer) => { });
if (!layer.properties) {
return;
}
let openWebsiteProperty: string | undefined; this.gameMap.onEnterArea((newAreas) => {
let websiteTriggerProperty: string | undefined; this.onEnterPlaceHandler(newAreas);
});
layer.properties.forEach((property) => { this.gameMap.onLeaveArea((oldAreas) => {
switch (property.name) { this.onLeavePlaceHandler(oldAreas);
case GameMapProperties.OPEN_WEBSITE: });
openWebsiteProperty = property.value as string | undefined; }
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER:
websiteTriggerProperty = property.value as string | undefined;
break;
}
});
if (!openWebsiteProperty) { private onEnterPlaceHandler(places: ITiledPlace[]): void {
return; places.forEach((place) => {
} if (!place.properties) {
return;
}
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer); 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;
if (!coWebsiteOpen) { place.properties.forEach((property) => {
return; switch (property.name) {
} case GameMapProperties.OPEN_WEBSITE:
openWebsiteProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_ALLOW_API:
allowApiProperty = property.value as boolean | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_POLICY:
websitePolicyProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_WIDTH:
websiteWidthProperty = property.value as number | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_POSITION:
websitePositionProperty = property.value as number | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER:
websiteTriggerProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER_MESSAGE:
websiteTriggerMessageProperty = property.value as string | undefined;
break;
}
});
const coWebsite = coWebsiteOpen.coWebsite; if (!openWebsiteProperty) {
return;
}
if (coWebsite) { const actionId = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
coWebsiteManager.closeCoWebsite(coWebsite);
}
this.coWebsitesOpenByLayer.delete(layer); if (this.coWebsitesOpenByPlace.has(place)) {
return;
}
if (!websiteTriggerProperty) { const coWebsiteOpen: OpenCoWebsite = {
return; actionId: actionId,
}
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);
}
this.coWebsitesActionTriggerByLayer.delete(layer);
});
}; };
handler(); this.coWebsitesOpenByPlace.set(place, coWebsiteOpen);
const loadCoWebsiteFunction = (coWebsite: CoWebsite) => {
coWebsiteManager.loadCoWebsite(coWebsite).catch(() => {
console.error("Error during loading a co-website: " + coWebsite.getUrl());
});
layoutManagerActionStore.removeAction(actionId);
};
const openCoWebsiteFunction = () => {
const coWebsite = new SimpleCoWebsite(
new URL(openWebsiteProperty ?? "", this.scene.MapUrlFile),
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
false
);
coWebsiteOpen.coWebsite = coWebsite;
coWebsiteManager.addCoWebsiteToStore(coWebsite, websitePositionProperty);
loadCoWebsiteFunction(coWebsite);
};
if (localUserStore.getForceCowebsiteTrigger() || websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON) {
if (!websiteTriggerMessageProperty) {
websiteTriggerMessageProperty = get(LL).trigger.cowebsite();
}
this.coWebsitesActionTriggerByPlace.set(place, actionId);
layoutManagerActionStore.addAction({
uuid: actionId,
type: "message",
message: websiteTriggerMessageProperty,
callback: () => openCoWebsiteFunction(),
userInputManager: this.scene.userInputManager,
});
} else if (websiteTriggerProperty === ON_ICON_TRIGGER_BUTTON) {
const coWebsite = new SimpleCoWebsite(
new URL(openWebsiteProperty ?? "", this.scene.MapUrlFile),
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
false
);
coWebsiteOpen.coWebsite = coWebsite;
coWebsiteManager.addCoWebsiteToStore(coWebsite, websitePositionProperty);
}
if (!websiteTriggerProperty) {
openCoWebsiteFunction();
}
});
}
private onLeavePlaceHandler(places: ITiledPlace[]): void {
places.forEach((place) => {
if (!place.properties) {
return;
}
let openWebsiteProperty: string | undefined;
let websiteTriggerProperty: string | undefined;
place.properties.forEach((property) => {
switch (property.name) {
case GameMapProperties.OPEN_WEBSITE:
openWebsiteProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_TRIGGER:
websiteTriggerProperty = property.value as string | undefined;
break;
}
});
if (!openWebsiteProperty) {
return;
}
const coWebsiteOpen = this.coWebsitesOpenByPlace.get(place);
if (!coWebsiteOpen) {
return;
}
const coWebsite = coWebsiteOpen.coWebsite;
if (coWebsite) {
coWebsiteManager.closeCoWebsite(coWebsite);
}
this.coWebsitesOpenByPlace.delete(place);
if (!websiteTriggerProperty) {
return;
}
const actionStore = get(layoutManagerActionStore);
const actionTriggerUuid = this.coWebsitesActionTriggerByPlace.get(place);
if (!actionTriggerUuid) {
return;
}
const action =
actionStore && actionStore.length > 0
? actionStore.find((action) => action.uuid === actionTriggerUuid)
: undefined;
if (action) {
layoutManagerActionStore.removeAction(actionTriggerUuid);
}
this.coWebsitesActionTriggerByPlace.delete(place);
}); });
} }
} }

View File

@ -892,6 +892,7 @@ export class GameScene extends DirtyScene {
}); });
}); });
// TODO: Move to GameMapPropertiesListener?
this.gameMap.onEnterArea((areas) => { this.gameMap.onEnterArea((areas) => {
for (const area of areas) { for (const area of areas) {
const focusable = area.properties?.find( const focusable = area.properties?.find(
@ -920,7 +921,9 @@ export class GameScene extends DirtyScene {
this.gameMap.onLeaveArea((areas) => { this.gameMap.onLeaveArea((areas) => {
for (const area of areas) { for (const area of areas) {
const focusable = area.properties?.find((property) => property.name === "focusable"); const focusable = area.properties?.find(
(property) => property.name === GameMapProperties.FOCUSABLE
);
if (focusable && focusable.value === true) { if (focusable && focusable.value === true) {
this.cameraManager.leaveFocusMode(this.CurrentPlayer, 1000); this.cameraManager.leaveFocusMode(this.CurrentPlayer, 1000);
break; break;

View File

@ -120,7 +120,7 @@
{ {
"name":"openWebsite", "name":"openWebsite",
"type":"string", "type":"string",
"value":"https:\/\/youtu.be\/iF-ucIgP0OE?list=RDGMEMWO-g6DgCWEqKlDtKbJA1GwVMiF-ucIgP0OE" "value":"https:\/\/www.youtube.com\/embed\/CvXUGIm_hkA?list=RDCvXUGIm_hkA"
}], }],
"rotation":0, "rotation":0,
"type":"area", "type":"area",