bitburner-src/src/Infiltration/ui/Game.tsx

157 lines
4.1 KiB
TypeScript
Raw Normal View History

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";
import { BackwardGame } from "./BackwardGame";
2022-04-24 21:38:39 +02:00
import { BracketGame } from "./BracketGame";
import { BribeGame } from "./BribeGame";
import { CheatCodeGame } from "./CheatCodeGame";
2022-04-24 21:38:39 +02:00
import { Countdown } from "./Countdown";
import { Cyberpunk2077Game } from "./Cyberpunk2077Game";
import { MinesweeperGame } from "./MinesweeperGame";
2022-04-24 21:38:39 +02:00
import { SlashGame } from "./SlashGame";
import { Victory } from "./Victory";
2022-04-24 21:38:39 +02:00
import { WireCuttingGame } from "./WireCuttingGame";
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;
}
enum Stage {
2021-09-05 01:09:30 +02:00
Countdown = 0,
Minigame,
Result,
Sell,
}
const minigames = [
2021-09-05 01:09:30 +02:00
SlashGame,
BracketGame,
BackwardGame,
BribeGame,
CheatCodeGame,
Cyberpunk2077Game,
MinesweeperGame,
WireCuttingGame,
];
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-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-09-05 01:09:30 +02:00
return id;
}
2021-09-05 01:09:30 +02:00
function setupNextGame(): void {
setGameIds({
lastGames: [gameIds.lastGames[1], gameIds.id],
id: nextGameId(),
});
}
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-09-05 01:09:30 +02:00
setupNextGame();
}
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-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
const damage = options?.automated
? player.hp.current
: props.StartingDifficulty * 3 * (player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 0.5 : 1);
2021-09-18 01:43:08 +02:00
if (player.takeDamage(damage)) {
router.toCity();
return;
}
2021-09-05 01:09:30 +02:00
setupNextGame();
}
function cancel(): void {
router.toCity();
return;
}
2021-09-05 01:09:30 +02:00
let stageComponent: React.ReactNode;
switch (stage) {
case Stage.Countdown:
2021-09-05 01:09:30 +02:00
stageComponent = <Countdown onFinish={() => setStage(Stage.Minigame)} />;
break;
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;
}
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-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-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 }}>
2022-04-25 01:49:46 +02:00
{stage !== Stage.Sell && (
<Button sx={{ width: "100%" }} onClick={cancel}>
Cancel Infiltration
</Button>
)}
2022-04-24 21:38:39 +02:00
<Typography variant="h5">
Level {level} / {props.MaxLevel}
</Typography>
<Progress />
</Paper>
2022-04-24 21:38:39 +02:00
{stageComponent}
</Container>
2021-09-05 01:09:30 +02:00
);
}