Initial commit for company code refactor. Split out all components into separate files and converted to typescript

This commit is contained in:
danielyxie 2018-11-15 17:28:23 -08:00
parent 23eef62332
commit d6bdc9433a
22 changed files with 170903 additions and 1557 deletions

58316
dist/engine.bundle.js vendored

File diff suppressed because one or more lines are too long

111045
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Bitburner</title> <title>Bitburner - development</title>
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
@ -471,7 +471,8 @@
<!-- Tutorial content --> <!-- Tutorial content -->
<div id="tutorial-container" class="generic-menupage-container"> <div id="tutorial-container" class="generic-menupage-container">
<a id="tutorial-getting-started-link" class="a-link-button" href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a> <a id="tutorial-getting-started-link" class="a-link-button"
href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a>
<a id="tutorial-networking-link" class="a-link-button"> Servers & Networking </a> <a id="tutorial-networking-link" class="a-link-button"> Servers & Networking </a>
<a id="tutorial-hacking-link" class="a-link-button"> Hacking </a> <a id="tutorial-hacking-link" class="a-link-button"> Hacking </a>
<a id="tutorial-scripts-link" class="a-link-button"> Scripts </a> <a id="tutorial-scripts-link" class="a-link-button"> Scripts </a>
@ -480,7 +481,8 @@
<a id="tutorial-jobs-link" class="a-link-button"> Companies and Infiltration </a> <a id="tutorial-jobs-link" class="a-link-button"> Companies and Infiltration </a>
<a id="tutorial-factions-link" class="a-link-button"> Factions </a> <a id="tutorial-factions-link" class="a-link-button"> Factions </a>
<a id="tutorial-augmentations-link" class="a-link-button"> Augmentations </a> <a id="tutorial-augmentations-link" class="a-link-button"> Augmentations </a>
<a id="tutorial-shortcuts-link" class="a-link-button" href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a> <a id="tutorial-shortcuts-link" class="a-link-button"
href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a>
<a id="tutorial-back-button" class="a-link-button"> Back </a> <a id="tutorial-back-button" class="a-link-button"> Back </a>
<p id="tutorial-text"> </p> <p id="tutorial-text"> </p>

32
src/Company/Companies.ts Normal file

@ -0,0 +1,32 @@
// Constructs all CompanyPosition objects using the metadata in data/companypositions.ts
import { companiesMetadata } from "./data/CompaniesMetadata";
import { Company, IConstructorParams } from "./Company";
import { IMap } from "../types";
import { Reviver } from "../../utils/JSONReviver";
export let Companies: IMap<Company> = {};
function addCompany(params: IConstructorParams) {
if (Companies[params.name] != null) {
console.warn(`Duplicate Company Position being defined: ${params.name}`);
}
Companies[params.name] = new Company(params);
}
// Used to initialize new Company objects for the Companies map
// Called when creating new game or after a prestige/reset
export function initCompanies() {
companiesMetadata.forEach((e) => {
addCompany(e);
});
}
// Used to load Companies map from a save
export function loadCompanies(saveString: string) {
Companies = JSON.parse(saveString, Reviver);
}
// Utility function to check if a string is valid company name
export function companyExists(name: string) {
return Companies.hasOwnProperty(name);
}

File diff suppressed because it is too large Load Diff

135
src/Company/Company.ts Normal file

@ -0,0 +1,135 @@
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { CompanyPosition } from "./CompanyPosition";
import { CONSTANTS } from "../Constants";
import { IMap } from "../types";
export interface IConstructorParams {
name: string;
info: string;
companyPositions: IMap<boolean>;
expMultiplier: number;
salaryMultiplier: number;
jobStatReqOffset: number;
}
const DefaultConstructorParams: IConstructorParams = {
name: "",
info: "",
companyPositions: {},
expMultiplier: 1,
salaryMultiplier: 1,
jobStatReqOffset: 0,
}
export class Company {
/**
* Initiatizes a Company from a JSON save state.
*/
static fromJSON(value: any): Company {
return Generic_fromJSON(Company, value.data);
}
/**
* Company name
*/
name: string;
/**
* Description and general information about company
*/
info: string;
/**
* Object that holds all available positions in this Company.
* Position names are held in keys.
* The values for the keys don't matter, but we'll make them booleans
*
* Must match names of Company Positions, defined in data/companypositionnames.ts
*/
companyPositions: IMap<boolean>;
/**
* Company-specific multiplier for earnings
*/
expMultiplier: number;
salaryMultiplier: number;
/**
* The additional levels of stats you need to quality for a job
* in this company.
*
* For example, the base stat requirement for an intern position is 1.
* But if a company has a offset of 200, then you would need stat(s) of 201
*/
jobStatReqOffset: number;
/**
* Properties to track the player's progress in this company
*/
isPlayerEmployed: boolean;
playerReputation: number;
favor: number;
rolloverRep: number;
constructor(p: IConstructorParams = DefaultConstructorParams) {
this.name = p.name;
this.info = p.info;
this.companyPositions = p.companyPositions;
this.expMultiplier = p.expMultiplier;
this.salaryMultiplier = p.salaryMultiplier;
this.jobStatReqOffset = p.jobStatReqOffset;
this.isPlayerEmployed = false;
this.playerReputation = 1;
this.favor = 0;
this.rolloverRep = 0;
}
hasPosition(pos: CompanyPosition | string): boolean {
if (pos instanceof CompanyPosition) {
return (this.companyPositions[pos.name] != null);
} else {
return (this.companyPositions[pos] != null);
}
}
gainFavor(): void {
if (this.favor == null) { this.favor = 0; }
if (this.rolloverRep == null) { this.rolloverRep = 0; }
var res = this.getFavorGain();
if (res.length != 2) {
console.error("Invalid result from getFavorGain() function");
return;
}
this.favor += res[0];
this.rolloverRep = res[1];
}
getFavorGain(): number[] {
if (this.favor == null) { this.favor = 0; }
if (this.rolloverRep == null) { this.rolloverRep = 0; }
let favorGain = 0, rep = this.playerReputation + this.rolloverRep;
let reqdRep = CONSTANTS.CompanyReputationToFavorBase *
Math.pow(CONSTANTS.CompanyReputationToFavorMult, this.favor);
while(rep > 0) {
if (rep >= reqdRep) {
++favorGain;
rep -= reqdRep;
} else {
break;
}
reqdRep *= CONSTANTS.FactionReputationToFavorMult;
}
return [favorGain, rep];
}
/**
* Serialize the current file to a JSON save state.
*/
toJSON(): any {
return Generic_toJSON("Company", this);
}
}
Reviver.constructors.Company = Company;

