more cleanup in engine

This commit is contained in:
Olivier Gagnon 2021-09-10 16:08:58 -04:00
parent b45ab657c5
commit 339d9a8d96
11 changed files with 269 additions and 490 deletions

@ -2455,22 +2455,6 @@ function augmentationExists(name) {
return Augmentations.hasOwnProperty(name); return Augmentations.hasOwnProperty(name);
} }
export function displayAugmentationsContent(contentEl) {
if (!routing.isOn(Page.Augmentations)) {
return;
}
if (!(contentEl instanceof HTMLElement)) {
return;
}
function backup() {
saveObject.exportGame();
onExport(Player);
}
ReactDOM.render(<AugmentationsRoot exportGameFn={backup} installAugmentationsFn={installAugmentations} />, contentEl);
}
export function isRepeatableAug(aug) { export function isRepeatableAug(aug) {
const augName = aug instanceof Augmentation ? aug.name : aug; const augName = aug instanceof Augmentation ? aug.name : aug;

@ -1,26 +0,0 @@
import { Page, routing } from ".././ui/navigationTracking";
import { Root } from "./ui/Root";
import { Player } from "../Player";
import * as React from "react";
import * as ReactDOM from "react-dom";
let milestonesContainer: HTMLElement | null = null;
(function () {
function setContainer(): void {
milestonesContainer = document.getElementById("milestones-container");
document.removeEventListener("DOMContentLoaded", setContainer);
}
document.addEventListener("DOMContentLoaded", setContainer);
})();
export function displayMilestonesContent(): void {
if (!routing.isOn(Page.Milestones)) {
return;
}
if (milestonesContainer instanceof HTMLElement) {
ReactDOM.render(<Root player={Player} />, milestonesContainer);
}
}

@ -16,7 +16,7 @@ function highestMilestone(p: IPlayer, milestones: Milestone[]): number {
return n; return n;
} }
export function Root(props: IProps): JSX.Element { export function MilestonesRoot(props: IProps): JSX.Element {
const n = highestMilestone(props.player, Milestones); const n = highestMilestone(props.player, Milestones);
const milestones = Milestones.map((milestone: Milestone, i: number) => { const milestones = Milestones.map((milestone: Milestone, i: number) => {
if (i <= n + 1) { if (i <= n + 1) {

@ -192,4 +192,5 @@ export interface IPlayer {
getCasinoWinnings(): number; getCasinoWinnings(): number;
quitJob(company: string): void; quitJob(company: string): void;
createHacknetServer(): void; createHacknetServer(): void;
startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
} }

@ -23,7 +23,7 @@ import { prestigeHomeComputer } from "./Server/ServerHelpers";
import { SourceFileFlags, updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; import { SourceFileFlags, updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
import { SpecialServerIps, prestigeSpecialServerIps, SpecialServerNames } from "./Server/SpecialServerIps"; import { SpecialServerIps, prestigeSpecialServerIps, SpecialServerNames } from "./Server/SpecialServerIps";
import { deleteStockMarket, initStockMarket, initSymbolToStockMap } from "./StockMarket/StockMarket"; import { deleteStockMarket, initStockMarket, initSymbolToStockMap } from "./StockMarket/StockMarket";
import { Terminal, postNetburnerText } from "./Terminal"; import { Terminal, postVersion } from "./Terminal";
import { Page, routing } from "./ui/navigationTracking"; import { Page, routing } from "./ui/navigationTracking";

@ -3,19 +3,6 @@ import { Programs } from "./Programs";
import { Player } from "../Player"; import { Player } from "../Player";
import { createElement } from "../../utils/uiHelpers/createElement"; import { createElement } from "../../utils/uiHelpers/createElement";
// this has the same key as 'Programs', not program names
const aLinks = {};
function displayCreateProgramContent() {
for (const key in aLinks) {
const p = Programs[key];
aLinks[key].style.display = "none";
if (!Player.hasProgram(p.name) && p.create.req(Player)) {
aLinks[key].style.display = "inline-block";
}
}
}
//Returns the number of programs that are currently available to be created //Returns the number of programs that are currently available to be created
function getNumAvailableCreateProgram() { function getNumAvailableCreateProgram() {
var count = 0; var count = 0;
@ -46,29 +33,4 @@ function getNumAvailableCreateProgram() {
return count; return count;
} }
function initCreateProgramButtons() { export { getNumAvailableCreateProgram };
const createProgramList = document.getElementById("create-program-list");
for (const key in Programs) {
if (Programs[key].create === null) {
continue;
}
const elem = createElement("a", {
class: "a-link-button",
id: Programs[key].htmlID(),
innerText: Programs[key].name,
tooltip: Programs[key].create.tooltip,
});
aLinks[key] = elem;
createProgramList.appendChild(elem);
}
for (const key in aLinks) {
const p = Programs[key];
aLinks[key].addEventListener("click", function () {
Player.startCreateProgramWork(p.name, p.create.time, p.create.level);
return false;
});
}
}
export { displayCreateProgramContent, getNumAvailableCreateProgram, initCreateProgramButtons };

@ -0,0 +1,49 @@
import React, { useState, useEffect } from "react";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Programs } from "../Programs";
interface IProps {
player: IPlayer;
}
export function ProgramsRoot(props: IProps): React.ReactElement {
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
const [divisionName, setDivisionName] = useState("Overview");
useEffect(() => {
const id = setInterval(rerender, 20);
return () => clearInterval(id);
}, []);
return (
<>
<p id="create-program-page-text">
This page displays any programs that you are able to create. Writing the code for a program takes time, which
can vary based on how complex the program is. If you are working on creating a program you can cancel at any
time. Your progress will be saved and you can continue later.
</p>
<ul id="create-program-list">
{Object.keys(Programs).map((programName) => {
const program = Programs[programName];
if (program == null) return <></>;
const create = program.create;
if (create === null) return <></>;
return (
<a
key={programName}
className="a-link-button tooltip"
onClick={() => props.player.startCreateProgramWork(program.name, create.time, create.level)}
>
{program.name}
<span className="tooltiptext">{create.tooltip}</span>
</a>
);
})}
</ul>
</>
);
}

@ -64,7 +64,7 @@ import * as FileSaver from "file-saver";
import * as libarg from "arg"; import * as libarg from "arg";
import React from "react"; import React from "react";
function postNetburnerText() { function postVersion() {
post("Bitburner v" + CONSTANTS.Version); post("Bitburner v" + CONSTANTS.Version);
} }
@ -2616,4 +2616,4 @@ let Terminal = {
}, },
}; };
export { postNetburnerText, Terminal }; export { postVersion, Terminal };

@ -0,0 +1,99 @@
import React from "react";
export function TutorialRoot(): React.ReactElement {
return (
<>
<h1>Tutorial (AKA Links to Documentation)</h1>
<a
id="tutorial-getting-started-link"
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
>
Getting Started
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
>
Servers & Networking
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
>
Hacking
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
>
Scripts
</a>
<br />
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
>
Traveling
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
>
Companies
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
>
Infiltration
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
>
Factions
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
>
Augmentations
</a>
<br />
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts
</a>
</>
);
}

@ -5,7 +5,13 @@
*/ */
import { convertTimeMsToTimeElapsedString, replaceAt } from "../utils/StringHelperFunctions"; import { convertTimeMsToTimeElapsedString, replaceAt } from "../utils/StringHelperFunctions";
import { Augmentations } from "./Augmentation/Augmentations"; import { Augmentations } from "./Augmentation/Augmentations";
import { initAugmentations, displayAugmentationsContent } from "./Augmentation/AugmentationHelpers"; import {
initAugmentations,
displayAugmentationsContent,
installAugmentations,
} from "./Augmentation/AugmentationHelpers";
import { onExport } from "./ExportBonus";
import { AugmentationsRoot } from "./Augmentation/ui/Root";
import { AugmentationNames } from "./Augmentation/data/AugmentationNames"; import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
import { initBitNodeMultipliers } from "./BitNode/BitNode"; import { initBitNodeMultipliers } from "./BitNode/BitNode";
import { Bladeburner } from "./Bladeburner/Bladeburner"; import { Bladeburner } from "./Bladeburner/Bladeburner";
@ -42,11 +48,8 @@ import { workerScripts } from "./Netscript/WorkerScripts";
import { loadAllRunningScripts, updateOnlineScriptTimes } from "./NetscriptWorker"; import { loadAllRunningScripts, updateOnlineScriptTimes } from "./NetscriptWorker";
import { Player } from "./Player"; import { Player } from "./Player";
import { prestigeAugmentation } from "./Prestige"; import { prestigeAugmentation } from "./Prestige";
import { import { getNumAvailableCreateProgram } from "./Programs/ProgramHelpers";
displayCreateProgramContent, import { ProgramsRoot } from "./Programs/ui/ProgramsRoot";
getNumAvailableCreateProgram,
initCreateProgramButtons,
} from "./Programs/ProgramHelpers";
import { redPillFlag } from "./RedPill"; import { redPillFlag } from "./RedPill";
import { saveObject, loadGame } from "./SaveObject"; import { saveObject, loadGame } from "./SaveObject";
import { Root as ScriptEditorRoot } from "./ScriptEditor/ui/Root"; import { Root as ScriptEditorRoot } from "./ScriptEditor/ui/Root";
@ -55,8 +58,9 @@ import { Settings } from "./Settings/Settings";
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
import { initSpecialServerIps } from "./Server/SpecialServerIps"; import { initSpecialServerIps } from "./Server/SpecialServerIps";
import { initSymbolToStockMap, processStockPrices, displayStockMarketContent } from "./StockMarket/StockMarket"; import { initSymbolToStockMap, processStockPrices, displayStockMarketContent } from "./StockMarket/StockMarket";
import { displayMilestonesContent } from "./Milestones/MilestoneHelpers"; import { MilestonesRoot } from "./Milestones/ui/MilestonesRoot";
import { Terminal, postNetburnerText } from "./Terminal"; import { Terminal, postVersion } from "./Terminal";
import { TutorialRoot } from "./Tutorial/ui/TutorialRoot";
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve"; import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
import { createStatusText } from "./ui/createStatusText"; import { createStatusText } from "./ui/createStatusText";
@ -197,9 +201,6 @@ const Engine = {
redPillContent: null, redPillContent: null,
cinematicTextContent: null, cinematicTextContent: null,
missionContent: null, missionContent: null,
// Character info
characterInfo: null,
}, },
indexedDb: undefined, indexedDb: undefined,
@ -218,8 +219,8 @@ const Engine = {
loadCharacterContent: function () { loadCharacterContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.characterContent.style.display = "block"; Engine.Display.characterContent.style.display = "block";
ReactDOM.render(<CharacterInfo player={Player} />, Engine.Display.characterInfo);
routing.navigateTo(Page.CharacterInfo); routing.navigateTo(Page.CharacterInfo);
ReactDOM.render(<CharacterInfo player={Player} />, Engine.Display.characterContent);
MainMenuLinks.Stats.classList.add("active"); MainMenuLinks.Stats.classList.add("active");
}, },
@ -227,50 +228,49 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.scriptEditorContent.style.display = "block"; Engine.Display.scriptEditorContent.style.display = "block";
routing.navigateTo(Page.ScriptEditor); routing.navigateTo(Page.ScriptEditor);
MainMenuLinks.ScriptEditor.classList.add("active");
ReactDOM.render( ReactDOM.render(
<ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />, <ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />,
Engine.Display.scriptEditorContent, Engine.Display.scriptEditorContent,
); );
MainMenuLinks.ScriptEditor.classList.add("active");
}, },
loadActiveScriptsContent: function () { loadActiveScriptsContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.activeScriptsContent.style.display = "block"; Engine.Display.activeScriptsContent.style.display = "block";
routing.navigateTo(Page.ActiveScripts); routing.navigateTo(Page.ActiveScripts);
MainMenuLinks.ActiveScripts.classList.add("active");
ReactDOM.render( ReactDOM.render(
<ActiveScriptsRoot p={Player} workerScripts={workerScripts} />, <ActiveScriptsRoot p={Player} workerScripts={workerScripts} />,
Engine.Display.activeScriptsContent, Engine.Display.activeScriptsContent,
); );
MainMenuLinks.ActiveScripts.classList.add("active");
}, },
loadHacknetNodesContent: function () { loadHacknetNodesContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.hacknetNodesContent.style.display = "block"; Engine.Display.hacknetNodesContent.style.display = "block";
routing.navigateTo(Page.HacknetNodes); routing.navigateTo(Page.HacknetNodes);
ReactDOM.render(<HacknetRoot player={Player} />, Engine.Display.hacknetNodesContent);
MainMenuLinks.HacknetNodes.classList.add("active"); MainMenuLinks.HacknetNodes.classList.add("active");
ReactDOM.render(<HacknetRoot player={Player} />, Engine.Display.hacknetNodesContent);
}, },
loadCreateProgramContent: function () { loadCreateProgramContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.createProgramContent.style.display = "block"; Engine.Display.createProgramContent.style.display = "block";
displayCreateProgramContent();
routing.navigateTo(Page.CreateProgram); routing.navigateTo(Page.CreateProgram);
MainMenuLinks.CreateProgram.classList.add("active"); MainMenuLinks.CreateProgram.classList.add("active");
ReactDOM.render(<ProgramsRoot player={Player} />, Engine.Display.createProgramContent);
}, },
loadFactionsContent: function () { loadFactionsContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.factionsContent.style.display = "block"; Engine.Display.factionsContent.style.display = "block";
routing.navigateTo(Page.Factions); routing.navigateTo(Page.Factions);
ReactDOM.render(<FactionList player={Player} engine={this} />, Engine.Display.factionsContent);
MainMenuLinks.Factions.classList.add("active"); MainMenuLinks.Factions.classList.add("active");
ReactDOM.render(<FactionList player={Player} engine={this} />, Engine.Display.factionsContent);
}, },
// TODO reactify
loadFactionContent: function () { loadFactionContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.factionContent.style.display = "block"; Engine.Display.factionContent.style.display = "block";
@ -281,16 +281,25 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.augmentationsContent.style.display = "block"; Engine.Display.augmentationsContent.style.display = "block";
routing.navigateTo(Page.Augmentations); routing.navigateTo(Page.Augmentations);
displayAugmentationsContent(Engine.Display.augmentationsContent);
MainMenuLinks.Augmentations.classList.add("active"); MainMenuLinks.Augmentations.classList.add("active");
function backup() {
saveObject.exportGame();
onExport(Player);
}
ReactDOM.render(
<AugmentationsRoot exportGameFn={backup} installAugmentationsFn={installAugmentations} />,
Engine.Display.augmentationsContent,
);
}, },
loadMilestonesContent: function () { loadMilestonesContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.milestonesContent.style.display = "block"; Engine.Display.milestonesContent.style.display = "block";
routing.navigateTo(Page.Milestones); routing.navigateTo(Page.Milestones);
displayMilestonesContent();
MainMenuLinks.Milestones.classList.add("active"); MainMenuLinks.Milestones.classList.add("active");
ReactDOM.render(<MilestonesRoot player={Player} />, Engine.Display.milestonesContent);
}, },
loadTutorialContent: function () { loadTutorialContent: function () {
@ -298,8 +307,10 @@ const Engine = {
Engine.Display.tutorialContent.style.display = "block"; Engine.Display.tutorialContent.style.display = "block";
routing.navigateTo(Page.Tutorial); routing.navigateTo(Page.Tutorial);
MainMenuLinks.Tutorial.classList.add("active"); MainMenuLinks.Tutorial.classList.add("active");
ReactDOM.render(<TutorialRoot />, Engine.Display.tutorialContent);
}, },
// TODO reactify
loadDevMenuContent: function () { loadDevMenuContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
createDevMenu(); createDevMenu();
@ -310,11 +321,12 @@ const Engine = {
loadLocationContent: function (initiallyInCity = true) { loadLocationContent: function (initiallyInCity = true) {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.locationContent.style.display = "block"; Engine.Display.locationContent.style.display = "block";
MainMenuLinks.City.classList.add("active");
routing.navigateTo(Page.Location); routing.navigateTo(Page.Location);
const rootComponent = <LocationRoot initiallyInCity={initiallyInCity} engine={Engine} p={Player} />; MainMenuLinks.City.classList.add("active");
ReactDOM.render(rootComponent, Engine.Display.locationContent); ReactDOM.render(
<LocationRoot initiallyInCity={initiallyInCity} engine={Engine} p={Player} />,
Engine.Display.locationContent,
);
}, },
loadTravelContent: function () { loadTravelContent: function () {
@ -323,11 +335,12 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
Player.gotoLocation(LocationName.TravelAgency); Player.gotoLocation(LocationName.TravelAgency);
Engine.Display.locationContent.style.display = "block"; Engine.Display.locationContent.style.display = "block";
MainMenuLinks.Travel.classList.add("active");
routing.navigateTo(Page.Location); routing.navigateTo(Page.Location);
const rootComponent = <LocationRoot initiallyInCity={false} engine={Engine} p={Player} />; MainMenuLinks.Travel.classList.add("active");
ReactDOM.render(rootComponent, Engine.Display.locationContent); ReactDOM.render(
<LocationRoot initiallyInCity={false} engine={Engine} p={Player} />,
Engine.Display.locationContent,
);
}, },
loadJobContent: function () { loadJobContent: function () {
@ -342,29 +355,33 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
Player.gotoLocation(Player.companyName); Player.gotoLocation(Player.companyName);
Engine.Display.locationContent.style.display = "block"; Engine.Display.locationContent.style.display = "block";
MainMenuLinks.Job.classList.add("active");
routing.navigateTo(Page.Location); routing.navigateTo(Page.Location);
const rootComponent = <LocationRoot initiallyInCity={false} engine={Engine} p={Player} />; MainMenuLinks.Job.classList.add("active");
ReactDOM.render(rootComponent, Engine.Display.locationContent); ReactDOM.render(
<LocationRoot initiallyInCity={false} engine={Engine} p={Player} />,
Engine.Display.locationContent,
);
}, },
// TODO reactify
loadWorkInProgressContent: function () { loadWorkInProgressContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
var mainMenu = document.getElementById("mainmenu-container"); const mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden"; mainMenu.style.visibility = "hidden";
Engine.Display.workInProgressContent.style.display = "block"; Engine.Display.workInProgressContent.style.display = "block";
routing.navigateTo(Page.WorkInProgress); routing.navigateTo(Page.WorkInProgress);
}, },
// TODO reactify
loadRedPillContent: function () { loadRedPillContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
var mainMenu = document.getElementById("mainmenu-container"); const mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "hidden"; mainMenu.style.visibility = "hidden";
Engine.Display.redPillContent.style.display = "block"; Engine.Display.redPillContent.style.display = "block";
routing.navigateTo(Page.RedPill); routing.navigateTo(Page.RedPill);
}, },
// TODO reactify
loadCinematicTextContent: function () { loadCinematicTextContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
var mainMenu = document.getElementById("mainmenu-container"); var mainMenu = document.getElementById("mainmenu-container");
@ -373,6 +390,7 @@ const Engine = {
routing.navigateTo(Page.CinematicText); routing.navigateTo(Page.CinematicText);
}, },
// TODO reactify
loadInfiltrationContent: function (name, difficulty, maxLevel) { loadInfiltrationContent: function (name, difficulty, maxLevel) {
Engine.hideAllContent(); Engine.hideAllContent();
const mainMenu = document.getElementById("mainmenu-container"); const mainMenu = document.getElementById("mainmenu-container");
@ -386,19 +404,17 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.stockMarketContent.style.display = "block"; Engine.Display.stockMarketContent.style.display = "block";
routing.navigateTo(Page.StockMarket); routing.navigateTo(Page.StockMarket);
MainMenuLinks.StockMarket.classList.add("active");
displayStockMarketContent(); displayStockMarketContent();
}, },
loadGangContent: function () { loadGangContent: function () {
if (!Player.inGang()) return;
Engine.hideAllContent(); Engine.hideAllContent();
if (Player.inGang()) {
Engine.Display.gangContent.style.display = "block"; Engine.Display.gangContent.style.display = "block";
routing.navigateTo(Page.Gang); routing.navigateTo(Page.Gang);
MainMenuLinks.Gang.classList.add("active");
ReactDOM.render(<GangRoot engine={this} gang={Player.gang} player={Player} />, Engine.Display.gangContent); ReactDOM.render(<GangRoot engine={this} gang={Player.gang} player={Player} />, Engine.Display.gangContent);
} else {
Engine.loadTerminalContent();
routing.navigateTo(Page.Terminal);
}
}, },
loadMissionContent: function () { loadMissionContent: function () {
@ -412,27 +428,28 @@ const Engine = {
loadCorporationContent: function () { loadCorporationContent: function () {
if (!(Player.corporation instanceof Corporation)) return; if (!(Player.corporation instanceof Corporation)) return;
Engine.hideAllContent(); Engine.hideAllContent();
routing.navigateTo(Page.Corporation);
Engine.Display.corporationContent.style.display = "block"; Engine.Display.corporationContent.style.display = "block";
routing.navigateTo(Page.Corporation);
MainMenuLinks.Corporation.classList.add("active");
ReactDOM.render(<CorporationRoot corp={Player.corporation} player={Player} />, Engine.Display.corporationContent); ReactDOM.render(<CorporationRoot corp={Player.corporation} player={Player} />, Engine.Display.corporationContent);
}, },
loadBladeburnerContent: function () { loadBladeburnerContent: function () {
if (!(Player.bladeburner instanceof Bladeburner)) return; if (!(Player.bladeburner instanceof Bladeburner)) return;
Engine.hideAllContent(); Engine.hideAllContent();
routing.navigateTo(Page.Bladeburner);
Engine.Display.bladeburnerContent.style.display = "block"; Engine.Display.bladeburnerContent.style.display = "block";
routing.navigateTo(Page.Bladeburner);
MainMenuLinks.Bladeburner.classList.add("active");
ReactDOM.render( ReactDOM.render(
<BladeburnerRoot bladeburner={Player.bladeburner} player={Player} engine={this} />, <BladeburnerRoot bladeburner={Player.bladeburner} player={Player} engine={this} />,
Engine.Display.bladeburnerContent, Engine.Display.bladeburnerContent,
); );
MainMenuLinks.Bladeburner.classList.add("active");
}, },
loadSleevesContent: function () { loadSleevesContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
routing.navigateTo(Page.Sleeves);
Engine.Display.sleevesContent.style.display = "block"; Engine.Display.sleevesContent.style.display = "block";
routing.navigateTo(Page.Sleeves);
ReactDOM.render(<SleeveRoot player={Player} />, Engine.Display.sleevesContent); ReactDOM.render(<SleeveRoot player={Player} />, Engine.Display.sleevesContent);
}, },
@ -440,6 +457,7 @@ const Engine = {
Engine.hideAllContent(); Engine.hideAllContent();
routing.navigateTo(Page.Resleeves); routing.navigateTo(Page.Resleeves);
Engine.Display.resleeveContent.style.display = "block"; Engine.Display.resleeveContent.style.display = "block";
MainMenuLinks.City.classList.add("active");
ReactDOM.render(<ResleeveRoot player={Player} />, Engine.Display.resleeveContent); ReactDOM.render(<ResleeveRoot player={Player} />, Engine.Display.resleeveContent);
}, },
@ -716,10 +734,6 @@ const Engine = {
if (Engine.Counters.updateDisplays <= 0) { if (Engine.Counters.updateDisplays <= 0) {
Engine.displayCharacterOverviewInfo(); Engine.displayCharacterOverviewInfo();
if (routing.isOn(Page.CreateProgram)) {
displayCreateProgramContent();
}
Engine.Counters.updateDisplays = 3; Engine.Counters.updateDisplays = 3;
} }
@ -1238,9 +1252,6 @@ const Engine = {
Engine.Display.missionContent = document.getElementById("mission-container"); Engine.Display.missionContent = document.getElementById("mission-container");
Engine.Display.missionContent.style.display = "none"; Engine.Display.missionContent.style.display = "none";
// Character info
Engine.Display.characterInfo = document.getElementById("character-content");
// Location page (page that shows up when you visit a specific location in World) // Location page (page that shows up when you visit a specific location in World)
Engine.Display.locationContent = document.getElementById("location-container"); Engine.Display.locationContent = document.getElementById("location-container");
Engine.Display.locationContent.style.display = "none"; Engine.Display.locationContent.style.display = "none";
@ -1285,110 +1296,30 @@ const Engine = {
return; return;
} }
MainMenuLinks.Terminal.addEventListener("click", function () { MainMenuLinks.Terminal.addEventListener("click", () => Engine.loadTerminalContent());
Engine.loadTerminalContent(); MainMenuLinks.ScriptEditor.addEventListener("click", () => Engine.loadScriptEditorContent());
return false; MainMenuLinks.ActiveScripts.addEventListener("click", () => Engine.loadActiveScriptsContent());
}); MainMenuLinks.CreateProgram.addEventListener("click", () => Engine.loadCreateProgramContent());
MainMenuLinks.Stats.addEventListener("click", () => Engine.loadCharacterContent());
MainMenuLinks.ScriptEditor.addEventListener("click", function () { MainMenuLinks.Factions.addEventListener("click", () => Engine.loadFactionsContent());
Engine.loadScriptEditorContent(); MainMenuLinks.Augmentations.addEventListener("click", () => Engine.loadAugmentationsContent());
return false; MainMenuLinks.HacknetNodes.addEventListener("click", () => Engine.loadHacknetNodesContent());
}); MainMenuLinks.Sleeves.addEventListener("click", () => Engine.loadSleevesContent());
MainMenuLinks.City.addEventListener("click", () => Engine.loadLocationContent());
MainMenuLinks.ActiveScripts.addEventListener("click", function () { MainMenuLinks.Travel.addEventListener("click", () => Engine.loadTravelContent());
Engine.loadActiveScriptsContent(); MainMenuLinks.Job.addEventListener("click", () => Engine.loadJobContent());
return false; MainMenuLinks.StockMarket.addEventListener("click", () => Engine.loadStockMarketContent());
}); MainMenuLinks.Bladeburner.addEventListener("click", () => Engine.loadBladeburnerContent());
MainMenuLinks.Corporation.addEventListener("click", () => Engine.loadCorporationContent());
MainMenuLinks.CreateProgram.addEventListener("click", function () { MainMenuLinks.Gang.addEventListener("click", () => Engine.loadGangContent());
Engine.loadCreateProgramContent(); MainMenuLinks.Milestones.addEventListener("click", () => Engine.loadMilestonesContent());
return false; MainMenuLinks.Tutorial.addEventListener("click", () => Engine.loadTutorialContent());
});
MainMenuLinks.Stats.addEventListener("click", function () {
Engine.loadCharacterContent();
return false;
});
MainMenuLinks.Factions.addEventListener("click", function () {
Engine.loadFactionsContent();
return false;
});
MainMenuLinks.Augmentations.addEventListener("click", function () {
Engine.loadAugmentationsContent();
return false;
});
MainMenuLinks.HacknetNodes.addEventListener("click", function () {
Engine.loadHacknetNodesContent();
return false;
});
MainMenuLinks.Sleeves.addEventListener("click", function () {
Engine.loadSleevesContent();
MainMenuLinks.Sleeves.classList.add("active");
return false;
});
MainMenuLinks.City.addEventListener("click", function () {
Engine.loadLocationContent();
return false;
});
MainMenuLinks.Travel.addEventListener("click", function () {
Engine.loadTravelContent();
return false;
});
MainMenuLinks.Job.addEventListener("click", function () {
Engine.loadJobContent();
return false;
});
MainMenuLinks.StockMarket.addEventListener("click", function () {
Engine.loadStockMarketContent();
MainMenuLinks.StockMarket.classList.add("active");
return false;
});
MainMenuLinks.Bladeburner.addEventListener("click", function () {
Engine.loadBladeburnerContent();
return false;
});
MainMenuLinks.Corporation.addEventListener("click", function () {
Engine.loadCorporationContent();
MainMenuLinks.Corporation.classList.add("active");
return false;
});
MainMenuLinks.Gang.addEventListener("click", function () {
Engine.loadGangContent();
MainMenuLinks.Gang.classList.add("active");
return false;
});
MainMenuLinks.Milestones.addEventListener("click", function () {
Engine.loadMilestonesContent();
return false;
});
MainMenuLinks.Tutorial.addEventListener("click", function () {
Engine.loadTutorialContent();
return false;
});
MainMenuLinks.DevMenu.addEventListener("click", function () { MainMenuLinks.DevMenu.addEventListener("click", function () {
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
Engine.loadDevMenuContent(); Engine.loadDevMenuContent();
} }
return false;
}); });
// Active scripts list
Engine.ActiveScriptsList = document.getElementById("active-scripts-list");
// Save, Delete, Import/Export buttons // Save, Delete, Import/Export buttons
Engine.Clickables.saveMainMenuButton = document.getElementById("save-game-link"); Engine.Clickables.saveMainMenuButton = document.getElementById("save-game-link");
Engine.Clickables.saveMainMenuButton.addEventListener("click", function () { Engine.Clickables.saveMainMenuButton.addEventListener("click", function () {
@ -1418,11 +1349,8 @@ const Engine = {
return false; return false;
}); });
// Create Program buttons
initCreateProgramButtons();
// Message at the top of terminal // Message at the top of terminal
postNetburnerText(); postVersion();
// Player was working cancel button // Player was working cancel button
if (Player.isWorking) { if (Player.isWorking) {
@ -1517,7 +1445,6 @@ const Engine = {
} }
dialogBoxCreate("Forcefully deleted all running scripts. Please save and refresh page."); dialogBoxCreate("Forcefully deleted all running scripts. Please save and refresh page.");
gameOptionsBoxClose(); gameOptionsBoxClose();
return false;
}); });
// DEBUG Soft Reset // DEBUG Soft Reset
@ -1525,13 +1452,11 @@ const Engine = {
dialogBoxCreate("Soft Reset!"); dialogBoxCreate("Soft Reset!");
prestigeAugmentation(); prestigeAugmentation();
gameOptionsBoxClose(); gameOptionsBoxClose();
return false;
}); });
// DEBUG File diagnostic // DEBUG File diagnostic
document.getElementById("debug-files").addEventListener("click", function () { document.getElementById("debug-files").addEventListener("click", function () {
createPopup("debug-files-diagnostic-popup", FileDiagnosticPopup, {}); createPopup("debug-files-diagnostic-popup", FileDiagnosticPopup, {});
return false;
}); });
}, },

@ -41,178 +41,93 @@
<div id="entire-game-container" style="visibility: hidden"> <div id="entire-game-container" style="visibility: hidden">
<div id="mainmenu-container"> <div id="mainmenu-container">
<!-- Main menu --> <!-- Main menu -->
<ul id="mainmenu" class="mainmenu noscrollbar"> <ul id="mainmenu" class="mainmenu noscrollbar noselect">
<!-- Hacking dropdown --> <!-- Hacking dropdown -->
<li id="hacking-menu-header-li"> <li id="hacking-menu-header-li">
<button id="hacking-menu-header" class="mainmenu-accordion-header noselect">Hacking</button> <button id="hacking-menu-header" class="mainmenu-accordion-header">Hacking</button>
</li> </li>
<li id="terminal-tab" class="mainmenu-accordion-panel noselect"> <li id="terminal-tab" class="mainmenu-accordion-panel">
<button id="terminal-menu-link">Terminal</button> <button id="terminal-menu-link">Terminal</button>
</li> </li>
<li id="create-script-tab" class="mainmenu-accordion-panel noselect"> <li id="create-script-tab" class="mainmenu-accordion-panel">
<button id="create-script-menu-link">Create Script</button> <button id="create-script-menu-link">Create Script</button>
</li> </li>
<li id="active-scripts-tab" class="mainmenu-accordion-panel noselect"> <li id="active-scripts-tab" class="mainmenu-accordion-panel">
<button id="active-scripts-menu-link">Active Scripts</button> <button id="active-scripts-menu-link">Active Scripts</button>
</li> </li>
<li id="create-program-tab" class="mainmenu-accordion-panel noselect"> <li id="create-program-tab" class="mainmenu-accordion-panel">
<button id="create-program-menu-link">Create Program</button> <button id="create-program-menu-link">Create Program</button>
<span id="create-program-notification" class="notification-off"> </span> <span id="create-program-notification" class="notification-off"> </span>
</li> </li>
<!-- Character dropdown --> <!-- Character dropdown -->
<li id="character-menu-header-li"> <li id="character-menu-header-li">
<button id="character-menu-header" class="mainmenu-accordion-header noselect">Character</button> <button id="character-menu-header" class="mainmenu-accordion-header">Character</button>
</li> </li>
<li id="stats-tab" class="mainmenu-accordion-panel noselect"> <li id="stats-tab" class="mainmenu-accordion-panel">
<button id="stats-menu-link">Stats</button> <button id="stats-menu-link">Stats</button>
</li> </li>
<li id="factions-tab" class="mainmenu-accordion-panel noselect"> <li id="factions-tab" class="mainmenu-accordion-panel">
<button id="factions-menu-link">Factions</button> <button id="factions-menu-link">Factions</button>
<span id="factions-notification" class="notification-off"> </span> <span id="factions-notification" class="notification-off"> </span>
</li> </li>
<li id="augmentations-tab" class="mainmenu-accordion-panel noselect"> <li id="augmentations-tab" class="mainmenu-accordion-panel">
<button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"> <button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
Augmentations Augmentations
</button> </button>
<span id="augmentations-notification" class="notification-off"> </span> <span id="augmentations-notification" class="notification-off"> </span>
</li> </li>
<li id="hacknet-nodes-tab" class="mainmenu-accordion-panel noselect"> <li id="hacknet-nodes-tab" class="mainmenu-accordion-panel">
<button id="hacknet-nodes-menu-link">Hacknet</button> <button id="hacknet-nodes-menu-link">Hacknet</button>
</li> </li>
<li id="sleeves-tab" class="mainmenu-accordion-panel noselect"> <li id="sleeves-tab" class="mainmenu-accordion-panel">
<button id="sleeves-menu-link">Sleeves</button> <button id="sleeves-menu-link">Sleeves</button>
</li> </li>
<!-- World dropdown --> <!-- World dropdown -->
<li id="world-menu-header-li"> <li id="world-menu-header-li">
<button id="world-menu-header" class="mainmenu-accordion-header noselect">World</button> <button id="world-menu-header" class="mainmenu-accordion-header">World</button>
</li> </li>
<li id="city-tab" class="mainmenu-accordion-panel noselect"> <li id="city-tab" class="mainmenu-accordion-panel">
<button id="city-menu-link">City</button> <button id="city-menu-link">City</button>
</li> </li>
<li id="travel-tab" class="mainmenu-accordion-panel noselect"> <li id="travel-tab" class="mainmenu-accordion-panel">
<button id="travel-menu-link">Travel</button> <button id="travel-menu-link">Travel</button>
</li> </li>
<li id="job-tab" class="mainmenu-accordion-panel noselect"> <li id="job-tab" class="mainmenu-accordion-panel">
<button id="job-menu-link">Job</button> <button id="job-menu-link">Job</button>
</li> </li>
<li id="stock-market-tab" class="mainmenu-accordion-panel noselect"> <li id="stock-market-tab" class="mainmenu-accordion-panel">
<button id="stock-market-menu-link">Stock Market</button> <button id="stock-market-menu-link">Stock Market</button>
</li> </li>
<li id="bladeburner-tab" class="mainmenu-accordion-panel noselect"> <li id="bladeburner-tab" class="mainmenu-accordion-panel">
<button id="bladeburner-menu-link">Bladeburner</button> <button id="bladeburner-menu-link">Bladeburner</button>
</li> </li>
<li id="corporation-tab" class="mainmenu-accordion-panel noselect"> <li id="corporation-tab" class="mainmenu-accordion-panel">
<button id="corporation-menu-link">Corp</button> <button id="corporation-menu-link">Corp</button>
</li> </li>
<li id="gang-tab" class="mainmenu-accordion-panel noselect"> <li id="gang-tab" class="mainmenu-accordion-panel">
<button id="gang-menu-link">Gang</button> <button id="gang-menu-link">Gang</button>
</li> </li>
<li id="help-menu-header-li"> <li id="help-menu-header-li">
<button id="help-menu-header" class="mainmenu-accordion-header noselect">Help</button> <button id="help-menu-header" class="mainmenu-accordion-header">Help</button>
</li> </li>
<li id="milestones-tab" class="mainmenu-accordion-panel noselect"> <li id="milestones-tab" class="mainmenu-accordion-panel">
<button id="milestones-menu-link">Milestones</button> <button id="milestones-menu-link">Milestones</button>
</li> </li>
<li id="tutorial-tab" class="mainmenu-accordion-panel noselect"> <li id="tutorial-tab" class="mainmenu-accordion-panel">
<button id="tutorial-menu-link">Tutorial</button> <button id="tutorial-menu-link">Tutorial</button>
</li> </li>
<li id="options-tab" class="mainmenu-accordion-panel noselect"> <li id="options-tab" class="mainmenu-accordion-panel">
<button id="options-menu-link">Options</button> <button id="options-menu-link">Options</button>
</li> </li>
<li id="dev-tab" class="mainmenu-accordion-panel noselect"> <li id="dev-tab" class="mainmenu-accordion-panel">
<button id="dev-menu-link">Dev</button> <button id="dev-menu-link">Dev</button>
</li> </li>
</ul> </ul>
</div> </div>
<div id="script-editor-container" class="generic-menupage-container">
<div id="script-editor-wrapper">
<div id="script-editor-filename-wrapper">
<p id="script-editor-filename-tag">
<strong style="background-color: #555">Script name: </strong>
</p>
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1" />
</div>
<div id="monaco-editor"></div>
<div id="script-editor-buttons-wrapper"></div>
<!-- Buttons below script editor -->
</div>
<!-- End wrapper -->
<div id="script-editor-options-panel">
<h1 style="color: white">Script Editor Options</h1>
<fieldset>
<label for="script-editor-option-editor">Editor</label>
<select id="script-editor-option-editor" class="dropdown">
<option value="Ace">Ace</option>
<option value="CodeMirror">CodeMirror</option>
</select>
</fieldset>
<fieldset>
<label for="script-editor-option-theme">Theme</label>
<select id="script-editor-option-theme" class="dropdown"></select>
</fieldset>
<fieldset>
<label for="script-editor-option-keybinding">Key Binding</label>
<select id="script-editor-option-keybinding" class="dropdown"></select>
</fieldset>
<fieldset>
<label for="script-editor-option-highlightactiveline">Highlight Active Line</label>
<input
type="checkbox"
class="optionCheckbox"
name="script-editor-option-highlightactiveline"
id="script-editor-option-highlightactiveline"
checked
/>
</fieldset>
<fieldset>
<label for="script-editor-option-showinvisibles">Show Invisibles</label>
<input
type="checkbox"
class="optionCheckbox"
name="script-editor-option-showinvisibles"
id="script-editor-option-showinvisibles"
/>
</fieldset>
<fieldset>
<label for="script-editor-option-usesofttab">Use Soft Tab</label>
<input
type="checkbox"
class="optionCheckbox"
name="script-editor-option-usesofttab"
id="script-editor-option-usesofttab"
checked
/>
</fieldset>
<fieldset id="script-editor-option-flex1-fieldset"></fieldset>
<fieldset id="script-editor-option-flex2-fieldset"></fieldset>
<fieldset id="script-editor-option-flex3-fieldset"></fieldset>
<fieldset id="script-editor-option-flex4-fieldset"></fieldset>
</div>
<!-- End script editor options panel -->
<!-- TODO(hydroflame): remove this once Monaco is implemented -->
<div id="ace-editor" style="display: none"></div>
<form id="codemirror-form-wrapper" style="display: none">
<textarea id="codemirror-editor"></textarea>
</form>
<div id="codemirror-vim-command-display-wrapper" style="display: none">
Key Buffer: <span id="codemirror-vim-command-display"></span>
</div>
</div>
<!-- Terminal page --> <!-- Terminal page -->
<div id="terminal-container"> <div id="terminal-container">
<table id="terminal"> <table id="terminal">
@ -233,133 +148,16 @@
</div> </div>
<!-- Character Info page --> <!-- Character Info page -->
<div id="character-container" class="generic-menupage-container"> <div id="character-container" class="generic-menupage-container"></div>
<div id="character-content"></div> <div id="active-scripts-container" class="generic-menupage-container"></div>
</div> <div id="script-editor-container" class="generic-menupage-container"></div>
<div id="hacknet-nodes-container" class="generic-menupage-container"></div>
<!-- Active scripts info page --> <div id="create-program-container" class="generic-menupage-container"></div>
<div id="active-scripts-container" class="generic-menupage-container">
<p id="active-scripts-text">
This page displays a list of all of your scripts that are currently running across every machine. It also
provides information about each script's production. The scripts are categorized by the hostname of the
servers on which they are running.
</p>
<p id="active-scripts-total-prod">
Total online production of Active scripts:
<span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br />
Total online production since last Aug installation:
<span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
(<span class="money-gold"
><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span
>)
</p>
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none"></ul>
</div>
<!-- Hacknet Nodes -->
<div id="hacknet-nodes-container" class="generic-menupage-container">
<!-- React Component -->
</div>
<!-- Create a program(executable) -->
<div id="create-program-container" class="generic-menupage-container">
<p id="create-program-page-text">
This page displays any programs that you are able to create. Writing the code for a program takes time, which
can vary based on how complex the program is. If you are working on creating a program you can cancel at any
time. Your progress will be saved and you can continue later.
</p>
<ul id="create-program-list"></ul>
</div>
<!-- Factions -->
<div id="factions-container" class="generic-menupage-container"></div> <div id="factions-container" class="generic-menupage-container"></div>
<!-- Single Faction info (when you select a faction from the Factions menu) -->
<div id="faction-container" class="generic-menupage-container"></div> <div id="faction-container" class="generic-menupage-container"></div>
<!-- Augmentations -->
<div id="augmentations-container" class="generic-menupage-container"></div> <div id="augmentations-container" class="generic-menupage-container"></div>
<!-- Milestones content -->
<div id="milestones-container" class="generic-menupage-container"></div> <div id="milestones-container" class="generic-menupage-container"></div>
<div id="tutorial-container" class="generic-menupage-container"></div>
<!-- Tutorial content -->
<div id="tutorial-container" class="generic-menupage-container">
<h1>Tutorial (AKA Links to Documentation)</h1>
<a
id="tutorial-getting-started-link"
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
>
Getting Started</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
>
Servers & Networking</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
>
Hacking</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
>
Scripts</a
><br /><br />
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
>
Traveling</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
>
Companies</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
>
Infiltration</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
>
Factions</a
><br /><br />
<a
class="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
>
Augmentations</a
><br /><br />
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts</a
>
</div>
<!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"></div> <div id="location-container" class="generic-menupage-container"></div>
<div id="infiltration-container" class="generic-fullscreen-container"></div> <div id="infiltration-container" class="generic-fullscreen-container"></div>
<div id="stock-market-container" class="generic-menupage-container"></div> <div id="stock-market-container" class="generic-menupage-container"></div>
@ -403,19 +201,6 @@
</div> </div>
</div> </div>
<!-- End of Infiltration pop up box -->
<div id="infiltration-box-container" class="popup-box-container">
<div id="infiltration-box-content" class="popup-box-content">
<p id="infiltration-box-text"></p>
<button id="infiltration-box-sell" class="a-link-button">Sell on Black Market</button>
<br /><br />
<select id="infiltration-faction-select" class="dropdown"></select>
<br />
<button id="infiltration-box-faction" class="a-link-button">Give to Faction for Reputation</button>
</div>
</div>
<!-- Mission container --> <!-- Mission container -->
<div id="mission-container" class="generic-fullscreen-container"></div> <div id="mission-container" class="generic-fullscreen-container"></div>