allbuild commit c8440ef2

This commit is contained in:
Olivier Gagnon 2022-07-28 14:35:55 -04:00
parent c8440ef268
commit 07c7f0641a
28 changed files with 186 additions and 351 deletions

@ -21,6 +21,14 @@ module.exports = {
plugins: ["@typescript-eslint"],
extends: ["plugin:@typescript-eslint/recommended"],
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^__",
varsIgnorePattern: "^__",
caughtErrorsIgnorePattern: "^__",
},
],
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
},

4
dist/main.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

42
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -71,6 +71,8 @@ getPlayer
hp have been moved to the hp struct
For example: getPlayer().max_hp => getPlayer().hp.max or hp.current
hasWseAccount, hasTixApiAccess, has4SData, has4SDataTixApi have been removed and replaced with similar stock functions
workForCompany
--------------

@ -89,7 +89,7 @@ export const CONSTANTS: {
LatestUpdate: string;
} = {
VersionString: "2.0.0",
VersionNumber: 22,
VersionNumber: 23,
// Speed (in ms) at which the main loop is updated
_idleSpeed: 200,
@ -269,6 +269,7 @@ v2.0.0 - 2022-07-19 Work rework
* stock.buy and stock.sell were renamed to stock.buyStock and stock.sellStock because 'buy' and 'sell'
are very common tokens.
* corporation.bribe no longer allows to give shares as bribe.
* hasWseAccount, hasTixApiAccess, has4SData, has4SDataTixApi have been removed and replaced with similar stock functions.
Netscript

@ -126,6 +126,10 @@ const hacknet = {
// Stock API
const stock = {
hasWSEAccount: 0.05,
hasTIXAPIAccess: 0.05,
has4SData: 0.05,
has4SDataTIXAPI: 0.05,
getSymbols: RamCostConstants.ScriptGetStockRamCost,
getPrice: RamCostConstants.ScriptGetStockRamCost,
getAskPrice: RamCostConstants.ScriptGetStockRamCost,

@ -585,31 +585,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
},
player(funcName: string, p: unknown): IPlayer {
const fakePlayer = {
hacking: undefined,
hp: undefined,
max_hp: undefined,
strength: undefined,
defense: undefined,
dexterity: undefined,
agility: undefined,
charisma: undefined,
intelligence: undefined,
hacking_exp: undefined,
strength_exp: undefined,
defense_exp: undefined,
dexterity_exp: undefined,
agility_exp: undefined,
charisma_exp: undefined,
hacking_chance_mult: undefined,
mults: undefined,
numPeopleKilled: undefined,
money: undefined,
city: undefined,
location: undefined,
hasWseAccount: undefined,
hasTixApiAccess: undefined,
has4SData: undefined,
has4SDataTixApi: undefined,
bitNodeN: undefined,
totalPlaytime: undefined,
playtimeSinceLastAug: undefined,
@ -2446,10 +2427,6 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
money: Player.money,
city: Player.city,
location: Player.location,
hasWseAccount: Player.hasWseAccount,
hasTixApiAccess: Player.hasTixApiAccess,
has4SData: Player.has4SData,
has4SDataTixApi: Player.has4SDataTixApi,
bitNodeN: Player.bitNodeN,
totalPlaytime: Player.totalPlaytime,
playtimeSinceLastAug: Player.playtimeSinceLastAug,

@ -39,6 +39,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
};
return {
hasWSEAccount: () => (): boolean => {
return player.hasWseAccount;
},
hasTIXAPIAccess: () => (): boolean => {
return player.hasTixApiAccess;
},
has4SData: () => (): boolean => {
return player.has4SData;
},
has4SDataTIXAPI: () => (): boolean => {
return player.has4SDataTixApi;
},
getSymbols: (ctx: NetscriptContext) => (): string[] => {
checkTixApiAccess(ctx);
return Object.values(StockSymbols);

@ -9,7 +9,6 @@
import { IPlayer } from "../IPlayer";
import { Person } from "../Person";
import { ITaskTracker, createTaskTracker } from "../ITaskTracker";
import { Augmentation } from "../../Augmentation/Augmentation";
@ -69,7 +68,7 @@ export class Sleeve extends Person {
/**
* Synchronization. Number between 0 and 100
* When experience is earned by sleeve, both the player and the sleeve get
* sync% of the experience earned. Other sleeves get sync^2% of exp
* sync% of the experience earned.
*/
sync = 1;
@ -83,6 +82,7 @@ export class Sleeve extends Person {
shockBonus(): number {
return this.shock / 100;
}
syncBonus(): number {
return this.sync / 100;
}
@ -110,123 +110,6 @@ export class Sleeve extends Person {
return true;
}
/**
* Called to stop the current task
*/
finishTask(p: IPlayer): void {
this.stopWork(p);
this.resetTaskStatus(p);
return;
}
/**
* Earn experience for any stats (supports multiple)
* This function also handles experience propogating to Player and other sleeves
*/
gainExperience(p: IPlayer, exp: ITaskTracker, numCycles = 1, fromOtherSleeve = false): ITaskTracker {
// If the experience is coming from another sleeve, it is not multiplied by anything.
// Also the player does not earn anything
if (fromOtherSleeve) {
if (exp.hack > 0) {
this.exp.hacking += exp.hack;
}
if (exp.str > 0) {
this.exp.strength += exp.str;
}
if (exp.def > 0) {
this.exp.defense += exp.def;
}
if (exp.dex > 0) {
this.exp.dexterity += exp.dex;
}
if (exp.agi > 0) {
this.exp.agility += exp.agi;
}
if (exp.cha > 0) {
this.exp.charisma += exp.cha;
}
return createTaskTracker();
}
// Experience is first multiplied by shock. Then 'synchronization'
// is accounted for
const multFac = (this.shock / 100) * (this.sync / 100) * numCycles;
const pHackExp = exp.hack * multFac;
const pStrExp = exp.str * multFac;
const pDefExp = exp.def * multFac;
const pDexExp = exp.dex * multFac;
const pAgiExp = exp.agi * multFac;
const pChaExp = exp.cha * multFac;
const pIntExp = exp.int * multFac;
// Experience is gained by both this sleeve and player
if (pHackExp > 0) {
this.gainHackingExp(pHackExp);
p.gainHackingExp(pHackExp);
}
if (pStrExp > 0) {
this.gainStrengthExp(pStrExp);
p.gainStrengthExp(pStrExp);
}
if (pDefExp > 0) {
this.gainDefenseExp(pDefExp);
p.gainDefenseExp(pDefExp);
}
if (pDexExp > 0) {
this.gainDexterityExp(pDexExp);
p.gainDexterityExp(pDexExp);
}
if (pAgiExp > 0) {
this.gainAgilityExp(pAgiExp);
p.gainAgilityExp(pAgiExp);
}
if (pChaExp > 0) {
this.gainCharismaExp(pChaExp);
p.gainCharismaExp(pChaExp);
}
if (pIntExp > 0) {
this.gainIntelligenceExp(pIntExp);
p.gainIntelligenceExp(pIntExp);
}
// Return the experience to be gained by other sleeves
return {
hack: pHackExp * (this.sync / 100),
str: pStrExp * (this.sync / 100),
def: pDefExp * (this.sync / 100),
dex: pDexExp * (this.sync / 100),
agi: pAgiExp * (this.sync / 100),
cha: pChaExp * (this.sync / 100),
int: pIntExp * (this.sync / 100),
money: exp.money,
};
}
/**
* 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");
// }
/**
* Returns the cost of upgrading this sleeve's memory by a certain amount
*/
@ -252,41 +135,6 @@ export class Sleeve extends Person {
return currCost * baseCost;
}
/**
* 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;
// }
// 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;
// return jobPerformance * this.mults.company_rep * favorMult;
// } else {
// return 0;
// }
// }
installAugmentation(aug: Augmentation): void {
this.exp.hacking = 0;
this.exp.strength = 0;
@ -312,7 +160,7 @@ export class Sleeve extends Person {
this.exp.charisma = 0;
// Reset task-related stuff
this.resetTaskStatus(p);
this.stopWork(p);
this.shockRecovery(p);
// Reset augs and multipliers
@ -342,27 +190,10 @@ export class Sleeve extends Person {
let cyclesUsed = this.storedCycles;
cyclesUsed = Math.min(cyclesUsed, 15);
if (this.currentWork) {
this.shock = Math.min(100, this.shock + 0.0001 * cyclesUsed);
if (!this.currentWork) return;
this.currentWork.process(p, this, cyclesUsed);
this.storedCycles -= cyclesUsed;
return;
}
// Shock gradually goes towards 100
this.shock = Math.min(100, this.shock + 0.0001 * cyclesUsed);
this.updateStatLevels();
this.storedCycles -= cyclesUsed;
return;
}
/**
* Resets all parameters used to keep information about the current task
*/
resetTaskStatus(p: IPlayer): void {
this.stopWork(p);
}
shockRecovery(p: IPlayer): boolean {
@ -645,58 +476,6 @@ 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;
// }
getBladeburnerActionTime(p: IPlayer, type: string, name: string): number {
//Maybe find workerscript and use original
const bb = p.bladeburner;
if (bb === null) {
const errorLogText = `bladeburner is null`;
console.error(`Function: sleeves.getBladeburnerActionTime; Message: '${errorLogText}'`);
return -1;
}
const time = bb.getActionTimeNetscriptFn(this, type, name);
if (typeof time === "string") {
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
console.error(`Function: sleeves.getBladeburnerActionTime; Message: '${errorLogText}'`);
return -1;
} else {
return time;
}
}
takeDamage(amt: number): boolean {
if (typeof amt !== "number") {
console.warn(`Player.takeDamage() called without a numeric argument: ${amt}`);

@ -4,7 +4,7 @@ import { Sleeve } from "../Sleeve";
import { applySleeveGains, Work, WorkType } from "./Work";
import { CONSTANTS } from "../../../Constants";
import { GeneralActions } from "../../../Bladeburner/data/GeneralActions";
import { applyWorkStatsExp, WorkStats } from "../../../Work/WorkStats";
import { WorkStats } from "../../../Work/WorkStats";
interface SleeveBladeburnerWorkParams {
type: string;

@ -5,7 +5,7 @@ import { ClassType } from "../../../Work/ClassWork";
import { LocationName } from "../../../Locations/data/LocationNames";
import { calculateClassEarnings } from "../../../Work/formulas/Class";
import { Sleeve } from "../Sleeve";
import { applyWorkStats, applyWorkStatsExp, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
export const isSleeveClassWork = (w: Work | null): w is SleeveClassWork => w !== null && w.type === WorkType.CLASS;

@ -6,7 +6,7 @@ import { LocationName } from "../../../Locations/data/LocationNames";
import { Companies } from "../../../Company/Companies";
import { Company } from "../../../Company/Company";
import { calculateCompanyWorkStats } from "../../../Work/formulas/Company";
import { applyWorkStats, applyWorkStatsExp, WorkStats } from "../../../Work/WorkStats";
import { WorkStats } from "../../../Work/WorkStats";
import { influenceStockThroughCompanyWork } from "../../../StockMarket/PlayerInfluencing";
interface SleeveCompanyWorkParams {

@ -5,7 +5,7 @@ import { applySleeveGains, Work, WorkType } from "./Work";
import { CrimeType } from "../../../utils/WorkType";
import { Crimes } from "../../../Crime/Crimes";
import { Crime } from "../../../Crime/Crime";
import { applyWorkStats, applyWorkStatsExp, newWorkStats, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
import { newWorkStats, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
import { CONSTANTS } from "../../../Constants";
export const isSleeveCrimeWork = (w: Work | null): w is SleeveCrimeWork => w !== null && w.type === WorkType.CRIME;

@ -6,13 +6,13 @@ import { FactionWorkType } from "../../../Work/data/FactionWorkType";
import { FactionNames } from "../../../Faction/data/FactionNames";
import { Factions } from "../../../Faction/Factions";
import { calculateFactionExp } from "../../../Work/formulas/Faction";
import { applyWorkStatsExp, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
import { Faction } from "../../../Faction/Faction";
import {
getFactionFieldWorkRepGain,
getFactionSecurityWorkRepGain,
getHackingWorkRepGain,
} from "../../../PersonObjects/formulas/reputation";
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
interface SleeveFactionWorkParams {
factionWorkType: FactionWorkType;

@ -21,7 +21,7 @@ export abstract class Work {
abstract process(player: IPlayer, sleeve: Sleeve, cycles: number): number;
abstract APICopy(): Record<string, unknown>;
abstract toJSON(): IReviverValue;
finish(_player: IPlayer): void {
finish(__player: IPlayer): void {
/* left for children to implement */
}
}

@ -35,7 +35,6 @@ export function SleeveElem(props: IProps): React.ReactElement {
const [abc, setABC] = useState(["------", "------", "------"]);
function setTask(): void {
props.sleeve.resetTaskStatus(player); // sets to idle
switch (abc[0]) {
case "------":
break;

@ -12,7 +12,6 @@ import { ReputationRate } from "../../../ui/React/ReputationRate";
import { use } from "../../../ui/Context";
import { Sleeve } from "../Sleeve";
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
import { isSleeveClassWork } from "../Work/SleeveClassWork";
import { isSleeveFactionWork } from "../Work/SleeveFactionWork";
import { isSleeveCompanyWork } from "../Work/SleeveCompanyWork";

@ -11,6 +11,14 @@ import { FactionNames } from "../../../Faction/data/FactionNames";
import { isSleeveFactionWork } from "../Work/SleeveFactionWork";
import { isSleeveCompanyWork } from "../Work/SleeveCompanyWork";
import { isSleeveBladeburnerWork } from "../Work/SleeveBladeburnerWork";
import { isSleeveRecoveryWork } from "../Work/SleeveRecoveryWork";
import { isSleeveSynchroWork } from "../Work/SleeveSynchroWork";
import { isSleeveClassWork } from "../Work/SleeveClassWork";
import { isSleeveInfiltrateWork } from "../Work/SleeveInfiltrateWork";
import { isSleeveSupportWork } from "../Work/SleeveSupportWork";
import { ClassType } from "../../../Work/ClassWork";
import { isSleeveCrimeWork } from "../Work/SleeveCrimeWork";
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
const universitySelectorOptions: string[] = [
"Study Computer Science",
@ -243,37 +251,88 @@ const canDo: {
};
function getABC(sleeve: Sleeve): [string, string, string] {
const w = sleeve.currentWork;
if (w === null) {
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", "------", "------"];
// }
if (isSleeveCompanyWork(w)) {
return ["Work for Company", w.companyName, "------"];
}
if (isSleeveFactionWork(w)) {
let workType = "";
switch (w.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", w.factionName, workType];
}
if (isSleeveBladeburnerWork(w)) {
if (w.actionType === "Contracts") {
return ["Perform Bladeburner Actions", "Take on contracts", w.actionName];
}
switch (w.actionName) {
case "Field Analysis":
return ["Perform Bladeburner Actions", "Field Analysis", "------"];
case "Diplomacy":
return ["Perform Bladeburner Actions", "Diplomacy", "------"];
case "Recruitment":
return ["Perform Bladeburner Actions", "Recruitment", "------"];
}
}
if (isSleeveClassWork(w)) {
switch (w.classType) {
case ClassType.StudyComputerScience:
return ["Take University Course", "Study Computer Science", w.location];
case ClassType.DataStructures:
return ["Take University Course", "Data Structures", w.location];
case ClassType.Networks:
return ["Take University Course", "Networks", w.location];
case ClassType.Algorithms:
return ["Take University Course", "Algorithms", w.location];
case ClassType.Management:
return ["Take University Course", "Management", w.location];
case ClassType.Leadership:
return ["Take University Course", "Leadership", w.location];
case ClassType.GymStrength:
return ["Workout at Gym", "Train Strength", w.location];
case ClassType.GymDefense:
return ["Workout at Gym", "Train Defense", w.location];
case ClassType.GymDexterity:
return ["Workout at Gym", "Train Dexterity", w.location];
case ClassType.GymAgility:
return ["Workout at Gym", "Train Agility", w.location];
}
}
if (isSleeveCrimeWork(w)) {
return [
"Commit Crime",
Object.values(Crimes).find((crime) => crime.type === w.crimeType)?.name ?? "Shoplift",
"------",
];
}
if (isSleeveSupportWork(w)) {
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
}
if (isSleeveInfiltrateWork(w)) {
return ["Perform Bladeburner Actions", "Infiltrate synthoids", "------"];
}
if (isSleeveRecoveryWork(w)) {
return ["Shock Recovery", "------", "------"];
}
if (isSleeveSynchroWork(w)) {
return ["Synchronize", "------", "------"];
}
return ["------", "------", "------"];
}
export function TaskSelector(props: IProps): React.ReactElement {

@ -26,7 +26,7 @@ export function TravelModal(props: IProps): React.ReactElement {
}
props.sleeve.city = city as CityName;
player.loseMoney(CONSTANTS.TravelCost, "sleeve");
props.sleeve.resetTaskStatus(player);
props.sleeve.stopWork(player);
props.rerender();
props.onClose();
}

@ -480,6 +480,9 @@ function evaluateVersionCompatibility(ver: string | number): void {
anyPlayer.exp.intelligence = anyPlayer.intelligence_exp;
v2APIBreak();
}
if (ver < 23) {
anyPlayer.currentWork = null;
}
}
}

@ -60,10 +60,6 @@ interface Player {
money: number;
city: string;
location: string;
hasWseAccount: boolean;
hasTixApiAccess: boolean;
has4SData: boolean;
has4SDataTixApi: boolean;
bitNodeN: number;
totalPlaytime: number;
playtimeSinceLastAug: number;
@ -1101,6 +1097,26 @@ export interface NetscriptPort {
* @public
*/
export interface TIX {
/**
* Returns true if the player has access to a WSE Account
* @remarks RAM cost: 0.05 GB
*/
hasWSEAccount(): boolean;
/**
* Returns true if the player has access to the TIX API
* @remarks RAM cost: 0.05 GB
*/
hasTIXAPIAccess(): boolean;
/**
* Returns true if the player has access to the 4S Data
* @remarks RAM cost: 0.05 GB
*/
has4SData(): boolean;
/**
* Returns true if the player has access to the 4SData TIX API
* @remarks RAM cost: 0.05 GB
*/
has4SDataTIXAPI(): boolean;
/**
* Returns an array of the symbols of the tradable stocks
*

@ -6,7 +6,7 @@ import { influenceStockThroughCompanyWork } from "../StockMarket/PlayerInfluenci
import { LocationName } from "../Locations/data/LocationNames";
import { calculateCompanyWorkStats } from "./formulas/Company";
import { Companies } from "../Company/Companies";
import { applyWorkStats, WorkStats } from "./WorkStats";
import { applyWorkStats, scaleWorkStats, WorkStats } from "./WorkStats";
import { Company } from "../Company/Company";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { Reputation } from "../ui/React/Reputation";
@ -38,7 +38,7 @@ export class CompanyWork extends Work {
if (!player.hasAugmentation(AugmentationNames.NeuroreceptorManager)) {
focusBonus = player.focus ? 1 : CONSTANTS.BaseFocusBonus;
}
return calculateCompanyWorkStats(player, player, this.getCompany());
return scaleWorkStats(calculateCompanyWorkStats(player, player, this.getCompany()), focusBonus);
}
process(player: IPlayer, cycles: number): boolean {

@ -4,7 +4,6 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
import { WorkStats } from "../WorkStats";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { CONSTANTS } from "../../Constants";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { IPerson } from "src/PersonObjects/IPerson";
export const calculateCompanyWorkStats = (player: IPlayer, worker: IPerson, company: Company): WorkStats => {

@ -33,7 +33,6 @@ import { Settings } from "./Settings/Settings";
import { ThemeEvents } from "./Themes/ui/Theme";
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
import { Terminal } from "./Terminal";
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
import { Money } from "./ui/React/Money";
import { Hashes } from "./ui/React/Hashes";
@ -121,20 +120,7 @@ const Engine: {
// Sleeves
for (let i = 0; i < Player.sleeves.length; ++i) {
if (Player.sleeves[i] instanceof Sleeve) {
const expForOtherSleeves = Player.sleeves[i].process(Player, numCycles);
// This sleeve earns experience for other sleeves
if (expForOtherSleeves == null) {
continue;
}
for (let j = 0; j < Player.sleeves.length; ++j) {
if (j === i) {
continue;
}
Player.sleeves[j].gainExperience(Player, expForOtherSleeves, numCycles, true);
}
}
Player.sleeves[i].process(Player, numCycles);
}
// Counters
@ -359,20 +345,7 @@ const Engine: {
// Sleeves offline progress
for (let i = 0; i < Player.sleeves.length; ++i) {
if (Player.sleeves[i] instanceof Sleeve) {
const expForOtherSleeves = Player.sleeves[i].process(Player, numCyclesOffline);
// This sleeve earns experience for other sleeves
if (expForOtherSleeves == null) {
continue;
}
for (let j = 0; j < Player.sleeves.length; ++j) {
if (j === i) {
continue;
}
Player.sleeves[j].gainExperience(Player, expForOtherSleeves, numCyclesOffline, true);
}
}
Player.sleeves[i].process(Player, numCyclesOffline);
}
// Update total playtime

@ -102,6 +102,10 @@ const getPlayerFields = [
"intelligence_exp",
"hp",
"max_hp",
"hasWseAccount",
"hasTixApiAccess",
"has4SData",
"has4SDataTixApi",
];
const mults = [