Add exit menu in multiplayer mode
This commit is contained in:
parent
cfeda33d33
commit
9f278a6b72
31
server.js
31
server.js
@ -290,15 +290,36 @@ function startMatch() {
|
||||
});
|
||||
}
|
||||
|
||||
function removePlayer(clientId) {
|
||||
function removePlayer(clientId, voluntaryLeave = false) {
|
||||
lobby.players = lobby.players.filter((p) => p.id !== clientId);
|
||||
|
||||
if (lobby.phase === "game") {
|
||||
const inRoster = lobby.roster.some((p) => p.id === clientId);
|
||||
if (inRoster) {
|
||||
const rosterIndex = lobby.roster.findIndex((p) => p.id === clientId);
|
||||
if (rosterIndex !== -1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ensureHost();
|
||||
@ -359,7 +380,7 @@ function handleMessage(client, msg) {
|
||||
}
|
||||
|
||||
if (msg.type === "lobby_leave") {
|
||||
removePlayer(client.id);
|
||||
removePlayer(client.id, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -515,7 +536,7 @@ wss.on("connection", (ws) => {
|
||||
ws.on("close", () => {
|
||||
clientsBySocket.delete(ws);
|
||||
clientsById.delete(client.id);
|
||||
removePlayer(client.id);
|
||||
removePlayer(client.id, false);
|
||||
});
|
||||
|
||||
ws.on("error", () => {
|
||||
|
||||
46
src/game.js
46
src/game.js
@ -408,7 +408,7 @@ function getMenuItems() {
|
||||
return [
|
||||
{ id: "nextRound", label: "Start Next Round" },
|
||||
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
||||
{ id: "leaveMatch", label: "Leave Match" },
|
||||
{ id: "exitLobby", label: "Exit To Lobby" },
|
||||
];
|
||||
}
|
||||
return [
|
||||
@ -419,7 +419,7 @@ function getMenuItems() {
|
||||
}
|
||||
return [
|
||||
{ id: "music", label: `Music: ${audio && audio.isMusicEnabled() ? "On" : "Off"}` },
|
||||
{ id: "leaveMatch", label: "Leave Match" },
|
||||
{ id: "exitLobby", label: "Exit To Lobby" },
|
||||
{ id: "close", label: "Close" },
|
||||
];
|
||||
}
|
||||
@ -513,6 +513,12 @@ function activateMenuSelection() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.id === "exitLobby") {
|
||||
closeMenu();
|
||||
leaveMultiplayerToLobby();
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.id === "leaveMatch") {
|
||||
closeMenu();
|
||||
leaveMultiplayerToMainMenu();
|
||||
@ -792,6 +798,27 @@ function handleSocketMessage(raw) {
|
||||
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 (!network.isHost || state.mode !== "multiplayer" || state.screen !== "game") {
|
||||
return;
|
||||
@ -883,6 +910,13 @@ function leaveMultiplayerToMainMenu() {
|
||||
state.message = "Select mode";
|
||||
}
|
||||
|
||||
function leaveMultiplayerToLobby() {
|
||||
sendSocketMessage("lobby_leave");
|
||||
leaveLobbyInternals();
|
||||
enterLobbyScreen();
|
||||
state.message = "Returned to lobby.";
|
||||
}
|
||||
|
||||
function leaveSinglePlayerToMainMenu() {
|
||||
closeMenu();
|
||||
inputState.bombQueued = false;
|
||||
@ -1001,7 +1035,6 @@ function serializeGameState(includeFullMap = false) {
|
||||
})),
|
||||
nextBombId: state.nextBombId,
|
||||
outcomePlayed: state.outcomePlayed,
|
||||
menuOpen: state.menu.open,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1127,7 +1160,6 @@ function applySnapshot(snapshot) {
|
||||
}));
|
||||
state.nextBombId = snapshot.nextBombId;
|
||||
state.outcomePlayed = snapshot.outcomePlayed;
|
||||
state.menu.open = snapshot.menuOpen;
|
||||
network.hasReceivedSnapshot = true;
|
||||
rebuildFireLookup();
|
||||
}
|
||||
@ -2682,14 +2714,14 @@ function onActionDown(action, isRepeat = false) {
|
||||
}
|
||||
|
||||
if (action.type === "menu" && !isRepeat) {
|
||||
if (state.mode === "multiplayer" && state.status === "running") {
|
||||
return;
|
||||
}
|
||||
if (state.menu.open) {
|
||||
closeMenu();
|
||||
} else {
|
||||
openMenu();
|
||||
}
|
||||
if (state.mode === "multiplayer" && !network.isHost) {
|
||||
sendLocalMultiplayerInput(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user