diff --git a/front/src/Api/Events/CameraFocusOnEvent.ts b/front/src/Api/Events/CameraFocusOnEvent.ts new file mode 100644 index 00000000..e6a1547e --- /dev/null +++ b/front/src/Api/Events/CameraFocusOnEvent.ts @@ -0,0 +1,15 @@ +import * as tg from "generic-type-guard"; + +export const isCameraFocusOnEvent = new tg.IsInterface() + .withProperties({ + x: tg.isNumber, + y: tg.isNumber, + width: tg.isNumber, + height: tg.isNumber, + smooth: tg.isBoolean, + }) + .get(); +/** + * A message sent from the iFrame to the game to set the camera focus on certain place. + */ +export type CameraFocusOnEvent = tg.GuardedType; diff --git a/front/src/Api/Events/CameraFollowPlayerEvent.ts b/front/src/Api/Events/CameraFollowPlayerEvent.ts new file mode 100644 index 00000000..cf34e7fc --- /dev/null +++ b/front/src/Api/Events/CameraFollowPlayerEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isCameraFollowPlayerEvent = new tg.IsInterface() + .withProperties({ + smooth: tg.isBoolean, + }) + .get(); +/** + * A message sent from the iFrame to the game to make the camera follow player. + */ +export type CameraFollowPlayerEvent = tg.GuardedType; diff --git a/front/src/Api/Events/CameraSetPositionEvent.ts b/front/src/Api/Events/CameraSetPositionEvent.ts new file mode 100644 index 00000000..ef421c44 --- /dev/null +++ b/front/src/Api/Events/CameraSetPositionEvent.ts @@ -0,0 +1,15 @@ +import * as tg from "generic-type-guard"; + +export const isCameraSetPositionEvent = new tg.IsInterface() + .withProperties({ + x: tg.isNumber, + y: tg.isNumber, + width: tg.isNumber, + height: tg.isNumber, + smooth: tg.isBoolean, + }) + .get(); +/** + * A message sent from the iFrame to the game to change the camera position. + */ +export type CameraSetPositionEvent = tg.GuardedType; diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index 2390145a..15a6ceef 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -31,6 +31,9 @@ import type { ChangeLayerEvent } from "./ChangeLayerEvent"; import { isPlayerPosition } from "./PlayerPosition"; import type { WasCameraUpdatedEvent } from "./WasCameraUpdatedEvent"; import type { ChangeZoneEvent } from "./ChangeZoneEvent"; +import type { CameraSetPositionEvent } from "./CameraSetPositionEvent"; +import type { CameraFocusOnEvent } from "./CameraFocusOnEvent"; +import type { CameraFollowPlayerEvent } from "./CameraFollowPlayerEvent"; export interface TypedMessageEvent extends MessageEvent { data: T; @@ -42,6 +45,9 @@ export interface TypedMessageEvent extends MessageEvent { export type IframeEventMap = { loadPage: LoadPageEvent; chat: ChatEvent; + cameraFocusOn: CameraFocusOnEvent; + cameraFollowPlayer: CameraFollowPlayerEvent; + cameraSetPosition: CameraSetPositionEvent; openPopup: OpenPopupEvent; closePopup: ClosePopupEvent; openTab: OpenTabEvent; diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 216a9510..30d41340 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -33,6 +33,9 @@ import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Store import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent"; import type { WasCameraUpdatedEvent } from "./Events/WasCameraUpdatedEvent"; import type { ChangeZoneEvent } from "./Events/ChangeZoneEvent"; +import { CameraSetPositionEvent, isCameraSetPositionEvent } from "./Events/CameraSetPositionEvent"; +import { CameraFocusOnEvent, isCameraFocusOnEvent } from "./Events/CameraFocusOnEvent"; +import { CameraFollowPlayerEvent, isCameraFollowPlayerEvent } from "./Events/CameraFollowPlayerEvent"; type AnswererCallback = ( query: IframeQueryMap[T]["query"], @@ -56,6 +59,15 @@ class IframeListener { private readonly _disablePlayerControlStream: Subject = new Subject(); public readonly disablePlayerControlStream = this._disablePlayerControlStream.asObservable(); + private readonly _cameraSetPositionStream: Subject = new Subject(); + public readonly cameraSetPositionStream = this._cameraSetPositionStream.asObservable(); + + private readonly _cameraFocusOnStream: Subject = new Subject(); + public readonly cameraFocusOnStream = this._cameraFocusOnStream.asObservable(); + + private readonly _cameraFollowPlayerStream: Subject = new Subject(); + public readonly cameraFollowPlayerStream = this._cameraFollowPlayerStream.asObservable(); + private readonly _enablePlayerControlStream: Subject = new Subject(); public readonly enablePlayerControlStream = this._enablePlayerControlStream.asObservable(); @@ -202,6 +214,12 @@ class IframeListener { this._hideLayerStream.next(payload.data); } else if (payload.type === "setProperty" && isSetPropertyEvent(payload.data)) { this._setPropertyStream.next(payload.data); + } else if (payload.type === "cameraSetPosition" && isCameraSetPositionEvent(payload.data)) { + this._cameraSetPositionStream.next(payload.data); + } else if (payload.type === "cameraFocusOn" && isCameraFocusOnEvent(payload.data)) { + this._cameraFocusOnStream.next(payload.data); + } else if (payload.type === "cameraFollowPlayer" && isCameraFollowPlayerEvent(payload.data)) { + this._cameraFollowPlayerStream.next(payload.data); } else if (payload.type === "chat" && isChatEvent(payload.data)) { scriptUtils.sendAnonymousChat(payload.data); } else if (payload.type === "openPopup" && isOpenPopupEvent(payload.data)) { diff --git a/front/src/Api/iframe/camera.ts b/front/src/Api/iframe/camera.ts index 4f62b94c..f562ce98 100644 --- a/front/src/Api/iframe/camera.ts +++ b/front/src/Api/iframe/camera.ts @@ -17,6 +17,27 @@ export class WorkAdventureCameraCommands extends IframeApiContribution { + // this.cameraManager.enterFocusMode({ ...cameraSetPositionEvent }, undefined, cameraSetPositionEvent.smooth ? 1000 : 0); + console.log("camera set position"); + }) + ); + + this.iframeSubscriptionList.push( + iframeListener.cameraFocusOnStream.subscribe((cameraFocusOnEvent) => { + this.cameraManager.enterFocusMode( + { ...cameraFocusOnEvent }, + undefined, + cameraFocusOnEvent.smooth ? 1000 : 0 + ); + }) + ); + + this.iframeSubscriptionList.push( + iframeListener.cameraFollowPlayerStream.subscribe((cameraFollowPlayerEvent) => { + this.cameraManager.leaveFocusMode(this.CurrentPlayer, cameraFollowPlayerEvent.smooth ? 1000 : 0); + }) + ); + this.iframeSubscriptionList.push( iframeListener.playSoundStream.subscribe((playSoundEvent) => { const url = new URL(playSoundEvent.url, this.MapUrlFile);