mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-30 18:07:33 +01:00
TYPESAFETY: CompanyName (#650)
This commit is contained in:
parent
e4d3a9020e
commit
e2655793f4
@ -1,46 +1,30 @@
|
||||
// Constructs all CompanyPosition objects using the metadata in data/companypositions.ts
|
||||
import { companiesMetadata } from "./data/CompaniesMetadata";
|
||||
import { Company, IConstructorParams } from "./Company";
|
||||
import { Reviver } from "../utils/JSONReviver";
|
||||
import { getCompaniesMetadata } from "./data/CompaniesMetadata";
|
||||
import { Company } from "./Company";
|
||||
import { Reviver, assertLoadingType } from "../utils/JSONReviver";
|
||||
import { CompanyName } from "./Enums";
|
||||
import { createEnumKeyedRecord } from "../Types/Record";
|
||||
import { getEnumHelper } from "../utils/EnumHelper";
|
||||
|
||||
export let Companies: Record<string, Company> = {};
|
||||
|
||||
function addCompany(params: IConstructorParams): void {
|
||||
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(): void {
|
||||
// Save Old Company data for 'favor'
|
||||
const oldCompanies = Companies;
|
||||
|
||||
// Re-construct all Companies
|
||||
Companies = {};
|
||||
companiesMetadata.forEach((e) => {
|
||||
addCompany(e);
|
||||
});
|
||||
|
||||
// Reset data
|
||||
for (const companyName of Object.keys(Companies)) {
|
||||
const company = Companies[companyName];
|
||||
const oldCompany = oldCompanies[companyName];
|
||||
if (!oldCompany) {
|
||||
// New game, so no OldCompanies data
|
||||
company.favor = 0;
|
||||
} else {
|
||||
company.favor = oldCompanies[companyName].favor;
|
||||
if (isNaN(company.favor)) {
|
||||
company.favor = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export const Companies: Record<CompanyName, Company> = (() => {
|
||||
const metadata = getCompaniesMetadata();
|
||||
return createEnumKeyedRecord(CompanyName, (name) => new Company(metadata[name]));
|
||||
})();
|
||||
|
||||
// Used to load Companies map from a save
|
||||
export function loadCompanies(saveString: string): void {
|
||||
Companies = JSON.parse(saveString, Reviver);
|
||||
const loadedCompanies = JSON.parse(saveString, Reviver) as unknown;
|
||||
// This loading method allows invalid data in player save, but just ignores anything invalid
|
||||
if (!loadedCompanies) return;
|
||||
if (typeof loadedCompanies !== "object") return;
|
||||
for (const [loadedCompanyName, loadedCompany] of Object.entries(loadedCompanies) as [string, unknown][]) {
|
||||
if (!getEnumHelper("CompanyName").isMember(loadedCompanyName)) continue;
|
||||
if (!loadedCompany) continue;
|
||||
if (typeof loadedCompany !== "object") continue;
|
||||
const company = Companies[loadedCompanyName];
|
||||
assertLoadingType<Company>(loadedCompany);
|
||||
const { playerReputation: loadedRep, favor: loadedFavor } = loadedCompany;
|
||||
if (typeof loadedRep === "number" && loadedRep > 0) company.playerReputation = loadedRep;
|
||||
if (typeof loadedFavor === "number" && loadedFavor > 0) company.favor = loadedFavor;
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,32 @@
|
||||
import { CompanyPosition } from "./CompanyPosition";
|
||||
import * as posNames from "./data/JobTracks";
|
||||
import type { CompanyPosition } from "./CompanyPosition";
|
||||
|
||||
import { CompanyName, JobName } from "@enums";
|
||||
import { favorToRep, repToFavor } from "../Faction/formulas/favor";
|
||||
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver";
|
||||
|
||||
export interface IConstructorParams {
|
||||
name: string;
|
||||
info: string;
|
||||
companyPositions: Record<string, boolean>;
|
||||
export interface CompanyCtorParams {
|
||||
name: CompanyName;
|
||||
info?: string;
|
||||
companyPositions: JobName[];
|
||||
expMultiplier: number;
|
||||
salaryMultiplier: number;
|
||||
jobStatReqOffset: number;
|
||||
isMegacorp?: boolean;
|
||||
hasFaction?: boolean;
|
||||
}
|
||||
|
||||
const DefaultConstructorParams: IConstructorParams = {
|
||||
name: "",
|
||||
info: "",
|
||||
companyPositions: {},
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
};
|
||||
|
||||
export class Company {
|
||||
/** Company name */
|
||||
name: string;
|
||||
// Static info, initialized once at game load.
|
||||
|
||||
/** Description and general information about company */
|
||||
info: string;
|
||||
name = CompanyName.NoodleBar;
|
||||
info = "";
|
||||
hasFaction = false;
|
||||
|
||||
/** Has faction associated. */
|
||||
isMegacorp: boolean;
|
||||
|
||||
/**
|
||||
* 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: Record<string, boolean>;
|
||||
companyPositions = new Set<JobName>();
|
||||
|
||||
/** Company-specific multiplier for earnings */
|
||||
expMultiplier: number;
|
||||
salaryMultiplier: number;
|
||||
expMultiplier = 1;
|
||||
salaryMultiplier = 1;
|
||||
|
||||
/**
|
||||
* The additional levels of stats you need to quality for a job
|
||||
@ -53,79 +35,76 @@ export class 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;
|
||||
jobStatReqOffset = 0;
|
||||
|
||||
/** Properties to track the player's progress in this company */
|
||||
isPlayerEmployed: boolean;
|
||||
playerReputation: number;
|
||||
favor: number;
|
||||
// Dynamic info, loaded from save and updated during game.
|
||||
playerReputation = 0;
|
||||
favor = 0;
|
||||
|
||||
constructor(p: IConstructorParams = DefaultConstructorParams) {
|
||||
constructor(p?: CompanyCtorParams) {
|
||||
if (!p) return;
|
||||
this.name = p.name;
|
||||
this.info = p.info;
|
||||
this.companyPositions = p.companyPositions;
|
||||
if (p.info) this.info = p.info;
|
||||
p.companyPositions.forEach((jobName) => this.companyPositions.add(jobName));
|
||||
this.expMultiplier = p.expMultiplier;
|
||||
this.salaryMultiplier = p.salaryMultiplier;
|
||||
this.jobStatReqOffset = p.jobStatReqOffset;
|
||||
|
||||
this.isPlayerEmployed = false;
|
||||
this.playerReputation = 1;
|
||||
this.favor = 0;
|
||||
this.isMegacorp = false;
|
||||
if (p.isMegacorp) this.isMegacorp = true;
|
||||
if (p.hasFaction) this.hasFaction = true;
|
||||
}
|
||||
|
||||
hasPosition(pos: CompanyPosition | string): boolean {
|
||||
return this.companyPositions[typeof pos === "string" ? pos : pos.name] != null;
|
||||
hasPosition(pos: CompanyPosition | JobName): boolean {
|
||||
return this.companyPositions.has(typeof pos === "string" ? pos : pos.name);
|
||||
}
|
||||
|
||||
hasAgentPositions(): boolean {
|
||||
return this.companyPositions[posNames.AgentCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.agent0);
|
||||
}
|
||||
|
||||
hasBusinessConsultantPositions(): boolean {
|
||||
return this.companyPositions[posNames.BusinessConsultantCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.businessConsult0);
|
||||
}
|
||||
|
||||
hasBusinessPositions(): boolean {
|
||||
return this.companyPositions[posNames.BusinessCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.business0);
|
||||
}
|
||||
|
||||
hasEmployeePositions(): boolean {
|
||||
return this.companyPositions[posNames.MiscCompanyPositions[1]] != null;
|
||||
return this.companyPositions.has(JobName.employee);
|
||||
}
|
||||
|
||||
hasITPositions(): boolean {
|
||||
return this.companyPositions[posNames.ITCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.IT0);
|
||||
}
|
||||
|
||||
hasSecurityPositions(): boolean {
|
||||
return this.companyPositions[posNames.SecurityCompanyPositions[2]] != null;
|
||||
return this.companyPositions.has(JobName.security0);
|
||||
}
|
||||
|
||||
hasSoftwareConsultantPositions(): boolean {
|
||||
return this.companyPositions[posNames.SoftwareConsultantCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.softwareConsult0);
|
||||
}
|
||||
|
||||
hasSoftwarePositions(): boolean {
|
||||
return this.companyPositions[posNames.SoftwareCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.software0);
|
||||
}
|
||||
|
||||
hasWaiterPositions(): boolean {
|
||||
return this.companyPositions[posNames.MiscCompanyPositions[0]] != null;
|
||||
return this.companyPositions.has(JobName.waiter);
|
||||
}
|
||||
|
||||
gainFavor(): void {
|
||||
if (this.favor == null) {
|
||||
this.favor = 0;
|
||||
}
|
||||
prestigeAugmentation(): void {
|
||||
if (this.favor == null) this.favor = 0;
|
||||
this.favor += this.getFavorGain();
|
||||
this.playerReputation = 0;
|
||||
}
|
||||
|
||||
prestigeSourceFile() {
|
||||
this.favor = 0;
|
||||
this.playerReputation = 0;
|
||||
}
|
||||
|
||||
getFavorGain(): number {
|
||||
if (this.favor == null) {
|
||||
this.favor = 0;
|
||||
}
|
||||
if (this.favor == null) this.favor = 0;
|
||||
const storedRep = Math.max(0, favorToRep(this.favor));
|
||||
const totalRep = storedRep + this.playerReputation;
|
||||
const newFavor = repToFavor(totalRep);
|
||||
@ -134,13 +113,16 @@ export class Company {
|
||||
|
||||
/** Serialize the current object to a JSON save state. */
|
||||
toJSON(): IReviverValue {
|
||||
return Generic_toJSON("Company", this);
|
||||
return Generic_toJSON("Company", this, Company.includedKeys);
|
||||
}
|
||||
|
||||
/** Initializes a Company from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): Company {
|
||||
return Generic_fromJSON(Company, value.data);
|
||||
return Generic_fromJSON(Company, value.data, Company.includedKeys);
|
||||
}
|
||||
|
||||
// Only these 3 keys are relevant to the save file
|
||||
static includedKeys = ["favor", "playerReputation"] as const;
|
||||
}
|
||||
|
||||
constructorsForReviver.Company = Company;
|
||||
|
@ -1,10 +1,18 @@
|
||||
import { Person as IPerson } from "@nsdefs";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import * as names from "./data/JobTracks";
|
||||
import { JobName } from "@enums";
|
||||
import {
|
||||
agentJobs,
|
||||
businessConsultJobs,
|
||||
businessJobs,
|
||||
itJobs,
|
||||
netEngJobs,
|
||||
securityJobs,
|
||||
softwareConsultJobs,
|
||||
softwareJobs,
|
||||
} from "./data/JobTracks";
|
||||
|
||||
export interface IConstructorParams {
|
||||
name: JobName;
|
||||
export interface CompanyPositionCtorParams {
|
||||
nextPosition: JobName | null;
|
||||
baseSalary: number;
|
||||
repMultiplier: number;
|
||||
@ -75,8 +83,8 @@ export class CompanyPosition {
|
||||
agilityExpGain: number;
|
||||
charismaExpGain: number;
|
||||
|
||||
constructor(p: IConstructorParams) {
|
||||
this.name = p.name;
|
||||
constructor(name: JobName, p: CompanyPositionCtorParams) {
|
||||
this.name = name;
|
||||
this.nextPosition = p.nextPosition;
|
||||
this.baseSalary = p.baseSalary;
|
||||
this.repMultiplier = p.repMultiplier;
|
||||
@ -136,42 +144,42 @@ export class CompanyPosition {
|
||||
}
|
||||
|
||||
isSoftwareJob(): boolean {
|
||||
return names.SoftwareCompanyPositions.includes(this.name);
|
||||
return softwareJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isITJob(): boolean {
|
||||
return names.ITCompanyPositions.includes(this.name);
|
||||
return itJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isSecurityEngineerJob(): boolean {
|
||||
return names.SecurityEngineerCompanyPositions.includes(this.name);
|
||||
return this.name === JobName.securityEng;
|
||||
}
|
||||
|
||||
isNetworkEngineerJob(): boolean {
|
||||
return names.NetworkEngineerCompanyPositions.includes(this.name);
|
||||
return netEngJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isBusinessJob(): boolean {
|
||||
return names.BusinessCompanyPositions.includes(this.name);
|
||||
return businessJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isSecurityJob(): boolean {
|
||||
return names.SecurityCompanyPositions.includes(this.name);
|
||||
return securityJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isAgentJob(): boolean {
|
||||
return names.AgentCompanyPositions.includes(this.name);
|
||||
return agentJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isSoftwareConsultantJob(): boolean {
|
||||
return names.SoftwareConsultantCompanyPositions.includes(this.name);
|
||||
return softwareConsultJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isBusinessConsultantJob(): boolean {
|
||||
return names.BusinessConsultantCompanyPositions.includes(this.name);
|
||||
return businessConsultJobs.includes(this.name);
|
||||
}
|
||||
|
||||
isPartTimeJob(): boolean {
|
||||
return names.PartTimeCompanyPositions.includes(this.name);
|
||||
return [JobName.employeePT, JobName.waiterPT].includes(this.name);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,10 @@
|
||||
// Constructs all CompanyPosition objects using the metadata in data/companypositions.ts
|
||||
import { companyPositionMetadata } from "./data/CompanyPositionsMetadata";
|
||||
import { CompanyPosition, IConstructorParams } from "./CompanyPosition";
|
||||
import { JobName } from "@enums";
|
||||
|
||||
export const CompanyPositions: Record<string, CompanyPosition> = {};
|
||||
import { getCompanyPositionMetadata } from "./data/CompanyPositionsMetadata";
|
||||
import { CompanyPosition } from "./CompanyPosition";
|
||||
import { createEnumKeyedRecord } from "../Types/Record";
|
||||
|
||||
function addCompanyPosition(params: IConstructorParams): void {
|
||||
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);
|
||||
});
|
||||
export const CompanyPositions: Record<JobName, CompanyPosition> = (() => {
|
||||
const metadata = getCompanyPositionMetadata();
|
||||
return createEnumKeyedRecord(JobName, (name) => new CompanyPosition(name, metadata[name]));
|
||||
})();
|
||||
|
40
src/Company/Enums.ts
Normal file
40
src/Company/Enums.ts
Normal file
@ -0,0 +1,40 @@
|
||||
export enum CompanyName {
|
||||
ECorp = "ECorp",
|
||||
MegaCorp = "MegaCorp",
|
||||
BachmanAndAssociates = "Bachman & Associates",
|
||||
BladeIndustries = "Blade Industries",
|
||||
NWO = "NWO",
|
||||
ClarkeIncorporated = "Clarke Incorporated",
|
||||
OmniTekIncorporated = "OmniTek Incorporated",
|
||||
FourSigma = "Four Sigma",
|
||||
KuaiGongInternational = "KuaiGong International",
|
||||
FulcrumTechnologies = "Fulcrum Technologies",
|
||||
StormTechnologies = "Storm Technologies",
|
||||
DefComm = "DefComm",
|
||||
HeliosLabs = "Helios Labs",
|
||||
VitaLife = "VitaLife",
|
||||
IcarusMicrosystems = "Icarus Microsystems",
|
||||
UniversalEnergy = "Universal Energy",
|
||||
GalacticCybersystems = "Galactic Cybersystems",
|
||||
AeroCorp = "AeroCorp",
|
||||
OmniaCybersystems = "Omnia Cybersystems",
|
||||
SolarisSpaceSystems = "Solaris Space Systems",
|
||||
DeltaOne = "DeltaOne",
|
||||
GlobalPharmaceuticals = "Global Pharmaceuticals",
|
||||
NovaMedical = "Nova Medical",
|
||||
CIA = "Central Intelligence Agency",
|
||||
NSA = "National Security Agency",
|
||||
WatchdogSecurity = "Watchdog Security",
|
||||
LexoCorp = "LexoCorp",
|
||||
RhoConstruction = "Rho Construction",
|
||||
AlphaEnterprises = "Alpha Enterprises",
|
||||
Police = "Aevum Police Headquarters",
|
||||
SysCoreSecurities = "SysCore Securities",
|
||||
CompuTek = "CompuTek",
|
||||
NetLinkTechnologies = "NetLink Technologies",
|
||||
CarmichaelSecurity = "Carmichael Security",
|
||||
FoodNStuff = "FoodNStuff",
|
||||
JoesGuns = "Joe's Guns",
|
||||
OmegaSoftware = "Omega Software",
|
||||
NoodleBar = "Noodle Bar",
|
||||
}
|
@ -1,17 +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 type { CompanyPosition } from "./CompanyPosition";
|
||||
import { CompanyPositions } from "./CompanyPositions";
|
||||
|
||||
export function getNextCompanyPositionHelper(currPos: CompanyPosition | null): CompanyPosition | null {
|
||||
if (currPos == null) {
|
||||
return null;
|
||||
}
|
||||
if (!currPos) return null;
|
||||
|
||||
const nextPosName: string | null = currPos.nextPosition;
|
||||
if (nextPosName == null) {
|
||||
return null;
|
||||
}
|
||||
const nextPosName = currPos.nextPosition;
|
||||
if (!nextPosName) return null;
|
||||
|
||||
return CompanyPositions[nextPosName];
|
||||
}
|
||||
|
@ -1,449 +1,309 @@
|
||||
import * as posNames from "./JobTracks";
|
||||
import { IConstructorParams } from "../Company";
|
||||
import { CompanyCtorParams } from "../Company";
|
||||
|
||||
import { LocationName } from "@enums";
|
||||
import { CompanyName, JobName } from "@enums";
|
||||
import {
|
||||
agentJobs,
|
||||
businessJobs,
|
||||
itJobs,
|
||||
netEngJobs,
|
||||
securityJobs,
|
||||
softwareConsultJobs,
|
||||
softwareJobs,
|
||||
} from "./JobTracks";
|
||||
|
||||
// These are grossly typed, need to address
|
||||
// Create Objects containing Company Positions by category
|
||||
// Will help in metadata construction later
|
||||
const AllSoftwarePositions: Record<string, boolean> = {};
|
||||
const AllITPositions: Record<string, boolean> = {};
|
||||
const AllNetworkEngineerPositions: Record<string, boolean> = {};
|
||||
const SecurityEngineerPositions: Record<string, boolean> = {};
|
||||
const AllTechnologyPositions: Record<string, boolean> = {};
|
||||
const AllBusinessPositions: Record<string, boolean> = {};
|
||||
const AllAgentPositions: Record<string, boolean> = {};
|
||||
const AllSecurityPositions: Record<string, boolean> = {};
|
||||
const AllSoftwareConsultantPositions: Record<string, boolean> = {};
|
||||
const AllBusinessConsultantPositions: Record<string, boolean> = {};
|
||||
const SoftwarePositionsUpToHeadOfEngineering: Record<string, boolean> = {};
|
||||
const SoftwarePositionsUpToLeadDeveloper: Record<string, boolean> = {};
|
||||
const BusinessPositionsUpToOperationsManager: Record<string, boolean> = {};
|
||||
const WaiterOnly: Record<string, boolean> = {};
|
||||
const EmployeeOnly: Record<string, boolean> = {};
|
||||
const PartTimeWaiterOnly: Record<string, boolean> = {};
|
||||
const PartTimeEmployeeOnly: Record<string, boolean> = {};
|
||||
const OperationsManagerOnly: Record<string, boolean> = {};
|
||||
const CEOOnly: Record<string, boolean> = {};
|
||||
export function getCompaniesMetadata(): Record<CompanyName, CompanyCtorParams> {
|
||||
const allTechJobs: JobName[] = [...softwareJobs, ...itJobs, ...netEngJobs, JobName.securityEng];
|
||||
const softwareJobsToHeadOfEng: JobName[] = softwareJobs.slice(0, 6);
|
||||
const softwareJobsToLeadDev: JobName[] = softwareJobs.slice(0, 4);
|
||||
const businessJobToOpsManager: JobName[] = businessJobs.slice(0, 4);
|
||||
|
||||
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;
|
||||
SecurityEngineerPositions[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;
|
||||
}
|
||||
return {
|
||||
[CompanyName.ECorp]: {
|
||||
name: CompanyName.ECorp,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
[CompanyName.MegaCorp]: {
|
||||
name: CompanyName.MegaCorp,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
[CompanyName.BachmanAndAssociates]: {
|
||||
name: CompanyName.BachmanAndAssociates,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.6,
|
||||
salaryMultiplier: 2.6,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.BladeIndustries]: {
|
||||
name: CompanyName.BladeIndustries,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.NWO]: {
|
||||
name: CompanyName.NWO,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
[CompanyName.ClarkeIncorporated]: {
|
||||
name: CompanyName.ClarkeIncorporated,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.OmniTekIncorporated]: {
|
||||
name: CompanyName.OmniTekIncorporated,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.FourSigma]: {
|
||||
name: CompanyName.FourSigma,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.5,
|
||||
salaryMultiplier: 2.5,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.KuaiGongInternational]: {
|
||||
name: CompanyName.KuaiGongInternational,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 2.2,
|
||||
salaryMultiplier: 2.2,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.FulcrumTechnologies]: {
|
||||
name: CompanyName.FulcrumTechnologies,
|
||||
companyPositions: [...allTechJobs, ...businessJobs],
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.StormTechnologies]: {
|
||||
name: CompanyName.StormTechnologies,
|
||||
companyPositions: [...allTechJobs, ...softwareConsultJobs, ...businessJobs],
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.DefComm]: {
|
||||
name: CompanyName.DefComm,
|
||||
companyPositions: [JobName.business5, ...allTechJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 1.75,
|
||||
salaryMultiplier: 1.75,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.HeliosLabs]: {
|
||||
name: CompanyName.HeliosLabs,
|
||||
companyPositions: [JobName.business5, ...allTechJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.VitaLife]: {
|
||||
name: CompanyName.VitaLife,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.IcarusMicrosystems]: {
|
||||
name: CompanyName.IcarusMicrosystems,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.UniversalEnergy]: {
|
||||
name: CompanyName.UniversalEnergy,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.GalacticCybersystems]: {
|
||||
name: CompanyName.GalacticCybersystems,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs],
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.AeroCorp]: {
|
||||
name: CompanyName.AeroCorp,
|
||||
companyPositions: [JobName.business3, JobName.business5, ...allTechJobs, ...securityJobs],
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.OmniaCybersystems]: {
|
||||
name: CompanyName.OmniaCybersystems,
|
||||
companyPositions: [JobName.business3, JobName.business5, ...allTechJobs, ...securityJobs],
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.SolarisSpaceSystems]: {
|
||||
name: CompanyName.SolarisSpaceSystems,
|
||||
companyPositions: [JobName.business3, JobName.business5, ...allTechJobs, ...securityJobs],
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.DeltaOne]: {
|
||||
name: CompanyName.DeltaOne,
|
||||
companyPositions: [JobName.business3, JobName.business5, ...allTechJobs, ...securityJobs],
|
||||
expMultiplier: 1.6,
|
||||
salaryMultiplier: 1.6,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.GlobalPharmaceuticals]: {
|
||||
name: CompanyName.GlobalPharmaceuticals,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs, ...securityJobs],
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
[CompanyName.NovaMedical]: {
|
||||
name: CompanyName.NovaMedical,
|
||||
companyPositions: [...allTechJobs, ...businessJobs, ...softwareConsultJobs, ...securityJobs],
|
||||
expMultiplier: 1.75,
|
||||
salaryMultiplier: 1.75,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
[CompanyName.CIA]: {
|
||||
name: CompanyName.CIA,
|
||||
companyPositions: [
|
||||
...softwareJobsToHeadOfEng,
|
||||
...netEngJobs,
|
||||
JobName.securityEng,
|
||||
...itJobs,
|
||||
...securityJobs,
|
||||
...agentJobs,
|
||||
],
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 149,
|
||||
},
|
||||
[CompanyName.NSA]: {
|
||||
name: CompanyName.NSA,
|
||||
companyPositions: [
|
||||
...softwareJobsToHeadOfEng,
|
||||
...netEngJobs,
|
||||
JobName.securityEng,
|
||||
...itJobs,
|
||||
...securityJobs,
|
||||
...agentJobs,
|
||||
],
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 149,
|
||||
},
|
||||
[CompanyName.WatchdogSecurity]: {
|
||||
name: CompanyName.WatchdogSecurity,
|
||||
companyPositions: [
|
||||
...softwareJobsToHeadOfEng,
|
||||
...netEngJobs,
|
||||
...itJobs,
|
||||
...securityJobs,
|
||||
...agentJobs,
|
||||
...softwareConsultJobs,
|
||||
],
|
||||
expMultiplier: 1.5,
|
||||
salaryMultiplier: 1.5,
|
||||
jobStatReqOffset: 124,
|
||||
},
|
||||
[CompanyName.LexoCorp]: {
|
||||
name: CompanyName.LexoCorp,
|
||||
companyPositions: [...allTechJobs, ...softwareConsultJobs, ...businessJobs, ...securityJobs],
|
||||
expMultiplier: 1.4,
|
||||
salaryMultiplier: 1.4,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
[CompanyName.RhoConstruction]: {
|
||||
name: CompanyName.RhoConstruction,
|
||||
companyPositions: [...softwareJobsToLeadDev, ...businessJobToOpsManager],
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 49,
|
||||
},
|
||||
[CompanyName.AlphaEnterprises]: {
|
||||
name: CompanyName.AlphaEnterprises,
|
||||
companyPositions: [...softwareJobsToLeadDev, ...businessJobToOpsManager, ...softwareConsultJobs],
|
||||
expMultiplier: 1.5,
|
||||
salaryMultiplier: 1.5,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
[CompanyName.Police]: {
|
||||
name: CompanyName.Police,
|
||||
companyPositions: [...securityJobs, ...softwareJobsToLeadDev],
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
[CompanyName.SysCoreSecurities]: {
|
||||
name: CompanyName.SysCoreSecurities,
|
||||
companyPositions: [...allTechJobs],
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 124,
|
||||
},
|
||||
[CompanyName.CompuTek]: {
|
||||
name: CompanyName.CompuTek,
|
||||
companyPositions: [...allTechJobs],
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 74,
|
||||
},
|
||||
[CompanyName.NetLinkTechnologies]: {
|
||||
name: CompanyName.NetLinkTechnologies,
|
||||
companyPositions: [...allTechJobs],
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
[CompanyName.CarmichaelSecurity]: {
|
||||
name: CompanyName.CarmichaelSecurity,
|
||||
companyPositions: [...allTechJobs, ...softwareConsultJobs, ...agentJobs, ...securityJobs],
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 74,
|
||||
},
|
||||
[CompanyName.FoodNStuff]: {
|
||||
name: CompanyName.FoodNStuff,
|
||||
companyPositions: [JobName.employee, JobName.employeePT],
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
[CompanyName.JoesGuns]: {
|
||||
name: CompanyName.JoesGuns,
|
||||
companyPositions: [JobName.employee, JobName.employeePT],
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
[CompanyName.OmegaSoftware]: {
|
||||
name: CompanyName.OmegaSoftware,
|
||||
companyPositions: [...softwareJobs, ...softwareConsultJobs, ...itJobs],
|
||||
expMultiplier: 1.1,
|
||||
salaryMultiplier: 1.1,
|
||||
jobStatReqOffset: 49,
|
||||
},
|
||||
[CompanyName.NoodleBar]: {
|
||||
name: CompanyName.NoodleBar,
|
||||
companyPositions: [JobName.waiter, JobName.waiterPT],
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
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: LocationName.AevumECorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12MegaCorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumBachmanAndAssociates,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.6,
|
||||
salaryMultiplier: 2.6,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12BladeIndustries,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenNWO,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 249,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumClarkeIncorporated,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenOmniTekIncorporated,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12FourSigma,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.5,
|
||||
salaryMultiplier: 2.5,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.ChongqingKuaiGongInternational,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.2,
|
||||
salaryMultiplier: 2.2,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumFulcrumTechnologies,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.IshimaStormTechnologies,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllSoftwareConsultantPositions, AllBusinessPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.NewTokyoDefComm,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.75,
|
||||
salaryMultiplier: 1.75,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenHeliosLabs,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.NewTokyoVitaLife,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12IcarusMicrosystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12UniversalEnergy,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumGalacticCybersystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumAeroCorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenOmniaCybersystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.ChongqingSolarisSpaceSystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12DeltaOne,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.6,
|
||||
salaryMultiplier: 1.6,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.NewTokyoGlobalPharmaceuticals,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 224,
|
||||
},
|
||||
{
|
||||
name: LocationName.IshimaNovaMedical,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
expMultiplier: 1.75,
|
||||
salaryMultiplier: 1.75,
|
||||
jobStatReqOffset: 199,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12CIA,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
SoftwarePositionsUpToHeadOfEngineering,
|
||||
AllNetworkEngineerPositions,
|
||||
SecurityEngineerPositions,
|
||||
AllITPositions,
|
||||
AllSecurityPositions,
|
||||
AllAgentPositions,
|
||||
),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 149,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12NSA,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
SoftwarePositionsUpToHeadOfEngineering,
|
||||
AllNetworkEngineerPositions,
|
||||
SecurityEngineerPositions,
|
||||
AllITPositions,
|
||||
AllSecurityPositions,
|
||||
AllAgentPositions,
|
||||
),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 149,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumWatchdogSecurity,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
SoftwarePositionsUpToHeadOfEngineering,
|
||||
AllNetworkEngineerPositions,
|
||||
AllITPositions,
|
||||
AllSecurityPositions,
|
||||
AllAgentPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
expMultiplier: 1.5,
|
||||
salaryMultiplier: 1.5,
|
||||
jobStatReqOffset: 124,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenLexoCorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
expMultiplier: 1.4,
|
||||
salaryMultiplier: 1.4,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumRhoConstruction,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, SoftwarePositionsUpToLeadDeveloper, BusinessPositionsUpToOperationsManager),
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 49,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12AlphaEnterprises,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
SoftwarePositionsUpToLeadDeveloper,
|
||||
BusinessPositionsUpToOperationsManager,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
expMultiplier: 1.5,
|
||||
salaryMultiplier: 1.5,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumPolice,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllSecurityPositions, SoftwarePositionsUpToLeadDeveloper),
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenSysCoreSecurities,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions),
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 124,
|
||||
},
|
||||
{
|
||||
name: LocationName.VolhavenCompuTek,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions),
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 74,
|
||||
},
|
||||
{
|
||||
name: LocationName.AevumNetLinkTechnologies,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions),
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 99,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12CarmichaelSecurity,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllAgentPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
expMultiplier: 1.2,
|
||||
salaryMultiplier: 1.2,
|
||||
jobStatReqOffset: 74,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12FoodNStuff,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, EmployeeOnly, PartTimeEmployeeOnly),
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
{
|
||||
name: LocationName.Sector12JoesGuns,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, EmployeeOnly, PartTimeEmployeeOnly),
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
{
|
||||
name: LocationName.IshimaOmegaSoftware,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, AllSoftwarePositions, AllSoftwareConsultantPositions, AllITPositions),
|
||||
expMultiplier: 1.1,
|
||||
salaryMultiplier: 1.1,
|
||||
jobStatReqOffset: 49,
|
||||
},
|
||||
{
|
||||
name: LocationName.NewTokyoNoodleBar,
|
||||
info: "",
|
||||
companyPositions: Object.assign({}, WaiterOnly, PartTimeWaiterOnly),
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 0,
|
||||
},
|
||||
];
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,5 @@
|
||||
import { JobName } from "@enums";
|
||||
|
||||
// This entire file can be reworked to
|
||||
export const SoftwareCompanyPositions: JobName[] = [
|
||||
export const softwareJobs = [
|
||||
JobName.software0,
|
||||
JobName.software1,
|
||||
JobName.software2,
|
||||
@ -11,14 +9,9 @@ export const SoftwareCompanyPositions: JobName[] = [
|
||||
JobName.software6,
|
||||
JobName.software7,
|
||||
];
|
||||
|
||||
export const ITCompanyPositions: JobName[] = [JobName.IT0, JobName.IT1, JobName.IT2, JobName.IT3];
|
||||
|
||||
export const SecurityEngineerCompanyPositions: JobName[] = [JobName.securityEng];
|
||||
|
||||
export const NetworkEngineerCompanyPositions: JobName[] = [JobName.networkEng0, JobName.networkEng1];
|
||||
|
||||
export const BusinessCompanyPositions: JobName[] = [
|
||||
export const itJobs = [JobName.IT0, JobName.IT1, JobName.IT2, JobName.IT3];
|
||||
export const netEngJobs = [JobName.networkEng0, JobName.networkEng1];
|
||||
export const businessJobs = [
|
||||
JobName.business0,
|
||||
JobName.business1,
|
||||
JobName.business2,
|
||||
@ -26,22 +19,7 @@ export const BusinessCompanyPositions: JobName[] = [
|
||||
JobName.business4,
|
||||
JobName.business5,
|
||||
];
|
||||
|
||||
export const SecurityCompanyPositions: JobName[] = [
|
||||
JobName.security0,
|
||||
JobName.security1,
|
||||
JobName.security2,
|
||||
JobName.security3,
|
||||
JobName.security4,
|
||||
JobName.security5,
|
||||
];
|
||||
|
||||
export const AgentCompanyPositions: JobName[] = [JobName.agent0, JobName.agent1, JobName.agent2];
|
||||
|
||||
export const MiscCompanyPositions: JobName[] = [JobName.waiter, JobName.employee];
|
||||
|
||||
export const SoftwareConsultantCompanyPositions: JobName[] = [JobName.softwareConsult0, JobName.softwareConsult1];
|
||||
|
||||
export const BusinessConsultantCompanyPositions: JobName[] = [JobName.businessConsult0, JobName.businessConsult1];
|
||||
|
||||
export const PartTimeCompanyPositions: JobName[] = [JobName.waiterPT, JobName.employeePT];
|
||||
export const securityJobs = [JobName.security0, JobName.security1, JobName.security2, JobName.security3];
|
||||
export const agentJobs = [JobName.agent0, JobName.agent1, JobName.agent2];
|
||||
export const softwareConsultJobs = [JobName.softwareConsult0, JobName.softwareConsult1];
|
||||
export const businessConsultJobs = [JobName.businessConsult0, JobName.businessConsult1];
|
||||
|
@ -4,18 +4,19 @@ import { Player } from "@player";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { CompanyName } from "../Enums";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
locName: string;
|
||||
companyName: CompanyName;
|
||||
company: Company;
|
||||
onQuit: () => void;
|
||||
}
|
||||
|
||||
export function QuitJobModal(props: IProps): React.ReactElement {
|
||||
function quit(): void {
|
||||
Player.quitJob(props.locName);
|
||||
Player.quitJob(props.companyName);
|
||||
props.onQuit();
|
||||
props.onClose();
|
||||
}
|
||||
|
11
src/Company/utils.ts
Normal file
11
src/Company/utils.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import type { CompanyName, LocationName } from "@enums";
|
||||
|
||||
type LocationNameString = `${LocationName}`;
|
||||
type CompanyNameString = `${CompanyName}`;
|
||||
type CompanyNamesAreAllLocationNames = CompanyNameString extends LocationNameString ? true : false;
|
||||
const __companyNameCheck: CompanyNamesAreAllLocationNames = true;
|
||||
|
||||
export function companyNameAsLocationName(companyName: CompanyName): LocationName {
|
||||
// Due to the check above, we know that all company names are valid location names.
|
||||
return companyName as unknown as LocationName;
|
||||
}
|
@ -9,64 +9,67 @@ import Button from "@mui/material/Button";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
|
||||
import { FactionName } from "@enums";
|
||||
import { Companies as AllCompanies } from "../../Company/Companies";
|
||||
import { CompanyName } from "@enums";
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { Adjuster } from "./Adjuster";
|
||||
import { isMember } from "../../utils/EnumHelper";
|
||||
import { getRecordValues } from "../../Types/Record";
|
||||
|
||||
const bigNumber = 1e12;
|
||||
|
||||
export function CompaniesDev(): React.ReactElement {
|
||||
const [company, setCompany] = useState(FactionName.ECorp as string);
|
||||
const [companyName, setCompanyName] = useState(CompanyName.ECorp);
|
||||
function setCompanyDropdown(event: SelectChangeEvent): void {
|
||||
setCompany(event.target.value);
|
||||
if (!isMember("CompanyName", event.target.value)) return;
|
||||
setCompanyName(event.target.value);
|
||||
}
|
||||
function resetCompanyRep(): void {
|
||||
AllCompanies[company].playerReputation = 0;
|
||||
Companies[companyName].playerReputation = 0;
|
||||
}
|
||||
|
||||
function modifyCompanyRep(modifier: number): (x: number) => void {
|
||||
return function (reputation: number): void {
|
||||
const c = AllCompanies[company];
|
||||
if (c != null && !isNaN(reputation)) {
|
||||
c.playerReputation += reputation * modifier;
|
||||
const company = Companies[companyName];
|
||||
if (!isNaN(reputation)) {
|
||||
company.playerReputation += reputation * modifier;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function modifyCompanyFavor(modifier: number): (x: number) => void {
|
||||
return function (favor: number): void {
|
||||
const c = AllCompanies[company];
|
||||
if (c != null && !isNaN(favor)) {
|
||||
c.favor += favor * modifier;
|
||||
const company = Companies[companyName];
|
||||
if (!isNaN(favor)) {
|
||||
company.favor += favor * modifier;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function resetCompanyFavor(): void {
|
||||
AllCompanies[company].favor = 0;
|
||||
Companies[companyName].favor = 0;
|
||||
}
|
||||
|
||||
function tonsOfRepCompanies(): void {
|
||||
for (const c of Object.keys(AllCompanies)) {
|
||||
AllCompanies[c].playerReputation = bigNumber;
|
||||
for (const company of getRecordValues(Companies)) {
|
||||
company.playerReputation = bigNumber;
|
||||
}
|
||||
}
|
||||
|
||||
function resetAllRepCompanies(): void {
|
||||
for (const c of Object.keys(AllCompanies)) {
|
||||
AllCompanies[c].playerReputation = 0;
|
||||
for (const company of getRecordValues(Companies)) {
|
||||
company.playerReputation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function tonsOfFavorCompanies(): void {
|
||||
for (const c of Object.keys(AllCompanies)) {
|
||||
AllCompanies[c].favor = bigNumber;
|
||||
for (const company of getRecordValues(Companies)) {
|
||||
company.favor = bigNumber;
|
||||
}
|
||||
}
|
||||
|
||||
function resetAllFavorCompanies(): void {
|
||||
for (const c of Object.keys(AllCompanies)) {
|
||||
AllCompanies[c].favor = 0;
|
||||
for (const company of getRecordValues(Companies)) {
|
||||
company.favor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +86,8 @@ export function CompaniesDev(): React.ReactElement {
|
||||
<Typography>Company:</Typography>
|
||||
</td>
|
||||
<td colSpan={3}>
|
||||
<Select id="dev-companies-dropdown" onChange={setCompanyDropdown} value={company}>
|
||||
{Object.values(AllCompanies).map((company) => (
|
||||
<Select id="dev-companies-dropdown" onChange={setCompanyDropdown} value={companyName}>
|
||||
{Object.values(Companies).map((company) => (
|
||||
<MenuItem key={company.name} value={company.name}>
|
||||
{company.name}
|
||||
</MenuItem>
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
export * from "./Augmentation/Enums";
|
||||
export * from "./Bladeburner/Enums";
|
||||
export * from "./Company/Enums";
|
||||
export * from "./Corporation/Enums";
|
||||
export * from "./Crime/Enums";
|
||||
export * from "./Faction/Enums";
|
||||
|
@ -21,7 +21,6 @@ for (const aug of getRecordValues(Augmentations)) {
|
||||
}
|
||||
|
||||
export function loadFactions(saveString: string): void {
|
||||
// The only information that should be loaded from player save is
|
||||
const loadedFactions = JSON.parse(saveString, Reviver) as unknown;
|
||||
// This loading method allows invalid data in player save, but just ignores anything invalid
|
||||
if (!loadedFactions) return;
|
||||
|
@ -22,6 +22,7 @@ import { Player } from "@player";
|
||||
import { GetServer } from "../Server/AllServers";
|
||||
import { Server } from "../Server/Server";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { isMember } from "../utils/EnumHelper";
|
||||
|
||||
// Returns a boolean indicating whether the player has Hacknet Servers
|
||||
// (the upgraded form of Hacknet Nodes)
|
||||
@ -564,7 +565,7 @@ export function purchaseHashUpgrade(upgName: string, upgTarget: string, count =
|
||||
break;
|
||||
}
|
||||
case "Company Favor": {
|
||||
if (!(upgTarget in Companies)) {
|
||||
if (!isMember("CompanyName", upgTarget)) {
|
||||
console.error(`Invalid target specified in purchaseHashUpgrade(): ${upgTarget}`);
|
||||
throw new Error(`'${upgTarget}' is not a company.`);
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Button from "@mui/material/Button";
|
||||
import { SelectChangeEvent } from "@mui/material/Select";
|
||||
import { FactionName } from "@enums";
|
||||
import { companiesMetadata } from "../../Company/data/CompaniesMetadata";
|
||||
import { CompanyName, FactionName } from "@enums";
|
||||
import { PartialRecord } from "../../Types/Record";
|
||||
import { isMember } from "../../utils/EnumHelper";
|
||||
|
||||
interface IProps {
|
||||
hashManager: HashManager;
|
||||
@ -24,8 +25,9 @@ interface IProps {
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
// Key is the hash upgrade name
|
||||
const serversMap: Record<string, string> = {};
|
||||
const companiesMap: Record<string, string> = {};
|
||||
const companiesMap: PartialRecord<string, CompanyName> = {};
|
||||
|
||||
export function HacknetUpgradeElem(props: IProps): React.ReactElement {
|
||||
const [selectedServer, setSelectedServer] = useState(
|
||||
@ -35,10 +37,9 @@ export function HacknetUpgradeElem(props: IProps): React.ReactElement {
|
||||
setSelectedServer(event.target.value);
|
||||
serversMap[props.upg.name] = event.target.value;
|
||||
}
|
||||
const [selectedCompany, setSelectedCompany] = useState(
|
||||
companiesMap[props.upg.name] ? companiesMap[props.upg.name] : companiesMetadata[0].name,
|
||||
);
|
||||
function changeTargetCompany(event: SelectChangeEvent): void {
|
||||
const [selectedCompany, setSelectedCompany] = useState(companiesMap[props.upg.name] ?? CompanyName.NoodleBar);
|
||||
function changeTargetCompany(event: SelectChangeEvent<CompanyName>): void {
|
||||
if (!isMember("CompanyName", event.target.value)) return;
|
||||
setSelectedCompany(event.target.value);
|
||||
companiesMap[props.upg.name] = event.target.value;
|
||||
}
|
||||
|
@ -12,11 +12,10 @@ import Box from "@mui/material/Box";
|
||||
import { ApplyToJobButton } from "./ApplyToJobButton";
|
||||
|
||||
import { Locations } from "../Locations";
|
||||
import { LocationName } from "@enums";
|
||||
import { CompanyName, JobName } from "@enums";
|
||||
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
import * as posNames from "../../Company/data/JobTracks";
|
||||
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { Favor } from "../../ui/React/Favor";
|
||||
@ -26,9 +25,10 @@ import { Player } from "@player";
|
||||
import { QuitJobModal } from "../../Company/ui/QuitJobModal";
|
||||
import { CompanyWork } from "../../Work/CompanyWork";
|
||||
import { useRerender } from "../../ui/React/hooks";
|
||||
import { companyNameAsLocationName } from "../../Company/utils";
|
||||
|
||||
interface IProps {
|
||||
locName: LocationName;
|
||||
companyName: CompanyName;
|
||||
}
|
||||
|
||||
export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
@ -39,17 +39,18 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
* We'll keep a reference to the Company that this component is being rendered for,
|
||||
* so we don't have to look it up every time
|
||||
*/
|
||||
const company = Companies[props.locName];
|
||||
if (company == null) throw new Error(`CompanyLocation component constructed with invalid company: ${props.locName}`);
|
||||
const company = Companies[props.companyName];
|
||||
if (company == null)
|
||||
throw new Error(`CompanyLocation component constructed with invalid company: ${props.companyName}`);
|
||||
|
||||
/** Reference to the Location that this component is being rendered for */
|
||||
const location = Locations[props.locName];
|
||||
const location = Locations[props.companyName];
|
||||
if (location == null) {
|
||||
throw new Error(`CompanyLocation component constructed with invalid location: ${props.locName}`);
|
||||
throw new Error(`CompanyLocation component constructed with invalid location: ${props.companyName}`);
|
||||
}
|
||||
|
||||
/** Name of company position that player holds, if applicable */
|
||||
const jobTitle = Player.jobs[props.locName] ? Player.jobs[props.locName] : null;
|
||||
const jobTitle = Player.jobs[props.companyName] ? Player.jobs[props.companyName] : null;
|
||||
|
||||
/**
|
||||
* CompanyPosition object for the job that the player holds at this company
|
||||
@ -57,7 +58,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
*/
|
||||
const companyPosition = jobTitle ? CompanyPositions[jobTitle] : null;
|
||||
|
||||
Player.location = props.locName;
|
||||
Player.location = companyNameAsLocationName(props.companyName);
|
||||
|
||||
function applyForAgentJob(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
@ -152,7 +153,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
return;
|
||||
}
|
||||
if (!location.infiltrationData)
|
||||
throw new Error(`trying to start infiltration at ${props.locName} but the infiltrationData is null`);
|
||||
throw new Error(`trying to start infiltration at ${props.companyName} but the infiltrationData is null`);
|
||||
|
||||
Router.toPage(Page.Infiltration, { location });
|
||||
}
|
||||
@ -167,7 +168,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
Player.startWork(
|
||||
new CompanyWork({
|
||||
singularity: false,
|
||||
companyName: props.locName,
|
||||
companyName: props.companyName,
|
||||
}),
|
||||
);
|
||||
Player.startFocusing();
|
||||
@ -224,7 +225,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
<Button onClick={work}>Work</Button>
|
||||
<Button onClick={() => setQuitOpen(true)}>Quit</Button>
|
||||
<QuitJobModal
|
||||
locName={props.locName}
|
||||
companyName={props.companyName}
|
||||
company={company}
|
||||
onQuit={rerender}
|
||||
open={quitOpen}
|
||||
@ -235,7 +236,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasAgentPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.AgentCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.agent0]}
|
||||
onClick={applyForAgentJob}
|
||||
text={"Apply for Agent Job"}
|
||||
/>
|
||||
@ -243,7 +244,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasBusinessConsultantPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.businessConsult0]}
|
||||
onClick={applyForBusinessConsultantJob}
|
||||
text={"Apply for Business Consultant Job"}
|
||||
/>
|
||||
@ -251,7 +252,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasBusinessPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.BusinessCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.business0]}
|
||||
onClick={applyForBusinessJob}
|
||||
text={"Apply for Business Job"}
|
||||
/>
|
||||
@ -259,7 +260,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasEmployeePositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[1]]}
|
||||
entryPosType={CompanyPositions[JobName.employee]}
|
||||
onClick={applyForEmployeeJob}
|
||||
text={"Apply to be an Employee"}
|
||||
/>
|
||||
@ -267,7 +268,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasEmployeePositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[1]]}
|
||||
entryPosType={CompanyPositions[JobName.employeePT]}
|
||||
onClick={applyForPartTimeEmployeeJob}
|
||||
text={"Apply to be a part-time Employee"}
|
||||
/>
|
||||
@ -275,7 +276,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasITPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.ITCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.IT0]}
|
||||
onClick={applyForItJob}
|
||||
text={"Apply for IT Job"}
|
||||
/>
|
||||
@ -283,7 +284,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasSecurityPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.SecurityCompanyPositions[2]]}
|
||||
entryPosType={CompanyPositions[JobName.security0]}
|
||||
onClick={applyForSecurityJob}
|
||||
text={"Apply for Security Job"}
|
||||
/>
|
||||
@ -291,7 +292,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasSoftwareConsultantPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.softwareConsult0]}
|
||||
onClick={applyForSoftwareConsultantJob}
|
||||
text={"Apply for Software Consultant Job"}
|
||||
/>
|
||||
@ -299,7 +300,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasSoftwarePositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.SoftwareCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.software0]}
|
||||
onClick={applyForSoftwareJob}
|
||||
text={"Apply for Software Job"}
|
||||
/>
|
||||
@ -307,7 +308,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasWaiterPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.waiter]}
|
||||
onClick={applyForWaiterJob}
|
||||
text={"Apply to be a Waiter"}
|
||||
/>
|
||||
@ -315,7 +316,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
{company.hasWaiterPositions() && (
|
||||
<ApplyToJobButton
|
||||
company={company}
|
||||
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[0]]}
|
||||
entryPosType={CompanyPositions[JobName.waiterPT]}
|
||||
onClick={applyForPartTimeWaiterJob}
|
||||
text={"Apply to be a part-time Waiter"}
|
||||
/>
|
||||
|
@ -31,6 +31,7 @@ import { Router } from "../../ui/GameRoot";
|
||||
import { Page } from "../../ui/Router";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { Tooltip } from "@mui/material";
|
||||
import { getEnumHelper } from "../../utils/EnumHelper";
|
||||
|
||||
interface IProps {
|
||||
loc: Location;
|
||||
@ -45,7 +46,10 @@ export function GenericLocation({ loc }: IProps): React.ReactElement {
|
||||
const content: React.ReactNode[] = [];
|
||||
|
||||
if (loc.types.includes(LocationType.Company)) {
|
||||
content.push(<CompanyLocation key="CompanyLocation" locName={loc.name} />);
|
||||
if (!getEnumHelper("CompanyName").isMember(loc.name)) {
|
||||
throw new Error(`Location name ${loc.name} is for a company but is not a company name.`);
|
||||
}
|
||||
content.push(<CompanyLocation key="CompanyLocation" companyName={loc.name} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Gym)) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import type { Singularity as ISingularity } from "@nsdefs";
|
||||
import type { Company } from "../Company/Company";
|
||||
|
||||
import { Player } from "@player";
|
||||
import {
|
||||
@ -31,7 +30,6 @@ import { Programs } from "../Programs/Programs";
|
||||
import { formatMoney, formatRam, formatReputation } from "../ui/formatNumber";
|
||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { companiesMetadata } from "../Company/data/CompaniesMetadata";
|
||||
import { Factions } from "../Faction/Factions";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||
@ -42,7 +40,7 @@ import { Server } from "../Server/Server";
|
||||
import { netscriptCanHack } from "../Hacking/netscriptCanHack";
|
||||
import { FactionInfos } from "../Faction/FactionInfo";
|
||||
import { donate, repNeededToDonate } from "../Faction/formulas/donation";
|
||||
import { InternalAPI, NetscriptContext, removedFunction } from "../Netscript/APIWrapper";
|
||||
import { InternalAPI, removedFunction } from "../Netscript/APIWrapper";
|
||||
import { enterBitNode } from "../RedPill";
|
||||
import { ClassWork } from "../Work/ClassWork";
|
||||
import { CreateProgramWork, isCreateProgramWork } from "../Work/CreateProgramWork";
|
||||
@ -56,14 +54,10 @@ import { Engine } from "../engine";
|
||||
import { getEnumHelper } from "../utils/EnumHelper";
|
||||
import { ScriptFilePath, resolveScriptFilePath } from "../Paths/ScriptFilePath";
|
||||
import { root } from "../Paths/Directory";
|
||||
import { companyNameAsLocationName } from "../Company/utils";
|
||||
import { getRecordEntries } from "../Types/Record";
|
||||
|
||||
export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
const getCompany = function (ctx: NetscriptContext, name: string): Company {
|
||||
const company = Companies[name];
|
||||
if (!company) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid company name: '${name}'`);
|
||||
return company;
|
||||
};
|
||||
|
||||
const runAfterReset = function (cbScript: ScriptFilePath) {
|
||||
//Run a script after reset
|
||||
if (!cbScript) return;
|
||||
@ -670,45 +664,35 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
},
|
||||
getCompanyPositions: (ctx) => (_companyName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
|
||||
// Make sure its a valid company
|
||||
if (companyName == null || companyName === "" || !Companies[companyName]) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid company: '${companyName}'`);
|
||||
}
|
||||
|
||||
return Object.entries(CompanyPositions)
|
||||
return getRecordEntries(CompanyPositions)
|
||||
.filter((_position) => Companies[companyName].hasPosition(_position[0]))
|
||||
.map((_position) => _position[1].name);
|
||||
},
|
||||
getCompanyPositionInfo: (ctx) => (_companyName, _positionName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
const positionName = getEnumHelper("JobName").nsGetMember(ctx, _positionName, "positionName");
|
||||
const company = Companies[companyName];
|
||||
|
||||
// Make sure its a valid company
|
||||
if (!(companyName in Companies)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid company: '${companyName}'`);
|
||||
}
|
||||
|
||||
if (!Companies[companyName].hasPosition(positionName)) {
|
||||
if (!company.hasPosition(positionName)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Company '${companyName}' does not have position '${positionName}'`);
|
||||
}
|
||||
|
||||
const c = CompanyPositions[positionName];
|
||||
const n = companiesMetadata.filter((company) => company.name === companyName)[0];
|
||||
const job = CompanyPositions[positionName];
|
||||
const res = {
|
||||
name: CompanyPositions[positionName].name,
|
||||
nextPosition: CompanyPositions[positionName].nextPosition,
|
||||
salary: CompanyPositions[positionName].baseSalary * n.salaryMultiplier,
|
||||
salary: CompanyPositions[positionName].baseSalary * company.salaryMultiplier,
|
||||
requiredReputation: CompanyPositions[positionName].requiredReputation,
|
||||
requiredSkills: {
|
||||
hacking: c.requiredHacking > 0 ? c.requiredHacking + n.jobStatReqOffset : 0,
|
||||
strength: c.requiredStrength > 0 ? c.requiredStrength + n.jobStatReqOffset : 0,
|
||||
defense: c.requiredDefense > 0 ? c.requiredDefense + n.jobStatReqOffset : 0,
|
||||
dexterity: c.requiredDexterity > 0 ? c.requiredDexterity + n.jobStatReqOffset : 0,
|
||||
agility: c.requiredAgility > 0 ? c.requiredAgility + n.jobStatReqOffset : 0,
|
||||
charisma: c.requiredCharisma > 0 ? c.requiredCharisma + n.jobStatReqOffset : 0,
|
||||
hacking: job.requiredHacking > 0 ? job.requiredHacking + company.jobStatReqOffset : 0,
|
||||
strength: job.requiredStrength > 0 ? job.requiredStrength + company.jobStatReqOffset : 0,
|
||||
defense: job.requiredDefense > 0 ? job.requiredDefense + company.jobStatReqOffset : 0,
|
||||
dexterity: job.requiredDexterity > 0 ? job.requiredDexterity + company.jobStatReqOffset : 0,
|
||||
agility: job.requiredAgility > 0 ? job.requiredAgility + company.jobStatReqOffset : 0,
|
||||
charisma: job.requiredCharisma > 0 ? job.requiredCharisma + company.jobStatReqOffset : 0,
|
||||
intelligence: 0,
|
||||
},
|
||||
};
|
||||
@ -718,26 +702,15 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
(ctx) =>
|
||||
(_companyName, _focus = true) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
const focus = !!_focus;
|
||||
|
||||
// Make sure its a valid company
|
||||
if (companyName == null || companyName === "" || !Companies[companyName]) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid company: '${companyName}'`);
|
||||
}
|
||||
|
||||
const jobName = Player.jobs[companyName];
|
||||
// Make sure player is actually employed at the company
|
||||
if (!Object.keys(Player.jobs).includes(companyName)) {
|
||||
if (!jobName) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `You do not have a job at: '${companyName}'`);
|
||||
}
|
||||
|
||||
// Check to make sure company position data is valid
|
||||
const companyPositionName = Player.jobs[companyName];
|
||||
const companyPosition = CompanyPositions[companyPositionName];
|
||||
if (companyPositionName === "" || !companyPosition) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `You do not have a job`);
|
||||
}
|
||||
|
||||
const wasFocused = Player.focus;
|
||||
|
||||
Player.startWork(
|
||||
@ -753,16 +726,15 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
Player.stopFocusing();
|
||||
Router.toPage(Page.Terminal);
|
||||
}
|
||||
helpers.log(ctx, () => `Began working at '${companyName}' with position '${companyPositionName}'`);
|
||||
helpers.log(ctx, () => `Began working at '${companyName}' with position '${jobName}'`);
|
||||
return true;
|
||||
},
|
||||
applyToCompany: (ctx) => (_companyName, _field) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
const field = helpers.string(ctx, "field", _field);
|
||||
getCompany(ctx, companyName);
|
||||
|
||||
Player.location = companyName as LocationName;
|
||||
Player.location = companyNameAsLocationName(companyName);
|
||||
let res;
|
||||
switch (field.toLowerCase()) {
|
||||
case "software":
|
||||
@ -826,26 +798,23 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
},
|
||||
quitJob: (ctx) => (_companyName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
Player.quitJob(companyName);
|
||||
},
|
||||
getCompanyRep: (ctx) => (_companyName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.playerReputation;
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
return Companies[companyName].playerReputation;
|
||||
},
|
||||
getCompanyFavor: (ctx) => (_companyName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.favor;
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
return Companies[companyName].favor;
|
||||
},
|
||||
getCompanyFavorGain: (ctx) => (_companyName) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.getFavorGain();
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
return Companies[companyName].getFavorGain();
|
||||
},
|
||||
checkFactionInvitations: (ctx) => () => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
@ -78,9 +78,9 @@ export function NetscriptSleeve(): InternalAPI<NetscriptSleeve> {
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].travel(cityName);
|
||||
},
|
||||
setToCompanyWork: (ctx) => (_sleeveNumber, acompanyName) => {
|
||||
setToCompanyWork: (ctx) => (_sleeveNumber, _companyName) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const companyName = helpers.string(ctx, "companyName", acompanyName);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
|
@ -17,7 +17,7 @@ import * as serverMethods from "./PlayerObjectServerMethods";
|
||||
import * as workMethods from "./PlayerObjectWorkMethods";
|
||||
|
||||
import { setPlayer } from "../../Player";
|
||||
import { FactionName, LocationName } from "@enums";
|
||||
import { CompanyName, FactionName, JobName, LocationName } from "@enums";
|
||||
import { HashManager } from "../../Hacknet/HashManager";
|
||||
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
||||
import { constructorsForReviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../../utils/JSONReviver";
|
||||
@ -26,7 +26,8 @@ import { cyrb53 } from "../../utils/StringHelperFunctions";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Person } from "../Person";
|
||||
import { getEnumHelper } from "../../utils/EnumHelper";
|
||||
import { isMember } from "../../utils/EnumHelper";
|
||||
import { PartialRecord } from "../../Types/Record";
|
||||
|
||||
export class PlayerObject extends Person implements IPlayer {
|
||||
// Player-specific properties
|
||||
@ -43,7 +44,7 @@ export class PlayerObject extends Person implements IPlayer {
|
||||
hashManager = new HashManager();
|
||||
hasTixApiAccess = false;
|
||||
hasWseAccount = false;
|
||||
jobs: Record<string, string> = {};
|
||||
jobs: PartialRecord<CompanyName, JobName> = {};
|
||||
karma = 0;
|
||||
numPeopleKilled = 0;
|
||||
location = LocationName.TravelAgency;
|
||||
@ -172,11 +173,9 @@ export class PlayerObject extends Person implements IPlayer {
|
||||
player.hp = { current: player.hp?.current ?? 10, max: player.hp?.max ?? 10 };
|
||||
player.money ??= 0;
|
||||
// Just remove from the save file any augs that have invalid name
|
||||
player.augmentations = player.augmentations.filter((ownedAug) =>
|
||||
getEnumHelper("AugmentationName").isMember(ownedAug.name),
|
||||
);
|
||||
player.augmentations = player.augmentations.filter((ownedAug) => isMember("AugmentationName", ownedAug.name));
|
||||
player.queuedAugmentations = player.queuedAugmentations.filter((ownedAug) =>
|
||||
getEnumHelper("AugmentationName").isMember(ownedAug.name),
|
||||
isMember("AugmentationName", ownedAug.name),
|
||||
);
|
||||
player.updateSkillLevels();
|
||||
// Converstion code for Player.sourceFiles is here instead of normal save conversion area because it needs
|
||||
@ -186,6 +185,12 @@ export class PlayerObject extends Person implements IPlayer {
|
||||
type OldSourceFiles = { n: number; lvl: number }[];
|
||||
player.sourceFiles = new JSONMap((player.sourceFiles as OldSourceFiles).map(({ n, lvl }) => [n, lvl]));
|
||||
}
|
||||
// Remove any invalid jobs
|
||||
for (const [loadedCompanyName, loadedJobName] of Object.entries(player.jobs)) {
|
||||
if (!isMember("CompanyName", loadedCompanyName) || !isMember("JobName", loadedJobName)) {
|
||||
delete player.jobs[loadedCompanyName as CompanyName];
|
||||
}
|
||||
}
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,13 @@
|
||||
import { AugmentationName, CityName, CompletedProgramName, FactionName, LocationName, ToastVariant } from "@enums";
|
||||
import {
|
||||
AugmentationName,
|
||||
CityName,
|
||||
CompanyName,
|
||||
CompletedProgramName,
|
||||
FactionName,
|
||||
JobName,
|
||||
LocationName,
|
||||
ToastVariant,
|
||||
} from "@enums";
|
||||
|
||||
import type { PlayerObject } from "./PlayerObject";
|
||||
import type { ProgramFilePath } from "../../Paths/ProgramFilePath";
|
||||
@ -13,7 +22,6 @@ import { getNextCompanyPositionHelper } from "../../Company/GetNextCompanyPositi
|
||||
import { getJobRequirementText } from "../../Company/GetJobRequirementText";
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
import { CompanyPosition } from "../../Company/CompanyPosition";
|
||||
import * as posNames from "../../Company/data/JobTracks";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Exploit } from "../../Exploits/Exploit";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
@ -44,6 +52,7 @@ import { achievements } from "../../Achievements/Achievements";
|
||||
|
||||
import { isCompanyWork } from "../../Work/CompanyWork";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { getEnumHelper, isMember } from "../../utils/EnumHelper";
|
||||
|
||||
export function init(this: PlayerObject): void {
|
||||
/* Initialize Player's home computer */
|
||||
@ -262,12 +271,9 @@ export function hospitalize(this: PlayerObject): number {
|
||||
//The 'sing' argument designates whether or not this is being called from
|
||||
//the applyToCompany() Netscript Singularity function
|
||||
export function applyForJob(this: PlayerObject, entryPosType: CompanyPosition, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
if (!company) {
|
||||
console.error(`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName]; //Company being applied to
|
||||
let pos = entryPosType;
|
||||
|
||||
if (!this.isQualified(company, pos)) {
|
||||
@ -347,7 +353,7 @@ export function getNextCompanyPosition(
|
||||
return entryPosType;
|
||||
}
|
||||
|
||||
export function quitJob(this: PlayerObject, company: string): void {
|
||||
export function quitJob(this: PlayerObject, company: CompanyName): void {
|
||||
if (isCompanyWork(this.currentWork) && this.currentWork.companyName === company) {
|
||||
this.finishWork(true);
|
||||
}
|
||||
@ -370,21 +376,23 @@ export function hasJob(this: PlayerObject): boolean {
|
||||
}
|
||||
|
||||
export function applyForSoftwareJob(this: PlayerObject, sing = false): boolean {
|
||||
return this.applyForJob(CompanyPositions[posNames.SoftwareCompanyPositions[0]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.software0], sing);
|
||||
}
|
||||
|
||||
export function applyForSoftwareConsultantJob(this: PlayerObject, sing = false): boolean {
|
||||
return this.applyForJob(CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.softwareConsult0], sing);
|
||||
}
|
||||
|
||||
export function applyForItJob(this: PlayerObject, sing = false): boolean {
|
||||
return this.applyForJob(CompanyPositions[posNames.ITCompanyPositions[0]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.IT0], sing);
|
||||
}
|
||||
|
||||
export function applyForSecurityEngineerJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions[posNames.SecurityEngineerCompanyPositions[0]])) {
|
||||
return this.applyForJob(CompanyPositions[posNames.SecurityEngineerCompanyPositions[0]], sing);
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
if (this.isQualified(company, CompanyPositions[JobName.securityEng])) {
|
||||
return this.applyForJob(CompanyPositions[JobName.securityEng], sing);
|
||||
} else {
|
||||
if (!sing) {
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for this position");
|
||||
@ -394,9 +402,11 @@ export function applyForSecurityEngineerJob(this: PlayerObject, sing = false): b
|
||||
}
|
||||
|
||||
export function applyForNetworkEngineerJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]])) {
|
||||
const pos = CompanyPositions[posNames.NetworkEngineerCompanyPositions[0]];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
if (this.isQualified(company, CompanyPositions[JobName.networkEng0])) {
|
||||
const pos = CompanyPositions[JobName.networkEng0];
|
||||
return this.applyForJob(pos, sing);
|
||||
} else {
|
||||
if (!sing) {
|
||||
@ -407,23 +417,25 @@ export function applyForNetworkEngineerJob(this: PlayerObject, sing = false): bo
|
||||
}
|
||||
|
||||
export function applyForBusinessJob(this: PlayerObject, sing = false): boolean {
|
||||
return this.applyForJob(CompanyPositions[posNames.BusinessCompanyPositions[0]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.business0], sing);
|
||||
}
|
||||
|
||||
export function applyForBusinessConsultantJob(this: PlayerObject, sing = false): boolean {
|
||||
return this.applyForJob(CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.businessConsult0], sing);
|
||||
}
|
||||
|
||||
export function applyForSecurityJob(this: PlayerObject, sing = false): boolean {
|
||||
// TODO Police Jobs
|
||||
// Indexing starts at 2 because 0 is for police officer
|
||||
return this.applyForJob(CompanyPositions[posNames.SecurityCompanyPositions[2]], sing);
|
||||
return this.applyForJob(CompanyPositions[JobName.security0], sing);
|
||||
}
|
||||
|
||||
export function applyForAgentJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions[posNames.AgentCompanyPositions[0]])) {
|
||||
const pos = CompanyPositions[posNames.AgentCompanyPositions[0]];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
if (this.isQualified(company, CompanyPositions[JobName.agent0])) {
|
||||
const pos = CompanyPositions[JobName.agent0];
|
||||
return this.applyForJob(pos, sing);
|
||||
} else {
|
||||
if (!sing) {
|
||||
@ -434,8 +446,10 @@ export function applyForAgentJob(this: PlayerObject, sing = false): boolean {
|
||||
}
|
||||
|
||||
export function applyForEmployeeJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
const position = posNames.MiscCompanyPositions[1];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
const position = JobName.employee;
|
||||
// Check if this company has the position
|
||||
if (!company.hasPosition(position)) {
|
||||
return false;
|
||||
@ -458,8 +472,10 @@ export function applyForEmployeeJob(this: PlayerObject, sing = false): boolean {
|
||||
}
|
||||
|
||||
export function applyForPartTimeEmployeeJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
const position = posNames.PartTimeCompanyPositions[1];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
const position = JobName.employeePT;
|
||||
// Check if this company has the position
|
||||
if (!company.hasPosition(position)) {
|
||||
return false;
|
||||
@ -481,8 +497,10 @@ export function applyForPartTimeEmployeeJob(this: PlayerObject, sing = false): b
|
||||
}
|
||||
|
||||
export function applyForWaiterJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
const position = posNames.MiscCompanyPositions[0];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
const position = JobName.waiter;
|
||||
// Check if this company has the position
|
||||
if (!company.hasPosition(position)) {
|
||||
return false;
|
||||
@ -502,8 +520,10 @@ export function applyForWaiterJob(this: PlayerObject, sing = false): boolean {
|
||||
}
|
||||
|
||||
export function applyForPartTimeWaiterJob(this: PlayerObject, sing = false): boolean {
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
const position = posNames.PartTimeCompanyPositions[0];
|
||||
const companyName = getEnumHelper("CompanyName").getMember(this.location);
|
||||
if (!companyName) return false;
|
||||
const company = Companies[companyName];
|
||||
const position = JobName.waiterPT;
|
||||
// Check if this company has the position
|
||||
if (!company.hasPosition(position)) {
|
||||
return false;
|
||||
@ -594,20 +614,16 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
const allPositions = Object.values(this.jobs);
|
||||
|
||||
// Given a company name, safely returns the reputation (returns 0 if invalid company is specified)
|
||||
function getCompanyRep(companyName: string): number {
|
||||
function getCompanyRep(companyName: CompanyName): number {
|
||||
const company = Companies[companyName];
|
||||
if (company == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return company.playerReputation;
|
||||
}
|
||||
return company.playerReputation;
|
||||
}
|
||||
|
||||
// Helper function that returns a boolean indicating whether the Player meets
|
||||
// the requirements for the specified company. There are two requirements:
|
||||
// 1. High enough reputation
|
||||
// 2. Player is employed at the company
|
||||
function checkMegacorpRequirements(companyName: string): boolean {
|
||||
function checkMegacorpRequirements(companyName: CompanyName): boolean {
|
||||
const serverMeta = serverMetadata.find((s) => s.specialName === companyName);
|
||||
const server = GetServer(serverMeta ? serverMeta.hostname : "");
|
||||
const bonus = (server as Server).backdoorInstalled ? -100e3 : 0;
|
||||
@ -673,7 +689,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!ecorpFac.isBanned &&
|
||||
!ecorpFac.isMember &&
|
||||
!ecorpFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.AevumECorp)
|
||||
checkMegacorpRequirements(CompanyName.ECorp)
|
||||
) {
|
||||
invitedFactions.push(ecorpFac);
|
||||
}
|
||||
@ -684,7 +700,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!megacorpFac.isBanned &&
|
||||
!megacorpFac.isMember &&
|
||||
!megacorpFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.Sector12MegaCorp)
|
||||
checkMegacorpRequirements(CompanyName.MegaCorp)
|
||||
) {
|
||||
invitedFactions.push(megacorpFac);
|
||||
}
|
||||
@ -695,7 +711,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!bachmanandassociatesFac.isBanned &&
|
||||
!bachmanandassociatesFac.isMember &&
|
||||
!bachmanandassociatesFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.AevumBachmanAndAssociates)
|
||||
checkMegacorpRequirements(CompanyName.BachmanAndAssociates)
|
||||
) {
|
||||
invitedFactions.push(bachmanandassociatesFac);
|
||||
}
|
||||
@ -706,19 +722,14 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!bladeindustriesFac.isBanned &&
|
||||
!bladeindustriesFac.isMember &&
|
||||
!bladeindustriesFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.Sector12BladeIndustries)
|
||||
checkMegacorpRequirements(CompanyName.BladeIndustries)
|
||||
) {
|
||||
invitedFactions.push(bladeindustriesFac);
|
||||
}
|
||||
|
||||
//NWO
|
||||
const nwoFac = Factions[FactionName.NWO];
|
||||
if (
|
||||
!nwoFac.isBanned &&
|
||||
!nwoFac.isMember &&
|
||||
!nwoFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.VolhavenNWO)
|
||||
) {
|
||||
if (!nwoFac.isBanned && !nwoFac.isMember && !nwoFac.alreadyInvited && checkMegacorpRequirements(CompanyName.NWO)) {
|
||||
invitedFactions.push(nwoFac);
|
||||
}
|
||||
|
||||
@ -728,7 +739,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!clarkeincorporatedFac.isBanned &&
|
||||
!clarkeincorporatedFac.isMember &&
|
||||
!clarkeincorporatedFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.AevumClarkeIncorporated)
|
||||
checkMegacorpRequirements(CompanyName.ClarkeIncorporated)
|
||||
) {
|
||||
invitedFactions.push(clarkeincorporatedFac);
|
||||
}
|
||||
@ -739,7 +750,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!omnitekincorporatedFac.isBanned &&
|
||||
!omnitekincorporatedFac.isMember &&
|
||||
!omnitekincorporatedFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.VolhavenOmniTekIncorporated)
|
||||
checkMegacorpRequirements(CompanyName.OmniTekIncorporated)
|
||||
) {
|
||||
invitedFactions.push(omnitekincorporatedFac);
|
||||
}
|
||||
@ -750,7 +761,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!foursigmaFac.isBanned &&
|
||||
!foursigmaFac.isMember &&
|
||||
!foursigmaFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.Sector12FourSigma)
|
||||
checkMegacorpRequirements(CompanyName.FourSigma)
|
||||
) {
|
||||
invitedFactions.push(foursigmaFac);
|
||||
}
|
||||
@ -761,7 +772,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!kuaigonginternationalFac.isBanned &&
|
||||
!kuaigonginternationalFac.isMember &&
|
||||
!kuaigonginternationalFac.alreadyInvited &&
|
||||
checkMegacorpRequirements(LocationName.ChongqingKuaiGongInternational)
|
||||
checkMegacorpRequirements(CompanyName.KuaiGongInternational)
|
||||
) {
|
||||
invitedFactions.push(kuaigonginternationalFac);
|
||||
}
|
||||
@ -778,7 +789,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!fulcrumsecrettechonologiesFac.isMember &&
|
||||
!fulcrumsecrettechonologiesFac.alreadyInvited &&
|
||||
fulcrumSecretServer.backdoorInstalled &&
|
||||
checkMegacorpRequirements(LocationName.AevumFulcrumTechnologies)
|
||||
checkMegacorpRequirements(CompanyName.FulcrumTechnologies)
|
||||
) {
|
||||
invitedFactions.push(fulcrumsecrettechonologiesFac);
|
||||
}
|
||||
@ -966,9 +977,9 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] {
|
||||
!silhouetteFac.isBanned &&
|
||||
!silhouetteFac.isMember &&
|
||||
!silhouetteFac.alreadyInvited &&
|
||||
(allPositions.includes("Chief Technology Officer") ||
|
||||
allPositions.includes("Chief Financial Officer") ||
|
||||
allPositions.includes("Chief Executive Officer")) &&
|
||||
(allPositions.includes(JobName.software7) || // CTO
|
||||
allPositions.includes(JobName.business4) || // CFO
|
||||
allPositions.includes(JobName.business5)) && // CEO
|
||||
this.money >= 15000000 &&
|
||||
this.karma <= -22
|
||||
) {
|
||||
@ -1136,8 +1147,7 @@ export function gainCodingContractReward(
|
||||
return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.join(", ")}`;
|
||||
}
|
||||
case CodingContractRewardType.CompanyReputation: {
|
||||
if (!Companies[reward.name]) {
|
||||
//If no/invalid company was designated, just give rewards to all factions
|
||||
if (!isMember("CompanyName", reward.name)) {
|
||||
return this.gainCodingContractReward({ type: CodingContractRewardType.FactionReputationAll });
|
||||
}
|
||||
const repGain = CONSTANTS.CodingContractBaseCompanyRepGain * difficulty;
|
||||
|
@ -9,18 +9,23 @@
|
||||
|
||||
import type { SleevePerson } from "@nsdefs";
|
||||
import type { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import type { Company } from "../../Company/Company";
|
||||
import type { CompanyPosition } from "../../Company/CompanyPosition";
|
||||
import type { SleeveWork } from "./Work/Work";
|
||||
|
||||
import { Player } from "@player";
|
||||
import { Person } from "../Person";
|
||||
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
import { Contracts } from "../../Bladeburner/data/Contracts";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { ClassType, CityName, CrimeType, FactionWorkType, GymType, LocationName, UniversityClassType } from "@enums";
|
||||
import {
|
||||
ClassType,
|
||||
CityName,
|
||||
CrimeType,
|
||||
FactionWorkType,
|
||||
GymType,
|
||||
LocationName,
|
||||
UniversityClassType,
|
||||
CompanyName,
|
||||
} from "@enums";
|
||||
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
|
||||
@ -277,18 +282,11 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
* Start work for one of the player's companies
|
||||
* Returns boolean indicating success
|
||||
*/
|
||||
workForCompany(companyName: string): boolean {
|
||||
if (!Companies[companyName] || Player.jobs[companyName] == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const company: Company | null = Companies[companyName];
|
||||
const companyPosition: CompanyPosition | null = CompanyPositions[Player.jobs[companyName]];
|
||||
if (company == null) return false;
|
||||
if (companyPosition == null) return false;
|
||||
workForCompany(companyName: CompanyName): boolean {
|
||||
const companyPositionName = Player.jobs[companyName];
|
||||
if (!companyPositionName) return false;
|
||||
|
||||
this.startWork(new SleeveCompanyWork(companyName));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Player } from "@player";
|
||||
import { LocationName } from "@enums";
|
||||
import { CompanyName, JobName } from "@enums";
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../../../utils/JSONReviver";
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { applySleeveGains, SleeveWorkClass, SleeveWorkType } from "./Work";
|
||||
@ -9,29 +9,29 @@ import { calculateCompanyWorkStats } from "../../../Work/Formulas";
|
||||
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { influenceStockThroughCompanyWork } from "../../../StockMarket/PlayerInfluencing";
|
||||
import { CompanyPositions } from "../../../Company/CompanyPositions";
|
||||
import { isMember } from "../../../utils/EnumHelper";
|
||||
import { invalidWork } from "../../../Work/InvalidWork";
|
||||
|
||||
export const isSleeveCompanyWork = (w: SleeveWorkClass | null): w is SleeveCompanyWork =>
|
||||
w !== null && w.type === SleeveWorkType.COMPANY;
|
||||
|
||||
export class SleeveCompanyWork extends SleeveWorkClass {
|
||||
type: SleeveWorkType.COMPANY = SleeveWorkType.COMPANY;
|
||||
companyName: string;
|
||||
companyName: CompanyName;
|
||||
|
||||
constructor(companyName?: string) {
|
||||
constructor(companyName = CompanyName.NoodleBar) {
|
||||
super();
|
||||
this.companyName = companyName ?? LocationName.NewTokyoNoodleBar;
|
||||
this.companyName = companyName;
|
||||
}
|
||||
|
||||
getCompany(): Company {
|
||||
const c = Companies[this.companyName];
|
||||
if (!c) throw new Error(`Company not found: '${this.companyName}'`);
|
||||
return c;
|
||||
return Companies[this.companyName];
|
||||
}
|
||||
|
||||
getGainRates(sleeve: Sleeve): WorkStats {
|
||||
getGainRates(sleeve: Sleeve, job: JobName): WorkStats {
|
||||
const company = this.getCompany();
|
||||
return scaleWorkStats(
|
||||
calculateCompanyWorkStats(sleeve, company, CompanyPositions[Player.jobs[company.name]], company.favor),
|
||||
calculateCompanyWorkStats(sleeve, company, CompanyPositions[job], company.favor),
|
||||
sleeve.shockBonus(),
|
||||
false,
|
||||
);
|
||||
@ -39,7 +39,9 @@ export class SleeveCompanyWork extends SleeveWorkClass {
|
||||
|
||||
process(sleeve: Sleeve, cycles: number) {
|
||||
const company = this.getCompany();
|
||||
const gains = this.getGainRates(sleeve);
|
||||
const job = Player.jobs[this.companyName];
|
||||
if (!job) return sleeve.stopWork();
|
||||
const gains = this.getGainRates(sleeve, job);
|
||||
applySleeveGains(sleeve, gains, cycles);
|
||||
company.playerReputation += gains.reputation * cycles;
|
||||
influenceStockThroughCompanyWork(company, gains.reputation, cycles);
|
||||
@ -59,7 +61,9 @@ export class SleeveCompanyWork extends SleeveWorkClass {
|
||||
|
||||
/** Initializes a CompanyWork object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): SleeveCompanyWork {
|
||||
return Generic_fromJSON(SleeveCompanyWork, value.data);
|
||||
const work = Generic_fromJSON(SleeveCompanyWork, value.data);
|
||||
if (!isMember("CompanyName", work.companyName)) return invalidWork();
|
||||
return work;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import { TaskSelector } from "./TaskSelector";
|
||||
import { TravelModal } from "./TravelModal";
|
||||
import { findCrime } from "../../../Crime/CrimeHelpers";
|
||||
import { SleeveWorkType } from "../Work/Work";
|
||||
import { getEnumHelper } from "../../../utils/EnumHelper";
|
||||
|
||||
function getWorkDescription(sleeve: Sleeve, progress: number): string {
|
||||
const work = sleeve.currentWork;
|
||||
@ -75,7 +76,8 @@ export function SleeveElem(props: SleeveElemProps): React.ReactElement {
|
||||
case "------":
|
||||
break;
|
||||
case "Work for Company":
|
||||
props.sleeve.workForCompany(abc[1]);
|
||||
if (getEnumHelper("CompanyName").isMember(abc[1])) props.sleeve.workForCompany(abc[1]);
|
||||
else console.error(`Invalid company name in setSleeveTask: ${abc[1]}`);
|
||||
break;
|
||||
case "Work for Faction":
|
||||
props.sleeve.workForFaction(abc[1], abc[2]);
|
||||
|
@ -2,6 +2,8 @@ import React from "react";
|
||||
|
||||
import { Typography, Table, TableBody, TableCell, TableRow } from "@mui/material";
|
||||
|
||||
import { Player } from "@player";
|
||||
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
|
||||
import {
|
||||
@ -141,8 +143,10 @@ export function EarningsElement(props: IProps): React.ReactElement {
|
||||
];
|
||||
}
|
||||
|
||||
if (isSleeveCompanyWork(props.sleeve.currentWork)) {
|
||||
const rates = props.sleeve.currentWork.getGainRates(props.sleeve);
|
||||
companyWork: if (isSleeveCompanyWork(props.sleeve.currentWork)) {
|
||||
const job = Player.jobs[props.sleeve.currentWork.companyName];
|
||||
if (!job) break companyWork;
|
||||
const rates = props.sleeve.currentWork.getGainRates(props.sleeve, job);
|
||||
data = [
|
||||
[`Money:`, <MoneyRate key="money-rate" money={CYCLES_PER_SEC * rates.money} />],
|
||||
[`Hacking Exp:`, `${formatExp(CYCLES_PER_SEC * rates.hackExp)} / sec`],
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { AugmentationName, CityName, CompletedProgramName, FactionName, LiteratureName } from "@enums";
|
||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { Companies, initCompanies } from "./Company/Companies";
|
||||
import { Companies } from "./Company/Companies";
|
||||
import { resetIndustryResearchTrees } from "./Corporation/data/IndustryData";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { joinFaction } from "./Faction/FactionHelpers";
|
||||
@ -71,7 +71,7 @@ export function prestigeAugmentation(): void {
|
||||
initForeignServers(Player.getHomeComputer());
|
||||
|
||||
// Gain favor for Companies and Factions
|
||||
for (const company of Object.values(Companies)) company.gainFavor();
|
||||
for (const company of Object.values(Companies)) company.prestigeAugmentation();
|
||||
for (const faction of Object.values(Factions)) faction.prestigeAugmentation();
|
||||
|
||||
// Stop a Terminal action if there is one.
|
||||
@ -89,7 +89,6 @@ export function prestigeAugmentation(): void {
|
||||
Player.reapplyAllAugmentations();
|
||||
Player.reapplyAllSourceFiles();
|
||||
Player.hp.current = Player.hp.max;
|
||||
initCompanies();
|
||||
|
||||
// Apply entropy from grafting
|
||||
Player.applyEntropy(Player.entropy);
|
||||
@ -194,7 +193,7 @@ export function prestigeSourceFile(isFlume: boolean): void {
|
||||
homeComp.cpuCores = 1;
|
||||
|
||||
// Reset favor for Companies and Factions
|
||||
for (const company of Object.values(Companies)) company.favor = 0;
|
||||
for (const company of Object.values(Companies)) company.prestigeSourceFile();
|
||||
for (const faction of Object.values(Factions)) faction.prestigeSourceFile();
|
||||
|
||||
// Stop a Terminal action if there is one
|
||||
@ -214,7 +213,6 @@ export function prestigeSourceFile(isFlume: boolean): void {
|
||||
|
||||
Player.reapplyAllAugmentations();
|
||||
Player.reapplyAllSourceFiles();
|
||||
initCompanies();
|
||||
|
||||
if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) {
|
||||
homeComp.programs.push(CompletedProgramName.formulas);
|
||||
|
@ -270,28 +270,6 @@ function evaluateVersionCompatibility(ver: string | number): void {
|
||||
anyPlayer.companyPosition = "";
|
||||
}
|
||||
}
|
||||
|
||||
// The "companyName" property of all Companies is renamed to "name"
|
||||
interface Company0_41_2 {
|
||||
name: string | number;
|
||||
companyName: string;
|
||||
companyPositions: Record<number, boolean>;
|
||||
}
|
||||
for (const companyName of Object.keys(Companies)) {
|
||||
const company = Companies[companyName] as unknown as Company0_41_2;
|
||||
if (company.name == 0 && company.companyName != null) {
|
||||
company.name = company.companyName;
|
||||
}
|
||||
|
||||
if (company.companyPositions instanceof Array) {
|
||||
const pos: Record<number, boolean> = {};
|
||||
|
||||
for (let i = 0; i < company.companyPositions.length; ++i) {
|
||||
pos[company.companyPositions[i]] = true;
|
||||
}
|
||||
company.companyPositions = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This version allowed players to hold multiple jobs
|
||||
|
10
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
10
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -6728,12 +6728,10 @@ declare enum JobName {
|
||||
business3 = "Operations Manager",
|
||||
business4 = "Chief Financial Officer",
|
||||
business5 = "Chief Executive Officer",
|
||||
security0 = "Police Officer",
|
||||
security1 = "Police Chief",
|
||||
security2 = "Security Guard",
|
||||
security3 = "Security Officer",
|
||||
security4 = "Security Supervisor",
|
||||
security5 = "Head of Security",
|
||||
security0 = "Security Guard",
|
||||
security1 = "Security Officer",
|
||||
security2 = "Security Supervisor",
|
||||
security3 = "Head of Security",
|
||||
agent0 = "Field Agent",
|
||||
agent1 = "Secret Agent",
|
||||
agent2 = "Special Operative",
|
||||
|
@ -74,9 +74,7 @@ export function influenceStockThroughCompanyWork(
|
||||
): void {
|
||||
const compName = company.name;
|
||||
let stock: Stock | null = null;
|
||||
if (typeof compName === "string" && compName !== "") {
|
||||
stock = StockMarket[compName];
|
||||
}
|
||||
stock = StockMarket[compName];
|
||||
if (!(stock instanceof Stock)) {
|
||||
return;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { constructorsForReviver, Generic_toJSON, Generic_fromJSON, IReviverValue
|
||||
import { Player } from "@player";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { influenceStockThroughCompanyWork } from "../StockMarket/PlayerInfluencing";
|
||||
import { AugmentationName, LocationName } from "@enums";
|
||||
import { AugmentationName, CompanyName, JobName } from "@enums";
|
||||
import { calculateCompanyWorkStats } from "./Formulas";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { applyWorkStats, scaleWorkStats, WorkStats } from "./WorkStats";
|
||||
@ -12,43 +12,42 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reputation } from "../ui/React/Reputation";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { CompanyPositions } from "../Company/CompanyPositions";
|
||||
import { isMember } from "../utils/EnumHelper";
|
||||
import { invalidWork } from "./InvalidWork";
|
||||
|
||||
interface CompanyWorkParams {
|
||||
companyName: string;
|
||||
companyName: CompanyName;
|
||||
singularity: boolean;
|
||||
}
|
||||
|
||||
export const isCompanyWork = (w: Work | null): w is CompanyWork => w !== null && w.type === WorkType.COMPANY;
|
||||
|
||||
export class CompanyWork extends Work {
|
||||
companyName: string;
|
||||
companyName: CompanyName;
|
||||
constructor(params?: CompanyWorkParams) {
|
||||
super(WorkType.COMPANY, params?.singularity ?? false);
|
||||
this.companyName = params?.companyName ?? LocationName.NewTokyoNoodleBar;
|
||||
this.companyName = params?.companyName ?? CompanyName.NoodleBar;
|
||||
}
|
||||
|
||||
getCompany(): Company {
|
||||
const c = Companies[this.companyName];
|
||||
if (!c) throw new Error(`Company not found: '${this.companyName}'`);
|
||||
return c;
|
||||
return Companies[this.companyName];
|
||||
}
|
||||
|
||||
getGainRates(): WorkStats {
|
||||
getGainRates(job: JobName): WorkStats {
|
||||
let focusBonus = 1;
|
||||
if (!Player.hasAugmentation(AugmentationName.NeuroreceptorManager, true)) {
|
||||
focusBonus = Player.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
const company = this.getCompany();
|
||||
return scaleWorkStats(
|
||||
calculateCompanyWorkStats(Player, company, CompanyPositions[Player.jobs[company.name]], company.favor),
|
||||
focusBonus,
|
||||
);
|
||||
return scaleWorkStats(calculateCompanyWorkStats(Player, company, CompanyPositions[job], company.favor), focusBonus);
|
||||
}
|
||||
|
||||
process(cycles: number): boolean {
|
||||
this.cyclesWorked += cycles;
|
||||
const company = this.getCompany();
|
||||
const gains = this.getGainRates();
|
||||
const job = Player.jobs[this.companyName];
|
||||
if (!job) return true;
|
||||
const gains = this.getGainRates(job);
|
||||
applyWorkStats(Player, gains, cycles, "work");
|
||||
company.playerReputation += gains.reputation * cycles;
|
||||
influenceStockThroughCompanyWork(company, gains.reputation, cycles);
|
||||
@ -81,7 +80,9 @@ export class CompanyWork extends Work {
|
||||
|
||||
/** Initializes a CompanyWork object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): CompanyWork {
|
||||
return Generic_fromJSON(CompanyWork, value.data);
|
||||
const work = Generic_fromJSON(CompanyWork, value.data);
|
||||
if (!isMember("CompanyName", work.companyName)) return invalidWork();
|
||||
return work;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,12 +47,10 @@ export enum JobName {
|
||||
business3 = "Operations Manager",
|
||||
business4 = "Chief Financial Officer",
|
||||
business5 = "Chief Executive Officer",
|
||||
security0 = "Police Officer",
|
||||
security1 = "Police Chief",
|
||||
security2 = "Security Guard",
|
||||
security3 = "Security Officer",
|
||||
security4 = "Security Supervisor",
|
||||
security5 = "Head of Security",
|
||||
security0 = "Security Guard",
|
||||
security1 = "Security Officer",
|
||||
security2 = "Security Supervisor",
|
||||
security3 = "Head of Security",
|
||||
agent0 = "Field Agent",
|
||||
agent1 = "Secret Agent",
|
||||
agent2 = "Special Operative",
|
||||
|
13
src/Work/InvalidWork.ts
Normal file
13
src/Work/InvalidWork.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// This file is just for providing the ability to not load an invalid work.
|
||||
import type { PlayerObject } from "../PersonObjects/Player/PlayerObject";
|
||||
import type { Sleeve } from "../PersonObjects/Sleeve/Sleeve";
|
||||
import type { SleeveWork } from "../PersonObjects/Sleeve/Work/Work";
|
||||
import type { Work } from "./Work";
|
||||
|
||||
// Type verifications to validate that Player.currentWork and sleeve.currentWork are allowed to be null.
|
||||
const __canPlayerWorkBeNull: null extends PlayerObject["currentWork"] ? true : false = true;
|
||||
const __canSleeveWorkBeNull: null extends Sleeve["currentWork"] ? true : false = true;
|
||||
|
||||
export function invalidWork<W extends Work | SleeveWork>(): W {
|
||||
return null as unknown as W;
|
||||
}
|
@ -3,7 +3,6 @@ import { AugmentationName, ToastVariant } from "@enums";
|
||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { initSourceFiles } from "./SourceFile/SourceFiles";
|
||||
import { generateRandomContract } from "./CodingContractGenerator";
|
||||
import { initCompanies } from "./Company/Companies";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { staneksGift } from "./CotMG/Helper";
|
||||
@ -374,7 +373,6 @@ const Engine: {
|
||||
Engine.start(); // Run main game loop and Scripts loop
|
||||
Player.init();
|
||||
initForeignServers(Player.getHomeComputer());
|
||||
initCompanies();
|
||||
Player.reapplyAllAugmentations();
|
||||
|
||||
// Start interactive tutorial
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Root React Component for the Corporation UI
|
||||
import React, { useMemo, useState, useEffect } from "react";
|
||||
import React, { useMemo, useState, useEffect, ReactNode } from "react";
|
||||
|
||||
import { Theme, useTheme } from "@mui/material/styles";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
@ -337,9 +337,9 @@ function Work(): React.ReactElement {
|
||||
|
||||
if (Player.currentWork === null || Player.focus) return <></>;
|
||||
|
||||
let details = <></>;
|
||||
let header = <></>;
|
||||
let innerText = <></>;
|
||||
let details: ReactNode = "";
|
||||
let header: ReactNode = "";
|
||||
let innerText: ReactNode = "";
|
||||
if (isCrimeWork(Player.currentWork)) {
|
||||
const crime = Player.currentWork.getCrime();
|
||||
const perc = (Player.currentWork.unitCompleted / crime.time) * 100;
|
||||
@ -391,11 +391,14 @@ function Work(): React.ReactElement {
|
||||
}
|
||||
if (isCompanyWork(Player.currentWork)) {
|
||||
const companyWork = Player.currentWork;
|
||||
const job = Player.jobs[companyWork.companyName];
|
||||
if (!job) return <></>;
|
||||
details = (
|
||||
<>
|
||||
{Player.jobs[companyWork.companyName]} at <strong>{companyWork.companyName}</strong>
|
||||
{job} at <strong>{companyWork.companyName}</strong>
|
||||
</>
|
||||
);
|
||||
|
||||
header = (
|
||||
<>
|
||||
Working at <strong>{companyWork.companyName}</strong>
|
||||
@ -405,7 +408,7 @@ function Work(): React.ReactElement {
|
||||
<>
|
||||
<Reputation reputation={companyWork.getCompany().playerReputation} /> rep
|
||||
<br />(
|
||||
<ReputationRate reputation={companyWork.getGainRates().reputation * (1000 / CONSTANTS.MilliPerCycle)} />)
|
||||
<ReputationRate reputation={companyWork.getGainRates(job).reputation * (1000 / CONSTANTS.MilliPerCycle)} />)
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
/**
|
||||
* Creates a dropdown (select HTML element) with company names as options
|
||||
*/
|
||||
import type { CompanyName } from "../../Enums";
|
||||
|
||||
import React from "react";
|
||||
import { companiesMetadata } from "../../Company/data/CompaniesMetadata";
|
||||
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Button from "@mui/material/Button";
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { getRecordKeys } from "../../Types/Record";
|
||||
|
||||
interface IProps {
|
||||
purchase: () => void;
|
||||
canPurchase: boolean;
|
||||
onChange: (event: SelectChangeEvent) => void;
|
||||
value: string;
|
||||
onChange: (event: SelectChangeEvent<CompanyName>) => void;
|
||||
value: CompanyName;
|
||||
}
|
||||
|
||||
const sortedCompanies = companiesMetadata.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const sortedCompanies = getRecordKeys(Companies).sort((a, b) => a.localeCompare(b));
|
||||
|
||||
export function CompanyDropdown(props: IProps): React.ReactElement {
|
||||
const companies = [];
|
||||
for (const company of sortedCompanies) {
|
||||
companies.push(
|
||||
<MenuItem key={company.name} value={company.name}>
|
||||
{company.name}
|
||||
<MenuItem key={company} value={company}>
|
||||
{company}
|
||||
</MenuItem>,
|
||||
);
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
cancel: () => Router.toPage(Page.Terminal),
|
||||
},
|
||||
title:
|
||||
`You cannot work for ${Player.currentWork.companyName || "(Company not found)"} at this time,` +
|
||||
`You cannot work for ${Player.currentWork.companyName} at this time,` +
|
||||
" please try again if you think this should have worked",
|
||||
|
||||
stopText: "Back to Terminal",
|
||||
@ -421,7 +421,8 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
const companyRep = comp.playerReputation;
|
||||
|
||||
const position = Player.jobs[Player.currentWork.companyName];
|
||||
const gains = Player.currentWork.getGainRates();
|
||||
if (!position) return <></>;
|
||||
const gains = Player.currentWork.getGainRates(position);
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: () => {
|
||||
|
@ -3,16 +3,17 @@ import { Factions } from "../../src/Faction/Factions";
|
||||
import { Player, setPlayer } from "../../src/Player";
|
||||
import { PlayerObject } from "../../src/PersonObjects/Player/PlayerObject";
|
||||
import { joinFaction } from "../../src/Faction/FactionHelpers";
|
||||
import { AugmentationName, CrimeType, FactionName } from "../../src/Enums";
|
||||
import { AugmentationName, CompanyName, CrimeType, FactionName } from "../../src/Enums";
|
||||
import { Augmentations } from "../../src/Augmentation/Augmentations";
|
||||
import { SleeveCrimeWork } from "../../src/PersonObjects/Sleeve/Work/SleeveCrimeWork";
|
||||
import { Companies } from "../../src/Company/Companies";
|
||||
|
||||
describe("Check Save File Continuity", () => {
|
||||
establishInitialConditions();
|
||||
// Calling getSaveString forces save info to update
|
||||
saveObject.getSaveString();
|
||||
|
||||
const savesToTest = ["FactionsSave", "PlayerSave"] as const;
|
||||
const savesToTest = ["FactionsSave", "PlayerSave", "CompaniesSave"] as const;
|
||||
for (const saveToTest of savesToTest) {
|
||||
test(`${saveToTest} continuity`, () => {
|
||||
const parsed = JSON.parse(saveObject[saveToTest]);
|
||||
@ -44,9 +45,6 @@ function establishInitialConditions() {
|
||||
initForeignServers(Player.getHomeComputer());
|
||||
*/
|
||||
|
||||
// not comparing companies yet
|
||||
// initCompanies()
|
||||
|
||||
// Sleeves (already added in game initializers section)
|
||||
Player.sleeves[0].installAugmentation(Augmentations[AugmentationName.BionicArms]);
|
||||
Player.sleeves[0].startWork(new SleeveCrimeWork(CrimeType.homicide));
|
||||
@ -61,6 +59,11 @@ function establishInitialConditions() {
|
||||
csec.playerReputation = 1e6;
|
||||
csec.favor = 20;
|
||||
|
||||
// Companies
|
||||
const noodleBar = Companies[CompanyName.NoodleBar];
|
||||
noodleBar.favor = 100;
|
||||
noodleBar.playerReputation = 100000;
|
||||
|
||||
// Bladeburner. Adding rank will also add bladeburner faction rep.
|
||||
Player.startBladeburner();
|
||||
Player.bladeburner?.changeRank(Player, 2000);
|
||||
|
@ -31,7 +31,7 @@ import {
|
||||
getSellTransactionGain,
|
||||
processTransactionForecastMovement,
|
||||
} from "../../src/StockMarket/StockMarketHelpers";
|
||||
import { OrderType, PositionType } from "../../src/Enums";
|
||||
import { CompanyName, OrderType, PositionType } from "../../src/Enums";
|
||||
|
||||
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
virtual: true,
|
||||
@ -1255,9 +1255,9 @@ describe("Stock Market Tests", function () {
|
||||
});
|
||||
|
||||
const company = new Company({
|
||||
name: "MockStock",
|
||||
name: "MockStock" as CompanyName,
|
||||
info: "",
|
||||
companyPositions: {},
|
||||
companyPositions: [],
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 1,
|
||||
|
@ -1,5 +1,276 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Check Save File Continuity CompaniesSave continuity 1`] = `
|
||||
{
|
||||
"AeroCorp": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Aevum Police Headquarters": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Alpha Enterprises": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Bachman & Associates": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Blade Industries": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Carmichael Security": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Central Intelligence Agency": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Clarke Incorporated": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"CompuTek": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"DefComm": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"DeltaOne": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"ECorp": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"FoodNStuff": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Four Sigma": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Fulcrum Technologies": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Galactic Cybersystems": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Global Pharmaceuticals": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Helios Labs": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Icarus Microsystems": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Joe's Guns": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"KuaiGong International": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"LexoCorp": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"MegaCorp": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"NWO": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"National Security Agency": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"NetLink Technologies": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Noodle Bar": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 100,
|
||||
"playerReputation": 100000,
|
||||
},
|
||||
},
|
||||
"Nova Medical": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Omega Software": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"OmniTek Incorporated": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Omnia Cybersystems": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Rho Construction": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Solaris Space Systems": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Storm Technologies": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"SysCore Securities": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Universal Energy": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"VitaLife": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
"Watchdog Security": {
|
||||
"ctor": "Company",
|
||||
"data": {
|
||||
"favor": 0,
|
||||
"playerReputation": 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Check Save File Continuity FactionsSave continuity 1`] = `
|
||||
{
|
||||
"Aevum": {
|
||||
|
Loading…
Reference in New Issue
Block a user