mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-11 02:03:58 +01:00
more updates
* added more keycodes constant support * implemented new faction mechanics for mini games * more small refactors
This commit is contained in:
parent
4e73e489ed
commit
0b171822df
@ -131,7 +131,7 @@ export const infiltratorsAugmentations = [
|
|||||||
factions: [FactionNames.Infiltrators],
|
factions: [FactionNames.Infiltrators],
|
||||||
}),
|
}),
|
||||||
new Augmentation({
|
new Augmentation({
|
||||||
name: AugmentationNames.AmuletOfPersuasian,
|
name: AugmentationNames.AmuletOfPersuasion,
|
||||||
repCost: 1e2,
|
repCost: 1e2,
|
||||||
moneyCost: 1e6,
|
moneyCost: 1e6,
|
||||||
info:
|
info:
|
||||||
|
@ -114,7 +114,7 @@ export const AugmentationNames: {
|
|||||||
BagOfSand: string;
|
BagOfSand: string;
|
||||||
IntellisenseModule: string;
|
IntellisenseModule: string;
|
||||||
ReverseDictionary: string;
|
ReverseDictionary: string;
|
||||||
AmuletOfPersuasian: string;
|
AmuletOfPersuasion: string;
|
||||||
LameSharkRepository: string;
|
LameSharkRepository: string;
|
||||||
CyberDecoder: string;
|
CyberDecoder: string;
|
||||||
MineDetector: string;
|
MineDetector: string;
|
||||||
@ -237,7 +237,7 @@ export const AugmentationNames: {
|
|||||||
BagOfSand: "A Bag of Sand",
|
BagOfSand: "A Bag of Sand",
|
||||||
IntellisenseModule: "Intellisense Module",
|
IntellisenseModule: "Intellisense Module",
|
||||||
ReverseDictionary: "Reverse Dictionary",
|
ReverseDictionary: "Reverse Dictionary",
|
||||||
AmuletOfPersuasian: "Amulet of Persuasian",
|
AmuletOfPersuasion: "Amulet of Persuasian",
|
||||||
LameSharkRepository: "Lame Shark Repository",
|
LameSharkRepository: "Lame Shark Repository",
|
||||||
CyberDecoder: "Cyber Decoder",
|
CyberDecoder: "Cyber Decoder",
|
||||||
MineDetector: "Mine Detector",
|
MineDetector: "Mine Detector",
|
||||||
|
@ -170,7 +170,6 @@ export function BitverseRoot(props: IProps): React.ReactElement {
|
|||||||
<>
|
<>
|
||||||
{Object.values(BitNodes)
|
{Object.values(BitNodes)
|
||||||
.filter((node) => {
|
.filter((node) => {
|
||||||
console.log(node.desc);
|
|
||||||
return node.desc !== "COMING SOON";
|
return node.desc !== "COMING SOON";
|
||||||
})
|
})
|
||||||
.map((node) => {
|
.map((node) => {
|
||||||
|
@ -109,7 +109,7 @@ export function Console(props: IProps): React.ReactElement {
|
|||||||
setCommand(prevCommand);
|
setCommand(prevCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === KEY.DOWNARROW) {
|
if (event.key === KEY.DOWN_ARROW) {
|
||||||
const i = consoleHistoryIndex;
|
const i = consoleHistoryIndex;
|
||||||
const len = consoleHistory.length;
|
const len = consoleHistory.length;
|
||||||
|
|
||||||
@ -140,14 +140,16 @@ export function Console(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper sx={{ p: 1 }}>
|
<Paper sx={{ p: 1 }}>
|
||||||
<Box sx={{
|
<Box
|
||||||
height: '60vh',
|
sx={{
|
||||||
paddingBottom: '8px',
|
height: "60vh",
|
||||||
display: 'flex',
|
paddingBottom: "8px",
|
||||||
alignItems: 'stretch',
|
display: "flex",
|
||||||
whiteSpace: 'pre-wrap',
|
alignItems: "stretch",
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
}}
|
}}
|
||||||
onClick={handleClick}>
|
onClick={handleClick}
|
||||||
|
>
|
||||||
<Box>
|
<Box>
|
||||||
<Logs entries={[...props.bladeburner.consoleLogs]} />
|
<Logs entries={[...props.bladeburner.consoleLogs]} />
|
||||||
</Box>
|
</Box>
|
||||||
@ -195,9 +197,7 @@ function Logs({ entries }: ILogProps): React.ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<List sx={{ height: "100%", overflow: "auto", p: 1 }} ref={scrollHook}>
|
<List sx={{ height: "100%", overflow: "auto", p: 1 }} ref={scrollHook}>
|
||||||
{entries && entries.map((log: any, i: number) => (
|
{entries && entries.map((log: any, i: number) => <Line key={i} content={log} />)}
|
||||||
<Line key={i} content={log} />
|
|
||||||
))}
|
|
||||||
</List>
|
</List>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ import { random } from "../utils";
|
|||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import { BlinkingCursor } from "./BlinkingCursor";
|
import { BlinkingCursor } from "./BlinkingCursor";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -33,16 +36,26 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement {
|
|||||||
const timer = difficulty.timer;
|
const timer = difficulty.timer;
|
||||||
const [answer] = useState(makeAnswer(difficulty));
|
const [answer] = useState(makeAnswer(difficulty));
|
||||||
const [guess, setGuess] = useState("");
|
const [guess, setGuess] = useState("");
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.ReverseDictionary, true);
|
||||||
|
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (event.key === "Backspace") return;
|
if (event.key === KEY.BACKSPACE) return;
|
||||||
const nextGuess = guess + event.key.toUpperCase();
|
const nextGuess = guess + event.key.toUpperCase();
|
||||||
if (!answer.startsWith(nextGuess)) props.onFailure();
|
if (!answer.startsWith(nextGuess)) props.onFailure();
|
||||||
else if (answer === nextGuess) props.onSuccess();
|
else if (answer === nextGuess) props.onSuccess();
|
||||||
else setGuess(nextGuess);
|
else setGuess(nextGuess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AnswerStyle {
|
||||||
|
transform?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const answerStyle: AnswerStyle = { transform: "scaleX(-1)" };
|
||||||
|
if (hasAugment) {
|
||||||
|
delete answerStyle.transform;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<GameTimer millis={timer} onExpire={props.onFailure} />
|
<GameTimer millis={timer} onExpire={props.onFailure} />
|
||||||
@ -51,7 +64,7 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement {
|
|||||||
<KeyHandler onKeyDown={press} onFailure={props.onFailure} />
|
<KeyHandler onKeyDown={press} onFailure={props.onFailure} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography style={{ transform: "scaleX(-1)" }}>{answer}</Typography>
|
<Typography style={answerStyle}>{answer}</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography>
|
<Typography>
|
||||||
|
@ -7,6 +7,9 @@ import { random } from "../utils";
|
|||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import { BlinkingCursor } from "./BlinkingCursor";
|
import { BlinkingCursor } from "./BlinkingCursor";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -29,28 +32,32 @@ const difficulties: {
|
|||||||
|
|
||||||
function generateLeftSide(difficulty: Difficulty): string {
|
function generateLeftSide(difficulty: Difficulty): string {
|
||||||
let str = "";
|
let str = "";
|
||||||
|
const options = [KEY.OPEN_BRACKET, KEY.LESS_THAN, KEY.OPEN_PARENTHESIS, KEY.OPEN_BRACE];
|
||||||
|
if (Player.hasAugmentation(AugmentationNames.IntellisenseModule, true)) {
|
||||||
|
options.splice(0, 1);
|
||||||
|
}
|
||||||
const length = random(difficulty.min, difficulty.max);
|
const length = random(difficulty.min, difficulty.max);
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
str += ["[", "<", "(", "{"][Math.floor(Math.random() * 4)];
|
str += options[Math.floor(Math.random() * 4)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChar(event: KeyboardEvent): string {
|
function getChar(event: KeyboardEvent): string {
|
||||||
if (event.key === ")") return ")";
|
if (event.key === KEY.CLOSE_PARENTHESIS) return KEY.CLOSE_PARENTHESIS;
|
||||||
if (event.key === "]") return "]";
|
if (event.key === KEY.CLOSE_BRACKET) return KEY.CLOSE_BRACKET;
|
||||||
if (event.key === "}") return "}";
|
if (event.key === KEY.CLOSE_BRACE) return KEY.CLOSE_BRACE;
|
||||||
if (event.key === ">") return ">";
|
if (event.key === KEY.GREATER_THAN) return KEY.GREATER_THAN;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function match(left: string, right: string): boolean {
|
function match(left: string, right: string): boolean {
|
||||||
return (
|
return (
|
||||||
(left === "[" && right === "]") ||
|
(left === KEY.OPEN_BRACKET && right === KEY.CLOSE_BRACKET) ||
|
||||||
(left === "<" && right === ">") ||
|
(left === KEY.LESS_THAN && right === KEY.GREATER_THAN) ||
|
||||||
(left === "(" && right === ")") ||
|
(left === KEY.OPEN_PARENTHESIS && right === KEY.CLOSE_PARENTHESIS) ||
|
||||||
(left === "{" && right === "}")
|
(left === KEY.OPEN_BRACE && right === KEY.CLOSE_BRACE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import { IMinigameProps } from "./IMinigameProps";
|
import { IMinigameProps } from "./IMinigameProps";
|
||||||
import { KeyHandler } from "./KeyHandler";
|
import { KeyHandler } from "./KeyHandler";
|
||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { downArrowSymbol, upArrowSymbol } from "../utils";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -29,20 +34,40 @@ export function BribeGame(props: IMinigameProps): React.ReactElement {
|
|||||||
interpolate(difficulties, props.difficulty, difficulty);
|
interpolate(difficulties, props.difficulty, difficulty);
|
||||||
const timer = difficulty.timer;
|
const timer = difficulty.timer;
|
||||||
const [choices] = useState(makeChoices(difficulty));
|
const [choices] = useState(makeChoices(difficulty));
|
||||||
|
const [correctIndex, setCorrectIndex] = useState(0);
|
||||||
const [index, setIndex] = useState(0);
|
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;
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.AmuletOfPersuasion, true);
|
||||||
|
|
||||||
|
if (hasAugment) {
|
||||||
|
upColor = correctIndex < index ? upColor : disabledColor;
|
||||||
|
downColor = correctIndex > index ? upColor : disabledColor;
|
||||||
|
choiceColor = correctIndex == index ? Settings.theme.success : disabledColor;
|
||||||
|
}
|
||||||
|
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const k = event.key;
|
const k = event.key;
|
||||||
if (k === " ") {
|
if (k === KEY.SPACE) {
|
||||||
if (positive.includes(choices[index])) props.onSuccess();
|
if (positive.includes(currentChoice)) props.onSuccess();
|
||||||
else props.onFailure();
|
else props.onFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newIndex = index;
|
let newIndex = index;
|
||||||
if (["ArrowUp", "w", "ArrowRight", "d"].includes(k)) newIndex++;
|
if ([KEY.UP_ARROW, KEY.W, KEY.RIGHT_ARROW, KEY.D].map((k) => k as string).includes(k)) newIndex++;
|
||||||
if (["ArrowDown", "s", "ArrowLeft", "a"].includes(k)) newIndex--;
|
if ([KEY.DOWN_ARROW, KEY.S, KEY.LEFT_ARROW, KEY.A].map((k) => k as string).includes(k)) newIndex--;
|
||||||
while (newIndex < 0) newIndex += choices.length;
|
while (newIndex < 0) newIndex += choices.length;
|
||||||
while (newIndex > choices.length - 1) newIndex -= choices.length;
|
while (newIndex > choices.length - 1) newIndex -= choices.length;
|
||||||
setIndex(newIndex);
|
setIndex(newIndex);
|
||||||
@ -56,14 +81,14 @@ export function BribeGame(props: IMinigameProps): React.ReactElement {
|
|||||||
<KeyHandler onKeyDown={press} onFailure={props.onFailure} />
|
<KeyHandler onKeyDown={press} onFailure={props.onFailure} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color={upColor}>
|
||||||
↑
|
{upArrowSymbol}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color={choiceColor}>
|
||||||
{choices[index]}
|
{currentChoice}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color={downColor}>
|
||||||
↓
|
{downArrowSymbol}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -3,9 +3,19 @@ import Grid from "@mui/material/Grid";
|
|||||||
import { IMinigameProps } from "./IMinigameProps";
|
import { IMinigameProps } from "./IMinigameProps";
|
||||||
import { KeyHandler } from "./KeyHandler";
|
import { KeyHandler } from "./KeyHandler";
|
||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { random, getArrow } from "../utils";
|
import {
|
||||||
|
random,
|
||||||
|
getArrow,
|
||||||
|
getInverseArrow,
|
||||||
|
leftArrowSymbol,
|
||||||
|
rightArrowSymbol,
|
||||||
|
upArrowSymbol,
|
||||||
|
downArrowSymbol,
|
||||||
|
} from "../utils";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -32,10 +42,11 @@ export function CheatCodeGame(props: IMinigameProps): React.ReactElement {
|
|||||||
const timer = difficulty.timer;
|
const timer = difficulty.timer;
|
||||||
const [code] = useState(generateCode(difficulty));
|
const [code] = useState(generateCode(difficulty));
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.LameSharkRepository, true);
|
||||||
|
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (code[index] !== getArrow(event)) {
|
if (code[index] !== getArrow(event) || (hasAugment && getInverseArrow(event))) {
|
||||||
props.onFailure();
|
props.onFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -56,7 +67,7 @@ export function CheatCodeGame(props: IMinigameProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateCode(difficulty: Difficulty): string {
|
function generateCode(difficulty: Difficulty): string {
|
||||||
const arrows = ["←", "→", "↑", "↓"];
|
const arrows = [leftArrowSymbol, rightArrowSymbol, upArrowSymbol, downArrowSymbol];
|
||||||
let code = "";
|
let code = "";
|
||||||
for (let i = 0; i < random(difficulty.min, difficulty.max); i++) {
|
for (let i = 0; i < random(difficulty.min, difficulty.max); i++) {
|
||||||
let arrow = arrows[Math.floor(4 * Math.random())];
|
let arrow = arrows[Math.floor(4 * Math.random())];
|
||||||
|
@ -4,8 +4,12 @@ import { IMinigameProps } from "./IMinigameProps";
|
|||||||
import { KeyHandler } from "./KeyHandler";
|
import { KeyHandler } from "./KeyHandler";
|
||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import { getArrow } from "../utils";
|
import { downArrowSymbol, getArrow, leftArrowSymbol, rightArrowSymbol, upArrowSymbol } from "../utils";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -32,25 +36,26 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
|
|||||||
interpolate(difficulties, props.difficulty, difficulty);
|
interpolate(difficulties, props.difficulty, difficulty);
|
||||||
const timer = difficulty.timer;
|
const timer = difficulty.timer;
|
||||||
const [grid] = useState(generatePuzzle(difficulty));
|
const [grid] = useState(generatePuzzle(difficulty));
|
||||||
const [answer] = useState(generateAnswer(grid, difficulty));
|
const [answers] = useState(generateAnswers(grid, difficulty));
|
||||||
const [index, setIndex] = useState(0);
|
const [currentAnswerIndex, setCurrentAnswerIndex] = useState(0);
|
||||||
const [pos, setPos] = useState([0, 0]);
|
const [pos, setPos] = useState([0, 0]);
|
||||||
|
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.CyberDecoder, true);
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const move = [0, 0];
|
const move = [0, 0];
|
||||||
const arrow = getArrow(event);
|
const arrow = getArrow(event);
|
||||||
switch (arrow) {
|
switch (arrow) {
|
||||||
case "↑":
|
case upArrowSymbol:
|
||||||
move[1]--;
|
move[1]--;
|
||||||
break;
|
break;
|
||||||
case "←":
|
case leftArrowSymbol:
|
||||||
move[0]--;
|
move[0]--;
|
||||||
break;
|
break;
|
||||||
case "↓":
|
case downArrowSymbol:
|
||||||
move[1]++;
|
move[1]++;
|
||||||
break;
|
break;
|
||||||
case "→":
|
case rightArrowSymbol:
|
||||||
move[0]++;
|
move[0]++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -59,15 +64,15 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
|
|||||||
next[1] = (next[1] + grid.length) % grid.length;
|
next[1] = (next[1] + grid.length) % grid.length;
|
||||||
setPos(next);
|
setPos(next);
|
||||||
|
|
||||||
if (event.key === " ") {
|
if (event.key === KEY.SPACE) {
|
||||||
const selected = grid[pos[1]][pos[0]];
|
const selected = grid[pos[1]][pos[0]];
|
||||||
const expected = answer[index];
|
const expected = answers[currentAnswerIndex];
|
||||||
if (selected !== expected) {
|
if (selected !== expected) {
|
||||||
props.onFailure();
|
props.onFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIndex(index + 1);
|
setCurrentAnswerIndex(currentAnswerIndex + 1);
|
||||||
if (answer.length === index + 1) props.onSuccess();
|
if (answers.length === currentAnswerIndex + 1) props.onSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,17 +82,17 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
|
|||||||
<GameTimer millis={timer} onExpire={props.onFailure} />
|
<GameTimer millis={timer} onExpire={props.onFailure} />
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h4">Match the symbols!</Typography>
|
<Typography variant="h4">Match the symbols!</Typography>
|
||||||
<Typography variant="h5" color="primary">
|
<Typography variant="h5" color={Settings.theme.primary}>
|
||||||
Targets:{" "}
|
Targets:{" "}
|
||||||
{answer.map((a, i) => {
|
{answers.map((a, i) => {
|
||||||
if (i == index)
|
if (i == currentAnswerIndex)
|
||||||
return (
|
return (
|
||||||
<span key={`${i}`} style={{ fontSize: "1em", color: "blue" }}>
|
<span key={`${i}`} style={{ fontSize: "1em", color: "blue" }}>
|
||||||
{a}
|
{a}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<span key={`${i}`} style={{ fontSize: "1em" }}>
|
<span key={`${i}`} style={{ fontSize: "1em", color: Settings.theme.primary }}>
|
||||||
{a}
|
{a}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@ -98,14 +103,20 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
|
|||||||
<div key={y}>
|
<div key={y}>
|
||||||
<Typography>
|
<Typography>
|
||||||
{line.map((cell, x) => {
|
{line.map((cell, x) => {
|
||||||
if (x == pos[0] && y == pos[1])
|
const isCorrectAnswer = cell === answers[currentAnswerIndex];
|
||||||
|
|
||||||
|
if (x == pos[0] && y == pos[1]) {
|
||||||
|
const selectOptionColor = hasAugment && isCorrectAnswer ? Settings.theme.success : "blue";
|
||||||
return (
|
return (
|
||||||
<span key={`${x}${y}`} style={{ fontSize: fontSize, color: "blue" }}>
|
<span key={`${x}${y}`} style={{ fontSize: fontSize, color: selectOptionColor }}>
|
||||||
{cell}
|
{cell}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const optionColor = hasAugment && isCorrectAnswer ? Settings.theme.success : Settings.theme.primary;
|
||||||
return (
|
return (
|
||||||
<span key={`${x}${y}`} style={{ fontSize: fontSize }}>
|
<span key={`${x}${y}`} style={{ fontSize: fontSize, color: optionColor }}>
|
||||||
{cell}
|
{cell}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@ -120,12 +131,12 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateAnswer(grid: string[][], difficulty: Difficulty): string[] {
|
function generateAnswers(grid: string[][], difficulty: Difficulty): string[] {
|
||||||
const answer = [];
|
const answers = [];
|
||||||
for (let i = 0; i < Math.round(difficulty.symbols); i++) {
|
for (let i = 0; i < Math.round(difficulty.symbols); i++) {
|
||||||
answer.push(grid[Math.floor(Math.random() * grid.length)][Math.floor(Math.random() * grid[0].length)]);
|
answers.push(grid[Math.floor(Math.random() * grid.length)][Math.floor(Math.random() * grid[0].length)]);
|
||||||
}
|
}
|
||||||
return answer;
|
return answers;
|
||||||
}
|
}
|
||||||
|
|
||||||
function randChar(): string {
|
function randChar(): string {
|
||||||
|
@ -42,7 +42,6 @@ export function InfiltrationRoot(props: IProps): React.ReactElement {
|
|||||||
const startingDifficulty = props.location.infiltrationData.startingSecurityLevel;
|
const startingDifficulty = props.location.infiltrationData.startingSecurityLevel;
|
||||||
const difficulty = calcDifficulty(player, startingDifficulty);
|
const difficulty = calcDifficulty(player, startingDifficulty);
|
||||||
const reward = calcReward(player, startingDifficulty);
|
const reward = calcReward(player, startingDifficulty);
|
||||||
console.log(`${difficulty} ${reward}`);
|
|
||||||
|
|
||||||
function cancel(): void {
|
function cancel(): void {
|
||||||
router.toCity();
|
router.toCity();
|
||||||
|
@ -4,8 +4,11 @@ import { IMinigameProps } from "./IMinigameProps";
|
|||||||
import { KeyHandler } from "./KeyHandler";
|
import { KeyHandler } from "./KeyHandler";
|
||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import { getArrow } from "../utils";
|
import { downArrowSymbol, getArrow, leftArrowSymbol, rightArrowSymbol, upArrowSymbol } from "../utils";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -35,23 +38,23 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement {
|
|||||||
const [answer, setAnswer] = useState(generateEmptyField(difficulty));
|
const [answer, setAnswer] = useState(generateEmptyField(difficulty));
|
||||||
const [pos, setPos] = useState([0, 0]);
|
const [pos, setPos] = useState([0, 0]);
|
||||||
const [memoryPhase, setMemoryPhase] = useState(true);
|
const [memoryPhase, setMemoryPhase] = useState(true);
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.MineDetector, true);
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (memoryPhase) return;
|
if (memoryPhase) return;
|
||||||
const move = [0, 0];
|
const move = [0, 0];
|
||||||
const arrow = getArrow(event);
|
const arrow = getArrow(event);
|
||||||
switch (arrow) {
|
switch (arrow) {
|
||||||
case "↑":
|
case upArrowSymbol:
|
||||||
move[1]--;
|
move[1]--;
|
||||||
break;
|
break;
|
||||||
case "←":
|
case leftArrowSymbol:
|
||||||
move[0]--;
|
move[0]--;
|
||||||
break;
|
break;
|
||||||
case "↓":
|
case downArrowSymbol:
|
||||||
move[1]++;
|
move[1]++;
|
||||||
break;
|
break;
|
||||||
case "→":
|
case rightArrowSymbol:
|
||||||
move[0]++;
|
move[0]++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -60,7 +63,7 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement {
|
|||||||
next[1] = (next[1] + minefield.length) % minefield.length;
|
next[1] = (next[1] + minefield.length) % minefield.length;
|
||||||
setPos(next);
|
setPos(next);
|
||||||
|
|
||||||
if (event.key == " ") {
|
if (event.key == KEY.SPACE) {
|
||||||
if (!minefield[pos[1]][pos[0]]) {
|
if (!minefield[pos[1]][pos[0]]) {
|
||||||
props.onFailure();
|
props.onFailure();
|
||||||
return;
|
return;
|
||||||
@ -93,6 +96,7 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement {
|
|||||||
} else {
|
} else {
|
||||||
if (x == pos[0] && y == pos[1]) return <span key={x}>[X] </span>;
|
if (x == pos[0] && y == pos[1]) return <span key={x}>[X] </span>;
|
||||||
if (answer[y][x]) return <span key={x}>[.] </span>;
|
if (answer[y][x]) return <span key={x}>[.] </span>;
|
||||||
|
if (hasAugment && minefield[y][x]) return <span key={x}>[?] </span>;
|
||||||
return <span key={x}>[ ] </span>;
|
return <span key={x}>[ ] </span>;
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
@ -5,6 +5,9 @@ import { KeyHandler } from "./KeyHandler";
|
|||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -30,13 +33,17 @@ export function SlashGame(props: IMinigameProps): React.ReactElement {
|
|||||||
|
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (event.key !== " ") return;
|
if (event.key !== KEY.SPACE) return;
|
||||||
if (phase !== 2) {
|
if (phase !== 2) {
|
||||||
props.onFailure();
|
props.onFailure();
|
||||||
} else {
|
} else {
|
||||||
props.onSuccess();
|
props.onSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.BagOfSand, true);
|
||||||
|
const phaseZeroTime = Math.random() * 3250 + 1500 - (250 + difficulty.window);
|
||||||
|
const phaseOneTime = 250;
|
||||||
|
const timeUntilAttacking = phaseZeroTime + phaseOneTime;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let id = window.setTimeout(() => {
|
let id = window.setTimeout(() => {
|
||||||
@ -44,8 +51,8 @@ export function SlashGame(props: IMinigameProps): React.ReactElement {
|
|||||||
id = window.setTimeout(() => {
|
id = window.setTimeout(() => {
|
||||||
setPhase(2);
|
setPhase(2);
|
||||||
id = window.setTimeout(() => setPhase(0), difficulty.window);
|
id = window.setTimeout(() => setPhase(0), difficulty.window);
|
||||||
}, 250);
|
}, phaseOneTime);
|
||||||
}, Math.random() * 3250 + 1500 - (250 + difficulty.window));
|
}, phaseZeroTime);
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(id);
|
clearInterval(id);
|
||||||
};
|
};
|
||||||
@ -56,6 +63,14 @@ export function SlashGame(props: IMinigameProps): React.ReactElement {
|
|||||||
<GameTimer millis={5000} onExpire={props.onFailure} />
|
<GameTimer millis={5000} onExpire={props.onFailure} />
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h4">Slash when his guard is down!</Typography>
|
<Typography variant="h4">Slash when his guard is down!</Typography>
|
||||||
|
{hasAugment ? (
|
||||||
|
<>
|
||||||
|
<Typography variant="h4">Guard will drop in...</Typography>
|
||||||
|
<GameTimer millis={timeUntilAttacking} onExpire={props.onFailure} />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
{phase === 0 && <Typography variant="h4">Guarding ...</Typography>}
|
{phase === 0 && <Typography variant="h4">Guarding ...</Typography>}
|
||||||
{phase === 1 && <Typography variant="h4">Preparing?</Typography>}
|
{phase === 1 && <Typography variant="h4">Preparing?</Typography>}
|
||||||
{phase === 2 && <Typography variant="h4">ATTACKING!</Typography>}
|
{phase === 2 && <Typography variant="h4">ATTACKING!</Typography>}
|
||||||
|
@ -6,6 +6,10 @@ import { KeyHandler } from "./KeyHandler";
|
|||||||
import { GameTimer } from "./GameTimer";
|
import { GameTimer } from "./GameTimer";
|
||||||
import { random } from "../utils";
|
import { random } from "../utils";
|
||||||
import { interpolate } from "./Difficulty";
|
import { interpolate } from "./Difficulty";
|
||||||
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
|
import { Player } from "../../Player";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
interface Difficulty {
|
interface Difficulty {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
@ -27,7 +31,7 @@ const difficulties: {
|
|||||||
Impossible: { timer: 4000, wiresmin: 9, wiresmax: 9, rules: 4 },
|
Impossible: { timer: 4000, wiresmin: 9, wiresmax: 9, rules: 4 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const types = ["|", ".", "/", "-", "█", "#"];
|
const types = [KEY.PIPE, KEY.DOT, KEY.FORWARD_SLASH, KEY.HYPHEN, "█", KEY.HASH];
|
||||||
|
|
||||||
const colors = ["red", "#FFC107", "blue", "white"];
|
const colors = ["red", "#FFC107", "blue", "white"];
|
||||||
|
|
||||||
@ -56,10 +60,15 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
|
|||||||
rules: 0,
|
rules: 0,
|
||||||
};
|
};
|
||||||
interpolate(difficulties, props.difficulty, difficulty);
|
interpolate(difficulties, props.difficulty, difficulty);
|
||||||
const timer = difficulty.timer;
|
const timer = 99999;
|
||||||
const [wires] = useState(generateWires(difficulty));
|
const [wires] = useState(generateWires(difficulty));
|
||||||
const [cutWires, setCutWires] = useState(new Array(wires.length).fill(false));
|
const [cutWires, setCutWires] = useState(new Array(wires.length).fill(false));
|
||||||
const [questions] = useState(generateQuestion(wires, difficulty));
|
const [questions] = useState(generateQuestion(wires, difficulty));
|
||||||
|
const hasAugment = Player.hasAugmentation(AugmentationNames.WireCuttingManual, true);
|
||||||
|
|
||||||
|
function checkWire(wireNum: number): boolean {
|
||||||
|
return questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1));
|
||||||
|
}
|
||||||
|
|
||||||
function press(this: Document, event: KeyboardEvent): void {
|
function press(this: Document, event: KeyboardEvent): void {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -69,7 +78,7 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
|
|||||||
setCutWires((old) => {
|
setCutWires((old) => {
|
||||||
const next = [...old];
|
const next = [...old];
|
||||||
next[wireNum - 1] = true;
|
next[wireNum - 1] = true;
|
||||||
if (!questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1))) {
|
if (!checkWire(wireNum)) {
|
||||||
props.onFailure();
|
props.onFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +116,14 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
|
|||||||
<div key={i}>
|
<div key={i}>
|
||||||
<Typography>
|
<Typography>
|
||||||
{wires.map((wire, j) => {
|
{wires.map((wire, j) => {
|
||||||
if ((i === 3 || i === 4) && cutWires[j])
|
if ((i === 3 || i === 4) && cutWires[j]) {
|
||||||
return <span key={j}> </span>;
|
return <span key={j}> </span>;
|
||||||
|
}
|
||||||
|
const isCorrectWire = checkWire(j);
|
||||||
|
const wireColor =
|
||||||
|
hasAugment && !isCorrectWire ? Settings.theme.disabled : wire.colors[i % wire.colors.length];
|
||||||
return (
|
return (
|
||||||
<span key={j} style={{ color: wire.colors[i % wire.colors.length] }}>
|
<span key={j} style={{ color: wireColor }}>
|
||||||
|{wire.tpe}|
|
|{wire.tpe}|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
@ -1,21 +1,46 @@
|
|||||||
|
import { KEY } from "../utils/helpers/keyCodes";
|
||||||
|
|
||||||
export function random(min: number, max: number): number {
|
export function random(min: number, max: number): number {
|
||||||
return Math.random() * (max - min) + min;
|
return Math.random() * (max - min) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const upArrowSymbol = "↑";
|
||||||
|
export const downArrowSymbol = "↑";
|
||||||
|
export const leftArrowSymbol = "↑";
|
||||||
|
export const rightArrowSymbol = "↑";
|
||||||
|
|
||||||
export function getArrow(event: KeyboardEvent): string {
|
export function getArrow(event: KeyboardEvent): string {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case "ArrowUp":
|
case KEY.UP_ARROW:
|
||||||
case "w":
|
case KEY.W:
|
||||||
return "↑";
|
return upArrowSymbol;
|
||||||
case "ArrowLeft":
|
case KEY.LEFT_ARROW:
|
||||||
case "a":
|
case KEY.A:
|
||||||
return "←";
|
return leftArrowSymbol;
|
||||||
case "ArrowDown":
|
case KEY.DOWN_ARROW:
|
||||||
case "s":
|
case KEY.S:
|
||||||
return "↓";
|
return downArrowSymbol;
|
||||||
case "ArrowRight":
|
case KEY.RIGHT_ARROW:
|
||||||
case "d":
|
case KEY.D:
|
||||||
return "→";
|
return rightArrowSymbol;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getInverseArrow(event: KeyboardEvent): string {
|
||||||
|
switch (event.key) {
|
||||||
|
case KEY.DOWN_ARROW:
|
||||||
|
case KEY.S:
|
||||||
|
return upArrowSymbol;
|
||||||
|
case KEY.RIGHT_ARROW:
|
||||||
|
case KEY.D:
|
||||||
|
return leftArrowSymbol;
|
||||||
|
case KEY.UP_ARROW:
|
||||||
|
case KEY.W:
|
||||||
|
return downArrowSymbol;
|
||||||
|
case KEY.LEFT_ARROW:
|
||||||
|
case KEY.A:
|
||||||
|
return rightArrowSymbol;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select previous command.
|
// Select previous command.
|
||||||
if (event.key === KEY.UPARROW || (Settings.EnableBashHotkeys && event.key === "p" && event.ctrlKey)) {
|
if (event.key === KEY.UP_ARROW || (Settings.EnableBashHotkeys && event.key === KEY.P && event.ctrlKey)) {
|
||||||
if (Settings.EnableBashHotkeys) {
|
if (Settings.EnableBashHotkeys) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select next command
|
// Select next command
|
||||||
if (event.key === KEY.DOWNARROW || (Settings.EnableBashHotkeys && event.key === "m" && event.ctrlKey)) {
|
if (event.key === KEY.DOWN_ARROW || (Settings.EnableBashHotkeys && event.key === KEY.M && event.ctrlKey)) {
|
||||||
if (Settings.EnableBashHotkeys) {
|
if (Settings.EnableBashHotkeys) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,27 @@ export enum KEY {
|
|||||||
ENTER = "Enter",
|
ENTER = "Enter",
|
||||||
ESC = "Escape",
|
ESC = "Escape",
|
||||||
TAB = "Tab",
|
TAB = "Tab",
|
||||||
UPARROW = "ArrowUp",
|
SPACE = " ",
|
||||||
DOWNARROW = "ArrowDown",
|
BACKSPACE = "Backspace",
|
||||||
LEFTARROW = "ArrowLeft",
|
UP_ARROW = "ArrowUp",
|
||||||
RIGHTARROW = "ArrowRight",
|
DOWN_ARROW = "ArrowDown",
|
||||||
|
LEFT_ARROW = "ArrowLeft",
|
||||||
|
RIGHT_ARROW = "ArrowRight",
|
||||||
|
|
||||||
|
OPEN_BRACKET = "[",
|
||||||
|
CLOSE_BRACKET = "]",
|
||||||
|
LESS_THAN = "<",
|
||||||
|
GREATER_THAN = ">",
|
||||||
|
OPEN_PARENTHESIS = "(",
|
||||||
|
CLOSE_PARENTHESIS = ")",
|
||||||
|
OPEN_BRACE = "{",
|
||||||
|
CLOSE_BRACE = "}",
|
||||||
|
|
||||||
|
PIPE = "|",
|
||||||
|
DOT = ".",
|
||||||
|
FORWARD_SLASH = "/",
|
||||||
|
HYPHEN = "-",
|
||||||
|
HASH = "#",
|
||||||
|
|
||||||
k0 = "0",
|
k0 = "0",
|
||||||
k1 = "1",
|
k1 = "1",
|
||||||
|
Loading…
Reference in New Issue
Block a user