@ -1,12 +1,12 @@
import { Generic_fromJSON, Generic_toJSON, Reviver } from "/utils/JSONReviver"; import { CONSTANTS } from "../Constants";
import { CONSTANTS } from "/src/Constants"; import * as names from "./data/CompanyPositionNames";
import * as names from "/src/Company/data/companypositionname";
/* tslint:disable:completed-docs */ /* tslint:disable:completed-docs */
interface ConstructorParams { export interface IConstructorParams {
name: string, name: string;
baseSalary: number, nextPosition: string | null;
baseSalary: number;
repMultiplier: number; repMultiplier: number;
reqdHacking?: number; reqdHacking?: number;
@ -33,17 +33,15 @@ interface ConstructorParams {
} }
export class CompanyPosition { export class CompanyPosition {
/**
* Initializes a CompanyPosition object from a JSON save state
*/
static fromJSON(value: any): CompanyPosition {
return Generic_fromJSON(CompanyPosition, value.data);
}
/** /**
* Position title * Position title
*/ */
positionName: string; name: string;
/**
* Title of next position to be promoted to
*/
nextPosition: string | null;
/** /**
* Base salary for this position ($ per 200ms game cycle) * Base salary for this position ($ per 200ms game cycle)
@ -54,7 +52,7 @@ export class CompanyPosition {
/** /**
* Reputation multiplier * Reputation multiplier
*/ */
positionMultiplier: number; repMultiplier: number;
/** /**
* Required stats to earn this position * Required stats to earn this position
@ -91,18 +89,19 @@ export class CompanyPosition {
agilityExpGain: number; agilityExpGain: number;
charismaExpGain: number; charismaExpGain: number;
constructor(p: ConstructorParams) { constructor(p: IConstructorParams) {
this.name = p.name; this.name = p.name;
this.nextPosition = p.nextPosition;
this.baseSalary = p.baseSalary; this.baseSalary = p.baseSalary;
this.repMultiplier = p.repMultiplier; this.repMultiplier = p.repMultiplier;
this.reqdHacking = (p.reqdHacking != null) ? p.reqdHacking : 0; this.requiredHacking = (p.reqdHacking != null) ? p.reqdHacking : 0;
this.reqdStrength = (p.reqdStrength != null) ? p.reqdStrength : 0; this.requiredStrength = (p.reqdStrength != null) ? p.reqdStrength : 0;
this.reqdDefense = (p.reqdDefense != null) ? p.reqdDefense : 0; this.requiredDefense = (p.reqdDefense != null) ? p.reqdDefense : 0;
this.reqdDexterity = (p.reqdDexterity != null) ? p.reqdDexterity : 0; this.requiredDexterity = (p.reqdDexterity != null) ? p.reqdDexterity : 0;
this.reqdAgility = (p.reqdAgility != null) ? p.reqdAgility : 0; this.requiredAgility = (p.reqdAgility != null) ? p.reqdAgility : 0;
this.reqdCharisma = (p.reqdCharisma != null) ? p.reqdCharisma : 0; this.requiredCharisma = (p.reqdCharisma != null) ? p.reqdCharisma : 0;
this.reqdReputation = (p.reqdReputation != null) ? p.reqdReputation : 0; this.requiredReputation = (p.reqdReputation != null) ? p.reqdReputation : 0;
this.hackingEffectiveness = (p.hackingEffectiveness != null) ? p.hackingEffectiveness : 0; this.hackingEffectiveness = (p.hackingEffectiveness != null) ? p.hackingEffectiveness : 0;
this.strengthEffectiveness = (p.strengthEffectiveness != null) ? p.strengthEffectiveness : 0; this.strengthEffectiveness = (p.strengthEffectiveness != null) ? p.strengthEffectiveness : 0;
@ -132,7 +131,7 @@ export class CompanyPosition {
const agiRatio: number = this.agilityEffectiveness * agi / CONSTANTS.MaxSkillLevel; const agiRatio: number = this.agilityEffectiveness * agi / CONSTANTS.MaxSkillLevel;
const chaRatio: number = this.charismaEffectiveness * cha / CONSTANTS.MaxSkillLevel; const chaRatio: number = this.charismaEffectiveness * cha / CONSTANTS.MaxSkillLevel;
let reputationGain: number = this.positionMultiplier * (hackRatio + strRatio + defRatio + dexRatio + agiRatio + chaRatio) / 100; let reputationGain: number = this.repMultiplier * (hackRatio + strRatio + defRatio + dexRatio + agiRatio + chaRatio) / 100;
if (isNaN(reputationGain)) { if (isNaN(reputationGain)) {
console.error("Company reputation gain calculated to be NaN"); console.error("Company reputation gain calculated to be NaN");
reputationGain = 0; reputationGain = 0;
@ -180,13 +179,4 @@ export class CompanyPosition {
isPartTimeJob(): boolean { isPartTimeJob(): boolean {
return names.PartTimeCompanyPositions.includes(this.name); return names.PartTimeCompanyPositions.includes(this.name);
} }
/**
* Serialize the current file to a JSON save state.
*/
toJSON(): any {
return Generic_toJSON("CompanyPosition", this);
} }
}
Reviver.constructors.CompanyPosition = CompanyPosition;

@ -0,0 +1,17 @@
// Constructs all CompanyPosition objects using the metadata in data/companypositions.ts
import { companyPositionMetadata } from "./data/CompanyPositionsMetadata";
import { CompanyPosition, IConstructorParams } from "./CompanyPosition";
import { IMap } from "../types";
export const CompanyPositions: IMap<CompanyPosition> = {};
function addCompanyPosition(params: IConstructorParams) {
if (CompanyPositions[params.name] != null) {
console.warn(`Duplicate Company Position being defined: ${params.name}`);
}
CompanyPositions[params.name] = new CompanyPosition(params);
}
companyPositionMetadata.forEach((e) => {
addCompanyPosition(e);
});

@ -0,0 +1,40 @@
import { Company } from "./Company";
import { CompanyPosition } from "./CompanyPosition";
/**
* Returns a string with the given CompanyPosition's stat requirements
*/
export function getJobRequirementText(company: Company, pos: CompanyPosition, tooltiptext: boolean = false): string {
let reqText: string = "";
const offset: number = company.jobStatReqOffset;
const reqHacking: number = pos.requiredHacking > 0 ? pos.requiredHacking+offset : 0;
const reqStrength: number = pos.requiredStrength > 0 ? pos.requiredStrength+offset : 0;
const reqDefense: number = pos.requiredDefense > 0 ? pos.requiredDefense+offset : 0;
const reqDexterity: number = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
const reqAgility: number = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
const reqCharisma: number = pos.requiredCharisma > 0 ? pos.requiredCharisma+offset : 0;
const reqRep: number = pos.requiredReputation;
if (tooltiptext) {
reqText = "Requires:<br>";
reqText += (reqHacking.toString() + " hacking<br>");
reqText += (reqStrength.toString() + " strength<br>");
reqText += (reqDefense.toString() + " defense<br>");
reqText += (reqDexterity.toString() + " dexterity<br>");
reqText += (reqAgility.toString() + " agility<br>");
reqText += (reqCharisma.toString() + " charisma<br>");
reqText += (reqRep.toString() + " reputation");
} else {
reqText = "(Requires ";
if (reqHacking > 0) {reqText += (reqHacking + " hacking, ");}
if (reqStrength > 0) {reqText += (reqStrength + " strength, ");}
if (reqDefense > 0) {reqText += (reqDefense + " defense, ");}
if (reqDexterity > 0) {reqText += (reqDexterity + " dexterity, ");}
if (reqAgility > 0) {reqText += (reqAgility + " agility, ");}
if (reqCharisma > 0) {reqText += (reqCharisma + " charisma, ");}
if (reqRep > 1) {reqText += (reqRep + " reputation, ");}
reqText = reqText.substring(0, reqText.length - 2);
reqText += ")";
}
return reqText;
}

@ -0,0 +1,13 @@
// Function that returns the next Company Position in the "ladder"
// i.e. the next position to get promoted to
import { CompanyPosition } from "./CompanyPosition";
import { CompanyPositions } from "./CompanyPositions";
export function getNextCompanyPosition(currPos: CompanyPosition | null): CompanyPosition | null {
if (currPos == null) { return null; }
const nextPosName: string | null = currPos.nextPosition;
if (nextPosName == null) { return null; }
return CompanyPositions[nextPosName];
}

1
src/Company/README.md Normal file

@ -0,0 +1 @@
Implementation of Company and Job related mechanics

@ -0,0 +1,545 @@
import { IConstructorParams } from "../Company";
import { Locations } from "../../Locations";
import * as posNames from "./CompanyPositionNames";
import { SafeObjectAssign } from "../../../utils/SafeObjectAssign";
import { IMap } from "../../types";
// Create Objects containing Company Positions by category
// Will help in metadata construction later
const AllSoftwarePositions: IMap<boolean> = {};
const AllITPositions: IMap<boolean> = {};
const AllNetworkEngineerPositions: IMap<boolean> = {};
const AllTechnologyPositions: IMap<boolean> = {};
const AllBusinessPositions: IMap<boolean> = {};
const AllAgentPositions: IMap<boolean> = {};
const AllSecurityPositions: IMap<boolean> = {};
const AllSoftwareConsultantPositions: IMap<boolean> = {};
const AllBusinessConsultantPositions: IMap<boolean> = {};
const SoftwarePositionsUpToHeadOfEngineering: IMap<boolean> = {};
const SoftwarePositionsUpToLeadDeveloper: IMap<boolean> = {};
const BusinessPositionsUpToOperationsManager: IMap<boolean> = {};
const WaiterOnly: IMap<boolean> = {};
const EmployeeOnly: IMap<boolean> = {};
const PartTimeWaiterOnly: IMap<boolean> = {};
const PartTimeEmployeeOnly: IMap<boolean> = {};
const OperationsManagerOnly: IMap<boolean> = {};
const CEOOnly: IMap<boolean> = {};
posNames.SoftwareCompanyPositions.forEach((e) => {
AllSoftwarePositions[e] = true;
AllTechnologyPositions[e] = true;
});
posNames.ITCompanyPositions.forEach((e) => {
AllITPositions[e] = true;
AllTechnologyPositions[e] = true;
});
posNames.NetworkEngineerCompanyPositions.forEach((e) => {
AllNetworkEngineerPositions[e] = true;
AllTechnologyPositions[e] = true;
});
AllTechnologyPositions[posNames.SecurityEngineerCompanyPositions[0]] = true;
posNames.BusinessCompanyPositions.forEach((e) => {
AllBusinessPositions[e] = true;
});
posNames.SecurityCompanyPositions.forEach((e) => {
AllSecurityPositions[e] = true;
});
posNames.AgentCompanyPositions.forEach((e) => {
AllAgentPositions[e] = true;
});
posNames.SoftwareConsultantCompanyPositions.forEach((e) => {
AllSoftwareConsultantPositions[e] = true;
});
posNames.BusinessConsultantCompanyPositions.forEach((e) => {
AllBusinessConsultantPositions[e] = true;
});
for (let i = 0; i < posNames.SoftwareCompanyPositions.length; ++i) {
const e = posNames.SoftwareCompanyPositions[i];
if (i <= 5) {
SoftwarePositionsUpToHeadOfEngineering[e] = true;
}
if (i <= 3) {
SoftwarePositionsUpToLeadDeveloper[e] = true;
}
}
for (let i = 0; i < posNames.BusinessCompanyPositions.length; ++i) {
const e = posNames.BusinessCompanyPositions[i];
if (i <= 3) {
BusinessPositionsUpToOperationsManager[e] = true;
}
}
WaiterOnly[posNames.MiscCompanyPositions[0]] = true;
EmployeeOnly[posNames.MiscCompanyPositions[1]] = true;
PartTimeWaiterOnly[posNames.PartTimeCompanyPositions[0]] = true;
PartTimeEmployeeOnly[posNames.PartTimeCompanyPositions[1]] = true;
OperationsManagerOnly[posNames.BusinessCompanyPositions[3]] = true;
CEOOnly[posNames.BusinessCompanyPositions[5]] = true;
// Metadata
export const companiesMetadata: IConstructorParams[] = [
{
name: Locations.AevumECorp,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 3,
salaryMultiplier: 3,
jobStatReqOffset: 249,
},
{
name: Locations.Sector12MegaCorp,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 3,
salaryMultiplier: 3,
jobStatReqOffset: 249,
},
{
name: Locations.AevumBachmanAndAssociates,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.6,
salaryMultiplier: 2.6,
jobStatReqOffset: 224,
},
{
name: Locations.Sector12BladeIndustries,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.75,
salaryMultiplier: 2.75,
jobStatReqOffset: 224,
},
{
name: Locations.VolhavenNWO,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.75,
salaryMultiplier: 2.75,
jobStatReqOffset: 249,
},
{
name: Locations.AevumClarkeIncorporated,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.25,
salaryMultiplier: 2.25,
jobStatReqOffset: 224,
},
{
name: Locations.VolhavenOmniTekIncorporated,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.25,
salaryMultiplier: 2.25,
jobStatReqOffset: 224,
},
{
name: Locations.Sector12FourSigma,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.5,
salaryMultiplier: 2.5,
jobStatReqOffset: 224,
},
{
name: Locations.ChongqingKuaiGongInternational,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 2.2,
salaryMultiplier: 2.2,
jobStatReqOffset: 224,
},
{
name: Locations.AevumFulcrumTechnologies,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions
),
expMultiplier: 2,
salaryMultiplier: 2,
jobStatReqOffset: 224,
},
{
name: Locations.IshimaStormTechnologies,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllSoftwareConsultantPositions,
AllBusinessPositions
),
expMultiplier: 1.8,
salaryMultiplier: 1.8,
jobStatReqOffset: 199,
},
{
name: Locations.NewTokyoDefComm,
info: "",
companyPositions: Object.assign({},
CEOOnly,
AllTechnologyPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.75,
salaryMultiplier: 1.75,
jobStatReqOffset: 199,
},
{
name: Locations.VolhavenHeliosLabs,
info: "",
companyPositions: Object.assign({},
CEOOnly,
AllTechnologyPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.8,
salaryMultiplier: 1.8,
jobStatReqOffset: 199,
},
{
name: Locations.NewTokyoVitaLife,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.8,
salaryMultiplier: 1.8,
jobStatReqOffset: 199,
},
{
name: Locations.Sector12IcarusMicrosystems,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.9,
salaryMultiplier: 1.9,
jobStatReqOffset: 199,
},
{
name: Locations.Sector12UniversalEnergy,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 2,
salaryMultiplier: 2,
jobStatReqOffset: 199,
},
{
name: Locations.AevumGalacticCybersystems,
info: "",
companyPositions: Object.assign({},
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.9,
salaryMultiplier: 1.9,
jobStatReqOffset: 199,
},
{
name: Locations.AevumAeroCorp,
info: "",
companyPositions: Object.assign({},
CEOOnly,
OperationsManagerOnly,
AllTechnologyPositions,
AllSecurityPositions
),
expMultiplier: 1.7,
salaryMultiplier: 1.7,
jobStatReqOffset: 199,
},
{
name: Locations.VolhavenOmniaCybersystems,
info: "",
companyPositions: SafeObjectAssign(
CEOOnly,
OperationsManagerOnly,
AllTechnologyPositions,
AllSecurityPositions,
),
expMultiplier: 1.7,
salaryMultiplier: 1.7,
jobStatReqOffset: 199,
},
{
name: Locations.ChongqingSolarisSpaceSystems,
info: "",
companyPositions: SafeObjectAssign(
CEOOnly,
OperationsManagerOnly,
AllTechnologyPositions,
AllSecurityPositions,
),
expMultiplier: 1.7,
salaryMultiplier: 1.7,
jobStatReqOffset: 199,
},
{
name: Locations.Sector12DeltaOne,
info: "",
companyPositions: SafeObjectAssign(
CEOOnly,
OperationsManagerOnly,
AllTechnologyPositions,
AllSecurityPositions,
),
expMultiplier: 1.6,
salaryMultiplier: 1.6,
jobStatReqOffset: 199,
},
{
name: Locations.NewTokyoGlobalPharmaceuticals,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions,
AllSecurityPositions
),
expMultiplier: 1.8,
salaryMultiplier: 1.8,
jobStatReqOffset: 224,
},
{
name: Locations.IshimaNovaMedical,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions,
AllBusinessPositions,
AllSoftwareConsultantPositions,
AllSecurityPositions
),
expMultiplier: 1.75,
salaryMultiplier: 1.75,
jobStatReqOffset: 199,
},
{
name: Locations.Sector12CIA,
info: "",
companyPositions: SafeObjectAssign(
SoftwarePositionsUpToHeadOfEngineering,
AllNetworkEngineerPositions,
AllITPositions,
AllSecurityPositions,
AllAgentPositions
),
expMultiplier: 2,
salaryMultiplier: 2,
jobStatReqOffset: 149,
},
{
name: Locations.Sector12NSA,
info: "",
companyPositions: SafeObjectAssign(
SoftwarePositionsUpToHeadOfEngineering,
AllNetworkEngineerPositions,
AllITPositions,
AllSecurityPositions,
AllAgentPositions
),
expMultiplier: 2,
salaryMultiplier: 2,
jobStatReqOffset: 149,
},
{
name: Locations.AevumWatchdogSecurity,
info: "",
companyPositions: SafeObjectAssign(
SoftwarePositionsUpToHeadOfEngineering,
AllNetworkEngineerPositions,
AllITPositions,
AllSecurityPositions,
AllAgentPositions,
AllSoftwareConsultantPositions
),
expMultiplier: 1.5,
salaryMultiplier: 1.5,
jobStatReqOffset: 124,
},
{
name: Locations.VolhavenLexoCorp,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions,
AllSoftwareConsultantPositions,
AllBusinessPositions,
AllSecurityPositions
),
expMultiplier: 1.4,
salaryMultiplier: 1.4,
jobStatReqOffset: 99,
},
{
name: Locations.AevumRhoConstruction,
info: "",
companyPositions: SafeObjectAssign(
SoftwarePositionsUpToLeadDeveloper,
BusinessPositionsUpToOperationsManager
),
expMultiplier: 1.3,
salaryMultiplier: 1.3,
jobStatReqOffset: 49,
},
{
name: Locations.Sector12AlphaEnterprises,
info: "",
companyPositions: SafeObjectAssign(
SoftwarePositionsUpToLeadDeveloper,
BusinessPositionsUpToOperationsManager,
AllSoftwareConsultantPositions
),
expMultiplier: 1.5,
salaryMultiplier: 1.5,
jobStatReqOffset: 99,
},
{
name: Locations.AevumPolice,
info: "",
companyPositions: SafeObjectAssign(
AllSecurityPositions,
SoftwarePositionsUpToLeadDeveloper
),
expMultiplier: 1.3,
salaryMultiplier: 1.3,
jobStatReqOffset: 99,
},
{
name: Locations.VolhavenSysCoreSecurities,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions
),
expMultiplier: 1.3,
salaryMultiplier: 1.3,
jobStatReqOffset: 124,
},
{
name: Locations.VolhavenCompuTek,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions
),
expMultiplier: 1.2,
salaryMultiplier: 1.2,
jobStatReqOffset: 74,
},
{
name: Locations.AevumNetLinkTechnologies,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions
),
expMultiplier: 1.2,
salaryMultiplier: 1.2,
jobStatReqOffset: 99,
},
{
name: Locations.Sector12CarmichaelSecurity,
info: "",
companyPositions: SafeObjectAssign(
AllTechnologyPositions,
AllAgentPositions,
AllSecurityPositions
),
expMultiplier: 1.2,
salaryMultiplier: 1.2,
jobStatReqOffset: 74,
},
{
name: Locations.Sector12FoodNStuff,
info: "",
companyPositions: SafeObjectAssign(
EmployeeOnly, PartTimeEmployeeOnly
),
expMultiplier: 1,
salaryMultiplier: 1,
jobStatReqOffset: 0,
},
{
name: Locations.Sector12JoesGuns,
info: "",
companyPositions: SafeObjectAssign(
EmployeeOnly, PartTimeEmployeeOnly
),
expMultiplier: 1,
salaryMultiplier: 1,
jobStatReqOffset: 0,
},
{
name: Locations.IshimaOmegaSoftware,
info: "",
companyPositions: SafeObjectAssign(
AllSoftwarePositions,
AllSoftwareConsultantPositions,
AllITPositions
),
expMultiplier: 1.1,
salaryMultiplier: 1.1,
jobStatReqOffset: 49,
},
{
name: Locations.NewTokyoNoodleBar,
info: "",
companyPositions: SafeObjectAssign(
WaiterOnly, PartTimeWaiterOnly
),
expMultiplier: 1,
salaryMultiplier: 1,
jobStatReqOffset: 0,
},
]

