diff --git a/leaky-ships/src/components/Gamefield/BorderTiles.tsx b/leaky-ships/src/components/Gamefield/BorderTiles.tsx
index 5a29274..2dcab34 100644
--- a/leaky-ships/src/components/Gamefield/BorderTiles.tsx
+++ b/leaky-ships/src/components/Gamefield/BorderTiles.tsx
@@ -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,
diff --git a/leaky-ships/src/components/Gamefield/EventBar.tsx b/leaky-ships/src/components/Gamefield/EventBar.tsx
index 8b164a8..80d3a1d 100644
--- a/leaky-ships/src/components/Gamefield/EventBar.tsx
+++ b/leaky-ships/src/components/Gamefield/EventBar.tsx
@@ -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 (
-
+
- {
- setMenu("main")
+ setGameProps("menu", "main")
},
}}
/>
-
+
{(e, i) => (
-
+
)}
-
+
- = 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,
diff --git a/leaky-ships/src/components/Gamefield/Gamefield.tsx b/leaky-ships/src/components/Gamefield/Gamefield.tsx
index f2205fb..fefb352 100644
--- a/leaky-ships/src/components/Gamefield/Gamefield.tsx
+++ b/leaky-ships/src/components/Gamefield/Gamefield.tsx
@@ -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()
diff --git a/leaky-ships/src/components/Gamefield/Ships.tsx b/leaky-ships/src/components/Gamefield/Ships.tsx
index 3686cc9..76235ac 100644
--- a/leaky-ships/src/components/Gamefield/Ships.tsx
+++ b/leaky-ships/src/components/Gamefield/Ships.tsx
@@ -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 (
-
- {(props) => }
+
+ {(props) => }
)
}
diff --git a/leaky-ships/src/components/Gamefield/Targets.tsx b/leaky-ships/src/components/Gamefield/Targets.tsx
index d4dab9b..d1f255f 100644
--- a/leaky-ships/src/components/Gamefield/Targets.tsx
+++ b/leaky-ships/src/components/Gamefield/Targets.tsx
@@ -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 (
-
-
+
+
{(props) => }
{(props) => }
= 0 && targetPreview().show}
+ when={
+ gameProps.gameState === "starting" &&
+ gameProps.mode >= 0 &&
+ targetPreview().show
+ }
>
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: "}
}
>
- {gamePin() ?? "----"}
+ {gameProps.gamePin ?? "----"}
@@ -103,7 +96,7 @@ function LobbyFrame(props: { openSettings: () => void }) {
Warte auf Verbindung
@@ -113,7 +106,7 @@ function LobbyFrame(props: { openSettings: () => void }) {
<>
VS
- {users[1].id() ? (
+ {users[1] ? (
) : (
diff --git a/leaky-ships/src/components/Lobby/Player.tsx b/leaky-ships/src/components/Lobby/Player.tsx
index f8ca028..6d3b768 100644
--- a/leaky-ships/src/components/Lobby/Player.tsx
+++ b/leaky-ships/src/components/Lobby/Player.tsx
@@ -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 (
@@ -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")}