From 33f0efd49c6c355c0e6a0c05617b862088fdd1ae Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Tue, 10 Aug 2021 11:25:21 -0400 Subject: [PATCH] converting more blade to react --- src/Bladeburner.jsx | 355 ++--------------------- src/Bladeburner/ui/AllPages.tsx | 46 +++ src/Bladeburner/ui/BlackOpElem.tsx | 5 +- src/Bladeburner/ui/Console.tsx | 43 +++ src/Bladeburner/ui/ContractElem.tsx | 1 - src/Bladeburner/ui/ContractList.tsx | 7 - src/Bladeburner/ui/GeneralActionList.tsx | 7 - src/Bladeburner/ui/OperationElem.tsx | 1 - src/Bladeburner/ui/OperationList.tsx | 7 - src/Bladeburner/ui/SkillElem.tsx | 5 +- src/Bladeburner/ui/SkillList.tsx | 3 +- src/Bladeburner/ui/SkillPage.tsx | 45 +-- src/Bladeburner/ui/Stats.tsx | 109 ++++++- 13 files changed, 234 insertions(+), 400 deletions(-) create mode 100644 src/Bladeburner/ui/AllPages.tsx create mode 100644 src/Bladeburner/ui/Console.tsx diff --git a/src/Bladeburner.jsx b/src/Bladeburner.jsx index 41f4ddafc..4693f99b2 100644 --- a/src/Bladeburner.jsx +++ b/src/Bladeburner.jsx @@ -68,6 +68,8 @@ import { OperationPage } from "./Bladeburner/ui/OperationPage"; import { BlackOpPage } from "./Bladeburner/ui/BlackOpPage"; import { SkillPage } from "./Bladeburner/ui/SkillPage"; import { Stats } from "./Bladeburner/ui/Stats"; +import { AllPages } from "./Bladeburner/ui/AllPages"; +import { Console } from "./Bladeburner/ui/Console"; import { StatsTable } from "./ui/React/StatsTable"; import { CopyableText } from "./ui/React/CopyableText"; @@ -443,9 +445,6 @@ Bladeburner.prototype.process = function() { } } - if (routing.isOn(Page.Bladeburner)) { - this.updateContent(); - } } } @@ -809,10 +808,6 @@ Bladeburner.prototype.completeAction = function() { return hackWorldDaemon(Player.bitNodeN); } - if (routing.isOn(Page.Bladeburner)) { - this.createActionAndSkillsContent(); - } - if (this.logging.blackops) { this.log(action.name + " successful! Gained " + formatNumber(rankGain, 1) + " rank"); } @@ -1228,7 +1223,6 @@ Bladeburner.prototype.initializeDomElementRefs = function() { overviewDiv: null, // Overview of stats that stays fixed on left actionAndSkillsDiv: null, // Panel for different sections (contracts, ops, skills) - currentTab: null, // Contracts, Operations, Black Ops, Skills consoleDiv: null, consoleTable: null, @@ -1236,29 +1230,6 @@ Bladeburner.prototype.initializeDomElementRefs = function() { consoleInputCell: null, // td consoleInputHeader: null, // "> " consoleInput: null, // Actual input element - - // Overview Content - overviewRank: null, - overviewStamina: null, - overviewStaminaHelpTip: null, - overviewGen1: null, // Stamina Penalty, Team, Hospitalized stats, current city - overviewEstPop: null, - overviewEstPopHelpTip: null, - overviewEstComms: null, - overviewChaos: null, - overviewSkillPoints: null, - overviewBonusTime: null, - overviewAugMults: null, - - // Actions and Skills Content - actionsAndSkillsDesc: null, - actionsAndSkillsList: null, // ul element of all UI elements in this panel - generalActions: {}, - contracts: {}, - operations: {}, - blackops: {}, - skills: {}, - skillPointsDisplay: null, }; } @@ -1282,10 +1253,8 @@ Bladeburner.prototype.createContent = function() { border:"1px solid white", margin:"6px", padding:"6px", }); - DomElems.currentTab = "general"; - - this.createOverviewContent(); - this.createActionAndSkillsContent(); + ReactDOM.render(, DomElems.overviewDiv); + ReactDOM.render(, DomElems.actionAndSkillsDiv); // Console DomElems.consoleDiv = createElement("div", { @@ -1297,32 +1266,13 @@ Bladeburner.prototype.createContent = function() { return false; }, }); - DomElems.consoleTable = createElement("table", {class:"bladeburner-console-table"}); - DomElems.consoleInputRow = createElement("tr", {class:"bladeburner-console-input-row", id:"bladeburner-console-input-row"}); - DomElems.consoleInputCell = createElement("td", {class:"bladeburner-console-input-cell"}); - DomElems.consoleInputHeader = createElement("pre", {innerText:"> "}); - DomElems.consoleInput = createElement("input", { - type:"text", class:"bladeburner-console-input", tabIndex:1, - onfocus:() => {DomElems.consoleInput.value = DomElems.consoleInput.value}, - }); - - DomElems.consoleInputCell.appendChild(DomElems.consoleInputHeader); - DomElems.consoleInputCell.appendChild(DomElems.consoleInput); - DomElems.consoleInputRow.appendChild(DomElems.consoleInputCell); - DomElems.consoleTable.appendChild(DomElems.consoleInputRow); - DomElems.consoleDiv.appendChild(DomElems.consoleTable); + ReactDOM.render(, DomElems.consoleDiv); DomElems.overviewConsoleParentDiv.appendChild(DomElems.overviewDiv); DomElems.overviewConsoleParentDiv.appendChild(DomElems.consoleDiv); DomElems.bladeburnerDiv.appendChild(DomElems.overviewConsoleParentDiv); DomElems.bladeburnerDiv.appendChild(DomElems.actionAndSkillsDiv); - - // legend - const legend = createElement("div") - legend.innerHTML = `${stealthIcon}= This action requires stealth, ${killIcon} = This action involves retirement` - DomElems.bladeburnerDiv.appendChild(legend); - document.getElementById("entire-game-container").appendChild(DomElems.bladeburnerDiv); if (this.consoleLogs.length === 0) { @@ -1333,8 +1283,6 @@ Bladeburner.prototype.createContent = function() { this.postToConsole(this.consoleLogs[i], false); } } - - DomElems.consoleInput.focus(); } Bladeburner.prototype.clearContent = function() { @@ -1346,290 +1294,35 @@ Bladeburner.prototype.clearContent = function() { this.initializeDomElementRefs(); } -Bladeburner.prototype.createOverviewContent = function() { - if (DomElems.overviewDiv == null) { - throw new Error("Bladeburner.createOverviewContent() called with DomElems.overviewDiv = null"); - } - - DomElems.overviewRank = createElement("p", { - innerText:"Rank: ", - display:"inline-block", - tooltip:"Your rank within the Bladeburner division", - }); - - DomElems.overviewStamina = createElement("p", { - display:"inline-block", - }); - - DomElems.overviewStaminaHelpTip = createElement("div", { - class:"help-tip", - innerText:"?", - clickListener: () => { - dialogBoxCreate("Performing actions will use up your stamina.

" + - "Your max stamina is determined primarily by your agility stat.

" + - "Your stamina gain rate is determined by both your agility and your " + - "max stamina. Higher max stamina leads to a higher gain rate.

" + - "Once your " + - "stamina falls below 50% of its max value, it begins to negatively " + - "affect the success rate of your contracts/operations. This penalty " + - "is shown in the overview panel. If the penalty is 15%, then this means " + - "your success rate would be multipled by 85% (100 - 15).

" + - "Your max stamina and stamina gain rate can also be increased by " + - "training, or through skills and Augmentation upgrades."); - }, - }); - - DomElems.overviewGen1 = createElement("p", { - display:"block", - }); - - DomElems.overviewEstPop = createElement("p", { - innerText:"Est. Synthoid Population: ", - display:"inline-block", - tooltip:"This is your Bladeburner division's estimate of how many Synthoids exist " + - "in your current city.", - }); - - DomElems.overviewEstPopHelpTip = createElement("div", { - innerText:"?", class:"help-tip", - clickListener:() => { - dialogBoxCreate("The success rate of your contracts/operations depends on " + - "the population of Synthoids in your current city. " + - "The success rate that is shown to you is only an estimate, " + - "and it is based on your Synthoid population estimate.

" + - "Therefore, it is important that this Synthoid population estimate " + - "is accurate so that you have a better idea of your " + - "success rate for contracts/operations. Certain " + - "actions will increase the accuracy of your population " + - "estimate.

" + - "The Synthoid populations of cities can change due to your " + - "actions or random events. If random events occur, they will " + - "be logged in the Bladeburner Console."); - }, - }); - - DomElems.overviewEstComms = createElement("p", { - innerText:"Est. Synthoid Communities: ", - display:"inline-block", - tooltip:"This is your Bladeburner divison's estimate of how many Synthoid " + - "communities exist in your current city.", - }); - - DomElems.overviewChaos = createElement("p", { - innerText:"City Chaos: ", - display:"inline-block", - tooltip:"The city's chaos level due to tensions and conflicts between humans and Synthoids. " + - "Having too high of a chaos level can make contracts and operations harder.", - }); - - DomElems.overviewBonusTime = createElement("p", { - innerText: "Bonus time: ", - display: "inline-block", - tooltip: "You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser). " + - "Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed.", - }); - DomElems.overviewSkillPoints = createElement("p", {display:"block"}); - - - DomElems.overviewAugMults = createElement("div", {display:"block"}); - - - DomElems.overviewDiv.appendChild(DomElems.overviewRank); - appendLineBreaks(DomElems.overviewDiv, 1); - DomElems.overviewDiv.appendChild(DomElems.overviewStamina); - DomElems.overviewDiv.appendChild(DomElems.overviewStaminaHelpTip); - DomElems.overviewDiv.appendChild(DomElems.overviewGen1); - DomElems.overviewDiv.appendChild(DomElems.overviewEstPop); - DomElems.overviewDiv.appendChild(DomElems.overviewEstPopHelpTip); - appendLineBreaks(DomElems.overviewDiv, 1); - DomElems.overviewDiv.appendChild(DomElems.overviewEstComms); - appendLineBreaks(DomElems.overviewDiv, 1); - DomElems.overviewDiv.appendChild(DomElems.overviewChaos); - appendLineBreaks(DomElems.overviewDiv, 2); - DomElems.overviewDiv.appendChild(DomElems.overviewBonusTime); - DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints); - appendLineBreaks(DomElems.overviewDiv, 1); - DomElems.overviewDiv.appendChild(DomElems.overviewAugMults); - - // Travel to new city button - appendLineBreaks(DomElems.overviewDiv, 1); - DomElems.overviewDiv.appendChild(createElement("a", { - innerHTML:"Travel", class:"a-link-button", display:"inline-block", - clickListener:() => { - var popupId = "bladeburner-travel-popup-cancel-btn"; - var popupArguments = []; - popupArguments.push(createElement("a", { // Cancel Button - innerText:"Cancel", class:"a-link-button", - clickListener:() => { - removeElementById(popupId); return false; - }, - })) - popupArguments.push(createElement("p", { // Info Text - innerText:"Travel to a different city for your Bladeburner " + - "activities. This does not cost any money. The city you are " + - "in for your Bladeburner duties does not affect " + - "your location in the game otherwise", - })); - for (var i = 0; i < BladeburnerConstants.CityNames.length; ++i) { - (function(inst, i) { - popupArguments.push(createElement("div", { - /** - * Reusing this css class...it adds a border and makes it - * so that background color changes when you hover - */ - class:"cmpy-mgmt-find-employee-option", - innerText:BladeburnerConstants.CityNames[i], - clickListener:() => { - inst.city = BladeburnerConstants.CityNames[i]; - removeElementById(popupId); - inst.updateOverviewContent(); - return false; - }, - })); - })(this, i); - } - createPopup(popupId, popupArguments); - }, - })); - - // Faction button - const bladeburnersFactionName = "Bladeburners"; - if (factionExists(bladeburnersFactionName)) { - var bladeburnerFac = Factions[bladeburnersFactionName]; - if (!(bladeburnerFac instanceof Faction)) { - throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button"); - } - DomElems.overviewDiv.appendChild(createElement("a", { - innerText:"Faction", class:"a-link-button", display:"inline-block", - tooltip:"Apply to the Bladeburner Faction, or go to the faction page if you are already a member", - clickListener:() => { - if (bladeburnerFac.isMember) { - Engine.loadFactionContent(); - displayFactionContent(bladeburnersFactionName); - } else { - if (this.rank >= BladeburnerConstants.RankNeededForFaction) { - joinFaction(bladeburnerFac); - dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction"); - removeChildrenFromElement(DomElems.overviewDiv); - this.createOverviewContent(); - } else { - dialogBoxCreate("You need a rank of 25 to join the Bladeburners Faction!") - } - } - return false; - }, - })); - } - - DomElems.overviewDiv.appendChild(createElement("br")); - DomElems.overviewDiv.appendChild(createElement("br")); - - this.updateOverviewContent(); -} - -Bladeburner.prototype.createActionAndSkillsContent = function() { - if (DomElems.currentTab == null) {DomElems.currentTab = "general";} - - removeChildrenFromElement(DomElems.actionAndSkillsDiv); - clearObject(DomElems.generalActions); - clearObject(DomElems.contracts); - clearObject(DomElems.operations); - clearObject(DomElems.blackops); - clearObject(DomElems.skills); - - //Navigation buttons - var currTab = DomElems.currentTab.toLowerCase(); - var buttons = ["General", "Contracts", "Operations", "BlackOps", "Skills"]; - for (var i = 0; i < buttons.length; ++i) { - (function(buttons, i, inst, currTab) { - - DomElems.actionAndSkillsDiv.appendChild(createElement("a", { - innerText:buttons[i], - class:currTab === buttons[i].toLowerCase() ? "bladeburner-nav-button-inactive" : "bladeburner-nav-button", - clickListener:() => { - DomElems.currentTab = buttons[i].toLowerCase(); - inst.createActionAndSkillsContent(); - return false; - }, - })); - }) (buttons, i, this, currTab); - } - - // General info/description for each action - DomElems.actionsAndSkillsDesc = createElement("p", { - display:"block", margin:"4px", padding:"4px", - }); - - // List for actions/skills - removeChildrenFromElement(DomElems.actionsAndSkillsList); - DomElems.actionsAndSkillsList = createElement("ul"); - - switch(currTab) { - case "general": - ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc); - ReactDOM.render(, DomElems.actionsAndSkillsDesc); - break; - case "contracts": - ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc); - ReactDOM.render(, DomElems.actionsAndSkillsDesc); - break; - case "operations": - ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc); - ReactDOM.render(, DomElems.actionsAndSkillsDesc); - break; - case "blackops": - ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc); - ReactDOM.render(, DomElems.actionsAndSkillsDesc); - break; - case "skills": - ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc); - ReactDOM.render(, DomElems.actionsAndSkillsDesc); - break; - default: - throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent"); - } - this.updateContent(); - - DomElems.actionAndSkillsDiv.appendChild(DomElems.actionsAndSkillsDesc); - DomElems.actionAndSkillsDiv.appendChild(DomElems.actionsAndSkillsList); -} - -Bladeburner.prototype.updateContent = function() { - this.updateOverviewContent(); -} - -Bladeburner.prototype.updateOverviewContent = function() { - if (!routing.isOn(Page.Bladeburner)) return; - ReactDOM.render(, DomElems.overviewDiv); -} - +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////HYDRO END OF UI////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Bladeburner Console Window Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) { const MaxConsoleEntries = 100; - if (saveToLogs === true) { + if (saveToLogs) { this.consoleLogs.push(input); if (this.consoleLogs.length > MaxConsoleEntries) { this.consoleLogs.shift(); } } - - if (input == null || DomElems.consoleDiv == null) {return;} - $("#bladeburner-console-input-row").before('' + input + ''); - - if (DomElems.consoleTable.childNodes.length > MaxConsoleEntries) { - DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild); - } - - this.updateConsoleScroll(); } -Bladeburner.prototype.updateConsoleScroll = function() { - DomElems.consoleDiv.scrollTop = DomElems.consoleDiv.scrollHeight; -} Bladeburner.prototype.resetConsoleInput = function() { DomElems.consoleInput.value = ""; @@ -2035,7 +1728,6 @@ Bladeburner.prototype.executeSkillConsoleCommand = function(args) { this.skillPoints -= pointCost; this.upgradeSkill(skill); this.log(skill.name + " upgraded to Level " + this.skills[skillName]); - this.createActionAndSkillsContent(); } else { this.postToConsole("You do not have enough Skill Points to upgrade this. You need " + formatNumber(pointCost, 0)); } @@ -2441,9 +2133,6 @@ Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript this.skillPoints -= cost; this.upgradeSkill(skill); - if (routing.isOn(Page.Bladeburner) && DomElems.currentTab.toLowerCase() === "skills") { - this.createActionAndSkillsContent(); - } workerScript.log("bladeburner.upgradeSkill", `'${skillName}' upgraded to level ${this.skills[skillName]}`); return true; } @@ -2514,10 +2203,6 @@ Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) } else if (this.rank >= BladeburnerConstants.RankNeededForFaction) { joinFaction(bladeburnerFac); workerScript.log("bladeburner.joinBladeburnerFaction", "Joined Bladeburners faction."); - if (routing.isOn(Page.Bladeburner)) { - removeChildrenFromElement(DomElems.overviewDiv); - this.createOverviewContent(); - } return true; } else { workerScript.log("bladeburner.joinBladeburnerFaction", `You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`); diff --git a/src/Bladeburner/ui/AllPages.tsx b/src/Bladeburner/ui/AllPages.tsx new file mode 100644 index 000000000..deadaf103 --- /dev/null +++ b/src/Bladeburner/ui/AllPages.tsx @@ -0,0 +1,46 @@ +import React, { useState, useEffect } from "react"; +import { GeneralActionPage } from "./GeneralActionPage"; +import { ContractPage } from "./ContractPage"; +import { OperationPage } from "./OperationPage"; +import { BlackOpPage } from "./BlackOpPage"; +import { SkillPage } from "./SkillPage"; +import { stealthIcon, killIcon } from "../data/Icons"; + +interface IProps { + bladeburner: any; +} + +export function AllPages(props: IProps): React.ReactElement { + const [page, setPage] = useState('General'); + const setRerender = useState(false)[1]; + + useEffect(() => { + const id = setInterval(() => setRerender(old => !old), 1000); + return () => clearInterval(id); + }, []); + + function Header(props: {name: string}): React.ReactElement { + return (setPage(props.name)} + className={page !== props.name ? + "bladeburner-nav-button" : + "bladeburner-nav-button-inactive"}> + {props.name} + ); + } + return (<> +
+
+
+
+
+
+ {page === 'General' && } + {page === 'Contracts' && } + {page === 'Operations' && } + {page === 'BlackOps' && } + {page === 'Skills' && } +
+ {stealthIcon}= This action requires stealth, {killIcon} = This action involves retirement + ); +} \ No newline at end of file diff --git a/src/Bladeburner/ui/BlackOpElem.tsx b/src/Bladeburner/ui/BlackOpElem.tsx index bcdd65855..3fd3268f9 100644 --- a/src/Bladeburner/ui/BlackOpElem.tsx +++ b/src/Bladeburner/ui/BlackOpElem.tsx @@ -1,4 +1,4 @@ -import * as React from "react"; +import React, { useState } from "react"; import { formatNumber, convertTimeMsToTimeElapsedString, @@ -13,6 +13,7 @@ interface IProps { } export function BlackOpElem(props: IProps): React.ReactElement { + const setRerender = useState(false)[1]; const isCompleted = (props.bladeburner.blackops[props.action.name] != null); if(isCompleted) { return ( @@ -29,7 +30,7 @@ export function BlackOpElem(props: IProps): React.ReactElement { props.bladeburner.action.type = ActionTypes.BlackOperation; props.bladeburner.action.name = props.action.name; props.bladeburner.startAction(props.bladeburner.action); - props.bladeburner.updateActionAndSkillsContent(); + setRerender(old => !old); } function onTeam() { diff --git a/src/Bladeburner/ui/Console.tsx b/src/Bladeburner/ui/Console.tsx new file mode 100644 index 000000000..7c4de7eb8 --- /dev/null +++ b/src/Bladeburner/ui/Console.tsx @@ -0,0 +1,43 @@ +import React, { useState, useRef, useEffect } from "react"; + +interface ILineProps { + content: any; +} + +function Line(props: ILineProps): React.ReactElement { + return ( + {props.content} + ) +} + +interface IProps { + bladeburner: any; +} + +export function Console(props: IProps): React.ReactElement { + const lastRef = useRef(null); + const setRerender = useState(false)[1]; + + useEffect(() => { + if(lastRef.current) + lastRef.current.scrollIntoView({block: "end", inline: "nearest", behavior: "smooth" }); + const id = setInterval(() => setRerender(old => !old), 1000); + return () => clearInterval(id); + }, []); + + return ( + + {/* + TODO: optimize this. + using `i` as a key here isn't great because it'll re-render everything + everytime the console reaches max length. + */} + {props.bladeburner.consoleLogs.map((log: any, i: number) => )} + + + + +
+
{"> "}
+
); +} \ No newline at end of file diff --git a/src/Bladeburner/ui/ContractElem.tsx b/src/Bladeburner/ui/ContractElem.tsx index 9ab48bba1..5ffc7d1e9 100644 --- a/src/Bladeburner/ui/ContractElem.tsx +++ b/src/Bladeburner/ui/ContractElem.tsx @@ -26,7 +26,6 @@ export function ContractElem(props: IProps): React.ReactElement { props.bladeburner.action.type = ActionTypes.Contract; props.bladeburner.action.name = props.action.name; props.bladeburner.startAction(props.bladeburner.action); - props.bladeburner.updateActionAndSkillsContent(); setRerender(old => !old); } diff --git a/src/Bladeburner/ui/ContractList.tsx b/src/Bladeburner/ui/ContractList.tsx index 142eb5ce0..dcea7ea5e 100644 --- a/src/Bladeburner/ui/ContractList.tsx +++ b/src/Bladeburner/ui/ContractList.tsx @@ -11,13 +11,6 @@ interface IProps { } export function ContractList(props: IProps): React.ReactElement { - const setRerender = useState(false)[1]; - - useEffect(() => { - const id = setInterval(() => setRerender(old => !old), 1000); - return () => clearInterval(id); - }, []); - const names = Object.keys(props.bladeburner.contracts); const contracts = props.bladeburner.contracts; return (<> diff --git a/src/Bladeburner/ui/GeneralActionList.tsx b/src/Bladeburner/ui/GeneralActionList.tsx index 15f329df9..e459899d4 100644 --- a/src/Bladeburner/ui/GeneralActionList.tsx +++ b/src/Bladeburner/ui/GeneralActionList.tsx @@ -12,13 +12,6 @@ interface IProps { } export function GeneralActionList(props: IProps): React.ReactElement { - const setRerender = useState(false)[1]; - - useEffect(() => { - const id = setInterval(() => setRerender(old => !old), 1000); - return () => clearInterval(id); - }, []); - const actions: Action[] = []; for (const name in GeneralActions) { if (GeneralActions.hasOwnProperty(name)) { diff --git a/src/Bladeburner/ui/OperationElem.tsx b/src/Bladeburner/ui/OperationElem.tsx index 1dabeb650..133778c8d 100644 --- a/src/Bladeburner/ui/OperationElem.tsx +++ b/src/Bladeburner/ui/OperationElem.tsx @@ -26,7 +26,6 @@ export function OperationElem(props: IProps): React.ReactElement { props.bladeburner.action.type = ActionTypes.Operation; props.bladeburner.action.name = props.action.name; props.bladeburner.startAction(props.bladeburner.action); - props.bladeburner.updateActionAndSkillsContent(); setRerender(old => !old); } diff --git a/src/Bladeburner/ui/OperationList.tsx b/src/Bladeburner/ui/OperationList.tsx index bff9cc3b7..d78d46351 100644 --- a/src/Bladeburner/ui/OperationList.tsx +++ b/src/Bladeburner/ui/OperationList.tsx @@ -11,13 +11,6 @@ interface IProps { } export function OperationList(props: IProps): React.ReactElement { - const setRerender = useState(false)[1]; - - useEffect(() => { - const id = setInterval(() => setRerender(old => !old), 1000); - return () => clearInterval(id); - }, []); - const names = Object.keys(props.bladeburner.operations); const operations = props.bladeburner.operations; return (<> diff --git a/src/Bladeburner/ui/SkillElem.tsx b/src/Bladeburner/ui/SkillElem.tsx index af7ebfbf1..44312e413 100644 --- a/src/Bladeburner/ui/SkillElem.tsx +++ b/src/Bladeburner/ui/SkillElem.tsx @@ -1,10 +1,11 @@ -import * as React from "react"; +import React, { useState } from "react"; import { CopyableText } from "../../ui/React/CopyableText"; import { formatNumber } from "../../../utils/StringHelperFunctions"; interface IProps { skill: any; bladeburner: any; + onUpgrade: () => void; } export function SkillElem(props: IProps): React.ReactElement { @@ -22,7 +23,7 @@ export function SkillElem(props: IProps): React.ReactElement { if (props.bladeburner.skillPoints < pointCost) return; props.bladeburner.skillPoints -= pointCost; props.bladeburner.upgradeSkill(props.skill); - props.bladeburner.createActionAndSkillsContent(); + props.onUpgrade(); } return (<> diff --git a/src/Bladeburner/ui/SkillList.tsx b/src/Bladeburner/ui/SkillList.tsx index 014b6f992..a7fbe2182 100644 --- a/src/Bladeburner/ui/SkillList.tsx +++ b/src/Bladeburner/ui/SkillList.tsx @@ -4,13 +4,14 @@ import { Skills } from "../Skills"; interface IProps { bladeburner: any; + onUpgrade: () => void; } export function SkillList(props: IProps): React.ReactElement { return (<> {Object.keys(Skills).map((skill: string) =>
  • - +
  • )} ); diff --git a/src/Bladeburner/ui/SkillPage.tsx b/src/Bladeburner/ui/SkillPage.tsx index 8a6e7e9bc..c465e95cc 100644 --- a/src/Bladeburner/ui/SkillPage.tsx +++ b/src/Bladeburner/ui/SkillPage.tsx @@ -1,4 +1,4 @@ -import * as React from "react"; +import React, { useState } from "react"; import { SkillList } from "./SkillList"; import { BladeburnerConstants } from "../data/Constants"; import { formatNumber } from "../../../utils/StringHelperFunctions"; @@ -9,6 +9,7 @@ interface IProps { export function SkillPage(props: IProps): React.ReactElement { + const setRerender = useState(false)[1]; const mults = props.bladeburner.skillMultipliers; function valid(mult: any) { @@ -16,7 +17,9 @@ export function SkillPage(props: IProps): React.ReactElement { } return (<> - Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)} +

    + Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)} +

    You will gain one skill point every {BladeburnerConstants.RanksPerSkillPoint} ranks.
    @@ -24,27 +27,27 @@ export function SkillPage(props: IProps): React.ReactElement { Note that when upgrading a skill, the benefit for that skill is additive. However, the effects of different skills with each other is multiplicative.
    -

    - {valid(mults["successChanceAll"]) && <>Total Success Chance: x{formatNumber(mults["successChanceAll"], 3)}
    } - {valid(mults["successChanceStealth"]) && <>Stealth Success Chance: x{formatNumber(mults["successChanceStealth"], 3)}
    } - {valid(mults["successChanceKill"]) && <>Retirement Success Chance: x{formatNumber(mults["successChanceKill"], 3)}
    } - {valid(mults["successChanceContract"]) && <>Contract Success Chance: x{formatNumber(mults["successChanceContract"], 3)}
    } - {valid(mults["successChanceOperation"]) && <>Operation Success Chance: x{formatNumber(mults["successChanceOperation"], 3)}
    } - {valid(mults["successChanceEstimate"]) && <>Synthoid Data Estimate: x{formatNumber(mults["successChanceEstimate"], 3)}
    } - {valid(mults["actionTime"]) && <>Action Time: x{formatNumber(mults["actionTime"], 3)}
    } - {valid(mults["effHack"]) && <>Hacking Skill: x{formatNumber(mults["effHack"], 3)}
    } - {valid(mults["effStr"]) && <>Strength: x{formatNumber(mults["effStr"], 3)}
    } - {valid(mults["effDef"]) && <>Defense: x{formatNumber(mults["effDef"], 3)}
    } - {valid(mults["effDex"]) && <>Dexterity: x{formatNumber(mults["effDex"], 3)}
    } - {valid(mults["effAgi"]) && <>Agility: x{formatNumber(mults["effAgi"], 3)}
    } - {valid(mults["effCha"]) && <>Charisma: x{formatNumber(mults["effCha"], 3)}
    } - {valid(mults["effInt"]) && <>Intelligence: x{formatNumber(mults["effInt"], 3)}
    } - {valid(mults["stamina"]) && <>Stamina: x{formatNumber(mults["stamina"], 3)}
    } - {valid(mults["money"]) && <>Contract Money: x{formatNumber(mults["money"], 3)}
    } - {valid(mults["expGain"]) && <>Exp Gain: x{formatNumber(mults["expGain"], 3)}
    }
    - + {valid(mults["successChanceAll"]) &&

    Total Success Chance: x{formatNumber(mults["successChanceAll"], 3)}

    } + {valid(mults["successChanceStealth"]) &&

    Stealth Success Chance: x{formatNumber(mults["successChanceStealth"], 3)}

    } + {valid(mults["successChanceKill"]) &&

    Retirement Success Chance: x{formatNumber(mults["successChanceKill"], 3)}

    } + {valid(mults["successChanceContract"]) &&

    Contract Success Chance: x{formatNumber(mults["successChanceContract"], 3)}

    } + {valid(mults["successChanceOperation"]) &&

    Operation Success Chance: x{formatNumber(mults["successChanceOperation"], 3)}

    } + {valid(mults["successChanceEstimate"]) &&

    Synthoid Data Estimate: x{formatNumber(mults["successChanceEstimate"], 3)}

    } + {valid(mults["actionTime"]) &&

    Action Time: x{formatNumber(mults["actionTime"], 3)}

    } + {valid(mults["effHack"]) &&

    Hacking Skill: x{formatNumber(mults["effHack"], 3)}

    } + {valid(mults["effStr"]) &&

    Strength: x{formatNumber(mults["effStr"], 3)}

    } + {valid(mults["effDef"]) &&

    Defense: x{formatNumber(mults["effDef"], 3)}

    } + {valid(mults["effDex"]) &&

    Dexterity: x{formatNumber(mults["effDex"], 3)}

    } + {valid(mults["effAgi"]) &&

    Agility: x{formatNumber(mults["effAgi"], 3)}

    } + {valid(mults["effCha"]) &&

    Charisma: x{formatNumber(mults["effCha"], 3)}

    } + {valid(mults["effInt"]) &&

    Intelligence: x{formatNumber(mults["effInt"], 3)}

    } + {valid(mults["stamina"]) &&

    Stamina: x{formatNumber(mults["stamina"], 3)}

    } + {valid(mults["money"]) &&

    Contract Money: x{formatNumber(mults["money"], 3)}

    } + {valid(mults["expGain"]) &&

    Exp Gain: x{formatNumber(mults["expGain"], 3)}

    } +
    + setRerender(old => !old)} /> ); } diff --git a/src/Bladeburner/ui/Stats.tsx b/src/Bladeburner/ui/Stats.tsx index 9e072f189..e766d8c11 100644 --- a/src/Bladeburner/ui/Stats.tsx +++ b/src/Bladeburner/ui/Stats.tsx @@ -52,27 +52,104 @@ export function Stats(props: IProps): React.ReactElement { "be logged in the Bladeburner Console."); } - return (

    - Rank: {formatNumber(props.bladeburner.rank, 2)}
    - Stamina: {formatNumber(props.bladeburner.stamina, 3)} / {formatNumber(props.bladeburner.maxStamina, 3)} + function openTravel() { + // var popupId = "bladeburner-travel-popup-cancel-btn"; + // var popupArguments = []; + // popupArguments.push(createElement("a", { // Cancel Button + // innerText:"Cancel", class:"a-link-button", + // clickListener:() => { + // removeElementById(popupId); return false; + // }, + // })) + // popupArguments.push(createElement("p", { // Info Text + // innerText:"Travel to a different city for your Bladeburner " + + // "activities. This does not cost any money. The city you are " + + // "in for your Bladeburner duties does not affect " + + // "your location in the game otherwise", + // })); + // for (var i = 0; i < BladeburnerConstants.CityNames.length; ++i) { + // (function(inst, i) { + // popupArguments.push(createElement("div", { + // // Reusing this css class...it adds a border and makes it + // // so that background color changes when you hover + // class:"cmpy-mgmt-find-employee-option", + // innerText:BladeburnerConstants.CityNames[i], + // clickListener:() => { + // inst.city = BladeburnerConstants.CityNames[i]; + // removeElementById(popupId); + // inst.updateOverviewContent(); + // return false; + // }, + // })); + // })(this, i); + // } + // createPopup(popupId, popupArguments); + } + + function openFaction() { + // if (bladeburnerFac.isMember) { + // Engine.loadFactionContent(); + // displayFactionContent(bladeburnersFactionName); + // } else { + // if (this.rank >= BladeburnerConstants.RankNeededForFaction) { + // joinFaction(bladeburnerFac); + // dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction"); + // removeChildrenFromElement(DomElems.overviewDiv); + // this.createOverviewContent(); + // } else { + // dialogBoxCreate("You need a rank of 25 to join the Bladeburners Faction!") + // } + // } + } + + return (<> +

    + Rank: {formatNumber(props.bladeburner.rank, 2)} + Your rank within the Bladeburner division. +


    +

    Stamina: {formatNumber(props.bladeburner.stamina, 3)} / {formatNumber(props.bladeburner.maxStamina, 3)}

    ?

    - Est. Synthoid Population: {numeralWrapper.formatPopulation(props.bladeburner.getCurrentCity().popEst)} +

    Stamina Penalty: {formatNumber((1-props.bladeburner.calculateStaminaPenalty())*100, 1)}%


    +

    Team Size: {formatNumber(props.bladeburner.teamSize, 0)}

    +

    Team Members Lost: {formatNumber(props.bladeburner.teamLost, 0)}


    +

    Num Times Hospitalized: {props.bladeburner.numHosp}

    +

    Money Lost From Hospitalizations: {Money(props.bladeburner.moneyLost)}


    +

    Current City: {props.bladeburner.city}

    +

    + Est. Synthoid Population: {numeralWrapper.formatPopulation(props.bladeburner.getCurrentCity().popEst)} + This is your Bladeburner division's estimate of how many Synthoids exist in your current city. +

    ?

    - Est. Synthoid Communities: {formatNumber(props.bladeburner.getCurrentCity().comms, 0)}
    - City Chaos: {formatNumber(props.bladeburner.getCurrentCity().chaos)}
    - Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}
    - Bonus time: {convertTimeMsToTimeElapsedString(props.bladeburner.storedCycles/BladeburnerConstants.CyclesPerSecond*1000)}
    - Stamina Penalty: {formatNumber((1-props.bladeburner.calculateStaminaPenalty())*100, 1)}%

    - Team Size: {formatNumber(props.bladeburner.teamSize, 0)}
    - Team Members Lost: {formatNumber(props.bladeburner.teamLost, 0)}

    - Num Times Hospitalized: {props.bladeburner.numHosp}
    - Money Lost From Hospitalizations: {Money(props.bladeburner.moneyLost)}

    - Current City: {props.bladeburner.city}
    +

    + Est. Synthoid Communities: {formatNumber(props.bladeburner.getCurrentCity().comms, 0)} + This is your Bladeburner divison's estimate of how many Synthoid communities exist in your current city. +


    +

    + City Chaos: {formatNumber(props.bladeburner.getCurrentCity().chaos)} + The city's chaos level due to tensions and conflicts between humans and Synthoids. Having too high of a chaos level can make contracts and operations harder. +


    +
    +

    + Bonus time: {convertTimeMsToTimeElapsedString(props.bladeburner.storedCycles/BladeburnerConstants.CyclesPerSecond*1000)}
    + + You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser). + Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed. + +

    +

    Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}


    {StatsTable([ ["Aug. Success Chance mult: ", formatNumber(props.player.bladeburner_success_chance_mult*100, 1) + "%"], ["Aug. Max Stamina mult: ", formatNumber(props.player.bladeburner_max_stamina_mult*100, 1) + "%"], ["Aug. Stamina Gain mult: ", formatNumber(props.player.bladeburner_stamina_gain_mult*100, 1) + "%"], ["Aug. Field Analysis mult: ", formatNumber(props.player.bladeburner_analysis_mult*100, 1) + "%"], ])} -

    ); -} \ No newline at end of file +
    + Travel + + Apply to the Bladeburner Faction, or go to the faction page if you are already a member + Faction + +
    +
    + ); +}