Change multiplayer menu

This commit is contained in:
thepaperpilot 2022-09-06 22:15:53 -05:00
parent a598832dff
commit 066afc5dfe
3 changed files with 134 additions and 75 deletions

View file

@ -7,7 +7,7 @@
<Draggable <Draggable
:list="settings.saves" :list="settings.saves"
handle=".handle" handle=".handle"
v-if="shown" v-if="shown && (!room || isHosting)"
:itemKey="(save: string) => save" :itemKey="(save: string) => save"
> >
<template #item="{ element }"> <template #item="{ element }">
@ -21,16 +21,18 @@
/> />
</template> </template>
</Draggable> </Draggable>
<div v-else>You are connected to a server - cannot change saves</div>
</template> </template>
<template v-slot:footer> <template v-slot:footer>
<div class="modal-footer"> <div class="modal-footer">
<Text <Text
v-if="!room || isHosting"
v-model="saveToImport" v-model="saveToImport"
title="Import Save" title="Import Save"
placeholder="Paste your save here!" placeholder="Paste your save here!"
:class="{ importingFailed }" :class="{ importingFailed }"
/> />
<div class="field"> <div class="field" v-if="!room || isHosting">
<span class="field-title">Create Save</span> <span class="field-title">Create Save</span>
<div class="field-buttons"> <div class="field-buttons">
<button class="button" @click="openSave(newSave().id)">New Game</button> <button class="button" @click="openSave(newSave().id)">New Game</button>
@ -59,6 +61,7 @@
<script setup lang="ts"> <script setup lang="ts">
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
import projInfo from "data/projInfo.json"; import projInfo from "data/projInfo.json";
import { isHosting, room } from "data/socket";
import type { PlayerData } from "game/player"; import type { PlayerData } from "game/player";
import player, { stringifySave } from "game/player"; import player, { stringifySave } from "game/player";
import settings from "game/settings"; import settings from "game/settings";

View file

@ -18,9 +18,8 @@
<button class="button open" @click="startConnecting"> <button class="button open" @click="startConnecting">
<h3>{{ room.name }}</h3> <h3>{{ room.name }}</h3>
</button> </button>
<span class="room-host">Hosted by {{ room.host }}</span <div class="room-host">Hosted by {{ room.host }}</div>
><br /> <div class="room-host">{{ room.numContentPacks }} active content packs</div>
<div>{{ room.numContentPacks }} active content packs</div>
</div> </div>
<div v-else class="details" style="display: flex"> <div v-else class="details" style="display: flex">
<span>Password:</span> <span>Password:</span>
@ -108,7 +107,6 @@ function submitPassword() {
} }
.room-host { .room-host {
margin-left: 4px;
font-size: 0.7em; font-size: 0.7em;
opacity: 0.7; opacity: 0.7;
} }

View file

