mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 06:32:26 +01:00
converting more blade to react/ts
This commit is contained in:
parent
0e9d7450c9
commit
988ca37764
@ -53,10 +53,22 @@ import { removeElement } from "../utils/uiHelpers/removeElement";
|
|||||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||||
|
|
||||||
import { SkillElem } from "./Bladeburner/ui/SkillElem";
|
import { SkillElem } from "./Bladeburner/ui/SkillElem";
|
||||||
|
import { SkillList } from "./Bladeburner/ui/SkillList";
|
||||||
import { BlackOpElem } from "./Bladeburner/ui/BlackOpElem";
|
import { BlackOpElem } from "./Bladeburner/ui/BlackOpElem";
|
||||||
|
import { BlackOpList } from "./Bladeburner/ui/BlackOpList";
|
||||||
import { OperationElem } from "./Bladeburner/ui/OperationElem";
|
import { OperationElem } from "./Bladeburner/ui/OperationElem";
|
||||||
|
import { OperationList } from "./Bladeburner/ui/OperationList";
|
||||||
import { ContractElem } from "./Bladeburner/ui/ContractElem";
|
import { ContractElem } from "./Bladeburner/ui/ContractElem";
|
||||||
|
import { ContractList } from "./Bladeburner/ui/ContractList";
|
||||||
import { GeneralActionElem } from "./Bladeburner/ui/GeneralActionElem";
|
import { GeneralActionElem } from "./Bladeburner/ui/GeneralActionElem";
|
||||||
|
import { GeneralActionList } from "./Bladeburner/ui/GeneralActionList";
|
||||||
|
import { GeneralActionPage } from "./Bladeburner/ui/GeneralActionPage";
|
||||||
|
import { ContractPage } from "./Bladeburner/ui/ContractPage";
|
||||||
|
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 { StatsTable } from "./ui/React/StatsTable";
|
import { StatsTable } from "./ui/React/StatsTable";
|
||||||
import { CopyableText } from "./ui/React/CopyableText";
|
import { CopyableText } from "./ui/React/CopyableText";
|
||||||
import { Money } from "./ui/React/Money";
|
import { Money } from "./ui/React/Money";
|
||||||
@ -1554,19 +1566,24 @@ Bladeburner.prototype.createActionAndSkillsContent = function() {
|
|||||||
|
|
||||||
switch(currTab) {
|
switch(currTab) {
|
||||||
case "general":
|
case "general":
|
||||||
this.createGeneralActionsContent();
|
ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc);
|
||||||
|
ReactDOM.render(<GeneralActionPage bladeburner={this} />, DomElems.actionsAndSkillsDesc);
|
||||||
break;
|
break;
|
||||||
case "contracts":
|
case "contracts":
|
||||||
this.createContractsContent();
|
ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc);
|
||||||
|
ReactDOM.render(<ContractPage bladeburner={this} />, DomElems.actionsAndSkillsDesc);
|
||||||
break;
|
break;
|
||||||
case "operations":
|
case "operations":
|
||||||
this.createOperationsContent();
|
ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc);
|
||||||
|
ReactDOM.render(<OperationPage bladeburner={this} />, DomElems.actionsAndSkillsDesc);
|
||||||
break;
|
break;
|
||||||
case "blackops":
|
case "blackops":
|
||||||
this.createBlackOpsContent();
|
ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc);
|
||||||
|
ReactDOM.render(<BlackOpPage bladeburner={this} />, DomElems.actionsAndSkillsDesc);
|
||||||
break;
|
break;
|
||||||
case "skills":
|
case "skills":
|
||||||
this.createSkillsContent();
|
ReactDOM.unmountComponentAtNode(DomElems.actionsAndSkillsDesc);
|
||||||
|
ReactDOM.render(<SkillPage bladeburner={this} />, DomElems.actionsAndSkillsDesc);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent");
|
throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent");
|
||||||
@ -1577,351 +1594,18 @@ Bladeburner.prototype.createActionAndSkillsContent = function() {
|
|||||||
DomElems.actionAndSkillsDiv.appendChild(DomElems.actionsAndSkillsList);
|
DomElems.actionAndSkillsDiv.appendChild(DomElems.actionsAndSkillsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bladeburner.prototype.createGeneralActionsContent = function() {
|
|
||||||
if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) {
|
|
||||||
throw new Error("Bladeburner.createGeneralActionsContent called with either " +
|
|
||||||
"DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");
|
|
||||||
}
|
|
||||||
|
|
||||||
DomElems.actionsAndSkillsDesc.innerText =
|
|
||||||
"These are generic actions that will assist you in your Bladeburner " +
|
|
||||||
"duties. They will not affect your Bladeburner rank in any way."
|
|
||||||
|
|
||||||
for (var actionName in GeneralActions) {
|
|
||||||
if (GeneralActions.hasOwnProperty(actionName)) {
|
|
||||||
DomElems.generalActions[actionName] = createElement("div", {
|
|
||||||
class:"bladeburner-action", name:actionName,
|
|
||||||
});
|
|
||||||
DomElems.actionsAndSkillsList.appendChild(DomElems.generalActions[actionName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.createContractsContent = function() {
|
|
||||||
if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) {
|
|
||||||
throw new Error("Bladeburner.createContractsContent called with either " +
|
|
||||||
"DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");
|
|
||||||
}
|
|
||||||
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML =
|
|
||||||
"Complete contracts in order to increase your Bladeburner rank and earn money. " +
|
|
||||||
"Failing a contract will cause you to lose HP, which can lead to hospitalization.<br><br>" +
|
|
||||||
"You can unlock higher-level contracts by successfully completing them. " +
|
|
||||||
"Higher-level contracts are more difficult, but grant more rank, experience, and money.";
|
|
||||||
|
|
||||||
for (var contractName in this.contracts) {
|
|
||||||
if (this.contracts.hasOwnProperty(contractName)) {
|
|
||||||
DomElems.contracts[contractName] = createElement("div", {
|
|
||||||
class:"bladeburner-action", name:contractName,
|
|
||||||
});
|
|
||||||
DomElems.actionsAndSkillsList.appendChild(DomElems.contracts[contractName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.createOperationsContent = function() {
|
|
||||||
if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) {
|
|
||||||
throw new Error("Bladeburner.createOperationsContent called with either " +
|
|
||||||
"DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");
|
|
||||||
}
|
|
||||||
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML =
|
|
||||||
"Carry out operations for the Bladeburner division. " +
|
|
||||||
"Failing an operation will reduce your Bladeburner rank. It will also " +
|
|
||||||
"cause you to lose HP, which can lead to hospitalization. In general, " +
|
|
||||||
"operations are harder and more punishing than contracts, " +
|
|
||||||
"but are also more rewarding.<br><br>" +
|
|
||||||
"Operations can affect the chaos level and Synthoid population of your " +
|
|
||||||
"current city. The exact effects vary between different Operations.<br><br>" +
|
|
||||||
"For operations, you can use a team. You must first recruit team members. " +
|
|
||||||
"Having a larger team will improves your chances of success.<br><br>" +
|
|
||||||
"You can unlock higher-level operations by successfully completing them. " +
|
|
||||||
"Higher-level operations are more difficult, but grant more rank and experience.";
|
|
||||||
|
|
||||||
for (var operationName in this.operations) {
|
|
||||||
if (this.operations.hasOwnProperty(operationName)) {
|
|
||||||
DomElems.operations[operationName] = createElement("div", {
|
|
||||||
class:"bladeburner-action", name:operationName,
|
|
||||||
});
|
|
||||||
DomElems.actionsAndSkillsList.appendChild(DomElems.operations[operationName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.createBlackOpsContent = function() {
|
|
||||||
|
|
||||||
if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) {
|
|
||||||
throw new Error("Bladeburner.createBlackOpsContent called with either " +
|
|
||||||
"DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML =
|
|
||||||
"Black Operations (Black Ops) are special, one-time covert operations. " +
|
|
||||||
"Each Black Op must be unlocked successively by completing " +
|
|
||||||
"the one before it.<br><br>" +
|
|
||||||
"<b>Your ultimate goal to climb through the ranks of Bladeburners is to complete " +
|
|
||||||
"all of the Black Ops.</b><br><br>" +
|
|
||||||
"Like normal operations, you may use a team for Black Ops. Failing " +
|
|
||||||
"a black op will incur heavy HP and rank losses.";
|
|
||||||
|
|
||||||
// Put Black Operations in sequence of required rank
|
|
||||||
var blackops = [];
|
|
||||||
for (var blackopName in BlackOperations) {
|
|
||||||
if (BlackOperations.hasOwnProperty(blackopName)) {
|
|
||||||
blackops.push(BlackOperations[blackopName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
blackops.sort(function(a, b) {
|
|
||||||
return (a.reqdRank - b.reqdRank);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var i = blackops.length-1; i >= 0 ; --i) {
|
|
||||||
if (this.blackops[[blackops[i].name]] == null && i !== 0 && this.blackops[[blackops[i-1].name]] == null) {continue;} // If this one nor the next are completed then this isn't unlocked yet.
|
|
||||||
DomElems.blackops[blackops[i].name] = createElement("div", {
|
|
||||||
class:"bladeburner-action", name:blackops[i].name,
|
|
||||||
});
|
|
||||||
DomElems.actionsAndSkillsList.appendChild(DomElems.blackops[blackops[i].name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.createSkillsContent = function() {
|
|
||||||
if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) {
|
|
||||||
throw new Error("Bladeburner.createSkillsContent called with either " +
|
|
||||||
"DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display Current multipliers
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML =
|
|
||||||
"You will gain one skill point every " + BladeburnerConstants.RanksPerSkillPoint + " ranks.<br><br>" +
|
|
||||||
"Note that when upgrading a skill, the benefit for that skill is additive. " +
|
|
||||||
"However, the effects of different skills with each other is multiplicative.<br><br>"
|
|
||||||
var multKeys = Object.keys(this.skillMultipliers);
|
|
||||||
for (var i = 0; i < multKeys.length; ++i) {
|
|
||||||
var mult = this.skillMultipliers[multKeys[i]];
|
|
||||||
if (mult && mult !== 1) {
|
|
||||||
mult = formatNumber(mult, 3);
|
|
||||||
switch(multKeys[i]) {
|
|
||||||
case "successChanceAll":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Total Success Chance: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "successChanceStealth":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Stealth Success Chance: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "successChanceKill":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Retirement Success Chance: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "successChanceContract":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Contract Success Chance: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "successChanceOperation":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Operation Success Chance: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "successChanceEstimate":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Synthoid Data Estimate: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "actionTime":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Action Time: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effHack":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Hacking Skill: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effStr":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Strength: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effDef":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Defense: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effDex":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Dexterity: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effAgi":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Agility: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effCha":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Charisma: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "effInt":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Intelligence: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "stamina":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Stamina: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "money":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Contract Money: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
case "expGain":
|
|
||||||
DomElems.actionsAndSkillsDesc.innerHTML += "Exp Gain: x" + mult + "<br>";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skill Points
|
|
||||||
DomElems.skillPointsDisplay = createElement("p", {
|
|
||||||
innerHTML:"<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>",
|
|
||||||
});
|
|
||||||
DomElems.actionAndSkillsDiv.appendChild(DomElems.skillPointsDisplay);
|
|
||||||
|
|
||||||
// UI Element for each skill
|
|
||||||
for (var skillName in Skills) {
|
|
||||||
if (Skills.hasOwnProperty(skillName)) {
|
|
||||||
DomElems.skills[skillName] = createElement("div", {
|
|
||||||
class:"bladeburner-action", name:skillName,
|
|
||||||
});
|
|
||||||
DomElems.actionsAndSkillsList.appendChild(DomElems.skills[skillName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateContent = function() {
|
Bladeburner.prototype.updateContent = function() {
|
||||||
this.updateOverviewContent();
|
this.updateOverviewContent();
|
||||||
this.updateActionAndSkillsContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bladeburner.prototype.updateOverviewContent = function() {
|
Bladeburner.prototype.updateOverviewContent = function() {
|
||||||
if (!routing.isOn(Page.Bladeburner)) {return;}
|
if (!routing.isOn(Page.Bladeburner)) return;
|
||||||
DomElems.overviewRank.childNodes[0].nodeValue = "Rank: " + formatNumber(this.rank, 2);
|
ReactDOM.render(<Stats bladeburner={this} player={Player} />, DomElems.overviewDiv);
|
||||||
DomElems.overviewStamina.innerText = "Stamina: " + formatNumber(this.stamina, 3) + " / " + formatNumber(this.maxStamina, 3);
|
|
||||||
ReactDOM.render(<>
|
|
||||||
Stamina Penalty: {formatNumber((1-this.calculateStaminaPenalty())*100, 1)}%<br /><br />
|
|
||||||
Team Size: {formatNumber(this.teamSize, 0)}<br />
|
|
||||||
Team Members Lost: {formatNumber(this.teamLost, 0)}<br /><br />
|
|
||||||
Num Times Hospitalized: {this.numHosp}<br />
|
|
||||||
Money Lost From Hospitalizations: {Money(this.moneyLost)}<br /><br />
|
|
||||||
Current City: {this.city}<br />
|
|
||||||
</>, DomElems.overviewGen1);
|
|
||||||
|
|
||||||
DomElems.overviewEstPop.childNodes[0].nodeValue = "Est. Synthoid Population: " + numeralWrapper.formatPopulation(this.getCurrentCity().popEst);
|
|
||||||
DomElems.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0);
|
|
||||||
DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
|
|
||||||
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0);
|
|
||||||
DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + convertTimeMsToTimeElapsedString(this.storedCycles/BladeburnerConstants.CyclesPerSecond*1000);
|
|
||||||
ReactDOM.render(StatsTable([
|
|
||||||
["Aug. Success Chance mult: ", formatNumber(Player.bladeburner_success_chance_mult*100, 1) + "%"],
|
|
||||||
["Aug. Max Stamina mult: ", formatNumber(Player.bladeburner_max_stamina_mult*100, 1) + "%"],
|
|
||||||
["Aug. Stamina Gain mult: ", formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%"],
|
|
||||||
["Aug. Field Analysis mult: ", formatNumber(Player.bladeburner_analysis_mult*100, 1) + "%"],
|
|
||||||
]), DomElems.overviewAugMults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bladeburner.prototype.updateActionAndSkillsContent = function() {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
if (DomElems.currentTab == null) {DomElems.currentTab = "general";}
|
///////////////////////////////HYDRO END OF UI//////////////////////////////////
|
||||||
switch(DomElems.currentTab.toLowerCase()) {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
case "general":
|
|
||||||
var actionElems = Object.keys(DomElems.generalActions);
|
|
||||||
for (var i = 0; i < actionElems.length; ++i) {
|
|
||||||
var actionElem = DomElems.generalActions[actionElems[i]];
|
|
||||||
var name = actionElem.name;
|
|
||||||
var actionObj = GeneralActions[name];
|
|
||||||
if (actionObj == null) {
|
|
||||||
throw new Error("Could not find Object " + name + " in Bladeburner.updateActionAndSkillsContent()");
|
|
||||||
}
|
|
||||||
if (this.action.type === ActionTypes[name]) {
|
|
||||||
actionElem.classList.add(ActiveActionCssClass);
|
|
||||||
} else {
|
|
||||||
actionElem.classList.remove(ActiveActionCssClass);
|
|
||||||
}
|
|
||||||
this.updateGeneralActionsUIElement(actionElem, actionObj);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "contracts":
|
|
||||||
var contractElems = Object.keys(DomElems.contracts);
|
|
||||||
for (var i = 0; i < contractElems.length; ++i) {
|
|
||||||
var contractElem = DomElems.contracts[contractElems[i]];
|
|
||||||
var name = contractElem.name;
|
|
||||||
if (this.action.type === ActionTypes["Contract"] && name === this.action.name) {
|
|
||||||
contractElem.classList.add(ActiveActionCssClass);
|
|
||||||
} else {
|
|
||||||
contractElem.classList.remove(ActiveActionCssClass);
|
|
||||||
}
|
|
||||||
var contract = this.contracts[name];
|
|
||||||
if (contract == null) {
|
|
||||||
throw new Error("Could not find Contract " + name + " in Bladeburner.updateActionAndSkillsContent()");
|
|
||||||
}
|
|
||||||
this.updateContractsUIElement(contractElem, contract);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "operations":
|
|
||||||
var operationElems = Object.keys(DomElems.operations);
|
|
||||||
for (var i = 0; i < operationElems.length; ++i) {
|
|
||||||
var operationElem = DomElems.operations[operationElems[i]];
|
|
||||||
var name = operationElem.name;
|
|
||||||
if (this.action.type === ActionTypes["Operation"] && name === this.action.name) {
|
|
||||||
operationElem.classList.add(ActiveActionCssClass);
|
|
||||||
} else {
|
|
||||||
operationElem.classList.remove(ActiveActionCssClass);
|
|
||||||
}
|
|
||||||
var operation = this.operations[name];
|
|
||||||
if (operation == null) {
|
|
||||||
throw new Error("Could not find Operation " + name + " in Bladeburner.updateActionAndSkillsContent()");
|
|
||||||
}
|
|
||||||
this.updateOperationsUIElement(operationElem, operation);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "blackops":
|
|
||||||
var blackopsElems = Object.keys(DomElems.blackops);
|
|
||||||
for (var i = 0; i < blackopsElems.length; ++i) {
|
|
||||||
var blackopElem = DomElems.blackops[blackopsElems[i]];
|
|
||||||
var name = blackopElem.name;
|
|
||||||
if (this.action.type === ActionTypes["BlackOperation"] && name === this.action.name) {
|
|
||||||
blackopElem.classList.add(ActiveActionCssClass);
|
|
||||||
} else {
|
|
||||||
blackopElem.classList.remove(ActiveActionCssClass);
|
|
||||||
}
|
|
||||||
var blackop = BlackOperations[name];
|
|
||||||
if (blackop == null) {
|
|
||||||
throw new Error("Could not find BlackOperation " + name + " in Bladeburner.updateActionAndSkillsContent()");
|
|
||||||
}
|
|
||||||
this.updateBlackOpsUIElement(blackopElem, blackop);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "skills":
|
|
||||||
DomElems.skillPointsDisplay.innerHTML = "<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>";
|
|
||||||
|
|
||||||
var skillElems = Object.keys(DomElems.skills);
|
|
||||||
for (var i = 0; i < skillElems.length; ++i) {
|
|
||||||
var skillElem = DomElems.skills[skillElems[i]];
|
|
||||||
var name = skillElem.name;
|
|
||||||
var skill = Skills[name];
|
|
||||||
if (skill == null) {
|
|
||||||
throw new Error("Could not find Skill " + name + " in Bladeburner.updateActionAndSkillsContent()");
|
|
||||||
}
|
|
||||||
this.updateSkillsUIElement(skillElem, skill);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateGeneralActionsUIElement = function(el, action) {
|
|
||||||
ReactDOM.unmountComponentAtNode(el);
|
|
||||||
ReactDOM.render(<GeneralActionElem bladeburner={this} action={action} />, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
|
||||||
ReactDOM.unmountComponentAtNode(el);
|
|
||||||
ReactDOM.render(<ContractElem bladeburner={this} action={action} />, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|
||||||
ReactDOM.unmountComponentAtNode(el);
|
|
||||||
ReactDOM.render(<OperationElem bladeburner={this} action={action} />, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|
||||||
ReactDOM.unmountComponentAtNode(el);
|
|
||||||
ReactDOM.render(<BlackOpElem bladeburner={this} action={action} />, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
|
||||||
ReactDOM.unmountComponentAtNode(el);
|
|
||||||
ReactDOM.render(<SkillElem bladeburner={this} skill={skill} />, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bladeburner Console Window
|
// Bladeburner Console Window
|
||||||
Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) {
|
Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) {
|
||||||
@ -2382,7 +2066,6 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
|||||||
this.action.type = ActionTypes[name];
|
this.action.type = ActionTypes[name];
|
||||||
this.action.name = name;
|
this.action.name = name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
this.updateActionAndSkillsContent();
|
|
||||||
} else {
|
} else {
|
||||||
this.postToConsole("Invalid action name specified: " + args[2]);
|
this.postToConsole("Invalid action name specified: " + args[2]);
|
||||||
}
|
}
|
||||||
@ -2393,7 +2076,6 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
|||||||
this.action.type = ActionTypes.Contract;
|
this.action.type = ActionTypes.Contract;
|
||||||
this.action.name = name;
|
this.action.name = name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
this.updateActionAndSkillsContent();
|
|
||||||
} else {
|
} else {
|
||||||
this.postToConsole("Invalid contract name specified: " + args[2]);
|
this.postToConsole("Invalid contract name specified: " + args[2]);
|
||||||
}
|
}
|
||||||
@ -2406,7 +2088,6 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
|||||||
this.action.type = ActionTypes.Operation;
|
this.action.type = ActionTypes.Operation;
|
||||||
this.action.name = name;
|
this.action.name = name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
this.updateActionAndSkillsContent();
|
|
||||||
} else {
|
} else {
|
||||||
this.postToConsole("Invalid Operation name specified: " + args[2]);
|
this.postToConsole("Invalid Operation name specified: " + args[2]);
|
||||||
}
|
}
|
||||||
@ -2419,7 +2100,6 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
|||||||
this.action.type = ActionTypes.BlackOperation;
|
this.action.type = ActionTypes.BlackOperation;
|
||||||
this.action.name = name;
|
this.action.name = name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
this.updateActionAndSkillsContent();
|
|
||||||
} else {
|
} else {
|
||||||
this.postToConsole("Invalid BlackOp name specified: " + args[2]);
|
this.postToConsole("Invalid BlackOp name specified: " + args[2]);
|
||||||
}
|
}
|
||||||
|
42
src/Bladeburner/ui/BlackOpList.tsx
Normal file
42
src/Bladeburner/ui/BlackOpList.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
convertTimeMsToTimeElapsedString,
|
||||||
|
} from "../../../utils/StringHelperFunctions";
|
||||||
|
import { ActionTypes } from "../data/ActionTypes";
|
||||||
|
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||||
|
import { stealthIcon, killIcon } from "../data/Icons";
|
||||||
|
import { BlackOperations } from "../BlackOperations";
|
||||||
|
import { BlackOperation } from "../BlackOperation";
|
||||||
|
import { BlackOpElem } from "./BlackOpElem";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BlackOpList(props: IProps): React.ReactElement {
|
||||||
|
let blackops: BlackOperation[] = [];
|
||||||
|
for (const blackopName in BlackOperations) {
|
||||||
|
if (BlackOperations.hasOwnProperty(blackopName)) {
|
||||||
|
blackops.push(BlackOperations[blackopName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blackops.sort(function(a, b) {
|
||||||
|
return (a.reqdRank - b.reqdRank);
|
||||||
|
});
|
||||||
|
|
||||||
|
blackops = blackops.filter((blackop: BlackOperation, i: number) =>
|
||||||
|
!(props.bladeburner.blackops[blackops[i].name] == null &&
|
||||||
|
i !== 0 &&
|
||||||
|
props.bladeburner.blackops[blackops[i-1].name] == null));
|
||||||
|
|
||||||
|
blackops = blackops.reverse();
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
{blackops.map((blackop: BlackOperation) =>
|
||||||
|
<li key={blackop.name} className="bladeburner-action">
|
||||||
|
<BlackOpElem bladeburner={props.bladeburner} action={blackop} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</>);
|
||||||
|
}
|
25
src/Bladeburner/ui/BlackOpPage.tsx
Normal file
25
src/Bladeburner/ui/BlackOpPage.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { BlackOpList } from "./BlackOpList";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BlackOpPage(props: IProps): React.ReactElement {
|
||||||
|
return (<>
|
||||||
|
<p style={{display: 'block', margin: '4px', padding: '4px'}}>
|
||||||
|
Black Operations (Black Ops) are special, one-time covert operations.
|
||||||
|
Each Black Op must be unlocked successively by completing
|
||||||
|
the one before it.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<b>Your ultimate goal to climb through the ranks of Bladeburners is to complete
|
||||||
|
all of the Black Ops.</b>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Like normal operations, you may use a team for Black Ops. Failing
|
||||||
|
a black op will incur heavy HP and rank losses.
|
||||||
|
</p>
|
||||||
|
<BlackOpList bladeburner={props.bladeburner} />
|
||||||
|
</>);
|
||||||
|
}
|
30
src/Bladeburner/ui/ContractList.tsx
Normal file
30
src/Bladeburner/ui/ContractList.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
convertTimeMsToTimeElapsedString,
|
||||||
|
} from "../../../utils/StringHelperFunctions";
|
||||||
|
import { ContractElem } from "./ContractElem";
|
||||||
|
import { Contract } from "../Contract";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (<>
|
||||||
|
{names.map((name: string) =>
|
||||||
|
<li key={name} className="bladeburner-action">
|
||||||
|
<ContractElem bladeburner={props.bladeburner} action={contracts[name]} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</>);
|
||||||
|
}
|
20
src/Bladeburner/ui/ContractPage.tsx
Normal file
20
src/Bladeburner/ui/ContractPage.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { ContractList } from "./ContractList";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ContractPage(props: IProps): React.ReactElement {
|
||||||
|
return (<>
|
||||||
|
<p style={{display: 'block', margin: '4px', padding: '4px'}}>
|
||||||
|
Complete contracts in order to increase your Bladeburner rank and earn money.
|
||||||
|
Failing a contract will cause you to lose HP, which can lead to hospitalization.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
You can unlock higher-level contracts by successfully completing them.
|
||||||
|
Higher-level contracts are more difficult, but grant more rank, experience, and money.
|
||||||
|
</p>
|
||||||
|
<ContractList bladeburner={props.bladeburner} />
|
||||||
|
</>);
|
||||||
|
}
|
35
src/Bladeburner/ui/GeneralActionList.tsx
Normal file
35
src/Bladeburner/ui/GeneralActionList.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
convertTimeMsToTimeElapsedString,
|
||||||
|
} from "../../../utils/StringHelperFunctions";
|
||||||
|
import { GeneralActionElem } from "./GeneralActionElem";
|
||||||
|
import { Action } from "../Action";
|
||||||
|
import { GeneralActions } from "../GeneralActions";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
actions.push(GeneralActions[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (<>
|
||||||
|
{actions.map((action: Action) =>
|
||||||
|
<li key={action.name} className="bladeburner-action">
|
||||||
|
<GeneralActionElem bladeburner={props.bladeburner} action={action} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</>);
|
||||||
|
}
|
16
src/Bladeburner/ui/GeneralActionPage.tsx
Normal file
16
src/Bladeburner/ui/GeneralActionPage.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { GeneralActionList } from "./GeneralActionList";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GeneralActionPage(props: IProps): React.ReactElement {
|
||||||
|
return (<>
|
||||||
|
<p style={{display: 'block', margin: '4px', padding: '4px'}}>
|
||||||
|
These are generic actions that will assist you in your Bladeburner
|
||||||
|
duties. They will not affect your Bladeburner rank in any way.
|
||||||
|
</p>
|
||||||
|
<GeneralActionList bladeburner={props.bladeburner} />
|
||||||
|
</>);
|
||||||
|
}
|
30
src/Bladeburner/ui/OperationList.tsx
Normal file
30
src/Bladeburner/ui/OperationList.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
convertTimeMsToTimeElapsedString,
|
||||||
|
} from "../../../utils/StringHelperFunctions";
|
||||||
|
import { OperationElem } from "./OperationElem";
|
||||||
|
import { Operation } from "../Operation";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (<>
|
||||||
|
{names.map((name: string) =>
|
||||||
|
<li key={name} className="bladeburner-action">
|
||||||
|
<OperationElem bladeburner={props.bladeburner} action={operations[name]} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</>);
|
||||||
|
}
|
31
src/Bladeburner/ui/OperationPage.tsx
Normal file
31
src/Bladeburner/ui/OperationPage.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { OperationList } from "./OperationList";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OperationPage(props: IProps): React.ReactElement {
|
||||||
|
return (<>
|
||||||
|
<p style={{display: 'block', margin: '4px', padding: '4px'}}>
|
||||||
|
Carry out operations for the Bladeburner division.
|
||||||
|
Failing an operation will reduce your Bladeburner rank. It will also
|
||||||
|
cause you to lose HP, which can lead to hospitalization. In general,
|
||||||
|
operations are harder and more punishing than contracts,
|
||||||
|
but are also more rewarding.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Operations can affect the chaos level and Synthoid population of your
|
||||||
|
current city. The exact effects vary between different Operations.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
For operations, you can use a team. You must first recruit team members.
|
||||||
|
Having a larger team will improves your chances of success.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
You can unlock higher-level operations by successfully completing them.
|
||||||
|
Higher-level operations are more difficult, but grant more rank and experience.
|
||||||
|
</p>
|
||||||
|
<OperationList bladeburner={props.bladeburner} />
|
||||||
|
</>);
|
||||||
|
}
|
17
src/Bladeburner/ui/SkillList.tsx
Normal file
17
src/Bladeburner/ui/SkillList.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { SkillElem } from "./SkillElem";
|
||||||
|
import { Skills } from "../Skills";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SkillList(props: IProps): React.ReactElement {
|
||||||
|
return (<>
|
||||||
|
{Object.keys(Skills).map((skill: string) =>
|
||||||
|
<li key={skill} className="bladeburner-action">
|
||||||
|
<SkillElem bladeburner={props.bladeburner} skill={Skills[skill]} />
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</>);
|
||||||
|
}
|
66
src/Bladeburner/ui/SkillPage.tsx
Normal file
66
src/Bladeburner/ui/SkillPage.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { SkillList } from "./SkillList";
|
||||||
|
import { BladeburnerConstants } from "../data/Constants";
|
||||||
|
import { formatNumber } from "../../../utils/StringHelperFunctions";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function SkillPage(props: IProps): React.ReactElement {
|
||||||
|
const mults = props.bladeburner.skillMultipliers;
|
||||||
|
|
||||||
|
function valid(mult: any) {
|
||||||
|
return mult && mult !== 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<strong>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</strong>
|
||||||
|
<p>
|
||||||
|
You will gain one skill point every {BladeburnerConstants.RanksPerSkillPoint} ranks.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Note that when upgrading a skill, the benefit for that skill is additive.
|
||||||
|
However, the effects of different skills with each other is multiplicative.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
{valid(mults["successChanceAll"]) && <>Total Success Chance: x{formatNumber(mults["successChanceAll"], 3)}<br /></>}
|
||||||
|
{valid(mults["successChanceStealth"]) && <>Stealth Success Chance: x{formatNumber(mults["successChanceStealth"], 3)}<br /></>}
|
||||||
|
{valid(mults["successChanceKill"]) && <>Retirement Success Chance: x{formatNumber(mults["successChanceKill"], 3)}<br /></>}
|
||||||
|
{valid(mults["successChanceContract"]) && <>Contract Success Chance: x{formatNumber(mults["successChanceContract"], 3)}<br /></>}
|
||||||
|
{valid(mults["successChanceOperation"]) && <>Operation Success Chance: x{formatNumber(mults["successChanceOperation"], 3)}<br /></>}
|
||||||
|
{valid(mults["successChanceEstimate"]) && <>Synthoid Data Estimate: x{formatNumber(mults["successChanceEstimate"], 3)}<br /></>}
|
||||||
|
{valid(mults["actionTime"]) && <>Action Time: x{formatNumber(mults["actionTime"], 3)}<br /></>}
|
||||||
|
{valid(mults["effHack"]) && <>Hacking Skill: x{formatNumber(mults["effHack"], 3)}<br /></>}
|
||||||
|
{valid(mults["effStr"]) && <>Strength: x{formatNumber(mults["effStr"], 3)}<br /></>}
|
||||||
|
{valid(mults["effDef"]) && <>Defense: x{formatNumber(mults["effDef"], 3)}<br /></>}
|
||||||
|
{valid(mults["effDex"]) && <>Dexterity: x{formatNumber(mults["effDex"], 3)}<br /></>}
|
||||||
|
{valid(mults["effAgi"]) && <>Agility: x{formatNumber(mults["effAgi"], 3)}<br /></>}
|
||||||
|
{valid(mults["effCha"]) && <>Charisma: x{formatNumber(mults["effCha"], 3)}<br /></>}
|
||||||
|
{valid(mults["effInt"]) && <>Intelligence: x{formatNumber(mults["effInt"], 3)}<br /></>}
|
||||||
|
{valid(mults["stamina"]) && <>Stamina: x{formatNumber(mults["stamina"], 3)}<br /></>}
|
||||||
|
{valid(mults["money"]) && <>Contract Money: x{formatNumber(mults["money"], 3)}<br /></>}
|
||||||
|
{valid(mults["expGain"]) && <>Exp Gain: x{formatNumber(mults["expGain"], 3)}<br /></>}
|
||||||
|
<br />
|
||||||
|
<SkillList bladeburner={props.bladeburner} />
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var multKeys = Object.keys(this.skillMultipliers);
|
||||||
|
for (var i = 0; i < multKeys.length; ++i) {
|
||||||
|
var mult = this.skillMultipliers[multKeys[i]];
|
||||||
|
if (mult && mult !== 1) {
|
||||||
|
mult = formatNumber(mult, 3);
|
||||||
|
switch(multKeys[i]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
78
src/Bladeburner/ui/Stats.tsx
Normal file
78
src/Bladeburner/ui/Stats.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
convertTimeMsToTimeElapsedString,
|
||||||
|
} from "../../../utils/StringHelperFunctions";
|
||||||
|
import { BladeburnerConstants } from "../data/Constants";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { StatsTable } from "../../ui/React/StatsTable";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
bladeburner: any;
|
||||||
|
player: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Stats(props: IProps): React.ReactElement {
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const id = setInterval(() => setRerender(old => !old), 1000);
|
||||||
|
return () => clearInterval(id);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function openStaminaHelp(): void {
|
||||||
|
dialogBoxCreate("Performing actions will use up your stamina.<br><br>" +
|
||||||
|
"Your max stamina is determined primarily by your agility stat.<br><br>" +
|
||||||
|
"Your stamina gain rate is determined by both your agility and your " +
|
||||||
|
"max stamina. Higher max stamina leads to a higher gain rate.<br><br>" +
|
||||||
|
"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).<br><br>" +
|
||||||
|
"Your max stamina and stamina gain rate can also be increased by " +
|
||||||
|
"training, or through skills and Augmentation upgrades.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPopulationHelp(): void {
|
||||||
|
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.<br><br>" +
|
||||||
|
"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.<br><br>" +
|
||||||
|
"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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<p>
|
||||||
|
Rank: {formatNumber(props.bladeburner.rank, 2)}<br />
|
||||||
|
Stamina: {formatNumber(props.bladeburner.stamina, 3)} / {formatNumber(props.bladeburner.maxStamina, 3)}
|
||||||
|
<div className="help-tip" onClick={openStaminaHelp}>?</div><br />
|
||||||
|
Est. Synthoid Population: {numeralWrapper.formatPopulation(props.bladeburner.getCurrentCity().popEst)}
|
||||||
|
<div className="help-tip" onClick={openPopulationHelp}>?</div><br />
|
||||||
|
Est. Synthoid Communities: {formatNumber(props.bladeburner.getCurrentCity().comms, 0)}<br />
|
||||||
|
City Chaos: {formatNumber(props.bladeburner.getCurrentCity().chaos)}<br />
|
||||||
|
Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}<br />
|
||||||
|
Bonus time: {convertTimeMsToTimeElapsedString(props.bladeburner.storedCycles/BladeburnerConstants.CyclesPerSecond*1000)}<br />
|
||||||
|
Stamina Penalty: {formatNumber((1-props.bladeburner.calculateStaminaPenalty())*100, 1)}%<br /><br />
|
||||||
|
Team Size: {formatNumber(props.bladeburner.teamSize, 0)}<br />
|
||||||
|
Team Members Lost: {formatNumber(props.bladeburner.teamLost, 0)}<br /><br />
|
||||||
|
Num Times Hospitalized: {props.bladeburner.numHosp}<br />
|
||||||
|
Money Lost From Hospitalizations: {Money(props.bladeburner.moneyLost)}<br /><br />
|
||||||
|
Current City: {props.bladeburner.city}<br />
|
||||||
|
{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) + "%"],
|
||||||
|
])}
|
||||||
|
</p>);
|
||||||
|
}
|
@ -63,7 +63,7 @@ export function CharacterInfo(p: IPlayer): React.ReactElement {
|
|||||||
if (src.casino) { parts.push([`Casino:`, Money(src.casino)]) }
|
if (src.casino) { parts.push([`Casino:`, Money(src.casino)]) }
|
||||||
if (src.sleeves) { parts.push([`Sleeves:`, Money(src.sleeves)]) }
|
if (src.sleeves) { parts.push([`Sleeves:`, Money(src.sleeves)]) }
|
||||||
|
|
||||||
return StatsTable(parts, "");
|
return StatsTable(parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMoneyModal(): void {
|
function openMoneyModal(): void {
|
||||||
@ -254,7 +254,7 @@ export function CharacterInfo(p: IPlayer): React.ReactElement {
|
|||||||
<span>{`Servers owned: ${p.purchasedServers.length} / ${getPurchaseServerLimit()}`}</span><br />
|
<span>{`Servers owned: ${p.purchasedServers.length} / ${getPurchaseServerLimit()}`}</span><br />
|
||||||
<Hacknet />
|
<Hacknet />
|
||||||
<span>{`Augmentations installed: ${p.augmentations.length}`}</span><br /><br />
|
<span>{`Augmentations installed: ${p.augmentations.length}`}</span><br /><br />
|
||||||
{StatsTable(timeRows, null)}
|
{StatsTable(timeRows)}
|
||||||
<br />
|
<br />
|
||||||
<CurrentBitNode />
|
<CurrentBitNode />
|
||||||
</pre>
|
</pre>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export function StatsTable(rows: any[][], title: string | null): React.ReactElement {
|
export function StatsTable(rows: any[][], title?: string): React.ReactElement {
|
||||||
let titleElem = <></>
|
let titleElem = <></>
|
||||||
if (title) {
|
if (title) {
|
||||||
titleElem = <><h2><u>{title}</u></h2><br /></>;
|
titleElem = <><h2><u>{title}</u></h2><br /></>;
|
||||||
|
@ -76,7 +76,7 @@ function containsAllStrings(arr: string[]): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Formats a number with commas and a specific number of decimal digits
|
// Formats a number with commas and a specific number of decimal digits
|
||||||
function formatNumber(num: number, numFractionDigits: number): string {
|
function formatNumber(num: number, numFractionDigits: number = 0): string {
|
||||||
return num.toLocaleString(undefined, {
|
return num.toLocaleString(undefined, {
|
||||||
maximumFractionDigits: numFractionDigits,
|
maximumFractionDigits: numFractionDigits,
|
||||||
minimumFractionDigits: numFractionDigits,
|
minimumFractionDigits: numFractionDigits,
|
||||||
|
Loading…
Reference in New Issue
Block a user