diff --git a/src/Augmentation/ui/SourceFileMinus1.tsx b/src/Augmentation/ui/SourceFileMinus1.tsx index e70fc846c..631209c71 100644 --- a/src/Augmentation/ui/SourceFileMinus1.tsx +++ b/src/Augmentation/ui/SourceFileMinus1.tsx @@ -7,7 +7,7 @@ import * as React from "react"; import { Player } from "../../Player"; import { Exploit, ExploitName } from "../../Exploits/Exploit"; -import { BBAccordion } from "../../ui/React/Accordion"; +import { BBAccordion } from "../../ui/React/BBAccordion"; export function SourceFileMinus1(): React.ReactElement { const exploits = Player.exploits; diff --git a/src/DevMenu.tsx b/src/DevMenu.tsx index 35960c820..b2f515198 100644 --- a/src/DevMenu.tsx +++ b/src/DevMenu.tsx @@ -1,18 +1,8 @@ import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; import { CodingContractTypes } from "./CodingContracts"; import { generateContract, generateRandomContract, generateRandomContractOnHome } from "./CodingContractGenerator"; -import { Companies } from "./Company/Companies"; -import { Programs } from "./Programs/Programs"; -import { Factions } from "./Faction/Factions"; import { IPlayer } from "./PersonObjects/IPlayer"; -import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile"; -import { AllServers } from "./Server/AllServers"; -import { HacknetServer } from "./Hacknet/HacknetServer"; -import { GetServerByHostname } from "./Server/ServerHelpers"; -import { hackWorldDaemon } from "./RedPill"; -import { StockMarket } from "./StockMarket/StockMarket"; import { Bladeburner } from "./Bladeburner/Bladeburner"; -import { Stock } from "./StockMarket/Stock"; import { IEngine } from "./IEngine"; import { saveObject } from "./SaveObject"; @@ -31,66 +21,27 @@ import ButtonGroup from "@material-ui/core/ButtonGroup"; import DoubleArrowIcon from "@material-ui/icons/DoubleArrow"; import ReplyAllIcon from "@material-ui/icons/ReplyAll"; import ReplyIcon from "@material-ui/icons/Reply"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; +import MenuItem from "@material-ui/core/MenuItem"; +import FormControl from "@material-ui/core/FormControl"; +import InputLabel from "@material-ui/core/InputLabel"; import { Theme } from "./ui/React/Theme"; -// Update as additional BitNodes get implemented -const validSFN = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; - -// Some dev menu buttons just add a lot of something for convenience -const tonsPP = 1e27; -const tonsP = 1e12; - -interface IValueAdjusterProps { - label: string; - placeholder: string; - add: (x: number) => void; - subtract: (x: number) => void; - reset: () => void; -} - -function ValueAdjusterComponent(props: IValueAdjusterProps): React.ReactElement { - const [value, setValue] = useState(""); - - function onChange(event: React.ChangeEvent): void { - if (event.target.value === "") setValue(""); - else setValue(parseFloat(event.target.value)); - } - - const { label, placeholder, add, subtract, reset } = props; - return ( - <> - - - - - add(typeof value !== "string" ? value : 0)}> - - - - ), - endAdornment: ( - <> - subtract(typeof value !== "string" ? value : 0)}> - - - - - - - ), - }} - /> - - ); -} +import { General } from "./DevMenu/ui/General"; +import { Stats } from "./DevMenu/ui/Stats"; +import { Factions } from "./DevMenu/ui/Factions"; +import { Augmentations } from "./DevMenu/ui/Augmentations"; +import { SourceFiles } from "./DevMenu/ui/SourceFiles"; +import { Programs } from "./DevMenu/ui/Programs"; +import { Servers } from "./DevMenu/ui/Servers"; +import { Companies } from "./DevMenu/ui/Companies"; +import { Bladeburner as BladeburnerElem } from "./DevMenu/ui/Bladeburner"; +import { Gang } from "./DevMenu/ui/Gang"; +import { Corporation } from "./DevMenu/ui/Corporation"; +import { CodingContracts } from "./DevMenu/ui/CodingContracts"; +import { StockMarket } from "./DevMenu/ui/StockMarket"; +import { Sleeves } from "./DevMenu/ui/Sleeves"; +import { TimeSkip } from "./DevMenu/ui/TimeSkip"; interface IProps { player: IPlayer; @@ -98,1504 +49,33 @@ interface IProps { } export function DevMenuRoot(props: IProps): React.ReactElement { - const [company, setCompany] = useState("ECorp"); - const [faction, setFaction] = useState("Illuminati"); - const [program, setProgram] = useState("NUKE.exe"); - const [server, setServer] = useState("home"); - const [augmentation, setAugmentation] = useState("Augmented Targeting I"); - const [codingcontract, setCodingcontract] = useState("Find Largest Prime Factor"); - const [stockPrice, setStockPrice] = useState(0); - const [stockSymbol, setStockSymbol] = useState(""); - - function setFactionDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setFaction(event.target.value as string); - } - - function setCompanyDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setCompany(event.target.value as string); - } - - function setProgramDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setProgram(event.target.value as string); - } - - function setServerDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setServer(event.target.value as string); - } - - function setAugmentationDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setAugmentation(event.target.value as string); - } - - function setCodingcontractDropdown(event: React.ChangeEvent<{ value: unknown }>): void { - setCodingcontract(event.target.value as string); - } - - function setStockPriceField(event: React.ChangeEvent): void { - setStockPrice(parseFloat(event.target.value)); - } - - function setStockSymbolField(event: React.ChangeEvent): void { - setStockSymbol(event.target.value); - } - - function addMoney(n: number) { - return function () { - props.player.gainMoney(n); - }; - } - - function upgradeRam(): void { - props.player.getHomeComputer().maxRam *= 2; - } - - function quickB1tFlum3(): void { - hackWorldDaemon(props.player.bitNodeN, true, true); - } - - function b1tflum3(): void { - hackWorldDaemon(props.player.bitNodeN, true); - } - - function quickHackW0r1dD43m0n(): void { - hackWorldDaemon(props.player.bitNodeN, false, true); - } - - function hackW0r1dD43m0n(): void { - hackWorldDaemon(props.player.bitNodeN); - } - - function modifyExp(stat: string, modifier: number) { - return function (exp: number) { - switch (stat) { - case "hacking": - if (exp) { - props.player.gainHackingExp(exp * modifier); - } - break; - case "strength": - if (exp) { - props.player.gainStrengthExp(exp * modifier); - } - break; - case "defense": - if (exp) { - props.player.gainDefenseExp(exp * modifier); - } - break; - case "dexterity": - if (exp) { - props.player.gainDexterityExp(exp * modifier); - } - break; - case "agility": - if (exp) { - props.player.gainAgilityExp(exp * modifier); - } - break; - case "charisma": - if (exp) { - props.player.gainCharismaExp(exp * modifier); - } - break; - case "intelligence": - if (exp) { - props.player.gainIntelligenceExp(exp * modifier); - } - break; - } - props.player.updateSkillLevels(); - }; - } - - function modifyKarma(modifier: number) { - return function (amt: number) { - props.player.karma += amt * modifier; - }; - } - - function tonsOfExp(): void { - props.player.gainHackingExp(tonsPP); - props.player.gainStrengthExp(tonsPP); - props.player.gainDefenseExp(tonsPP); - props.player.gainDexterityExp(tonsPP); - props.player.gainAgilityExp(tonsPP); - props.player.gainCharismaExp(tonsPP); - props.player.gainIntelligenceExp(tonsPP); - props.player.updateSkillLevels(); - } - - function resetAllExp(): void { - props.player.hacking_exp = 0; - props.player.strength_exp = 0; - props.player.defense_exp = 0; - props.player.dexterity_exp = 0; - props.player.agility_exp = 0; - props.player.charisma_exp = 0; - props.player.intelligence_exp = 0; - props.player.updateSkillLevels(); - } - - function resetExperience(stat: string): () => void { - return function () { - switch (stat) { - case "hacking": - props.player.hacking_exp = 0; - break; - case "strength": - props.player.strength_exp = 0; - break; - case "defense": - props.player.defense_exp = 0; - break; - case "dexterity": - props.player.dexterity_exp = 0; - break; - case "agility": - props.player.agility_exp = 0; - break; - case "charisma": - props.player.charisma_exp = 0; - break; - case "intelligence": - props.player.intelligence_exp = 0; - break; - } - props.player.updateSkillLevels(); - }; - } - - function resetKarma(): () => void { - return function () { - props.player.karma = 0; - }; - } - - function enableIntelligence(): void { - if (props.player.intelligence === 0) { - props.player.intelligence = 1; - props.player.updateSkillLevels(); - } - } - - function disableIntelligence(): void { - props.player.intelligence_exp = 0; - props.player.intelligence = 0; - props.player.updateSkillLevels(); - } - - function receiveInvite(): void { - props.player.receiveInvite(faction); - } - - function receiveAllInvites(): void { - for (const i in Factions) { - props.player.receiveInvite(Factions[i].name); - } - } - - function modifyFactionRep(modifier: number): (x: number) => void { - return function (reputation: number): void { - const fac = Factions[faction]; - if (fac != null && !isNaN(reputation)) { - fac.playerReputation += reputation * modifier; - } - }; - } - - function resetFactionRep(): void { - const fac = Factions[faction]; - if (fac != null) { - fac.playerReputation = 0; - } - } - - function modifyFactionFavor(modifier: number): (x: number) => void { - return function (favor: number): void { - const fac = Factions[faction]; - if (fac != null && !isNaN(favor)) { - fac.favor += favor * modifier; - } - }; - } - - function resetFactionFavor(): void { - const fac = Factions[faction]; - if (fac != null) { - fac.favor = 0; - } - } - - function tonsOfRep(): void { - for (const i in Factions) { - Factions[i].playerReputation = tonsPP; - } - } - - function resetAllRep(): void { - for (const i in Factions) { - Factions[i].playerReputation = 0; - } - } - - function tonsOfFactionFavor(): void { - for (const i in Factions) { - Factions[i].favor = tonsPP; - } - } - - function resetAllFactionFavor(): void { - for (const i in Factions) { - Factions[i].favor = 0; - } - } - - function queueAug(): void { - props.player.queueAugmentation(augmentation); - } - - function queueAllAugs(): void { - for (const i in AugmentationNames) { - const augName = AugmentationNames[i]; - props.player.queueAugmentation(augName); - } - } - - function setSF(sfN: number, sfLvl: number) { - return function () { - if (sfLvl === 0) { - props.player.sourceFiles = props.player.sourceFiles.filter((sf) => sf.n !== sfN); - return; - } - - if (!props.player.sourceFiles.some((sf) => sf.n === sfN)) { - props.player.sourceFiles.push(new PlayerOwnedSourceFile(sfN, sfLvl)); - return; - } - - for (let i = 0; i < props.player.sourceFiles.length; i++) { - if (props.player.sourceFiles[i].n === sfN) { - props.player.sourceFiles[i].lvl = sfLvl; - } - } - }; - } - - function setAllSF(sfLvl: number) { - return () => { - for (let i = 0; i < validSFN.length; i++) { - setSF(validSFN[i], sfLvl)(); - } - }; - } - - function clearExploits(): void { - props.player.exploits = []; - } - - function addProgram(): void { - if (!props.player.hasProgram(program)) { - props.player.getHomeComputer().programs.push(program); - } - } - - function addAllPrograms(): void { - for (const i in Programs) { - if (!props.player.hasProgram(Programs[i].name)) { - props.player.getHomeComputer().programs.push(Programs[i].name); - } - } - } - - function rootServer(): void { - const s = GetServerByHostname(server); - if (s === null) return; - if (s instanceof HacknetServer) return; - s.hasAdminRights = true; - s.sshPortOpen = true; - s.ftpPortOpen = true; - s.smtpPortOpen = true; - s.httpPortOpen = true; - s.sqlPortOpen = true; - s.openPortCount = 5; - } - - function rootAllServers(): void { - for (const i in AllServers) { - const s = AllServers[i]; - if (s instanceof HacknetServer) return; - s.hasAdminRights = true; - s.sshPortOpen = true; - s.ftpPortOpen = true; - s.smtpPortOpen = true; - s.httpPortOpen = true; - s.sqlPortOpen = true; - s.openPortCount = 5; - } - } - - function minSecurity(): void { - const s = GetServerByHostname(server); - if (s === null) return; - if (s instanceof HacknetServer) return; - s.hackDifficulty = s.minDifficulty; - } - - function minAllSecurity(): void { - for (const i in AllServers) { - const server = AllServers[i]; - if (server instanceof HacknetServer) continue; - server.hackDifficulty = server.minDifficulty; - } - } - - function maxMoney(): void { - const s = GetServerByHostname(server); - if (s === null) return; - if (s instanceof HacknetServer) return; - s.moneyAvailable = s.moneyMax; - } - - function maxAllMoney(): void { - for (const i in AllServers) { - const server = AllServers[i]; - if (server instanceof HacknetServer) continue; - server.moneyAvailable = server.moneyMax; - } - } - - function modifyCompanyRep(modifier: number): (x: number) => void { - return function (reputation: number): void { - const c = Companies[company]; - if (c != null && !isNaN(reputation)) { - c.playerReputation += reputation * modifier; - } - }; - } - - function resetCompanyRep(): void { - Companies[company].playerReputation = 0; - } - - function modifyCompanyFavor(modifier: number): (x: number) => void { - return function (favor: number): void { - const c = Companies[company]; - if (c != null && !isNaN(favor)) { - c.favor += favor * modifier; - } - }; - } - - function resetCompanyFavor(): void { - Companies[company].favor = 0; - } - - function tonsOfRepCompanies(): void { - for (const c in Companies) { - Companies[c].playerReputation = tonsP; - } - } - - function resetAllRepCompanies(): void { - for (const c in Companies) { - Companies[c].playerReputation = 0; - } - } - - function tonsOfFavorCompanies(): void { - for (const c in Companies) { - Companies[c].favor = tonsP; - } - } - - function resetAllFavorCompanies(): void { - for (const c in Companies) { - Companies[c].favor = 0; - } - } - - function modifyBladeburnerRank(modify: number): (x: number) => void { - return function (rank: number): void { - if (props.player.bladeburner) { - props.player.bladeburner.changeRank(props.player, rank * modify); - } - }; - } - - function resetBladeburnerRank(): void { - props.player.bladeburner.rank = 0; - props.player.bladeburner.maxRank = 0; - } - - function addTonsBladeburnerRank(): void { - if (props.player.bladeburner) { - props.player.bladeburner.changeRank(props.player, tonsP); - } - } - - function modifyBladeburnerCycles(modify: number): (x: number) => void { - return function (cycles: number): void { - if (props.player.bladeburner) { - props.player.bladeburner.storedCycles += cycles * modify; - } - }; - } - - function resetBladeburnerCycles(): void { - if (props.player.bladeburner) { - props.player.bladeburner.storedCycles = 0; - } - } - - function addTonsBladeburnerCycles(): void { - if (props.player.bladeburner) { - props.player.bladeburner.storedCycles += tonsP; - } - } - - function addTonsGangCycles(): void { - if (props.player.gang) { - props.player.gang.storedCycles = tonsP; - } - } - - function modifyGangCycles(modify: number): (x: number) => void { - return function (cycles: number): void { - if (props.player.gang) { - props.player.gang.storedCycles += cycles * modify; - } - }; - } - - function resetGangCycles(): void { - if (props.player.gang) { - props.player.gang.storedCycles = 0; - } - } - - function addTonsCorporationFunds(): void { - if (props.player.corporation) { - props.player.corporation.funds = props.player.corporation.funds.plus(1e99); - } - } - - function resetCorporationFunds(): void { - if (props.player.corporation) { - props.player.corporation.funds = props.player.corporation.funds.minus(props.player.corporation.funds); - } - } - - function addTonsCorporationCycles(): void { - if (props.player.corporation) { - props.player.corporation.storedCycles = tonsP; - } - } - - function modifyCorporationCycles(modify: number): (x: number) => void { - return function (cycles: number): void { - if (props.player.corporation) { - props.player.corporation.storedCycles += cycles * modify; - } - }; - } - - function resetCorporationCycles(): void { - if (props.player.corporation) { - props.player.corporation.storedCycles = 0; - } - } - - function finishCorporationProducts(): void { - if (!props.player.corporation) return; - props.player.corporation.divisions.forEach((div) => { - Object.keys(div.products).forEach((prod) => { - const product = div.products[prod]; - if (product === undefined) throw new Error("Impossible product undefined"); - product.prog = 99.9; - }); - }); - } - - function addCorporationResearch(): void { - if (!props.player.corporation) return; - props.player.corporation.divisions.forEach((div) => { - div.sciResearch.qty += 1e10; - }); - } - - function specificContract(): void { - generateContract({ - problemType: codingcontract, - server: "home", - }); - } - - function processStocks(sub: (arg0: Stock) => void): void { - const inputSymbols = stockSymbol.replace(/\s/g, ""); - - let match: (symbol: string) => boolean = (): boolean => { - return true; - }; - - if (inputSymbols !== "" && inputSymbols !== "all") { - match = function (symbol: string): boolean { - return inputSymbols.split(",").includes(symbol); - }; - } - - for (const name in StockMarket) { - if (StockMarket.hasOwnProperty(name)) { - const stock = StockMarket[name]; - if (stock instanceof Stock && match(stock.symbol)) { - sub(stock); - } - } - } - } - - function doSetStockPrice(): void { - if (!isNaN(stockPrice)) { - processStocks((stock: Stock) => { - stock.price = stockPrice; - }); - } - } - - function viewStockCaps(): void { - const stocks: JSX.Element[] = []; - processStocks((stock: Stock) => { - stocks.push( - - {stock.symbol} - - - - , - ); - }); - dialogBoxCreate( - - - - - - - {stocks} - -
StockPrice cap
, - ); - } - - function sleeveMaxAllShock(): void { - for (let i = 0; i < props.player.sleeves.length; ++i) { - props.player.sleeves[i].shock = 0; - } - } - - function sleeveClearAllShock(): void { - for (let i = 0; i < props.player.sleeves.length; ++i) { - props.player.sleeves[i].shock = 100; - } - } - - function sleeveSyncMaxAll(): void { - for (let i = 0; i < props.player.sleeves.length; ++i) { - props.player.sleeves[i].sync = 100; - } - } - - function sleeveSyncClearAll(): void { - for (let i = 0; i < props.player.sleeves.length; ++i) { - props.player.sleeves[i].sync = 0; - } - } - - function timeskip(time: number) { - return () => { - props.player.lastUpdate -= time; - props.engine._lastUpdate -= time; - saveObject.saveGame(props.engine.indexedDb); - setTimeout(() => location.reload(), 1000); - }; - } - - const factions = []; - for (const i in Factions) { - factions.push( - , - ); - } - - const augs = []; - for (const i in AugmentationNames) { - augs.push( - , - ); - } - - const programs = []; - for (const i in Programs) { - programs.push( - , - ); - } - - const servers = []; - for (const i in AllServers) { - const hn = AllServers[i].hostname; - servers.push( - , - ); - } - - const companies = []; - for (const c in Companies) { - const name = Companies[c].name; - companies.push( - , - ); - } - - const contractTypes = []; - const contractTypeNames = Object.keys(CodingContractTypes); - for (let i = 0; i < contractTypeNames.length; i++) { - const name = contractTypeNames[i]; - contractTypes.push( - , - ); - } - return ( -
-
-

Development Menu - Only meant to be used for testing/debugging

-
-
-

Generic

-
-
- - - - - - -
-
- - - - -
-
-
-
-

Experience / Stats

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- All: - - - -
- Hacking: - - -
- Strength: - - -
- Defense: - - -
- Dexterity: - - -
- Agility: - - -
- Charisma: - - -
- Intelligence: - - - - - - -
- Karma: - - -
-
-
-
-
-
-

Factions

-
- - - - - - - - - - - - - - - - - - - - - - - -
- Faction: - - -
- Reputation: - - -
- Favor: - - -
- All Reputation: - - - -
- All Favor: - - - -
-
-
-
-
-
-

Augmentations

-
- - - - - - - - - - - -
- Aug: - - -
- Queue: - - - -
-
-
-
-
-
-

Source-Files

-
- - - - - - - - - - - {validSFN.map((i) => ( - - - - - ))} - -
- Exploits: - - -
- All: - - - - - - - -
- SF-{i}: - - - - - - - -
-
-
-
-
-
-

Programs

-
- - - - - - - - - - - -
- Program: - - -
- Add: - - - -
-
-
-
-
-
-

Servers

-
- - - - - - - - - - - - - - - - - - - - - - -
- Server: - - -
- Root: - - - - -
- Security: - - - - -
- Money: - - - - -
-
-
-
-
-
-

Companies

-
- - - - - - - - - - - - - - - - - - - - - - - -
- Company: - - -
- Reputation: - - -
- Favor: - - -
- All Reputation: - - - -
- All Favor: - - - -
-
-
+ <> +

Development Menu - Only meant to be used for testing/debugging

+ + + + + + + + - {props.player.bladeburner instanceof Bladeburner && ( -
-
-
-

Bladeburner

-
- - - - - - - - - - - - - -
- Rank: - - - - -
- Cycles: - - - - -
-
-
- )} + {props.player.bladeburner instanceof Bladeburner && } - {props.player.inGang() && ( -
-
-
-

Gang

-
- - - - - - - - -
- Cycles: - - - - -
-
-
- )} + {props.player.inGang() && } - {props.player.hasCorporation() && ( -
-
-
-

Corporation

-
- - - - - - - - - - - - - - - - - -
- - -
- Cycles: - - - - -
- -
- -
-
-
- )} + {props.player.hasCorporation() && } -
-
-
-

Coding Contracts

-
- - - - - - - - - -
- - -
- - -
-
-
+ - {props.player.hasWseAccount && ( -
-
-
-

Stock Market

-
- - - - - - - - - - - - - - - -
- Symbol: - - -
- Price: - - - -
- Caps: - - -
-
-
- )} + {props.player.hasWseAccount && } - {props.player.sleeves.length > 0 && ( -
-
-
-

Sleeves

-
- - - - - - - - - - - - - -
- Shock: - - - - -
- Sync: - - - - -
-
-
- )} + {props.player.sleeves.length > 0 && } -
-
-
-

Offline time skip:

-
-
- - - -
-
-
-
+ +
); } diff --git a/src/DevMenu/ui/Adjuster.tsx b/src/DevMenu/ui/Adjuster.tsx new file mode 100644 index 000000000..657176633 --- /dev/null +++ b/src/DevMenu/ui/Adjuster.tsx @@ -0,0 +1,60 @@ +import React, { useState } from "react"; +import AddIcon from "@material-ui/icons/Add"; +import RemoveIcon from "@material-ui/icons/Remove"; +import IconButton from "@material-ui/core/IconButton"; +import ExposureZeroIcon from "@material-ui/icons/ExposureZero"; +import DoubleArrowIcon from "@material-ui/icons/DoubleArrow"; +import { TextField } from "../../ui/React/TextField"; + +interface IProps { + label: string; + placeholder: string; + add: (x: number) => void; + subtract: (x: number) => void; + tons: () => void; + reset: () => void; +} + +export function Adjuster(props: IProps): React.ReactElement { + const [value, setValue] = useState(""); + + function onChange(event: React.ChangeEvent): void { + if (event.target.value === "") setValue(""); + else setValue(parseFloat(event.target.value)); + } + + const { label, placeholder, add, subtract, reset, tons } = props; + return ( + <> + + + + + add(typeof value !== "string" ? value : 0)}> + + + + ), + endAdornment: ( + <> + subtract(typeof value !== "string" ? value : 0)}> + + + + + + + ), + }} + /> + + ); +} diff --git a/src/DevMenu/ui/Augmentations.tsx b/src/DevMenu/ui/Augmentations.tsx new file mode 100644 index 000000000..94fd032e6 --- /dev/null +++ b/src/DevMenu/ui/Augmentations.tsx @@ -0,0 +1,81 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; +import MenuItem from "@material-ui/core/MenuItem"; +import IconButton from "@material-ui/core/IconButton"; +import ReplyAllIcon from "@material-ui/icons/ReplyAll"; +import ReplyIcon from "@material-ui/icons/Reply"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Augmentations(props: IProps): React.ReactElement { + const [augmentation, setAugmentation] = useState("Augmented Targeting I"); + + function setAugmentationDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setAugmentation(event.target.value as string); + } + function queueAug(): void { + props.player.queueAugmentation(augmentation); + } + + function queueAllAugs(): void { + for (const i in AugmentationNames) { + const augName = AugmentationNames[i]; + props.player.queueAugmentation(augName); + } + } + return ( + + }> +

