merged develop
This commit is contained in:
@@ -18,7 +18,7 @@ import { soundManager } from "./SoundManager";
|
||||
import { SharedVariablesManager } from "./SharedVariablesManager";
|
||||
import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager";
|
||||
|
||||
import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager";
|
||||
import { lazyLoadPlayerCharacterTextures } from "../Entity/PlayerTexturesLoadingManager";
|
||||
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
import { DEBUG_MODE, JITSI_URL, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable";
|
||||
@@ -30,7 +30,7 @@ import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
import { SimplePeer } from "../../WebRtc/SimplePeer";
|
||||
import { Loader } from "../Components/Loader";
|
||||
import { RemotePlayer } from "../Entity/RemotePlayer";
|
||||
import { RemotePlayer, RemotePlayerEvent } from "../Entity/RemotePlayer";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene";
|
||||
import { PlayerAnimationDirections } from "../Player/Animation";
|
||||
import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player";
|
||||
@@ -98,6 +98,10 @@ import { startLayerNamesStore } from "../../Stores/StartLayerNamesStore";
|
||||
import { JitsiCoWebsite } from "../../WebRtc/CoWebsite/JitsiCoWebsite";
|
||||
import { SimpleCoWebsite } from "../../WebRtc/CoWebsite/SimpleCoWebsite";
|
||||
import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite";
|
||||
import type { VideoPeer } from "../../WebRtc/VideoPeer";
|
||||
import CancelablePromise from "cancelable-promise";
|
||||
import { Deferred } from "ts-deferred";
|
||||
import { SuperLoaderPlugin } from "../Services/SuperLoaderPlugin";
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
reconnecting: boolean;
|
||||
@@ -163,13 +167,9 @@ export class GameScene extends DirtyScene {
|
||||
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
||||
public connection: RoomConnection | undefined;
|
||||
private simplePeer!: SimplePeer;
|
||||
private connectionAnswerPromise: Promise<RoomJoinedMessageInterface>;
|
||||
private connectionAnswerPromiseResolve!: (
|
||||
value: RoomJoinedMessageInterface | PromiseLike<RoomJoinedMessageInterface>
|
||||
) => void;
|
||||
private connectionAnswerPromiseDeferred: Deferred<RoomJoinedMessageInterface>;
|
||||
// A promise that will resolve when the "create" method is called (signaling loading is ended)
|
||||
private createPromise: Promise<void>;
|
||||
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
||||
private createPromiseDeferred: Deferred<void>;
|
||||
private iframeSubscriptionList!: Array<Subscription>;
|
||||
private peerStoreUnsubscribe!: Unsubscriber;
|
||||
private emoteUnsubscribe!: Unsubscriber;
|
||||
@@ -221,6 +221,7 @@ export class GameScene extends DirtyScene {
|
||||
private lastCameraEvent: WasCameraUpdatedEvent | undefined;
|
||||
private firstCameraUpdateSent: boolean = false;
|
||||
private currentPlayerGroupId?: number;
|
||||
public readonly superLoad: SuperLoaderPlugin;
|
||||
|
||||
constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) {
|
||||
super({
|
||||
@@ -233,13 +234,10 @@ export class GameScene extends DirtyScene {
|
||||
this.MapUrlFile = MapUrlFile;
|
||||
this.roomUrl = room.key;
|
||||
|
||||
this.createPromise = new Promise<void>((resolve, reject): void => {
|
||||
this.createPromiseResolve = resolve;
|
||||
});
|
||||
this.connectionAnswerPromise = new Promise<RoomJoinedMessageInterface>((resolve, reject): void => {
|
||||
this.connectionAnswerPromiseResolve = resolve;
|
||||
});
|
||||
this.createPromiseDeferred = new Deferred<void>();
|
||||
this.connectionAnswerPromiseDeferred = new Deferred<RoomJoinedMessageInterface>();
|
||||
this.loader = new Loader(this);
|
||||
this.superLoad = new SuperLoaderPlugin(this);
|
||||
}
|
||||
|
||||
//hook preload scene
|
||||
@@ -247,13 +245,6 @@ export class GameScene extends DirtyScene {
|
||||
//initialize frame event of scripting API
|
||||
this.listenToIframeEvents();
|
||||
|
||||
const localUser = localUserStore.getLocalUser();
|
||||
const textures = localUser?.textures;
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
loadCustomTexture(this.load, texture).catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
this.load.image("iconTalk", "/resources/icons/icon_talking.png");
|
||||
|
||||
if (touchScreenManager.supportTouchScreen) {
|
||||
@@ -416,11 +407,11 @@ export class GameScene extends DirtyScene {
|
||||
this.load.on("complete", () => {
|
||||
// FIXME: the factory might fail because the resources might not be loaded yet...
|
||||
// We would need to add a loader ended event in addition to the createPromise
|
||||
this.createPromise
|
||||
this.createPromiseDeferred.promise
|
||||
.then(async () => {
|
||||
itemFactory.create(this);
|
||||
|
||||
const roomJoinedAnswer = await this.connectionAnswerPromise;
|
||||
const roomJoinedAnswer = await this.connectionAnswerPromiseDeferred.promise;
|
||||
|
||||
for (const object of objectsOfType) {
|
||||
// TODO: we should pass here a factory to create sprites (maybe?)
|
||||
@@ -574,7 +565,6 @@ export class GameScene extends DirtyScene {
|
||||
this.pathfindingManager = new PathfindingManager(
|
||||
this,
|
||||
this.gameMap.getCollisionGrid(),
|
||||
this.gameMap.getWalkingCostGrid(),
|
||||
this.gameMap.getTileDimensions()
|
||||
);
|
||||
|
||||
@@ -618,7 +608,7 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
}
|
||||
|
||||
this.createPromiseResolve();
|
||||
this.createPromiseDeferred.resolve();
|
||||
// Now, let's load the script, if any
|
||||
const scripts = this.getScriptUrls(this.mapFile);
|
||||
const disableModuleMode = this.getProperty(this.mapFile, GameMapProperties.SCRIPT_DISABLE_MODULE_SUPPORT) as
|
||||
@@ -644,7 +634,7 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
|
||||
const talkIconVolumeTreshold = 10;
|
||||
let oldPeerNumber = 0;
|
||||
const oldPeers = new Map<number, VideoPeer>();
|
||||
this.peerStoreUnsubscribe = peerStore.subscribe((peers) => {
|
||||
this.volumeStoreUnsubscribers.forEach((unsubscribe) => unsubscribe());
|
||||
this.volumeStoreUnsubscribers.clear();
|
||||
@@ -661,10 +651,17 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
|
||||
const newPeerNumber = peers.size;
|
||||
if (newPeerNumber > oldPeerNumber) {
|
||||
if (newPeerNumber > oldPeers.size) {
|
||||
this.playSound("audio-webrtc-in");
|
||||
} else if (newPeerNumber < oldPeerNumber) {
|
||||
} else if (newPeerNumber < oldPeers.size) {
|
||||
this.playSound("audio-webrtc-out");
|
||||
const oldPeersKeys = oldPeers.keys();
|
||||
const newPeersKeys = Array.from(peers.keys());
|
||||
for (const oldKey of oldPeersKeys) {
|
||||
if (!newPeersKeys.includes(oldKey)) {
|
||||
this.MapPlayersByKey.get(oldKey)?.showTalkIcon(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newPeerNumber > 0) {
|
||||
if (!this.localVolumeStoreUnsubscriber) {
|
||||
@@ -682,7 +679,10 @@ export class GameScene extends DirtyScene {
|
||||
this.localVolumeStoreUnsubscriber = undefined;
|
||||
}
|
||||
}
|
||||
oldPeerNumber = newPeerNumber;
|
||||
oldPeers.clear();
|
||||
for (const [key, val] of peers) {
|
||||
oldPeers.set(key, val);
|
||||
}
|
||||
});
|
||||
|
||||
this.emoteUnsubscribe = emoteStore.subscribe((emote) => {
|
||||
@@ -715,7 +715,11 @@ export class GameScene extends DirtyScene {
|
||||
this.currentPlayerGroupId = groupId;
|
||||
});
|
||||
|
||||
Promise.all([this.connectionAnswerPromise as Promise<unknown>, ...scriptPromises])
|
||||
Promise.all([
|
||||
this.connectionAnswerPromiseDeferred.promise as Promise<unknown>,
|
||||
...scriptPromises,
|
||||
this.CurrentPlayer.getTextureLoadedPromise() as Promise<unknown>,
|
||||
])
|
||||
.then(() => {
|
||||
this.scene.wake();
|
||||
})
|
||||
@@ -752,6 +756,14 @@ export class GameScene extends DirtyScene {
|
||||
.then((onConnect: OnConnectInterface) => {
|
||||
this.connection = onConnect.connection;
|
||||
|
||||
lazyLoadPlayerCharacterTextures(this.superLoad, onConnect.room.characterLayers)
|
||||
.then((layers) => {
|
||||
this.currentPlayerTexturesResolve(layers);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.currentPlayerTexturesReject(e);
|
||||
});
|
||||
|
||||
playersStore.connectToRoomConnection(this.connection);
|
||||
userIsAdminStore.set(this.connection.hasTag("admin"));
|
||||
|
||||
@@ -878,7 +890,7 @@ export class GameScene extends DirtyScene {
|
||||
);
|
||||
|
||||
//this.initUsersPosition(roomJoinedMessage.users);
|
||||
this.connectionAnswerPromiseResolve(onConnect.room);
|
||||
this.connectionAnswerPromiseDeferred.resolve(onConnect.room);
|
||||
// Analyze tags to find if we are admin. If yes, show console.
|
||||
|
||||
if (this.scene.isSleeping()) {
|
||||
@@ -1122,6 +1134,23 @@ ${escapedMessage}
|
||||
})
|
||||
);
|
||||
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.addActionsMenuKeyToRemotePlayerStream.subscribe((data) => {
|
||||
this.MapPlayersByKey.get(data.id)?.registerActionsMenuAction({
|
||||
actionName: data.actionKey,
|
||||
callback: () => {
|
||||
iframeListener.sendActionsMenuActionClickedEvent({ actionName: data.actionKey, id: data.id });
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.removeActionsMenuKeyFromRemotePlayerEvent.subscribe((data) => {
|
||||
this.MapPlayersByKey.get(data.id)?.unregisterActionsMenuAction(data.actionKey);
|
||||
})
|
||||
);
|
||||
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.trackCameraUpdateStream.subscribe(() => {
|
||||
if (!this.firstCameraUpdateSent) {
|
||||
@@ -1280,7 +1309,7 @@ ${escapedMessage}
|
||||
iframeListener.registerAnswerer("getState", async () => {
|
||||
// The sharedVariablesManager is not instantiated before the connection is established. So we need to wait
|
||||
// for the connection to send back the answer.
|
||||
await this.connectionAnswerPromise;
|
||||
await this.connectionAnswerPromiseDeferred.promise;
|
||||
return {
|
||||
mapUrl: this.MapUrlFile,
|
||||
startLayerName: this.startPositionCalculator.startLayerName,
|
||||
@@ -1303,7 +1332,7 @@ ${escapedMessage}
|
||||
})
|
||||
);
|
||||
iframeListener.registerAnswerer("loadTileset", (eventTileset) => {
|
||||
return this.connectionAnswerPromise.then(() => {
|
||||
return this.connectionAnswerPromiseDeferred.promise.then(() => {
|
||||
const jsonTilesetDir = eventTileset.url.substr(0, eventTileset.url.lastIndexOf("/"));
|
||||
//Initialise the firstgid to 1 because if there is no tileset in the tilemap, the firstgid will be 1
|
||||
let newFirstgid = 1;
|
||||
@@ -1466,7 +1495,7 @@ ${escapedMessage}
|
||||
phaserLayers[i].setCollisionByProperty({ collides: true }, visible);
|
||||
}
|
||||
}
|
||||
this.pathfindingManager.setCollisionGrid(this.gameMap.getCollisionGrid(), this.gameMap.getWalkingCostGrid());
|
||||
this.pathfindingManager.setCollisionGrid(this.gameMap.getCollisionGrid());
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
@@ -1548,7 +1577,7 @@ ${escapedMessage}
|
||||
this.messageSubscription?.unsubscribe();
|
||||
this.userInputManager.destroy();
|
||||
this.pinchManager?.destroy();
|
||||
this.emoteManager.destroy();
|
||||
this.emoteManager?.destroy();
|
||||
this.cameraManager.destroy();
|
||||
this.peerStoreUnsubscribe();
|
||||
this.emoteUnsubscribe();
|
||||
@@ -1614,6 +1643,8 @@ ${escapedMessage}
|
||||
}
|
||||
})
|
||||
.catch((reason) => console.warn(reason));
|
||||
|
||||
urlManager.clearHashParameter();
|
||||
} catch (err) {
|
||||
console.warn(`Cannot proceed with moveTo command:\n\t-> ${err}`);
|
||||
}
|
||||
@@ -1705,16 +1736,23 @@ ${escapedMessage}
|
||||
}
|
||||
}
|
||||
|
||||
// The promise that will resolve to the current player texture. This will be available only after connection is established.
|
||||
private currentPlayerTexturesResolve!: (value: string[]) => void;
|
||||
private currentPlayerTexturesReject!: (reason: unknown) => void;
|
||||
private currentPlayerTexturesPromise: CancelablePromise<string[]> = new CancelablePromise((resolve, reject) => {
|
||||
this.currentPlayerTexturesResolve = resolve;
|
||||
this.currentPlayerTexturesReject = reject;
|
||||
});
|
||||
|
||||
private createCurrentPlayer() {
|
||||
//TODO create animation moving between exit and start
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers);
|
||||
try {
|
||||
this.CurrentPlayer = new Player(
|
||||
this,
|
||||
this.startPositionCalculator.startPosition.x,
|
||||
this.startPositionCalculator.startPosition.y,
|
||||
this.playerName,
|
||||
texturesPromise,
|
||||
this.currentPlayerTexturesPromise,
|
||||
PlayerAnimationDirections.Down,
|
||||
false,
|
||||
this.companion,
|
||||
@@ -1898,9 +1936,10 @@ ${escapedMessage}
|
||||
return;
|
||||
}
|
||||
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, addPlayerData.characterLayers);
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.superLoad, addPlayerData.characterLayers);
|
||||
const player = new RemotePlayer(
|
||||
addPlayerData.userId,
|
||||
addPlayerData.userUuid,
|
||||
this,
|
||||
addPlayerData.position.x,
|
||||
addPlayerData.position.y,
|
||||
@@ -1928,6 +1967,10 @@ ${escapedMessage}
|
||||
this.activatablesManager.handlePointerOutActivatableObject();
|
||||
this.markDirty();
|
||||
});
|
||||
|
||||
player.on(RemotePlayerEvent.Clicked, () => {
|
||||
iframeListener.sendRemotePlayerClickedEvent({ id: player.userId });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2070,8 +2113,6 @@ ${escapedMessage}
|
||||
right: camera.scrollX + camera.width,
|
||||
bottom: camera.scrollY + camera.height,
|
||||
});
|
||||
|
||||
this.loader.resize();
|
||||
}
|
||||
|
||||
private getObjectLayerData(objectName: string): ITiledMapObject | undefined {
|
||||
|
||||
Reference in New Issue
Block a user