CORPORATION: Add a new API to sell a division (#1210)

Also refactoring around use of "player" variable (whether it is capitalized or not).
This commit is contained in:
catloversg 2024-04-16 11:19:47 +07:00 committed by GitHub
parent dd3975ab1d
commit 216500ed32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 111 additions and 152 deletions

@ -21,8 +21,40 @@ import {
sellSharesFailureReason, sellSharesFailureReason,
buybackSharesFailureReason, buybackSharesFailureReason,
issueNewSharesFailureReason, issueNewSharesFailureReason,
costOfCreatingCorporation,
} from "./helpers"; } from "./helpers";
import { PositiveInteger } from "../types"; import { PositiveInteger } from "../types";
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
export function createCorporation(corporationName: string, selfFund: boolean, restart: boolean): boolean {
if (!Player.canAccessCorporation()) {
return false;
}
if (Player.corporation && !restart) {
return false;
}
if (!corporationName) {
return false;
}
if (Player.bitNodeN !== 3 && !selfFund) {
throw new Error("Cannot use seed funds outside of BitNode 3");
}
if (currentNodeMults.CorporationSoftcap < 0.15) {
throw new Error(`You cannot create a corporation in BitNode ${Player.bitNodeN}`);
}
if (selfFund) {
const cost = costOfCreatingCorporation(restart);
if (!Player.canAfford(cost)) {
return false;
}
Player.startCorporation(corporationName, false);
Player.loseMoney(cost, "corporation");
} else {
Player.startCorporation(corporationName, true);
}
return true;
}
export function NewDivision(corporation: Corporation, industry: IndustryType, name: string): void { export function NewDivision(corporation: Corporation, industry: IndustryType, name: string): void {
if (corporation.divisions.size >= corporation.maxDivisions) if (corporation.divisions.size >= corporation.maxDivisions)

@ -5,6 +5,13 @@ import { Corporation } from "./Corporation";
import { CorpUpgrade } from "./data/CorporationUpgrades"; import { CorpUpgrade } from "./data/CorporationUpgrades";
import * as corpConstants from "./data/Constants"; import * as corpConstants from "./data/Constants";
export function costOfCreatingCorporation(restart: boolean): number {
if (restart && !Player.corporation?.seedFunded) {
return 50e9;
}
return 150e9;
}
export function calculateUpgradeCost(corporation: Corporation, upgrade: CorpUpgrade, amount: PositiveInteger): number { export function calculateUpgradeCost(corporation: Corporation, upgrade: CorpUpgrade, amount: PositiveInteger): number {
const priceMult = upgrade.priceMult; const priceMult = upgrade.priceMult;
const level = corporation.upgrades[upgrade.name].level; const level = corporation.upgrades[upgrade.name].level;

@ -28,11 +28,11 @@ import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import { MultiplierButtons } from "./MultiplierButtons"; import { MultiplierButtons } from "./MultiplierButtons";
import { SellCorporationModal } from "./modals/SellCorporationModal";
import { SellDivisionModal } from "./modals/SellDivisionModal"; import { SellDivisionModal } from "./modals/SellDivisionModal";
import { getRecordKeys } from "../../Types/Record"; import { getRecordKeys } from "../../Types/Record";
import { PositiveInteger } from "../../types"; import { PositiveInteger } from "../../types";
import { ButtonWithTooltip } from "../../ui/Components/ButtonWithTooltip"; import { ButtonWithTooltip } from "../../ui/Components/ButtonWithTooltip";
import { CreateCorporationModal } from "./modals/CreateCorporationModal";
interface IProps { interface IProps {
rerender: () => void; rerender: () => void;
@ -319,16 +319,12 @@ function SellDivisionButton(): React.ReactElement {
function RestartButton(): React.ReactElement { function RestartButton(): React.ReactElement {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
function restart(): void {
setOpen(true);
}
return ( return (
<> <>
<ButtonWithTooltip normalTooltip={"Sell corporation and start over"} onClick={restart}> <ButtonWithTooltip normalTooltip={"Sell corporation and start over"} onClick={() => setOpen(true)}>
Sell CEO position Sell CEO position
</ButtonWithTooltip> </ButtonWithTooltip>
<SellCorporationModal open={open} onClose={() => setOpen(false)} /> <CreateCorporationModal open={open} onClose={() => setOpen(false)} restart={true} />
</> </>
); );
} }

@ -9,18 +9,21 @@ import { Player } from "@player";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import { ButtonWithTooltip } from "../../../ui/Components/ButtonWithTooltip"; import { ButtonWithTooltip } from "../../../ui/Components/ButtonWithTooltip";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
import { createCorporation } from "../../Actions";
import { costOfCreatingCorporation } from "../../helpers";
interface IProps { interface IProps {
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
restart: boolean;
} }
export function CreateCorporationModal(props: IProps): React.ReactElement { export function CreateCorporationModal(props: IProps): React.ReactElement {
const canSelfFund = Player.canAfford(150e9); const cost = costOfCreatingCorporation(props.restart);
const canSelfFund = Player.canAfford(cost);
const [name, setName] = useState(""); const [name, setName] = useState("");
if (!Player.canAccessCorporation() || Player.corporation) { if (!Player.canAccessCorporation() || (Player.corporation && !props.restart)) {
props.onClose();
return <></>; return <></>;
} }
@ -30,24 +33,10 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
setName(event.target.value); setName(event.target.value);
} }
function selfFund(): void { function createCorporationWithUI(corporationName: string, selfFund: boolean): void {
if (!canSelfFund) return; if (!createCorporation(corporationName, selfFund, props.restart)) {
if (name == "") return;
Player.startCorporation(name, false);
Player.loseMoney(150e9, "corporation");
props.onClose();
Router.toPage(Page.Corporation);
}
function seed(): void {
if (name == "") {
return; return;
} }
Player.startCorporation(name, true);
props.onClose(); props.onClose();
Router.toPage(Page.Corporation); Router.toPage(Page.Corporation);
} }
@ -55,30 +44,39 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Typography> <Typography>
Would you like to start a corporation? This will require <Money money={150e9} forPurchase={true} /> for {!props.restart ? (
registration and initial funding.{" "}
{Player.bitNodeN === 3 && (
<> <>
This <Money money={150e9} /> can either be self-funded, or you can obtain the seed money from the government Would you like to start a corporation? This will require <Money money={cost} forPurchase={true} /> for
in exchange for {formatShares(500e6)} shares (a <b>33.3%</b> stake in the company). registration and initial funding.{" "}
{Player.bitNodeN === 3 && (
<>
This <Money money={cost} /> can either be self-funded, or you can obtain the seed money from the
government in exchange for {formatShares(500e6)} shares (a <b>33.3%</b> stake in the company).
</>
)}
</>
) : (
<>
Would you like to sell your position as CEO and start a new corporation? Everything from your current
corporation will be gone and you start fresh.
</> </>
)} )}
<br /> <br />
<br /> <br />
If you would like to start one, please enter a name for your corporation below: If you would like to start {props.restart ? "a new" : ""} one, please enter a name for your corporation below:
</Typography> </Typography>
<br /> <br />
<TextField autoFocus={true} placeholder="Corporation Name" onChange={onChange} value={name} /> <TextField autoFocus={true} placeholder="Corporation Name" onChange={onChange} value={name} />
{Player.bitNodeN === 3 && ( {Player.bitNodeN === 3 && (
<ButtonWithTooltip onClick={seed} disabledTooltip={disabledTextForNoName}> <ButtonWithTooltip onClick={() => createCorporationWithUI(name, false)} disabledTooltip={disabledTextForNoName}>
Use seed money Use seed money
</ButtonWithTooltip> </ButtonWithTooltip>
)} )}
<ButtonWithTooltip <ButtonWithTooltip
onClick={selfFund} onClick={() => createCorporationWithUI(name, true)}
disabledTooltip={disabledTextForNoName || (canSelfFund ? "" : "Insufficient player funds")} disabledTooltip={disabledTextForNoName || (canSelfFund ? "" : "Insufficient player funds")}
> >
Self-Fund (<Money money={150e9} forPurchase={true} />) Self-Fund (<Money money={cost} forPurchase={true} />)
</ButtonWithTooltip> </ButtonWithTooltip>
</Modal> </Modal>
); );

@ -1,72 +0,0 @@
import React, { useState } from "react";
import { Money } from "../../../ui/React/Money";
import { Modal } from "../../../ui/React/Modal";
import { Router } from "../../../ui/GameRoot";
import { Page } from "../../../ui/Router";
import { Player } from "@player";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
interface IProps {
open: boolean;
onClose: () => void;
}
export function SellCorporationModal(props: IProps): React.ReactElement {
let cost = 150e9;
if (!Player.corporation?.seedFunded) {
cost /= 3;
}
const canSelfFund = Player.canAfford(cost);
const [name, setName] = useState("");
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setName(event.target.value);
}
function selfFund(): void {
if (!canSelfFund) return;
if (name == "") return;
Player.startCorporation(name, false);
Player.loseMoney(cost, "corporation");
props.onClose();
Router.toPage(Page.Corporation);
}
function seed(): void {
if (name == "") {
return;
}
Player.startCorporation(name, true);
props.onClose();
Router.toPage(Page.Corporation);
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>
Would you like to sell your position as CEO and start a new corporation? Everything from your current
corporation will be gone and you start fresh.
<br />
<br />
If you would like to start new one, please enter a name for your corporation below:
</Typography>
<br />
<TextField autoFocus={true} placeholder="Corporation Name" onChange={onChange} value={name} />
{Player.bitNodeN === 3 && (
<Button onClick={seed} disabled={name == ""}>
Use seed money
</Button>
)}
<Button onClick={selfFund} disabled={name == "" || !canSelfFund}>
Self-Fund (<Money money={cost} forPurchase={true} />)
</Button>
</Modal>
);
}

@ -144,7 +144,7 @@ export function SpecialLocation(props: SpecialLocationProps): React.ReactElement
<Button disabled={!Player.canAccessCorporation() || !!Player.corporation} onClick={() => setOpen(true)}> <Button disabled={!Player.canAccessCorporation() || !!Player.corporation} onClick={() => setOpen(true)}>
Create a Corporation Create a Corporation
</Button> </Button>
<CreateCorporationModal open={open} onClose={() => setOpen(false)} /> <CreateCorporationModal open={open} onClose={() => setOpen(false)} restart={false} />
</> </>
); );
} }

