2022-04-24 21:38:39 +02:00
|
|
|
import { Button, Container, Paper, Typography } from "@mui/material";
|
2021-09-05 01:09:30 +02:00
|
|
|
import React, { useState } from "react";
|
2022-04-24 21:38:39 +02:00
|
|
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
|
|
|
import { use } from "../../ui/Context";
|
2021-06-13 17:05:40 +02:00
|
|
|
import { BackwardGame } from "./BackwardGame";
|
2022-04-24 21:38:39 +02:00
|
|
|
import { BracketGame } from "./BracketGame";
|
2021-06-13 17:05:40 +02:00
|
|
|
import { BribeGame } from "./BribeGame";
|
|
|
|
import { CheatCodeGame } from "./CheatCodeGame";
|
2022-04-24 21:38:39 +02:00
|
|
|
import { Countdown } from "./Countdown";
|
2021-06-13 17:05:40 +02:00
|
|
|
import { Cyberpunk2077Game } from "./Cyberpunk2077Game";
|
|
|
|
import { MinesweeperGame } from "./MinesweeperGame";
|
2022-04-24 21:38:39 +02:00
|
|
|
import { SlashGame } from "./SlashGame";
|
2021-06-13 17:05:40 +02:00
|
|
|
import { Victory } from "./Victory";
|
2022-04-24 21:38:39 +02:00
|
|
|
import { WireCuttingGame } from "./WireCuttingGame";
|
2021-06-13 17:05:40 +02:00
|
|
|
|
|
|
|
interface IProps {
|
2021-09-05 01:09:30 +02:00
|
|
|
StartingDifficulty: number;
|
|
|
|
Difficulty: number;
|
2021-12-03 21:11:31 +01:00
|
|
|
Reward: number;
|
2021-09-05 01:09:30 +02:00
|
|
|
MaxLevel: number;
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
enum Stage {
|
2021-09-05 01:09:30 +02:00
|
|
|
Countdown = 0,
|
|
|
|
Minigame,
|
|
|
|
Result,
|
|
|
|
Sell,
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const minigames = [
|
2021-09-05 01:09:30 +02:00
|
|
|
SlashGame,
|
|
|
|
BracketGame,
|
|
|
|
BackwardGame,
|
|
|
|
BribeGame,
|
|
|
|
CheatCodeGame,
|
|
|
|
Cyberpunk2077Game,
|
|
|
|
MinesweeperGame,
|
|
|
|
WireCuttingGame,
|
|
|
|
];
|
2021-06-13 17:05:40 +02:00
|
|
|
|
|
|
|
export function Game(props: IProps): React.ReactElement {
|
2021-09-18 01:43:08 +02:00
|
|
|
const player = use.Player();
|
|
|
|
const router = use.Router();
|
2021-09-05 01:09:30 +02:00
|
|
|
const [level, setLevel] = useState(1);
|
|
|
|
const [stage, setStage] = useState(Stage.Countdown);
|
|
|
|
const [results, setResults] = useState("");
|
|
|
|
const [gameIds, setGameIds] = useState({
|
|
|
|
lastGames: [-1, -1],
|
|
|
|
id: Math.floor(Math.random() * minigames.length),
|
|
|
|
});
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function nextGameId(): number {
|
|
|
|
let id = gameIds.lastGames[0];
|
|
|
|
const ids = [gameIds.lastGames[0], gameIds.lastGames[1], gameIds.id];
|
|
|
|
while (ids.includes(id)) {
|
|
|
|
id = Math.floor(Math.random() * minigames.length);
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
return id;
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function setupNextGame(): void {
|
|
|
|
setGameIds({
|
|
|
|
lastGames: [gameIds.lastGames[1], gameIds.id],
|
|
|
|
id: nextGameId(),
|
|
|
|
});
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function success(): void {
|
|
|
|
pushResult(true);
|
|
|
|
if (level === props.MaxLevel) {
|
|
|
|
setStage(Stage.Sell);
|
|
|
|
} else {
|
|
|
|
setStage(Stage.Countdown);
|
|
|
|
setLevel(level + 1);
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
setupNextGame();
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function pushResult(win: boolean): void {
|
|
|
|
setResults((old) => {
|
|
|
|
let next = old;
|
|
|
|
next += win ? "✓" : "✗";
|
|
|
|
if (next.length > 15) next = next.slice(1);
|
|
|
|
return next;
|
|
|
|
});
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function failure(options?: { automated: boolean }): void {
|
|
|
|
setStage(Stage.Countdown);
|
|
|
|
pushResult(false);
|
|
|
|
// Kill the player immediately if they use automation, so
|
|
|
|
// it's clear they're not meant to
|
2022-03-27 06:26:43 +02:00
|
|
|
const damage = options?.automated
|
|
|
|
? player.hp
|
2022-04-22 21:30:49 +02:00
|
|
|
: props.StartingDifficulty * 3 * (player.hasAugmentation(AugmentationNames.WKSharmonizer) ? 0.5 : 1);
|
2021-09-18 01:43:08 +02:00
|
|
|
if (player.takeDamage(damage)) {
|
|
|
|
router.toCity();
|
|
|
|
return;
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
setupNextGame();
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2022-01-06 09:30:15 +01:00
|
|
|
function cancel(): void {
|
|
|
|
router.toCity();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
let stageComponent: React.ReactNode;
|
|
|
|
switch (stage) {
|
2021-06-13 17:05:40 +02:00
|
|
|
case Stage.Countdown:
|
2021-09-05 01:09:30 +02:00
|
|
|
stageComponent = <Countdown onFinish={() => setStage(Stage.Minigame)} />;
|
|
|
|
break;
|
2021-06-13 17:05:40 +02:00
|
|
|
case Stage.Minigame: {
|
2022-04-24 23:50:51 +02:00
|
|
|
const MiniGame = minigames[gameIds.id];
|
2021-09-09 05:47:34 +02:00
|
|
|
stageComponent = <MiniGame onSuccess={success} onFailure={failure} difficulty={props.Difficulty + level / 50} />;
|
2021-09-05 01:09:30 +02:00
|
|
|
break;
|
2021-06-13 17:05:40 +02:00
|
|
|
}
|
|
|
|
case Stage.Sell:
|
2021-09-05 01:09:30 +02:00
|
|
|
stageComponent = (
|
|
|
|
<Victory
|
|
|
|
StartingDifficulty={props.StartingDifficulty}
|
|
|
|
Difficulty={props.Difficulty}
|
2021-12-03 21:11:31 +01:00
|
|
|
Reward={props.Reward}
|
2021-09-05 01:09:30 +02:00
|
|
|
MaxLevel={props.MaxLevel}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
function Progress(): React.ReactElement {
|
|
|
|
return (
|
2021-11-02 21:20:32 +01:00
|
|
|
<Typography variant="h4">
|
2021-09-09 05:47:34 +02:00
|
|
|
<span style={{ color: "gray" }}>{results.slice(0, results.length - 1)}</span>
|
2021-09-05 01:09:30 +02:00
|
|
|
{results[results.length - 1]}
|
2021-11-02 21:20:32 +01:00
|
|
|
</Typography>
|
2021-09-05 01:09:30 +02:00
|
|
|
);
|
|
|
|
}
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
return (
|
2022-04-24 21:38:39 +02:00
|
|
|
<Container>
|
|
|
|
<Paper sx={{ p: 1, mb: 1, display: "grid", justifyItems: "center", gap: 1 }}>
|
|
|
|
<Button sx={{ width: "100%" }} onClick={cancel}>
|
|
|
|
Cancel
|
|
|
|
</Button>
|
|
|
|
<Typography variant="h5">
|
|
|
|
Level {level} / {props.MaxLevel}
|
|
|
|
</Typography>
|
|
|
|
<Progress />
|
|
|
|
</Paper>
|
2021-06-13 17:05:40 +02:00
|
|
|
|
2022-04-24 21:38:39 +02:00
|
|
|
{stageComponent}
|
|
|
|
</Container>
|
2021-09-05 01:09:30 +02:00
|
|
|
);
|
|
|
|
}
|