Augmentations

+
+ + + + + + + + +
+ Aug: + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Bladeburner.tsx b/src/DevMenu/ui/Bladeburner.tsx new file mode 100644 index 000000000..287dc9603 --- /dev/null +++ b/src/DevMenu/ui/Bladeburner.tsx @@ -0,0 +1,101 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Bladeburner(props: IProps): React.ReactElement { + function modifyBladeburnerRank(modify: number): (x: number) => void { + return function (rank: number): void { + if (props.player.bladeburner) { + props.player.bladeburner.changeRank(props.player, rank * modify); + } + }; + } + + function resetBladeburnerRank(): void { + props.player.bladeburner.rank = 0; + props.player.bladeburner.maxRank = 0; + } + + function addTonsBladeburnerRank(): void { + if (props.player.bladeburner) { + props.player.bladeburner.changeRank(props.player, bigNumber); + } + } + + function modifyBladeburnerCycles(modify: number): (x: number) => void { + return function (cycles: number): void { + if (props.player.bladeburner) { + props.player.bladeburner.storedCycles += cycles * modify; + } + }; + } + + function resetBladeburnerCycles(): void { + if (props.player.bladeburner) { + props.player.bladeburner.storedCycles = 0; + } + } + + function addTonsBladeburnerCycles(): void { + if (props.player.bladeburner) { + props.player.bladeburner.storedCycles += bigNumber; + } + } + + return ( + + }> +

Bladeburner

+
+ + + + + + + + + + + + +
+ Rank: + + +
+ Cycles: + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/CodingContracts.tsx b/src/DevMenu/ui/CodingContracts.tsx new file mode 100644 index 000000000..9944f2b43 --- /dev/null +++ b/src/DevMenu/ui/CodingContracts.tsx @@ -0,0 +1,74 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { generateContract, generateRandomContract, generateRandomContractOnHome } from "../../CodingContractGenerator"; +import ButtonGroup from "@material-ui/core/ButtonGroup"; +import MenuItem from "@material-ui/core/MenuItem"; +import { CodingContractTypes } from "../../CodingContracts"; + +// Update as additional BitNodes get implemented +const validSFN = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function CodingContracts(props: IProps): React.ReactElement { + const [codingcontract, setCodingcontract] = useState("Find Largest Prime Factor"); + function setCodingcontractDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setCodingcontract(event.target.value as string); + } + + function specificContract(): void { + generateContract({ + problemType: codingcontract, + server: "home", + }); + } + + return ( + + }> +

Coding Contracts

+
+ + + + + + + + + + +
+ + +
+ + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Companies.tsx b/src/DevMenu/ui/Companies.tsx new file mode 100644 index 000000000..eb698db63 --- /dev/null +++ b/src/DevMenu/ui/Companies.tsx @@ -0,0 +1,156 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { Companies as AllCompanies } from "../../Company/Companies"; +import FormControl from "@material-ui/core/FormControl"; +import MenuItem from "@material-ui/core/MenuItem"; +import IconButton from "@material-ui/core/IconButton"; +import ReplyAllIcon from "@material-ui/icons/ReplyAll"; +import ReplyIcon from "@material-ui/icons/Reply"; +import InputLabel from "@material-ui/core/InputLabel"; +import { Adjuster } from "./Adjuster"; + +const bigNumber = 1e12; + +interface IProps { + player: IPlayer; +} + +export function Companies(props: IProps): React.ReactElement { + const [company, setCompany] = useState("ECorp"); + function setCompanyDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setCompany(event.target.value as string); + } + function resetCompanyRep(): void { + AllCompanies[company].playerReputation = 0; + } + + function modifyCompanyRep(modifier: number): (x: number) => void { + return function (reputation: number): void { + const c = AllCompanies[company]; + if (c != null && !isNaN(reputation)) { + c.playerReputation += reputation * modifier; + } + }; + } + + function modifyCompanyFavor(modifier: number): (x: number) => void { + return function (favor: number): void { + const c = AllCompanies[company]; + if (c != null && !isNaN(favor)) { + c.favor += favor * modifier; + } + }; + } + + function resetCompanyFavor(): void { + AllCompanies[company].favor = 0; + } + + function tonsOfRepCompanies(): void { + for (const c in AllCompanies) { + AllCompanies[c].playerReputation = bigNumber; + } + } + + function resetAllRepCompanies(): void { + for (const c in AllCompanies) { + AllCompanies[c].playerReputation = 0; + } + } + + function tonsOfFavorCompanies(): void { + for (const c in AllCompanies) { + AllCompanies[c].favor = bigNumber; + } + } + + function resetAllFavorCompanies(): void { + for (const c in AllCompanies) { + AllCompanies[c].favor = 0; + } + } + + return ( + + }> +

Companies

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ Company: + + +
+ Reputation: + + modifyCompanyRep(1)(bigNumber)} + add={modifyCompanyRep(1)} + subtract={modifyCompanyRep(-1)} + reset={resetCompanyRep} + /> +
+ Favor: + + modifyCompanyFavor(1)(2000)} + add={modifyCompanyFavor(1)} + subtract={modifyCompanyFavor(-1)} + reset={resetCompanyFavor} + /> +
+ All Reputation: + + + +
+ All Favor: + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Corporation.tsx b/src/DevMenu/ui/Corporation.tsx new file mode 100644 index 000000000..8505b395d --- /dev/null +++ b/src/DevMenu/ui/Corporation.tsx @@ -0,0 +1,113 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Corporation(props: IProps): React.ReactElement { + function addTonsCorporationFunds(): void { + if (props.player.corporation) { + props.player.corporation.funds = props.player.corporation.funds.plus(1e99); + } + } + + function resetCorporationFunds(): void { + if (props.player.corporation) { + props.player.corporation.funds = props.player.corporation.funds.minus(props.player.corporation.funds); + } + } + + function addTonsCorporationCycles(): void { + if (props.player.corporation) { + props.player.corporation.storedCycles = bigNumber; + } + } + + function modifyCorporationCycles(modify: number): (x: number) => void { + return function (cycles: number): void { + if (props.player.corporation) { + props.player.corporation.storedCycles += cycles * modify; + } + }; + } + + function resetCorporationCycles(): void { + if (props.player.corporation) { + props.player.corporation.storedCycles = 0; + } + } + + function finishCorporationProducts(): void { + if (!props.player.corporation) return; + props.player.corporation.divisions.forEach((div) => { + Object.keys(div.products).forEach((prod) => { + const product = div.products[prod]; + if (product === undefined) throw new Error("Impossible product undefined"); + product.prog = 99.9; + }); + }); + } + + function addCorporationResearch(): void { + if (!props.player.corporation) return; + props.player.corporation.divisions.forEach((div) => { + div.sciResearch.qty += 1e10; + }); + } + + return ( + + }> +

Corporation

+
+ + + + + + + + + + + + + + + + + +
+ + +
+ Cycles: + + +
+ +
+ +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Factions.tsx b/src/DevMenu/ui/Factions.tsx new file mode 100644 index 000000000..1692eb28b --- /dev/null +++ b/src/DevMenu/ui/Factions.tsx @@ -0,0 +1,193 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { Factions as AllFaction } from "../../Faction/Factions"; +import FormControl from "@material-ui/core/FormControl"; +import MenuItem from "@material-ui/core/MenuItem"; +import IconButton from "@material-ui/core/IconButton"; +import ReplyAllIcon from "@material-ui/icons/ReplyAll"; +import ReplyIcon from "@material-ui/icons/Reply"; +import InputLabel from "@material-ui/core/InputLabel"; + +const bigNumber = 1e12; + +interface IProps { + player: IPlayer; +} + +export function Factions(props: IProps): React.ReactElement { + const [faction, setFaction] = useState("Illuminati"); + + function setFactionDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setFaction(event.target.value as string); + } + + function receiveInvite(): void { + props.player.receiveInvite(faction); + } + + function receiveAllInvites(): void { + for (const i in AllFaction) { + props.player.receiveInvite(AllFaction[i].name); + } + } + + function modifyFactionRep(modifier: number): (x: number) => void { + return function (reputation: number): void { + const fac = AllFaction[faction]; + if (fac != null && !isNaN(reputation)) { + fac.playerReputation += reputation * modifier; + } + }; + } + + function resetFactionRep(): void { + const fac = AllFaction[faction]; + if (fac != null) { + fac.playerReputation = 0; + } + } + + function modifyFactionFavor(modifier: number): (x: number) => void { + return function (favor: number): void { + const fac = AllFaction[faction]; + if (fac != null && !isNaN(favor)) { + fac.favor += favor * modifier; + } + }; + } + + function resetFactionFavor(): void { + const fac = AllFaction[faction]; + if (fac != null) { + fac.favor = 0; + } + } + + function tonsOfRep(): void { + for (const i in AllFaction) { + AllFaction[i].playerReputation = bigNumber; + } + } + + function resetAllRep(): void { + for (const i in AllFaction) { + AllFaction[i].playerReputation = 0; + } + } + + function tonsOfFactionFavor(): void { + for (const i in AllFaction) { + AllFaction[i].favor = bigNumber; + } + } + + function resetAllFactionFavor(): void { + for (const i in AllFaction) { + AllFaction[i].favor = 0; + } + } + + return ( + + }> +

Factions

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ Faction: + + + Faction + + +
+ Reputation: + + modifyFactionRep(1)(bigNumber)} + add={modifyFactionRep(1)} + subtract={modifyFactionRep(-1)} + reset={resetFactionRep} + /> +
+ Favor: + + modifyFactionFavor(1)(2000)} + add={modifyFactionFavor(1)} + subtract={modifyFactionFavor(-1)} + reset={resetFactionFavor} + /> +
+ All Reputation: + + + +
+ All Favor: + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Gang.tsx b/src/DevMenu/ui/Gang.tsx new file mode 100644 index 000000000..8ad25fb7b --- /dev/null +++ b/src/DevMenu/ui/Gang.tsx @@ -0,0 +1,67 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Gang(props: IProps): React.ReactElement { + function addTonsGangCycles(): void { + if (props.player.gang) { + props.player.gang.storedCycles = bigNumber; + } + } + + function modifyGangCycles(modify: number): (x: number) => void { + return function (cycles: number): void { + if (props.player.gang) { + props.player.gang.storedCycles += cycles * modify; + } + }; + } + + function resetGangCycles(): void { + if (props.player.gang) { + props.player.gang.storedCycles = 0; + } + } + + return ( + + }> +

Gang

+
+ + + + + + + + +
+ Cycles: + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/General.tsx b/src/DevMenu/ui/General.tsx new file mode 100644 index 000000000..210a16f96 --- /dev/null +++ b/src/DevMenu/ui/General.tsx @@ -0,0 +1,87 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Money } from "../../ui/React/Money"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { hackWorldDaemon } from "../../RedPill"; + +interface IProps { + player: IPlayer; +} + +export function General(props: IProps): React.ReactElement { + function addMoney(n: number) { + return function () { + props.player.gainMoney(n); + }; + } + + function upgradeRam(): void { + props.player.getHomeComputer().maxRam *= 2; + } + + function quickB1tFlum3(): void { + hackWorldDaemon(props.player.bitNodeN, true, true); + } + + function b1tflum3(): void { + hackWorldDaemon(props.player.bitNodeN, true); + } + + function quickHackW0r1dD43m0n(): void { + hackWorldDaemon(props.player.bitNodeN, false, true); + } + + function hackW0r1dD43m0n(): void { + hackWorldDaemon(props.player.bitNodeN); + } + + return ( + + }> +

General

+
+ +
+ + + + + + +
+
+ + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Programs.tsx b/src/DevMenu/ui/Programs.tsx new file mode 100644 index 000000000..85cd88406 --- /dev/null +++ b/src/DevMenu/ui/Programs.tsx @@ -0,0 +1,80 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { Programs as AllPrograms } from "../../Programs/Programs"; +import FormControl from "@material-ui/core/FormControl"; +import MenuItem from "@material-ui/core/MenuItem"; +import IconButton from "@material-ui/core/IconButton"; +import ReplyAllIcon from "@material-ui/icons/ReplyAll"; +import ReplyIcon from "@material-ui/icons/Reply"; +import InputLabel from "@material-ui/core/InputLabel"; + +const bigNumber = 1e12; + +interface IProps { + player: IPlayer; +} + +export function Programs(props: IProps): React.ReactElement { + const [program, setProgram] = useState("NUKE.exe"); + function setProgramDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setProgram(event.target.value as string); + } + function addProgram(): void { + if (!props.player.hasProgram(program)) { + props.player.getHomeComputer().programs.push(program); + } + } + + function addAllPrograms(): void { + for (const i in AllPrograms) { + if (!props.player.hasProgram(AllPrograms[i].name)) { + props.player.getHomeComputer().programs.push(AllPrograms[i].name); + } + } + } + + return ( + + }> +

Programs

+
+ + + + + + + + + + + + +
+ Program: + + +
+ Add: + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Servers.tsx b/src/DevMenu/ui/Servers.tsx new file mode 100644 index 000000000..050c6607f --- /dev/null +++ b/src/DevMenu/ui/Servers.tsx @@ -0,0 +1,149 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Select } from "../../ui/React/Select"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { AllServers } from "../../Server/AllServers"; +import { HacknetServer } from "../../Hacknet/HacknetServer"; +import { GetServerByHostname } from "../../Server/ServerHelpers"; +import FormControl from "@material-ui/core/FormControl"; +import MenuItem from "@material-ui/core/MenuItem"; +import IconButton from "@material-ui/core/IconButton"; +import ReplyAllIcon from "@material-ui/icons/ReplyAll"; +import ReplyIcon from "@material-ui/icons/Reply"; +import InputLabel from "@material-ui/core/InputLabel"; + +const bigNumber = 1e12; + +interface IProps { + player: IPlayer; +} + +export function Servers(props: IProps): React.ReactElement { + const [server, setServer] = useState("home"); + function setServerDropdown(event: React.ChangeEvent<{ value: unknown }>): void { + setServer(event.target.value as string); + } + function rootServer(): void { + const s = GetServerByHostname(server); + if (s === null) return; + if (s instanceof HacknetServer) return; + s.hasAdminRights = true; + s.sshPortOpen = true; + s.ftpPortOpen = true; + s.smtpPortOpen = true; + s.httpPortOpen = true; + s.sqlPortOpen = true; + s.openPortCount = 5; + } + + function rootAllServers(): void { + for (const i in AllServers) { + const s = AllServers[i]; + if (s instanceof HacknetServer) return; + s.hasAdminRights = true; + s.sshPortOpen = true; + s.ftpPortOpen = true; + s.smtpPortOpen = true; + s.httpPortOpen = true; + s.sqlPortOpen = true; + s.openPortCount = 5; + } + } + + function minSecurity(): void { + const s = GetServerByHostname(server); + if (s === null) return; + if (s instanceof HacknetServer) return; + s.hackDifficulty = s.minDifficulty; + } + + function minAllSecurity(): void { + for (const i in AllServers) { + const server = AllServers[i]; + if (server instanceof HacknetServer) continue; + server.hackDifficulty = server.minDifficulty; + } + } + + function maxMoney(): void { + const s = GetServerByHostname(server); + if (s === null) return; + if (s instanceof HacknetServer) return; + s.moneyAvailable = s.moneyMax; + } + + function maxAllMoney(): void { + for (const i in AllServers) { + const server = AllServers[i]; + if (server instanceof HacknetServer) continue; + server.moneyAvailable = server.moneyMax; + } + } + + return ( + + }> +

Servers

+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ Server: + + +
+ Root: + + + + +
+ Security: + + + + +
+ Money: + + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Sleeves.tsx b/src/DevMenu/ui/Sleeves.tsx new file mode 100644 index 000000000..6e58a05e3 --- /dev/null +++ b/src/DevMenu/ui/Sleeves.tsx @@ -0,0 +1,81 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import ButtonGroup from "@material-ui/core/ButtonGroup"; + +// Update as additional BitNodes get implemented +const validSFN = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Sleeves(props: IProps): React.ReactElement { + function sleeveMaxAllShock(): void { + for (let i = 0; i < props.player.sleeves.length; ++i) { + props.player.sleeves[i].shock = 0; + } + } + + function sleeveClearAllShock(): void { + for (let i = 0; i < props.player.sleeves.length; ++i) { + props.player.sleeves[i].shock = 100; + } + } + + function sleeveSyncMaxAll(): void { + for (let i = 0; i < props.player.sleeves.length; ++i) { + props.player.sleeves[i].sync = 100; + } + } + + function sleeveSyncClearAll(): void { + for (let i = 0; i < props.player.sleeves.length; ++i) { + props.player.sleeves[i].sync = 0; + } + } + + return ( + + }> +

Sleeves

+
+ + + + + + + + + + + + + + +
+ Shock: + + + + +
+ Sync: + + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/SourceFiles.tsx b/src/DevMenu/ui/SourceFiles.tsx new file mode 100644 index 000000000..6254b7f65 --- /dev/null +++ b/src/DevMenu/ui/SourceFiles.tsx @@ -0,0 +1,103 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import ButtonGroup from "@material-ui/core/ButtonGroup"; + +// Update as additional BitNodes get implemented +const validSFN = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function SourceFiles(props: IProps): React.ReactElement { + function setSF(sfN: number, sfLvl: number) { + return function () { + if (sfLvl === 0) { + props.player.sourceFiles = props.player.sourceFiles.filter((sf) => sf.n !== sfN); + return; + } + + if (!props.player.sourceFiles.some((sf) => sf.n === sfN)) { + props.player.sourceFiles.push(new PlayerOwnedSourceFile(sfN, sfLvl)); + return; + } + + for (let i = 0; i < props.player.sourceFiles.length; i++) { + if (props.player.sourceFiles[i].n === sfN) { + props.player.sourceFiles[i].lvl = sfLvl; + } + } + }; + } + + function setAllSF(sfLvl: number) { + return () => { + for (let i = 0; i < validSFN.length; i++) { + setSF(validSFN[i], sfLvl)(); + } + }; + } + + function clearExploits(): void { + props.player.exploits = []; + } + + return ( + + }> +

Source-Files

+
+ + + + + + + + + + + + {validSFN.map((i) => ( + + + + + ))} + +
+ Exploits: + + +
+ All: + + + + + + + +
+ SF-{i}: + + + + + + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/Stats.tsx b/src/DevMenu/ui/Stats.tsx new file mode 100644 index 000000000..d4adad16f --- /dev/null +++ b/src/DevMenu/ui/Stats.tsx @@ -0,0 +1,286 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function Stats(props: IProps): React.ReactElement { + function modifyExp(stat: string, modifier: number) { + return function (exp: number) { + switch (stat) { + case "hacking": + if (exp) { + props.player.gainHackingExp(exp * modifier); + } + break; + case "strength": + if (exp) { + props.player.gainStrengthExp(exp * modifier); + } + break; + case "defense": + if (exp) { + props.player.gainDefenseExp(exp * modifier); + } + break; + case "dexterity": + if (exp) { + props.player.gainDexterityExp(exp * modifier); + } + break; + case "agility": + if (exp) { + props.player.gainAgilityExp(exp * modifier); + } + break; + case "charisma": + if (exp) { + props.player.gainCharismaExp(exp * modifier); + } + break; + case "intelligence": + if (exp) { + props.player.gainIntelligenceExp(exp * modifier); + } + break; + } + props.player.updateSkillLevels(); + }; + } + + function modifyKarma(modifier: number) { + return function (amt: number) { + props.player.karma += amt * modifier; + }; + } + + function tonsOfExp(): void { + props.player.gainHackingExp(bigNumber); + props.player.gainStrengthExp(bigNumber); + props.player.gainDefenseExp(bigNumber); + props.player.gainDexterityExp(bigNumber); + props.player.gainAgilityExp(bigNumber); + props.player.gainCharismaExp(bigNumber); + props.player.gainIntelligenceExp(bigNumber); + props.player.updateSkillLevels(); + } + + function resetAllExp(): void { + props.player.hacking_exp = 0; + props.player.strength_exp = 0; + props.player.defense_exp = 0; + props.player.dexterity_exp = 0; + props.player.agility_exp = 0; + props.player.charisma_exp = 0; + props.player.intelligence_exp = 0; + props.player.updateSkillLevels(); + } + + function resetExperience(stat: string): () => void { + return function () { + switch (stat) { + case "hacking": + props.player.hacking_exp = 0; + break; + case "strength": + props.player.strength_exp = 0; + break; + case "defense": + props.player.defense_exp = 0; + break; + case "dexterity": + props.player.dexterity_exp = 0; + break; + case "agility": + props.player.agility_exp = 0; + break; + case "charisma": + props.player.charisma_exp = 0; + break; + case "intelligence": + props.player.intelligence_exp = 0; + break; + } + props.player.updateSkillLevels(); + }; + } + + function resetKarma(): () => void { + return function () { + props.player.karma = 0; + }; + } + + function enableIntelligence(): void { + if (props.player.intelligence === 0) { + props.player.intelligence = 1; + props.player.updateSkillLevels(); + } + } + + function disableIntelligence(): void { + props.player.intelligence_exp = 0; + props.player.intelligence = 0; + props.player.updateSkillLevels(); + } + + return ( + + }> +

Experience / Stats

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ All: + + + +
+ Hacking: + + modifyExp("hacking", 1)(bigNumber)} + add={modifyExp("hacking", 1)} + subtract={modifyExp("hacking", -1)} + reset={resetExperience("hacking")} + /> +
+ Strength: + + modifyExp("strength", 1)(bigNumber)} + add={modifyExp("strength", 1)} + subtract={modifyExp("strength", -1)} + reset={resetExperience("strength")} + /> +
+ Defense: + + modifyExp("defense", 1)(bigNumber)} + add={modifyExp("defense", 1)} + subtract={modifyExp("defense", -1)} + reset={resetExperience("defense")} + /> +
+ Dexterity: + + modifyExp("dexterity", 1)(bigNumber)} + add={modifyExp("dexterity", 1)} + subtract={modifyExp("dexterity", -1)} + reset={resetExperience("dexterity")} + /> +
+ Agility: + + modifyExp("agility", 1)(bigNumber)} + add={modifyExp("agility", 1)} + subtract={modifyExp("agility", -1)} + reset={resetExperience("agility")} + /> +
+ Charisma: + + modifyExp("charisma", 1)(bigNumber)} + add={modifyExp("charisma", 1)} + subtract={modifyExp("charisma", -1)} + reset={resetExperience("charisma")} + /> +
+ Intelligence: + + modifyExp("intelligence", 1)(bigNumber)} + add={modifyExp("intelligence", 1)} + subtract={modifyExp("intelligence", -1)} + reset={resetExperience("intelligence")} + /> + + + + +
+ Karma: + + modifyExp("intelligence", 1)(100000)} + add={modifyKarma(1)} + subtract={modifyKarma(-1)} + reset={resetKarma()} + /> +
+
+
+ ); +} diff --git a/src/DevMenu/ui/StockMarket.tsx b/src/DevMenu/ui/StockMarket.tsx new file mode 100644 index 000000000..6696ac71e --- /dev/null +++ b/src/DevMenu/ui/StockMarket.tsx @@ -0,0 +1,128 @@ +import React, { useState } from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { TextField } from "../../ui/React/TextField"; +import { Money } from "../../ui/React/Money"; +import { Adjuster } from "./Adjuster"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import { dialogBoxCreate } from "../../../utils/DialogBox"; +import { StockMarket as SM } from "../../StockMarket/StockMarket"; +import { Stock } from "../../StockMarket/Stock"; + +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; +} + +export function StockMarket(props: IProps): React.ReactElement { + const [stockPrice, setStockPrice] = useState(0); + const [stockSymbol, setStockSymbol] = useState(""); + + function setStockPriceField(event: React.ChangeEvent): void { + setStockPrice(parseFloat(event.target.value)); + } + + function setStockSymbolField(event: React.ChangeEvent): void { + setStockSymbol(event.target.value); + } + + function processStocks(sub: (arg0: Stock) => void): void { + const inputSymbols = stockSymbol.replace(/\s/g, ""); + + let match: (symbol: string) => boolean = (): boolean => { + return true; + }; + + if (inputSymbols !== "" && inputSymbols !== "all") { + match = function (symbol: string): boolean { + return inputSymbols.split(",").includes(symbol); + }; + } + + for (const name in SM) { + if (SM.hasOwnProperty(name)) { + const stock = SM[name]; + if (stock instanceof Stock && match(stock.symbol)) { + sub(stock); + } + } + } + } + + function doSetStockPrice(): void { + if (!isNaN(stockPrice)) { + processStocks((stock: Stock) => { + stock.price = stockPrice; + }); + } + } + + function viewStockCaps(): void { + const stocks: JSX.Element[] = []; + processStocks((stock: Stock) => { + stocks.push( + + {stock.symbol} + + + + , + ); + }); + dialogBoxCreate( + + + + + + + {stocks} + +
StockPrice cap
, + ); + } + return ( + + }> +

Stock Market

+
+ + + + + + + + + + + + + + + + +
+ Symbol: + + +
+ Price: + + + +
+ Caps: + + +
+
+
+ ); +} diff --git a/src/DevMenu/ui/TimeSkip.tsx b/src/DevMenu/ui/TimeSkip.tsx new file mode 100644 index 000000000..a8babbd84 --- /dev/null +++ b/src/DevMenu/ui/TimeSkip.tsx @@ -0,0 +1,46 @@ +import React from "react"; + +import Accordion from "@material-ui/core/Accordion"; +import AccordionSummary from "@material-ui/core/AccordionSummary"; +import AccordionDetails from "@material-ui/core/AccordionDetails"; +import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; + +import { Button } from "../../ui/React/Button"; +import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; +import { IPlayer } from "../../PersonObjects/IPlayer"; +import ButtonGroup from "@material-ui/core/ButtonGroup"; +import { saveObject } from "../../SaveObject"; +import { IEngine } from "../../IEngine"; + +// Update as additional BitNodes get implemented +const validSFN = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; +const bigNumber = 1e27; + +interface IProps { + player: IPlayer; + engine: IEngine; +} + +export function TimeSkip(props: IProps): React.ReactElement { + function timeskip(time: number) { + return () => { + props.player.lastUpdate -= time; + props.engine._lastUpdate -= time; + saveObject.saveGame(props.engine.indexedDb); + setTimeout(() => location.reload(), 1000); + }; + } + + return ( + + }> +