@ -0,0 +1,602 @@
// Metadata used for constructing Company Positions
import { IConstructorParams } from "../CompanyPosition";
import * as posNames from "./CompanyPositionNames";
export const companyPositionMetadata: IConstructorParams[] = [
{
name: posNames.SoftwareCompanyPositions[0], // Software Enginering Intern
nextPosition: posNames.SoftwareCompanyPositions[1], // Junior Software Engineer
baseSalary: 33,
charismaEffectiveness: 15,
charismaExpGain: 0.02,
hackingEffectiveness: 85,
hackingExpGain: 0.05,
reqdHacking: 1,
repMultiplier: 0.9,
},
{
name: posNames.SoftwareCompanyPositions[1], // Junior Software Engineer
nextPosition: posNames.SoftwareCompanyPositions[2], // Senior Software Engineer
baseSalary: 80,
charismaEffectiveness: 15,
charismaExpGain: 0.05,
hackingEffectiveness: 85,
hackingExpGain: 0.1,
reqdHacking: 51,
reqdReputation: 8e3,
repMultiplier: 1.1,
},
{
name: posNames.SoftwareCompanyPositions[2], // Senior Software Engineer
nextPosition: posNames.SoftwareCompanyPositions[3], // Lead Software Developer
baseSalary: 165,
charismaEffectiveness: 20,
charismaExpGain: 0.08,
hackingEffectiveness: 80,
hackingExpGain: 0.4,
reqdCharisma: 51,
reqdHacking: 251,
reqdReputation: 40e3,
repMultiplier: 1.3,
},
{
name: posNames.SoftwareCompanyPositions[3], // Lead Software Developer
nextPosition: posNames.SoftwareCompanyPositions[4], // Head of Software
baseSalary: 500,
charismaEffectiveness: 25,
charismaExpGain: 0.1,
hackingEffectiveness: 75,
hackingExpGain: 0.8,
reqdCharisma: 151,
reqdHacking: 401,
reqdReputation: 200e3,
repMultiplier: 1.5,
},
{
name: posNames.SoftwareCompanyPositions[4], // Head of Software
nextPosition: posNames.SoftwareCompanyPositions[5], // Head of Engineering
baseSalary: 800,
charismaEffectiveness: 25,
charismaExpGain: 0.5,
hackingEffectiveness: 75,
hackingExpGain: 1,
reqdCharisma: 251,
reqdHacking: 501,
reqdReputation: 400e3,
repMultiplier: 1.6,
},
{
name: posNames.SoftwareCompanyPositions[5], // Head of Engineering
nextPosition: posNames.SoftwareCompanyPositions[6], // Vice President of Technology
baseSalary: 1650,
charismaEffectiveness: 25,
charismaExpGain: 0.5,
hackingEffectiveness: 75,
hackingExpGain: 1.1,
reqdCharisma: 251,
reqdHacking: 501,
reqdReputation: 800e3,
repMultiplier: 1.6,
},
{
name: posNames.SoftwareCompanyPositions[6], // Vice President of Technology
nextPosition: posNames.SoftwareCompanyPositions[7], // Chief Technology Officer
baseSalary: 2310,
charismaEffectiveness: 30,
charismaExpGain: 0.6,
hackingEffectiveness: 70,
hackingExpGain: 1.2,
reqdCharisma: 401,
reqdHacking: 601,
reqdReputation: 1.6e6,
repMultiplier: 1.75,
},
{
name: posNames.SoftwareCompanyPositions[7], // Chief Technology Officer
nextPosition: null,
baseSalary: 2640,
charismaEffectiveness: 35,
charismaExpGain: 1,
hackingEffectiveness: 65,
hackingExpGain: 1.5,
reqdCharisma: 501,
reqdHacking: 751,
reqdReputation: 3.2e6,
repMultiplier: 2,
},
{
name: posNames.ITCompanyPositions[0], // IT Intern
nextPosition: posNames.ITCompanyPositions[1], // IT Analyst
baseSalary: 26,
charismaEffectiveness: 10,
charismaExpGain: 0.01,
hackingEffectiveness: 90,
hackingExpGain: 0.04,
reqdHacking: 1,
repMultiplier: 0.9,
},
{
name: posNames.ITCompanyPositions[1], // IT Analyst
nextPosition: posNames.ITCompanyPositions[2], // IT Manager
baseSalary: 66,
charismaEffectiveness: 15,
charismaExpGain: 0.02,
hackingEffectiveness: 85,
hackingExpGain: 0.08,
reqdHacking: 26,
reqdReputation: 7e3,
repMultiplier: 1.1,
},
{
name: posNames.ITCompanyPositions[2], // IT Manager
nextPosition: posNames.ITCompanyPositions[3], // Systems Administrator
baseSalary: 132,
charismaEffectiveness: 20,
charismaExpGain: 0.1,
hackingEffectiveness: 80,
hackingExpGain: 0.3,
reqdCharisma: 51,
reqdHacking: 151,
reqdReputation: 35e3,
repMultiplier: 1.3,
},
{
name: posNames.ITCompanyPositions[3], // Systems Administrator
nextPosition: posNames.SoftwareCompanyPositions[5], // Head of Engineering
baseSalary: 410,
charismaEffectiveness: 20,
charismaExpGain: 0.2,
hackingEffectiveness: 80,
hackingExpGain: 0.5,
reqdCharisma: 76,
reqdHacking: 251,
reqdReputation: 175e3,
repMultiplier: 1.4,
},
{
name: posNames.SecurityEngineerCompanyPositions[0], // Security Engineer
nextPosition: posNames.SoftwareCompanyPositions[5], // Head of Engineering
baseSalary: 121,
charismaEffectiveness: 15,
charismaExpGain: 0.05,
hackingEffectiveness: 85,
hackingExpGain: 0.4,
reqdCharisma: 26,
reqdHacking: 151,
reqdReputation: 35e3,
repMultiplier: 1.2,
},
{
name: posNames.NetworkEngineerCompanyPositions[0], // Network Engineer
nextPosition: posNames.NetworkEngineerCompanyPositions[1], // Network Adminsitrator
baseSalary: 121,
charismaEffectiveness: 15,
charismaExpGain: 0.05,
hackingEffectiveness: 85,
hackingExpGain: 0.4,
reqdCharisma: 26,
reqdHacking: 151,
reqdReputation: 35e3,
repMultiplier: 1.2,
},
{
name: posNames.NetworkEngineerCompanyPositions[1], // Network Administrator
nextPosition: posNames.SoftwareCompanyPositions[5], // Head of Engineering
baseSalary: 410,
charismaEffectiveness: 20,
charismaExpGain: 0.1,
hackingEffectiveness: 0.80,
hackingExpGain: 0.5,
reqdCharisma: 76,
reqdHacking: 251,
reqdReputation: 175e3,
repMultiplier: 1.3,
},
{
name: posNames.BusinessCompanyPositions[0], // Business Intern
nextPosition: posNames.BusinessCompanyPositions[1], // Business Analyst
baseSalary: 46,
charismaEffectiveness: 90,
charismaExpGain: 0.08,
hackingEffectiveness: 10,
hackingExpGain: 0.01,
reqdCharisma: 1,
reqdHacking: 1,
repMultiplier: 0.9,
},
{
name: posNames.BusinessCompanyPositions[1], // Business Analyst
nextPosition: posNames.BusinessCompanyPositions[2], // Business Manager
baseSalary: 100,
charismaEffectiveness: 85,
charismaExpGain: 0.15,
hackingEffectiveness: 15,
hackingExpGain: 0.02,
reqdCharisma: 51,
reqdHacking: 6,
reqdReputation: 8e3,
repMultiplier: 1.1,
},
{
name: posNames.BusinessCompanyPositions[2], // Business Manager
nextPosition: posNames.BusinessCompanyPositions[3], // Operations Manager
baseSalary: 200,
charismaEffectiveness: 85,
charismaExpGain: 0.3,
hackingEffectiveness: 15,
hackingExpGain: 0.02,
reqdCharisma: 101,
reqdHacking: 51,
reqdReputation: 40e3,
repMultiplier: 1.3,
},
{
name: posNames.BusinessCompanyPositions[3], // Operations Manager
nextPosition: posNames.BusinessCompanyPositions[4], // Chief Financial Officer
baseSalary: 660,
charismaEffectiveness: 85,
charismaExpGain: 0.4,
hackingEffectiveness: 15,
hackingExpGain: 0.02,
reqdCharisma: 226,
reqdHacking: 51,
reqdReputation: 200e3,
repMultiplier: 1.5,
},
{
name: posNames.BusinessCompanyPositions[4], // Chief Financial Officer
nextPosition: posNames.BusinessCompanyPositions[5], // Chief Executive Officer
baseSalary: 1950,
charismaEffectiveness: 90,
charismaExpGain: 1,
hackingEffectiveness: 10,
hackingExpGain: 0.05,
reqdCharisma: 501,
reqdHacking: 76,
reqdReputation: 800e3,
repMultiplier: 1.6,
},
{
name: posNames.BusinessCompanyPositions[5], // Chief Executive Officer
nextPosition: null,
baseSalary: 3900,
charismaEffectiveness: 90,
charismaExpGain: 1.5,
hackingEffectiveness: 10,
hackingExpGain: 0.05,
reqdCharisma: 751,
reqdHacking: 101,
reqdReputation: 3.2e6,
repMultiplier: 1.75,
},
{
name: posNames.SecurityCompanyPositions[0], // Police Officer
nextPosition: posNames.SecurityCompanyPositions[1], // Police Chief
baseSalary: 82,
hackingEffectiveness: 5,
strengthEffectiveness: 20,
defenseEffectiveness: 20,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 15,
hackingExpGain: 0.02,
strengthExpGain: 0.08,
defenseExpGain: 0.08,
dexterityExpGain: 0.08,
agilityExpGain: 0.08,
charismaExpGain: 0.04,
reqdHacking: 11,
reqdStrength: 101,
reqdDefense: 101,
reqdDexterity: 101,
reqdAgility: 101,
reqdCharisma: 51,
reqdReputation: 8e3,
repMultiplier: 1,
},
{
name: posNames.SecurityCompanyPositions[1], // Police Chief
nextPosition: null,
baseSalary: 460,
hackingEffectiveness: 5,
strengthEffectiveness: 20,
defenseEffectiveness: 20,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 15,
hackingExpGain: 0.02,
strengthExpGain: 0.1,
defenseExpGain: 0.1,
dexterityExpGain: 0.1,
agilityExpGain: 0.1,
charismaExpGain: 0.1,
reqdHacking: 101,
reqdStrength: 301,
reqdDefense: 301,
reqdDexterity: 301,
reqdAgility: 301,
reqdCharisma: 151,
reqdReputation: 36e3,
repMultiplier: 1.25,
},
{
name: posNames.SecurityCompanyPositions[2], // Security Guard
nextPosition: posNames.SecurityCompanyPositions[3], // Security Officer
baseSalary: 50,
hackingEffectiveness: 5,
strengthEffectiveness: 20,
defenseEffectiveness: 20,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 15,
hackingExpGain: 0.01,
strengthExpGain: 0.04,
defenseExpGain: 0.04,
dexterityExpGain: 0.04,
agilityExpGain: 0.04,
charismaExpGain: 0.02,
reqdStrength: 51,
reqdDefense: 51,
reqdDexterity: 51,
reqdAgility: 51,
reqdCharisma: 1,
repMultiplier: 1,
},
{
name: posNames.SecurityCompanyPositions[3], // Security Officer
nextPosition: posNames.SecurityCompanyPositions[4], // Security Supervisor
baseSalary: 195,
hackingEffectiveness: 10,
strengthEffectiveness: 20,
defenseEffectiveness: 20,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 10,
hackingExpGain: 0.02,
strengthExpGain: 0.1,
defenseExpGain: 0.1,
dexterityExpGain: 0.1,
agilityExpGain: 0.1,
charismaExpGain: 0.05,
reqdHacking: 26,
reqdStrength: 151,
reqdDefense: 151,
reqdDexterity: 151,
reqdAgility: 151,
reqdCharisma: 51,
reqdReputation: 8e3,
repMultiplier: 1.1,
},
{
name: posNames.SecurityCompanyPositions[4], // Security Supervisor
nextPosition: posNames.SecurityCompanyPositions[5], // Head of Security
baseSalary: 660,
hackingEffectiveness: 10,
strengthEffectiveness: 15,
defenseEffectiveness: 15,
dexterityEffectiveness: 15,
agilityEffectiveness: 15,
charismaEffectiveness: 30,
hackingExpGain: 0.02,
strengthExpGain: 0.12,
defenseExpGain: 0.12,
dexterityExpGain: 0.12,
agilityExpGain: 0.12,
charismaExpGain: 0.1,
reqdHacking: 26,
reqdStrength: 251,
reqdDefense: 251,
reqdDexterity: 251,
reqdAgility: 251,
reqdCharisma: 101,
reqdReputation: 36e3,
repMultiplier: 1.25,
},
{
name: posNames.SecurityCompanyPositions[5], // Head of Security
nextPosition: null,
baseSalary: 1320,
hackingEffectiveness: 10,
strengthEffectiveness: 15,
defenseEffectiveness: 15,
dexterityEffectiveness: 15,
agilityEffectiveness: 15,
charismaEffectiveness: 30,
hackingExpGain: 0.05,
strengthExpGain: 0.15,
defenseExpGain: 0.15,
dexterityExpGain: 0.15,
agilityExpGain: 0.15,
charismaExpGain: 0.15,
reqdHacking: 51,
reqdStrength: 501,
reqdDefense: 501,
reqdDexterity: 501,
reqdAgility: 501,
reqdCharisma: 151,
reqdReputation: 144e3,
repMultiplier: 1.4,
},
{
name: posNames.AgentCompanyPositions[0], // Field Agent
nextPosition: posNames.AgentCompanyPositions[0], // Secret Agent
baseSalary: 330,
hackingEffectiveness: 10,
strengthEffectiveness: 15,
defenseEffectiveness: 15,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 20,
hackingExpGain: 0.04,
strengthExpGain: 0.08,
defenseExpGain: 0.08,
dexterityExpGain: 0.08,
agilityExpGain: 0.08,
charismaExpGain: 0.05,
reqdHacking: 101,
reqdStrength: 101,
reqdDefense: 101,
reqdDexterity: 101,
reqdAgility: 101,
reqdCharisma: 101,
reqdReputation: 8e3,
repMultiplier: 1,
},
{
name: posNames.AgentCompanyPositions[0], // Secret Agent
nextPosition: posNames.AgentCompanyPositions[0], // Special Operative
baseSalary: 990,
hackingEffectiveness: 15,
strengthEffectiveness: 15,
defenseEffectiveness: 15,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 15,
hackingExpGain: 0.1,
strengthExpGain: 0.15,
defenseExpGain: 0.15,
dexterityExpGain: 0.15,
agilityExpGain: 0.15,
charismaExpGain: 0.1,
reqdHacking: 201,
reqdStrength: 251,
reqdDefense: 251,
reqdDexterity: 251,
reqdAgility: 251,
reqdCharisma: 201,
reqdReputation: 32e3,
repMultiplier: 1.25,
},
{
name: posNames.AgentCompanyPositions[0], // Special Operative
nextPosition: null,
baseSalary: 2000,
hackingEffectiveness: 15,
strengthEffectiveness: 15,
defenseEffectiveness: 15,
dexterityEffectiveness: 20,
agilityEffectiveness: 20,
charismaEffectiveness: 15,
hackingExpGain: 0.15,
strengthExpGain: 0.2,
defenseExpGain: 0.2,
dexterityExpGain: 0.2,
agilityExpGain: 0.2,
charismaExpGain: 0.15,
reqdHacking: 251,
reqdStrength: 501,
reqdDefense: 501,
reqdDexterity: 501,
reqdAgility: 501,
reqdCharisma: 251,
reqdReputation: 162e3,
repMultiplier: 1.5,
},
{
name: posNames.MiscCompanyPositions[0], // Waiter
nextPosition: null,
baseSalary: 22,
strengthEffectiveness: 10,
dexterityEffectiveness: 10,
agilityEffectiveness: 10,
charismaEffectiveness: 70,
strengthExpGain: 0.02,
defenseExpGain: 0.02,
dexterityExpGain: 0.02,
agilityExpGain: 0.02,
charismaExpGain: 0.05,
repMultiplier: 1,
},
{
name: posNames.MiscCompanyPositions[1], // Employee
nextPosition: null,
baseSalary: 22,
strengthEffectiveness: 10,
dexterityEffectiveness: 10,
agilityEffectiveness: 10,
charismaEffectiveness: 70,
strengthExpGain: 0.02,
defenseExpGain: 0.02,
dexterityExpGain: 0.02,
agilityExpGain: 0.02,
charismaExpGain: 0.04,
repMultiplier: 1,
},
{
name: posNames.SoftwareConsultantCompanyPositions[0], // Software Consultant
nextPosition: posNames.SoftwareConsultantCompanyPositions[1], // Senior Software Consultant
baseSalary: 66,
hackingEffectiveness: 80,
charismaEffectiveness: 20,
hackingExpGain: 0.08,
charismaExpGain: 0.03,
reqdHacking: 51,
repMultiplier: 1,
},
{
name: posNames.SoftwareConsultantCompanyPositions[1], // Senior Software Consultant
nextPosition: null,
baseSalary: 132,
hackingEffectiveness: 75,
charismaEffectiveness: 25,
hackingExpGain: 0.25,
charismaExpGain: 0.06,
reqdHacking: 251,
reqdCharisma: 51,
repMultiplier: 1.2,
},
{
name: posNames.BusinessConsultantCompanyPositions[0], // Business Consultant
nextPosition: posNames.BusinessConsultantCompanyPositions[1], // Senior Business Consultant
baseSalary: 66,
hackingEffectiveness: 20,
charismaEffectiveness: 80,
hackingExpGain: 0.015,
charismaExpGain: 0.15,
reqdHacking: 6,
reqdCharisma: 51,
repMultiplier: 1,
},
{
name: posNames.BusinessConsultantCompanyPositions[0], // Senior Business Consultant
nextPosition: null,
baseSalary: 525,
hackingEffectiveness: 15,
charismaEffectiveness: 85,
hackingExpGain: 0.015,
charismaExpGain: 0.3,
reqdHacking: 51,
reqdCharisma: 226,
repMultiplier: 1.2,
},
{
name: posNames.PartTimeCompanyPositions[0], // Part-time waiter
nextPosition: null,
baseSalary: 20,
strengthEffectiveness: 10,
dexterityEffectiveness: 10,
agilityEffectiveness: 10,
charismaEffectiveness: 70,
strengthExpGain: 0.0075,
defenseExpGain: 0.0075,
dexterityExpGain: 0.0075,
agilityExpGain: 0.0075,
charismaExpGain: 0.04,
repMultiplier: 1,
},
{
name: posNames.PartTimeCompanyPositions[1], // Part-time employee
nextPosition: null,
baseSalary: 20,
strengthEffectiveness: 10,
dexterityEffectiveness: 10,
agilityEffectiveness: 10,
charismaEffectiveness: 70,
strengthExpGain: 0.0075,
defenseExpGain: 0.0075,
dexterityExpGain: 0.0075,
agilityExpGain: 0.0075,
charismaExpGain: 0.03,
repMultiplier: 1,
},
]

