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

180 lines
4.9 KiB
TypeScript
Raw Normal View History

2022-04-25 01:51:30 +02:00
import { Paper, Typography } from "@mui/material";
import React, { useEffect, useState } from "react";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Player } from "../../Player";
import { Settings } from "../../Settings/Settings";
2022-04-25 01:51:30 +02:00
import { KEY } from "../../utils/helpers/keyCodes";
import { downArrowSymbol, upArrowSymbol } from "../utils";
2022-04-25 01:51:30 +02:00
import { interpolate } from "./Difficulty";
import { GameTimer } from "./GameTimer";
import { IMinigameProps } from "./IMinigameProps";
import { KeyHandler } from "./KeyHandler";
interface Difficulty {
2021-09-05 01:09:30 +02:00
[key: string]: number;
timer: number;
size: number;
}
const difficulties: {
2021-09-05 01:09:30 +02:00
Trivial: Difficulty;
Normal: Difficulty;
Hard: Difficulty;
Impossible: Difficulty;
} = {
2021-09-05 01:09:30 +02:00
Trivial: { timer: 12000, size: 6 },
Normal: { timer: 9000, size: 8 },
Hard: { timer: 5000, size: 9 },
Impossible: { timer: 2500, size: 12 },
};
export function BribeGame(props: IMinigameProps): React.ReactElement {
2021-09-05 01:09:30 +02:00
const difficulty: Difficulty = { timer: 0, size: 0 };
interpolate(difficulties, props.difficulty, difficulty);
const timer = difficulty.timer;
const [choices] = useState(makeChoices(difficulty));
const [correctIndex, setCorrectIndex] = useState(0);
2021-09-05 01:09:30 +02:00
const [index, setIndex] = useState(0);
const currentChoice = choices[index];
useEffect(() => {
setCorrectIndex(choices.findIndex((choice) => positive.includes(choice)));
}, [choices]);
const defaultColor = Settings.theme.primary;
const disabledColor = Settings.theme.disabled;
let upColor = defaultColor;
let downColor = defaultColor;
let choiceColor = defaultColor;
2022-04-22 21:30:49 +02:00
const hasAugment = Player.hasAugmentation(AugmentationNames.BeautyOfAphrodite, true);
if (hasAugment) {
const upIndex = index + 1 >= choices.length ? 0 : index + 1;
let upDistance = correctIndex - upIndex;
if (upIndex > correctIndex) {
upDistance = choices.length - 1 - upIndex + correctIndex;
}
const downIndex = index - 1 < 0 ? choices.length - 1 : index - 1;
let downDistance = downIndex - correctIndex;
if (downIndex < correctIndex) {
downDistance = downIndex + choices.length - 1 - correctIndex;
}
const onCorrectIndex = correctIndex == index;
upColor = upDistance <= downDistance && !onCorrectIndex ? upColor : disabledColor;
downColor = upDistance >= downDistance && !onCorrectIndex ? downColor : disabledColor;
choiceColor = onCorrectIndex ? defaultColor : disabledColor;
}
2021-09-25 04:15:19 +02:00
function press(this: Document, event: KeyboardEvent): void {
2021-09-05 01:09:30 +02:00
event.preventDefault();
const k = event.key;
if (k === KEY.SPACE) {
if (positive.includes(currentChoice)) props.onSuccess();
2021-09-05 01:09:30 +02:00
else props.onFailure();
return;
}
2021-09-05 01:09:30 +02:00
let newIndex = index;
if ([KEY.UP_ARROW, KEY.W, KEY.RIGHT_ARROW, KEY.D].map((k) => k as string).includes(k)) newIndex++;
if ([KEY.DOWN_ARROW, KEY.S, KEY.LEFT_ARROW, KEY.A].map((k) => k as string).includes(k)) newIndex--;
2021-09-05 01:09:30 +02:00
while (newIndex < 0) newIndex += choices.length;
while (newIndex > choices.length - 1) newIndex -= choices.length;
setIndex(newIndex);
}
return (
2022-04-24 21:52:58 +02:00
<>
2021-09-05 01:09:30 +02:00
<GameTimer millis={timer} onExpire={props.onFailure} />
2022-04-24 21:52:58 +02:00
<Paper sx={{ display: "grid", justifyItems: "center" }}>
<Typography variant="h4">Say something nice about the guard</Typography>
2021-09-05 01:09:30 +02:00
<KeyHandler onKeyDown={press} onFailure={props.onFailure} />
<Typography variant="h5" color={upColor}>
{upArrowSymbol}
2021-10-01 19:08:37 +02:00
</Typography>
<Typography variant="h5" color={choiceColor}>
{currentChoice}
2021-10-01 19:08:37 +02:00
</Typography>
<Typography variant="h5" color={downColor}>
{downArrowSymbol}
2021-10-01 19:08:37 +02:00
</Typography>
2022-04-24 21:52:58 +02:00
</Paper>
</>
2021-09-05 01:09:30 +02:00
);
}
function shuffleArray(array: string[]): void {
2021-09-05 01:09:30 +02:00
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
function makeChoices(difficulty: Difficulty): string[] {
2021-09-05 01:09:30 +02:00
const choices = [];
choices.push(positive[Math.floor(Math.random() * positive.length)]);
for (let i = 0; i < difficulty.size; i++) {
const option = negative[Math.floor(Math.random() * negative.length)];
if (choices.includes(option)) {
i--;
continue;
}
2021-09-05 01:09:30 +02:00
choices.push(option);
}
shuffleArray(choices);
return choices;
}
2021-09-05 01:09:30 +02:00
const positive = [
"affectionate",
"agreeable",
"bright",
"charming",
"creative",
"determined",
"energetic",
"friendly",
"funny",
"generous",
"polite",
"likable",
"diplomatic",
"helpful",
"giving",
"kind",
"hardworking",
"patient",
"dynamic",
"loyal",
2022-08-10 00:25:02 +02:00
"straightforward",
2021-09-05 01:09:30 +02:00
];
2021-09-05 01:09:30 +02:00
const negative = [
"aggressive",
"aloof",
"arrogant",
"big-headed",
"boastful",
"boring",
"bossy",
"careless",
"clingy",
"couch potato",
"cruel",
"cynical",
"grumpy",
"hot air",
"know it all",
"obnoxious",
"pain in the neck",
"picky",
"tactless",
"thoughtless",
2022-04-25 01:49:46 +02:00
"cringe",
2021-09-05 01:09:30 +02:00
];