mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
implement gameboard v1
This commit is contained in:
parent
b103db681b
commit
0d7336edc2
177 changed files with 16995 additions and 139 deletions
|
|
@ -0,0 +1,156 @@
|
|||
import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Check from '@mui/icons-material/Check';
|
||||
|
||||
import { useWebClient } from '@app/hooks';
|
||||
import { GameSelectors, useAppSelector } from '@app/store';
|
||||
import { App } from '@app/types';
|
||||
|
||||
import './ZoneContextMenu.css';
|
||||
|
||||
export interface ZoneContextMenuProps {
|
||||
isOpen: boolean;
|
||||
anchorPosition: { top: number; left: number } | null;
|
||||
gameId: number;
|
||||
playerId: number | null;
|
||||
zoneName: string | null;
|
||||
onClose: () => void;
|
||||
onRequestDrawN: () => void;
|
||||
onRequestDumpN: () => void;
|
||||
onRequestRevealTopN: () => void;
|
||||
onRequestRevealZone: () => void;
|
||||
}
|
||||
|
||||
function ZoneContextMenu({
|
||||
isOpen,
|
||||
anchorPosition,
|
||||
gameId,
|
||||
playerId,
|
||||
zoneName,
|
||||
onClose,
|
||||
onRequestDrawN,
|
||||
onRequestDumpN,
|
||||
onRequestRevealTopN,
|
||||
onRequestRevealZone,
|
||||
}: ZoneContextMenuProps) {
|
||||
const webClient = useWebClient();
|
||||
|
||||
const zone = useAppSelector((state) =>
|
||||
playerId != null && zoneName != null
|
||||
? GameSelectors.getZone(state, gameId, playerId, zoneName)
|
||||
: undefined,
|
||||
);
|
||||
|
||||
if (playerId == null || zoneName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const game = webClient.request.game;
|
||||
const alwaysReveal = zone?.alwaysRevealTopCard ?? false;
|
||||
const alwaysLook = zone?.alwaysLookAtTopCard ?? false;
|
||||
|
||||
// Close-then-act helpers (avoid duplicating onClose at every site).
|
||||
const run = (fn: () => void) => () => {
|
||||
fn();
|
||||
onClose();
|
||||
};
|
||||
|
||||
const handleDrawOne = () => {
|
||||
game.drawCards(gameId, { number: 1 });
|
||||
};
|
||||
|
||||
const handleShuffle = () => {
|
||||
game.shuffle(gameId, { zoneName: App.ZoneName.DECK, start: 0, end: -1 });
|
||||
};
|
||||
|
||||
const handleRevealTop = () => {
|
||||
game.revealCards(gameId, {
|
||||
zoneName: App.ZoneName.DECK,
|
||||
playerId: -1,
|
||||
topCards: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleAlwaysReveal = () => {
|
||||
game.changeZoneProperties(gameId, {
|
||||
zoneName: App.ZoneName.DECK,
|
||||
alwaysRevealTopCard: !alwaysReveal,
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleAlwaysLook = () => {
|
||||
game.changeZoneProperties(gameId, {
|
||||
zoneName: App.ZoneName.DECK,
|
||||
alwaysLookAtTopCard: !alwaysLook,
|
||||
});
|
||||
};
|
||||
|
||||
const menuItems: React.ReactNode[] = [];
|
||||
|
||||
if (zoneName === App.ZoneName.DECK) {
|
||||
menuItems.push(
|
||||
<MenuItem key="draw-one" onClick={run(handleDrawOne)}>Draw a card</MenuItem>,
|
||||
<MenuItem key="draw-n" onClick={run(onRequestDrawN)}>Draw N cards…</MenuItem>,
|
||||
<MenuItem key="shuffle" onClick={run(handleShuffle)}>Shuffle</MenuItem>,
|
||||
<MenuItem key="dump-n" onClick={run(onRequestDumpN)}>Dump top N…</MenuItem>,
|
||||
<Divider key="d1" />,
|
||||
<MenuItem key="reveal-top" onClick={run(handleRevealTop)}>
|
||||
Reveal top card to all
|
||||
</MenuItem>,
|
||||
<MenuItem key="reveal-top-n" onClick={run(onRequestRevealTopN)}>
|
||||
Reveal top N to…
|
||||
</MenuItem>,
|
||||
<Divider key="d2" />,
|
||||
<MenuItem
|
||||
key="always-reveal"
|
||||
onClick={run(handleToggleAlwaysReveal)}
|
||||
className="zone-context-menu__toggle"
|
||||
>
|
||||
<span className="zone-context-menu__check" aria-hidden>
|
||||
{alwaysReveal ? <Check fontSize="inherit" /> : null}
|
||||
</span>
|
||||
Always reveal top card
|
||||
</MenuItem>,
|
||||
<MenuItem
|
||||
key="always-look"
|
||||
onClick={run(handleToggleAlwaysLook)}
|
||||
className="zone-context-menu__toggle"
|
||||
>
|
||||
<span className="zone-context-menu__check" aria-hidden>
|
||||
{alwaysLook ? <Check fontSize="inherit" /> : null}
|
||||
</span>
|
||||
Always look at top card
|
||||
</MenuItem>,
|
||||
);
|
||||
} else if (zoneName === App.ZoneName.GRAVE) {
|
||||
menuItems.push(
|
||||
<MenuItem key="reveal-grave" onClick={run(onRequestRevealZone)}>
|
||||
Reveal graveyard to…
|
||||
</MenuItem>,
|
||||
);
|
||||
} else if (zoneName === App.ZoneName.EXILE) {
|
||||
menuItems.push(
|
||||
<MenuItem key="reveal-exile" onClick={run(onRequestRevealZone)}>
|
||||
Reveal exile to…
|
||||
</MenuItem>,
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu
|
||||
open={isOpen}
|
||||
onClose={onClose}
|
||||
anchorReference="anchorPosition"
|
||||
anchorPosition={anchorPosition ?? undefined}
|
||||
data-testid="zone-context-menu"
|
||||
className="zone-context-menu"
|
||||
>
|
||||
{menuItems}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
export default ZoneContextMenu;
|
||||
Loading…
Add table
Add a link
Reference in a new issue