diff --git a/src/Bladeburner/Action.tsx b/src/Bladeburner/Action.tsx index f128f444c..d2f273f82 100644 --- a/src/Bladeburner/Action.tsx +++ b/src/Bladeburner/Action.tsx @@ -1,10 +1,10 @@ -import { Player } from "@player"; import { getRandomInt } from "../utils/helpers/getRandomInt"; import { addOffset } from "../utils/helpers/addOffset"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; import { BladeburnerConstants } from "./data/Constants"; import { Bladeburner } from "./Bladeburner"; import { Person } from "../PersonObjects/Person"; +import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence"; interface ISuccessChanceParams { est: boolean; @@ -254,7 +254,7 @@ export class Action { competence += this.weights[stat] * Math.pow(effMultiplier * playerStatLvl, this.decays[stat]); } } - competence *= Player.getIntelligenceBonus(0.75); + competence *= calculateIntelligenceBonus(person.skills.intelligence, 0.75); competence *= inst.calculateStaminaPenalty(); competence *= this.getTeamSuccessBonus(inst); @@ -277,7 +277,7 @@ export class Action { } // Augmentation multiplier - competence *= Player.mults.bladeburner_success_chance; + competence *= person.mults.bladeburner_success_chance; if (isNaN(competence)) { throw new Error("Competence calculated as NaN in Action.getSuccessChance()"); diff --git a/src/Company/CompanyPosition.ts b/src/Company/CompanyPosition.ts index b4905f950..ecb3ac039 100644 --- a/src/Company/CompanyPosition.ts +++ b/src/Company/CompanyPosition.ts @@ -1,4 +1,4 @@ -import { Person } from "../PersonObjects/Person"; +import { Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { CONSTANTS } from "../Constants"; import * as names from "./data/companypositionnames"; @@ -118,7 +118,7 @@ export class CompanyPosition { this.charismaExpGain = p.charismaExpGain != null ? p.charismaExpGain : 0; } - calculateJobPerformance(worker: Person): number { + calculateJobPerformance(worker: IPerson): number { const hackRatio: number = (this.hackingEffectiveness * worker.skills.hacking) / CONSTANTS.MaxSkillLevel; const strRatio: number = (this.strengthEffectiveness * worker.skills.strength) / CONSTANTS.MaxSkillLevel; const defRatio: number = (this.defenseEffectiveness * worker.skills.defense) / CONSTANTS.MaxSkillLevel; diff --git a/src/Corporation/ui/modals/CreateCorporationModal.tsx b/src/Corporation/ui/modals/CreateCorporationModal.tsx index 9a2cd26ec..14082a716 100644 --- a/src/Corporation/ui/modals/CreateCorporationModal.tsx +++ b/src/Corporation/ui/modals/CreateCorporationModal.tsx @@ -15,7 +15,7 @@ interface IProps { export function CreateCorporationModal(props: IProps): React.ReactElement { const canSelfFund = Player.canAfford(150e9); - if (!Player.canAccessCorporation() || Player.hasCorporation()) { + if (!Player.canAccessCorporation() || Player.corporation) { props.onClose(); return <>; } @@ -26,13 +26,8 @@ export function CreateCorporationModal(props: IProps): React.ReactElement { } function selfFund(): void { - if (!canSelfFund) { - return; - } - - if (name == "") { - return; - } + if (!canSelfFund) return; + if (name == "") return; Player.startCorporation(name); Player.loseMoney(150e9, "corporation"); diff --git a/src/Crime/Crime.ts b/src/Crime/Crime.ts index ceee8d4f6..c1387252b 100644 --- a/src/Crime/Crime.ts +++ b/src/Crime/Crime.ts @@ -1,9 +1,10 @@ import { CONSTANTS } from "../Constants"; import { Player } from "@player"; -import { Person } from "../PersonObjects/Person"; +import { Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { WorkerScript } from "../Netscript/WorkerScript"; import { CrimeType } from "../utils/WorkType"; import { CrimeWork } from "../Work/CrimeWork"; +import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence"; interface IConstructorParams { hacking_success_weight?: number; @@ -120,7 +121,7 @@ export class Crime { return this.time; } - successRate(p: Person): number { + successRate(p: IPerson): number { let chance: number = this.hacking_success_weight * p.skills.hacking + this.strength_success_weight * p.skills.strength + @@ -132,7 +133,7 @@ export class Crime { chance /= CONSTANTS.MaxSkillLevel; chance /= this.difficulty; chance *= p.mults.crime_success; - chance *= p.getIntelligenceBonus(1); + chance *= calculateIntelligenceBonus(p.skills.intelligence, 1); return Math.min(chance, 1); } diff --git a/src/Faction/formulas/donation.ts b/src/Faction/formulas/donation.ts index 0cc4c2067..936d76d51 100644 --- a/src/Faction/formulas/donation.ts +++ b/src/Faction/formulas/donation.ts @@ -1,7 +1,7 @@ import { CONSTANTS } from "../../Constants"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; -import { Person } from "../../PersonObjects/Person"; +import { Person as IPerson } from "../../ScriptEditor/NetscriptDefinitions"; -export function repFromDonation(amt: number, person: Person): number { +export function repFromDonation(amt: number, person: IPerson): number { return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain; } diff --git a/src/Hacking.ts b/src/Hacking.ts index 78308ecd9..a1026d679 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -1,10 +1,10 @@ import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; -import { Person } from "./PersonObjects/Person"; +import { Person as IPerson } from "./ScriptEditor/NetscriptDefinitions"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; import { Server } from "./Server/Server"; /** Returns the chance the person has to successfully hack a server */ -export function calculateHackingChance(server: Server, person: Person): number { +export function calculateHackingChance(server: Server, person: IPerson): number { const hackFactor = 1.75; const difficultyMult = (100 - server.hackDifficulty) / 100; const skillMult = hackFactor * person.skills.hacking; @@ -28,7 +28,7 @@ export function calculateHackingChance(server: Server, person: Person): number { * Returns the amount of hacking experience the person will gain upon * successfully hacking a server */ -export function calculateHackingExpGain(server: Server, person: Person): number { +export function calculateHackingExpGain(server: Server, person: IPerson): number { const baseExpGain = 3; const diffFactor = 0.3; if (server.baseDifficulty == null) { @@ -44,7 +44,7 @@ export function calculateHackingExpGain(server: Server, person: Person): number * Returns the percentage of money that will be stolen from a server if * it is successfully hacked (returns the decimal form, not the actual percent value) */ -export function calculatePercentMoneyHacked(server: Server, person: Person): number { +export function calculatePercentMoneyHacked(server: Server, person: IPerson): number { // Adjust if needed for balancing. This is the divisor for the final calculation const balanceFactor = 240; @@ -63,7 +63,7 @@ export function calculatePercentMoneyHacked(server: Server, person: Person): num } /** Returns time it takes to complete a hack on a server, in seconds */ -export function calculateHackingTime(server: Server, person: Person): number { +export function calculateHackingTime(server: Server, person: IPerson): number { const difficultyMult = server.requiredHackingSkill * server.hackDifficulty; const baseDiff = 500; @@ -82,14 +82,14 @@ export function calculateHackingTime(server: Server, person: Person): number { } /** Returns time it takes to complete a grow operation on a server, in seconds */ -export function calculateGrowTime(server: Server, person: Person): number { +export function calculateGrowTime(server: Server, person: IPerson): number { const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2 return growTimeMultiplier * calculateHackingTime(server, person); } /** Returns time it takes to complete a weaken operation on a server, in seconds */ -export function calculateWeakenTime(server: Server, person: Person): number { +export function calculateWeakenTime(server: Server, person: IPerson): number { const weakenTimeMultiplier = 4; // Relative to hacking time return weakenTimeMultiplier * calculateHackingTime(server, person); diff --git a/src/Locations/ui/SpecialLocation.tsx b/src/Locations/ui/SpecialLocation.tsx index 565242a47..88fac804b 100644 --- a/src/Locations/ui/SpecialLocation.tsx +++ b/src/Locations/ui/SpecialLocation.tsx @@ -43,11 +43,10 @@ type IProps = { export function SpecialLocation(props: IProps): React.ReactElement { const setRerender = useState(false)[1]; - const inBladeburner = Player.inBladeburner(); /** Click handler for Bladeburner button at Sector-12 NSA */ function handleBladeburner(): void { - if (Player.inBladeburner()) { + if (Player.bladeburner) { // Enter Bladeburner division Router.toBladeburner(); } else if ( @@ -80,7 +79,7 @@ export function SpecialLocation(props: IProps): React.ReactElement { if (!Player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) { return <>; } - const text = inBladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division"; + const text = Player.bladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division"; return ( <>
@@ -143,7 +142,7 @@ export function SpecialLocation(props: IProps): React.ReactElement { } return ( <> - setOpen(false)} /> diff --git a/src/Netscript/NetscriptHelpers.ts b/src/Netscript/NetscriptHelpers.ts index 024c482bb..a9d657f14 100644 --- a/src/Netscript/NetscriptHelpers.ts +++ b/src/Netscript/NetscriptHelpers.ts @@ -21,7 +21,6 @@ import { CONSTANTS } from "../Constants"; import { influenceStockThroughServerHack } from "../StockMarket/PlayerInfluencing"; import { IPort, NetscriptPort } from "../NetscriptPort"; import { NetscriptPorts } from "../NetscriptWorker"; -import { Person } from "../PersonObjects/Person"; import { FormulaGang } from "../Gang/formulas/formulas"; import { GangMember } from "../Gang/GangMember"; import { GangMemberTask } from "../Gang/GangMemberTask"; @@ -29,7 +28,7 @@ import { RunningScript } from "../Script/RunningScript"; import { toNative } from "../NetscriptFunctions/toNative"; import { ScriptIdentifier } from "./ScriptIdentifier"; import { findRunningScript, findRunningScriptByPid } from "../Script/ScriptHelpers"; -import { RunningScript as IRunningScript } from "../ScriptEditor/NetscriptDefinitions"; +import { RunningScript as IRunningScript, Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { arrayToString } from "../utils/helpers/arrayToString"; import { HacknetServer } from "../Hacknet/HacknetServer"; import { BaseServer } from "../Server/BaseServer"; @@ -53,7 +52,7 @@ export const helpers = { scriptIdentifier, hack, getValidPort, - player, + person, server, gang, gangMember, @@ -546,27 +545,15 @@ function getValidPort(ctx: NetscriptContext, port: number): IPort { return iport; } -function player(ctx: NetscriptContext, p: unknown): Person { - const fakePlayer = { +function person(ctx: NetscriptContext, p: unknown): IPerson { + const fakePerson = { hp: undefined, + exp: undefined, mults: undefined, - numPeopleKilled: undefined, - money: undefined, city: undefined, - location: undefined, - bitNodeN: undefined, - totalPlaytime: undefined, - playtimeSinceLastAug: undefined, - playtimeSinceLastBitnode: undefined, - jobs: undefined, - factions: undefined, - tor: undefined, - inBladeburner: undefined, - hasCorporation: undefined, - entropy: undefined, }; - if (!roughlyIs(fakePlayer, p)) throw makeRuntimeErrorMsg(ctx, `player should be a Player.`, "TYPE"); - return p as Person; + if (!roughlyIs(fakePerson, p)) throw makeRuntimeErrorMsg(ctx, `person should be a Person.`, "TYPE"); + return p as IPerson; } function server(ctx: NetscriptContext, s: unknown): Server { diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index 01010b150..00030c0c7 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -231,6 +231,7 @@ const gang = { // Bladeburner API const bladeburner = { + inBladeburner: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 4, getContractNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10, getOperationNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10, getBlackOpNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10, @@ -295,9 +296,8 @@ const sleeve = { setToCompanyWork: RamCostConstants.ScriptSleeveBaseRamCost, setToFactionWork: RamCostConstants.ScriptSleeveBaseRamCost, setToGymWorkout: RamCostConstants.ScriptSleeveBaseRamCost, - getSleeveStats: RamCostConstants.ScriptSleeveBaseRamCost, getTask: RamCostConstants.ScriptSleeveBaseRamCost, - getInformation: RamCostConstants.ScriptSleeveBaseRamCost, + getSleeve: RamCostConstants.ScriptSleeveBaseRamCost, getSleeveAugmentations: RamCostConstants.ScriptSleeveBaseRamCost, getSleevePurchasableAugs: RamCostConstants.ScriptSleeveBaseRamCost, purchaseSleeveAug: RamCostConstants.ScriptSleeveBaseRamCost, @@ -343,6 +343,7 @@ const grafting = { } as const; const corporation = { + hasCorporation: 0, getMaterialNames: 0, getIndustryTypes: 0, getEmployeePositions: 0, @@ -453,6 +454,7 @@ export const RamCosts: RamCostTree> = { enableLog: 0, isLogEnabled: 0, getScriptLogs: 0, + hasTorRouter: 0.05, nuke: RamCostConstants.ScriptPortProgramRamCost, brutessh: RamCostConstants.ScriptPortProgramRamCost, ftpcrack: RamCostConstants.ScriptPortProgramRamCost, @@ -543,15 +545,13 @@ export const RamCosts: RamCostTree> = { bypass: 0, alterReality: 0, rainbow: 0, - heart: { - // Easter egg function - break: 0, - }, + heart: { break: 0 }, iKnowWhatImDoing: 0, formulas: { mockServer: 0, mockPlayer: 0, + mockPerson: 0, reputation: { calculateFavorToRep: 0, calculateRepToFavor: 0, @@ -597,6 +597,7 @@ export const RamCosts: RamCostTree> = { ascensionMultiplier: 0, }, work: { + crimeSuccessChance: 0, crimeGains: 0, classGains: 0, factionGains: 0, diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 67321d12c..1d4f82846 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -78,6 +78,7 @@ import { ScriptDeath } from "./Netscript/ScriptDeath"; import { getBitNodeMultipliers } from "./BitNode/BitNode"; import { assert, arrayAssert, stringAssert, objectAssert } from "./utils/helpers/typeAssertion"; import { CrimeType } from "./utils/WorkType"; +import { cloneDeep } from "lodash"; export const enums = { toast: ToastVariant, @@ -122,6 +123,7 @@ const base: InternalAPI = { helpers.log(ctx, () => `returned ${server.serversOnNetwork.length} connections for ${server.hostname}`); return out; }, + hasTorRouter: () => () => Player.hasTorRouter(), hack: (ctx) => (_hostname, opts = {}) => { @@ -1806,10 +1808,10 @@ const base: InternalAPI = { }, getPlayer: () => () => { const data = { - hp: JSON.parse(JSON.stringify(Player.hp)), - skills: JSON.parse(JSON.stringify(Player.skills)), - exp: JSON.parse(JSON.stringify(Player.exp)), - mults: JSON.parse(JSON.stringify(Player.mults)), + hp: cloneDeep(Player.hp), + skills: cloneDeep(Player.skills), + exp: cloneDeep(Player.exp), + mults: cloneDeep(Player.mults), numPeopleKilled: Player.numPeopleKilled, money: Player.money, city: Player.city, @@ -1818,14 +1820,10 @@ const base: InternalAPI = { totalPlaytime: Player.totalPlaytime, playtimeSinceLastAug: Player.playtimeSinceLastAug, playtimeSinceLastBitnode: Player.playtimeSinceLastBitnode, - jobs: {}, + jobs: cloneDeep(Player.jobs), factions: Player.factions.slice(), - tor: Player.hasTorRouter(), - inBladeburner: Player.inBladeburner(), - hasCorporation: Player.hasCorporation(), entropy: Player.entropy, }; - Object.assign(data.jobs, Player.jobs); return data; }, getMoneySources: () => () => ({ diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts index d57f9a1af..6d251d55d 100644 --- a/src/NetscriptFunctions/Bladeburner.ts +++ b/src/NetscriptFunctions/Bladeburner.ts @@ -47,6 +47,7 @@ export function NetscriptBladeburner(): InternalAPI { }; return { + inBladeburner: () => () => !!Player.bladeburner, getContractNames: (ctx) => () => { const bladeburner = getBladeburner(ctx); return bladeburner.getContractNamesNetscriptFn(); diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 3f689d10a..17c087874 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -1,4 +1,4 @@ -import { Player as player } from "../Player"; +import { Player, Player as player } from "../Player"; import { OfficeSpace } from "../Corporation/OfficeSpace"; import { Product } from "../Corporation/Product"; @@ -63,7 +63,7 @@ import { CityName } from "../Locations/data/CityNames"; export function NetscriptCorporation(): InternalAPI { function createCorporation(corporationName: string, selfFund = true): boolean { - if (!player.canAccessCorporation() || player.hasCorporation()) return false; + if (!player.canAccessCorporation() || player.corporation) return false; if (!corporationName) return false; if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3"); if (BitNodeMultipliers.CorporationSoftcap < 0.15) @@ -705,6 +705,7 @@ export function NetscriptCorporation(): InternalAPI { return { ...warehouseAPI, ...officeAPI, + hasCorporation: () => () => !!Player.corporation, // Todo: Just remove these functions and provide enums? getMaterialNames: (ctx) => () => { checkAccess(ctx); diff --git a/src/NetscriptFunctions/Formulas.ts b/src/NetscriptFunctions/Formulas.ts index f8062af81..539e52c5a 100644 --- a/src/NetscriptFunctions/Formulas.ts +++ b/src/NetscriptFunctions/Formulas.ts @@ -26,7 +26,7 @@ import { calculateWeakenTime, } from "../Hacking"; import { Programs } from "../Programs/Programs"; -import { Formulas as IFormulas } from "../ScriptEditor/NetscriptDefinitions"; +import { Formulas as IFormulas, Player as IPlayer, Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { calculateRespectGain, calculateWantedLevelGain, @@ -87,26 +87,10 @@ export function NetscriptFormulas(): InternalAPI { requiredHackingSkill: 0, serverGrowth: 0, }), - mockPlayer: () => () => ({ + mockPlayer: () => (): IPlayer => ({ hp: { current: 0, max: 0 }, - skills: { - hacking: 0, - strength: 0, - defense: 0, - dexterity: 0, - agility: 0, - charisma: 0, - intelligence: 0, - }, - exp: { - hacking: 0, - strength: 0, - defense: 0, - dexterity: 0, - agility: 0, - charisma: 0, - intelligence: 0, - }, + skills: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 }, + exp: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 }, mults: defaultMultipliers(), numPeopleKilled: 0, money: 0, @@ -118,11 +102,15 @@ export function NetscriptFormulas(): InternalAPI { playtimeSinceLastBitnode: 0, jobs: {}, factions: [], - tor: false, - hasCorporation: false, - inBladeburner: false, entropy: 0, }), + mockPerson: () => (): IPerson => ({ + hp: { current: 0, max: 0 }, + skills: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 }, + exp: { hacking: 0, strength: 0, defense: 0, dexterity: 0, agility: 0, charisma: 0, intelligence: 0 }, + mults: defaultMultipliers(), + city: "", + }), reputation: { calculateFavorToRep: (ctx) => (_favor) => { const favor = helpers.number(ctx, "favor", _favor); @@ -136,9 +124,9 @@ export function NetscriptFormulas(): InternalAPI { }, repFromDonation: (ctx) => (_amount, _player) => { const amount = helpers.number(ctx, "amount", _amount); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return repFromDonation(amount, player); + return repFromDonation(amount, person); }, }, skills: { @@ -162,49 +150,49 @@ export function NetscriptFormulas(): InternalAPI { hacking: { hackChance: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculateHackingChance(server, player); + return calculateHackingChance(server, person); }, hackExp: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculateHackingExpGain(server, player); + return calculateHackingExpGain(server, person); }, hackPercent: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculatePercentMoneyHacked(server, player); + return calculatePercentMoneyHacked(server, person); }, growPercent: (ctx) => (_server, _threads, _player, _cores = 1) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); const threads = helpers.number(ctx, "threads", _threads); const cores = helpers.number(ctx, "cores", _cores); checkFormulasAccess(ctx); - return calculateServerGrowth(server, threads, player, cores); + return calculateServerGrowth(server, threads, person, cores); }, hackTime: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculateHackingTime(server, player) * 1000; + return calculateHackingTime(server, person) * 1000; }, growTime: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculateGrowTime(server, player) * 1000; + return calculateGrowTime(server, person) * 1000; }, weakenTime: (ctx) => (_server, _player) => { const server = helpers.server(ctx, _server); - const player = helpers.player(ctx, _player); + const person = helpers.person(ctx, _player); checkFormulasAccess(ctx); - return calculateWeakenTime(server, player) * 1000; + return calculateWeakenTime(server, person) * 1000; }, }, hacknetNodes: { @@ -365,20 +353,26 @@ export function NetscriptFormulas(): InternalAPI { }, }, work: { + crimeSuccessChance: (ctx) => (_person, _crimeType) => { + const person = helpers.person(ctx, _person); + const crimeType = helpers.string(ctx, "crimeType", _crimeType); + if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`); + return Crimes[crimeType].successRate(person); + }, crimeGains: (ctx) => (_person, _crimeType) => { - const person = helpers.player(ctx, _person); + const person = helpers.person(ctx, _person); const crimeType = helpers.string(ctx, "crimeType", _crimeType); if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`); return calculateCrimeWorkStats(person, Crimes[crimeType]); }, classGains: (ctx) => (_person, _classType, _locationName) => { - const person = helpers.player(ctx, _person); + const person = helpers.person(ctx, _person); const classType = helpers.string(ctx, "classType", _classType); const locationName = helpers.string(ctx, "locationName", _locationName); return calculateClassEarnings(person, classType as ClassType, locationName as LocationName); }, factionGains: (ctx) => (_player, _workType, _favor) => { - const player = helpers.player(ctx, _player); + const player = helpers.person(ctx, _player); const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType; const favor = helpers.number(ctx, "favor", _favor); const exp = calculateFactionExp(player, workType); @@ -386,9 +380,8 @@ export function NetscriptFormulas(): InternalAPI { exp.reputation = rep; return exp; }, - companyGains: (ctx) => (_player, _companyName, _positionName, _favor) => { - const player = helpers.player(ctx, _player); + const player = helpers.person(ctx, _player); CompanyPositions; const positionName = helpers.string(ctx, "_positionName", _positionName); const position = Object.values(CompanyPositions).find((c) => c.name === positionName); diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 1107bc318..636e2fcf7 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -1234,7 +1234,6 @@ export function NetscriptSingularity(): InternalAPI { return true; }; const bladeburnerRequirements = () => { - if (!Player.inBladeburner()) return false; if (!Player.bladeburner) return false; return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus]; }; diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index 43586bbd5..9fe4845f0 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -4,7 +4,7 @@ import { CityName } from "../Locations/data/CityNames"; import { findCrime } from "../Crime/CrimeHelpers"; import { Augmentation } from "../Augmentation/Augmentation"; -import { Sleeve as ISleeve, SleeveSkills } from "../ScriptEditor/NetscriptDefinitions"; +import { sleeve } from "../ScriptEditor/NetscriptDefinitions"; import { checkEnum } from "../utils/helpers/checkEnum"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork"; @@ -15,7 +15,7 @@ import { Crimes } from "../Crime/Crimes"; import { CrimeType } from "../utils/WorkType"; import { cloneDeep } from "lodash"; -export function NetscriptSleeve(): InternalAPI { +export function NetscriptSleeve(): InternalAPI { const checkSleeveAPIAccess = function (ctx: NetscriptContext) { if (Player.bitNodeN !== 10 && !Player.sourceFileLvl(10)) { throw helpers.makeRuntimeErrorMsg( @@ -33,21 +33,6 @@ export function NetscriptSleeve(): InternalAPI { } }; - const getSleeveStats = function (sleeveNumber: number): SleeveSkills { - const sl = Player.sleeves[sleeveNumber]; - return { - shock: 100 - sl.shock, - sync: sl.sync, - memory: sl.memory, - hacking: sl.skills.hacking, - strength: sl.skills.strength, - defense: sl.skills.defense, - dexterity: sl.skills.dexterity, - agility: sl.skills.agility, - charisma: sl.skills.charisma, - }; - }; - return { getNumSleeves: (ctx) => () => { checkSleeveAPIAccess(ctx); @@ -154,12 +139,6 @@ export function NetscriptSleeve(): InternalAPI { return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat); }, - getSleeveStats: (ctx) => (_sleeveNumber) => { - const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); - checkSleeveAPIAccess(ctx); - checkSleeveNumber(ctx, sleeveNumber); - return getSleeveStats(sleeveNumber); - }, getTask: (ctx) => (_sleeveNumber) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); checkSleeveAPIAccess(ctx); @@ -169,40 +148,25 @@ export function NetscriptSleeve(): InternalAPI { if (sl.currentWork === null) return null; return sl.currentWork.APICopy(); }, - getInformation: (ctx) => (_sleeveNumber) => { + getSleeve: (ctx) => (_sleeveNumber) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); checkSleeveAPIAccess(ctx); checkSleeveNumber(ctx, sleeveNumber); const sl = Player.sleeves[sleeveNumber]; - return { - tor: false, - city: sl.city, - hp: sl.hp, - jobs: Object.keys(Player.jobs), // technically sleeves have the same jobs as the player. - jobTitle: Object.values(Player.jobs), - mult: { - agility: sl.mults.agility, - agilityExp: sl.mults.agility_exp, - charisma: sl.mults.charisma, - charismaExp: sl.mults.charisma_exp, - companyRep: sl.mults.company_rep, - crimeMoney: sl.mults.crime_money, - crimeSuccess: sl.mults.crime_success, - defense: sl.mults.defense, - defenseExp: sl.mults.defense_exp, - dexterity: sl.mults.dexterity, - dexterityExp: sl.mults.dexterity_exp, - factionRep: sl.mults.faction_rep, - hacking: sl.mults.hacking, - hackingExp: sl.mults.hacking_exp, - strength: sl.mults.strength, - strengthExp: sl.mults.strength_exp, - workMoney: sl.mults.work_money, - }, + const data = { + hp: cloneDeep(sl.hp), skills: cloneDeep(sl.skills), + exp: cloneDeep(sl.exp), + mults: cloneDeep(sl.mults), + city: sl.city, + shock: sl.shock, + sync: sl.sync, + memory: sl.memory, }; + + return data; }, getSleeveAugmentations: (ctx) => (_sleeveNumber) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); @@ -238,7 +202,7 @@ export function NetscriptSleeve(): InternalAPI { checkSleeveAPIAccess(ctx); checkSleeveNumber(ctx, sleeveNumber); - if (getSleeveStats(sleeveNumber).shock > 0) { + if (Player.sleeves[sleeveNumber].shock > 0) { throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`); } diff --git a/src/PersonObjects/Grafting/GraftingHelpers.ts b/src/PersonObjects/Grafting/GraftingHelpers.ts index 19bcdd8f8..f6346382b 100644 --- a/src/PersonObjects/Grafting/GraftingHelpers.ts +++ b/src/PersonObjects/Grafting/GraftingHelpers.ts @@ -1,6 +1,7 @@ import { StaticAugmentations } from "../../Augmentation/StaticAugmentations"; import { GraftableAugmentation } from "./GraftableAugmentation"; import { Player } from "@player"; +import { calculateIntelligenceBonus } from "../formulas/intelligence"; export const getGraftingAvailableAugs = (): string[] => { const augs: string[] = []; @@ -14,7 +15,7 @@ export const getGraftingAvailableAugs = (): string[] => { }; export const graftingIntBonus = (): number => { - return 1 + (Player.getIntelligenceBonus(3) - 1) / 3; + return 1 + (calculateIntelligenceBonus(Player.skills.intelligence, 3) - 1) / 3; }; export const calculateGraftingTimeWithBonus = (aug: GraftableAugmentation): number => { diff --git a/src/PersonObjects/Person.ts b/src/PersonObjects/Person.ts index d969b0470..c398d574d 100644 --- a/src/PersonObjects/Person.ts +++ b/src/PersonObjects/Person.ts @@ -2,14 +2,14 @@ import * as personMethods from "./PersonMethods"; import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; import { CityName } from "../Locations/data/CityNames"; import { calculateSkill } from "./formulas/skill"; -import { calculateIntelligenceBonus } from "./formulas/intelligence"; import { defaultMultipliers } from "./Multipliers"; import { Skills } from "./Skills"; import { HP } from "./HP"; +import { Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { IReviverValue } from "../utils/JSONReviver"; // Base class representing a person-like object -export abstract class Person { +export abstract class Person implements IPerson { hp: HP = { current: 10, max: 10 }; skills: Skills = { hacking: 1, @@ -58,10 +58,6 @@ export abstract class Person { this.mults = defaultMultipliers(); } - getIntelligenceBonus(weight: number): number { - return calculateIntelligenceBonus(this.skills.intelligence, weight); - } - abstract takeDamage(amt: number): boolean; abstract whoAmI(): string; abstract toJSON(): IReviverValue; diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 1aa7a04c2..b20b2201a 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -26,8 +26,9 @@ import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { CONSTANTS } from "../../Constants"; import { Work } from "src/Work/Work"; import { Person } from "../Person"; +import { Player as IPlayer } from "../../ScriptEditor/NetscriptDefinitions"; -export class PlayerObject extends Person { +export class PlayerObject extends Person implements IPlayer { // Player-specific properties bitNodeN = 1; //current bitnode corporation: Corporation | null = null; @@ -102,11 +103,9 @@ export class PlayerObject extends Person { getUpgradeHomeRamCost = serverMethods.getUpgradeHomeRamCost; getUpgradeHomeCoresCost = serverMethods.getUpgradeHomeCoresCost; gotoLocation = generalMethods.gotoLocation; - hasCorporation = corporationMethods.hasCorporation; hasGangWith = gangMethods.hasGangWith; hasTorRouter = serverMethods.hasTorRouter; hasProgram = generalMethods.hasProgram; - inBladeburner = bladeburnerMethods.inBladeburner; inGang = gangMethods.inGang; isAwareOfGang = gangMethods.isAwareOfGang; isQualified = generalMethods.isQualified; diff --git a/src/PersonObjects/Player/PlayerObjectBladeburnerMethods.ts b/src/PersonObjects/Player/PlayerObjectBladeburnerMethods.ts index 3febedfdf..42a24914e 100644 --- a/src/PersonObjects/Player/PlayerObjectBladeburnerMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectBladeburnerMethods.ts @@ -5,10 +5,6 @@ export function canAccessBladeburner(this: PlayerObject): boolean { return this.bitNodeN === 6 || this.bitNodeN === 7 || this.sourceFileLvl(6) > 0 || this.sourceFileLvl(7) > 0; } -export function inBladeburner(this: PlayerObject): boolean { - return Boolean(this.bladeburner); -} - export function startBladeburner(this: PlayerObject): void { this.bladeburner = new Bladeburner(); } diff --git a/src/PersonObjects/Player/PlayerObjectCorporationMethods.ts b/src/PersonObjects/Player/PlayerObjectCorporationMethods.ts index 1014c112a..dc97cb17f 100644 --- a/src/PersonObjects/Player/PlayerObjectCorporationMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectCorporationMethods.ts @@ -9,10 +9,6 @@ export function canAccessCorporation(this: PlayerObject): boolean { return this.bitNodeN === 3 || this.sourceFileLvl(3) > 0; } -export function hasCorporation(this: PlayerObject): boolean { - return Boolean(this.corporation); -} - export function startCorporation(this: PlayerObject, corpName: string, additionalShares = 0): void { this.corporation = new Corporation({ name: corpName, diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index 7fc012f0b..90726549a 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -138,9 +138,10 @@ export function prestigeSourceFile(this: PlayerObject): void { } } - // Gang this.gang = null; resetGangs(); + this.corporation = null; + this.bladeburner = null; // Reset Stock market this.hasWseAccount = false; diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 787f86882..dde9acf1e 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -40,8 +40,9 @@ import { SleeveSupportWork } from "./Work/SleeveSupportWork"; import { SleeveBladeburnerWork } from "./Work/SleeveBladeburnerWork"; import { SleeveCrimeWork } from "./Work/SleeveCrimeWork"; import * as sleeveMethods from "./SleeveMethods"; +import { Sleeve as ISleeve } from "../../ScriptEditor/NetscriptDefinitions"; -export class Sleeve extends Person { +export class Sleeve extends Person implements ISleeve { currentWork: Work | null = null; /** Clone retains 'memory' synchronization (and maybe exp?) upon prestige/installing Augs */ diff --git a/src/PersonObjects/Sleeve/Work/SleeveSynchroWork.ts b/src/PersonObjects/Sleeve/Work/SleeveSynchroWork.ts index b159785ec..15cecc43f 100644 --- a/src/PersonObjects/Sleeve/Work/SleeveSynchroWork.ts +++ b/src/PersonObjects/Sleeve/Work/SleeveSynchroWork.ts @@ -2,6 +2,7 @@ import { Player } from "@player"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../../../utils/JSONReviver"; import { Sleeve } from "../Sleeve"; import { Work, WorkType } from "./Work"; +import { calculateIntelligenceBonus } from "../../formulas/intelligence"; export const isSleeveSynchroWork = (w: Work | null): w is SleeveSynchroWork => w !== null && w.type === WorkType.SYNCHRO; @@ -12,7 +13,10 @@ export class SleeveSynchroWork extends Work { } process(sleeve: Sleeve, cycles: number): number { - sleeve.sync = Math.min(100, sleeve.sync + Player.getIntelligenceBonus(0.5) * 0.0002 * cycles); + sleeve.sync = Math.min( + 100, + sleeve.sync + calculateIntelligenceBonus(Player.skills.intelligence, 0.5) * 0.0002 * cycles, + ); if (sleeve.sync >= 100) sleeve.stopWork(); return 0; } diff --git a/src/PersonObjects/Sleeve/ui/StatsElement.tsx b/src/PersonObjects/Sleeve/ui/StatsElement.tsx index d9086fea3..c999d8178 100644 --- a/src/PersonObjects/Sleeve/ui/StatsElement.tsx +++ b/src/PersonObjects/Sleeve/ui/StatsElement.tsx @@ -2,6 +2,8 @@ import React from "react"; import { Typography, Table, TableBody, TableCell, TableRow } from "@mui/material"; +import { CONSTANTS } from "../../../Constants"; + import { numeralWrapper } from "../../../ui/numeralFormat"; import { Settings } from "../../../Settings/Settings"; import { StatsRow } from "../../../ui/React/StatsRow"; @@ -15,7 +17,8 @@ import { isSleeveClassWork } from "../Work/SleeveClassWork"; import { isSleeveFactionWork } from "../Work/SleeveFactionWork"; import { isSleeveCompanyWork } from "../Work/SleeveCompanyWork"; import { isSleeveCrimeWork } from "../Work/SleeveCrimeWork"; -import { BitNodeMultipliers } from "../../../BitNode/BitNodeMultipliers"; + +const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle; interface IProps { sleeve: Sleeve; @@ -99,37 +102,37 @@ export function EarningsElement(props: IProps): React.ReactElement { if (isSleeveCrimeWork(props.sleeve.currentWork)) { const gains = props.sleeve.currentWork.getExp(props.sleeve); data = [ - [`Money:`, ], - [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * gains.hackExp)}`], - [`Strength Exp:`, `${numeralWrapper.formatExp(5 * gains.strExp)}`], - [`Defense Exp:`, `${numeralWrapper.formatExp(5 * gains.defExp)}`], - [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * gains.dexExp)}`], - [`Agility Exp:`, `${numeralWrapper.formatExp(5 * gains.agiExp)}`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * gains.chaExp)}`], + [`Money:`, ], + [`Hacking Exp:`, `${numeralWrapper.formatExp(gains.hackExp)}`], + [`Strength Exp:`, `${numeralWrapper.formatExp(gains.strExp)}`], + [`Defense Exp:`, `${numeralWrapper.formatExp(gains.defExp)}`], + [`Dexterity Exp:`, `${numeralWrapper.formatExp(gains.dexExp)}`], + [`Agility Exp:`, `${numeralWrapper.formatExp(gains.agiExp)}`], + [`Charisma Exp:`, `${numeralWrapper.formatExp(gains.chaExp)}`], ]; } if (isSleeveClassWork(props.sleeve.currentWork)) { const rates = props.sleeve.currentWork.calculateRates(props.sleeve); data = [ - [`Money:`, ], - [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * rates.hackExp)} / sec`], - [`Strength Exp:`, `${numeralWrapper.formatExp(5 * rates.strExp)} / sec`], - [`Defense Exp:`, `${numeralWrapper.formatExp(5 * rates.defExp)} / sec`], - [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * rates.dexExp)} / sec`], - [`Agility Exp:`, `${numeralWrapper.formatExp(5 * rates.agiExp)} / sec`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * rates.chaExp)} / sec`], + [`Money:`, ], + [`Hacking Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.hackExp)} / sec`], + [`Strength Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.strExp)} / sec`], + [`Defense Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.defExp)} / sec`], + [`Dexterity Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.dexExp)} / sec`], + [`Agility Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.agiExp)} / sec`], + [`Charisma Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.chaExp)} / sec`], ]; } if (isSleeveFactionWork(props.sleeve.currentWork)) { const rates = props.sleeve.currentWork.getExpRates(props.sleeve); const repGain = props.sleeve.currentWork.getReputationRate(props.sleeve); data = [ - [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * rates.hackExp)} / sec`], - [`Strength Exp:`, `${numeralWrapper.formatExp(5 * rates.strExp)} / sec`], - [`Defense Exp:`, `${numeralWrapper.formatExp(5 * rates.defExp)} / sec`], - [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * rates.dexExp)} / sec`], - [`Agility Exp:`, `${numeralWrapper.formatExp(5 * rates.agiExp)} / sec`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * rates.chaExp)} / sec`], + [`Hacking Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.hackExp)} / sec`], + [`Strength Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.strExp)} / sec`], + [`Defense Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.defExp)} / sec`], + [`Dexterity Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.dexExp)} / sec`], + [`Agility Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.agiExp)} / sec`], + [`Charisma Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.chaExp)} / sec`], [`Reputation:`, ], ]; } @@ -137,14 +140,14 @@ export function EarningsElement(props: IProps): React.ReactElement { if (isSleeveCompanyWork(props.sleeve.currentWork)) { const rates = props.sleeve.currentWork.getGainRates(props.sleeve); data = [ - [`Money:`, ], - [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * rates.hackExp)} / sec`], - [`Strength Exp:`, `${numeralWrapper.formatExp(5 * rates.strExp)} / sec`], - [`Defense Exp:`, `${numeralWrapper.formatExp(5 * rates.defExp)} / sec`], - [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * rates.dexExp)} / sec`], - [`Agility Exp:`, `${numeralWrapper.formatExp(5 * rates.agiExp)} / sec`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * rates.chaExp)} / sec`], - [`Reputation:`, ], + [`Money:`, ], + [`Hacking Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.hackExp)} / sec`], + [`Strength Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.strExp)} / sec`], + [`Defense Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.defExp)} / sec`], + [`Dexterity Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.dexExp)} / sec`], + [`Agility Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.agiExp)} / sec`], + [`Charisma Exp:`, `${numeralWrapper.formatExp(CYCLES_PER_SEC * rates.chaExp)} / sec`], + [`Reputation:`, ], ]; } diff --git a/src/PersonObjects/Sleeve/ui/TaskSelector.tsx b/src/PersonObjects/Sleeve/ui/TaskSelector.tsx index a0001a421..9575c989a 100644 --- a/src/PersonObjects/Sleeve/ui/TaskSelector.tsx +++ b/src/PersonObjects/Sleeve/ui/TaskSelector.tsx @@ -246,7 +246,7 @@ const canDo: { "Take University Course": (sleeve: Sleeve) => [CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city), "Workout at Gym": (sleeve: Sleeve) => [CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city), - "Perform Bladeburner Actions": () => Player.inBladeburner(), + "Perform Bladeburner Actions": () => !!Player.bladeburner, "Shock Recovery": (sleeve: Sleeve) => sleeve.shock < 100, Synchronize: (sleeve: Sleeve) => sleeve.sync < 100, }; diff --git a/src/PersonObjects/formulas/reputation.ts b/src/PersonObjects/formulas/reputation.ts index f549493ff..21a2e579d 100644 --- a/src/PersonObjects/formulas/reputation.ts +++ b/src/PersonObjects/formulas/reputation.ts @@ -1,7 +1,7 @@ import { CONSTANTS } from "../../Constants"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { CalculateShareMult } from "../../NetworkShare/Share"; -import { Person } from "../Person"; +import { Person as IPerson } from "../../ScriptEditor/NetscriptDefinitions"; import { calculateIntelligenceBonus } from "./intelligence"; function mult(favor: number): number { @@ -12,7 +12,7 @@ function mult(favor: number): number { return favorMult * BitNodeMultipliers.FactionWorkRepGain; } -export function getHackingWorkRepGain(p: Person, favor: number): number { +export function getHackingWorkRepGain(p: IPerson, favor: number): number { return ( ((p.skills.hacking + p.skills.intelligence / 3) / CONSTANTS.MaxSkillLevel) * p.mults.faction_rep * @@ -22,7 +22,7 @@ export function getHackingWorkRepGain(p: Person, favor: number): number { ); } -export function getFactionSecurityWorkRepGain(p: Person, favor: number): number { +export function getFactionSecurityWorkRepGain(p: IPerson, favor: number): number { const t = (0.9 * (p.skills.strength + @@ -35,7 +35,7 @@ export function getFactionSecurityWorkRepGain(p: Person, favor: number): number return t * p.mults.faction_rep * mult(favor) * calculateIntelligenceBonus(p.skills.intelligence, 1); } -export function getFactionFieldWorkRepGain(p: Person, favor: number): number { +export function getFactionFieldWorkRepGain(p: IPerson, favor: number): number { const t = (0.9 * (p.skills.strength + diff --git a/src/Prestige.ts b/src/Prestige.ts index 973884d78..504859d3c 100755 --- a/src/Prestige.ts +++ b/src/Prestige.ts @@ -281,10 +281,7 @@ export function prestigeSourceFile(flume: boolean): void { deleteStockMarket(); } - Player.gang = null; - Player.corporation = null; resetIndustryResearchTrees(); - Player.bladeburner = null; // Source-File 9 (level 3) effect if (Player.sourceFileLvl(9) >= 3) { diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 00a370ca4..0dbbdd28f 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -42,20 +42,28 @@ interface Person { skills: Skills; exp: Skills; mults: Multipliers; - numPeopleKilled: number; - money: number; city: string; - location: string; +} + +/** @public */ +interface Player extends Person { + money: number; + numPeopleKilled: number; + entropy: number; + jobs: Record; + factions: string[]; bitNodeN: number; totalPlaytime: number; playtimeSinceLastAug: number; playtimeSinceLastBitnode: number; - jobs: Record; - factions: string[]; - tor: boolean; - hasCorporation: boolean; - inBladeburner: boolean; - entropy: number; + location: string; +} + +/** @public */ +interface Sleeve extends Person { + shock: number; + sync: number; + memory: number; } /** @public */ @@ -90,65 +98,65 @@ interface MoneySources { /** @public */ export interface Multipliers { /** Multiplier to hacking skill */ - hacking?: number; + hacking: number; /** Multiplier to strength skill */ - strength?: number; + strength: number; /** Multiplier to defense skill */ - defense?: number; + defense: number; /** Multiplier to dexterity skill */ - dexterity?: number; + dexterity: number; /** Multiplier to agility skill */ - agility?: number; + agility: number; /** Multiplier to charisma skill */ - charisma?: number; + charisma: number; /** Multiplier to hacking experience gain rate */ - hacking_exp?: number; + hacking_exp: number; /** Multiplier to strength experience gain rate */ - strength_exp?: number; + strength_exp: number; /** Multiplier to defense experience gain rate */ - defense_exp?: number; + defense_exp: number; /** Multiplier to dexterity experience gain rate */ - dexterity_exp?: number; + dexterity_exp: number; /** Multiplier to agility experience gain rate */ - agility_exp?: number; + agility_exp: number; /** Multiplier to charisma experience gain rate */ - charisma_exp?: number; + charisma_exp: number; /** Multiplier to chance of successfully performing a hack */ - hacking_chance?: number; + hacking_chance: number; /** Multiplier to hacking speed */ - hacking_speed?: number; + hacking_speed: number; /** Multiplier to amount of money the player gains from hacking */ - hacking_money?: number; + hacking_money: number; /** Multiplier to amount of money injected into servers using grow */ - hacking_grow?: number; + hacking_grow: number; /** Multiplier to amount of reputation gained when working */ - company_rep?: number; + company_rep: number; /** Multiplier to amount of reputation gained when working */ - faction_rep?: number; + faction_rep: number; /** Multiplier to amount of money gained from crimes */ - crime_money?: number; + crime_money: number; /** Multiplier to crime success rate */ - crime_success?: number; + crime_success: number; /** Multiplier to amount of money gained from working */ - work_money?: number; + work_money: number; /** Multiplier to amount of money produced by Hacknet Nodes */ - hacknet_node_money?: number; + hacknet_node_money: number; /** Multiplier to cost of purchasing a Hacknet Node */ - hacknet_node_purchase_cost?: number; + hacknet_node_purchase_cost: number; /** Multiplier to cost of ram for a Hacknet Node */ - hacknet_node_ram_cost?: number; + hacknet_node_ram_cost: number; /** Multiplier to cost of core for a Hacknet Node */ - hacknet_node_core_cost?: number; + hacknet_node_core_cost: number; /** Multiplier to cost of leveling up a Hacknet Node */ - hacknet_node_level_cost?: number; + hacknet_node_level_cost: number; /** Multiplier to Bladeburner max stamina */ - bladeburner_max_stamina?: number; + bladeburner_max_stamina: number; /** Multiplier to Bladeburner stamina gain rate */ - bladeburner_stamina_gain?: number; + bladeburner_stamina_gain: number; /** Multiplier to effectiveness in Bladeburner Field Analysis */ - bladeburner_analysis?: number; + bladeburner_analysis: number; /** Multiplier to success chance in Bladeburner contracts/operations */ - bladeburner_success_chance?: number; + bladeburner_success_chance: number; } /** @public */ @@ -259,7 +267,7 @@ export interface CodingAttemptOptions { } /** - * Return value of {@link Sleeve.getSleevePurchasableAugs | getSleevePurchasableAugs} + * Return value of {@link sleeve.getSleevePurchasableAugs | getSleevePurchasableAugs} * @public */ export interface AugmentPair { @@ -869,52 +877,6 @@ export interface GangMemberAscension { cha: number; } -/** - * Object representing a sleeve stats. - * @public - */ -export interface SleeveSkills { - /** Current shock of the sleeve [0-100] */ - shock: number; - /** Current sync of the sleeve [0-100] */ - sync: number; - /** Current memory of the sleeve [1-100] */ - memory: number; - /** Current hacking skill of the sleeve */ - hacking: number; - /** Current strength of the sleeve */ - strength: number; - /** Current defense of the sleeve */ - defense: number; - /** Current dexterity of the sleeve */ - dexterity: number; - /** Current agility of the sleeve */ - agility: number; - /** Current charisma of the sleeve */ - charisma: number; -} - -/** - * Object representing sleeve information. - * @public - */ -export interface SleeveInformation { - /** Location of the sleeve */ - city: string; - /** hp of the sleeve */ - hp: HP; - /** Jobs available to the sleeve */ - jobs: string[]; - /** Job titles available to the sleeve */ - jobTitle: string[]; - /** Does this sleeve have access to the tor router */ - tor: boolean; - /** Sleeve multipliers */ - mult: Multipliers; - /** Sleeve skills */ - skills: Skills; -} - /** * Object representing a sleeve current task. * @public @@ -3137,6 +3099,13 @@ export interface Bladeburner { * @returns Amount of accumulated “bonus time” (milliseconds) for the Bladeburner mechanic. */ getBonusTime(): number; + + /** Returns whether player is a member of bladeburner division. Does not require API access. + * @remarks + * RAM cost: 1 GB + * + * @returns whether player is a member of bladeburner division. */ + inBladeburner(): boolean; } /** @@ -3511,7 +3480,7 @@ export interface Gang { * If you are not in BitNode-10, then you must have Source-File 10 in order to use this API. * @public */ -export interface Sleeve { +export interface sleeve { /** * Get the number of sleeves you own. * @remarks @@ -3523,29 +3492,17 @@ export interface Sleeve { */ getNumSleeves(): number; - /** - * Get the stats of a sleeve. - * @remarks - * RAM cost: 4 GB - * - * Return a structure containing the stats of the sleeve. - * - * @param sleeveNumber - Index of the sleeve to get stats of. - * @returns Object containing the stats of the sleeve. - */ - getSleeveStats(sleeveNumber: number): SleeveSkills; - /** * Get information about a sleeve. * @remarks * RAM cost: 4 GB * - * Return a struct containing tons of information about this sleeve + * Return a person object for this sleeve * * @param sleeveNumber - Index of the sleeve to retrieve information. - * @returns Object containing tons of information about this sleeve. + * @returns Object containing information about this sleeve. */ - getInformation(sleeveNumber: number): SleeveInformation; + getSleeve(sleeveNumber: number): Sleeve; /** * Get task of a sleeve. @@ -3853,6 +3810,7 @@ export interface WorkStats { * @public */ interface WorkFormulas { + crimeSuccessChance(person: Person, crimeType: CrimeType | CrimeNames): number; crimeGains(person: Person, crimeType: CrimeType | CrimeNames): WorkStats; classGains(person: Person, classType: string, locationName: string): WorkStats; factionGains(person: Person, workType: string, favor: number): WorkStats; @@ -4129,7 +4087,8 @@ interface GangFormulas { */ export interface Formulas { mockServer(): Server; - mockPlayer(): Person; + mockPlayer(): Player; + mockPerson(): Person; /** Reputation formulas */ reputation: ReputationFormulas; /** Skills formulas */ @@ -4465,7 +4424,7 @@ export interface NS { * Namespace for sleeve functions. * @remarks RAM cost: 0 GB */ - readonly sleeve: Sleeve; + readonly sleeve: sleeve; /** * Namespace for stock functions. @@ -5180,6 +5139,25 @@ export interface NS { */ scan(host?: string): string[]; + /** Returns whether the player has access to the darkweb. + * @remarks + * RAM cost: 0.05GB + * + * @example + * ```js + * // NS1: + * if (hasTorRouter()) tprint("TOR router detected."); + * ``` + * + * @example + * ```js + * // NS2: + * if (ns.hasTorRouter()) tprint("TOR router detected."); + * ``` + * + * @returns Whether player has access to the dark web. */ + hasTorRouter(): boolean; + /** * Runs NUKE.exe on a server. * @remarks @@ -6705,7 +6683,7 @@ export interface NS { * * @returns Player info */ - getPlayer(): Person; + getPlayer(): Player; /** * Get information about the sources of income for this run. @@ -7201,12 +7179,14 @@ export interface WarehouseAPI { * @public */ export interface Corporation extends WarehouseAPI, OfficeAPI { - /** - * Create a Corporation + /** Returns whether the player has a corporation. Does not require API access. + * @returns whether the player has a corporation */ + hasCorporation(): boolean; + + /** Create a Corporation * @param divisionName - Name of the division * @param selfFund - If you should self fund, defaults to true, false will only work on Bitnode 3 - * @returns true if created and false if not - */ + * @returns true if created and false if not */ createCorporation(corporationName: string, selfFund: boolean): boolean; /** * Check if you have a one time unlockable upgrade diff --git a/src/Server/formulas/grow.ts b/src/Server/formulas/grow.ts index a739adf7b..ec94c8eec 100644 --- a/src/Server/formulas/grow.ts +++ b/src/Server/formulas/grow.ts @@ -1,9 +1,9 @@ import { CONSTANTS } from "../../Constants"; import { Server } from "../Server"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; -import { Person } from "../../PersonObjects/Person"; +import { Person as IPerson } from "../../ScriptEditor/NetscriptDefinitions"; -export function calculateServerGrowth(server: Server, threads: number, p: Person, cores = 1): number { +export function calculateServerGrowth(server: Server, threads: number, p: IPerson, cores = 1): number { const numServerGrowthCycles = Math.max(Math.floor(threads), 0); //Get adjusted growth rate, which accounts for server security diff --git a/src/Work/CreateProgramWork.ts b/src/Work/CreateProgramWork.ts index 292f56bc9..dd18b686e 100644 --- a/src/Work/CreateProgramWork.ts +++ b/src/Work/CreateProgramWork.ts @@ -6,6 +6,7 @@ import { Player } from "@player"; import { Programs } from "../Programs/Programs"; import { Work, WorkType } from "./Work"; import { Program } from "../Programs/Program"; +import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence"; export const isCreateProgramWork = (w: Work | null): w is CreateProgramWork => w !== null && w.type === WorkType.CREATE_PROGRAM; @@ -61,7 +62,7 @@ export class CreateProgramWork extends Work { } //Higher hacking skill will allow you to create programs faster const reqLvl = this.getProgram().create?.level ?? 0; - let skillMult = (Player.skills.hacking / reqLvl) * Player.getIntelligenceBonus(3); //This should always be greater than 1; + let skillMult = (Player.skills.hacking / reqLvl) * calculateIntelligenceBonus(Player.skills.intelligence, 3); //This should always be greater than 1; skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary skillMult *= focusBonus; //Skill multiplier directly applied to "time worked" diff --git a/src/Work/Formulas.ts b/src/Work/Formulas.ts index 579e5379e..e6d573832 100644 --- a/src/Work/Formulas.ts +++ b/src/Work/Formulas.ts @@ -1,7 +1,7 @@ import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { Crime } from "../Crime/Crime"; import { newWorkStats, scaleWorkStats, WorkStats, multWorkStats } from "./WorkStats"; -import { Person } from "../PersonObjects/Person"; +import { Person as IPerson } from "../ScriptEditor/NetscriptDefinitions"; import { CONSTANTS } from "../Constants"; import { FactionWorkType } from "./data/FactionWorkType"; import { @@ -40,7 +40,7 @@ export const FactionWorkStats: Record = { }), }; -export function calculateCrimeWorkStats(person: Person, crime: Crime): WorkStats { +export function calculateCrimeWorkStats(person: IPerson, crime: Crime): WorkStats { const gains = scaleWorkStats( multWorkStats( //Todo: rework crime and workstats interfaces to use the same naming convention for exp values, then we can just make a workStats directly from a crime. @@ -63,7 +63,7 @@ export function calculateCrimeWorkStats(person: Person, crime: Crime): WorkStats return gains; } -export const calculateFactionRep = (person: Person, type: FactionWorkType, favor: number): number => { +export const calculateFactionRep = (person: IPerson, type: FactionWorkType, favor: number): number => { const repFormulas = { [FactionWorkType.HACKING]: getHackingWorkRepGain, [FactionWorkType.FIELD]: getFactionFieldWorkRepGain, @@ -72,7 +72,7 @@ export const calculateFactionRep = (person: Person, type: FactionWorkType, favor return repFormulas[type](person, favor); }; -export function calculateFactionExp(person: Person, type: FactionWorkType): WorkStats { +export function calculateFactionExp(person: IPerson, type: FactionWorkType): WorkStats { return scaleWorkStats( multWorkStats(FactionWorkStats[type], person.mults), BitNodeMultipliers.FactionWorkExpGain / gameCPS, @@ -87,7 +87,7 @@ export function calculateCost(classs: Class, location: Location): number { return classs.earnings.money * location.costMult * discount; } -export function calculateClassEarnings(person: Person, type: ClassType, locationName: LocationName): WorkStats { +export function calculateClassEarnings(person: IPerson, type: ClassType, locationName: LocationName): WorkStats { const hashManager = Player.hashManager; const classs = Classes[type]; const location = Locations[locationName]; @@ -107,7 +107,7 @@ export function calculateClassEarnings(person: Person, type: ClassType, location } export const calculateCompanyWorkStats = ( - worker: Person, + worker: IPerson, company: Company, companyPosition: CompanyPosition, favor: number,