@ -449,6 +449,7 @@ const corporation = {
hasResearched: RamCostConstants.CorporationInfo, hasResearched: RamCostConstants.CorporationInfo,
setAutoJobAssignment: RamCostConstants.CorporationAction, setAutoJobAssignment: RamCostConstants.CorporationAction,
getOfficeSizeUpgradeCost: RamCostConstants.CorporationInfo, getOfficeSizeUpgradeCost: RamCostConstants.CorporationInfo,
sellDivision: RamCostConstants.CorporationAction,
} as const; } as const;
/** RamCosts guaranteed to match ns structure 1:1 (aside from args and enums). /** RamCosts guaranteed to match ns structure 1:1 (aside from args and enums).

@ -1,4 +1,4 @@
import { Player, Player as player } from "../Player"; import { Player } from "@player";
import { OfficeSpace } from "../Corporation/OfficeSpace"; import { OfficeSpace } from "../Corporation/OfficeSpace";
import { Product } from "../Corporation/Product"; import { Product } from "../Corporation/Product";
@ -50,6 +50,8 @@ import {
LimitMaterialProduction, LimitMaterialProduction,
LimitProductProduction, LimitProductProduction,
UpgradeWarehouseCost, UpgradeWarehouseCost,
createCorporation,
removeDivision,
} from "../Corporation/Actions"; } from "../Corporation/Actions";
import { CorpUnlocks } from "../Corporation/data/CorporationUnlocks"; import { CorpUnlocks } from "../Corporation/data/CorporationUnlocks";
import { CorpUpgrades } from "../Corporation/data/CorporationUpgrades"; import { CorpUpgrades } from "../Corporation/data/CorporationUpgrades";
@ -58,7 +60,6 @@ import { IndustriesData, IndustryResearchTrees } from "../Corporation/data/Indus
import * as corpConstants from "../Corporation/data/Constants"; import * as corpConstants from "../Corporation/data/Constants";
import { ResearchMap } from "../Corporation/ResearchMap"; import { ResearchMap } from "../Corporation/ResearchMap";
import { Factions } from "../Faction/Factions"; import { Factions } from "../Faction/Factions";
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
import { InternalAPI, NetscriptContext, setRemovedFunctions } from "../Netscript/APIWrapper"; import { InternalAPI, NetscriptContext, setRemovedFunctions } from "../Netscript/APIWrapper";
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers } from "../Netscript/NetscriptHelpers";
import { getEnumHelper } from "../utils/EnumHelper"; import { getEnumHelper } from "../utils/EnumHelper";
@ -68,24 +69,6 @@ import { PositiveInteger } from "../types";
import { getRecordKeys } from "../Types/Record"; import { getRecordKeys } from "../Types/Record";
export function NetscriptCorporation(): InternalAPI<NSCorporation> { export function NetscriptCorporation(): InternalAPI<NSCorporation> {
function createCorporation(corporationName: string, selfFund = true): boolean {
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 (currentNodeMults.CorporationSoftcap < 0.15)
throw new Error(`You cannot create a corporation in Bitnode ${player.bitNodeN}`);
if (selfFund) {
if (!player.canAfford(150e9)) return false;
player.startCorporation(corporationName, false);
player.loseMoney(150e9, "corporation");
} else {
player.startCorporation(corporationName, true);
}
return true;
}
function hasUnlock(unlockName: CorpUnlockName): boolean { function hasUnlock(unlockName: CorpUnlockName): boolean {
const corporation = getCorporation(); const corporation = getCorporation();
return corporation.unlocks.has(unlockName); return corporation.unlocks.has(unlockName);
@ -128,7 +111,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const faction = Factions[factionName]; const faction = Factions[factionName];
const info = faction.getInfo(); const info = faction.getInfo();
if (!info.offersWork()) return false; if (!info.offersWork()) return false;
if (player.hasGangWith(factionName)) return false; if (Player.hasGangWith(factionName)) return false;
const repGain = amountCash / corpConstants.bribeAmountPerReputation; const repGain = amountCash / corpConstants.bribeAmountPerReputation;
faction.playerReputation += repGain; faction.playerReputation += repGain;
@ -138,7 +121,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
} }
function getCorporation(): Corporation { function getCorporation(): Corporation {
const corporation = player.corporation; const corporation = Player.corporation;
if (corporation === null) throw new Error("cannot be called without a corporation"); if (corporation === null) throw new Error("cannot be called without a corporation");
return corporation; return corporation;
} }
@ -178,9 +161,9 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
} }
function checkAccess(ctx: NetscriptContext, api?: CorpUnlockName): void { function checkAccess(ctx: NetscriptContext, api?: CorpUnlockName): void {
if (!player.corporation) throw helpers.errorMessage(ctx, "Must own a corporation."); if (!Player.corporation) throw helpers.errorMessage(ctx, "Must own a corporation.");
if (!api) return; if (!api) return;
if (!player.corporation.unlocks.has(api)) { if (!Player.corporation.unlocks.has(api)) {
throw helpers.errorMessage(ctx, "You do not have access to this API."); throw helpers.errorMessage(ctx, "You do not have access to this API.");
} }
} }
@ -732,7 +715,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
(_corporationName, _selfFund = true): boolean => { (_corporationName, _selfFund = true): boolean => {
const corporationName = helpers.string(ctx, "corporationName", _corporationName); const corporationName = helpers.string(ctx, "corporationName", _corporationName);
const selfFund = !!_selfFund; const selfFund = !!_selfFund;
return createCorporation(corporationName, selfFund); return createCorporation(corporationName, selfFund, false);
}, },
hasUnlock: (ctx) => (_unlockName) => { hasUnlock: (ctx) => (_unlockName) => {
checkAccess(ctx); checkAccess(ctx);
@ -803,6 +786,12 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
CorporationPromise.promise = new Promise<CorpStateName>((res) => (CorporationPromise.resolve = res)); CorporationPromise.promise = new Promise<CorpStateName>((res) => (CorporationPromise.resolve = res));
return CorporationPromise.promise; return CorporationPromise.promise;
}, },
sellDivision: (ctx) => (_divisionName) => {
checkAccess(ctx);
const corporation = getCorporation();
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
removeDivision(corporation, divisionName);
},
}; };
// Removed functions // Removed functions

@ -1,4 +1,4 @@
import { Player } from "../Player"; import { Player } from "@player";
import { Exploit } from "../Exploits/Exploit"; import { Exploit } from "../Exploits/Exploit";
import * as bcrypt from "bcryptjs"; import * as bcrypt from "bcryptjs";
import { Apr1Events as devMenu } from "../ui/Apr1"; import { Apr1Events as devMenu } from "../ui/Apr1";

@ -1,4 +1,4 @@
import { Player as player } from "../Player"; import { Player } from "@player";
import { calculateServerGrowth, calculateGrowMoney } from "../Server/formulas/grow"; import { calculateServerGrowth, calculateGrowMoney } from "../Server/formulas/grow";
import { numCycleForGrowthCorrected } from "../Server/ServerHelpers"; import { numCycleForGrowthCorrected } from "../Server/ServerHelpers";
import { import {
@ -62,7 +62,7 @@ import { findCrime } from "../Crime/CrimeHelpers";
export function NetscriptFormulas(): InternalAPI<IFormulas> { export function NetscriptFormulas(): InternalAPI<IFormulas> {
const checkFormulasAccess = function (ctx: NetscriptContext): void { const checkFormulasAccess = function (ctx: NetscriptContext): void {
if (!player.hasProgram(CompletedProgramName.formulas)) { if (!Player.hasProgram(CompletedProgramName.formulas)) {
throw helpers.errorMessage(ctx, `Requires Formulas.exe to run.`); throw helpers.errorMessage(ctx, `Requires Formulas.exe to run.`);
} }
}; };
@ -325,7 +325,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
const upgName = helpers.string(ctx, "upgName", _upgName); const upgName = helpers.string(ctx, "upgName", _upgName);
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
const upg = player.hashManager.getUpgrade(upgName); const upg = Player.hashManager.getUpgrade(upgName);
if (!upg) { if (!upg) {
throw helpers.errorMessage(ctx, `Invalid Hash Upgrade: ${upgName}`); throw helpers.errorMessage(ctx, `Invalid Hash Upgrade: ${upgName}`);
} }

@ -1,4 +1,4 @@
import { Player as player } from "../Player"; import { Player } from "@player";
import { HacknetServerConstants } from "../Hacknet/data/Constants"; import { HacknetServerConstants } from "../Hacknet/data/Constants";
import { import {
getCostOfNextHacknetNode, getCostOfNextHacknetNode,
@ -25,12 +25,12 @@ import { helpers } from "../Netscript/NetscriptHelpers";
export function NetscriptHacknet(): InternalAPI<IHacknet> { export function NetscriptHacknet(): InternalAPI<IHacknet> {
// Utility function to get Hacknet Node object // Utility function to get Hacknet Node object
const getHacknetNode = function (ctx: NetscriptContext, i: number): HacknetNode | HacknetServer { const getHacknetNode = function (ctx: NetscriptContext, i: number): HacknetNode | HacknetServer {
if (i < 0 || i >= player.hacknetNodes.length) { if (i < 0 || i >= Player.hacknetNodes.length) {
throw helpers.errorMessage(ctx, "Index specified for Hacknet Node is out-of-bounds: " + i); throw helpers.errorMessage(ctx, "Index specified for Hacknet Node is out-of-bounds: " + i);
} }
if (hasHacknetServers()) { if (hasHacknetServers()) {
const hi = player.hacknetNodes[i]; const hi = Player.hacknetNodes[i];
if (typeof hi !== "string") throw new Error("hacknet node was not a string"); if (typeof hi !== "string") throw new Error("hacknet node was not a string");
const hserver = GetServer(hi); const hserver = GetServer(hi);
if (!(hserver instanceof HacknetServer)) throw new Error("hacknet server was not actually hacknet server"); if (!(hserver instanceof HacknetServer)) throw new Error("hacknet server was not actually hacknet server");
@ -43,7 +43,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return hserver; return hserver;
} else { } else {
const node = player.hacknetNodes[i]; const node = Player.hacknetNodes[i];
if (!(node instanceof HacknetNode)) throw new Error("hacknet node was not node."); if (!(node instanceof HacknetNode)) throw new Error("hacknet node was not node.");
return node; return node;
} }
@ -51,7 +51,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return { return {
numNodes: () => () => { numNodes: () => () => {
return player.hacknetNodes.length; return Player.hacknetNodes.length;
}, },
maxNumNodes: () => () => { maxNumNodes: () => () => {
if (hasHacknetServers()) { if (hasHacknetServers()) {
@ -140,7 +140,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost); return node.calculateLevelUpgradeCost(n, Player.mults.hacknet_node_level_cost);
}, },
getRamUpgradeCost: getRamUpgradeCost:
(ctx) => (ctx) =>
@ -148,7 +148,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost); return node.calculateRamUpgradeCost(n, Player.mults.hacknet_node_ram_cost);
}, },
getCoreUpgradeCost: getCoreUpgradeCost:
(ctx) => (ctx) =>
@ -156,7 +156,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost); return node.calculateCoreUpgradeCost(n, Player.mults.hacknet_node_core_cost);
}, },
getCacheUpgradeCost: getCacheUpgradeCost:
(ctx) => (ctx) =>
@ -177,13 +177,13 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 0; return 0;
} }
return player.hashManager.hashes; return Player.hashManager.hashes;
}, },
hashCapacity: () => () => { hashCapacity: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 0; return 0;
} }
return player.hashManager.capacity; return Player.hashManager.capacity;
}, },
hashCost: hashCost:
(ctx) => (ctx) =>
@ -194,7 +194,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return Infinity; return Infinity;
} }
return player.hashManager.getUpgradeCost(upgName, count); return Player.hashManager.getUpgradeCost(upgName, count);
}, },
spendHashes: spendHashes:
(ctx) => (ctx) =>
@ -219,7 +219,7 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
}, },
getHashUpgradeLevel: (ctx) => (_upgName) => { getHashUpgradeLevel: (ctx) => (_upgName) => {
const upgName = helpers.string(ctx, "upgName", _upgName); const upgName = helpers.string(ctx, "upgName", _upgName);
const level = player.hashManager.upgrades[upgName]; const level = Player.hashManager.upgrades[upgName];
if (level === undefined) { if (level === undefined) {
throw helpers.errorMessage(ctx, `Invalid Hash Upgrade: ${upgName}`); throw helpers.errorMessage(ctx, `Invalid Hash Upgrade: ${upgName}`);
} }
@ -229,13 +229,13 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 1; return 1;
} }
return player.hashManager.getStudyMult(); return Player.hashManager.getStudyMult();
}, },
getTrainingMult: () => () => { getTrainingMult: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 1; return 1;
} }
return player.hashManager.getTrainingMult(); return Player.hashManager.getTrainingMult();
}, },
}; };
} }

@ -1,4 +1,4 @@
import { Player } from "../Player"; import { Player } from "@player";
import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling"; import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling";
import { import {
StockMarket, StockMarket,

@ -8181,6 +8181,14 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
* ``` * ```
*/ */
nextUpdate(): Promise<CorpStateName>; nextUpdate(): Promise<CorpStateName>;
/**
* Sell a division
* @remarks
* RAM cost: 20 GB
*
* @param divisionName - Name of the division */
sellDivision(divisionName: string): void;
} }
/** Product rating information /** Product rating information