@ -1,3 +1,5 @@
// Defs for job titles, stored in arrays and categorized by job "type"
export const SoftwareCompanyPositions: string[] = [ export const SoftwareCompanyPositions: string[] = [
"Software Engineering Intern", "Software Engineering Intern",
"Junior Software Engineer", "Junior Software Engineer",
@ -35,8 +37,9 @@ export const BusinessCompanyPositions: string[] = [
]; ];
export const SecurityCompanyPositions: string[] = [ export const SecurityCompanyPositions: string[] = [
"Security Guard",
"Police Officer", "Police Officer",
"Police Chief",
"Security Guard",
"Security Officer", "Security Officer",
"Security Supervisor", "Security Supervisor",
"Head of Security" "Head of Security"
@ -48,6 +51,11 @@ export const AgentCompanyPositions: string[] = [
"Special Operative" "Special Operative"
]; ];
export const MiscCompanyPositions: string[] = [
"Waiter",
"Employee"
];
export const SoftwareConsultantCompanyPositions: string[] = [ export const SoftwareConsultantCompanyPositions: string[] = [
"Software Consultant", "Software Consultant",
"Senior Software Consultant" "Senior Software Consultant"

@ -1,4 +1,6 @@
let CONSTANTS = { import {IMap} from "./types";
export let CONSTANTS: IMap<any> = {
Version: "0.41.0", Version: "0.41.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
@ -515,5 +517,3 @@ let CONSTANTS = {
` `
} }
export {CONSTANTS};

@ -1,6 +1,8 @@
import {Bladeburner} from "./Bladeburner"; import {Bladeburner} from "./Bladeburner";
import {CompanyPositions, initCompanies, import {CompanyPositions} from "./Company/CompanyPositions";
Companies, getJobRequirementText} from "./Company"; import {Companies} from "./Company/Companies";
import {getJobRequirementText} from "./Company/GetJobRequirementText";
import * as posNames from "./Company/data/CompanyPositionNames";
import {Corporation} from "./CompanyManagement"; import {Corporation} from "./CompanyManagement";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {Crimes} from "./Crimes"; import {Crimes} from "./Crimes";
@ -241,7 +243,7 @@ function displayLocationContent() {
locationTxtDiv1.style.display = "block"; locationTxtDiv1.style.display = "block";
locationTxtDiv2.style.display = "block"; locationTxtDiv2.style.display = "block";
locationTxtDiv3.style.display = "block"; locationTxtDiv3.style.display = "block";
jobTitle.innerHTML = "Job Title: " + Player.companyPosition.positionName; jobTitle.innerHTML = "Job Title: " + Player.companyPosition;
var repGain = company.getFavorGain(); var repGain = company.getFavorGain();
if (repGain.length != 2) {repGain = 0;} if (repGain.length != 2) {repGain = 0;}
repGain = repGain[0]; repGain = repGain[0];
@ -301,19 +303,19 @@ function displayLocationContent() {
var hospitalTreatmentCost = (Player.max_hp - Player.hp) * CONSTANTS.HospitalCostPerHp; var hospitalTreatmentCost = (Player.max_hp - Player.hp) * CONSTANTS.HospitalCostPerHp;
//Set tooltip for job requirements //Set tooltip for job requirements
setJobRequirementTooltip(loc, CompanyPositions.SoftwareIntern, softwareJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.SoftwareCompanyPositions[0]], softwareJob);
setJobRequirementTooltip(loc, CompanyPositions.SoftwareConsultant, softwareConsultantJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]], softwareConsultantJob);
setJobRequirementTooltip(loc, CompanyPositions.ITIntern, itJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.ITCompanyPositions[0]], itJob);
setJobRequirementTooltip(loc, CompanyPositions.SecurityEngineer, securityEngineerJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.SecurityEngineerCompanyPositions[0]], securityEngineerJob);
setJobRequirementTooltip(loc, CompanyPositions.NetworkEngineer, networkEngineerJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]], networkEngineerJob);
setJobRequirementTooltip(loc, CompanyPositions.BusinessIntern, businessJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.BusinessCompanyPositions[0]], businessJob);
setJobRequirementTooltip(loc, CompanyPositions.BusinessConsultant, businessConsultantJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]], businessConsultantJob);
setJobRequirementTooltip(loc, CompanyPositions.SecurityGuard, securityJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.SecurityCompanyPositions[0]], securityJob);
setJobRequirementTooltip(loc, CompanyPositions.FieldAgent, agentJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.AgentCompanyPositions[0]], agentJob);
setJobRequirementTooltip(loc, CompanyPositions.Employee, employeeJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.MiscCompanyPositions[1]], employeeJob);
setJobRequirementTooltip(loc, CompanyPositions.PartTimeEmployee, employeePartTimeJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.PartTimeCompanyPositions[1]], employeePartTimeJob);
setJobRequirementTooltip(loc, CompanyPositions.Waiter, waiterJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.MiscCompanyPositions[0]], waiterJob);
setJobRequirementTooltip(loc, CompanyPositions.PartTimeWaiter, waiterPartTimeJob); setJobRequirementTooltip(loc, CompanyPositions[posNames.PartTimeCompanyPositions[0]], waiterPartTimeJob);
switch (loc) { switch (loc) {
case Locations.AevumTravelAgency: case Locations.AevumTravelAgency:
@ -1035,13 +1037,13 @@ function displayLocationContent() {
if (loc == Player.companyName) { if (loc == Player.companyName) {
var currPos = Player.companyPosition; var currPos = Player.companyPosition;
if (currPos.positionName == CompanyPositions.Employee.positionName) { if (currPos.name == "Employee") {
employeeJob.style.display = "none"; employeeJob.style.display = "none";
} else if (currPos.positionName == CompanyPositions.Waiter.positionName) { } else if (currPos.name == "Waiter") {
waiterJob.style.display = "none"; waiterJob.style.display = "none";
} else if (currPos.positionName == CompanyPositions.PartTimeEmployee.positionName) { } else if (currPos.name == "Part-time Employee") {
employeePartTimeJob.style.display = "none"; employeePartTimeJob.style.display = "none";
} else if (currPos.positionName == CompanyPositions.PartTimeWaiter.positionName) { } else if (currPos.name == "Part-time Waiter") {
waiterPartTimeJob.style.display = "none"; waiterPartTimeJob.style.display = "none";
} }
} }

@ -8,8 +8,10 @@ import {Augmentations, Augmentation,
import {BitNodeMultipliers} from "./BitNodeMultipliers"; import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {determineCrimeSuccess, findCrime} from "./Crimes"; import {determineCrimeSuccess, findCrime} from "./Crimes";
import {Bladeburner} from "./Bladeburner"; import {Bladeburner} from "./Bladeburner";
import {Companies, Company, CompanyPosition, import {Company} from "./Company/Company";
CompanyPositions, companyExists} from "./Company"; import {Companies, companyExists} from "./Company/Companies";
import {CompanyPosition} from "./Company/CompanyPosition";
import {CompanyPositions} from "./Company/CompanyPositions";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {Programs} from "./CreateProgram"; import {Programs} from "./CreateProgram";
import {DarkWebItems} from "./DarkWeb"; import {DarkWebItems} from "./DarkWeb";
@ -2692,8 +2694,8 @@ function NetscriptFunctions(workerScript) {
} }
var companyPositionTitle = ""; var companyPositionTitle = "";
if (Player.companyPosition instanceof CompanyPosition) { if (CompanyPositions[Player.companyPosition] instanceof CompanyPosition) {
companyPositionTitle = Player.companyPosition.positionName; companyPositionTitle = Player.companyPosition;
} }
return { return {
bitnode: Player.bitNodeN, bitnode: Player.bitNodeN,
@ -2834,7 +2836,8 @@ function NetscriptFunctions(workerScript) {
return; return;
} }
if (Player.companyPosition == "" || !(Player.companyPosition instanceof CompanyPosition)) { const companyPosition = CompanyPositions[Player.companyPosition];
if (Player.companyPosition === "" || !(companyPosition instanceof CompanyPosition)) {
workerScript.scriptRef.log("ERROR: workForCompany() failed because you do not have a job"); workerScript.scriptRef.log("ERROR: workForCompany() failed because you do not have a job");
return false; return false;
} }
@ -2846,13 +2849,13 @@ function NetscriptFunctions(workerScript) {
} }
} }
if (Player.companyPosition.isPartTimeJob()) { if (companyPosition.isPartTimeJob()) {
Player.startWorkPartTime(); Player.startWorkPartTime();
} else { } else {
Player.startWork(); Player.startWork();
} }
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.workForCompany == null) { if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.workForCompany == null) {
workerScript.scriptRef.log("Began working at " + Player.companyName + " as a " + Player.companyPosition.positionName); workerScript.log(`Began working at ${Player.companyName} as a ${Player.companyPosition}`);
} }
return true; return true;
}, },
@ -2928,11 +2931,11 @@ function NetscriptFunctions(workerScript) {
} }
if (res) { if (res) {
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.applyToCompany == null) { if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.applyToCompany == null) {
workerScript.scriptRef.log("You were offered a new job at " + companyName + " as a " + Player.companyPosition.positionName); workerScript.log(`You were offered a new job at ${companyName} as a ${Player.companyPosition}`);
} }
} else { } else {
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.applyToCompany == null) { if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.applyToCompany == null) {
workerScript.scriptRef.log("You failed to get a new job/promotion at " + companyName + " in the " + field + " field."); workerScript.log(`You failed to get a new job/promotion at ${companyName} in the ${field} field.`);
} }
} }
return res; return res;

@ -3,9 +3,11 @@ import {Augmentations, applyAugmentation,
PlayerOwnedAugmentation} from "./Augmentations"; PlayerOwnedAugmentation} from "./Augmentations";
import {BitNodeMultipliers} from "./BitNodeMultipliers"; import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CodingContractRewardType} from "./CodingContracts"; import {CodingContractRewardType} from "./CodingContracts";
import {Company, Companies, getNextCompanyPosition, import {Company} from "./Company/Company";
getJobRequirementText, CompanyPosition, import {Companies} from "./Company/Companies";
CompanyPositions} from "./Company"; import {getNextCompanyPosition} from "./Company/GetNextCompanyPosition";
import {getJobRequirementText} from "./Company/GetJobRequirementText";
import {CompanyPositions} from "./Company/CompanyPositions";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {Corporation} from "./CompanyManagement"; import {Corporation} from "./CompanyManagement";
import {Programs} from "./CreateProgram"; import {Programs} from "./CreateProgram";
@ -94,8 +96,8 @@ function PlayerObject() {
this.location = ""; this.location = "";
//Company Information //Company Information
this.companyName = ""; //Name of Company, equivalent to an object from Locations this.companyName = ""; // Name of Company. Must match a key value in Companies map
this.companyPosition = ""; //CompanyPosition object this.companyPosition = ""; // Name of Company Position. Must match a key value in CompanyPositions map
//Servers //Servers
this.currentServer = ""; //IP address of Server currently being accessed through terminal this.currentServer = ""; //IP address of Server currently being accessed through terminal
@ -710,13 +712,13 @@ PlayerObject.prototype.work = function(numCycles) {
var comp = Companies[this.companyName], companyRep = "0"; var comp = Companies[this.companyName], companyRep = "0";
if (comp == null || !(comp instanceof Company)) { if (comp == null || !(comp instanceof Company)) {
console.log("ERROR: Could not find Company: " + this.companyName); console.error(`Could not find Company: ${this.companyName}`);
} else { } else {
companyRep = comp.playerReputation; companyRep = comp.playerReputation;
} }
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName + txt.innerHTML = "You are currently working as a " + this.companyPosition +
" at " + this.companyName + " (Current Company Reputation: " + " at " + this.companyName + " (Current Company Reputation: " +
numeralWrapper.format(companyRep, '0,0') + ")<br><br>" + numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + "You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
@ -838,7 +840,7 @@ PlayerObject.prototype.workPartTime = function(numCycles) {
} }
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName + txt.innerHTML = "You are currently working as a " + this.companyPosition +
" at " + Player.companyName + " (Current Company Reputation: " + " at " + Player.companyName + " (Current Company Reputation: " +
numeralWrapper.format(companyRep, '0,0') + ")<br><br>" + numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + "You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
@ -1070,60 +1072,116 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
//Money gained per game cycle //Money gained per game cycle
PlayerObject.prototype.getWorkMoneyGain = function() { PlayerObject.prototype.getWorkMoneyGain = function() {
var bn11Mult = 1; // If player has SF-11, calculate salary multiplier from favor
var company = Companies[this.companyName]; let bn11Mult = 1;
if (hasBn11SF) { const company = Companies[this.companyName];
bn11Mult = 1 + (company.favor / 100); if (hasBn11SF) { bn11Mult = 1 + (company.favor / 100); }
// Get base salary
const companyPosition = CompanyPositions[this.companyPosition];
if (companyPosition == null) {
console.error(`Could not find CompanyPosition object for ${this.companyPosition}. Work salary will be 0`);
return 0;
} }
return this.companyPosition.baseSalary * company.salaryMultiplier *
this.work_money_mult * BitNodeMultipliers.CompanyWorkMoney * bn11Mult; return companyPosition.baseSalary * company.salaryMultiplier * this.work_money_mult * BitNodeMultipliers.CompanyWorkMoney * bn11Mult;
} }
//Hack exp gained per game cycle //Hack exp gained per game cycle
PlayerObject.prototype.getWorkHackExpGain = function() { PlayerObject.prototype.getWorkHackExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.hackingExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.hacking_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work hack exp gain will be 0`].join(" "));
return 0;
}
return companyPosition.hackingExpGain * company.expMultiplier * this.hacking_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Str exp gained per game cycle //Str exp gained per game cycle
PlayerObject.prototype.getWorkStrExpGain = function() { PlayerObject.prototype.getWorkStrExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.strengthExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.strength_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work str exp gain will be 0`].join(" "));
return 0;
}
return this.companyPosition.strengthExpGain * company.expMultiplier * this.strength_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Def exp gained per game cycle //Def exp gained per game cycle
PlayerObject.prototype.getWorkDefExpGain = function() { PlayerObject.prototype.getWorkDefExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.defenseExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.defense_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work def exp gain will be 0`].join(" "));
return 0;
}
return this.companyPosition.defenseExpGain * company.expMultiplier * this.defense_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Dex exp gained per game cycle //Dex exp gained per game cycle
PlayerObject.prototype.getWorkDexExpGain = function() { PlayerObject.prototype.getWorkDexExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.dexterityExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.dexterity_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work dex exp gain will be 0`].join(" "));
return 0;
}
return this.companyPosition.dexterityExpGain * company.expMultiplier * this.dexterity_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Agi exp gained per game cycle //Agi exp gained per game cycle
PlayerObject.prototype.getWorkAgiExpGain = function() { PlayerObject.prototype.getWorkAgiExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.agilityExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.agility_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work agi exp gain will be 0`].join(" "));
return 0;
}
return this.companyPosition.agilityExpGain * company.expMultiplier * this.agility_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Charisma exp gained per game cycle //Charisma exp gained per game cycle
PlayerObject.prototype.getWorkChaExpGain = function() { PlayerObject.prototype.getWorkChaExpGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
return this.companyPosition.charismaExpGain * company.expMultiplier * const companyPosition = CompanyPositions[this.companyPosition];
this.charisma_exp_mult * BitNodeMultipliers.CompanyWorkExpGain; if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work cha exp gain will be 0`].join(" "));
return 0;
}
return this.companyPosition.charismaExpGain * company.expMultiplier * this.charisma_exp_mult * BitNodeMultipliers.CompanyWorkExpGain;
} }
//Reputation gained per game cycle //Reputation gained per game cycle
PlayerObject.prototype.getWorkRepGain = function() { PlayerObject.prototype.getWorkRepGain = function() {
var company = Companies[this.companyName]; const company = Companies[this.companyName];
const companyPosition = CompanyPositions[this.companyPosition];
if (company == null || companyPosition == null) {
console.error([`Could not find Company object for ${this.companyName}`,
`or CompanyPosition object for ${this.companyPosition}.`,
`Work rep gain will be 0`].join(" "));
return 0;
}
var jobPerformance = this.companyPosition.calculateJobPerformance(this.hacking_skill, this.strength, var jobPerformance = this.companyPosition.calculateJobPerformance(this.hacking_skill, this.strength,
this.defense, this.dexterity, this.defense, this.dexterity,
this.agility, this.charisma); this.agility, this.charisma);
@ -1612,20 +1670,25 @@ PlayerObject.prototype.hospitalize = function() {
//The 'sing' argument designates whether or not this is being called from //The 'sing' argument designates whether or not this is being called from
//the applyToCompany() Netscript Singularity function //the applyToCompany() Netscript Singularity function
PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) { PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
var currCompany = ""; // Get current company and job
if (this.companyName != "") { let currCompany = null;
if (this.companyName !== "") {
currCompany = Companies[this.companyName]; currCompany = Companies[this.companyName];
} }
var currPositionName = ""; const currPositionName = this.companyPosition;
if (this.companyPosition != "") {
currPositionName = this.companyPosition.positionName; // Get company that's being applied to
} const company = Companies[this.location]; //Company being applied to
var company = Companies[this.location]; //Company being applied to if (!(company instanceof Company)) {
if (sing && !(company instanceof Company)) { if (sing) {
return "ERROR: Invalid company name: " + this.location + ". applyToCompany() failed"; return "ERROR: Invalid company name: " + this.location + ". applyToCompany() failed";
} else {
console.error(`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`);
return;
}
} }
var pos = entryPosType; let pos = entryPosType;
if (!this.isQualified(company, pos)) { if (!this.isQualified(company, pos)) {
var reqText = getJobRequirementText(company, pos); var reqText = getJobRequirementText(company, pos);
@ -1635,8 +1698,8 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
} }
while (true) { while (true) {
if (Engine.Debug) {console.log("Determining qualification for next Company Position");} console.log("Determining qualification for next Company Position");
var newPos = getNextCompanyPosition(pos); let newPos = getNextCompanyPosition(pos);
if (newPos == null) {break;} if (newPos == null) {break;}
//Check if this company has this position //Check if this company has this position
@ -1652,9 +1715,8 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
} }
//Check if the determined job is the same as the player's current job //Check if the determined job is the same as the player's current job
if (currCompany != "") { if (currCompany != null) {
if (currCompany.companyName == company.companyName && if (currCompany.name == company.name && pos.name == currPositionName) {
pos.positionName == currPositionName) {
var nextPos = getNextCompanyPosition(pos); var nextPos = getNextCompanyPosition(pos);
if (nextPos == null) { if (nextPos == null) {
if (sing) {return false;} if (sing) {return false;}
@ -1673,35 +1735,27 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
//Lose reputation from a Company if you are leaving it for another job //Lose reputation from a Company if you are leaving it for another job
var leaveCompany = false; let leaveCompany = false;
var oldCompanyName = ""; let oldCompanyName = "";
if (currCompany != "") { if (currCompany != null) {
if (currCompany.companyName != company.companyName) { if (currCompany.name != company.name) {
leaveCompany = true; leaveCompany = true;
oldCompanyName = currCompany.companyName; oldCompanyName = currCompany.name;
company.playerReputation -= 1000; company.playerReputation -= 1000;
if (company.playerReputation < 0) { company.playerReputation = 0; } if (company.playerReputation < 0) { company.playerReputation = 0; }
} }
} }
this.companyName = company.companyName; this.companyName = company.name;
this.companyPosition = pos; this.companyPosition = pos.name;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
if (leaveCompany) { if (leaveCompany) {
if (sing) { return true; } if (sing) { return true; }
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + dialogBoxCreate([`Congratulations! You were offered a new job at ${this.companyName} as a ${pos.name}!`,
pos.positionName + "!<br>" + `You lost 1000 reputation at your old company ${oldCompanyName} because you left.`].join("<br>"));
"You lost 1000 reputation at your old company " + oldCompanyName + " because you left.");
} else { } else {
if (sing) { return true; } if (sing) { return true; }
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.positionName + "!"); dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.name + "!");
} }
Engine.loadLocationContent(); Engine.loadLocationContent();
@ -1710,32 +1764,32 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
//Returns your next position at a company given the field (software, business, etc.) //Returns your next position at a company given the field (software, business, etc.)
PlayerObject.prototype.getNextCompanyPosition = function(company, entryPosType) { PlayerObject.prototype.getNextCompanyPosition = function(company, entryPosType) {
var currCompany = null; var currCompany = null;
if (this.companyName != "") { if (this.name !== "") {
currCompany = Companies[this.companyName]; currCompany = Companies[this.name];
} }
//Not employed at this company, so return the entry position //Not employed at this company, so return the entry position
if (currCompany == null || (currCompany.companyName != company.companyName)) { if (currCompany == null || (currCompany.name != company.name)) {
return entryPosType; return entryPosType;
} }
//If the entry pos type and the player's current position have the same type, //If the entry pos type and the player's current position have the same type,
//return the player's "nextCompanyPosition". Otherwise return the entryposType //return the player's "nextCompanyPosition". Otherwise return the entryposType
//Employed at this company, so just return the next position if it exists. //Employed at this company, so just return the next position if it exists.
if ((this.companyPosition.isSoftwareJob() && entryPosType.isSoftwareJob()) || const currentPosition = CompanyPositions[this.companyPosition];
(this.companyPosition.isITJob() && entryPosType.isITJob()) || if ((currentPosition.isSoftwareJob() && entryPosType.isSoftwareJob()) ||
(this.companyPosition.isBusinessJob() && entryPosType.isBusinessJob()) || (currentPosition.isITJob() && entryPosType.isITJob()) ||
(this.companyPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) || (currentPosition.isBusinessJob() && entryPosType.isBusinessJob()) ||
(this.companyPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) || (currentPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) ||
(this.companyPosition.isSecurityJob() && entryPosType.isSecurityJob()) || (currentPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) ||
(this.companyPosition.isAgentJob() && entryPosType.isAgentJob()) || (currentPosition.isSecurityJob() && entryPosType.isSecurityJob()) ||
(this.companyPosition.isSoftwareConsultantJob() && entryPosType.isSoftwareConsultantJob()) || (currentPosition.isAgentJob() && entryPosType.isAgentJob()) ||
(this.companyPosition.isBusinessConsultantJob() && entryPosType.isBusinessConsultantJob()) || (currentPosition.isSoftwareConsultantJob() && entryPosType.isSoftwareConsultantJob()) ||
(this.companyPosition.isPartTimeJob() && entryPosType.isPartTimeJob())) { (currentPosition.isBusinessConsultantJob() && entryPosType.isBusinessConsultantJob()) ||
return getNextCompanyPosition(this.companyPosition); (currentPosition.isPartTimeJob() && entryPosType.isPartTimeJob())) {
return getNextCompanyPosition(currentPosition);
} }
return entryPosType; return entryPosType;
} }
@ -2177,10 +2231,12 @@ PlayerObject.prototype.checkForFactionInvitations = function() {
//Silhouette //Silhouette
var silhouetteFac = Factions["Silhouette"]; var silhouetteFac = Factions["Silhouette"];
const companyPosition = CompanyPositions[this.companyPosition];
if (!silhouetteFac.isBanned && !silhouetteFac.isMember && !silhouetteFac.alreadyInvited && if (!silhouetteFac.isBanned && !silhouetteFac.isMember && !silhouetteFac.alreadyInvited &&
(this.companyPosition.positionName == CompanyPositions.CTO.positionName || companyPosition != null &&
this.companyPosition.positionName == CompanyPositions.CFO.positionName || (companyPosition.name == "Chief Technology Officer" ||
this.companyPosition.positionName == CompanyPositions.CEO.positionName) && companyPosition.name == "Chief Financial Officer" ||
companyPosition.name == "Chief Executive Officer") &&
this.money.gte(15000000) && this.karma <= -22) { this.money.gte(15000000) && this.karma <= -22) {
invitedFactions.push(silhouetteFac); invitedFactions.push(silhouetteFac);
} }

@ -4,7 +4,7 @@ import {Augmentations, augmentationExists,
import {initBitNodeMultipliers} from "./BitNode"; import {initBitNodeMultipliers} from "./BitNode";
import {Bladeburner} from "./Bladeburner"; import {Bladeburner} from "./Bladeburner";
import {writeCinematicText} from "./CinematicText"; import {writeCinematicText} from "./CinematicText";
import {Companies, Company, initCompanies} from "./Company"; import {Companies, initCompanies} from "./Company/Companies";
import {Programs} from "./CreateProgram"; import {Programs} from "./CreateProgram";
import {Engine} from "./engine"; import {Engine} from "./engine";
import {Factions, Faction, initFactions, import {Factions, Faction, initFactions,

@ -1,7 +1,7 @@
import {loadAliases, loadGlobalAliases, import {loadAliases, loadGlobalAliases,
Aliases, GlobalAliases} from "./Alias"; Aliases, GlobalAliases} from "./Alias";
import {loadCompanies, Companies, import {Companies, loadCompanies} from "./Company/Companies";
CompanyPositions} from "./Company"; import {CompanyPosition} from "./Company/CompanyPosition";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {Engine} from "./engine"; import {Engine} from "./engine";
import {loadFactions, Factions, import {loadFactions, Factions,
@ -187,29 +187,20 @@ function loadGame(saveString) {
if (saveObj.hasOwnProperty("VersionSave")) { if (saveObj.hasOwnProperty("VersionSave")) {
try { try {
var ver = JSON.parse(saveObj.VersionSave, Reviver); var ver = JSON.parse(saveObj.VersionSave, Reviver);
if (Player.bitNodeN == null || Player.bitNodeN === 0) { // This version refactored the Company/job-related code
Player.setBitNodeNumber(1); if (ver < "0.41.2") {
// Player's company position is now a string
if (Player.companyPosition !== "" || Player.companyPosition instanceof CompanyPosition) {
console.log("Changed Player.companyPosition value to be compatible with v0.41.2");
Player.companyPosition = Player.companyPosition.positionName;
} }
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
console.log("Evaluating changes needed for version compatibility"); // The "companyName" property of all Companies is renamed to "name"
if (Player.augmentations.length > 0 || Player.queuedAugmentations.length > 0 || for (var companyName in Companies) {
Player.sourceFiles.length > 0) { const company = Companies[companyName];
//If you have already purchased an Aug...you are far enough in the game if (company.name == null && company.companyName != null) {
//that everything should be available console.log("Changed company name property to be compatible with v0.41.2");
Player.firstFacInvRecvd = true; company.name = company.companyName;
Player.firstAugPurchased = true;
Player.firstJobRecvd = true;
Player.firstTimeTraveled = true;
Player.firstProgramAvailable = true;
} else {
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
Player.firstFacInvRecvd = true;
}
if (Player.companyName !== "" || Player.companyPosition !== "") {
Player.firstJobRecvd = true;
}
if (Player.hacking_skill >= 25) {
Player.firstScriptAvailable = true;
} }
} }
} }
@ -310,23 +301,27 @@ function loadImportedGame(saveObj, saveString) {
if (tempSaveObj.hasOwnProperty("VersionSave")) { if (tempSaveObj.hasOwnProperty("VersionSave")) {
try { try {
var ver = JSON.parse(tempSaveObj.VersionSave, Reviver); var ver = JSON.parse(tempSaveObj.VersionSave, Reviver);
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) { // This version refactored the Company/job-related code
if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) { if (ver < "0.41.2") {
tempPlayer.bitNodeN = 1; // Player's company position is now a string
if (Player.companyPosition !== "" || Player.companyPosition instanceof CompanyPosition) {
console.log("Changed Player.companyPosition value to be compatible with v0.41.2");
Player.companyPosition = Player.companyPosition.positionName;
} }
if (tempPlayer.sourceFiles == null) {
tempPlayer.sourceFiles = []; // The "companyName" property of all Companies is renamed to "name"
for (var companyName in Companies) {
const company = Companies[companyName];
if (company.name == null && company.companyName != null) {
console.log("Changed company name property to be compatible with v0.41.2");
company.name = company.companyName;
} }
} }
if (ver != CONSTANTS.Version) {
//createNewUpdateText();
} }
} catch(e) { } catch(e) {
console.log("Parsing Version save failed: " + e); console.error("Parsing Version save failed: " + e);
//createNewUpdateText();
} }
} else { } else {
//createNewUpdateText();
} }
if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && tempSaveObj.hasOwnProperty("AllGangsSave")) { if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && tempSaveObj.hasOwnProperty("AllGangsSave")) {
try { try {
@ -405,30 +400,20 @@ function loadImportedGame(saveObj, saveString) {
if (saveObj.hasOwnProperty("VersionSave")) { if (saveObj.hasOwnProperty("VersionSave")) {
try { try {
var ver = JSON.parse(saveObj.VersionSave, Reviver); var ver = JSON.parse(saveObj.VersionSave, Reviver);
if (Player.bitNodeN == null || Player.bitNodeN == 0) { // This version refactored the Company/job-related code
Player.setBitNodeNumber(1); if (ver < "0.41.2") {
// Player's company position is now a string
if (Player.companyPosition !== "" || Player.companyPosition instanceof CompanyPosition) {
console.log("Changed Player.companyPosition value to be compatible with v0.41.2");
Player.companyPosition = Player.companyPosition.positionName;
}
} // The "companyName" property of all Companies is renamed to "name"
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) { for (var companyName in Companies) {
console.log("Evaluating changes needed for version compatibility"); const company = Companies[companyName];
if (Player.augmentations.length > 0 || Player.queuedAugmentations.length > 0 || if (company.name == null && company.companyName != null) {
Player.sourceFiles.length > 0) { console.log("Changed company name property to be compatible with v0.41.2");
//If you have already purchased an Aug...you are far enough in the game company.name = company.companyName;
//that everything should be available
Player.firstFacInvRecvd = true;
Player.firstAugPurchased = true;
Player.firstJobRecvd = true;
Player.firstTimeTraveled = true;
Player.firstProgramAvailable = true;
} else {
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
Player.firstFacInvRecvd = true;
}
if (Player.companyName !== "" || Player.companyPosition !== "") {
Player.firstJobRecvd = true;
}
if (Player.hacking_skill >= 25) {
Player.firstScriptAvailable = true;
} }
} }
} }
@ -467,7 +452,6 @@ function loadImportedGame(saveObj, saveString) {
console.log("Importing game"); console.log("Importing game");
Engine.setDisplayElements(); //Sets variables for important DOM elements Engine.setDisplayElements(); //Sets variables for important DOM elements
Engine.init(); //Initialize buttons, work, etc. Engine.init(); //Initialize buttons, work, etc.
CompanyPositions.init();
//Calculate the number of cycles have elapsed while offline //Calculate the number of cycles have elapsed while offline
Engine._lastUpdate = new Date().getTime(); Engine._lastUpdate = new Date().getTime();

@ -25,7 +25,8 @@ import {Bladeburner} from "./Bladeburner";
import {CharacterOverview} from "./CharacterOverview"; import {CharacterOverview} from "./CharacterOverview";
import {cinematicTextFlag} from "./CinematicText"; import {cinematicTextFlag} from "./CinematicText";
import {generateRandomContract} from "./CodingContractGenerator"; import {generateRandomContract} from "./CodingContractGenerator";
import {CompanyPositions, initCompanies} from "./Company"; import {CompanyPositions} from "./Company/CompanyPositions";
import {initCompanies} from "./Company/Companies";
import {Corporation} from "./CompanyManagement"; import {Corporation} from "./CompanyManagement";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {displayCreateProgramContent, import {displayCreateProgramContent,
@ -537,8 +538,8 @@ const Engine = {
removeChildrenFromElement(Engine.Display.characterInfo); removeChildrenFromElement(Engine.Display.characterInfo);
var companyPosition = ""; var companyPosition = "";
if (Player.companyPosition != "") { if (Player.companyPosition !== "") {
companyPosition = Player.companyPosition.positionName; companyPosition = Player.companyPosition;
} }
var intText = ""; var intText = "";
@ -1201,7 +1202,6 @@ const Engine = {
initSourceFiles(); initSourceFiles();
Engine.setDisplayElements(); //Sets variables for important DOM elements Engine.setDisplayElements(); //Sets variables for important DOM elements
Engine.init(); //Initialize buttons, work, etc. Engine.init(); //Initialize buttons, work, etc.
CompanyPositions.init();
initAugmentations(); //Also calls Player.reapplyAllAugmentations() initAugmentations(); //Also calls Player.reapplyAllAugmentations()
Player.reapplyAllSourceFiles(); Player.reapplyAllSourceFiles();
initStockSymbols(); initStockSymbols();
@ -1302,7 +1302,6 @@ const Engine = {
initForeignServers(); initForeignServers();
initCompanies(); initCompanies();
initFactions(); initFactions();
CompanyPositions.init();
initAugmentations(); initAugmentations();
initMessages(); initMessages();
initStockSymbols(); initStockSymbols();

@ -0,0 +1,7 @@
// Modified version of Object.assign() that prevents you from
// accidentally modifying the 'target' (first argument)
export function SafeObjectAssign(...args: any[]) {
const argsCopy: any[] = Array.from(arguments);
argsCopy.unshift({});
Object.assign.apply(null, argsCopy);
}