Replace gameProp signals with store
This commit is contained in:
parent
4390269ed1
commit
252f6f6028
14 changed files with 331 additions and 339 deletions
|
@ -1,10 +1,9 @@
|
|||
import { For } from "solid-js"
|
||||
import {
|
||||
gameState,
|
||||
mode,
|
||||
gameProps,
|
||||
mouseCursor,
|
||||
removeShip,
|
||||
setMode,
|
||||
setGameProps,
|
||||
setMouseCursor,
|
||||
setShips,
|
||||
setTarget,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
import { useSession } from "~/hooks/useSession"
|
||||
import {
|
||||
borderCN,
|
||||
compiledHits,
|
||||
cornerCN,
|
||||
fieldIndex,
|
||||
intersectingShip,
|
||||
|
@ -32,19 +32,21 @@ type TilesType = {
|
|||
}
|
||||
|
||||
function BorderTiles() {
|
||||
const { selfIndex, activeUser, ships } = useSession()
|
||||
const { selfIndex, ships } = useSession()
|
||||
|
||||
const settingTarget = (isGameTile: boolean, x: number, y: number) => {
|
||||
if (gameState() === "running") {
|
||||
const list = targetList(targetPreview(), mode())
|
||||
const sIndex = selfIndex()
|
||||
if (sIndex === -1) return
|
||||
if (gameProps.gameState === "running") {
|
||||
const list = targetList(targetPreview(), gameProps.mode)
|
||||
if (
|
||||
!isGameTile ||
|
||||
!list.filter(
|
||||
({ x, y }) => !isAlreadyHit(x, y, activeUser()?.hits() ?? []),
|
||||
({ x, y }) => !isAlreadyHit(x, y, compiledHits(sIndex === 0 ? 1 : 0)),
|
||||
).length
|
||||
)
|
||||
return
|
||||
if (!overlapsWithAnyBorder(targetPreview(), mode()))
|
||||
if (!overlapsWithAnyBorder(targetPreview(), gameProps.mode))
|
||||
setTarget({
|
||||
show: true,
|
||||
x,
|
||||
|
@ -52,15 +54,17 @@ function BorderTiles() {
|
|||
orientation: targetPreview().orientation,
|
||||
})
|
||||
} else if (
|
||||
gameState() === "starting" &&
|
||||
gameProps.gameState === "starting" &&
|
||||
targetPreview().show &&
|
||||
!intersectingShip(ships(), shipProps(ships(), mode(), targetPreview()))
|
||||
.score
|
||||
!intersectingShip(
|
||||
ships(),
|
||||
shipProps(ships(), gameProps.mode, targetPreview()),
|
||||
).score
|
||||
) {
|
||||
setMouseCursor((e) => ({ ...e, shouldShow: false }))
|
||||
setShips(
|
||||
[...ships(), shipProps(ships(), mode(), targetPreview())],
|
||||
selfIndex(),
|
||||
[...ships(), shipProps(ships(), gameProps.mode, targetPreview())],
|
||||
sIndex,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +98,11 @@ function BorderTiles() {
|
|||
class={props.className}
|
||||
style={{ "--x": props.x, "--y": props.y }}
|
||||
onClick={() => {
|
||||
if (gameState() === "running") {
|
||||
const sIndex = selfIndex()
|
||||
if (sIndex === -1) return
|
||||
if (gameProps.gameState === "running") {
|
||||
settingTarget(props.isGameTile, props.x, props.y)
|
||||
} else if (gameState() === "starting") {
|
||||
} else if (gameProps.gameState === "starting") {
|
||||
const { index } = intersectingShip(ships(), {
|
||||
...mouseCursor(),
|
||||
size: 1,
|
||||
|
@ -107,8 +113,8 @@ function BorderTiles() {
|
|||
settingTarget(props.isGameTile, props.x, props.y)
|
||||
else {
|
||||
const ship = ships()[index]
|
||||
setMode(ship.size - 2)
|
||||
removeShip(ship, selfIndex())
|
||||
setGameProps("mode", ship.size - 2)
|
||||
removeShip(ship, sIndex)
|
||||
setMouseCursor((e) => ({ ...e, shouldShow: true }))
|
||||
}
|
||||
}
|
||||
|
@ -119,10 +125,10 @@ function BorderTiles() {
|
|||
y: props.y,
|
||||
shouldShow:
|
||||
props.isGameTile &&
|
||||
(gameState() === "starting"
|
||||
(gameProps.gameState === "starting"
|
||||
? intersectingShip(
|
||||
ships(),
|
||||
shipProps(ships(), mode(), {
|
||||
shipProps(ships(), gameProps.mode, {
|
||||
x: props.x,
|
||||
y: props.y,
|
||||
orientation: targetPreview().orientation,
|
||||
|
|
|
@ -28,18 +28,11 @@ import { For, Show, createEffect } from "solid-js"
|
|||
import { useNavigate } from "solid-start"
|
||||
import { useDrawProps } from "~/hooks/useDrawProps"
|
||||
import {
|
||||
allowChat,
|
||||
allowMarkDraw,
|
||||
allowSpecials,
|
||||
allowSpectators,
|
||||
gameState,
|
||||
menu,
|
||||
mode,
|
||||
gameProps,
|
||||
reset,
|
||||
setGameProps,
|
||||
setGameSetting,
|
||||
setIsReadyFor,
|
||||
setMenu,
|
||||
setMode,
|
||||
setTarget,
|
||||
setTargetPreview,
|
||||
target,
|
||||
|
@ -60,36 +53,36 @@ function EventBar(props: { clear: () => void }) {
|
|||
icon: "burger-menu",
|
||||
text: "Menu",
|
||||
callback: () => {
|
||||
setMenu("menu")
|
||||
setGameProps("menu", "menu")
|
||||
},
|
||||
},
|
||||
gameState() === "running"
|
||||
gameProps.gameState === "running"
|
||||
? {
|
||||
icon: faSwords,
|
||||
text: "Attack",
|
||||
callback: () => {
|
||||
setMenu("moves")
|
||||
setGameProps("menu", "moves")
|
||||
},
|
||||
}
|
||||
: {
|
||||
icon: faShip,
|
||||
text: "Ships",
|
||||
callback: () => {
|
||||
setMenu("moves")
|
||||
setGameProps("menu", "moves")
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "pen",
|
||||
text: "Draw",
|
||||
callback: () => {
|
||||
setMenu("draw")
|
||||
setGameProps("menu", "draw")
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "gear",
|
||||
text: "Settings",
|
||||
callback: () => {
|
||||
setMenu("settings")
|
||||
setGameProps("menu", "settings")
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -99,48 +92,46 @@ function EventBar(props: { clear: () => void }) {
|
|||
text: "Surrender",
|
||||
iconColor: "darkred",
|
||||
callback: () => {
|
||||
setMenu("surrender")
|
||||
setGameProps("menu", "surrender")
|
||||
},
|
||||
},
|
||||
],
|
||||
moves:
|
||||
gameState() === "running"
|
||||
gameProps.gameState === "running"
|
||||
? [
|
||||
{
|
||||
icon: "scope",
|
||||
text: "Fire missile",
|
||||
enabled: mode() === 0,
|
||||
enabled: gameProps.mode === 0,
|
||||
callback: () => {
|
||||
setMode(0)
|
||||
setGameProps("mode", 0)
|
||||
setTarget((t) => ({ ...t, show: false }))
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "torpedo",
|
||||
text: "Fire torpedo",
|
||||
enabled: mode() === 1 || mode() === 2,
|
||||
enabled: gameProps.mode === 1 || gameProps.mode === 2,
|
||||
amount:
|
||||
2 -
|
||||
(selfUser()
|
||||
?.moves()
|
||||
.filter((e) => e.type === "htorpedo" || e.type === "vtorpedo")
|
||||
.length ?? 0),
|
||||
(selfUser()?.moves.filter(
|
||||
(e) => e.type === "htorpedo" || e.type === "vtorpedo",
|
||||
).length ?? 0),
|
||||
callback: () => {
|
||||
setMode(1)
|
||||
setGameProps("mode", 1)
|
||||
setTarget((t) => ({ ...t, show: false }))
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "radar",
|
||||
text: "Radar scan",
|
||||
enabled: mode() === 3,
|
||||
enabled: gameProps.mode === 3,
|
||||
amount:
|
||||
1 -
|
||||
(selfUser()
|
||||
?.moves()
|
||||
.filter((e) => e.type === "radar").length ?? 0),
|
||||
(selfUser()?.moves.filter((e) => e.type === "radar").length ??
|
||||
0),
|
||||
callback: () => {
|
||||
setMode(3)
|
||||
setGameProps("mode", 3)
|
||||
setTarget((t) => ({ ...t, show: false }))
|
||||
},
|
||||
},
|
||||
|
@ -152,7 +143,7 @@ function EventBar(props: { clear: () => void }) {
|
|||
amount: 1 - ships().filter((e) => e.size === 2).length,
|
||||
callback: () => {
|
||||
if (1 - ships().filter((e) => e.size === 2).length === 0) return
|
||||
setMode(0)
|
||||
setGameProps("mode", 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -161,7 +152,7 @@ function EventBar(props: { clear: () => void }) {
|
|||
amount: 3 - ships().filter((e) => e.size === 3).length,
|
||||
callback: () => {
|
||||
if (3 - ships().filter((e) => e.size === 3).length === 0) return
|
||||
setMode(1)
|
||||
setGameProps("mode", 1)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -170,7 +161,7 @@ function EventBar(props: { clear: () => void }) {
|
|||
amount: 2 - ships().filter((e) => e.size === 4).length,
|
||||
callback: () => {
|
||||
if (2 - ships().filter((e) => e.size === 4).length === 0) return
|
||||
setMode(2)
|
||||
setGameProps("mode", 2)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -199,31 +190,31 @@ function EventBar(props: { clear: () => void }) {
|
|||
{
|
||||
icon: faGlasses,
|
||||
text: "Spectators",
|
||||
disabled: !allowSpectators(),
|
||||
disabled: !gameProps.allowSpectators,
|
||||
callback: setGameSetting({
|
||||
allowSpectators: !allowSpectators(),
|
||||
allowSpectators: !gameProps.allowSpectators,
|
||||
}),
|
||||
},
|
||||
{
|
||||
icon: faSparkles,
|
||||
text: "Specials",
|
||||
disabled: !allowSpecials(),
|
||||
disabled: !gameProps.allowSpecials,
|
||||
callback: setGameSetting({
|
||||
allowSpecials: !allowSpecials(),
|
||||
allowSpecials: !gameProps.allowSpecials,
|
||||
}),
|
||||
},
|
||||
{
|
||||
icon: faComments,
|
||||
text: "Chat",
|
||||
disabled: !allowChat(),
|
||||
callback: setGameSetting({ allowChat: !allowChat() }),
|
||||
disabled: !gameProps.allowChat,
|
||||
callback: setGameSetting({ allowChat: !gameProps.allowChat }),
|
||||
},
|
||||
{
|
||||
icon: faScribble,
|
||||
text: "Mark/Draw",
|
||||
disabled: !allowMarkDraw(),
|
||||
disabled: !gameProps.allowMarkDraw,
|
||||
callback: setGameSetting({
|
||||
allowMarkDraw: !allowMarkDraw(),
|
||||
allowMarkDraw: !gameProps.allowMarkDraw,
|
||||
}),
|
||||
},
|
||||
],
|
||||
|
@ -243,7 +234,7 @@ function EventBar(props: { clear: () => void }) {
|
|||
text: "No",
|
||||
iconColor: "red",
|
||||
callback: () => {
|
||||
setMenu("main")
|
||||
setGameProps("menu", "main")
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -251,22 +242,22 @@ function EventBar(props: { clear: () => void }) {
|
|||
|
||||
createEffect(() => {
|
||||
if (
|
||||
menu() !== "moves" ||
|
||||
gameState() !== "starting" ||
|
||||
mode() < 0 ||
|
||||
items().moves[mode()].amount
|
||||
gameProps.menu !== "moves" ||
|
||||
gameProps.gameState !== "starting" ||
|
||||
gameProps.mode < 0 ||
|
||||
items().moves[gameProps.mode].amount
|
||||
)
|
||||
return
|
||||
const index = items().moves.findIndex((e) => e.amount)
|
||||
setMode(index)
|
||||
setGameProps("mode", index)
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
setEnable(menu() === "draw")
|
||||
setEnable(gameProps.menu === "draw")
|
||||
})
|
||||
|
||||
// createEffect(() => {
|
||||
// if (gameState() !== "running") return
|
||||
// if (gameProps.gameState !== "running") return
|
||||
|
||||
// const toastId = "otherPlayer"
|
||||
// if (isActiveIndex) toast.dismiss(toastId)
|
||||
|
@ -293,47 +284,55 @@ function EventBar(props: { clear: () => void }) {
|
|||
|
||||
return (
|
||||
<div class="event-bar">
|
||||
<Show when={menu() !== "main"}>
|
||||
<Show when={gameProps.menu !== "main"}>
|
||||
<Item
|
||||
{...{
|
||||
icon: faReply,
|
||||
text: "Return",
|
||||
iconColor: "#555",
|
||||
callback: () => {
|
||||
setMenu("main")
|
||||
setGameProps("menu", "main")
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Show>
|
||||
<For each={items()[menu()]}>
|
||||
<For each={items()[gameProps.menu]}>
|
||||
{(e, i) => (
|
||||
<Show when={isActiveIndex() || menu() !== "main" || i() !== 1}>
|
||||
<Show
|
||||
when={isActiveIndex() || gameProps.menu !== "main" || i() !== 1}
|
||||
>
|
||||
<Item {...e} />
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
<Show when={menu() === "moves"}>
|
||||
<Show when={gameProps.menu === "moves"}>
|
||||
<Item
|
||||
{...{
|
||||
icon: selfUser()?.isReady() ? faLock : faCheck,
|
||||
text: selfUser()?.isReady() ? "unready" : "Done",
|
||||
disabled: gameState() === "starting" ? mode() >= 0 : undefined,
|
||||
enabled: gameState() === "running" && mode() >= 0 && target().show,
|
||||
icon: selfUser()?.isReady ? faLock : faCheck,
|
||||
text: selfUser()?.isReady ? "unready" : "Done",
|
||||
disabled:
|
||||
gameProps.gameState === "starting"
|
||||
? gameProps.mode >= 0
|
||||
: undefined,
|
||||
enabled:
|
||||
gameProps.gameState === "running" &&
|
||||
gameProps.mode >= 0 &&
|
||||
target().show,
|
||||
callback: () => {
|
||||
const i = selfIndex()
|
||||
if (i === -1) return
|
||||
switch (gameState()) {
|
||||
switch (gameProps.gameState) {
|
||||
case "starting":
|
||||
const isReady = !users[i].isReady()
|
||||
const isReady = !users[i]?.isReady
|
||||
setIsReadyFor({ isReady, i })
|
||||
socket.emit("isReady", isReady)
|
||||
break
|
||||
|
||||
case "running":
|
||||
const moves = selfUser()?.moves()
|
||||
const moves = selfUser()?.moves
|
||||
const length = moves?.length
|
||||
const props = {
|
||||
type: modes[mode()].type,
|
||||
type: modes[gameProps.mode].type,
|
||||
x: target().x,
|
||||
y: target().y,
|
||||
orientation: target().orientation,
|
||||
|
|
|
@ -11,12 +11,10 @@ import { useDraw } from "~/hooks/useDraw"
|
|||
import { useDrawProps } from "~/hooks/useDrawProps"
|
||||
import {
|
||||
full,
|
||||
gameId,
|
||||
gameState,
|
||||
mode,
|
||||
gameProps,
|
||||
mouseCursor,
|
||||
reset,
|
||||
setMode,
|
||||
setGameProps,
|
||||
setMouseCursor,
|
||||
setTargetPreview,
|
||||
target,
|
||||
|
@ -40,27 +38,28 @@ function Gamefield() {
|
|||
|
||||
createEffect(() => {
|
||||
if (
|
||||
gameState() !== "starting" ||
|
||||
!users[0].isReady() ||
|
||||
!users[1].isReady()
|
||||
gameProps.gameState !== "starting" ||
|
||||
!users[0]?.isReady ||
|
||||
!users[1]?.isReady
|
||||
)
|
||||
return
|
||||
socket.emit("ships", ships() ?? [])
|
||||
socket.emit("ships", ships())
|
||||
socket.emit("gameState", "running")
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (gameId() || !isConnected()) return
|
||||
if (gameProps.gameId || !isConnected) return
|
||||
socket.emit("update", full)
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (mode() < 0) return
|
||||
if (gameProps.mode < 0) return
|
||||
const { x, y, show } = target()
|
||||
const { shouldShow, ...position } = mouseCursor()
|
||||
if (
|
||||
!shouldShow ||
|
||||
(gameState() === "running" && overlapsWithAnyBorder(position, mode()))
|
||||
(gameProps.gameState === "running" &&
|
||||
overlapsWithAnyBorder(position, gameProps.mode))
|
||||
)
|
||||
setTargetPreview((t) => ({ ...t, show: false }))
|
||||
else {
|
||||
|
@ -71,14 +70,17 @@ function Gamefield() {
|
|||
}))
|
||||
const handleKeyPress = (event: KeyboardEvent) => {
|
||||
if (event.key !== "r") return
|
||||
if (gameState() === "starting") {
|
||||
if (gameProps.gameState === "starting") {
|
||||
setTargetPreview((t) => ({
|
||||
...t,
|
||||
orientation: t.orientation === "h" ? "v" : "h",
|
||||
}))
|
||||
}
|
||||
if (gameState() === "running" && (mode() === 1 || mode() === 2))
|
||||
setMode(mode() === 1 ? 2 : 1)
|
||||
if (
|
||||
gameProps.gameState === "running" &&
|
||||
(gameProps.mode === 1 || gameProps.mode === 2)
|
||||
)
|
||||
setGameProps("mode", gameProps.mode === 1 ? 2 : 1)
|
||||
}
|
||||
document.addEventListener("keydown", handleKeyPress)
|
||||
onCleanup(() => {
|
||||
|
@ -88,7 +90,7 @@ function Gamefield() {
|
|||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (gameState() !== "aborted") return
|
||||
if (gameProps.gameState !== "aborted") return
|
||||
// toast.info("Enemy gave up!")
|
||||
navigator("/")
|
||||
reset()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { For, Show } from "solid-js"
|
||||
import { gameState } from "~/hooks/useGameProps"
|
||||
import { gameProps } from "~/hooks/useGameProps"
|
||||
import { useSession } from "~/hooks/useSession"
|
||||
import Ship from "./Ship"
|
||||
|
||||
|
@ -7,8 +7,8 @@ function Ships() {
|
|||
const { isActiveIndex, selfUser } = useSession()
|
||||
|
||||
return (
|
||||
<Show when={gameState() !== "running" || !isActiveIndex()}>
|
||||
<For each={selfUser()?.ships()}>{(props) => <Ship {...props} />}</For>
|
||||
<Show when={gameProps.gameState !== "running" || !isActiveIndex()}>
|
||||
<For each={selfUser()?.ships}>{(props) => <Ship {...props} />}</For>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { For, Match, Switch } from "solid-js"
|
||||
import { gameState, mode, target, targetPreview } from "~/hooks/useGameProps"
|
||||
import { gameProps, target, targetPreview } from "~/hooks/useGameProps"
|
||||
import { useSession } from "~/hooks/useSession"
|
||||
import {
|
||||
compiledHits,
|
||||
composeTargetTiles,
|
||||
intersectingShip,
|
||||
shipProps,
|
||||
|
@ -11,29 +12,39 @@ import HitElems from "./HitElems"
|
|||
import Ship from "./Ship"
|
||||
|
||||
function Targets() {
|
||||
const { activeUser, ships } = useSession()
|
||||
const { activeIndex, ships } = useSession()
|
||||
|
||||
const ship = () => shipProps(ships(), mode(), targetPreview())
|
||||
const ship = () => shipProps(ships(), gameProps.mode, targetPreview())
|
||||
const intersectionProps = () => intersectingShip(ships(), ship())
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Match when={gameState() === "running"}>
|
||||
<For each={composeTargetTiles(target(), mode(), activeUser().hits())}>
|
||||
<Match when={gameProps.gameState === "running"}>
|
||||
<For
|
||||
each={composeTargetTiles(
|
||||
target(),
|
||||
gameProps.mode,
|
||||
compiledHits(activeIndex() === 0 ? 1 : 0),
|
||||
)}
|
||||
>
|
||||
{(props) => <GamefieldPointer {...props} />}
|
||||
</For>
|
||||
<For
|
||||
each={composeTargetTiles(
|
||||
targetPreview(),
|
||||
mode(),
|
||||
activeUser().hits(),
|
||||
gameProps.mode,
|
||||
compiledHits(activeIndex() === 0 ? 1 : 0),
|
||||
)}
|
||||
>
|
||||
{(props) => <GamefieldPointer {...props} preview />}
|
||||
</For>
|
||||
</Match>
|
||||
<Match
|
||||
when={gameState() === "starting" && mode() >= 0 && targetPreview().show}
|
||||
when={
|
||||
gameProps.gameState === "starting" &&
|
||||
gameProps.mode >= 0 &&
|
||||
targetPreview().show
|
||||
}
|
||||
>
|
||||
<Ship
|
||||
{...ship()}
|
||||
|
|
|
@ -5,15 +5,7 @@ import {
|
|||
import { JSX, Show, createEffect, createSignal, onCleanup } from "solid-js"
|
||||
import { useNavigate } from "solid-start"
|
||||
import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"
|
||||
import {
|
||||
full,
|
||||
gameId,
|
||||
gamePin,
|
||||
gameState,
|
||||
leave,
|
||||
reset,
|
||||
users,
|
||||
} from "~/hooks/useGameProps"
|
||||
import { full, gameProps, leave, reset, users } from "~/hooks/useGameProps"
|
||||
import { useSession } from "~/hooks/useSession"
|
||||
import useSocket from "~/hooks/useSocket"
|
||||
import { socket } from "~/lib/socket"
|
||||
|
@ -45,7 +37,7 @@ function LobbyFrame(props: { openSettings: () => void }) {
|
|||
const navigator = useNavigate()
|
||||
const { session } = useSession()
|
||||
const [launchTime, setLaunchTime] = createSignal(3)
|
||||
const launching = () => users[0].isReady() && users[1].isReady()
|
||||
const launching = () => users[0]?.isReady && users[1]?.isReady
|
||||
|
||||
createEffect(() => {
|
||||
if (!launching() || launchTime() > 0) return
|
||||
|
@ -64,12 +56,13 @@ function LobbyFrame(props: { openSettings: () => void }) {
|
|||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (gameId() || !isConnected()) return
|
||||
if (gameProps.gameId || !isConnected) return
|
||||
socket.emit("update", full)
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (gameState() === "unknown" || gameState() === "lobby") return
|
||||
if (gameProps.gameState === "unknown" || gameProps.gameState === "lobby")
|
||||
return
|
||||
navigator("/gamefield")
|
||||
})
|
||||
|
||||
|
@ -90,10 +83,10 @@ function LobbyFrame(props: { openSettings: () => void }) {
|
|||
>
|
||||
{"Game-PIN: "}
|
||||
<Show
|
||||
when={isConnected()}
|
||||
when={isConnected}
|
||||
fallback={<FontAwesomeIcon icon={faSpinnerThird} spin />}
|
||||
>
|
||||
<span class="underline">{gamePin() ?? "----"}</span>
|
||||
<span class="underline">{gameProps.gamePin ?? "----"}</span>
|
||||
</Show>
|
||||
</Show>
|
||||
</h1>
|
||||
|
@ -103,7 +96,7 @@ function LobbyFrame(props: { openSettings: () => void }) {
|
|||
</div>
|
||||
<div class="flex items-center justify-around">
|
||||
<Show
|
||||
when={isConnected()}
|
||||
when={isConnected}
|
||||
fallback={
|
||||
<p class="font-farro m-48 text-center text-6xl font-medium">
|
||||
Warte auf Verbindung
|
||||
|
@ -113,7 +106,7 @@ function LobbyFrame(props: { openSettings: () => void }) {
|
|||
<>
|
||||
<Player src="player_blue.png" i={0} userId={session()?.user?.id} />
|
||||
<p class="font-farro m-4 text-6xl font-semibold">VS</p>
|
||||
{users[1].id() ? (
|
||||
{users[1] ? (
|
||||
<Player src="player_red.png" i={1} userId={session()?.user?.id} />
|
||||
) : (
|
||||
<p class="font-farro w-96 text-center text-4xl font-medium">
|
||||
|
|
|
@ -44,9 +44,7 @@ function HourGlass() {
|
|||
|
||||
function Player(props: { src: string; i: 0 | 1; userId?: string }) {
|
||||
const player = () => users[props.i]
|
||||
const isReady = () => users[props.i].isReady()
|
||||
const isConnected = () => users[props.i].isConnected()
|
||||
const primary = () => props.userId && props.userId === users[props.i].id()
|
||||
const primary = () => props.userId && props.userId === player()?.id
|
||||
|
||||
return (
|
||||
<div class="flex w-96 flex-col items-center gap-4 p-4">
|
||||
|
@ -56,7 +54,7 @@ function Player(props: { src: string; i: 0 | 1; userId?: string }) {
|
|||
primary() ? "font-semibold" : "font-normal",
|
||||
)}
|
||||
>
|
||||
{player().name() ?? "Spieler " + (props.i === 1 ? "2" : "1")}
|
||||
{player()?.name ?? "Spieler " + (props.i === 1 ? "2" : "1")}
|
||||
</p>
|
||||
<div class="relative">
|
||||
<img
|
||||
|
@ -74,21 +72,27 @@ function Player(props: { src: string; i: 0 | 1; userId?: string }) {
|
|||
</Show>
|
||||
</div>
|
||||
<Button
|
||||
type={isConnected() ? (isReady() ? "green" : "orange") : "gray"}
|
||||
type={
|
||||
player()?.isConnected
|
||||
? player()?.isReady
|
||||
? "green"
|
||||
: "orange"
|
||||
: "gray"
|
||||
}
|
||||
latching
|
||||
isLatched={!!isReady()}
|
||||
isLatched={player()?.isReady}
|
||||
onClick={() => {
|
||||
if (!player()) return
|
||||
socket.emit("isReady", !isReady())
|
||||
socket.emit("isReady", !player()?.isReady)
|
||||
setIsReadyFor({
|
||||
i: props.i,
|
||||
isReady: !isReady(),
|
||||
isReady: !player()?.isReady,
|
||||
})
|
||||
}}
|
||||
disabled={!primary()}
|
||||
>
|
||||
Ready
|
||||
{isReady() && isConnected() ? (
|
||||
{player()?.isReady && player()?.isConnected ? (
|
||||
<FontAwesomeIcon icon={faCheck} class="ml-4 w-12" />
|
||||
) : primary() ? (
|
||||
<FontAwesomeIcon
|
||||
|
|
|
@ -3,11 +3,10 @@ import { socket } from "~/lib/socket"
|
|||
import { GamePropsSchema, GameState } from "~/lib/zodSchemas"
|
||||
// import { toast } from "react-toastify"
|
||||
import { createSignal } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { getPayloadFromProps } from "~/lib/getPayloadFromProps"
|
||||
import { getPayloadwithChecksum } from "~/lib/getPayloadwithChecksum"
|
||||
import {
|
||||
compileHits,
|
||||
initialUser,
|
||||
initlialMouseCursor,
|
||||
initlialTarget,
|
||||
initlialTargetPreview,
|
||||
|
@ -17,81 +16,75 @@ import {
|
|||
GameSettings,
|
||||
MouseCursor,
|
||||
MoveDispatchProps,
|
||||
NewUsers,
|
||||
ShipProps,
|
||||
Target,
|
||||
TargetPreview,
|
||||
User,
|
||||
Users,
|
||||
} from "../interfaces/frontend"
|
||||
|
||||
export const [hash, setHash] = createSignal<string | null>(null)
|
||||
export const [gamePin, setGamePin] = createSignal<string | null>(null)
|
||||
export const [gameId, setGameId] = createSignal<string>("")
|
||||
export const [gameState, setGameState] = createSignal<GameState>("unknown")
|
||||
export const [allowChat, setAllowChat] = createSignal(false)
|
||||
export const [allowMarkDraw, setAllowMarkDraw] = createSignal(false)
|
||||
export const [allowSpecials, setAllowSpecials] = createSignal(false)
|
||||
export const [allowSpectators, setallowSpectators] = createSignal(false)
|
||||
export const [menu, setMenu] = createSignal<keyof EventBarModes>("moves")
|
||||
export const [mode, setMode] = createSignal(0)
|
||||
export interface GameProps {
|
||||
hash: string | null
|
||||
gamePin: string | null
|
||||
gameId: string
|
||||
gameState: GameState
|
||||
allowChat: boolean
|
||||
allowMarkDraw: boolean
|
||||
allowSpecials: boolean
|
||||
allowSpectators: boolean
|
||||
menu: keyof EventBarModes
|
||||
mode: number
|
||||
}
|
||||
|
||||
const initialGameProps = {
|
||||
hash: null,
|
||||
gamePin: null,
|
||||
gameId: "",
|
||||
gameState: "unknown",
|
||||
allowChat: false,
|
||||
allowMarkDraw: false,
|
||||
allowSpecials: false,
|
||||
allowSpectators: false,
|
||||
menu: "moves",
|
||||
mode: 0,
|
||||
} satisfies GameProps
|
||||
|
||||
export const [gameProps, setGameProps] =
|
||||
createStore<GameProps>(initialGameProps)
|
||||
|
||||
const initialUsers = { 0: null, 1: null }
|
||||
export const [users, setUsers] = createStore<Users>(initialUsers)
|
||||
|
||||
export const [target, setTarget] = createSignal<Target>(initlialTarget)
|
||||
export const [targetPreview, setTargetPreview] = createSignal<TargetPreview>(
|
||||
initlialTargetPreview,
|
||||
)
|
||||
export const [mouseCursor, setMouseCursor] =
|
||||
createSignal<MouseCursor>(initlialMouseCursor)
|
||||
export const users = {
|
||||
0: {
|
||||
...initialUser(),
|
||||
hits: () => compileHits(users, 0),
|
||||
},
|
||||
1: { ...initialUser(), hits: () => compileHits(users, 1) },
|
||||
forEach(cb: (user: ReturnType<typeof initialUser>, i: 0 | 1) => void) {
|
||||
cb(this[0], 0)
|
||||
cb(this[1], 1)
|
||||
},
|
||||
map<T>(cb: (user: ReturnType<typeof initialUser>, i: 0 | 1) => T) {
|
||||
return { 0: cb(this[0], 0), 1: cb(this[1], 1) }
|
||||
},
|
||||
}
|
||||
export type Users = typeof users
|
||||
|
||||
export function DispatchMove(move: MoveDispatchProps, index: 0 | 1) {
|
||||
users[index].setMoves((e) => [...e, move])
|
||||
setUsers(index, "moves", (e) => [...e, move])
|
||||
}
|
||||
export function setShips(ships: ShipProps[], index: number) {
|
||||
users.forEach(({ setShips }, i) => {
|
||||
if (index !== i) return
|
||||
setShips(ships)
|
||||
})
|
||||
export function setShips(ships: ShipProps[], index: 0 | 1) {
|
||||
setUsers(index, "ships", ships)
|
||||
}
|
||||
export function removeShip({ size, variant, x, y }: ShipProps, index: number) {
|
||||
users.forEach((user, i) => {
|
||||
if (index !== i) return
|
||||
const indexToRemove = user
|
||||
.ships()
|
||||
.findIndex(
|
||||
export function removeShip({ size, variant, x, y }: ShipProps, index: 0 | 1) {
|
||||
setUsers(index, "ships", (ships) => {
|
||||
const indexToRemove = ships.findIndex(
|
||||
(ship) =>
|
||||
ship.size === size &&
|
||||
ship.variant === variant &&
|
||||
ship.x === x &&
|
||||
ship.y === y,
|
||||
)
|
||||
user.setShips((ships) => ships.filter((_, i) => i !== indexToRemove))
|
||||
|
||||
return ships.filter((_, i) => i !== indexToRemove)
|
||||
})
|
||||
}
|
||||
|
||||
export function setPlayer(newUsers: NewUsers): string | null {
|
||||
export function setPlayer(newUsers: Users): string | null {
|
||||
let hash: string | null = null
|
||||
users.forEach((user, i) => {
|
||||
const newUser = newUsers[i]
|
||||
if (!newUser) return defaultUser(user)
|
||||
|
||||
user.setId(newUser.id)
|
||||
user.setName(newUser.name)
|
||||
user.setChats(newUser.chats)
|
||||
user.setMoves(newUser.moves)
|
||||
user.setShips(newUser.ships)
|
||||
})
|
||||
setUsers(newUsers)
|
||||
const body = getPayloadwithChecksum(getPayloadFromProps())
|
||||
if (!body.hash) {
|
||||
console.log("Something is wrong... ")
|
||||
|
@ -102,15 +95,15 @@ export function setPlayer(newUsers: NewUsers): string | null {
|
|||
return null
|
||||
}
|
||||
hash = body.hash
|
||||
setHash(hash)
|
||||
setGameProps("hash", hash)
|
||||
return hash
|
||||
}
|
||||
export function setSetting(newSettings: GameSettings): string | null {
|
||||
let hash: string | null = null
|
||||
setAllowChat((e) => newSettings.allowChat ?? e)
|
||||
setAllowMarkDraw((e) => newSettings.allowMarkDraw ?? e)
|
||||
setAllowSpecials((e) => newSettings.allowSpecials ?? e)
|
||||
setallowSpectators((e) => newSettings.allowSpectators ?? e)
|
||||
setGameProps("allowChat", (e) => newSettings.allowChat ?? e)
|
||||
setGameProps("allowMarkDraw", (e) => newSettings.allowMarkDraw ?? e)
|
||||
setGameProps("allowSpecials", (e) => newSettings.allowSpecials ?? e)
|
||||
setGameProps("allowSpectators", (e) => newSettings.allowSpectators ?? e)
|
||||
const body = getPayloadwithChecksum(getPayloadFromProps())
|
||||
if (!body.hash) {
|
||||
console.log("Something is wrong... ")
|
||||
|
@ -121,7 +114,7 @@ export function setSetting(newSettings: GameSettings): string | null {
|
|||
return null
|
||||
}
|
||||
hash = body.hash
|
||||
setHash(hash)
|
||||
setGameProps("hash", hash)
|
||||
return hash
|
||||
}
|
||||
|
||||
|
@ -137,36 +130,41 @@ export function setGameSetting(newSettings: GameSettings) {
|
|||
}
|
||||
|
||||
export function full(newProps: GamePropsSchema) {
|
||||
if (hash() === newProps.hash) {
|
||||
if (gameProps.hash === newProps.hash) {
|
||||
console.log("Everything up to date.")
|
||||
} else {
|
||||
console.log("Update was needed.", hash(), newProps.hash)
|
||||
console.log("Update was needed.", gameProps.hash, newProps.hash)
|
||||
|
||||
if (gameId() !== newProps.payload?.game?.id)
|
||||
if (gameProps.gameId !== newProps.payload?.game?.id)
|
||||
console.warn(
|
||||
"Different gameId detected on update: ",
|
||||
gameId(),
|
||||
gameProps.gameId,
|
||||
newProps.payload?.game?.id,
|
||||
)
|
||||
|
||||
setHash(newProps.hash)
|
||||
setGamePin(newProps.payload.gamePin)
|
||||
setGameId(newProps.payload.game?.id ?? "")
|
||||
setGameState(newProps.payload.game?.state ?? "unknown")
|
||||
setAllowChat(newProps.payload.game?.allowChat ?? false)
|
||||
setAllowMarkDraw(newProps.payload.game?.allowMarkDraw ?? false)
|
||||
setAllowSpecials(newProps.payload.game?.allowSpecials ?? false)
|
||||
setallowSpectators(newProps.payload.game?.allowSpectators ?? false)
|
||||
users.forEach((user, i) => {
|
||||
const newUser = newProps.payload.users[i]
|
||||
if (!newUser) return
|
||||
|
||||
user.setId(newUser.id)
|
||||
user.setName(newUser.name)
|
||||
user.setChats(newUser.chats)
|
||||
user.setMoves(newUser.moves)
|
||||
user.setShips(newUser.ships)
|
||||
setGameProps({
|
||||
hash: newProps.hash,
|
||||
gamePin: newProps.payload.gamePin,
|
||||
gameId: newProps.payload.game?.id ?? "",
|
||||
gameState: newProps.payload.game?.state ?? "unknown",
|
||||
allowChat: newProps.payload.game?.allowChat ?? false,
|
||||
allowMarkDraw: newProps.payload.game?.allowMarkDraw ?? false,
|
||||
allowSpecials: newProps.payload.game?.allowSpecials ?? false,
|
||||
allowSpectators: newProps.payload.game?.allowSpectators ?? false,
|
||||
})
|
||||
const compiledUsers = [
|
||||
newProps.payload.users[0],
|
||||
newProps.payload.users[1],
|
||||
].map((user) =>
|
||||
user
|
||||
? {
|
||||
...user,
|
||||
isReady: false,
|
||||
isConnected: false,
|
||||
}
|
||||
: null,
|
||||
) as [User, User]
|
||||
setUsers({ 0: compiledUsers[0], 1: compiledUsers[1] })
|
||||
}
|
||||
}
|
||||
export function leave(cb: () => void) {
|
||||
|
@ -179,12 +177,12 @@ export function leave(cb: () => void) {
|
|||
})
|
||||
}
|
||||
export function setIsReadyFor({ i, isReady }: { i: 0 | 1; isReady: boolean }) {
|
||||
users[i].setIsReady(isReady)
|
||||
users[i].setIsConnected(true)
|
||||
setUsers(i, (e) => ({ ...e, isReady, isConnected: true }))
|
||||
}
|
||||
export function newGameState(newState: GameState) {
|
||||
setGameState(newState)
|
||||
users.forEach((e) => e.setIsReady(false))
|
||||
setGameProps("gameState", newState)
|
||||
setUsers(0, (e) => (e && e.isReady ? { isReady: false } : e))
|
||||
setUsers(1, (e) => (e && e.isReady ? { isReady: false } : e))
|
||||
}
|
||||
export function setIsConnectedFor({
|
||||
i,
|
||||
|
@ -193,34 +191,15 @@ export function setIsConnectedFor({
|
|||
i: 0 | 1
|
||||
isConnected: boolean
|
||||
}) {
|
||||
users[i].setIsConnected(isConnected)
|
||||
setUsers(i, "isConnected", isConnected)
|
||||
if (isConnected) return
|
||||
users[i].setIsReady(false)
|
||||
setUsers(i, "isReady", false)
|
||||
}
|
||||
|
||||
export function reset() {
|
||||
setHash(null)
|
||||
setGamePin(null)
|
||||
setGameId("")
|
||||
setGameState("unknown")
|
||||
setallowSpectators(false)
|
||||
setAllowSpecials(false)
|
||||
setAllowChat(false)
|
||||
setAllowMarkDraw(false)
|
||||
setMenu("moves")
|
||||
setMode(0)
|
||||
setGameProps(initialGameProps)
|
||||
setTarget(initlialTarget)
|
||||
setTargetPreview(initlialTargetPreview)
|
||||
setMouseCursor(initlialMouseCursor)
|
||||
users.forEach(defaultUser)
|
||||
}
|
||||
|
||||
function defaultUser(user: ReturnType<typeof initialUser>) {
|
||||
user.setIsReady(false)
|
||||
user.setIsConnected(false)
|
||||
user.setId("")
|
||||
user.setName("")
|
||||
user.setChats([])
|
||||
user.setMoves([])
|
||||
user.setShips([])
|
||||
setUsers(initialUsers)
|
||||
}
|
||||
|
|
|
@ -9,14 +9,15 @@ import {
|
|||
useContext,
|
||||
} from "solid-js"
|
||||
import { useIsRouting } from "solid-start"
|
||||
import { gameState, setMenu, setMode, users } from "./useGameProps"
|
||||
import { gameProps, setGameProps, users } from "./useGameProps"
|
||||
|
||||
const [state, setState] = createSignal<Session | null | undefined>(undefined)
|
||||
|
||||
const selfIndex = () => {
|
||||
switch (state()?.user?.id) {
|
||||
case users[0].id():
|
||||
case users[0]?.id:
|
||||
return 0
|
||||
case users[1].id():
|
||||
case users[1]?.id:
|
||||
return 1
|
||||
default:
|
||||
return -1
|
||||
|
@ -24,9 +25,9 @@ const selfIndex = () => {
|
|||
}
|
||||
|
||||
const activeIndex = () => {
|
||||
if (gameState() !== "running") return 0
|
||||
const l1 = users[0].moves().length
|
||||
const l2 = users[1].moves().length
|
||||
if (gameProps.gameState !== "running") return 0
|
||||
const l1 = users[0]?.moves.length ?? 0
|
||||
const l2 = users[1]?.moves.length ?? 0
|
||||
return l1 > l2 ? 1 : 0
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,8 @@ const selfUser = () => {
|
|||
*/
|
||||
const activeUser = () => users[activeIndex() === 0 ? 1 : 0]
|
||||
|
||||
const ships = () => selfUser()?.ships() ?? []
|
||||
const ships = () => selfUser()?.ships ?? []
|
||||
|
||||
const contextValue = {
|
||||
session: state,
|
||||
selfIndex,
|
||||
|
@ -82,13 +84,13 @@ export function SessionProvider(props: { children: JSX.Element }) {
|
|||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (gameState() !== "running") return
|
||||
if (gameProps.gameState !== "running") return
|
||||
if (activeIndex() === selfIndex()) {
|
||||
setMenu("moves")
|
||||
setMode(0)
|
||||
setGameProps("menu", "moves")
|
||||
setGameProps("mode", 0)
|
||||
} else {
|
||||
setMenu("main")
|
||||
setMode(-1)
|
||||
setGameProps("menu", "main")
|
||||
setGameProps("mode", -1)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -3,14 +3,15 @@ import status from "http-status"
|
|||
import { createEffect, createSignal, onCleanup } from "solid-js"
|
||||
import { useNavigate } from "solid-start"
|
||||
import { socket } from "~/lib/socket"
|
||||
import { GamePropsSchema } from "~/lib/zodSchemas"
|
||||
import { frontendUsers } from "~/lib/utils/helpers"
|
||||
import { GamePropsSchema, GameState } from "~/lib/zodSchemas"
|
||||
import { isAuthenticated } from "~/routes/start"
|
||||
import { GameSettings, PlayerEvent } from "../interfaces/frontend"
|
||||
import {
|
||||
DispatchMove,
|
||||
full,
|
||||
gameId,
|
||||
setGameState,
|
||||
gameProps,
|
||||
setGameProps,
|
||||
setIsConnectedFor,
|
||||
setIsReadyFor,
|
||||
setPlayer,
|
||||
|
@ -29,7 +30,7 @@ function useSocket() {
|
|||
const isConnected = () => {
|
||||
const i = selfIndex()
|
||||
return i !== -1
|
||||
? users[i].isConnected() && isConnectedState()
|
||||
? users[i]?.isConnected && isConnectedState()
|
||||
: isConnectedState()
|
||||
}
|
||||
|
||||
|
@ -87,7 +88,8 @@ function useSocket() {
|
|||
isConnected: true,
|
||||
})
|
||||
const index = selfIndex()
|
||||
if (index !== -1) socket.emit("isReady", users[index].isReady())
|
||||
if (index !== -1)
|
||||
socket.emit("isReady", users[index]?.isReady ?? false)
|
||||
message = "Player has joined the lobby."
|
||||
break
|
||||
|
||||
|
@ -100,7 +102,7 @@ function useSocket() {
|
|||
if (type === "disconnect") return
|
||||
|
||||
const { hash } = event
|
||||
const newHash = setPlayer(event.users)
|
||||
const newHash = setPlayer(frontendUsers(event.users))
|
||||
if (!newHash || newHash === hash) return
|
||||
console.log("hash", hash, newHash)
|
||||
socket.emit("update", (body) => {
|
||||
|
@ -109,6 +111,8 @@ function useSocket() {
|
|||
})
|
||||
}
|
||||
|
||||
const setGameState = (state: GameState) => setGameProps("gameState", state)
|
||||
|
||||
const gameSetting = (newSettings: GameSettings, hash: string) => {
|
||||
const newHash = setSetting(newSettings)
|
||||
if (!newHash || newHash === hash) return
|
||||
|
@ -148,7 +152,7 @@ function useSocket() {
|
|||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (!gameId()) {
|
||||
if (!gameProps.gameId) {
|
||||
socket.disconnect()
|
||||
fetch("/api/game/running", {
|
||||
method: "GET",
|
||||
|
|
|
@ -26,11 +26,11 @@ export interface ServerToClientEvents {
|
|||
isReady: (payload: { i: 0 | 1; isReady: boolean }) => void
|
||||
isConnected: (payload: { i: 0 | 1; isConnected: boolean }) => void
|
||||
"get-canvas-state": () => void
|
||||
"canvas-state-from-server": (state: string, userIndex: number) => void
|
||||
"draw-line": (props: DrawLineProps, userIndex: number) => void
|
||||
"canvas-state-from-server": (state: string, userIndex: 0 | 1) => void
|
||||
"draw-line": (props: DrawLineProps, userIndex: 0 | 1) => void
|
||||
"canvas-clear": () => void
|
||||
gameState: (newState: GameState) => void
|
||||
ships: (ships: ShipProps[], index: number) => void
|
||||
ships: (ships: ShipProps[], index: 0 | 1) => void
|
||||
dispatchMove: (props: MoveDispatchProps, i: 0 | 1) => void
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ interface SocketData {
|
|||
props: {
|
||||
userId: string
|
||||
gameId: string
|
||||
index: number
|
||||
index: 0 | 1
|
||||
}
|
||||
user: Session["user"]
|
||||
gameId: string
|
||||
|
|
|
@ -81,11 +81,15 @@ export type PlayerEvent =
|
|||
| {
|
||||
type: "connect" | "leave"
|
||||
i: 0 | 1
|
||||
users: NewUsers
|
||||
users: Players
|
||||
hash: string
|
||||
}
|
||||
| {
|
||||
type: "disconnect"
|
||||
i: 0 | 1
|
||||
}
|
||||
export type NewUsers = { 0: PlayerSchema | null; 1: PlayerSchema | null }
|
||||
export type Players = { 0: PlayerSchema; 1: PlayerSchema }
|
||||
export type User =
|
||||
| (PlayerSchema & { isReady: boolean; isConnected: boolean })
|
||||
| null
|
||||
export type Users = { 0: User; 1: User }
|
||||
|
|
|
@ -1,32 +1,28 @@
|
|||
import {
|
||||
allowChat,
|
||||
allowMarkDraw,
|
||||
allowSpecials,
|
||||
allowSpectators,
|
||||
gameId,
|
||||
gamePin,
|
||||
gameState,
|
||||
users,
|
||||
} from "~/hooks/useGameProps"
|
||||
import { gameProps, users } from "~/hooks/useGameProps"
|
||||
|
||||
export function getPayloadFromProps() {
|
||||
const reducedUsers = [users[0], users[1]].map((user, i) =>
|
||||
user
|
||||
? {
|
||||
index: i,
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
chats: user.chats,
|
||||
moves: user.moves,
|
||||
ships: user.ships,
|
||||
}
|
||||
: null,
|
||||
)
|
||||
return {
|
||||
game: {
|
||||
id: gameId(),
|
||||
state: gameState(),
|
||||
allowChat: allowChat(),
|
||||
allowMarkDraw: allowMarkDraw(),
|
||||
allowSpecials: allowSpecials(),
|
||||
allowSpectators: allowSpectators(),
|
||||
id: gameProps.gameId,
|
||||
state: gameProps.gameState,
|
||||
allowChat: gameProps.allowChat,
|
||||
allowMarkDraw: gameProps.allowMarkDraw,
|
||||
allowSpecials: gameProps.allowSpecials,
|
||||
allowSpectators: gameProps.allowSpectators,
|
||||
},
|
||||
gamePin: gamePin(),
|
||||
users: users.map((user, i) => ({
|
||||
index: i,
|
||||
id: user.id(),
|
||||
name: user.name(),
|
||||
chats: user.chats(),
|
||||
moves: user.moves(),
|
||||
ships: user.ships(),
|
||||
})),
|
||||
gamePin: gameProps.gamePin,
|
||||
users: { 0: reducedUsers[0], 1: reducedUsers[1] },
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import { createSignal } from "solid-js"
|
||||
import { count } from "~/components/Gamefield/Gamefield"
|
||||
import { Users } from "~/hooks/useGameProps"
|
||||
import { users } from "~/hooks/useGameProps"
|
||||
import type {
|
||||
Hit,
|
||||
IndexedPosition,
|
||||
Mode,
|
||||
Players,
|
||||
PointerProps,
|
||||
Position,
|
||||
ShipProps,
|
||||
Target,
|
||||
TargetList,
|
||||
TargetPreview,
|
||||
User,
|
||||
} from "../../interfaces/frontend"
|
||||
import { ChatSchema, MoveSchema, MoveType, Orientation } from "../zodSchemas"
|
||||
import { MoveType, Orientation } from "../zodSchemas"
|
||||
|
||||
export function borderCN(count: number, x: number, y: number) {
|
||||
if (x === 0) return "left"
|
||||
|
@ -131,31 +132,6 @@ export const initlialMouseCursor = {
|
|||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
export function initialUser() {
|
||||
const [isReady, setIsReady] = createSignal(false)
|
||||
const [isConnected, setIsConnected] = createSignal(false)
|
||||
const [id, setId] = createSignal<string>("")
|
||||
const [name, setName] = createSignal<string>("")
|
||||
const [chats, setChats] = createSignal<ChatSchema[]>([])
|
||||
const [moves, setMoves] = createSignal<MoveSchema[]>([])
|
||||
const [ships, setShips] = createSignal<ShipProps[]>([])
|
||||
return {
|
||||
isReady,
|
||||
setIsReady,
|
||||
isConnected,
|
||||
setIsConnected,
|
||||
id,
|
||||
setId,
|
||||
name,
|
||||
setName,
|
||||
chats,
|
||||
setChats,
|
||||
moves,
|
||||
setMoves,
|
||||
ships,
|
||||
setShips,
|
||||
}
|
||||
}
|
||||
|
||||
export const shipProps = (
|
||||
ships: ShipProps[],
|
||||
|
@ -249,14 +225,16 @@ export function intersectingShip(
|
|||
}
|
||||
}
|
||||
|
||||
export function compileHits(users: Users, i: 0 | 1) {
|
||||
return users[i === 0 ? 1 : 0].moves().reduce((hits, move) => {
|
||||
export function compiledHits(i: 0 | 1) {
|
||||
return (
|
||||
users[i === 0 ? 1 : 0]?.moves.reduce((hits, move) => {
|
||||
const list = targetList(move, move.type)
|
||||
if (move.type === MoveType.Enum.radar) return hits
|
||||
return [
|
||||
return move.type === MoveType.Enum.radar
|
||||
? hits
|
||||
: [
|
||||
...hits,
|
||||
...list.map(({ x, y }) => ({
|
||||
hit: !!intersectingShip(users[i].ships(), {
|
||||
hit: !!intersectingShip(users[i]?.ships ?? [], {
|
||||
...move,
|
||||
size: 1,
|
||||
variant: 0,
|
||||
|
@ -265,5 +243,19 @@ export function compileHits(users: Users, i: 0 | 1) {
|
|||
y,
|
||||
})),
|
||||
]
|
||||
}, [] as Hit[])
|
||||
}, [] as Hit[]) ?? []
|
||||
)
|
||||
}
|
||||
|
||||
export const frontendUsers = (users: Players) => {
|
||||
const compiledUsers = [users[0], users[1]].map((user) =>
|
||||
user
|
||||
? {
|
||||
...user,
|
||||
isReady: false,
|
||||
isConnected: false,
|
||||
}
|
||||
: null,
|
||||
) as [User, User]
|
||||
return { 0: compiledUsers[0], 1: compiledUsers[1] }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue