mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-29 12:27:07 +02:00
Began implementing Sleeve UI page
This commit is contained in:
@@ -51,14 +51,6 @@ export interface ICrime {
|
||||
kills: number;
|
||||
}
|
||||
|
||||
// Interface for Faction object
|
||||
// Used because at the time of implementation, the Faction object has not been
|
||||
// converted to TypeScript
|
||||
export interface IFaction {
|
||||
name: string;
|
||||
playerReputation: number;
|
||||
}
|
||||
|
||||
// Interface that defines a generic object used to track experience/money
|
||||
// earnings for tasks
|
||||
export interface ITaskTracker {
|
||||
@@ -129,6 +121,12 @@ export abstract class Person {
|
||||
|
||||
work_money_mult: number;
|
||||
|
||||
/**
|
||||
* Augmentations
|
||||
*/
|
||||
this.augmentations = [];
|
||||
this.queuedAugmentations = [];
|
||||
|
||||
/**
|
||||
* City that the person is in
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Sleeves are clones of the player that can be used to perform
|
||||
* different tasks synchronously.
|
||||
* Sleeves are bodies that contain the player's cloned consciousness.
|
||||
* The player can use these bodies to perform different tasks synchronously.
|
||||
*
|
||||
* Each sleeve is its own individual, meaning it has its own stats/exp
|
||||
*
|
||||
@@ -11,7 +11,6 @@ import { SleeveTaskType } from "./SleeveTaskTypesEnum";
|
||||
import { Person,
|
||||
IPlayer,
|
||||
ICrime,
|
||||
IFaction,
|
||||
ITaskTracker,
|
||||
createTaskTracker } from "../Person";
|
||||
|
||||
@@ -101,6 +100,8 @@ export class Sleeve extends Person {
|
||||
* Sleeve shock. Number between 1 and 100
|
||||
* Trauma/shock that comes with being in a sleeve. Experience earned
|
||||
* is multipled by shock%. This gets applied before synchronization
|
||||
*
|
||||
* Reputation earned is also multiplied by shock%
|
||||
*/
|
||||
shock: number = 1;
|
||||
|
||||
@@ -251,6 +252,7 @@ export class Sleeve extends Person {
|
||||
* Earn money for player
|
||||
*/
|
||||
gainMoney(p: IPlayer, task: ITaskTracker, numCycles: number=1): void {
|
||||
this.earningsForPlayer.money += (task.money * numCycles);
|
||||
p.gainMoney(task.money * numCycles);
|
||||
}
|
||||
|
||||
@@ -262,17 +264,17 @@ export class Sleeve extends Person {
|
||||
if (this.currentTask === SleeveTaskType.Faction) {
|
||||
switch (this.factionWorkType) {
|
||||
case FactionWorkType.Hacking:
|
||||
return this.getFactionHackingWorkRepGain();
|
||||
return this.getFactionHackingWorkRepGain() * (this.shock / 100);
|
||||
case FactionWorkType.Field:
|
||||
return this.getFactionFieldWorkRepGain();
|
||||
return this.getFactionFieldWorkRepGain() * (this.shock / 100);
|
||||
case FactionWorkType.Security:
|
||||
return this.getFactionSecurityWorkRepGain();
|
||||
return this.getFactionSecurityWorkRepGain() * (this.shock / 100);
|
||||
default:
|
||||
console.warn(`Invalid Sleeve.factionWorkType property in Sleeve.getRepGain(): ${this.factionWorkType}`);
|
||||
return 0;
|
||||
}
|
||||
} else if (this.currentTask === SleeveTaskType.Company) {
|
||||
return 0;
|
||||
return 0; // TODO
|
||||
} else {
|
||||
console.warn(`Sleeve.getRepGain() called for invalid task type: ${this.currentTask}`);
|
||||
return 0;
|
||||
@@ -327,16 +329,21 @@ export class Sleeve extends Person {
|
||||
retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed);
|
||||
this.gainMoney(p, this.gainRatesForTask, cyclesUsed);
|
||||
|
||||
// TODO REP for both this and company
|
||||
const fac = Factions[this.currentTaskLocation];
|
||||
// Gain faction reputation
|
||||
const fac: Faction = Factions[this.currentTaskLocation];
|
||||
if (!(fac instanceof Faction)) {
|
||||
console.error(`Invalid faction for Sleeve task: ${this.currentTaskLocation}`);
|
||||
break;
|
||||
}
|
||||
|
||||
const repGainPerCycle: number = this.getRepGain();
|
||||
fac.playerReputation += (repGainPerCycle * cyclesUsed);
|
||||
break;
|
||||
case SleeveTaskType.Company:
|
||||
retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed);
|
||||
this.gainMoney(p, this.gainRatesForTask, cyclesUsed);
|
||||
|
||||
// TODO Rep gain for this
|
||||
break;
|
||||
case SleeveTaskType.Recovery:
|
||||
this.shock = Math.max(100, this.shock + (0.001 * this.storedCycles));
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Module for handling the Sleeve UI
|
||||
*/
|
||||
import { Sleeve } from "./Sleeve";
|
||||
import { SleeveTaskType } from "./SleeveTaskTypesEnum";
|
||||
|
||||
import { IMap } from "../../types";
|
||||
|
||||
import { Page,
|
||||
routing } from "../../ui/navigationTracking";
|
||||
|
||||
import { exceptionAlert } from "../../../utils/helpers/exceptionAlert";
|
||||
|
||||
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||
import { removeElement } from "../../../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
// Object that keeps track of all DOM elements for the UI for a single Sleeve
|
||||
interface ISleeveUIElems {
|
||||
container: Element | null,
|
||||
statsPanel: Element | null,
|
||||
stats: Element | null,
|
||||
statsTooltip: Element | null,
|
||||
taskPanel: Element | null,
|
||||
taskSelector: Element | null,
|
||||
taskDetailsSelector: Element | null,
|
||||
taskDescription: Element | null,
|
||||
earningsPanel: Element | null,
|
||||
currentEarningsInfo: Element | null,
|
||||
totalEarningsInfo: Element | null,
|
||||
}
|
||||
|
||||
// Object that keeps track of all DOM elements for the entire Sleeve UI
|
||||
interface IPageUIElems {
|
||||
container: Element | null;
|
||||
info: Element | null,
|
||||
sleeveList: Element | null,
|
||||
sleeves: ISleeveUIElems[] | null,
|
||||
}
|
||||
|
||||
const UIElems: IPageUIElems = {
|
||||
container: null,
|
||||
info: null,
|
||||
sleeveList: null,
|
||||
sleeves: null,
|
||||
}
|
||||
|
||||
// Interface for Player object
|
||||
interface IPlayer {
|
||||
sleeves: Sleeve[];
|
||||
}
|
||||
|
||||
// Creates the UI for the entire Sleeves page
|
||||
export function createSleevesPage(p: IPlayer) {
|
||||
if (!routing.isOn(Page.Sleeves)) { return; }
|
||||
|
||||
try {
|
||||
UIElems.container = createElement("div", {
|
||||
class: "generic-menupage-container",
|
||||
id: "sleeves-container",
|
||||
position: "fixed",
|
||||
});
|
||||
|
||||
UIElems.info = createElement("p", {
|
||||
display: "inline-block",
|
||||
innerText: "Sleeves are MK-V Synthoids (synthetic androids) into which your " +
|
||||
"consciousness has copied. In other words, these Synthoids contain " +
|
||||
"a perfect duplicate of your mind.<br><br>" +
|
||||
"Sleeves can be used to perform different tasks synchronously.",
|
||||
});
|
||||
|
||||
UIElems.sleeveList = createElement("ul");
|
||||
UIElems.sleeves = [];
|
||||
|
||||
for (const sleeve of p.sleeves) {
|
||||
UIElems.sleeves.push(this.createSleeveUi(sleeve, p.sleeves));
|
||||
}
|
||||
|
||||
UIElems.container.appendChild(UIElems.info);
|
||||
UIElems.container.appendChild(UIElems.sleeveList);
|
||||
|
||||
document.getElementById("entire-game-container")!.appendChild(UIElems.container);
|
||||
} catch(e) {
|
||||
exceptionAlert(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the UI for the entire Sleeves page
|
||||
export function updateSleevesPage() {
|
||||
if (!routing.isOn(Page.Sleeves)) { return; }
|
||||
}
|
||||
|
||||
export function clearSleevesPage() {
|
||||
removeElement(UIElems.container);
|
||||
for (const prop in UIElems) {
|
||||
UIElems[prop] = 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[]) {
|
||||
if (!routing.isOn(Page.Sleeves)) { return; }
|
||||
|
||||
const elems: ISleeveUIElems = {
|
||||
container: null,
|
||||
statsPanel: null,
|
||||
stats: null,
|
||||
statsTooltip: null,
|
||||
taskPanel: null,
|
||||
taskSelector: null,
|
||||
taskDetailsSelector: null,
|
||||
taskDescription: null,
|
||||
earningsPanel: null,
|
||||
currentEarningsInfo: null,
|
||||
totalEarningsButton: null,
|
||||
}
|
||||
|
||||
elems.container = createElement("div", {
|
||||
class: "sleeve-container",
|
||||
display: "block",
|
||||
});
|
||||
|
||||
elems.statsPanel = createElement("div", { class: "sleeve-panel" });
|
||||
elems.stats = createElement("p", { class: "sleeve-stats-text tooltip" });
|
||||
elems.statsTooltip = createElement("span", { class: "tooltiptext" });
|
||||
elems.stats.appendChild(elems.statsTooltip);
|
||||
elems.statsPanel.appendChild(elems.stats);
|
||||
|
||||
elems.taskPanel = createElement("div", { class: "sleeve-panel" });
|
||||
elems.taskSelector = createElement("select");
|
||||
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.taskSelector.addEventListener("change", () => {
|
||||
updateSleeveTaskSelector(sleeve, elems, allSleeves);
|
||||
});
|
||||
// TODO Set initial value for task selector
|
||||
elems.taskDetailsSelector = createElement("select");
|
||||
elems.taskDescription = createElement("p");
|
||||
elems.taskPanel.appendChild(elems.taskSelector);
|
||||
elems.taskPanel.appendChild(elems.taskDetailsSelector);
|
||||
elems.taskPanel.appendChild(elems.taskDescription);
|
||||
|
||||
elems.earningsPanel = createElement("div", { class: "sleeve-panel" });
|
||||
elems.currentEarningsInfo = createElement("p");
|
||||
elems.totalEarningsButton = createElement("button", { class: "std-button" });
|
||||
|
||||
return elems;
|
||||
}
|
||||
|
||||
// Updates the UI for a single Sleeve
|
||||
function updateSleeveUi() {
|
||||
if (!routing.isOn(Page.Sleeves)) { return; }
|
||||
}
|
||||
|
||||
// Whenever a new task is selected, the "details" selector must update accordingly
|
||||
function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSleeves: Sleeve[]) {
|
||||
const value: string =
|
||||
}
|
||||
Reference in New Issue
Block a user