mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-30 03:23:48 +01:00
Convert sleeves to react, fix shock recovery bug
This commit is contained in:
parent
b0fcdb8363
commit
d5c9306395
@ -3,14 +3,15 @@
|
|||||||
*/
|
*/
|
||||||
@import "theme";
|
@import "theme";
|
||||||
|
|
||||||
.sleeve-container {
|
#sleeves-container {
|
||||||
|
position: fixed;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sleeve-elem {
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
width: 75%;
|
display: block;
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: $defaultFontSize * 0.875;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sleeves-page-info {
|
.sleeves-page-info {
|
||||||
|
@ -252,6 +252,7 @@ export class Sleeve extends Person {
|
|||||||
|
|
||||||
// Experience is first multiplied by shock. Then 'synchronization'
|
// Experience is first multiplied by shock. Then 'synchronization'
|
||||||
// is accounted for
|
// is accounted for
|
||||||
|
|
||||||
const multFac = (this.shock / 100) * (this.sync / 100) * numCycles;
|
const multFac = (this.shock / 100) * (this.sync / 100) * numCycles;
|
||||||
const pHackExp = exp.hack * multFac;
|
const pHackExp = exp.hack * multFac;
|
||||||
const pStrExp = exp.str * multFac;
|
const pStrExp = exp.str * multFac;
|
||||||
@ -491,7 +492,7 @@ export class Sleeve extends Person {
|
|||||||
this.currentTaskTime += time;
|
this.currentTaskTime += time;
|
||||||
|
|
||||||
// Shock gradually goes towards 100
|
// Shock gradually goes towards 100
|
||||||
this.shock = Math.min(100, this.shock + 0.0001 * this.storedCycles);
|
this.shock = Math.min(100, this.shock + 0.0001 * cyclesUsed);
|
||||||
|
|
||||||
let retValue: ITaskTracker = createTaskTracker();
|
let retValue: ITaskTracker = createTaskTracker();
|
||||||
switch (this.currentTask) {
|
switch (this.currentTask) {
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/**
|
|
||||||
* Module for handling the UI for purchasing Sleeve Augmentations
|
|
||||||
* This UI is a popup, not a full page
|
|
||||||
*/
|
|
||||||
import React from "react";
|
|
||||||
import { Sleeve } from "./Sleeve";
|
|
||||||
import { findSleevePurchasableAugs } from "./SleeveHelpers";
|
|
||||||
|
|
||||||
import { IPlayer } from "../IPlayer";
|
|
||||||
|
|
||||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
|
||||||
|
|
||||||
import { Money } from "../../ui/React/Money";
|
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|
||||||
|
|
||||||
import { createElement } from "../../../utils/uiHelpers/createElement";
|
|
||||||
import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
|
||||||
import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton";
|
|
||||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
|
||||||
|
|
||||||
import { renderToStaticMarkup } from "react-dom/server";
|
|
||||||
|
|
||||||
export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer): void {
|
|
||||||
// Array of all owned Augmentations. Names only
|
|
||||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {
|
|
||||||
return e.name;
|
|
||||||
});
|
|
||||||
|
|
||||||
// You can only purchase Augmentations that are actually available from
|
|
||||||
// your factions. I.e. you must be in a faction that has the Augmentation
|
|
||||||
// and you must also have enough rep in that faction in order to purchase it.
|
|
||||||
const availableAugs = findSleevePurchasableAugs(sleeve, p);
|
|
||||||
|
|
||||||
// Create popup
|
|
||||||
const popupId = "purchase-sleeve-augs-popup";
|
|
||||||
|
|
||||||
// Close popup button
|
|
||||||
const closeBtn = createPopupCloseButton(popupId, { innerText: "Cancel" });
|
|
||||||
|
|
||||||
// General info about owned Augmentations
|
|
||||||
const ownedAugsInfo = createElement("p", {
|
|
||||||
display: "block",
|
|
||||||
innerHTML: "Owned Augmentations:",
|
|
||||||
});
|
|
||||||
|
|
||||||
const popupElems: HTMLElement[] = [closeBtn, ownedAugsInfo];
|
|
||||||
|
|
||||||
// Show owned augmentations
|
|
||||||
// First we'll make a div with a reduced width, so the tooltips don't go off
|
|
||||||
// the edge of the popup
|
|
||||||
const ownedAugsDiv = createElement("div", { width: "70%" });
|
|
||||||
for (const ownedAug of ownedAugNames) {
|
|
||||||
const aug: Augmentation | null = Augmentations[ownedAug];
|
|
||||||
if (aug == null) {
|
|
||||||
console.warn(`Invalid Augmentation: ${ownedAug}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tooltip = aug.info;
|
|
||||||
if (typeof tooltip !== "string") {
|
|
||||||
tooltip = renderToStaticMarkup(tooltip);
|
|
||||||
}
|
|
||||||
tooltip += "<br /><br />";
|
|
||||||
tooltip += renderToStaticMarkup(aug.stats);
|
|
||||||
|
|
||||||
ownedAugsDiv.appendChild(
|
|
||||||
createElement("div", {
|
|
||||||
class: "gang-owned-upgrade", // Reusing a class from the Gang UI
|
|
||||||
innerText: ownedAug,
|
|
||||||
tooltip: tooltip,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
popupElems.push(ownedAugsDiv);
|
|
||||||
|
|
||||||
// General info about buying Augmentations
|
|
||||||
const info = createElement("p", {
|
|
||||||
innerHTML: [
|
|
||||||
`You can purchase Augmentations for your Duplicate Sleeves. These Augmentations`,
|
|
||||||
`have the same effect as they would for you. You can only purchase Augmentations`,
|
|
||||||
`that you have unlocked through Factions.<br><br>`,
|
|
||||||
`When purchasing an Augmentation for a Duplicate Sleeve, they are immediately`,
|
|
||||||
`installed. This means that the Duplicate Sleeve will immediately lose all of`,
|
|
||||||
`its stat experience.`,
|
|
||||||
].join(" "),
|
|
||||||
});
|
|
||||||
|
|
||||||
popupElems.push(info);
|
|
||||||
|
|
||||||
for (const aug of availableAugs) {
|
|
||||||
const div = createElement("div", {
|
|
||||||
class: "cmpy-mgmt-upgrade-div", // We'll reuse this CSS class
|
|
||||||
});
|
|
||||||
|
|
||||||
let info = aug.info;
|
|
||||||
if (typeof info !== "string") {
|
|
||||||
info = renderToStaticMarkup(info);
|
|
||||||
}
|
|
||||||
info += "<br /><br />";
|
|
||||||
info += renderToStaticMarkup(aug.stats);
|
|
||||||
|
|
||||||
div.appendChild(
|
|
||||||
createElement("p", {
|
|
||||||
fontSize: "12px",
|
|
||||||
innerHTML: [
|
|
||||||
`<h2>${aug.name}</h2><br>`,
|
|
||||||
`Cost: ${renderToStaticMarkup(<Money money={aug.startingCost} player={p} />)}<br><br>`,
|
|
||||||
`${info}`,
|
|
||||||
].join(" "),
|
|
||||||
padding: "2px",
|
|
||||||
clickListener: () => {
|
|
||||||
if (sleeve.tryBuyAugmentation(p, aug)) {
|
|
||||||
dialogBoxCreate(`Installed ${aug.name} on Duplicate Sleeve!`, false);
|
|
||||||
removeElementById(popupId);
|
|
||||||
createSleevePurchaseAugsPopup(sleeve, p);
|
|
||||||
} else {
|
|
||||||
dialogBoxCreate(`You cannot afford ${aug.name}`, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
popupElems.push(div);
|
|
||||||
}
|
|
||||||
|
|
||||||
createPopup(popupId, popupElems);
|
|
||||||
}
|
|
@ -1,733 +0,0 @@
|
|||||||
/**
|
|
||||||
* Module for handling the Sleeve UI
|
|
||||||
*/
|
|
||||||
import React from "react";
|
|
||||||
import { Sleeve } from "./Sleeve";
|
|
||||||
import { SleeveTaskType } from "./SleeveTaskTypesEnum";
|
|
||||||
import { SleeveFaq } from "./data/SleeveFaq";
|
|
||||||
|
|
||||||
import { IPlayer } from "../IPlayer";
|
|
||||||
|
|
||||||
import { Faction } from "../../Faction/Faction";
|
|
||||||
import { Factions } from "../../Faction/Factions";
|
|
||||||
import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
|
|
||||||
|
|
||||||
import { Crime } from "../../Crime/Crime";
|
|
||||||
import { Crimes } from "../../Crime/Crimes";
|
|
||||||
import { CityName } from "../../Locations/data/CityNames";
|
|
||||||
import { LocationName } from "../../Locations/data/LocationNames";
|
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
|
||||||
import { Page, routing } from "../../ui/navigationTracking";
|
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|
||||||
|
|
||||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
|
||||||
import { exceptionAlert } from "../../../utils/helpers/exceptionAlert";
|
|
||||||
|
|
||||||
import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners";
|
|
||||||
import { createElement } from "../../../utils/uiHelpers/createElement";
|
|
||||||
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
|
||||||
import { getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
|
||||||
import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement";
|
|
||||||
import { removeElement } from "../../../utils/uiHelpers/removeElement";
|
|
||||||
|
|
||||||
import { SleeveAugmentationsPopup } from "./ui/SleeveAugmentationsPopup";
|
|
||||||
import { TravelPopup } from "./ui/TravelPopup";
|
|
||||||
import { EarningsTableElement } from "./ui/EarningsTableElement";
|
|
||||||
import { Money } from "../../ui/React/Money";
|
|
||||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
|
||||||
import { ReputationRate } from "../../ui/React/ReputationRate";
|
|
||||||
import { StatsElement } from "./ui/StatsElement";
|
|
||||||
import { MoreStatsContent } from "./ui/MoreStatsContent";
|
|
||||||
import { MoreEarningsContent } from "./ui/MoreEarningsContent";
|
|
||||||
import * as ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
// Object that keeps track of all DOM elements for the UI for a single Sleeve
|
|
||||||
interface ISleeveUIElems {
|
|
||||||
container: HTMLElement | null;
|
|
||||||
statsPanel: HTMLElement | null;
|
|
||||||
stats: HTMLElement | null;
|
|
||||||
moreStatsButton: HTMLElement | null;
|
|
||||||
travelButton: HTMLElement | null;
|
|
||||||
purchaseAugsButton: HTMLElement | null;
|
|
||||||
taskPanel: HTMLElement | null;
|
|
||||||
taskSelector: HTMLSelectElement | null;
|
|
||||||
taskDetailsSelector: HTMLSelectElement | null;
|
|
||||||
taskDetailsSelector2: HTMLSelectElement | null;
|
|
||||||
taskDescription: HTMLElement | null;
|
|
||||||
taskSetButton: HTMLElement | null;
|
|
||||||
taskProgressBar: HTMLElement | null;
|
|
||||||
earningsPanel: HTMLElement | null;
|
|
||||||
currentEarningsInfo: HTMLElement | null;
|
|
||||||
totalEarningsButton: HTMLElement | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Object that keeps track of all DOM elements for the entire Sleeve UI
|
|
||||||
interface IPageUIElems {
|
|
||||||
container: HTMLElement | null;
|
|
||||||
docButton: HTMLElement | null;
|
|
||||||
faqButton: HTMLElement | null;
|
|
||||||
info: HTMLElement | null;
|
|
||||||
sleeveList: HTMLElement | null;
|
|
||||||
sleeves: ISleeveUIElems[] | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UIElems: IPageUIElems = {
|
|
||||||
container: null,
|
|
||||||
docButton: null,
|
|
||||||
faqButton: null,
|
|
||||||
info: null,
|
|
||||||
sleeveList: null,
|
|
||||||
sleeves: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Creates the UI for the entire Sleeves page
|
|
||||||
let playerRef: IPlayer | null;
|
|
||||||
export function createSleevesPage(p: IPlayer): void {
|
|
||||||
if (!routing.isOn(Page.Sleeves)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
playerRef = p;
|
|
||||||
|
|
||||||
UIElems.container = createElement("div", {
|
|
||||||
class: "generic-menupage-container",
|
|
||||||
id: "sleeves-container",
|
|
||||||
position: "fixed",
|
|
||||||
});
|
|
||||||
|
|
||||||
UIElems.info = createElement("p", {
|
|
||||||
class: "sleeves-page-info",
|
|
||||||
innerHTML:
|
|
||||||
"<h1>Sleeves</h1>Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your " +
|
|
||||||
"consciousness has been copied. In other words, these Synthoids contain " +
|
|
||||||
"a perfect duplicate of your mind.<br /><br />" +
|
|
||||||
"Sleeves can be used to perform different tasks synchronously.<br /><br />",
|
|
||||||
});
|
|
||||||
|
|
||||||
UIElems.faqButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "inline-block",
|
|
||||||
innerText: "FAQ",
|
|
||||||
clickListener: () => {
|
|
||||||
dialogBoxCreate(SleeveFaq, false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
UIElems.docButton = createElement("a", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "inline-block",
|
|
||||||
href: "https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves",
|
|
||||||
innerText: "Documentation",
|
|
||||||
target: "_blank",
|
|
||||||
});
|
|
||||||
|
|
||||||
UIElems.sleeveList = createElement("ul");
|
|
||||||
UIElems.sleeves = [];
|
|
||||||
|
|
||||||
// Create UI modules for all Sleeve
|
|
||||||
for (const sleeve of p.sleeves) {
|
|
||||||
const sleeveUi = createSleeveUi(sleeve, p.sleeves);
|
|
||||||
if (sleeveUi.container == null) throw new Error("sleeveUi.container is null in createSleevesPage()");
|
|
||||||
UIElems.sleeveList.appendChild(sleeveUi.container);
|
|
||||||
UIElems.sleeves.push(sleeveUi);
|
|
||||||
}
|
|
||||||
|
|
||||||
UIElems.container.appendChild(UIElems.info);
|
|
||||||
UIElems.container.appendChild(UIElems.faqButton);
|
|
||||||
UIElems.container.appendChild(UIElems.docButton);
|
|
||||||
UIElems.container.appendChild(UIElems.sleeveList);
|
|
||||||
|
|
||||||
const container = document.getElementById("entire-game-container");
|
|
||||||
if (container === null) throw new Error("entire-game-container not found in createSleevesPage()");
|
|
||||||
container.appendChild(UIElems.container);
|
|
||||||
} catch (e) {
|
|
||||||
exceptionAlert(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the UI for the entire Sleeves page
|
|
||||||
export function updateSleevesPage(): void {
|
|
||||||
if (!routing.isOn(Page.Sleeves)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (playerRef === null) throw new Error("playerRef is null in updateSleevesPage()");
|
|
||||||
if (UIElems.sleeves === null) throw new Error("UIElems.sleeves is null in updateSleevesPage()");
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (let i = 0; i < playerRef.sleeves.length; ++i) {
|
|
||||||
const sleeve: Sleeve = playerRef.sleeves[i];
|
|
||||||
const elems: ISleeveUIElems = UIElems.sleeves[i];
|
|
||||||
updateSleeveUi(sleeve, elems);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
exceptionAlert(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearSleevesPage(): void {
|
|
||||||
if (UIElems.container instanceof HTMLElement) {
|
|
||||||
removeElement(UIElems.container);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const prop in UIElems) {
|
|
||||||
(UIElems as any)[prop] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerRef = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the UI for a single Sleeve
|
|
||||||
// Returns an object containing the DOM elements in the UI (ISleeveUIElems)
|
|
||||||
function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
|
||||||
const elems: ISleeveUIElems = {
|
|
||||||
container: null,
|
|
||||||
statsPanel: null,
|
|
||||||
stats: null,
|
|
||||||
moreStatsButton: null,
|
|
||||||
travelButton: null,
|
|
||||||
purchaseAugsButton: null,
|
|
||||||
taskPanel: null,
|
|
||||||
taskSelector: null,
|
|
||||||
taskDetailsSelector: null,
|
|
||||||
taskDetailsSelector2: null,
|
|
||||||
taskDescription: null,
|
|
||||||
taskSetButton: null,
|
|
||||||
taskProgressBar: null,
|
|
||||||
earningsPanel: null,
|
|
||||||
currentEarningsInfo: null,
|
|
||||||
totalEarningsButton: null,
|
|
||||||
};
|
|
||||||
if (playerRef === null) return elems;
|
|
||||||
|
|
||||||
if (!routing.isOn(Page.Sleeves)) {
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
elems.container = createElement("div", {
|
|
||||||
class: "sleeve-container",
|
|
||||||
display: "block",
|
|
||||||
});
|
|
||||||
|
|
||||||
elems.statsPanel = createElement("div", {
|
|
||||||
class: "sleeve-panel",
|
|
||||||
width: "25%",
|
|
||||||
});
|
|
||||||
elems.stats = createElement("div", { class: "sleeve-stats-text" });
|
|
||||||
elems.moreStatsButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "More Stats",
|
|
||||||
clickListener: () => {
|
|
||||||
dialogBoxCreate(<MoreStatsContent sleeve={sleeve} />);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
elems.travelButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Travel",
|
|
||||||
clickListener: () => {
|
|
||||||
if (playerRef == null) throw new Error("playerRef is null in purchaseAugsButton.click()");
|
|
||||||
const popupId = "sleeve-travel-popup";
|
|
||||||
createPopup(popupId, TravelPopup, {
|
|
||||||
popupId: popupId,
|
|
||||||
sleeve: sleeve,
|
|
||||||
player: playerRef,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
elems.purchaseAugsButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "block",
|
|
||||||
innerText: "Manage Augmentations",
|
|
||||||
clickListener: () => {
|
|
||||||
if (playerRef == null) throw new Error("playerRef is null in purchaseAugsButton.click()");
|
|
||||||
const popupId = "sleeve-augmentation-popup";
|
|
||||||
createPopup(popupId, SleeveAugmentationsPopup, {
|
|
||||||
sleeve: sleeve,
|
|
||||||
player: playerRef,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
elems.statsPanel.appendChild(elems.stats);
|
|
||||||
elems.statsPanel.appendChild(elems.moreStatsButton);
|
|
||||||
elems.statsPanel.appendChild(elems.travelButton);
|
|
||||||
if (sleeve.shock >= 100) {
|
|
||||||
// You can only buy augs when shock recovery is 0
|
|
||||||
elems.statsPanel.appendChild(elems.purchaseAugsButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
elems.taskPanel = createElement("div", {
|
|
||||||
class: "sleeve-panel",
|
|
||||||
width: "40%",
|
|
||||||
});
|
|
||||||
elems.taskSelector = createElement("select", {
|
|
||||||
class: "dropdown",
|
|
||||||
}) as HTMLSelectElement;
|
|
||||||
elems.taskSelector.add(createOptionElement("------"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Work for Company"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Work for Faction"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Commit Crime"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Take University Course"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Workout at Gym"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Shock Recovery"));
|
|
||||||
elems.taskSelector.add(createOptionElement("Synchronize"));
|
|
||||||
elems.taskDetailsSelector = createElement("select", {
|
|
||||||
class: "dropdown",
|
|
||||||
}) as HTMLSelectElement;
|
|
||||||
elems.taskDetailsSelector2 = createElement("select", {
|
|
||||||
class: "dropdown",
|
|
||||||
}) as HTMLSelectElement;
|
|
||||||
elems.taskDescription = createElement("p");
|
|
||||||
elems.taskProgressBar = createElement("p");
|
|
||||||
elems.taskSelector.addEventListener("change", () => {
|
|
||||||
updateSleeveTaskSelector(sleeve, elems, allSleeves);
|
|
||||||
});
|
|
||||||
elems.taskSelector.selectedIndex = sleeve.currentTask; // Set initial value for Task Selector
|
|
||||||
elems.taskSelector.dispatchEvent(new Event("change"));
|
|
||||||
updateSleeveTaskDescription(sleeve, elems);
|
|
||||||
elems.taskSetButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Set Task",
|
|
||||||
clickListener: () => {
|
|
||||||
setSleeveTask(sleeve, elems);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
elems.taskPanel.appendChild(elems.taskSelector);
|
|
||||||
elems.taskPanel.appendChild(elems.taskDetailsSelector);
|
|
||||||
elems.taskPanel.appendChild(elems.taskDetailsSelector2);
|
|
||||||
elems.taskPanel.appendChild(elems.taskSetButton);
|
|
||||||
elems.taskPanel.appendChild(elems.taskDescription);
|
|
||||||
elems.taskPanel.appendChild(elems.taskProgressBar);
|
|
||||||
|
|
||||||
elems.earningsPanel = createElement("div", {
|
|
||||||
class: "sleeve-panel",
|
|
||||||
width: "35%",
|
|
||||||
});
|
|
||||||
elems.currentEarningsInfo = createElement("div");
|
|
||||||
elems.totalEarningsButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "More Earnings Info",
|
|
||||||
clickListener: () => {
|
|
||||||
dialogBoxCreate(<MoreEarningsContent sleeve={sleeve} />);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
elems.earningsPanel.appendChild(elems.currentEarningsInfo);
|
|
||||||
elems.earningsPanel.appendChild(elems.totalEarningsButton);
|
|
||||||
|
|
||||||
updateSleeveUi(sleeve, elems);
|
|
||||||
|
|
||||||
elems.container.appendChild(elems.statsPanel);
|
|
||||||
elems.container.appendChild(elems.taskPanel);
|
|
||||||
elems.container.appendChild(elems.earningsPanel);
|
|
||||||
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the UI for a single Sleeve
|
|
||||||
function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems): void {
|
|
||||||
if (!routing.isOn(Page.Sleeves)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (playerRef == null) throw new Error("playerRef is null in updateSleeveUi()");
|
|
||||||
if (elems.taskProgressBar == null) throw new Error("elems.taskProgressBar is null");
|
|
||||||
if (elems.stats == null) throw new Error("elems.stats is null");
|
|
||||||
if (elems.currentEarningsInfo == null) throw new Error("elems.currentEarningsInfo is null");
|
|
||||||
|
|
||||||
ReactDOM.render(StatsElement(sleeve), elems.stats);
|
|
||||||
|
|
||||||
if (sleeve.currentTask === SleeveTaskType.Crime) {
|
|
||||||
const data = [
|
|
||||||
[`Money`, <Money money={parseFloat(sleeve.currentTaskLocation)} />, `(on success)`],
|
|
||||||
[`Hacking Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.hack), `(2x on success)`],
|
|
||||||
[`Strength Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.str), `(2x on success)`],
|
|
||||||
[`Defense Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.def), `(2x on success)`],
|
|
||||||
[`Dexterity Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.dex), `(2x on success)`],
|
|
||||||
[`Agility Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.agi), `(2x on success)`],
|
|
||||||
[`Charisma Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.cha), `(2x on success)`],
|
|
||||||
];
|
|
||||||
ReactDOM.render(EarningsTableElement("Earnings (Pre-Synchronization)", data), elems.currentEarningsInfo);
|
|
||||||
|
|
||||||
elems.taskProgressBar.innerText = createProgressBarText({
|
|
||||||
progress: sleeve.currentTaskTime / sleeve.currentTaskMaxTime,
|
|
||||||
totalTicks: 25,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const data = [
|
|
||||||
[`Money:`, MoneyRate(5 * sleeve.gainRatesForTask.money)],
|
|
||||||
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.hack)} / s`],
|
|
||||||
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.str)} / s`],
|
|
||||||
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.def)} / s`],
|
|
||||||
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.dex)} / s`],
|
|
||||||
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.agi)} / s`],
|
|
||||||
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`],
|
|
||||||
];
|
|
||||||
if (sleeve.currentTask === SleeveTaskType.Company || sleeve.currentTask === SleeveTaskType.Faction) {
|
|
||||||
const repGain: number = sleeve.getRepGain(playerRef);
|
|
||||||
data.push([`Reputation:`, ReputationRate(5 * repGain)]);
|
|
||||||
}
|
|
||||||
ReactDOM.render(EarningsTableElement("Earnings (Pre-Synchronization)", data), elems.currentEarningsInfo);
|
|
||||||
|
|
||||||
elems.taskProgressBar.innerText = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const universitySelectorOptions: string[] = [
|
|
||||||
"Study Computer Science",
|
|
||||||
"Data Structures",
|
|
||||||
"Networks",
|
|
||||||
"Algorithms",
|
|
||||||
"Management",
|
|
||||||
"Leadership",
|
|
||||||
];
|
|
||||||
|
|
||||||
const gymSelectorOptions: string[] = ["Train Strength", "Train Defense", "Train Dexterity", "Train Agility"];
|
|
||||||
|
|
||||||
// Whenever a new task is selected, the "details" selector must update accordingly
|
|
||||||
function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSleeves: Sleeve[]): void {
|
|
||||||
if (playerRef == null) {
|
|
||||||
throw new Error(`playerRef is null in updateSleeveTaskSelector()`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array of all companies that other sleeves are working at
|
|
||||||
const forbiddenCompanies: string[] = [];
|
|
||||||
for (const otherSleeve of allSleeves) {
|
|
||||||
if (sleeve === otherSleeve) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (otherSleeve.currentTask === SleeveTaskType.Company) {
|
|
||||||
forbiddenCompanies.push(otherSleeve.currentTaskLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array of all factions that other sleeves are working for
|
|
||||||
const forbiddenFactions: string[] = [];
|
|
||||||
for (const otherSleeve of allSleeves) {
|
|
||||||
if (sleeve === otherSleeve) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (otherSleeve.currentTask === SleeveTaskType.Faction) {
|
|
||||||
forbiddenFactions.push(otherSleeve.currentTaskLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elems.taskDetailsSelector === null) {
|
|
||||||
throw new Error("elems.taskDetailsSelector is null");
|
|
||||||
}
|
|
||||||
if (elems.taskDetailsSelector2 === null) {
|
|
||||||
throw new Error("elems.taskDetailsSelector is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset Selectors
|
|
||||||
removeChildrenFromElement(elems.taskDetailsSelector);
|
|
||||||
removeChildrenFromElement(elems.taskDetailsSelector2);
|
|
||||||
elems.taskDetailsSelector2 = clearEventListeners(elems.taskDetailsSelector2) as HTMLSelectElement;
|
|
||||||
|
|
||||||
const value: string = getSelectValue(elems.taskSelector);
|
|
||||||
switch (value) {
|
|
||||||
case "Work for Company": {
|
|
||||||
let companyCount = 0;
|
|
||||||
const allJobs: string[] = Object.keys(playerRef.jobs);
|
|
||||||
for (let i = 0; i < allJobs.length; ++i) {
|
|
||||||
if (!forbiddenCompanies.includes(allJobs[i])) {
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement(allJobs[i]));
|
|
||||||
|
|
||||||
// Set initial value of the 'Details' selector
|
|
||||||
if (sleeve.currentTaskLocation === allJobs[i]) {
|
|
||||||
elems.taskDetailsSelector.selectedIndex = companyCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
++companyCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("------"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Work for Faction": {
|
|
||||||
let factionCount = 0;
|
|
||||||
for (const fac of playerRef.factions) {
|
|
||||||
if (!forbiddenFactions.includes(fac)) {
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement(fac));
|
|
||||||
|
|
||||||
// Set initial value of the 'Details' Selector
|
|
||||||
if (sleeve.currentTaskLocation === fac) {
|
|
||||||
elems.taskDetailsSelector.selectedIndex = factionCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
++factionCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The available faction work types depends on the faction
|
|
||||||
elems.taskDetailsSelector.addEventListener("change", () => {
|
|
||||||
if (elems.taskDetailsSelector2 === null) throw new Error("elems.taskDetailsSelector2 is null");
|
|
||||||
const facName = getSelectValue(elems.taskDetailsSelector);
|
|
||||||
const faction: Faction | null = Factions[facName];
|
|
||||||
if (faction == null) {
|
|
||||||
console.warn(`Invalid faction name when trying to update Sleeve Task Selector: ${facName}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const facInfo = faction.getInfo();
|
|
||||||
removeChildrenFromElement(elems.taskDetailsSelector2);
|
|
||||||
let numOptionsAdded = 0;
|
|
||||||
if (facInfo.offerHackingWork) {
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("Hacking Contracts"));
|
|
||||||
if (sleeve.factionWorkType === FactionWorkType.Hacking) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = numOptionsAdded;
|
|
||||||
}
|
|
||||||
++numOptionsAdded;
|
|
||||||
}
|
|
||||||
if (facInfo.offerFieldWork) {
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("Field Work"));
|
|
||||||
if (sleeve.factionWorkType === FactionWorkType.Field) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = numOptionsAdded;
|
|
||||||
}
|
|
||||||
++numOptionsAdded;
|
|
||||||
}
|
|
||||||
if (facInfo.offerSecurityWork) {
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("Security Work"));
|
|
||||||
if (sleeve.factionWorkType === FactionWorkType.Security) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = numOptionsAdded;
|
|
||||||
}
|
|
||||||
++numOptionsAdded;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
elems.taskDetailsSelector.dispatchEvent(new Event("change"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Commit Crime": {
|
|
||||||
let i = 0;
|
|
||||||
for (const crimeLabel in Crimes) {
|
|
||||||
const name: string = Crimes[crimeLabel].name;
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement(name, crimeLabel));
|
|
||||||
|
|
||||||
// Set initial value for crime type
|
|
||||||
if (sleeve.crimeType === "") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const crime: Crime | null = Crimes[sleeve.crimeType];
|
|
||||||
if (crime === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (name === crime.name) {
|
|
||||||
elems.taskDetailsSelector.selectedIndex = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("------"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Take University Course":
|
|
||||||
// First selector has class type
|
|
||||||
for (let i = 0; i < universitySelectorOptions.length; ++i) {
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement(universitySelectorOptions[i]));
|
|
||||||
|
|
||||||
// Set initial value
|
|
||||||
if (sleeve.className === universitySelectorOptions[i]) {
|
|
||||||
elems.taskDetailsSelector.selectedIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second selector has which university
|
|
||||||
switch (sleeve.city) {
|
|
||||||
case CityName.Aevum:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSummitUniversity));
|
|
||||||
break;
|
|
||||||
case CityName.Sector12:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12RothmanUniversity));
|
|
||||||
break;
|
|
||||||
case CityName.Volhaven:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenZBInstituteOfTechnology));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("No university available in city!"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Workout at Gym":
|
|
||||||
// First selector has what stat is being trained
|
|
||||||
for (let i = 0; i < gymSelectorOptions.length; ++i) {
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement(gymSelectorOptions[i]));
|
|
||||||
|
|
||||||
// Set initial value
|
|
||||||
if (sleeve.gymStatType === gymSelectorOptions[i].substring(6, 9).toLowerCase()) {
|
|
||||||
elems.taskDetailsSelector.selectedIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second selector has gym
|
|
||||||
// In this switch statement we also set the initial value of the second selector
|
|
||||||
switch (sleeve.city) {
|
|
||||||
case CityName.Aevum:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumCrushFitnessGym));
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.AevumSnapFitnessGym));
|
|
||||||
|
|
||||||
// Set initial value
|
|
||||||
if (sleeve.currentTaskLocation === LocationName.AevumCrushFitnessGym) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = 0;
|
|
||||||
} else if (sleeve.currentTaskLocation === LocationName.AevumSnapFitnessGym) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CityName.Sector12:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12IronGym));
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.Sector12PowerhouseGym));
|
|
||||||
|
|
||||||
// Set initial value
|
|
||||||
if (sleeve.currentTaskLocation === LocationName.Sector12IronGym) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = 0;
|
|
||||||
} else if (sleeve.currentTaskLocation === LocationName.Sector12PowerhouseGym) {
|
|
||||||
elems.taskDetailsSelector2.selectedIndex = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CityName.Volhaven:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement(LocationName.VolhavenMilleniumFitnessGym));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("No gym available in city!"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "Shock Recovery":
|
|
||||||
case "Synchronize":
|
|
||||||
case "------":
|
|
||||||
// No options in "Details" selector
|
|
||||||
elems.taskDetailsSelector.add(createOptionElement("------"));
|
|
||||||
elems.taskDetailsSelector2.add(createOptionElement("------"));
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
|
||||||
try {
|
|
||||||
if (playerRef == null) {
|
|
||||||
throw new Error("playerRef is null in Sleeve UI's setSleeveTask()");
|
|
||||||
}
|
|
||||||
if (elems.taskDescription == null) throw new Error("elems.taskDescription is null");
|
|
||||||
|
|
||||||
const taskValue: string = getSelectValue(elems.taskSelector);
|
|
||||||
const detailValue: string = getSelectValue(elems.taskDetailsSelector);
|
|
||||||
const detailValue2: string = getSelectValue(elems.taskDetailsSelector2);
|
|
||||||
|
|
||||||
let res = false;
|
|
||||||
switch (taskValue) {
|
|
||||||
case "------":
|
|
||||||
elems.taskDescription.innerText = "This sleeve is currently idle";
|
|
||||||
break;
|
|
||||||
case "Work for Company":
|
|
||||||
res = sleeve.workForCompany(playerRef, detailValue);
|
|
||||||
break;
|
|
||||||
case "Work for Faction":
|
|
||||||
res = sleeve.workForFaction(playerRef, detailValue, detailValue2);
|
|
||||||
break;
|
|
||||||
case "Commit Crime":
|
|
||||||
res = sleeve.commitCrime(playerRef, detailValue);
|
|
||||||
break;
|
|
||||||
case "Take University Course":
|
|
||||||
res = sleeve.takeUniversityCourse(playerRef, detailValue2, detailValue);
|
|
||||||
break;
|
|
||||||
case "Workout at Gym":
|
|
||||||
res = sleeve.workoutAtGym(playerRef, detailValue2, detailValue);
|
|
||||||
break;
|
|
||||||
case "Shock Recovery":
|
|
||||||
sleeve.currentTask = SleeveTaskType.Recovery;
|
|
||||||
res = sleeve.shockRecovery(playerRef);
|
|
||||||
break;
|
|
||||||
case "Synchronize":
|
|
||||||
res = sleeve.synchronize(playerRef);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error(`Invalid/Unrecognized taskValue in setSleeveTask(): ${taskValue}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
updateSleeveTaskDescription(sleeve, elems);
|
|
||||||
} else {
|
|
||||||
switch (taskValue) {
|
|
||||||
case "Work for Faction":
|
|
||||||
elems.taskDescription.innerText =
|
|
||||||
"Failed to assign sleeve to task. This is most likely because the selected faction does not offer the selected work type.";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elems.taskDescription.innerText = "Failed to assign sleeve to task. Invalid choice(s).";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (routing.isOn(Page.Sleeves)) {
|
|
||||||
updateSleevesPage();
|
|
||||||
|
|
||||||
// Update the task selector for all sleeves by triggering a change event
|
|
||||||
if (UIElems.sleeves == null) throw new Error("UIElems.sleeves is null");
|
|
||||||
for (const e of UIElems.sleeves) {
|
|
||||||
if (e.taskSelector == null) throw new Error("e.taskSelector is null");
|
|
||||||
e.taskSelector.dispatchEvent(new Event("change"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Exception caught in setSleeveTask(): ${e}`);
|
|
||||||
exceptionAlert(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSleeveTaskDescription(sleeve: Sleeve, elems: ISleeveUIElems): void {
|
|
||||||
try {
|
|
||||||
if (playerRef == null) {
|
|
||||||
throw new Error("playerRef is null in Sleeve UI's setSleeveTask()");
|
|
||||||
}
|
|
||||||
|
|
||||||
const taskValue: string = getSelectValue(elems.taskSelector);
|
|
||||||
const detailValue: string = getSelectValue(elems.taskDetailsSelector);
|
|
||||||
const detailValue2: string = getSelectValue(elems.taskDetailsSelector2);
|
|
||||||
if (elems.taskDescription == null) throw new Error("elems.taskDescription should not be null");
|
|
||||||
|
|
||||||
switch (taskValue) {
|
|
||||||
case "------":
|
|
||||||
elems.taskDescription.innerText = "This sleeve is currently idle";
|
|
||||||
break;
|
|
||||||
case "Work for Company":
|
|
||||||
elems.taskDescription.innerText = `This sleeve is currently working your job at ${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
|
||||||
case "Work for Faction":
|
|
||||||
elems.taskDescription.innerText = `This sleeve is currently doing ${detailValue2} for ${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
|
||||||
case "Commit Crime":
|
|
||||||
elems.taskDescription.innerText = `This sleeve is currently attempting to ${
|
|
||||||
Crimes[detailValue].type
|
|
||||||
} (Success Rate: ${numeralWrapper.formatPercentage(Crimes[detailValue].successRate(sleeve))}).`;
|
|
||||||
break;
|
|
||||||
case "Take University Course":
|
|
||||||
elems.taskDescription.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
|
||||||
case "Workout at Gym":
|
|
||||||
elems.taskDescription.innerText = `This sleeve is currently working out at ${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
|
||||||
case "Shock Recovery":
|
|
||||||
elems.taskDescription.innerText =
|
|
||||||
"This sleeve is currently set to focus on shock recovery. This causes " +
|
|
||||||
"the Sleeve's shock to decrease at a faster rate.";
|
|
||||||
break;
|
|
||||||
case "Synchronize":
|
|
||||||
elems.taskDescription.innerText =
|
|
||||||
"This sleeve is currently set to synchronize with the original consciousness. " +
|
|
||||||
"This causes the Sleeve's synchronization to increase.";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error(`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${taskValue}`);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Exception caught in updateSleeveTaskDescription(): ${e}`);
|
|
||||||
exceptionAlert(e);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,17 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export function EarningsTableElement(title: string, stats: any[][]): React.ReactElement {
|
interface IProps {
|
||||||
|
title: string;
|
||||||
|
stats: any[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EarningsTableElement(props: IProps): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<pre>{title}</pre>
|
<pre>{props.title}</pre>
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{stats.map((stat: any[], i: number) => (
|
{props.stats.map((stat: any[], i: number) => (
|
||||||
<tr key={i}>
|
<tr key={i}>
|
||||||
{stat.map((s: any, i: number) => {
|
{stat.map((s: any, i: number) => {
|
||||||
let style = {};
|
let style = {};
|
||||||
|
240
src/PersonObjects/Sleeve/ui/SleeveElem.tsx
Normal file
240
src/PersonObjects/Sleeve/ui/SleeveElem.tsx
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
import { Sleeve } from "../Sleeve";
|
||||||
|
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
|
||||||
|
import { SleeveFaq } from "../data/SleeveFaq";
|
||||||
|
|
||||||
|
import { IPlayer } from "../../IPlayer";
|
||||||
|
|
||||||
|
import { Faction } from "../../../Faction/Faction";
|
||||||
|
import { Factions } from "../../../Faction/Factions";
|
||||||
|
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||||
|
|
||||||
|
import { Crime } from "../../../Crime/Crime";
|
||||||
|
import { Crimes } from "../../../Crime/Crimes";
|
||||||
|
import { CityName } from "../../../Locations/data/CityNames";
|
||||||
|
import { LocationName } from "../../../Locations/data/LocationNames";
|
||||||
|
|
||||||
|
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||||
|
import { Page, routing } from "../../../ui/navigationTracking";
|
||||||
|
|
||||||
|
import { dialogBoxCreate } from "../../../../utils/DialogBox";
|
||||||
|
|
||||||
|
import { createProgressBarText } from "../../../../utils/helpers/createProgressBarText";
|
||||||
|
import { exceptionAlert } from "../../../../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
|
import { clearEventListeners } from "../../../../utils/uiHelpers/clearEventListeners";
|
||||||
|
import { createElement } from "../../../../utils/uiHelpers/createElement";
|
||||||
|
import { createOptionElement } from "../../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { createPopup } from "../../../ui/React/createPopup";
|
||||||
|
import { getSelectValue } from "../../../../utils/uiHelpers/getSelectData";
|
||||||
|
import { removeChildrenFromElement } from "../../../../utils/uiHelpers/removeChildrenFromElement";
|
||||||
|
import { removeElement } from "../../../../utils/uiHelpers/removeElement";
|
||||||
|
|
||||||
|
import { SleeveAugmentationsPopup } from "../ui/SleeveAugmentationsPopup";
|
||||||
|
import { TravelPopup } from "../ui/TravelPopup";
|
||||||
|
import { EarningsTableElement } from "../ui/EarningsTableElement";
|
||||||
|
import { Money } from "../../../ui/React/Money";
|
||||||
|
import { MoneyRate } from "../../../ui/React/MoneyRate";
|
||||||
|
import { ReputationRate } from "../../../ui/React/ReputationRate";
|
||||||
|
import { StatsElement } from "../ui/StatsElement";
|
||||||
|
import { MoreStatsContent } from "../ui/MoreStatsContent";
|
||||||
|
import { MoreEarningsContent } from "../ui/MoreEarningsContent";
|
||||||
|
import { TaskSelector } from "../ui/TaskSelector";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
player: IPlayer;
|
||||||
|
sleeve: Sleeve;
|
||||||
|
rerender: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SleeveElem(props: IProps): React.ReactElement {
|
||||||
|
const [abc, setABC] = useState(["------", "------", "------"]);
|
||||||
|
|
||||||
|
function openMoreStats(): void {
|
||||||
|
dialogBoxCreate(<MoreStatsContent sleeve={props.sleeve} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openTravel(): void {
|
||||||
|
const popupId = "sleeve-travel-popup";
|
||||||
|
createPopup(popupId, TravelPopup, {
|
||||||
|
popupId: popupId,
|
||||||
|
sleeve: props.sleeve,
|
||||||
|
player: props.player,
|
||||||
|
rerender: props.rerender,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openManageAugmentations(): void {
|
||||||
|
const popupId = "sleeve-augmentation-popup";
|
||||||
|
createPopup(popupId, SleeveAugmentationsPopup, {
|
||||||
|
sleeve: props.sleeve,
|
||||||
|
player: props.player,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMoreEarnings(): void {
|
||||||
|
dialogBoxCreate(<MoreEarningsContent sleeve={props.sleeve} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTask(): void {
|
||||||
|
props.sleeve.resetTaskStatus(); // sets to idle
|
||||||
|
let res;
|
||||||
|
switch (abc[0]) {
|
||||||
|
case "------":
|
||||||
|
break;
|
||||||
|
case "Work for Company":
|
||||||
|
res = props.sleeve.workForCompany(props.player, abc[1]);
|
||||||
|
break;
|
||||||
|
case "Work for Faction":
|
||||||
|
res = props.sleeve.workForFaction(props.player, abc[1], abc[2]);
|
||||||
|
break;
|
||||||
|
case "Commit Crime":
|
||||||
|
res = props.sleeve.commitCrime(props.player, abc[1]);
|
||||||
|
break;
|
||||||
|
case "Take University Course":
|
||||||
|
res = props.sleeve.takeUniversityCourse(props.player, abc[2], abc[1]);
|
||||||
|
break;
|
||||||
|
case "Workout at Gym":
|
||||||
|
res = props.sleeve.workoutAtGym(props.player, abc[2], abc[1]);
|
||||||
|
break;
|
||||||
|
case "Shock Recovery":
|
||||||
|
res = props.sleeve.shockRecovery(props.player);
|
||||||
|
break;
|
||||||
|
case "Synchronize":
|
||||||
|
res = props.sleeve.synchronize(props.player);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Invalid/Unrecognized taskValue in setSleeveTask(): ${abc[0]}`);
|
||||||
|
}
|
||||||
|
props.rerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
let desc = <></>;
|
||||||
|
switch (props.sleeve.currentTask) {
|
||||||
|
case SleeveTaskType.Idle:
|
||||||
|
desc = <>This sleeve is currently idle</>;
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Company:
|
||||||
|
desc = <>This sleeve is currently working your job at ${props.sleeve.currentTaskLocation}.</>;
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Faction:
|
||||||
|
desc = (
|
||||||
|
<>
|
||||||
|
This sleeve is currently doing ${props.sleeve.factionWorkType} for ${props.sleeve.currentTaskLocation}.
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Crime:
|
||||||
|
desc = (
|
||||||
|
<>
|
||||||
|
This sleeve is currently attempting to {Crimes[props.sleeve.crimeType].type} (Success Rate:{" "}
|
||||||
|
{numeralWrapper.formatPercentage(Crimes[props.sleeve.crimeType].successRate(props.sleeve))}).
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Class:
|
||||||
|
desc = <>This sleeve is currently studying/taking a course at {props.sleeve.currentTaskLocation}.</>;
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Gym:
|
||||||
|
desc = <>This sleeve is currently working out at {props.sleeve.currentTaskLocation}.</>;
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Recovery:
|
||||||
|
desc = (
|
||||||
|
<>
|
||||||
|
This sleeve is currently set to focus on shock recovery. This causes the Sleeve's shock to decrease at a
|
||||||
|
faster rate.
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SleeveTaskType.Synchro:
|
||||||
|
desc = (
|
||||||
|
<>
|
||||||
|
This sleeve is currently set to synchronize with the original consciousness. This causes the Sleeve's
|
||||||
|
synchronization to increase.
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${abc[0]}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data: any[][] = [];
|
||||||
|
if (props.sleeve.currentTask === SleeveTaskType.Crime) {
|
||||||
|
data = [
|
||||||
|
[`Money`, <Money money={parseFloat(props.sleeve.currentTaskLocation)} />, `(on success)`],
|
||||||
|
[`Hacking Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack), `(2x on success)`],
|
||||||
|
[`Strength Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str), `(2x on success)`],
|
||||||
|
[`Defense Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def), `(2x on success)`],
|
||||||
|
[`Dexterity Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.dex), `(2x on success)`],
|
||||||
|
[`Agility Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.agi), `(2x on success)`],
|
||||||
|
[`Charisma Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.cha), `(2x on success)`],
|
||||||
|
];
|
||||||
|
|
||||||
|
// elems.taskProgressBar.innerText = createProgressBarText({
|
||||||
|
// progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
|
||||||
|
// totalTicks: 25,
|
||||||
|
// });
|
||||||
|
} else {
|
||||||
|
data = [
|
||||||
|
[`Money:`, MoneyRate(5 * props.sleeve.gainRatesForTask.money)],
|
||||||
|
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.hack)} / s`],
|
||||||
|
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.str)} / s`],
|
||||||
|
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.def)} / s`],
|
||||||
|
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.dex)} / s`],
|
||||||
|
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.agi)} / s`],
|
||||||
|
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.cha)} / s`],
|
||||||
|
];
|
||||||
|
if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) {
|
||||||
|
const repGain: number = props.sleeve.getRepGain(props.player);
|
||||||
|
data.push([`Reputation:`, ReputationRate(5 * repGain)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// elems.taskProgressBar.innerText = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="sleeve-elem">
|
||||||
|
<div className="sleeve-panel" style={{ width: "25%" }}>
|
||||||
|
<div className="sleeve-stats-text">
|
||||||
|
<StatsElement sleeve={props.sleeve} />
|
||||||
|
<button className="std-button" onClick={openMoreStats}>
|
||||||
|
More Stats
|
||||||
|
</button>
|
||||||
|
<button className="std-button" onClick={openTravel}>
|
||||||
|
Travel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`std-button${props.sleeve.shock < 100 ? " tooltip" : ""}`}
|
||||||
|
onClick={openManageAugmentations}
|
||||||
|
style={{ display: "block" }}
|
||||||
|
disabled={props.sleeve.shock < 100}
|
||||||
|
>
|
||||||
|
Manage Augmentations
|
||||||
|
{props.sleeve.shock < 100 && <span className="tooltiptext">Unlocked when sleeve has fully recovered</span>}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sleeve-panel" style={{ width: "40%" }}>
|
||||||
|
<TaskSelector player={props.player} sleeve={props.sleeve} setABC={setABC} />
|
||||||
|
<p>{desc}</p>
|
||||||
|
<p>
|
||||||
|
{props.sleeve.currentTask === SleeveTaskType.Crime &&
|
||||||
|
createProgressBarText({
|
||||||
|
progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
|
||||||
|
totalTicks: 25,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<button className="std-button" onClick={setTask}>
|
||||||
|
Set Task
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="sleeve-panel" style={{ width: "35%" }}>
|
||||||
|
<EarningsTableElement title="Earnings (Pre-Synchronization)" stats={data} />
|
||||||
|
<button className="std-button" onClick={openMoreEarnings}>
|
||||||
|
More Earnings Info
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
93
src/PersonObjects/Sleeve/ui/SleeveRoot.tsx
Normal file
93
src/PersonObjects/Sleeve/ui/SleeveRoot.tsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
import { Sleeve } from "../Sleeve";
|
||||||
|
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
|
||||||
|
import { SleeveFaq } from "../data/SleeveFaq";
|
||||||
|
|
||||||
|
import { IPlayer } from "../../IPlayer";
|
||||||
|
|
||||||
|
import { Faction } from "../../../Faction/Faction";
|
||||||
|
import { Factions } from "../../../Faction/Factions";
|
||||||
|
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||||
|
|
||||||
|
import { Crime } from "../../../Crime/Crime";
|
||||||
|
import { Crimes } from "../../../Crime/Crimes";
|
||||||
|
import { CityName } from "../../../Locations/data/CityNames";
|
||||||
|
import { LocationName } from "../../../Locations/data/LocationNames";
|
||||||
|
|
||||||
|
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||||
|
import { Page, routing } from "../../../ui/navigationTracking";
|
||||||
|
|
||||||
|
import { dialogBoxCreate } from "../../../../utils/DialogBox";
|
||||||
|
|
||||||
|
import { createProgressBarText } from "../../../../utils/helpers/createProgressBarText";
|
||||||
|
import { exceptionAlert } from "../../../../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
|
import { clearEventListeners } from "../../../../utils/uiHelpers/clearEventListeners";
|
||||||
|
import { createElement } from "../../../../utils/uiHelpers/createElement";
|
||||||
|
import { createOptionElement } from "../../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { createPopup } from "../../../ui/React/createPopup";
|
||||||
|
import { getSelectValue } from "../../../../utils/uiHelpers/getSelectData";
|
||||||
|
import { removeChildrenFromElement } from "../../../../utils/uiHelpers/removeChildrenFromElement";
|
||||||
|
import { removeElement } from "../../../../utils/uiHelpers/removeElement";
|
||||||
|
|
||||||
|
import { SleeveAugmentationsPopup } from "../ui/SleeveAugmentationsPopup";
|
||||||
|
import { TravelPopup } from "../ui/TravelPopup";
|
||||||
|
import { EarningsTableElement } from "../ui/EarningsTableElement";
|
||||||
|
import { Money } from "../../../ui/React/Money";
|
||||||
|
import { MoneyRate } from "../../../ui/React/MoneyRate";
|
||||||
|
import { ReputationRate } from "../../../ui/React/ReputationRate";
|
||||||
|
import { StatsElement } from "../ui/StatsElement";
|
||||||
|
import { MoreStatsContent } from "../ui/MoreStatsContent";
|
||||||
|
import { MoreEarningsContent } from "../ui/MoreEarningsContent";
|
||||||
|
import { SleeveElem } from "../ui/SleeveElem";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
player: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SleeveRoot(props: IProps): React.ReactElement {
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
|
function rerender(): void {
|
||||||
|
setRerender((old) => !old);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const id = setInterval(rerender, 150);
|
||||||
|
return () => clearInterval(id);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ width: "70%" }}>
|
||||||
|
<h1>Sleeves</h1>
|
||||||
|
<p>
|
||||||
|
Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your consciousness has been copied. In
|
||||||
|
other words, these Synthoids contain a perfect duplicate of your mind.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Sleeves can be used to perform different tasks synchronously.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button className="std-button" style={{ display: "inline-block" }}>
|
||||||
|
FAQ
|
||||||
|
</button>
|
||||||
|
<a
|
||||||
|
className="std-button"
|
||||||
|
style={{ display: "inline-block" }}
|
||||||
|
target="_blank"
|
||||||
|
href="https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves"
|
||||||
|
>
|
||||||
|
Documentation
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
{props.player.sleeves.map((sleeve, i) => (
|
||||||
|
<li key={i}>
|
||||||
|
<SleeveElem rerender={rerender} player={props.player} sleeve={sleeve} />
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -2,7 +2,11 @@ import { Sleeve } from "../Sleeve";
|
|||||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
interface IProps {
|
||||||
|
sleeve: Sleeve;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StatsElement(props: IProps): React.ReactElement {
|
||||||
let style = {};
|
let style = {};
|
||||||
style = { textAlign: "right" };
|
style = { textAlign: "right" };
|
||||||
return (
|
return (
|
||||||
@ -12,65 +16,65 @@ export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
|||||||
<tr>
|
<tr>
|
||||||
<td className="character-hp-cell">HP: </td>
|
<td className="character-hp-cell">HP: </td>
|
||||||
<td className="character-hp-cell" style={style}>
|
<td className="character-hp-cell" style={style}>
|
||||||
{numeralWrapper.formatHp(sleeve.hp)} / {numeralWrapper.formatHp(sleeve.max_hp)}
|
{numeralWrapper.formatHp(props.sleeve.hp)} / {numeralWrapper.formatHp(props.sleeve.max_hp)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>City: </td>
|
<td>City: </td>
|
||||||
<td style={style}>{sleeve.city}</td>
|
<td style={style}>{props.sleeve.city}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-hack-cell">Hacking: </td>
|
<td className="character-hack-cell">Hacking: </td>
|
||||||
<td className="character-hack-cell" style={style}>
|
<td className="character-hack-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.hacking_skill)}
|
{numeralWrapper.formatSkill(props.sleeve.hacking_skill)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-combat-cell">Strength: </td>
|
<td className="character-combat-cell">Strength: </td>
|
||||||
<td className="character-combat-cell" style={style}>
|
<td className="character-combat-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.strength)}
|
{numeralWrapper.formatSkill(props.sleeve.strength)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-combat-cell">Defense: </td>
|
<td className="character-combat-cell">Defense: </td>
|
||||||
<td className="character-combat-cell" style={style}>
|
<td className="character-combat-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.defense)}
|
{numeralWrapper.formatSkill(props.sleeve.defense)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-combat-cell">Dexterity: </td>
|
<td className="character-combat-cell">Dexterity: </td>
|
||||||
<td className="character-combat-cell" style={style}>
|
<td className="character-combat-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.dexterity)}
|
{numeralWrapper.formatSkill(props.sleeve.dexterity)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-combat-cell">Agility: </td>
|
<td className="character-combat-cell">Agility: </td>
|
||||||
<td className="character-combat-cell" style={style}>
|
<td className="character-combat-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.agility)}
|
{numeralWrapper.formatSkill(props.sleeve.agility)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-cha-cell">Charisma: </td>
|
<td className="character-cha-cell">Charisma: </td>
|
||||||
<td className="character-cha-cell" style={style}>
|
<td className="character-cha-cell" style={style}>
|
||||||
{numeralWrapper.formatSkill(sleeve.charisma)}
|
{numeralWrapper.formatSkill(props.sleeve.charisma)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-int-cell">Shock: </td>
|
<td className="character-int-cell">Shock: </td>
|
||||||
<td className="character-int-cell" style={style}>
|
<td className="character-int-cell" style={style}>
|
||||||
{numeralWrapper.formatSleeveShock(100 - sleeve.shock)}
|
{numeralWrapper.formatSleeveShock(100 - props.sleeve.shock)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-int-cell">Sync: </td>
|
<td className="character-int-cell">Sync: </td>
|
||||||
<td className="character-int-cell" style={style}>
|
<td className="character-int-cell" style={style}>
|
||||||
{numeralWrapper.formatSleeveSynchro(sleeve.sync)}
|
{numeralWrapper.formatSleeveSynchro(props.sleeve.sync)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="character-int-cell">Memory: </td>
|
<td className="character-int-cell">Memory: </td>
|
||||||
<td className="character-int-cell" style={style}>
|
<td className="character-int-cell" style={style}>
|
||||||
{numeralWrapper.formatSleeveMemory(sleeve.memory)}
|
{numeralWrapper.formatSleeveMemory(props.sleeve.memory)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
290
src/PersonObjects/Sleeve/ui/TaskSelector.tsx
Normal file
290
src/PersonObjects/Sleeve/ui/TaskSelector.tsx
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Sleeve } from "../Sleeve";
|
||||||
|
import { IPlayer } from "../../IPlayer";
|
||||||
|
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
|
||||||
|
import { Crimes } from "../../../Crime/Crimes";
|
||||||
|
import { LocationName } from "../../../Locations/data/LocationNames";
|
||||||
|
import { CityName } from "../../../Locations/data/CityNames";
|
||||||
|
import { Factions } from "../../../Faction/Factions";
|
||||||
|
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||||
|
|
||||||
|
const universitySelectorOptions: string[] = [
|
||||||
|
"Study Computer Science",
|
||||||
|
"Data Structures",
|
||||||
|
"Networks",
|
||||||
|
"Algorithms",
|
||||||
|
"Management",
|
||||||
|
"Leadership",
|
||||||
|
];
|
||||||
|
|
||||||
|
const gymSelectorOptions: string[] = ["Train Strength", "Train Defense", "Train Dexterity", "Train Agility"];
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
sleeve: Sleeve;
|
||||||
|
player: IPlayer;
|
||||||
|
setABC: (abc: string[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITaskDetails {
|
||||||
|
first: string[];
|
||||||
|
second: (s1: string) => string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
|
||||||
|
// Array of all companies that other sleeves are working at
|
||||||
|
const forbiddenCompanies = [];
|
||||||
|
for (const otherSleeve of player.sleeves) {
|
||||||
|
if (sleeve === otherSleeve) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (otherSleeve.currentTask === SleeveTaskType.Company) {
|
||||||
|
forbiddenCompanies.push(otherSleeve.currentTaskLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let allJobs: string[] = Object.keys(player.jobs);
|
||||||
|
for (let i = 0; i < allJobs.length; ++i) {
|
||||||
|
if (!forbiddenCompanies.includes(allJobs[i])) {
|
||||||
|
allJobs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allJobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
|
||||||
|
// Array of all factions that other sleeves are working for
|
||||||
|
const forbiddenFactions = [];
|
||||||
|
for (const otherSleeve of player.sleeves) {
|
||||||
|
if (sleeve === otherSleeve) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (otherSleeve.currentTask === SleeveTaskType.Faction) {
|
||||||
|
forbiddenFactions.push(otherSleeve.currentTaskLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const factions = [];
|
||||||
|
for (const fac of player.factions) {
|
||||||
|
if (!forbiddenFactions.includes(fac)) {
|
||||||
|
factions.push(fac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return factions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tasks: {
|
||||||
|
[key: string]: undefined | ((player: IPlayer, sleeve: Sleeve) => ITaskDetails);
|
||||||
|
["------"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Work for Company"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Work for Faction"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Commit Crime"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Take University Course"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Workout at Gym"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Shock Recovery"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
["Synchronize"]: (player: IPlayer, sleeve: Sleeve) => ITaskDetails;
|
||||||
|
} = {
|
||||||
|
"------": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
return { first: ["------"], second: () => ["------"] };
|
||||||
|
},
|
||||||
|
"Work for Company": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
let jobs = possibleJobs(player, sleeve);
|
||||||
|
|
||||||
|
if (jobs.length === 0) jobs = ["------"];
|
||||||
|
return { first: jobs, second: () => ["------"] };
|
||||||
|
},
|
||||||
|
"Work for Faction": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
let factions = possibleFactions(player, sleeve);
|
||||||
|
if (factions.length === 0) factions = ["------"];
|
||||||
|
|
||||||
|
return {
|
||||||
|
first: factions,
|
||||||
|
second: (s1: string) => {
|
||||||
|
const faction = Factions[s1];
|
||||||
|
const facInfo = faction.getInfo();
|
||||||
|
const options: string[] = [];
|
||||||
|
if (facInfo.offerHackingWork) {
|
||||||
|
options.push("Hacking Contracts");
|
||||||
|
}
|
||||||
|
if (facInfo.offerFieldWork) {
|
||||||
|
options.push("Field Work");
|
||||||
|
}
|
||||||
|
if (facInfo.offerSecurityWork) {
|
||||||
|
options.push("Security Work");
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
"Commit Crime": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
return { first: Object.keys(Crimes), second: () => ["------"] };
|
||||||
|
},
|
||||||
|
"Take University Course": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
let universities: string[] = [];
|
||||||
|
switch (sleeve.city) {
|
||||||
|
case CityName.Aevum:
|
||||||
|
universities = [LocationName.AevumSummitUniversity];
|
||||||
|
break;
|
||||||
|
case CityName.Sector12:
|
||||||
|
universities = [LocationName.Sector12RothmanUniversity];
|
||||||
|
break;
|
||||||
|
case CityName.Volhaven:
|
||||||
|
universities = [LocationName.VolhavenZBInstituteOfTechnology];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
universities = ["No university available in city!"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { first: universitySelectorOptions, second: () => universities };
|
||||||
|
},
|
||||||
|
"Workout at Gym": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
let gyms: string[] = [];
|
||||||
|
switch (sleeve.city) {
|
||||||
|
case CityName.Aevum:
|
||||||
|
gyms = [LocationName.AevumCrushFitnessGym, LocationName.AevumSnapFitnessGym];
|
||||||
|
break;
|
||||||
|
case CityName.Sector12:
|
||||||
|
gyms = [LocationName.Sector12IronGym, LocationName.Sector12PowerhouseGym];
|
||||||
|
break;
|
||||||
|
case CityName.Volhaven:
|
||||||
|
gyms = [LocationName.VolhavenMilleniumFitnessGym];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gyms = ["No gym available in city!"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { first: gymSelectorOptions, second: () => gyms };
|
||||||
|
},
|
||||||
|
"Shock Recovery": (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
return { first: ["------"], second: () => ["------"] };
|
||||||
|
},
|
||||||
|
Synchronize: (player: IPlayer, sleeve: Sleeve): ITaskDetails => {
|
||||||
|
return { first: ["------"], second: () => ["------"] };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const canDo: {
|
||||||
|
[key: string]: undefined | ((player: IPlayer, sleeve: Sleeve) => boolean);
|
||||||
|
["------"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Work for Company"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Work for Faction"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Commit Crime"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Take University Course"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Workout at Gym"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Shock Recovery"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
["Synchronize"]: (player: IPlayer, sleeve: Sleeve) => boolean;
|
||||||
|
} = {
|
||||||
|
["------"]: () => true,
|
||||||
|
["Work for Company"]: (player: IPlayer, sleeve: Sleeve) => possibleJobs(player, sleeve).length > 0,
|
||||||
|
["Work for Faction"]: (player: IPlayer, sleeve: Sleeve) => possibleFactions(player, sleeve).length > 0,
|
||||||
|
["Commit Crime"]: () => true,
|
||||||
|
["Take University Course"]: (player: IPlayer, sleeve: Sleeve) =>
|
||||||
|
[CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city),
|
||||||
|
["Workout at Gym"]: (player: IPlayer, sleeve: Sleeve) =>
|
||||||
|
[CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city),
|
||||||
|
["Shock Recovery"]: (player: IPlayer, sleeve: Sleeve) => sleeve.shock < 100,
|
||||||
|
["Synchronize"]: (player: IPlayer, sleeve: Sleeve) => sleeve.sync < 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
function getABC(sleeve: Sleeve): [string, string, string] {
|
||||||
|
switch (sleeve.currentTask) {
|
||||||
|
case SleeveTaskType.Idle:
|
||||||
|
return ["------", "------", "------"];
|
||||||
|
case SleeveTaskType.Company:
|
||||||
|
return ["Work for Company", sleeve.currentTaskLocation, "------"];
|
||||||
|
case SleeveTaskType.Faction:
|
||||||
|
let workType = "";
|
||||||
|
switch (sleeve.factionWorkType) {
|
||||||
|
case FactionWorkType.Hacking:
|
||||||
|
workType = "Hacking Contracts";
|
||||||
|
break;
|
||||||
|
case FactionWorkType.Field:
|
||||||
|
workType = "Field Work";
|
||||||
|
break;
|
||||||
|
case FactionWorkType.Security:
|
||||||
|
workType = "Security Work";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ["Work for Faction", sleeve.currentTaskLocation, workType];
|
||||||
|
case SleeveTaskType.Crime:
|
||||||
|
return ["Commit Crime", sleeve.crimeType, "------"];
|
||||||
|
case SleeveTaskType.Class:
|
||||||
|
return ["Take University Course", sleeve.className, sleeve.currentTaskLocation];
|
||||||
|
case SleeveTaskType.Gym:
|
||||||
|
return ["Workout at Gym", sleeve.gymStatType, sleeve.currentTaskLocation];
|
||||||
|
case SleeveTaskType.Recovery:
|
||||||
|
return ["Shock Recovery", "------", "------"];
|
||||||
|
case SleeveTaskType.Synchro:
|
||||||
|
return ["Synchronize", "------", "------"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TaskSelector(props: IProps): React.ReactElement {
|
||||||
|
const abc = getABC(props.sleeve);
|
||||||
|
const [s0, setS0] = useState(abc[0]);
|
||||||
|
const [s1, setS1] = useState(abc[1]);
|
||||||
|
const [s2, setS2] = useState(abc[2]);
|
||||||
|
|
||||||
|
const validActions = Object.keys(canDo).filter((k) =>
|
||||||
|
(canDo[k] as (player: IPlayer, sleeve: Sleeve) => boolean)(props.player, props.sleeve),
|
||||||
|
);
|
||||||
|
|
||||||
|
const detailsF = tasks[s0];
|
||||||
|
if (detailsF === undefined) throw new Error(`No function for task '${s0}'`);
|
||||||
|
const details = detailsF(props.player, props.sleeve);
|
||||||
|
const details2 = details.second(s1);
|
||||||
|
|
||||||
|
function onS0Change(event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||||
|
const n = event.target.value;
|
||||||
|
const detailsF = tasks[n];
|
||||||
|
if (detailsF === undefined) throw new Error(`No function for task '${s0}'`);
|
||||||
|
const details = detailsF(props.player, props.sleeve);
|
||||||
|
const details2 = details.second(details.first[0]);
|
||||||
|
setS2(details2[0]);
|
||||||
|
setS1(details.first[0]);
|
||||||
|
setS0(n);
|
||||||
|
props.setABC([n, details.first[0], details2[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onS1Change(event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||||
|
setS1(event.target.value);
|
||||||
|
props.setABC([s0, event.target.value, s2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onS2Change(event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||||
|
setS2(event.target.value);
|
||||||
|
props.setABC([s0, s1, event.target.value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<select className="dropdown" onChange={onS0Change} defaultValue={s0}>
|
||||||
|
{validActions.map((task) => (
|
||||||
|
<option key={task} value={task}>
|
||||||
|
{task}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
{!(details.first.length === 1 && details.first[0] === "------") && (
|
||||||
|
<select className="dropdown" onChange={onS1Change} defaultValue={s1}>
|
||||||
|
{details.first.map((detail) => (
|
||||||
|
<option key={detail} value={detail}>
|
||||||
|
{detail}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
)}
|
||||||
|
{!(details2.length === 1 && details2[0] === "------") && (
|
||||||
|
<select className="dropdown" onChange={onS2Change} defaultValue={s2}>
|
||||||
|
{details2.map((detail) => (
|
||||||
|
<option key={detail} value={detail}>
|
||||||
|
{detail}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -12,6 +12,7 @@ interface IProps {
|
|||||||
popupId: string;
|
popupId: string;
|
||||||
sleeve: Sleeve;
|
sleeve: Sleeve;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TravelPopup(props: IProps): React.ReactElement {
|
export function TravelPopup(props: IProps): React.ReactElement {
|
||||||
@ -23,6 +24,7 @@ export function TravelPopup(props: IProps): React.ReactElement {
|
|||||||
props.player.loseMoney(CONSTANTS.TravelCost);
|
props.player.loseMoney(CONSTANTS.TravelCost);
|
||||||
props.sleeve.resetTaskStatus();
|
props.sleeve.resetTaskStatus();
|
||||||
removePopup(props.popupId);
|
removePopup(props.popupId);
|
||||||
|
props.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -35,7 +37,7 @@ export function TravelPopup(props: IProps): React.ReactElement {
|
|||||||
{Object.keys(Cities)
|
{Object.keys(Cities)
|
||||||
.filter((city: string) => props.sleeve.city !== city)
|
.filter((city: string) => props.sleeve.city !== city)
|
||||||
.map((city: string) => (
|
.map((city: string) => (
|
||||||
<div className="cmpy-mgmt-find-employee-option" onClick={() => travel(city)}>
|
<div key={city} className="cmpy-mgmt-find-employee-option" onClick={() => travel(city)}>
|
||||||
{city}
|
{city}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -23,6 +23,7 @@ import { Root as BladeburnerRoot } from "./Bladeburner/ui/Root";
|
|||||||
import { Root as GangRoot } from "./Gang/ui/Root";
|
import { Root as GangRoot } from "./Gang/ui/Root";
|
||||||
import { CorporationRoot } from "./Corporation/ui/CorporationRoot";
|
import { CorporationRoot } from "./Corporation/ui/CorporationRoot";
|
||||||
import { ResleeveRoot } from "./PersonObjects/Resleeving/ui/ResleeveRoot";
|
import { ResleeveRoot } from "./PersonObjects/Resleeving/ui/ResleeveRoot";
|
||||||
|
import { SleeveRoot } from "./PersonObjects/Sleeve/ui/SleeveRoot";
|
||||||
import { displayInfiltrationContent } from "./Infiltration/Helper";
|
import { displayInfiltrationContent } from "./Infiltration/Helper";
|
||||||
import {
|
import {
|
||||||
getHackingWorkRepGain,
|
getHackingWorkRepGain,
|
||||||
@ -57,7 +58,6 @@ import { initSymbolToStockMap, processStockPrices, displayStockMarketContent } f
|
|||||||
import { displayMilestonesContent } from "./Milestones/MilestoneHelpers";
|
import { displayMilestonesContent } from "./Milestones/MilestoneHelpers";
|
||||||
import { Terminal, postNetburnerText } from "./Terminal";
|
import { Terminal, postNetburnerText } from "./Terminal";
|
||||||
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
||||||
import { clearSleevesPage, createSleevesPage, updateSleevesPage } from "./PersonObjects/Sleeve/SleeveUI";
|
|
||||||
|
|
||||||
import { createStatusText } from "./ui/createStatusText";
|
import { createStatusText } from "./ui/createStatusText";
|
||||||
import { CharacterInfo } from "./ui/CharacterInfo";
|
import { CharacterInfo } from "./ui/CharacterInfo";
|
||||||
@ -190,6 +190,7 @@ const Engine = {
|
|||||||
gangContent: null,
|
gangContent: null,
|
||||||
bladeburnerContent: null,
|
bladeburnerContent: null,
|
||||||
resleeveContent: null,
|
resleeveContent: null,
|
||||||
|
sleeveContent: null,
|
||||||
corporationContent: null,
|
corporationContent: null,
|
||||||
locationContent: null,
|
locationContent: null,
|
||||||
workInProgressContent: null,
|
workInProgressContent: null,
|
||||||
@ -429,14 +430,10 @@ const Engine = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
loadSleevesContent: function () {
|
loadSleevesContent: function () {
|
||||||
// This is for Duplicate Sleeves page, not Re-sleeving @ Vita Life
|
|
||||||
try {
|
|
||||||
Engine.hideAllContent();
|
Engine.hideAllContent();
|
||||||
routing.navigateTo(Page.Sleeves);
|
routing.navigateTo(Page.Sleeves);
|
||||||
createSleevesPage(Player);
|
Engine.Display.sleevesContent.style.display = "block";
|
||||||
} catch (e) {
|
ReactDOM.render(<SleeveRoot player={Player} />, Engine.Display.sleevesContent);
|
||||||
exceptionAlert(e);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadResleevingContent: function () {
|
loadResleevingContent: function () {
|
||||||
@ -487,20 +484,18 @@ const Engine = {
|
|||||||
Engine.Display.resleeveContent.style.display = "none";
|
Engine.Display.resleeveContent.style.display = "none";
|
||||||
ReactDOM.unmountComponentAtNode(Engine.Display.resleeveContent);
|
ReactDOM.unmountComponentAtNode(Engine.Display.resleeveContent);
|
||||||
|
|
||||||
|
Engine.Display.sleevesContent.style.display = "none";
|
||||||
|
ReactDOM.unmountComponentAtNode(Engine.Display.sleevesContent);
|
||||||
|
|
||||||
Engine.Display.corporationContent.style.display = "none";
|
Engine.Display.corporationContent.style.display = "none";
|
||||||
ReactDOM.unmountComponentAtNode(Engine.Display.corporationContent);
|
ReactDOM.unmountComponentAtNode(Engine.Display.corporationContent);
|
||||||
|
|
||||||
Engine.Display.resleeveContent.style.display = "none";
|
|
||||||
ReactDOM.unmountComponentAtNode(Engine.Display.resleeveContent);
|
|
||||||
|
|
||||||
Engine.Display.workInProgressContent.style.display = "none";
|
Engine.Display.workInProgressContent.style.display = "none";
|
||||||
Engine.Display.redPillContent.style.display = "none";
|
Engine.Display.redPillContent.style.display = "none";
|
||||||
Engine.Display.cinematicTextContent.style.display = "none";
|
Engine.Display.cinematicTextContent.style.display = "none";
|
||||||
Engine.Display.stockMarketContent.style.display = "none";
|
Engine.Display.stockMarketContent.style.display = "none";
|
||||||
Engine.Display.missionContent.style.display = "none";
|
Engine.Display.missionContent.style.display = "none";
|
||||||
|
|
||||||
clearSleevesPage();
|
|
||||||
|
|
||||||
// Make nav menu tabs inactive
|
// Make nav menu tabs inactive
|
||||||
Engine.inactivateMainMenuLinks();
|
Engine.inactivateMainMenuLinks();
|
||||||
|
|
||||||
@ -738,8 +733,6 @@ const Engine = {
|
|||||||
Engine.displayCharacterOverviewInfo();
|
Engine.displayCharacterOverviewInfo();
|
||||||
if (routing.isOn(Page.CreateProgram)) {
|
if (routing.isOn(Page.CreateProgram)) {
|
||||||
displayCreateProgramContent();
|
displayCreateProgramContent();
|
||||||
} else if (routing.isOn(Page.Sleeves)) {
|
|
||||||
updateSleevesPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine.Counters.updateDisplays = 3;
|
Engine.Counters.updateDisplays = 3;
|
||||||
@ -1258,6 +1251,9 @@ const Engine = {
|
|||||||
Engine.Display.resleeveContent = document.getElementById("resleeve-container");
|
Engine.Display.resleeveContent = document.getElementById("resleeve-container");
|
||||||
Engine.Display.resleeveContent.style.display = "none";
|
Engine.Display.resleeveContent.style.display = "none";
|
||||||
|
|
||||||
|
Engine.Display.sleevesContent = document.getElementById("sleeves-container");
|
||||||
|
Engine.Display.sleevesContent.style.display = "none";
|
||||||
|
|
||||||
Engine.Display.corporationContent = document.getElementById("corporation-container");
|
Engine.Display.corporationContent = document.getElementById("corporation-container");
|
||||||
Engine.Display.corporationContent.style.display = "none";
|
Engine.Display.corporationContent.style.display = "none";
|
||||||
|
|
||||||
|
@ -367,6 +367,7 @@
|
|||||||
<div id="resleeve-container" class="generic-menupage-container"></div>
|
<div id="resleeve-container" class="generic-menupage-container"></div>
|
||||||
<div id="gang-container" class="generic-menupage-container"></div>
|
<div id="gang-container" class="generic-menupage-container"></div>
|
||||||
<div id="corporation-container" class="generic-menupage-container"></div>
|
<div id="corporation-container" class="generic-menupage-container"></div>
|
||||||
|
<div id="sleeves-container" class="generic-menupage-container"></div>
|
||||||
|
|
||||||
<!-- Generic Yes/No Pop Up box -->
|
<!-- Generic Yes/No Pop Up box -->
|
||||||
<div id="yes-no-box-container" class="popup-box-container">
|
<div id="yes-no-box-container" class="popup-box-container">
|
||||||
|
Loading…
Reference in New Issue
Block a user