tome-web/client/game/Game.tsx

178 lines
5.1 KiB
TypeScript
Raw Normal View History

2021-09-24 06:51:17 -04:00
import React from 'react'
2021-09-23 23:34:33 -04:00
2021-09-24 06:51:17 -04:00
import type { GameHandle, Selection } from './types.ts'
import BoardSlot from './BoardSlot.tsx'
import CardToken from './cards/Card.tsx'
import {
isAttackSelection,
isMoveSelection,
isPlayCardSelection,
isAlly,
isBoard,
isHand,
} from './selection.tsx'
2021-09-23 23:34:33 -04:00
2021-09-24 06:51:17 -04:00
type GameProps = GameHandle
2021-09-23 23:34:33 -04:00
export default function Game(props: GameProps): JSX.Element {
const {
team,
board,
player,
deck,
enemyLife,
enemyDeckSize,
enemyHandSize,
currentTurn,
canDraw,
hasDrawn,
gameStatus,
drawChoices,
startTurn,
endTurn,
startDraw,
commitDraw,
attackCard,
moveCard,
playCard,
getView,
} = props
2021-09-24 06:51:17 -04:00
const [selection, setSelection] = React.useState<Selection | null>(null)
2021-09-23 23:34:33 -04:00
2021-09-24 06:51:17 -04:00
function selectCard(nextSelection: Selection): void {
if (selection === null) {
2021-09-24 06:51:17 -04:00
setSelection(nextSelection)
} else {
if (isAttackSelection(selection, nextSelection)) {
attackCard(selection.index, nextSelection.index)
} else if (isMoveSelection(selection, nextSelection)) {
moveCard(selection.index, nextSelection.index)
} else if (isPlayCardSelection(selection, nextSelection)) {
playCard(selection.index, nextSelection.index)
}
setSelection(null)
}
}
2021-09-23 23:34:33 -04:00
React.useEffect(() => {
if (currentTurn === team) {
startTurn()
}
}, [currentTurn, startTurn])
React.useEffect(() => {
const intervalId = setInterval(
() => {
getView()
},
1000,
)
return () => {
clearInterval(intervalId)
}
}, [getView])
2021-09-23 23:34:33 -04:00
2021-09-24 06:51:17 -04:00
const enemyBoard = team === 1 ? board.scourge : board.sentinal
const allyBoard = team === 1 ? board.sentinal : board.scourge
const isMyTurn = currentTurn === team
2021-09-23 23:34:33 -04:00
return (
2021-09-24 06:51:17 -04:00
<div className="game-container">
<div className="game-sidebar">
<div className="player-info">
<h4>Opponent</h4>
<p>Life: {enemyLife}</p>
<p>Deck: {enemyDeckSize}</p>
</div>
<div>
<p>{isMyTurn ? 'My' : 'Enemy'} Turn</p>
{isMyTurn && canDraw && <button type="button" onClick={startDraw}>Start Draw</button>}
{isMyTurn && hasDrawn && <button type="button" onClick={endTurn}>End Turn</button>}
</div>
2021-09-24 06:51:17 -04:00
<div className="player-info">
<p>Life: {player.life}</p>
<p>Deck: {deck.cards.length}</p>
2021-09-24 06:51:17 -04:00
</div>
</div>
<div className="game-board">
<div className="hand">
{Array(enemyHandSize).fill(null).map(() => (
<CardToken cardKey={null} isSelected={false} disabled />
2021-09-24 06:51:17 -04:00
))}
</div>
<div className="fighter-area enemy">
{enemyBoard.map((card, index) => (
<BoardSlot
card={card ?? null}
onSelect={() => selectCard({target: 'opponent', type: 'board', index})}
isSelected={
selection
? !isAlly(selection) && isBoard(selection) && selection.index === index
: false
}
disabled={!(currentTurn === team && hasDrawn)}
2021-09-24 06:51:17 -04:00
/>
))}
</div>
<div className="fighter-area ally">
{allyBoard.map((card, index) => (
<BoardSlot
card={card ?? null}
onSelect={() => selectCard({target: 'ally', type: 'board', index})}
isSelected={
selection
? isAlly(selection) && isBoard(selection) && selection.index === index
: false
}
disabled={!(currentTurn === team && hasDrawn)}
2021-09-24 06:51:17 -04:00
/>
))}
</div>
{drawChoices.length > 0 && (
<React.Fragment>
<div className="draw-choices">
{drawChoices.map((card, index) => (
<CardToken
cardKey={card.type === -1 ? null : card.type}
onSelect={() => selectCard({target: 'ally', type: 'draws', index})}
isSelected={
selection
? selection.type === 'draws' && selection.index === index
: false
}
disabled={false}
/>
))}
</div>
<div>
<button
type="button"
onClick={
() => selection && selection.type === 'draws' && commitDraw(selection.index)
}
disabled={selection?.type !== 'draws'}
>
Draw Card
</button>
</div>
</React.Fragment>
)}
2021-09-24 06:51:17 -04:00
<div className="hand">
{player.hand.map((card, index) => (
<CardToken
cardKey={card.type === -1 ? null : card.type}
2021-09-24 06:51:17 -04:00
onSelect={() => selectCard({target: 'ally', type: 'hand', index})}
isSelected={
selection
? isAlly(selection) && isHand(selection) && selection.index === index
: false
}
disabled={!(isMyTurn && hasDrawn)}
2021-09-24 06:51:17 -04:00
/>
))}
</div>
</div>
</div>
2021-09-23 23:34:33 -04:00
)
}