Sleeves

+
+ + + + + +
+ ); +} diff --git a/src/Diagnostic/FileDiagnosticPopup.tsx b/src/Diagnostic/FileDiagnosticPopup.tsx index 42e76bc8f..c414e963e 100644 --- a/src/Diagnostic/FileDiagnosticPopup.tsx +++ b/src/Diagnostic/FileDiagnosticPopup.tsx @@ -1,6 +1,6 @@ import React from "react"; import { AllServers } from "../Server/AllServers"; -import { BBAccordion } from "../ui/React/Accordion"; +import { BBAccordion } from "../ui/React/BBAccordion"; import { numeralWrapper } from "../ui/numeralFormat"; interface IServerProps { diff --git a/src/Gang/ui/GangMemberAccordion.tsx b/src/Gang/ui/GangMemberAccordion.tsx index 33fea6cb6..4c415fe81 100644 --- a/src/Gang/ui/GangMemberAccordion.tsx +++ b/src/Gang/ui/GangMemberAccordion.tsx @@ -4,7 +4,7 @@ import React from "react"; import { Gang } from "../Gang"; import { GangMember } from "../GangMember"; -import { BBAccordion } from "../../ui/React/Accordion"; +import { BBAccordion } from "../../ui/React/BBAccordion"; import { GangMemberAccordionContent } from "./GangMemberAccordionContent"; interface IProps { diff --git a/src/StockMarket/ui/StockTicker.tsx b/src/StockMarket/ui/StockTicker.tsx index 58d4d7cc4..f5617756b 100644 --- a/src/StockMarket/ui/StockTicker.tsx +++ b/src/StockMarket/ui/StockTicker.tsx @@ -18,7 +18,7 @@ import { PositionTypes } from "../data/PositionTypes"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { SourceFileFlags } from "../../SourceFile/SourceFileFlags"; import { numeralWrapper } from "../../ui/numeralFormat"; -import { BBAccordion } from "../../ui/React/Accordion"; +import { BBAccordion } from "../../ui/React/BBAccordion"; import { Money } from "../../ui/React/Money"; import { createPopup } from "../../ui/React/createPopup"; diff --git a/src/ui/ActiveScripts/ServerAccordion.tsx b/src/ui/ActiveScripts/ServerAccordion.tsx index dbf0bfb5d..5bb090b25 100644 --- a/src/ui/ActiveScripts/ServerAccordion.tsx +++ b/src/ui/ActiveScripts/ServerAccordion.tsx @@ -4,7 +4,7 @@ */ import * as React from "react"; -import { BBAccordion } from "../React/Accordion"; +import { BBAccordion } from "../React/BBAccordion"; import { ServerAccordionContent } from "./ServerAccordionContent"; import { BaseServer } from "../../Server/BaseServer"; diff --git a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx index 8689adbc2..3b4f2f5e2 100644 --- a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx +++ b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx @@ -6,7 +6,7 @@ import * as React from "react"; import { numeralWrapper } from "../numeralFormat"; -import { BBAccordion } from "../React/Accordion"; +import { BBAccordion } from "../React/BBAccordion"; import { AccordionButton } from "../React/AccordionButton"; import { killWorkerScript } from "../../Netscript/killWorkerScript"; diff --git a/src/ui/React/AugmentationAccordion.tsx b/src/ui/React/AugmentationAccordion.tsx index 5968b9bd9..b657a9e1a 100644 --- a/src/ui/React/AugmentationAccordion.tsx +++ b/src/ui/React/AugmentationAccordion.tsx @@ -6,7 +6,7 @@ */ import * as React from "react"; -import { BBAccordion } from "./Accordion"; +import { BBAccordion } from "./BBAccordion"; import { Augmentation } from "../../Augmentation/Augmentation"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; diff --git a/src/ui/React/Accordion.tsx b/src/ui/React/BBAccordion.tsx similarity index 100% rename from src/ui/React/Accordion.tsx rename to src/ui/React/BBAccordion.tsx diff --git a/src/ui/React/SourceFileAccordion.tsx b/src/ui/React/SourceFileAccordion.tsx index e8a460c91..72e9541b4 100644 --- a/src/ui/React/SourceFileAccordion.tsx +++ b/src/ui/React/SourceFileAccordion.tsx @@ -6,7 +6,7 @@ */ import * as React from "react"; -import { BBAccordion } from "./Accordion"; +import { BBAccordion } from "./BBAccordion"; import { SourceFile } from "../../SourceFile/SourceFile"; diff --git a/src/ui/React/TextField.tsx b/src/ui/React/TextField.tsx index b5f757765..4f25c6eb5 100644 --- a/src/ui/React/TextField.tsx +++ b/src/ui/React/TextField.tsx @@ -7,48 +7,11 @@ import React from "react"; import { TextField as MuiTF, TextFieldProps, makeStyles } from "@material-ui/core"; import { colors } from "./Theme"; -const useStyles = makeStyles({ - // Tries to emulate StdButton in buttons.scss - root: { - backgroundColor: colors.well, - color: "white", - borderRadius: 0, - "& .MuiInputBase-input": { - color: colors.primarylight, // Text color - }, - "& .MuiInputBase-input::placeholder::before": { - color: colors.primarydark, - userSelect: "none", - }, - "& .MuiInput-underline:before": { - borderBottomColor: colors.primarydark, - }, - "& .MuiInput-underline:hover:before": { - borderBottomColor: colors.primary, - }, - "& .MuiInput-underline:after": { - borderBottomColor: colors.primarylight, - }, - "& .MuiInputLabel-root::before": { - color: colors.primary, - }, - "& .MuiInputLabel-root": { - // The little label on the top-right - color: colors.primary, // unfocused - userSelect: "none", - "&.Mui-focused": { - color: colors.primarylight, // focused - }, - }, - }, -}); - export const TextField: React.FC = (props: TextFieldProps) => { return ( diff --git a/src/ui/React/Theme.tsx b/src/ui/React/Theme.tsx index c6dbca327..e1449280d 100644 --- a/src/ui/React/Theme.tsx +++ b/src/ui/React/Theme.tsx @@ -27,6 +27,64 @@ export const theme = createMuiTheme({ root: { backgroundColor: colors.well, }, + input: { + color: colors.primary, + "&::placeholder": { + userSelect: "none", + color: colors.primarydark, + }, + }, + }, + MuiInput: { + root: { + backgroundColor: colors.well, + borderBottomColor: "#fff", + }, + underline: { + "&:hover:before": { + borderBottomColor: colors.primarydark, + }, + "&:before": { + borderBottomColor: colors.primary, + }, + "&:after": { + borderBottomColor: colors.primarylight, + }, + }, + }, + MuiInputLabel: { + root: { + color: colors.primarydark, // why is this switched? + userSelect: "none", + "&:before": { + color: colors.primarylight, + }, + }, + }, + MuiSelect: { + icon: { + color: colors.primary, + }, + }, + MuiMenu: { + list: { + backgroundColor: colors.well, + }, + }, + MuiMenuItem: { + root: { + color: colors.primary, + }, + }, + MuiAccordionSummary: { + root: { + backgroundColor: "#111", + }, + }, + MuiAccordionDetails: { + root: { + backgroundColor: "#000", + }, }, }, });