Add exit menu in multiplayer mode
This commit is contained in:
parent
cfeda33d33
commit
9f278a6b72
33
server.js
33
server.js
@ -290,13 +290,34 @@ function startMatch() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePlayer(clientId) {
|
function removePlayer(clientId, voluntaryLeave = false) {
|
||||||
lobby.players = lobby.players.filter((p) => p.id !== clientId);
|
lobby.players = lobby.players.filter((p) => p.id !== clientId);
|
||||||
|
|
||||||
if (lobby.phase === "game") {
|
if (lobby.phase === "game") {
|
||||||
const inRoster = lobby.roster.some((p) => p.id === clientId);
|
const rosterIndex = lobby.roster.findIndex((p) => p.id === clientId);
|
||||||
if (inRoster) {
|
if (rosterIndex !== -1) {
|
||||||
endMatch("A player disconnected. Back to lobby.");
|
const wasHost = clientId === lobby.hostId;
|
||||||
|
lobby.roster.splice(rosterIndex, 1);
|
||||||
|
|
||||||
|
if (wasHost) {
|
||||||
|
if (voluntaryLeave && lobby.roster.length > 0) {
|
||||||
|
lobby.hostId = lobby.roster[0].id;
|
||||||
|
broadcast({ type: "game_player_left", playerId: clientId });
|
||||||
|
broadcastLobbyState("Host left the round. New host assigned.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
endMatch(voluntaryLeave ? "Host left the round. Back to lobby." : "Host disconnected. Back to lobby.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!voluntaryLeave) {
|
||||||
|
endMatch("A player disconnected. Back to lobby.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast({ type: "game_player_left", playerId: clientId });
|
||||||
|
broadcastLobbyState("A player left the round.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,7 +380,7 @@ function handleMessage(client, msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type === "lobby_leave") {
|
if (msg.type === "lobby_leave") {
|
||||||
removePlayer(client.id);
|
removePlayer(client.id, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,7 +536,7 @@ wss.on("connection", (ws) => {
|
|||||||
ws.on("close", () => {
|
ws.on("close", () => {
|
||||||
clientsBySocket.delete(ws);
|
clientsBySocket.delete(ws);
|
||||||
clientsById.delete(client.id);
|
clientsById.delete(client.id);
|
||||||
removePlayer(client.id);
|
removePlayer(client.id, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on("error", () => {
|
ws.on("error", () => {
|
||||||
|
|||||||
46
src/game.js
46
src/game.js
@ -408,7 +408,7 @@ function getMenuItems() {
|
|||||||
return [
|
return [
|
||||||
{ id: "nextRound", label: "Start Next Round" },
|
{ id: "nextRound", label: "Start Next Round" },
|
||||||
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
||||||
{ id: "leaveMatch", label: "Leave Match" },
|
{ id: "exitLobby", label: "Exit To Lobby" },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
@ -419,7 +419,7 @@ function getMenuItems() {
|
|||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
||||||
{ id: "leaveMatch", label: "Leave Match" },
|
{ id: "exitLobby", label: "Exit To Lobby" },
|
||||||
{ id: "close", label: "Close" },
|
{ id: "close", label: "Close" },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -513,6 +513,12 @@ function activateMenuSelection() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.id === "exitLobby") {
|
||||||
|
closeMenu();
|
||||||
|
leaveMultiplayerToLobby();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.id === "leaveMatch") {
|
if (item.id === "leaveMatch") {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
leaveMultiplayerToMainMenu();
|
leaveMultiplayerToMainMenu();
|
||||||
@ -792,6 +798,27 @@ function handleSocketMessage(raw) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg.type === "game_player_left") {
|
||||||
|
if (typeof msg.playerId !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
network.activeRoster = network.activeRoster.filter((player) => player.id !== msg.playerId);
|
||||||
|
network.remoteInputs.delete(msg.playerId);
|
||||||
|
network.remoteBombPrev.delete(msg.playerId);
|
||||||
|
|
||||||
|
if (state.mode === "multiplayer" && state.screen === "game") {
|
||||||
|
const player = state.players.find((entry) => entry.ownerId === msg.playerId) || null;
|
||||||
|
if (player && player.alive) {
|
||||||
|
killPlayer(player, null);
|
||||||
|
showMatchNotification(player.name + " left the round.");
|
||||||
|
} else {
|
||||||
|
showMatchNotification("A player left the round.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.type === "player_input") {
|
if (msg.type === "player_input") {
|
||||||
if (!network.isHost || state.mode !== "multiplayer" || state.screen !== "game") {
|
if (!network.isHost || state.mode !== "multiplayer" || state.screen !== "game") {
|
||||||
return;
|
return;
|
||||||
@ -883,6 +910,13 @@ function leaveMultiplayerToMainMenu() {
|
|||||||
state.message = "Select mode";
|
state.message = "Select mode";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function leaveMultiplayerToLobby() {
|
||||||
|
sendSocketMessage("lobby_leave");
|
||||||
|
leaveLobbyInternals();
|
||||||
|
enterLobbyScreen();
|
||||||
|
state.message = "Returned to lobby.";
|
||||||
|
}
|
||||||
|
|
||||||
function leaveSinglePlayerToMainMenu() {
|
function leaveSinglePlayerToMainMenu() {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
inputState.bombQueued = false;
|
inputState.bombQueued = false;
|
||||||
@ -1001,7 +1035,6 @@ function serializeGameState(includeFullMap = false) {
|
|||||||
})),
|
})),
|
||||||
nextBombId: state.nextBombId,
|
nextBombId: state.nextBombId,
|
||||||
outcomePlayed: state.outcomePlayed,
|
outcomePlayed: state.outcomePlayed,
|
||||||
menuOpen: state.menu.open,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,7 +1160,6 @@ function applySnapshot(snapshot) {
|
|||||||
}));
|
}));
|
||||||
state.nextBombId = snapshot.nextBombId;
|
state.nextBombId = snapshot.nextBombId;
|
||||||
state.outcomePlayed = snapshot.outcomePlayed;
|
state.outcomePlayed = snapshot.outcomePlayed;
|
||||||
state.menu.open = snapshot.menuOpen;
|
|
||||||
network.hasReceivedSnapshot = true;
|
network.hasReceivedSnapshot = true;
|
||||||
rebuildFireLookup();
|
rebuildFireLookup();
|
||||||
}
|
}
|
||||||
@ -2682,14 +2714,14 @@ function onActionDown(action, isRepeat = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === "menu" && !isRepeat) {
|
if (action.type === "menu" && !isRepeat) {
|
||||||
if (state.mode === "multiplayer" && state.status === "running") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state.menu.open) {
|
if (state.menu.open) {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
} else {
|
} else {
|
||||||
openMenu();
|
openMenu();
|
||||||
}
|
}
|
||||||
|
if (state.mode === "multiplayer" && !network.isHost) {
|
||||||
|
sendLocalMultiplayerInput(true);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user