@ -11,7 +11,6 @@
<h3>Connected to {{ currentRoom }}</h3> <h3>Connected to {{ currentRoom }}</h3>
</div> </div>
<br /> <br />
<h4>Connected Players</h4>
<ul class="players-list"> <ul class="players-list">
<div v-for="(nickname, i) in nicknames" :key="i" style="display: flex"> <div v-for="(nickname, i) in nicknames" :key="i" style="display: flex">
<span>{{ nickname }}</span> <span>{{ nickname }}</span>
@ -31,30 +30,15 @@
</button> </button>
</div> </div>
</ul> </ul>
</template>
<template v-else>
<Room
v-for="(room, i) in rooms ?? []"
:key="i"
:room="room"
:isPrivate="false"
@connect="password => join(room.name, password)"
/>
<div v-if="rooms != null && rooms.length === 0" style="text-align: center">
No public rooms found
</div>
<div v-if="rooms == null" style="text-align: center">
Loading public rooms list...
</div>
<br /> <br />
<button <button
class="button" class="button large"
style="float: right; display: inline-block" @click="() => host(hostRoomName, hostRoomPassword, hostPrivate)"
@click="refresh()"
> >
Refresh {{ isHosting ? "Close" : "Leave" }} room
</button> </button>
</template> </template>
<component v-else :is="render(tabs)" />
</template> </template>
<div v-else> <div v-else>
Not connected to a server. Please set up networking in the options modal. Not connected to a server. Please set up networking in the options modal.
@ -64,50 +48,8 @@
</template> </template>
<template v-slot:footer> <template v-slot:footer>
<div class="modal-footer"> <div class="modal-footer">
<div v-if="connected && !currentRoom">
<br />
<hr />
<div style="margin-top: 10px; margin-bottom: -10px">Direct Connect</div>
<div class="direct-connect field">
<Text v-model="directRoomName" placeholder="Room Name" />
<Text v-model="directRoomPassword" placeholder="Room Password" />
<div class="field-buttons">
<button
class="button"
@click="join(directRoomName, directRoomPassword)"
>
Connect
</button>
</div>
</div>
<div style="margin-top: 10px; margin-bottom: -10px">Host current world</div>
<div class="direct-connect field">
<Text v-model="hostRoomName" placeholder="Room Name" />
<Text v-model="hostRoomPassword" placeholder="Room Password" />
<Toggle
v-model="hostPrivate"
title="Private"
style="width: 320px; margin-right: 10px"
/>
<div class="field-buttons">
<button
class="button"
@click="host(hostRoomName, hostRoomPassword, hostPrivate)"
>
Host
</button>
</div>
</div>
</div>
<div class="footer"> <div class="footer">
<div style="flex-grow: 1"></div> <div style="flex-grow: 1"></div>
<button
v-if="currentRoom"
class="button modal-default-button"
@click="emitToServer('leave room')"
>
Leave room
</button>
<button class="button modal-default-button" @click="isOpen = false"> <button class="button modal-default-button" @click="isOpen = false">
Close Close
</button> </button>
@ -117,7 +59,7 @@
</Modal> </Modal>
</template> </template>
<script setup lang="ts"> <script setup lang="tsx">
import Text from "components/fields/Text.vue"; import Text from "components/fields/Text.vue";
import Toggle from "components/fields/Toggle.vue"; import Toggle from "components/fields/Toggle.vue";
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
@ -129,9 +71,12 @@ import {
nicknames, nicknames,
room as currentRoom room as currentRoom
} from "data/socket"; } from "data/socket";
import { jsx } from "features/feature";
import { createTabFamily } from "features/tabs/tabFamily";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import { PlayerData } from "game/player"; import player, { PlayerData } from "game/player";
import settings from "game/settings"; import settings from "game/settings";
import { render } from "util/vue";
import type { ComponentPublicInstance } from "vue"; import type { ComponentPublicInstance } from "vue";
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import { main } from "./projEntry"; import { main } from "./projEntry";
@ -155,9 +100,112 @@ const hostRoomName = ref("");
const hostRoomPassword = ref(""); const hostRoomPassword = ref("");
const hostPrivate = ref<boolean>(false); const hostPrivate = ref<boolean>(false);
watch(isOpen, isOpen => { const tabs = createTabFamily(
if (isOpen) { {
roomList: () => ({
display: "Room List",
tab: jsx(() => (
<>
{(rooms.value ?? []).map(r => (
<Room
room={r}
isPrivate={false}
onConnect={password => join(r.name, password)}
/>
))}
{rooms.value != null && rooms.value.length === 0 ? (
<div style="text-align: center">No public rooms found</div>
) : null}
{rooms.value == null ? (
<div style="text-align: center">Loading public rooms list...</div>
) : null}
<br />
<button class="button large" onClick={refresh}>
Refresh
</button>
</>
))
}),
direct: () => ({
display: "Private Room",
tab: jsx(() => (
<>
<div class="direct-connect">
<div class="field">
<Text
onUpdate:modelValue={value => (directRoomName.value = value)}
modelValue={directRoomName.value}
title="Room Name"
/>
</div>
<div class="field">
<Text
onUpdate:modelValue={value => (directRoomPassword.value = value)}
modelValue={directRoomPassword.value}
title="Room Password"
/>
</div>
<button
class="button large"
onClick={() => join(directRoomName.value, directRoomPassword.value)}
>
Connect
</button>
</div>
</>
))
}),
host: () => ({
display: "Host",
tab: jsx(() => (
<>
<div class="field">
<Text
onUpdate:modelValue={value => (hostRoomName.value = value)}
modelValue={hostRoomName.value}
title="Room Name"
/>
</div>
<div class="field">
<Text
onUpdate:modelValue={value => (hostRoomPassword.value = value)}
modelValue={hostRoomPassword.value}
title="Room Password"
/>
</div>
<Toggle
onUpdate:modelValue={value => (hostPrivate.value = value)}
modelValue={hostPrivate.value}
title="Private"
/>
<div style="font-size: small">
You will host the currently active single player world, allowing other
players to join and modify your save. It is recommended to backup your save
frequently.
</div>
<br />
<button
class="button large"
onClick={() =>
host(hostRoomName.value, hostRoomPassword.value, hostPrivate.value)
}
>
Host
</button>
</>
))
})
},
() => ({
style: "margin-left: 0; margin-right: 0; --layer-color: var(--link)"
})
);
watch([isOpen, tabs.selected], ([isOpen, currentTab]) => {
if (isOpen && currentTab === "roomList") {
refresh(); refresh();
} else if (isOpen && currentTab === "host") {
hostRoomName.value = `${settings.nickname}'s ${player.name}`;
} }
}); });
@ -165,7 +213,7 @@ watch(currentRoom, room => {
if (!room) { if (!room) {
directRoomName.value = ""; directRoomName.value = "";
directRoomPassword.value = ""; directRoomPassword.value = "";
hostRoomName.value = ""; hostRoomName.value = `${settings.nickname}'s ${player.name}`;
hostRoomPassword.value = ""; hostRoomPassword.value = "";
refresh(); refresh();
} }
@ -227,8 +275,18 @@ function host(room: string, password?: string, privateRoom?: boolean) {
.field-title { .field-title {
white-space: nowrap; white-space: nowrap;
} }
</style>
.direct-connect :deep(input[type="text"]) { <style>
margin-right: 10px; .large.button {
font-size: large;
width: 100%;
background: var(--feature-background);
border-radius: var(--border-radius);
}
.large.button:hover {
background: var(--highlighted);
text-shadow: unset;
} }
</style> </style>