diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index 8fa56851f..a0995cb7c 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -155,6 +155,7 @@ const singularity = { purchaseTor: SF4Cost(RamCostConstants.SingularityFn1), purchaseProgram: SF4Cost(RamCostConstants.SingularityFn1), getCurrentServer: SF4Cost(RamCostConstants.SingularityFn1), + getCompanyPositionInfo: SF4Cost(RamCostConstants.SingularityFn1), getCompanyPositions: SF4Cost(RamCostConstants.SingularityFn1), connect: SF4Cost(RamCostConstants.SingularityFn1), manualHack: SF4Cost(RamCostConstants.SingularityFn1), diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 1e5fc8616..2d7425c07 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -15,7 +15,7 @@ import { Singularity as ISingularity } from "@nsdefs"; import { findCrime } from "../Crime/CrimeHelpers"; import { CompanyPositions } from "../Company/CompanyPositions"; import { DarkWebItems } from "../DarkWeb/DarkWebItems"; -import { CityName, LocationName } from "../Enums"; +import { CityName, LocationName, JobName } from "../Enums"; import { Router } from "../ui/GameRoot"; import { SpecialServers } from "../Server/data/SpecialServers"; import { Page } from "../ui/Router"; @@ -26,6 +26,7 @@ import { formatMoney, formatRam, formatReputation } from "../ui/formatNumber"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { Company } from "../Company/Company"; import { Companies } from "../Company/Companies"; +import { companiesMetadata } from "../Company/data/CompaniesMetadata"; import { Factions, factionExists } from "../Faction/Factions"; import { Faction } from "../Faction/Faction"; import { helpers } from "../Netscript/NetscriptHelpers"; @@ -51,6 +52,7 @@ import { calculateCrimeWorkStats } from "../Work/Formulas"; import { findEnumMember } from "../utils/helpers/enum"; import { areFilesEqual } from "../Terminal/DirectoryHelpers"; import { Engine } from "../engine"; +import { checkEnum } from "../utils/helpers/enum"; export function NetscriptSingularity(): InternalAPI { const getAugmentation = function (ctx: NetscriptContext, name: string): Augmentation { @@ -687,6 +689,44 @@ export function NetscriptSingularity(): InternalAPI { .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 positionName = helpers.string(ctx, "positionName", _positionName); + + // Make sure its a valid company + if (!(companyName in Companies)) { + throw helpers.makeRuntimeErrorMsg(ctx, `Invalid company: '${companyName}'`); + } + + // Make sure its a valid position + if (!checkEnum(JobName, positionName)) { + throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position: '${positionName}'`); + } + + if (!Companies[companyName].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 res = { + name: CompanyPositions[positionName].name, + nextPosition: CompanyPositions[positionName].nextPosition, + salary: CompanyPositions[positionName].baseSalary * n.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, + intelligence: 0, + }, + }; + return res; + }, workForCompany: (ctx) => (_companyName, _focus = true) => { diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 7c6495d6b..58c77ced0 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -1698,6 +1698,28 @@ export interface Singularity { */ getUpgradeHomeCoresCost(): number; + /** + * Get Requirements for Company Position. + * @remarks + * RAM cost: 2 GB * 16/4/1 + * + * + * This function will return an object that contains the requirements for + * a specific position at a specific country. + * + * @example + * ```js + * const companyName = "ECorp"; + * const position = "Chief Executive Officer"; + * + * let requirements = ns.singularity.getCompanyPositionInfo(companyName, position); + * ``` + * @param companyName - Name of company to get the requirements for. Must be an exact match. + * @param positionName - Name of position to get the requirements for. Must be an exact match. + * @returns CompanyPositionInfo object. + */ + getCompanyPositionInfo(companyName: string, positionName: JobName): CompanyPositionInfo; + /** * Get List of Company Positions. * @remarks @@ -2361,6 +2383,19 @@ export interface Singularity { getCurrentWork(): any | null; } +/** + * Company position requirements and salary. + * @public + * @returns - An object representing the requirements and salary for a company/position combination. + */ +export interface CompanyPositionInfo { + name: CompanyPosName; + nextPosition: CompanyPosName | null; + salary: number; + requiredReputation: number; + requiredSkills: Skills; +} + /** * Hacknet API * @remarks