Skip to content

Commit

Permalink
Merge pull request #38 from JollyGrin/feat/view-enemy-graveyard
Browse files Browse the repository at this point in the history
Feat/view enemy graveyard
  • Loading branch information
JollyGrin authored Sep 28, 2024
2 parents 49bba2d + b528641 commit 403fcb0
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 57 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Find instructions if you wish to setup your own game server.


## Todo
- [ ] view enemy graveyard
- [x] view enemy graveyard
- [x] add four cores deck import https://fourcores.xyz/api/tts/T33jdoAJy8PGY9Agq1fo
- [ ] add hand drawing mode (for mobile, just deck and hand)
- [ ] add setting to flip enemy card upside down
Expand Down
2 changes: 2 additions & 0 deletions src/components/molecules/CommandModal/Command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ActionIds,
ActionRollDice,
ActScryX,
ViewCemetary,
} from "./Commands";
import { PlayerDataProps } from "@/types/card";

Expand Down Expand Up @@ -35,6 +36,7 @@ export const Command = (props: GameStateActions & PlayerDataProps) => {
if (id === "scry_x") return <ActScryX {...props} deckType="deck" />;
if (id === "scry_x_atlas")
return <ActScryX {...props} deckType="atlas" />;
if (id === "view_cemetary") return <ViewCemetary />;

return <Box>No action setup</Box>;
}}
Expand Down
20 changes: 19 additions & 1 deletion src/components/molecules/CommandModal/Commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import {
import { useRouter } from "next/router";
import { useState } from "react";
import { css } from "styled-system/css";
import { Box, Flex, VStack } from "styled-system/jsx";
import { Box, Flex, HStack, VStack } from "styled-system/jsx";
import { input } from "styled-system/recipes";
import { GiPirateGrave as IconGrave } from "react-icons/gi";

export const actions = [
{
Expand All @@ -42,6 +43,10 @@ export const actions = [
value: "scry_x_atlas",
label: "View top X cards of atlas deck",
},
{
value: "view_cemetary",
label: "View enemy cemetary",
},
] as const;
export type ActionIds = (typeof actions)[number]["value"];

Expand Down Expand Up @@ -170,3 +175,16 @@ export const ActScryX = ({
</VStack>
);
};

export const ViewCemetary = () => {
return (
<Box>
<p>To view an enemy cemetary:</p>
<HStack flexWrap="wrap">
<p>click on the</p>
<IconGrave />
<p>icon next to the player&apos;s name</p>
</HStack>
</Box>
);
};
128 changes: 73 additions & 55 deletions src/components/organisms/GameBoard/Header/PlayerBox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PlayerData, PlayersState } from "@/types/card";
import { GRIDS } from "../constants";
import { Flex, HStack } from "styled-system/jsx";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { IconType } from "react-icons";
import { JsxStyleProps } from "styled-system/types";
import { cva } from "styled-system/css/cva.mjs";
Expand All @@ -15,6 +15,7 @@ import {
} from "react-icons/gi";
import { LiaDiceD6Solid as IconD6 } from "react-icons/lia";
import { FaDiceD20 as IconD20 } from "react-icons/fa";
import { ViewGraveyardModal } from "./ViewGraveyardModal";

export const PlayerBox = ({
name,
Expand All @@ -23,6 +24,13 @@ export const PlayerBox = ({
name: string;
player: PlayersState["GLOBAL"];
}) => {
const [modal, setModal] = useState(false);
const disclosure = {
onOpen: () => setModal(true),
isOpen: modal === true,
onClose: () => setModal(false),
};

const life = player?.data?.life ?? 0;

function length(position: number) {
Expand All @@ -42,65 +50,75 @@ export const PlayerBox = ({
if (player?.data?.earth === undefined) return null;

return (
<HStack fontSize="1rem" gap={1}>
<p className={textStyle({ visual: "bold" })}>{name}</p>

<Flex
minW="3rem"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
alignItems="center"
justifyContent="center"
gap={1}
style={{
background: bg,
}}
>
<IconHealth fontSize="0.75rem" />
<p>{life}</p>
</Flex>
<>
{disclosure.isOpen && (
<ViewGraveyardModal
cards={player.state[GRIDS.GRAVE]}
onClose={disclosure.onClose}
/>
)}
<HStack fontSize="1rem" gap={1}>
<p className={textStyle({ visual: "bold" })}>{name}</p>

<Flex
bg="rgba(255,255,255,0.5)"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
gap={2}
alignItems="center"
>
<Resource icon="earth" value={player.data.earth} />
<Resource icon="fire" value={player.data.fire} />
<Resource icon="water" value={player.data.water} />
<Resource icon="wind" value={player.data.wind} />
<IconMana color="gray" size={15} style={{ marginLeft: "0.25rem" }} />
<p
<Flex
minW="3rem"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
alignItems="center"
justifyContent="center"
gap={1}
style={{
color: "gray",
background: bg,
}}
>
{player.data.manaRemaining}
{"/"}
{player.data.mana}
</p>
</Flex>
<IconHealth fontSize="0.75rem" />
<p>{life}</p>
</Flex>

<Flex
bg="rgba(255,255,255,0.5)"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
gap={2}
>
<Stat Icon={IconGrave} value={length(GRIDS.GRAVE)} />
<Stat Icon={IconDeck} value={length(GRIDS.DECK)} />
<Stat Icon={IconMap} value={length(GRIDS.ATLAS_DECK)} />
<Stat Icon={IconHand} value={length(GRIDS.HAND)} />
{player?.data?.dice?.d6 !== undefined && (
<Stat Icon={IconD6} value={player?.data?.dice?.d6} />
)}
{player?.data?.dice?.d20 !== undefined && (
<Stat Icon={IconD20} value={player?.data?.dice?.d20} />
)}
</Flex>
</HStack>
<Flex
bg="rgba(255,255,255,0.5)"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
gap={2}
alignItems="center"
>
<Resource icon="earth" value={player.data.earth} />
<Resource icon="fire" value={player.data.fire} />
<Resource icon="water" value={player.data.water} />
<Resource icon="wind" value={player.data.wind} />
<IconMana color="gray" size={15} style={{ marginLeft: "0.25rem" }} />
<p
style={{
color: "gray",
}}
>
{player.data.manaRemaining}
{"/"}
{player.data.mana}
</p>
</Flex>

<Flex
bg="rgba(255,255,255,0.5)"
p="0.1rem 0.5rem"
borderRadius="0.75rem"
gap={2}
>
<span onClick={disclosure.onOpen}>
<Stat Icon={IconGrave} value={length(GRIDS.GRAVE)} />
</span>
<Stat Icon={IconDeck} value={length(GRIDS.DECK)} />
<Stat Icon={IconMap} value={length(GRIDS.ATLAS_DECK)} />
<Stat Icon={IconHand} value={length(GRIDS.HAND)} />
{player?.data?.dice?.d6 !== undefined && (
<Stat Icon={IconD6} value={player?.data?.dice?.d6} />
)}
{player?.data?.dice?.d20 !== undefined && (
<Stat Icon={IconD20} value={player?.data?.dice?.d20} />
)}
</Flex>
</HStack>
</>
);
};

Expand Down
44 changes: 44 additions & 0 deletions src/components/organisms/GameBoard/Header/ViewGraveyardModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { CardImage } from "@/components/atoms/card-view/card";
import { Modal } from "@/components/atoms/Modal";
import { GridItem } from "@/types/card";
import { css } from "styled-system/css";
import { Box, Flex } from "styled-system/jsx";

export const ViewGraveyardModal = (props: {
cards: GridItem;
onClose(): void;
}) => {
return (
<Modal
wrapperProps={{ open: true, onOpenChange: props.onClose }}
content={
<Box>
<p
className={css({
fontSize: "2rem",
fontWeight: 600,
})}
>
Graveyard
</p>
<Flex minW="50vw" minH="20vh" flexWrap="wrap">
{props.cards?.map((card) => (
<Box
key={card.id}
aspectRatio={8 / 11}
h="350px"
position="relative"
filter="saturate(1)"
_hover={{
filter: "saturate(1.75)",
}}
>
<CardImage key={card.id} img={card.img} minH={"0"} />
</Box>
))}
</Flex>
</Box>
}
/>
);
};
3 changes: 3 additions & 0 deletions src/components/organisms/GameBoard/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ export const initGameData: PlayerData = {
manaRemaining: 0,
};

/**
* Returns the webp
* */
export function getCardImage(identifier: string, quality: 50 | 100 = 100) {
return `https://card.cards.army/cards/${quality === 100 ? "" : "/50"}${identifier}.webp`;
}

0 comments on commit 403fcb0

Please sign in to comment.