remove unused fields on sleeves

This commit is contained in:
Olivier Gagnon 2022-07-28 03:08:39 -04:00
parent 4549b0d467
commit 3b35b07860
9 changed files with 142 additions and 445 deletions

@ -36,6 +36,8 @@ import { joinFaction } from "../Faction/FactionHelpers";
import { WorkerScript } from "../Netscript/WorkerScript";
import { FactionNames } from "../Faction/data/FactionNames";
import { KEY } from "../utils/helpers/keyCodes";
import { isSleeveInfiltrateWork } from "../PersonObjects/Sleeve/Work/SleeveInfiltrateWork";
import { isSleeveSupportWork } from "../PersonObjects/Sleeve/Work/SleeveSupportWork";
interface BlackOpsAttempt {
error?: string;
@ -1124,7 +1126,7 @@ export class Bladeburner implements IBladeburner {
const losses = getRandomInt(0, max);
this.teamSize -= losses;
if (this.teamSize < this.sleeveSize) {
const sup = player.sleeves.filter((x) => x.bbAction == "Support main sleeve");
const sup = player.sleeves.filter((x) => isSleeveSupportWork(x.currentWork));
for (let i = 0; i > this.teamSize - this.sleeveSize; i--) {
const r = Math.floor(Math.random() * sup.length);
sup[r].takeDamage(sup[r].hp.max);
@ -1438,7 +1440,7 @@ export class Bladeburner implements IBladeburner {
const losses = getRandomInt(1, teamLossMax);
this.teamSize -= losses;
if (this.teamSize < this.sleeveSize) {
const sup = player.sleeves.filter((x) => x.bbAction == "Support main sleeve");
const sup = player.sleeves.filter((x) => isSleeveSupportWork(x.currentWork));
for (let i = 0; i > this.teamSize - this.sleeveSize; i--) {
const r = Math.floor(Math.random() * sup.length);
sup[r].takeDamage(sup[r].hp.max);
@ -1602,7 +1604,7 @@ export class Bladeburner implements IBladeburner {
}
infiltrateSynthoidCommunities(p: IPlayer): void {
const infilSleeves = p.sleeves.filter((s) => s.bbAction === "Infiltrate synthoids").length;
const infilSleeves = p.sleeves.filter((s) => isSleeveInfiltrateWork(s.currentWork)).length;
const amt = Math.pow(infilSleeves, -0.5) / 2;
for (const contract of Object.keys(this.contracts)) {
this.contracts[contract].count += amt;

@ -1,5 +1,4 @@
import { IPlayer } from "../PersonObjects/IPlayer";
import { SleeveTaskType } from "../PersonObjects/Sleeve/SleeveTaskTypesEnum";
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
import { CityName } from "../Locations/data/CityNames";
@ -15,7 +14,9 @@ import {
} from "../ScriptEditor/NetscriptDefinitions";
import { checkEnum } from "../utils/helpers/checkEnum";
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
import { FactionWorkType } from "../Work/data/FactionWorkType";
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
const checkSleeveAPIAccess = function (ctx: NetscriptContext): void {
@ -120,7 +121,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
continue;
}
const other = player.sleeves[i];
if (other.currentTask === SleeveTaskType.Company && other.currentTaskLocation === companyName) {
if (isSleeveCompanyWork(other.currentWork) && other.currentWork.companyName === companyName) {
throw ctx.makeRuntimeErrorMsg(
`Sleeve ${sleeveNumber} cannot work for company ${companyName} because Sleeve ${i} is already working for them.`,
);
@ -144,7 +145,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
continue;
}
const other = player.sleeves[i];
if (other.currentTask === SleeveTaskType.Faction && other.currentTaskLocation === factionName) {
if (isSleeveFactionWork(other.currentWork) && other.currentWork.factionName === factionName) {
throw ctx.makeRuntimeErrorMsg(
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because Sleeve ${i} is already working for them.`,
);
@ -223,36 +224,6 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
strengthExp: sl.mults.strength_exp,
workMoney: sl.mults.work_money,
},
timeWorked: sl.currentTaskTime,
earningsForSleeves: {
workHackExpGain: sl.earningsForSleeves.hack,
workStrExpGain: sl.earningsForSleeves.str,
workDefExpGain: sl.earningsForSleeves.def,
workDexExpGain: sl.earningsForSleeves.dex,
workAgiExpGain: sl.earningsForSleeves.agi,
workChaExpGain: sl.earningsForSleeves.cha,
workMoneyGain: sl.earningsForSleeves.money,
},
earningsForPlayer: {
workHackExpGain: sl.earningsForPlayer.hack,
workStrExpGain: sl.earningsForPlayer.str,
workDefExpGain: sl.earningsForPlayer.def,
workDexExpGain: sl.earningsForPlayer.dex,
workAgiExpGain: sl.earningsForPlayer.agi,
workChaExpGain: sl.earningsForPlayer.cha,
workMoneyGain: sl.earningsForPlayer.money,
},
earningsForTask: {
workHackExpGain: sl.earningsForTask.hack,
workStrExpGain: sl.earningsForTask.str,
workDefExpGain: sl.earningsForTask.def,
workDexExpGain: sl.earningsForTask.dex,
workAgiExpGain: sl.earningsForTask.agi,
workChaExpGain: sl.earningsForTask.cha,
workMoneyGain: sl.earningsForTask.money,
},
workRepGain: sl.getRepGain(player),
};
},
getSleeveAugmentations:
@ -343,11 +314,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
continue;
}
const other = player.sleeves[i];
if (
other.currentTask === SleeveTaskType.Bladeburner &&
other.bbAction === action &&
other.bbContract === contract
) {
if (isSleeveBladeburnerWork(other.currentWork) && other.currentWork.actionName === contract) {
throw ctx.helper.makeRuntimeErrorMsg(
`Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
);

@ -6,7 +6,6 @@
*
* Sleeves are unlocked in BitNode-10.
*/
import { SleeveTaskType } from "./SleeveTaskTypesEnum";
import { IPlayer } from "../IPlayer";
import { Person } from "../Person";
@ -14,8 +13,6 @@ import { ITaskTracker, createTaskTracker } from "../ITaskTracker";
import { Augmentation } from "../../Augmentation/Augmentation";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { Crime } from "../../Crime/Crime";
import { Crimes } from "../../Crime/Crimes";
@ -33,9 +30,7 @@ import { CityName } from "../../Locations/data/CityNames";
import { LocationName } from "../../Locations/data/LocationNames";
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../../utils/JSONReviver";
import { BladeburnerConstants } from "../../Bladeburner/data/Constants";
import { numeralWrapper } from "../../ui/numeralFormat";
import { capitalizeFirstLetter } from "../../utils/StringHelperFunctions";
import { FactionWorkType } from "../../Work/data/FactionWorkType";
import { Work } from "./Work/Work";
import { SleeveClassWork } from "./Work/SleeveClassWork";
@ -51,82 +46,6 @@ import { SleeveCrimeWork } from "./Work/SleeveCrimeWork";
export class Sleeve extends Person {
currentWork: Work | null = null;
/**
* Stores the name of the class that the player is currently taking
*/
className = "";
/**
* Stores the type of crime the sleeve is currently attempting
* Must match the name of a Crime object
*/
crimeType = "";
/**
* Enum value for current task
*/
currentTask: SleeveTaskType = SleeveTaskType.Idle;
/**
* Contains details about the sleeve's current task. The info stored
* in this depends on the task type
*
* Faction/Company Work: Name of Faction/Company
* Crime: Money earned if successful
* Class/Gym: Name of university/gym
* Bladeburner: success chance
*/
currentTaskLocation = "";
/**
* Maximum amount of time (in milliseconds) that can be spent on current task.
*/
currentTaskMaxTime = 0;
/**
* Milliseconds spent on current task
*/
currentTaskTime = 0;
/**
* Keeps track of experience earned for other sleeves
*/
earningsForSleeves: ITaskTracker = createTaskTracker();
/**
* Keeps track of experience + money earned for player
*/
earningsForPlayer: ITaskTracker = createTaskTracker();
/**
* Keeps track of experienced earned in the current task/action
*/
earningsForTask: ITaskTracker = createTaskTracker();
/**
* Keeps track of what type of work sleeve is doing for faction, if applicable
*/
factionWorkType: FactionWorkType = FactionWorkType.HACKING;
/**
* Records experience gain rate for the current task
*/
gainRatesForTask: ITaskTracker = createTaskTracker();
/**
* String that stores what stat the sleeve is training at the gym
*/
gymStatType = "";
/**
* String that stores what stat the sleeve is training at the gym
*/
bbAction = "";
/**
* String that stores what stat the sleeve is training at the gym
*/
bbContract = "";
/**
* Clone retains 'memory' synchronization (and maybe exp?) upon prestige/installing Augs
@ -187,12 +106,6 @@ export class Sleeve extends Person {
return false;
}
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork === null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
this.startWork(p, new SleeveCrimeWork(crime.type));
return true;
}
@ -259,43 +172,31 @@ export class Sleeve extends Person {
if (pHackExp > 0) {
this.gainHackingExp(pHackExp);
p.gainHackingExp(pHackExp);
this.earningsForPlayer.hack += pHackExp;
this.earningsForTask.hack += pHackExp;
}
if (pStrExp > 0) {
this.gainStrengthExp(pStrExp);
p.gainStrengthExp(pStrExp);
this.earningsForPlayer.str += pStrExp;
this.earningsForTask.str += pStrExp;
}
if (pDefExp > 0) {
this.gainDefenseExp(pDefExp);
p.gainDefenseExp(pDefExp);
this.earningsForPlayer.def += pDefExp;
this.earningsForTask.def += pDefExp;
}
if (pDexExp > 0) {
this.gainDexterityExp(pDexExp);
p.gainDexterityExp(pDexExp);
this.earningsForPlayer.dex += pDexExp;
this.earningsForTask.dex += pDexExp;
}
if (pAgiExp > 0) {
this.gainAgilityExp(pAgiExp);
p.gainAgilityExp(pAgiExp);
this.earningsForPlayer.agi += pAgiExp;
this.earningsForTask.agi += pAgiExp;
}
if (pChaExp > 0) {
this.gainCharismaExp(pChaExp);
p.gainCharismaExp(pChaExp);
this.earningsForPlayer.cha += pChaExp;
this.earningsForTask.cha += pChaExp;
}
if (pIntExp > 0) {
@ -303,14 +204,6 @@ export class Sleeve extends Person {
p.gainIntelligenceExp(pIntExp);
}
// Record earnings for other sleeves
this.earningsForSleeves.hack += pHackExp * (this.sync / 100);
this.earningsForSleeves.str += pStrExp * (this.sync / 100);
this.earningsForSleeves.def += pDefExp * (this.sync / 100);
this.earningsForSleeves.dex += pDexExp * (this.sync / 100);
this.earningsForSleeves.agi += pAgiExp * (this.sync / 100);
this.earningsForSleeves.cha += pChaExp * (this.sync / 100);
// Return the experience to be gained by other sleeves
return {
hack: pHackExp * (this.sync / 100),
@ -327,12 +220,12 @@ export class Sleeve extends Person {
/**
* Earn money for player
*/
gainMoney(p: IPlayer, task: ITaskTracker, numCycles = 1): void {
const gain: number = task.money * numCycles;
this.earningsForTask.money += gain;
this.earningsForPlayer.money += gain;
p.gainMoney(gain, "sleeves");
}
// gainMoney(p: IPlayer, task: ITaskTracker, numCycles = 1): void {
// const gain: number = task.money * numCycles;
// this.earningsForTask.money += gain;
// this.earningsForPlayer.money += gain;
// p.gainMoney(gain, "sleeves");
// }
/**
* Returns the cost of upgrading this sleeve's memory by a certain amount
@ -363,36 +256,36 @@ export class Sleeve extends Person {
* Gets reputation gain for the current task
* Only applicable when working for company or faction
*/
getRepGain(p: IPlayer): number {
if (this.currentTask === SleeveTaskType.Company) {
const companyName: string = this.currentTaskLocation;
const company: Company | null = Companies[companyName];
if (company == null) {
console.error(`Invalid company found when trying to calculate rep gain: ${companyName}`);
return 0;
}
// getRepGain(p: IPlayer): number {
// if (this.currentTask === SleeveTaskType.Company) {
// const companyName: string = this.currentTaskLocation;
// const company: Company | null = Companies[companyName];
// if (company == null) {
// console.error(`Invalid company found when trying to calculate rep gain: ${companyName}`);
// return 0;
// }
const companyPosition: CompanyPosition | null = CompanyPositions[p.jobs[companyName]];
if (companyPosition == null) {
console.error(`Invalid company position name found when trying to calculate rep gain: ${p.jobs[companyName]}`);
return 0;
}
// const companyPosition: CompanyPosition | null = CompanyPositions[p.jobs[companyName]];
// if (companyPosition == null) {
// console.error(`Invalid company position name found when trying to calculate rep gain: ${p.jobs[companyName]}`);
// return 0;
// }
const jobPerformance: number = companyPosition.calculateJobPerformance(
this.skills.hacking,
this.skills.strength,
this.skills.defense,
this.skills.dexterity,
this.skills.agility,
this.skills.charisma,
);
const favorMult = 1 + company.favor / 100;
// const jobPerformance: number = companyPosition.calculateJobPerformance(
// this.skills.hacking,
// this.skills.strength,
// this.skills.defense,
// this.skills.dexterity,
// this.skills.agility,
// this.skills.charisma,
// );
// const favorMult = 1 + company.favor / 100;
return jobPerformance * this.mults.company_rep * favorMult;
} else {
return 0;
}
}
// return jobPerformance * this.mults.company_rep * favorMult;
// } else {
// return 0;
// }
// }
installAugmentation(aug: Augmentation): void {
this.exp.hacking = 0;
@ -420,8 +313,6 @@ export class Sleeve extends Person {
// Reset task-related stuff
this.resetTaskStatus(p);
this.earningsForSleeves = createTaskTracker();
this.earningsForPlayer = createTaskTracker();
this.shockRecovery(p);
// Reset augs and multipliers
@ -457,20 +348,6 @@ export class Sleeve extends Person {
return;
}
let time = cyclesUsed * CONSTANTS.MilliPerCycle;
if (this.currentTaskMaxTime !== 0 && this.currentTaskTime + time > this.currentTaskMaxTime) {
time = this.currentTaskMaxTime - this.currentTaskTime;
cyclesUsed = Math.floor(time / CONSTANTS.MilliPerCycle);
if (time < 0 || cyclesUsed < 0) {
console.warn(`Sleeve.process() calculated negative cycle usage`);
time = 0;
cyclesUsed = 0;
}
}
this.currentTaskTime += time;
// Shock gradually goes towards 100
this.shock = Math.min(100, this.shock + 0.0001 * cyclesUsed);
@ -486,39 +363,14 @@ export class Sleeve extends Person {
*/
resetTaskStatus(p: IPlayer): void {
this.stopWork(p);
if (this.bbAction == "Support main sleeve") {
p.bladeburner?.sleeveSupport(false);
}
this.earningsForTask = createTaskTracker();
this.gainRatesForTask = createTaskTracker();
this.currentTask = SleeveTaskType.Idle;
this.currentTaskTime = 0;
this.currentTaskMaxTime = 0;
this.factionWorkType = FactionWorkType.HACKING;
this.crimeType = "";
this.currentTaskLocation = "";
this.gymStatType = "";
this.className = "";
this.bbAction = "";
this.bbContract = "------";
}
shockRecovery(p: IPlayer): boolean {
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork === null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
this.startWork(p, new SleeveRecoveryWork());
return true;
}
synchronize(p: IPlayer): boolean {
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork !== null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
this.startWork(p, new SleeveSynchroWork());
return true;
}
@ -527,12 +379,6 @@ export class Sleeve extends Person {
* Take a course at a university
*/
takeUniversityCourse(p: IPlayer, universityName: string, className: string): boolean {
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
// Set exp/money multipliers based on which university.
// Also check that the sleeve is in the right city
let loc: LocationName | undefined;
@ -632,12 +478,6 @@ export class Sleeve extends Person {
return false;
}
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork !== null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
const company: Company | null = Companies[companyName];
const companyPosition: CompanyPosition | null = CompanyPositions[p.jobs[companyName]];
if (company == null) return false;
@ -658,12 +498,6 @@ export class Sleeve extends Person {
return false;
}
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork === null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
const factionInfo = faction.getInfo();
// Set type of work (hacking/field/security), and the experience gains
@ -697,12 +531,6 @@ export class Sleeve extends Person {
* Begin a gym workout task
*/
workoutAtGym(p: IPlayer, gymName: string, stat: string): boolean {
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
// Set exp/money multipliers based on which university.
// Also check that the sleeve is in the right city
let loc: LocationName | undefined;
@ -770,42 +598,14 @@ export class Sleeve extends Person {
* Begin a bladeburner task
*/
bladeburner(p: IPlayer, action: string, contract: string): boolean {
if (this.currentTask !== SleeveTaskType.Idle || this.currentWork === null) {
this.finishTask(p);
} else {
this.resetTaskStatus(p);
}
this.gainRatesForTask.hack = 0;
this.gainRatesForTask.str = 0;
this.gainRatesForTask.def = 0;
this.gainRatesForTask.dex = 0;
this.gainRatesForTask.agi = 0;
this.gainRatesForTask.cha = 0;
this.gainRatesForTask.money = 0;
this.currentTaskLocation = "";
const time = 0;
this.bbContract = "------";
switch (action) {
case "Field analysis":
// time = this.getBladeburnerActionTime(p, "General", action);
// this.gainRatesForTask.hack = 20 * this.mults.hacking_exp;
// this.gainRatesForTask.cha = 20 * this.mults.charisma_exp;
this.startWork(p, new SleeveBladeburnerWork({ type: "General", name: "Field Analysis" }));
return true;
case "Recruitment":
// time = this.getBladeburnerActionTime(p, "General", action);
// this.gainRatesForTask.cha =
// 2 * BladeburnerConstants.BaseStatGain * (p.bladeburner?.getRecruitmentTime(this) ?? 0) * 1000;
// this.currentTaskLocation = `(Success Rate: ${numeralWrapper.formatPercentage(
// this.recruitmentSuccessChance(p),
// )})`;
this.startWork(p, new SleeveBladeburnerWork({ type: "General", name: "Recruitment" }));
return true;
case "Diplomacy":
// time = this.getBladeburnerActionTime(p, "General", action);
this.startWork(p, new SleeveBladeburnerWork({ type: "General", name: "Diplomacy" }));
return true;
case "Infiltrate synthoids":
@ -817,16 +617,8 @@ export class Sleeve extends Person {
case "Take on contracts":
this.startWork(p, new SleeveBladeburnerWork({ type: "Contracts", name: contract }));
return true;
// time = this.getBladeburnerActionTime(p, "Contracts", contract);
// this.contractGainRates(p, "Contracts", contract);
// this.currentTaskLocation = this.contractSuccessChance(p, "Contracts", contract);
// this.bbContract = capitalizeEachWord(contract.toLowerCase());
// break;
}
this.bbAction = capitalizeFirstLetter(action.toLowerCase());
this.currentTaskMaxTime = time;
this.currentTask = SleeveTaskType.Bladeburner;
return true;
}
@ -853,38 +645,38 @@ export class Sleeve extends Person {
}
}
contractGainRates(p: IPlayer, type: string, name: string): void {
const bb = p.bladeburner;
if (bb === null) {
const errorLogText = `bladeburner is null`;
console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
return;
}
const actionIdent = bb.getActionIdFromTypeAndName(type, name);
if (actionIdent === null) {
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
this.resetTaskStatus(p);
return;
}
const action = bb.getActionObject(actionIdent);
if (action === null) {
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
this.resetTaskStatus(p);
return;
}
const retValue = bb.getActionStats(action, true);
this.gainRatesForTask.hack = retValue.hack;
this.gainRatesForTask.str = retValue.str;
this.gainRatesForTask.def = retValue.def;
this.gainRatesForTask.dex = retValue.dex;
this.gainRatesForTask.agi = retValue.agi;
this.gainRatesForTask.cha = retValue.cha;
const rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
this.gainRatesForTask.money =
BladeburnerConstants.ContractBaseMoneyGain * rewardMultiplier * bb.skillMultipliers.money;
}
// contractGainRates(p: IPlayer, type: string, name: string): void {
// const bb = p.bladeburner;
// if (bb === null) {
// const errorLogText = `bladeburner is null`;
// console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
// return;
// }
// const actionIdent = bb.getActionIdFromTypeAndName(type, name);
// if (actionIdent === null) {
// const errorLogText = `Invalid action: type='${type}' name='${name}'`;
// console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
// this.resetTaskStatus(p);
// return;
// }
// const action = bb.getActionObject(actionIdent);
// if (action === null) {
// const errorLogText = `Invalid action: type='${type}' name='${name}'`;
// console.error(`Function: sleeves.contractGainRates; Message: '${errorLogText}'`);
// this.resetTaskStatus(p);
// return;
// }
// const retValue = bb.getActionStats(action, true);
// this.gainRatesForTask.hack = retValue.hack;
// this.gainRatesForTask.str = retValue.str;
// this.gainRatesForTask.def = retValue.def;
// this.gainRatesForTask.dex = retValue.dex;
// this.gainRatesForTask.agi = retValue.agi;
// this.gainRatesForTask.cha = retValue.cha;
// const rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
// this.gainRatesForTask.money =
// BladeburnerConstants.ContractBaseMoneyGain * rewardMultiplier * bb.skillMultipliers.money;
// }
getBladeburnerActionTime(p: IPlayer, type: string, name: string): number {
//Maybe find workerscript and use original

@ -5,7 +5,6 @@ import { Work, WorkType } from "./Work";
import { CONSTANTS } from "../../../Constants";
import { GeneralActions } from "../../../Bladeburner/data/GeneralActions";
import { applyWorkStatsExp, WorkStats } from "../../../Work/WorkStats";
import { Contracts } from "src/Bladeburner/data/Contracts";
interface SleeveBladeburnerWorkParams {
type: string;

@ -38,12 +38,16 @@ export class SleeveCrimeWork extends Work {
});
}
cyclesNeeded(): number {
return this.getCrime().time / CONSTANTS._idleSpeed;
}
process(player: IPlayer, sleeve: Sleeve, cycles: number): number {
this.cyclesWorked += cycles;
const crime = this.getCrime();
const gains = this.getExp();
if (this.cyclesWorked >= crime.time / CONSTANTS._idleSpeed) {
if (this.cyclesWorked >= this.cyclesNeeded()) {
if (Math.random() < crime.successRate(sleeve)) {
applyWorkStats(player, sleeve, gains, 1, "sleeves");
@ -51,7 +55,7 @@ export class SleeveCrimeWork extends Work {
} else {
applyWorkStats(player, sleeve, scaleWorkStats(gains, 0.25), 1, "sleeves");
}
this.cyclesWorked -= crime.time / CONSTANTS._idleSpeed;
this.cyclesWorked -= this.cyclesNeeded();
}
return 0;
}

@ -1,58 +0,0 @@
import { Sleeve } from "../Sleeve";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { Money } from "../../../ui/React/Money";
import * as React from "react";
import { StatsTable } from "../../../ui/React/StatsTable";
import { Modal } from "../../../ui/React/Modal";
interface IProps {
open: boolean;
onClose: () => void;
sleeve: Sleeve;
}
export function MoreEarningsModal(props: IProps): React.ReactElement {
return (
<Modal open={props.open} onClose={props.onClose}>
<StatsTable
rows={[
["Money ", <Money money={props.sleeve.earningsForTask.money} />],
["Hacking Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.hack)],
["Strength Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.str)],
["Defense Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.def)],
["Dexterity Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.dex)],
["Agility Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.agi)],
["Charisma Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.cha)],
]}
title="Earnings for Current Task:"
/>
<br />
<StatsTable
rows={[
["Money: ", <Money money={props.sleeve.earningsForPlayer.money} />],
["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.hack)],
["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.str)],
["Defense Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.def)],
["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.dex)],
["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.agi)],
["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.cha)],
]}
title="Total Earnings for Host Consciousness:"
/>
<br />
<StatsTable
rows={[
["Money: ", <Money money={props.sleeve.earningsForSleeves.money} />],
["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.hack)],
["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.str)],
["Defense Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.def)],
["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.dex)],
["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.agi)],
["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.cha)],
]}
title="Total Earnings for Other Sleeves:"
/>
<br />
</Modal>
);
}

@ -2,13 +2,10 @@ import { Box, Button, Paper, Tooltip, Typography } from "@mui/material";
import React, { useState } from "react";
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
import { CONSTANTS } from "../../../Constants";
import { Crimes } from "../../../Crime/Crimes";
import { use } from "../../../ui/Context";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { ProgressBar } from "../../../ui/React/Progress";
import { Sleeve } from "../Sleeve";
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
import { MoreEarningsModal } from "./MoreEarningsModal";
import { MoreStatsModal } from "./MoreStatsModal";
import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal";
import { EarningsElement, StatsElement } from "./StatsElement";
@ -32,7 +29,6 @@ interface IProps {
export function SleeveElem(props: IProps): React.ReactElement {
const player = use.Player();
const [statsOpen, setStatsOpen] = useState(false);
const [earningsOpen, setEarningsOpen] = useState(false);
const [travelOpen, setTravelOpen] = useState(false);
const [augmentationsOpen, setAugmentationsOpen] = useState(false);
@ -161,7 +157,6 @@ export function SleeveElem(props: IProps): React.ReactElement {
<StatsElement sleeve={props.sleeve} />
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "100%" }}>
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
<Button onClick={() => setEarningsOpen(true)}>More Earnings Info</Button>
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
<span>
<Button
@ -196,20 +191,28 @@ export function SleeveElem(props: IProps): React.ReactElement {
</Button>
<Typography>{desc}</Typography>
<Typography>
{(props.sleeve.currentTask === SleeveTaskType.Crime ||
props.sleeve.currentTask === SleeveTaskType.Bladeburner) &&
props.sleeve.currentTaskMaxTime > 0 && (
<ProgressBar
variant="determinate"
value={(props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime) * 100}
color="primary"
/>
)}
{isSleeveCrimeWork(props.sleeve.currentWork) && (
<ProgressBar
variant="determinate"
value={(props.sleeve.currentWork.cyclesWorked / props.sleeve.currentWork.cyclesNeeded()) * 100}
color="primary"
/>
)}
{isSleeveBladeburnerWork(props.sleeve.currentWork) && (
<ProgressBar
variant="determinate"
value={
(props.sleeve.currentWork.cyclesWorked /
props.sleeve.currentWork.cyclesNeeded(player, props.sleeve)) *
100
}
color="primary"
/>
)}
</Typography>
</span>
</Paper>
<MoreStatsModal open={statsOpen} onClose={() => setStatsOpen(false)} sleeve={props.sleeve} />
<MoreEarningsModal open={earningsOpen} onClose={() => setEarningsOpen(false)} sleeve={props.sleeve} />
<TravelModal
open={travelOpen}
onClose={() => setTravelOpen(false)}

@ -1,7 +1,6 @@
import React, { useState } from "react";
import { Sleeve } from "../Sleeve";
import { IPlayer } from "../../IPlayer";
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
import { Crimes } from "../../../Crime/Crimes";
import { LocationName } from "../../../Locations/data/LocationNames";
import { CityName } from "../../../Locations/data/CityNames";
@ -9,7 +8,9 @@ import { Factions } from "../../../Faction/Factions";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
import { FactionNames } from "../../../Faction/data/FactionNames";
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
import { isSleeveFactionWork } from "../Work/SleeveFactionWork";
import { isSleeveCompanyWork } from "../Work/SleeveCompanyWork";
import { isSleeveBladeburnerWork } from "../Work/SleeveBladeburnerWork";
const universitySelectorOptions: string[] = [
"Study Computer Science",
@ -49,8 +50,8 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
if (sleeve === otherSleeve) {
continue;
}
if (otherSleeve.currentTask === SleeveTaskType.Company) {
forbiddenCompanies.push(otherSleeve.currentTaskLocation);
if (isSleeveCompanyWork(otherSleeve.currentWork)) {
forbiddenCompanies.push(otherSleeve.currentWork.companyName);
}
}
const allJobs: string[] = Object.keys(player.jobs);
@ -68,8 +69,8 @@ function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
if (sleeve === otherSleeve) {
continue;
}
if (otherSleeve.currentTask === SleeveTaskType.Faction) {
forbiddenFactions.push(otherSleeve.currentTaskLocation);
if (isSleeveFactionWork(otherSleeve.currentWork)) {
forbiddenFactions.push(otherSleeve.currentWork.factionName);
}
}
@ -98,8 +99,9 @@ function possibleContracts(player: IPlayer, sleeve: Sleeve): string[] {
if (sleeve === otherSleeve) {
continue;
}
if (otherSleeve.currentTask === SleeveTaskType.Bladeburner && otherSleeve.bbAction == "Take on contracts") {
contracts = contracts.filter((x) => x != otherSleeve.bbContract);
if (isSleeveBladeburnerWork(otherSleeve.currentWork) && otherSleeve.currentWork.actionType === "Contracts") {
const w = otherSleeve.currentWork;
contracts = contracts.filter((x) => x != w.actionName);
}
}
if (contracts.length === 0) {
@ -241,51 +243,37 @@ const canDo: {
};
function getABC(sleeve: Sleeve): [string, string, string] {
switch (sleeve.currentTask) {
case SleeveTaskType.Idle:
return ["------", "------", "------"];
case SleeveTaskType.Company:
return ["Work for Company", sleeve.currentTaskLocation, "------"];
case SleeveTaskType.Faction: {
let workType = "";
switch (sleeve.factionWorkType) {
case FactionWorkType.HACKING:
workType = "Hacking Contracts";
break;
case FactionWorkType.FIELD:
workType = "Field Work";
break;
case FactionWorkType.SECURITY:
workType = "Security Work";
break;
}
return ["Work for Faction", sleeve.currentTaskLocation, workType];
}
case SleeveTaskType.Crime:
return ["Commit Crime", sleeve.crimeType, "------"];
case SleeveTaskType.Class:
return ["Take University Course", sleeve.className, sleeve.currentTaskLocation];
case SleeveTaskType.Gym: {
switch (sleeve.gymStatType) {
case "none":
return ["Idle", "------", "------"];
case "str":
return ["Workout at Gym", "Train Strength", sleeve.currentTaskLocation];
case "def":
return ["Workout at Gym", "Train Defense", sleeve.currentTaskLocation];
case "dex":
return ["Workout at Gym", "Train Dexterity", sleeve.currentTaskLocation];
case "agi":
return ["Workout at Gym", "Train Agility", sleeve.currentTaskLocation];
}
}
case SleeveTaskType.Bladeburner:
return ["Perform Bladeburner Actions", sleeve.bbAction, sleeve.bbContract];
case SleeveTaskType.Recovery:
return ["Shock Recovery", "------", "------"];
case SleeveTaskType.Synchro:
return ["Synchronize", "------", "------"];
}
return ["------", "------", "------"];
// switch (sleeve.currentTask) {
// case SleeveTaskType.Idle:
// case SleeveTaskType.Company:
// case SleeveTaskType.Faction: {
// }
// case SleeveTaskType.Crime:
// return ["Commit Crime", sleeve.crimeType, "------"];
// case SleeveTaskType.Class:
// case SleeveTaskType.Gym: {
// switch (sleeve.gymStatType) {
// case "none":
// return ["Idle", "------", "------"];
// case "str":
// return ["Workout at Gym", "Train Strength", sleeve.currentTaskLocation];
// case "def":
// return ["Workout at Gym", "Train Defense", sleeve.currentTaskLocation];
// case "dex":
// return ["Workout at Gym", "Train Dexterity", sleeve.currentTaskLocation];
// case "agi":
// return ["Workout at Gym", "Train Agility", sleeve.currentTaskLocation];
// }
// }
// case SleeveTaskType.Bladeburner:
// return ["Perform Bladeburner Actions", sleeve.bbAction, sleeve.bbContract];
// case SleeveTaskType.Recovery:
// return ["Shock Recovery", "------", "------"];
// case SleeveTaskType.Synchro:
// return ["Synchronize", "------", "------"];
// }
}
export function TaskSelector(props: IProps): React.ReactElement {

@ -1022,7 +1022,7 @@ export interface SleeveInformation {
* Object representing a sleeve current task.
* @public
*/
export interface SleeveTask = any;
export type SleeveTask = any;
/**
* Object representing a port. A port is a serialized queue.