mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-24 15:12:27 +01:00
create program and grafting done
This commit is contained in:
parent
647392626e
commit
606f1bf6c4
@ -7,6 +7,7 @@ import { SpecialServers } from "../Server/data/SpecialServers";
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { DarkWebItem } from "./DarkWebItem";
|
||||
import { isCreateProgramWork } from "../Work/CreateProgramWork";
|
||||
|
||||
//Posts a "help" message if connected to DarkWeb
|
||||
export function checkIfConnectedToDarkweb(): void {
|
||||
@ -74,7 +75,7 @@ export function buyDarkwebItem(itemName: string): void {
|
||||
|
||||
Player.getHomeComputer().pushProgram(item.program);
|
||||
// Cancel if the program is in progress of writing
|
||||
if (Player.createProgramName === item.program) {
|
||||
if (isCreateProgramWork(Player.currentWork) && Player.currentWork.programName === item.program) {
|
||||
Player.isWorking = false;
|
||||
Player.resetWorkStatus();
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ export function SaveFile(): React.ReactElement {
|
||||
|
||||
function doRestore(): void {
|
||||
const save = JSON.parse(saveFile);
|
||||
console.log(Object.keys(save));
|
||||
// TODO: Continue here.
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ function initSaveFunctions(): void {
|
||||
try {
|
||||
saveObject.exportGame();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000);
|
||||
}
|
||||
},
|
||||
@ -199,7 +199,7 @@ function initElectronBridge(): void {
|
||||
bridge.send("save-completed");
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
SnackbarEvents.emit("Could not save game.", ToastVariant.ERROR, 2000);
|
||||
});
|
||||
});
|
||||
@ -207,7 +207,7 @@ function initElectronBridge(): void {
|
||||
try {
|
||||
window.appSaveFns.triggerGameExport();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000);
|
||||
}
|
||||
});
|
||||
@ -215,7 +215,7 @@ function initElectronBridge(): void {
|
||||
try {
|
||||
window.appSaveFns.triggerScriptsExport();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
SnackbarEvents.emit("Could not export scripts.", ToastVariant.ERROR, 2000);
|
||||
}
|
||||
});
|
||||
|
@ -252,7 +252,6 @@ export class Gang implements IGang {
|
||||
const total = Object.values(AllGangs)
|
||||
.map((g) => g.territory)
|
||||
.reduce((p, c) => p + c, 0);
|
||||
console.log(total);
|
||||
Object.values(AllGangs).forEach((g) => (g.territory /= total));
|
||||
}
|
||||
}
|
||||
|
@ -2418,8 +2418,6 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
||||
workChaExpGained: Player.workChaExpGained,
|
||||
workRepGained: Player.workRepGained,
|
||||
workMoneyGained: Player.workMoneyGained,
|
||||
createProgramName: Player.createProgramName,
|
||||
createProgramReqLvl: Player.createProgramReqLvl,
|
||||
work_money_mult: Player.work_money_mult,
|
||||
hacknet_node_money_mult: Player.hacknet_node_money_mult,
|
||||
hacknet_node_purchase_cost_mult: Player.hacknet_node_purchase_cost_mult,
|
||||
|
@ -7,6 +7,7 @@ import { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../Per
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Grafting as IGrafting } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Router } from "../ui/GameRoot";
|
||||
import { GraftingWork } from "../Work/GraftingWork";
|
||||
|
||||
export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
||||
const checkGraftingAPIAccess = (ctx: NetscriptContext): void => {
|
||||
@ -79,8 +80,13 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
||||
return false;
|
||||
}
|
||||
|
||||
player.loseMoney(craftableAug.cost, "augmentations");
|
||||
player.startGraftAugmentationWork(augName, craftableAug.time);
|
||||
player.startNEWWork(
|
||||
new GraftingWork({
|
||||
singularity: true,
|
||||
augmentation: augName,
|
||||
player: player,
|
||||
}),
|
||||
);
|
||||
|
||||
if (focus) {
|
||||
player.startFocusing();
|
||||
|
@ -51,6 +51,7 @@ import { enterBitNode } from "../RedPill";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { WorkType } from "../utils/WorkType";
|
||||
import { ClassWork, ClassType } from "../Work/ClassWork";
|
||||
import { CreateProgramWork, isCreateProgramWork } from "../Work/CreateProgramWork";
|
||||
|
||||
export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript): InternalAPI<ISingularity> {
|
||||
const getAugmentation = function (_ctx: NetscriptContext, name: string): Augmentation {
|
||||
@ -528,7 +529,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
|
||||
player.getHomeComputer().pushProgram(item.program);
|
||||
// Cancel if the program is in progress of writing
|
||||
if (player.createProgramName === item.program) {
|
||||
if (isCreateProgramWork(player.currentWork) && player.currentWork.programName === item.program) {
|
||||
player.isWorking = false;
|
||||
player.resetWorkStatus();
|
||||
}
|
||||
@ -1182,7 +1183,13 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
return false;
|
||||
}
|
||||
|
||||
player.startCreateProgramWork(p.name, create.time, create.level);
|
||||
player.startNEWWork(
|
||||
new CreateProgramWork({
|
||||
programName: p.name,
|
||||
singularity: true,
|
||||
player: player,
|
||||
}),
|
||||
);
|
||||
if (focus) {
|
||||
player.startFocusing();
|
||||
Router.toWork();
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CheckBox, CheckBoxOutlineBlank, Construction } from "@mui/icons-material";
|
||||
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { GraftingWork } from "../../../Work/GraftingWork";
|
||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
||||
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
||||
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
|
||||
@ -19,7 +20,7 @@ import { IPlayer } from "../../IPlayer";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
import { calculateGraftingTimeWithBonus, getGraftingAvailableAugs } from "../GraftingHelpers";
|
||||
|
||||
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
export const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
|
||||
const canGraft = (player: IPlayer, aug: GraftableAugmentation): boolean => {
|
||||
if (player.money < aug.cost) {
|
||||
@ -154,9 +155,13 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
open={graftOpen}
|
||||
onClose={() => setGraftOpen(false)}
|
||||
onConfirm={() => {
|
||||
const graftableAug = GraftableAugmentations[selectedAug];
|
||||
player.loseMoney(graftableAug.cost, "augmentations");
|
||||
player.startGraftAugmentationWork(selectedAug, graftableAug.time);
|
||||
player.startNEWWork(
|
||||
new GraftingWork({
|
||||
augmentation: selectedAug,
|
||||
singularity: false,
|
||||
player: player,
|
||||
}),
|
||||
);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
}}
|
||||
|
@ -126,12 +126,7 @@ export interface IPlayer extends IPerson {
|
||||
bladeburner_success_chance_mult: number;
|
||||
|
||||
currentWork: Work | null;
|
||||
createProgramReqLvl: number;
|
||||
factionWorkType: string;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
timeNeededToCompleteWork: number;
|
||||
focus: boolean;
|
||||
currentWorkFactionName: string;
|
||||
@ -227,7 +222,6 @@ export interface IPlayer extends IPerson {
|
||||
quitJob(company: string, sing?: boolean): void;
|
||||
hasJob(): boolean;
|
||||
createHacknetServer(): HacknetServer;
|
||||
startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
|
||||
queueAugmentation(augmentationName: string): void;
|
||||
receiveInvite(factionName: string): void;
|
||||
updateSkillLevels(): void;
|
||||
@ -237,7 +231,6 @@ export interface IPlayer extends IPerson {
|
||||
finishWork(cancelled: boolean, sing?: boolean): string;
|
||||
cancelationPenalty(): number;
|
||||
finishWorkPartTime(sing?: boolean): string;
|
||||
finishCreateProgramWork(cancelled: boolean): string;
|
||||
resetMultipliers(): void;
|
||||
prestigeAugmentation(): void;
|
||||
prestigeSourceFile(): void;
|
||||
@ -253,15 +246,11 @@ export interface IPlayer extends IPerson {
|
||||
getWorkMoneyGain(): number;
|
||||
processWorkEarnings(cycles: number): void;
|
||||
hospitalize(): void;
|
||||
createProgramWork(numCycles: number): boolean;
|
||||
checkForFactionInvitations(): Faction[];
|
||||
setBitNodeNumber(n: number): void;
|
||||
getMult(name: string): number;
|
||||
setMult(name: string, mult: number): void;
|
||||
canAccessCotMG(): boolean;
|
||||
sourceFileLvl(n: number): number;
|
||||
startGraftAugmentationWork(augmentationName: string, time: number): void;
|
||||
graftAugmentationWork(numCycles: number): boolean;
|
||||
finishGraftAugmentationWork(cancelled: boolean, singularity?: boolean): string;
|
||||
applyEntropy(stacks?: number): void;
|
||||
}
|
||||
|
@ -138,12 +138,7 @@ export class PlayerObject implements IPlayer {
|
||||
bladeburner_success_chance_mult: number;
|
||||
|
||||
currentWork: Work | null;
|
||||
createProgramReqLvl: number;
|
||||
factionWorkType: PlayerFactionWorkType;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
timeNeededToCompleteWork: number;
|
||||
focus: boolean;
|
||||
currentWorkFactionName: string;
|
||||
@ -252,7 +247,6 @@ export class PlayerObject implements IPlayer {
|
||||
hasJob: () => boolean;
|
||||
process: (router: IRouter, numCycles?: number) => void;
|
||||
createHacknetServer: () => HacknetServer;
|
||||
startCreateProgramWork: (programName: string, time: number, reqLevel: number) => void;
|
||||
queueAugmentation: (augmentationName: string) => void;
|
||||
receiveInvite: (factionName: string) => void;
|
||||
updateSkillLevels: () => void;
|
||||
@ -262,7 +256,6 @@ export class PlayerObject implements IPlayer {
|
||||
finishWork: (cancelled: boolean, sing?: boolean) => string;
|
||||
cancelationPenalty: () => number;
|
||||
finishWorkPartTime: (sing?: boolean) => string;
|
||||
finishCreateProgramWork: (cancelled: boolean) => string;
|
||||
resetMultipliers: () => void;
|
||||
prestigeAugmentation: () => void;
|
||||
prestigeSourceFile: () => void;
|
||||
@ -279,16 +272,12 @@ export class PlayerObject implements IPlayer {
|
||||
getWorkMoneyGain: () => number;
|
||||
processWorkEarnings: (cycles: number) => void;
|
||||
hospitalize: () => void;
|
||||
createProgramWork: (numCycles: number) => boolean;
|
||||
checkForFactionInvitations: () => Faction[];
|
||||
setBitNodeNumber: (n: number) => void;
|
||||
getMult: (name: string) => number;
|
||||
setMult: (name: string, mult: number) => void;
|
||||
canAccessCotMG: () => boolean;
|
||||
sourceFileLvl: (n: number) => number;
|
||||
startGraftAugmentationWork: (augmentationName: string, time: number) => void;
|
||||
graftAugmentationWork: (numCycles: number) => boolean;
|
||||
finishGraftAugmentationWork: (cancelled: boolean, singularity?: boolean) => string;
|
||||
applyEntropy: (stacks?: number) => void;
|
||||
|
||||
constructor() {
|
||||
@ -410,14 +399,7 @@ export class PlayerObject implements IPlayer {
|
||||
this.workRepGained = 0;
|
||||
this.workMoneyGained = 0;
|
||||
|
||||
this.createProgramName = "";
|
||||
this.createProgramReqLvl = 0;
|
||||
|
||||
this.graftAugmentationName = "";
|
||||
this.timeWorkedGraftAugmentation = 0;
|
||||
|
||||
this.timeWorked = 0; //in m;
|
||||
this.timeWorkedCreateProgram = 0;
|
||||
this.timeNeededToCompleteWork = 0;
|
||||
|
||||
this.work_money_mult = 1;
|
||||
@ -538,12 +520,6 @@ export class PlayerObject implements IPlayer {
|
||||
this.getWorkChaExpGain = generalMethods.getWorkChaExpGain;
|
||||
this.getWorkRepGain = generalMethods.getWorkRepGain;
|
||||
this.process = generalMethods.process;
|
||||
this.startCreateProgramWork = generalMethods.startCreateProgramWork;
|
||||
this.createProgramWork = generalMethods.createProgramWork;
|
||||
this.finishCreateProgramWork = generalMethods.finishCreateProgramWork;
|
||||
this.startGraftAugmentationWork = generalMethods.startGraftAugmentationWork;
|
||||
this.graftAugmentationWork = generalMethods.craftAugmentationWork;
|
||||
this.finishGraftAugmentationWork = generalMethods.finishGraftAugmentationWork;
|
||||
this.singularityStopWork = generalMethods.singularityStopWork;
|
||||
this.takeDamage = generalMethods.takeDamage;
|
||||
this.regenerateHp = generalMethods.regenerateHp;
|
||||
|
@ -66,9 +66,8 @@ import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { ITaskTracker } from "../ITaskTracker";
|
||||
import { IPerson } from "../IPerson";
|
||||
import { Player } from "../../Player";
|
||||
import { graftingIntBonus } from "../Grafting/GraftingHelpers";
|
||||
|
||||
import { WorkType, PlayerFactionWorkType, ClassType, CrimeType } from "../../utils/WorkType";
|
||||
import { WorkType, PlayerFactionWorkType } from "../../utils/WorkType";
|
||||
|
||||
export function init(this: IPlayer): void {
|
||||
/* Initialize Player's home computer */
|
||||
@ -143,7 +142,6 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
this.isWorking = false;
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
|
||||
this.workHackExpGainRate = 0;
|
||||
this.workStrExpGainRate = 0;
|
||||
@ -537,13 +535,9 @@ export function resetWorkStatus(this: IPlayer, generalType?: WorkType, group?: s
|
||||
this.workMoneyGained = 0;
|
||||
|
||||
this.timeWorked = 0;
|
||||
this.timeWorkedCreateProgram = 0;
|
||||
this.timeWorkedGraftAugmentation = 0;
|
||||
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.graftAugmentationName = "";
|
||||
this.workType = WorkType.None;
|
||||
}
|
||||
|
||||
@ -603,18 +597,10 @@ export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||
if (this.workForFaction(numCycles)) {
|
||||
router.toFaction(Factions[this.currentWorkFactionName]);
|
||||
}
|
||||
} else if (this.workType === WorkType.CreateProgram) {
|
||||
if (this.createProgramWork(numCycles)) {
|
||||
router.toTerminal();
|
||||
}
|
||||
} else if (this.workType === WorkType.CompanyPartTime) {
|
||||
if (this.workPartTime(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.workType === WorkType.GraftAugmentation) {
|
||||
if (this.graftAugmentationWork(numCycles)) {
|
||||
router.toGrafting();
|
||||
}
|
||||
} else if (this.work(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
@ -1257,143 +1243,6 @@ export function getWorkRepGain(this: IPlayer): number {
|
||||
// return t * this.faction_rep_mult;
|
||||
// }
|
||||
|
||||
/* Creating a Program */
|
||||
export function startCreateProgramWork(this: IPlayer, programName: string, time: number, reqLevel: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = WorkType.CreateProgram;
|
||||
|
||||
//Time needed to complete work affected by hacking skill (linearly based on
|
||||
//ratio of (your skill - required level) to MAX skill)
|
||||
//var timeMultiplier = (CONSTANTS.MaxSkillLevel - (this.hacking - reqLevel)) / CONSTANTS.MaxSkillLevel;
|
||||
//if (timeMultiplier > 1) {timeMultiplier = 1;}
|
||||
//if (timeMultiplier < 0.01) {timeMultiplier = 0.01;}
|
||||
this.createProgramReqLvl = reqLevel;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
//Check for incomplete program
|
||||
for (let i = 0; i < this.getHomeComputer().programs.length; ++i) {
|
||||
const programFile = this.getHomeComputer().programs[i];
|
||||
if (programFile.startsWith(programName) && programFile.endsWith("%-INC")) {
|
||||
const res = programFile.split("-");
|
||||
if (res.length != 3) {
|
||||
break;
|
||||
}
|
||||
const percComplete = Number(res[1].slice(0, -1));
|
||||
if (isNaN(percComplete) || percComplete < 0 || percComplete >= 100) {
|
||||
break;
|
||||
}
|
||||
this.timeWorkedCreateProgram = (percComplete / 100) * this.timeNeededToCompleteWork;
|
||||
this.getHomeComputer().programs.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.createProgramName = programName;
|
||||
}
|
||||
|
||||
export function createProgramWork(this: IPlayer, numCycles: number): boolean {
|
||||
let focusBonus = 1;
|
||||
if (!this.hasAugmentation(AugmentationNames["NeuroreceptorManager"])) {
|
||||
focusBonus = this.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
//Higher hacking skill will allow you to create programs faster
|
||||
const reqLvl = this.createProgramReqLvl;
|
||||
let skillMult = (this.hacking / reqLvl) * this.getIntelligenceBonus(3); //This should always be greater than 1;
|
||||
skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary
|
||||
skillMult *= focusBonus;
|
||||
//Skill multiplier directly applied to "time worked"
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
this.timeWorkedCreateProgram += CONSTANTS._idleSpeed * numCycles * skillMult;
|
||||
|
||||
if (this.timeWorkedCreateProgram >= this.timeNeededToCompleteWork) {
|
||||
this.finishCreateProgramWork(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): string {
|
||||
const programName = this.createProgramName;
|
||||
let message = "";
|
||||
if (!cancelled) {
|
||||
//Complete case
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
const lines = [`You've finished creating ${programName}!`, "The new program can be found on your home computer."];
|
||||
dialogBoxCreate(lines.join("<br>"));
|
||||
message = lines.join(" ");
|
||||
|
||||
if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
this.getHomeComputer().programs.push(programName);
|
||||
}
|
||||
} else if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
//Incomplete case
|
||||
const perc = (Math.floor((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 10000) / 100).toString();
|
||||
const incompleteName = programName + "-" + perc + "%-INC";
|
||||
this.getHomeComputer().programs.push(incompleteName);
|
||||
message = `Cancelled creating program: ${programName} (${perc}% complete)`;
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
this.resetWorkStatus();
|
||||
return message;
|
||||
}
|
||||
|
||||
export function startGraftAugmentationWork(this: IPlayer, augmentationName: string, time: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = WorkType.GraftAugmentation;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
this.graftAugmentationName = augmentationName;
|
||||
}
|
||||
|
||||
export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean {
|
||||
let focusBonus = 1;
|
||||
if (!this.hasAugmentation(AugmentationNames.NeuroreceptorManager)) {
|
||||
focusBonus = this.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
|
||||
let skillMult = graftingIntBonus(this);
|
||||
skillMult *= focusBonus;
|
||||
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
this.timeWorkedGraftAugmentation += CONSTANTS._idleSpeed * numCycles * skillMult;
|
||||
|
||||
if (this.timeWorkedGraftAugmentation >= this.timeNeededToCompleteWork) {
|
||||
this.finishGraftAugmentationWork(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, singularity = false): string {
|
||||
const augName = this.graftAugmentationName;
|
||||
if (cancelled === false) {
|
||||
applyAugmentation({ name: augName, level: 1 });
|
||||
|
||||
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
||||
this.entropy += 1;
|
||||
this.applyEntropy(this.entropy);
|
||||
}
|
||||
|
||||
dialogBoxCreate(
|
||||
`You've finished grafting ${augName}.<br>The augmentation has been applied to your body` +
|
||||
(this.hasAugmentation(AugmentationNames.CongruityImplant) ? "." : ", but you feel a bit off."),
|
||||
);
|
||||
} else if (cancelled && singularity === false) {
|
||||
dialogBoxCreate(`You cancelled the grafting of ${augName}.<br>Your money was not returned to you.`);
|
||||
}
|
||||
|
||||
// Intelligence gain
|
||||
if (!cancelled) {
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceGraftBaseExpGain * this.timeWorked) / 10000);
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
this.resetWorkStatus();
|
||||
return `Grafting of ${augName} has ended.`;
|
||||
}
|
||||
|
||||
//Cancels the player's current "work" assignment and gives the proper rewards
|
||||
//Used only for Singularity functions, so no popups are created
|
||||
export function singularityStopWork(this: IPlayer): string {
|
||||
@ -1414,12 +1263,6 @@ export function singularityStopWork(this: IPlayer): string {
|
||||
case WorkType.Faction:
|
||||
res = this.finishFactionWork(true, true);
|
||||
break;
|
||||
case WorkType.CreateProgram:
|
||||
res = this.finishCreateProgramWork(true);
|
||||
break;
|
||||
case WorkType.GraftAugmentation:
|
||||
res = this.finishGraftAugmentationWork(true, true);
|
||||
break;
|
||||
default:
|
||||
console.error(`Unrecognized work type (${this.workType})`);
|
||||
return "";
|
||||
|
@ -8,6 +8,7 @@ import { use } from "../../ui/Context";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
|
||||
import { Programs } from "../Programs";
|
||||
import { CreateProgramWork } from "../../Work/CreateProgramWork";
|
||||
|
||||
export const ProgramsSeen: string[] = [];
|
||||
|
||||
@ -96,7 +97,9 @@ export function ProgramsRoot(): React.ReactElement {
|
||||
sx={{ my: 1, width: "100%" }}
|
||||
onClick={(event) => {
|
||||
if (!event.isTrusted) return;
|
||||
player.startCreateProgramWork(program.name, create.time, create.level);
|
||||
player.startNEWWork(
|
||||
new CreateProgramWork({ player: player, singularity: false, programName: program.name }),
|
||||
);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
}}
|
||||
|
@ -199,7 +199,7 @@ class BitburnerSaveObject {
|
||||
try {
|
||||
parsedSave = JSON.parse(newSave);
|
||||
} catch (error) {
|
||||
console.log(error); // We'll handle below
|
||||
console.error(error); // We'll handle below
|
||||
}
|
||||
|
||||
if (!parsedSave || parsedSave.ctor !== "BitburnerSaveObject" || !parsedSave.data) {
|
||||
|
2
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
2
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -68,8 +68,6 @@ interface Player {
|
||||
workChaExpGained: number;
|
||||
workRepGained: number;
|
||||
workMoneyGained: number;
|
||||
createProgramName: string;
|
||||
createProgramReqLvl: number;
|
||||
work_money_mult: number;
|
||||
hacknet_node_money_mult: number;
|
||||
hacknet_node_purchase_cost_mult: number;
|
||||
|
@ -46,7 +46,6 @@ export function GetServer(s: string): BaseServer | null {
|
||||
const server = AllServers[s];
|
||||
if (server) return server;
|
||||
}
|
||||
console.log(AllServers);
|
||||
|
||||
if (!isValidIPAddress(s)) {
|
||||
return GetServerByHostname(s);
|
||||
|
@ -126,8 +126,6 @@ interface ClassWorkParams {
|
||||
export const isClassWork = (w: Work | null): w is ClassWork => w !== null && w.type === WorkType.CLASS;
|
||||
|
||||
export class ClassWork extends Work {
|
||||
type = WorkType.CLASS;
|
||||
|
||||
classType: ClassType;
|
||||
location: LocationName;
|
||||
cyclesWorked: number;
|
||||
@ -135,7 +133,7 @@ export class ClassWork extends Work {
|
||||
earnings = newWorkStats();
|
||||
|
||||
constructor(params?: ClassWorkParams) {
|
||||
super();
|
||||
super(WorkType.CLASS);
|
||||
this.classType = params?.classType ?? ClassType.StudyComputerScience;
|
||||
this.location = params?.location ?? LocationName.Sector12RothmanUniversity;
|
||||
this.singularity = params?.singularity ?? false;
|
||||
|
125
src/Work/CreateProgramWork.ts
Normal file
125
src/Work/CreateProgramWork.ts
Normal file
@ -0,0 +1,125 @@
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Programs } from "../Programs/Programs";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { Program } from "../Programs/Program";
|
||||
|
||||
export const isCreateProgramWork = (w: Work | null): w is CreateProgramWork =>
|
||||
w !== null && w.type === WorkType.CREATE_PROGRAM;
|
||||
|
||||
interface CreateProgramWorkParams {
|
||||
programName: string;
|
||||
singularity: boolean;
|
||||
player: IPlayer;
|
||||
}
|
||||
|
||||
export class CreateProgramWork extends Work {
|
||||
programName: string;
|
||||
// amount of cycles spent doing this task
|
||||
cyclesWorked: number;
|
||||
singularity: boolean;
|
||||
// amount of effective work completed on the program (time boosted by skills).
|
||||
unitCompleted: number;
|
||||
|
||||
constructor(params?: CreateProgramWorkParams) {
|
||||
super(WorkType.CREATE_PROGRAM);
|
||||
this.cyclesWorked = 0;
|
||||
this.unitCompleted = 0;
|
||||
this.programName = params?.programName ?? "";
|
||||
this.singularity = params?.singularity ?? false;
|
||||
|
||||
if (params?.player) {
|
||||
const player = params.player;
|
||||
for (let i = 0; i < player.getHomeComputer().programs.length; ++i) {
|
||||
const programFile = player.getHomeComputer().programs[i];
|
||||
if (programFile.startsWith(this.programName) && programFile.endsWith("%-INC")) {
|
||||
const res = programFile.split("-");
|
||||
if (res.length != 3) {
|
||||
break;
|
||||
}
|
||||
const percComplete = Number(res[1].slice(0, -1));
|
||||
if (isNaN(percComplete) || percComplete < 0 || percComplete >= 100) {
|
||||
break;
|
||||
}
|
||||
this.unitCompleted = (percComplete / 100) * this.unitNeeded();
|
||||
player.getHomeComputer().programs.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unitNeeded(): number {
|
||||
return this.getProgram().create?.time ?? 0;
|
||||
}
|
||||
|
||||
getProgram(): Program {
|
||||
const p = Object.values(Programs).find((p) => p.name.toLowerCase() === this.programName.toLowerCase());
|
||||
if (!p) throw new Error("Create program work started with invalid program " + this.programName);
|
||||
return p;
|
||||
}
|
||||
|
||||
process(player: IPlayer, cycles: number): boolean {
|
||||
let focusBonus = 1;
|
||||
if (!player.hasAugmentation(AugmentationNames["NeuroreceptorManager"])) {
|
||||
focusBonus = player.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
//Higher hacking skill will allow you to create programs faster
|
||||
const reqLvl = this.getProgram().create?.level ?? 0;
|
||||
let skillMult = (player.hacking / reqLvl) * player.getIntelligenceBonus(3); //This should always be greater than 1;
|
||||
skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary
|
||||
skillMult *= focusBonus;
|
||||
//Skill multiplier directly applied to "time worked"
|
||||
this.cyclesWorked += cycles;
|
||||
this.unitCompleted += CONSTANTS._idleSpeed * cycles * skillMult;
|
||||
|
||||
if (this.unitCompleted >= this.unitNeeded()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
finish(player: IPlayer, cancelled: boolean): void {
|
||||
const programName = this.programName;
|
||||
if (!cancelled) {
|
||||
//Complete case
|
||||
player.gainIntelligenceExp(
|
||||
(CONSTANTS.IntelligenceProgramBaseExpGain * this.cyclesWorked * CONSTANTS._idleSpeed) / 1000,
|
||||
);
|
||||
if (!this.singularity) {
|
||||
const lines = [
|
||||
`You've finished creating ${programName}!`,
|
||||
"The new program can be found on your home computer.",
|
||||
];
|
||||
dialogBoxCreate(lines.join("<br>"));
|
||||
}
|
||||
|
||||
if (!player.getHomeComputer().programs.includes(programName)) {
|
||||
player.getHomeComputer().programs.push(programName);
|
||||
}
|
||||
} else if (!player.getHomeComputer().programs.includes(programName)) {
|
||||
//Incomplete case
|
||||
const perc = ((100 * this.unitCompleted) / this.unitNeeded()).toFixed(2);
|
||||
const incompleteName = programName + "-" + perc + "%-INC";
|
||||
player.getHomeComputer().programs.push(incompleteName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("CreateProgramWork", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiatizes a CreateProgramWork object from a JSON save state.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
static fromJSON(value: any): CreateProgramWork {
|
||||
return Generic_fromJSON(CreateProgramWork, value.data);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.CreateProgramWork = CreateProgramWork;
|
@ -19,14 +19,12 @@ interface CrimeWorkParams {
|
||||
export const isCrimeWork = (w: Work | null): w is CrimeWork => w !== null && w.type === WorkType.CRIME;
|
||||
|
||||
export class CrimeWork extends Work {
|
||||
type = WorkType.CRIME;
|
||||
|
||||
crimeType: CrimeType;
|
||||
cyclesWorked: number;
|
||||
singularity: boolean;
|
||||
|
||||
constructor(params?: CrimeWorkParams) {
|
||||
super();
|
||||
super(WorkType.CRIME);
|
||||
this.crimeType = params?.crimeType ?? CrimeType.Shoplift;
|
||||
this.singularity = params?.singularity ?? false;
|
||||
this.cyclesWorked = 0;
|
||||
|
106
src/Work/GraftingWork.tsx
Normal file
106
src/Work/GraftingWork.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import React from "react";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { GraftableAugmentations } from "../PersonObjects/Grafting/ui/GraftingRoot";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { graftingIntBonus } from "../PersonObjects/Grafting/GraftingHelpers";
|
||||
import { applyAugmentation } from "../Augmentation/AugmentationHelpers";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation";
|
||||
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||
|
||||
export const isGraftingWork = (w: Work | null): w is GraftingWork => w !== null && w.type === WorkType.GRAFTING;
|
||||
|
||||
interface GraftingWorkParams {
|
||||
augmentation: string;
|
||||
singularity: boolean;
|
||||
player: IPlayer;
|
||||
}
|
||||
|
||||
export class GraftingWork extends Work {
|
||||
augmentation: string;
|
||||
singularity: boolean;
|
||||
cyclesWorked: number;
|
||||
unitCompleted: number;
|
||||
|
||||
constructor(params?: GraftingWorkParams) {
|
||||
super(WorkType.GRAFTING);
|
||||
this.cyclesWorked = 0;
|
||||
this.unitCompleted = 0;
|
||||
this.augmentation = params?.augmentation ?? AugmentationNames.Targeting1;
|
||||
this.singularity = params?.singularity ?? false;
|
||||
if (params?.player) params.player.loseMoney(GraftableAugmentations[this.augmentation].cost, "augmentations");
|
||||
}
|
||||
|
||||
unitNeeded(): number {
|
||||
return new GraftableAugmentation(StaticAugmentations[this.augmentation]).time;
|
||||
}
|
||||
|
||||
process(player: IPlayer, cycles: number): boolean {
|
||||
let focusBonus = 1;
|
||||
if (!player.hasAugmentation(AugmentationNames.NeuroreceptorManager)) {
|
||||
focusBonus = player.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
|
||||
this.cyclesWorked += cycles;
|
||||
this.unitCompleted += CONSTANTS._idleSpeed * cycles * graftingIntBonus(player) * focusBonus;
|
||||
|
||||
return this.unitCompleted >= this.unitNeeded();
|
||||
}
|
||||
|
||||
finish(player: IPlayer, cancelled: boolean): void {
|
||||
const augName = this.augmentation;
|
||||
if (!cancelled) {
|
||||
applyAugmentation({ name: augName, level: 1 });
|
||||
|
||||
if (!player.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
||||
player.entropy += 1;
|
||||
player.applyEntropy(player.entropy);
|
||||
}
|
||||
|
||||
if (!this.singularity) {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
You've finished grafting {augName}.<br />
|
||||
The augmentation has been applied to your body{" "}
|
||||
{player.hasAugmentation(AugmentationNames.CongruityImplant) ? "." : ", but you feel a bit off."}
|
||||
</>,
|
||||
);
|
||||
}
|
||||
} else if (cancelled && !this.singularity) {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
You cancelled the grafting of {augName}.
|
||||
<br />
|
||||
Your money was not returned to you.
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
// Intelligence gain
|
||||
if (!cancelled) {
|
||||
player.gainIntelligenceExp(
|
||||
(CONSTANTS.IntelligenceGraftBaseExpGain * this.cyclesWorked * CONSTANTS._idleSpeed) / 10000,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("GraftingWork", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiatizes a GraftingWork object from a JSON save state.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
static fromJSON(value: any): GraftingWork {
|
||||
return Generic_fromJSON(GraftingWork, value.data);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.GraftingWork = GraftingWork;
|
@ -1,13 +1,20 @@
|
||||
import { IPlayer } from "src/PersonObjects/IPlayer";
|
||||
|
||||
export abstract class Work {
|
||||
abstract type: WorkType;
|
||||
type: WorkType;
|
||||
|
||||
constructor(type: WorkType) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
abstract process(player: IPlayer, cycles: number): boolean;
|
||||
abstract finish(player: IPlayer, cancelled: boolean): void;
|
||||
abstract toJSON(): any;
|
||||
}
|
||||
|
||||
export enum WorkType {
|
||||
CRIME = "CRIME",
|
||||
CLASS = "CLASS",
|
||||
CREATE_PROGRAM = "CREATE_PROGRAM",
|
||||
GRAFTING = "GRAFTING",
|
||||
}
|
||||
|
@ -306,15 +306,9 @@ const Engine: {
|
||||
case WorkType.Faction:
|
||||
Player.workForFaction(numCyclesOffline);
|
||||
break;
|
||||
case WorkType.CreateProgram:
|
||||
Player.createProgramWork(numCyclesOffline);
|
||||
break;
|
||||
case WorkType.CompanyPartTime:
|
||||
Player.workPartTime(numCyclesOffline);
|
||||
break;
|
||||
case WorkType.GraftAugmentation:
|
||||
Player.graftAugmentationWork(numCyclesOffline);
|
||||
break;
|
||||
default:
|
||||
Player.work(numCyclesOffline);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
|
||||
Router[fnName] = _wrap(Router[fnName], (func, ...args) => {
|
||||
if (!allowRoutingCalls) {
|
||||
// Let's just log to console.
|
||||
console.log(`Routing is currently disabled - Attempted router.${fnName}()`);
|
||||
console.error(`Routing is currently disabled - Attempted router.${fnName}()`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ export function AlertManager(): React.ReactElement {
|
||||
setAlerts((old) => {
|
||||
const hash = getMessageHash(text);
|
||||
if (old.some((a) => a.hash === hash)) {
|
||||
console.log("Duplicate message");
|
||||
return old;
|
||||
}
|
||||
return [
|
||||
|
@ -29,6 +29,8 @@ import { Box, Tooltip } from "@mui/material";
|
||||
import { WorkType } from "../../utils/WorkType";
|
||||
import { isClassWork } from "../../Work/ClassWork";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { isCreateProgramWork } from "../../Work/CreateProgramWork";
|
||||
import { isGraftingWork } from "../../Work/GraftingWork";
|
||||
|
||||
interface IProps {
|
||||
save: () => void;
|
||||
@ -150,6 +152,26 @@ function Work(): React.ReactElement {
|
||||
header = <>You are {player.currentWork.getClass().youAreCurrently}</>;
|
||||
innerText = <>{convertTimeMsToTimeElapsedString(player.currentWork.cyclesWorked * CONSTANTS._idleSpeed)}</>;
|
||||
}
|
||||
if (isCreateProgramWork(player.currentWork)) {
|
||||
const create = player.currentWork;
|
||||
details = <>Coding {create.programName}</>;
|
||||
header = <>Creating a program</>;
|
||||
innerText = (
|
||||
<>
|
||||
{create.programName} {((create.unitCompleted / create.unitNeeded()) * 100).toFixed(2)}%
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (isGraftingWork(player.currentWork)) {
|
||||
const graft = player.currentWork;
|
||||
details = <>Grafting {graft.augmentation}</>;
|
||||
header = <>Grafting an Augmentation</>;
|
||||
innerText = (
|
||||
<>
|
||||
<strong>{((graft.unitCompleted / graft.unitNeeded()) * 100).toFixed(2)}%</strong> done
|
||||
</>
|
||||
);
|
||||
}
|
||||
switch (player.workType) {
|
||||
case WorkType.CompanyPartTime:
|
||||
case WorkType.Company:
|
||||
@ -186,25 +208,6 @@ function Work(): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case WorkType.CreateProgram:
|
||||
details = <>Coding {player.createProgramName}</>;
|
||||
header = <>Creating a program</>;
|
||||
innerText = (
|
||||
<>
|
||||
{player.createProgramName}{" "}
|
||||
{((player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100).toFixed(2)}%
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case WorkType.GraftAugmentation:
|
||||
details = <>Grafting {player.graftAugmentationName}</>;
|
||||
header = <>Grafting an Augmentation</>;
|
||||
innerText = (
|
||||
<>
|
||||
<strong>{((player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}%</strong>{" "}
|
||||
done
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -22,7 +22,9 @@ import { StatsRow } from "./React/StatsRow";
|
||||
import { WorkType, ClassType } from "../utils/WorkType";
|
||||
import { isCrimeWork } from "../Work/CrimeWork";
|
||||
import { isClassWork } from "../Work/ClassWork";
|
||||
import { WorkStats } from "src/Work/WorkStats";
|
||||
import { WorkStats } from "../Work/WorkStats";
|
||||
import { isCreateProgramWork } from "../Work/CreateProgramWork";
|
||||
import { isGraftingWork } from "../Work/GraftingWork";
|
||||
|
||||
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
|
||||
|
||||
@ -301,6 +303,76 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
stopText: stopText,
|
||||
};
|
||||
}
|
||||
|
||||
if (isCreateProgramWork(player.currentWork)) {
|
||||
const create = player.currentWork;
|
||||
function cancel(): void {
|
||||
player.finishNEWWork(true);
|
||||
router.toTerminal();
|
||||
}
|
||||
function unfocus(): void {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
|
||||
const completion = (create.unitCompleted / create.unitNeeded()) * 100;
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on coding <b>{create.programName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
progress: {
|
||||
elapsed: create.cyclesWorked * CONSTANTS._idleSpeed,
|
||||
percentage: completion,
|
||||
},
|
||||
|
||||
stopText: "Stop creating program",
|
||||
stopTooltip: "Your work will be saved and you can return to complete the program later.",
|
||||
};
|
||||
}
|
||||
|
||||
if (isGraftingWork(player.currentWork)) {
|
||||
const graft = player.currentWork;
|
||||
function cancel(): void {
|
||||
player.finishNEWWork(true);
|
||||
router.toTerminal();
|
||||
}
|
||||
function unfocus(): void {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on grafting <b>{graft.augmentation}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
progress: {
|
||||
elapsed: graft.cyclesWorked * CONSTANTS._idleSpeed,
|
||||
percentage: (graft.unitCompleted / graft.unitNeeded()) * 100,
|
||||
},
|
||||
|
||||
stopText: "Stop grafting",
|
||||
stopTooltip: (
|
||||
<>
|
||||
If you cancel, your work will <b>not</b> be saved, and the money you spent will <b>not</b> be returned
|
||||
</>
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
switch (player.workType) {
|
||||
@ -509,80 +581,6 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
break;
|
||||
}
|
||||
|
||||
case WorkType.CreateProgram: {
|
||||
function cancel(): void {
|
||||
player.finishCreateProgramWork(true);
|
||||
router.toTerminal();
|
||||
}
|
||||
function unfocus(): void {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
|
||||
const completion = (player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100;
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on coding <b>{player.createProgramName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
progress: {
|
||||
elapsed: player.timeWorked,
|
||||
percentage: completion,
|
||||
},
|
||||
|
||||
stopText: "Stop creating program",
|
||||
stopTooltip: "Your work will be saved and you can return to complete the program later.",
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WorkType.GraftAugmentation: {
|
||||
function cancel(): void {
|
||||
player.finishGraftAugmentationWork(true);
|
||||
router.toTerminal();
|
||||
}
|
||||
function unfocus(): void {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
|
||||
const completion = (player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100;
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on grafting <b>{player.graftAugmentationName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
progress: {
|
||||
elapsed: player.timeWorked,
|
||||
percentage: completion,
|
||||
},
|
||||
|
||||
stopText: "Stop grafting",
|
||||
stopTooltip: (
|
||||
<>
|
||||
If you cancel, your work will <b>not</b> be saved, and the money you spent will <b>not</b> be returned
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (player.currentWork === null) {
|
||||
router.toTerminal();
|
||||
|
Loading…
Reference in New Issue
Block a user