1
0

241 lines
6.5 KiB
TypeScript

import React, { useEffect, useContext, useMemo, useRef, useState, useCallback } from "react";
import equal from "fast-deep-equal";
import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import "./ViewCard.css";
import { Resource } from "./Resource";
import { GlobalContext } from "./GlobalContext";
/* eslint-disable @typescript-eslint/no-explicit-any */
interface ViewCardProps {
cardActive: any;
setCardActive: (card: any) => void;
}
const ViewCard: React.FC<ViewCardProps> = ({ cardActive, setCardActive }) => {
const { lastJsonMessage, sendJsonMessage } = useContext(GlobalContext);
const [priv, setPriv] = useState<any>(undefined);
const [turns, setTurns] = useState<number>(0);
const [rules, setRules] = useState<any>({});
const fields = useMemo(() => ["private", "turns", "rules"], []);
useEffect(() => {
if (!lastJsonMessage) {
return;
}
const data = lastJsonMessage;
switch (data.type) {
case "game-update":
console.log(`view-card - game update`);
if ("private" in data.update && !equal(data.update.private, priv)) {
setPriv(data.update.private);
}
if ("turns" in data.update && data.update.turns !== turns) {
setTurns(data.update.turns);
}
if ("rules" in data.update && !equal(data.update.rules, rules)) {
setRules(data.update.rules);
}
break;
default:
break;
}
}, [lastJsonMessage, priv, turns, rules]);
useEffect(() => {
if (!sendJsonMessage) {
return;
}
sendJsonMessage({
type: "get",
fields,
});
}, [sendJsonMessage, fields]);
const playCard = useCallback(() => {
if (sendJsonMessage) {
sendJsonMessage({
type: "play-card",
card: cardActive,
});
}
setCardActive(undefined);
}, [sendJsonMessage, cardActive, setCardActive]);
const close = () => {
setCardActive(undefined);
};
if (!cardActive) {
return <></>;
}
const capitalize = (string: string) => {
if (string === "vp") {
return "Victory Point";
}
if (string === "army") {
return "Knight";
}
return string.charAt(0).toUpperCase() + string.slice(1);
};
let description: React.ReactElement, lookup: string;
if (cardActive.type === "progress") {
lookup = `${cardActive.type}-${cardActive.card}`;
} else {
lookup = cardActive.type;
}
const points = "victory-points" in rules && rules["victory-points"].enabled ? rules["victory-points"].points : 0;
let cardName = "";
switch (lookup) {
case "army":
cardName = "Knight";
description = (
<>
<div>
When played, you <b>must</b> move the robber.
</div>
<div>
Steal <b>1</b> resource card from the owner of an adjacent settlement or city.
</div>
<div>You may only play one development card during your turn -- either one knight or one progress card.</div>
</>
);
break;
case "vp":
cardName = `Victory Point: ${capitalize(cardActive.card)}`;
description = (
<>
<div>
<b>1</b> victory point.
</div>
<div>
You only reveal your victory point cards when the game is over, either when you or an opponent reaches{" "}
<b>{points}+</b> victory points on their turn and declares victory!
</div>
</>
);
break;
case "progress-road-1":
case "progress-road-2":
cardName = "Road Building";
description = (
<>
<div>
Play <b>2</b> new roads as if you had just built them.
</div>
<div>
This is still limited by the number of roads you have. If you do not have enough roads remaining, or if there
are no valid road building locations, the number of roads you can place will be reduced.
</div>
<div>
You currently have <b>{priv?.roads}</b> roads remaining.
</div>
</>
);
break;
case "progress-monopoly":
cardName = "Monopoly";
description = (
<>
<div>
When you play this card, you will select <b>1</b> type of resource. All other players must give you all their
resource cards of that type.
</div>
</>
);
break;
case "progress-year-of-plenty":
cardName = "Year of Plenty";
description = (
<>
<div>
Take any <b>2</b> resources from the bank. Add them to your hand. They can be
<b>2</b> of the same resource or <b>1</b> of two differ resources.
</div>
</>
);
break;
default:
description = <>Unknown card type {lookup}</>;
break;
}
let canPlay = false;
if (cardActive.type === "vp") {
let points = priv?.points || 0;
priv?.development?.forEach((item: any) => {
if (item.type === "vp") {
points++;
}
});
canPlay = points >= points;
if (!canPlay && !cardActive.played) {
description = (
<>
{description}
<div>
You do not have enough victory points to play this card yet. You can currently reach <b>{points}</b> points.
</div>
</>
);
}
} else {
canPlay = cardActive.turn < turns;
if (!canPlay) {
description = (
<>
{description}
<div>You can not play this card until your next turn.</div>
</>
);
}
if (canPlay) {
canPlay = priv?.playedCard !== turns;
if (!canPlay) {
description = (
<>
{description}
<div>You have already played a development card this turn.</div>
</>
);
}
}
}
if (cardActive.played) {
description = (
<>
{description}
<div>You have already played this card.</div>
</>
);
canPlay = false;
}
return (
<div className="ViewCard">
<Paper>
<div className="Title">{cardName}</div>
<div style={{ display: "flex", flexDirection: "row" }}>
<Resource type={`${cardActive.type}-${cardActive.card}`} disabled count={1} />
<div className="Description">{description}</div>
</div>
{!cardActive.played && (
<Button disabled={!canPlay} onClick={playCard}>
play
</Button>
)}
<Button onClick={close}>close</Button>
</Paper>
</div>
);
};
export { ViewCard };