diff --git a/markdown/bitburner.corporation.cancreatecorporation.md b/markdown/bitburner.corporation.cancreatecorporation.md new file mode 100644 index 000000000..0b769e4c1 --- /dev/null +++ b/markdown/bitburner.corporation.cancreatecorporation.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [Corporation](./bitburner.corporation.md) > [canCreateCorporation](./bitburner.corporation.cancreatecorporation.md) + +## Corporation.canCreateCorporation() method + +Return whether the player can create a corporation. Does not require API access. + +**Signature:** + +```typescript +canCreateCorporation(selfFund: boolean): CreatingCorporationCheckResult; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| selfFund | boolean | true if you want to self-fund, false otherwise | + +**Returns:** + +[CreatingCorporationCheckResult](./bitburner.creatingcorporationcheckresult.md) + +Result of the check + +## Remarks + +RAM cost: 0 GB + diff --git a/markdown/bitburner.corporation.createcorporation.md b/markdown/bitburner.corporation.createcorporation.md index 84dbf33c6..c1ce111f2 100644 --- a/markdown/bitburner.corporation.createcorporation.md +++ b/markdown/bitburner.corporation.createcorporation.md @@ -4,7 +4,11 @@ ## Corporation.createCorporation() method -Create a Corporation. +Create a Corporation. You should use [canCreateCorporation](./bitburner.corporation.cancreatecorporation.md) to check if you are unsure you can do it, because it throws an error in these cases: + +- Use seed money outside BitNode 3. + +- Be in a BitNode that has CorporationSoftcap (a BitNode modifier) less than 0.15. **Signature:** @@ -16,7 +20,7 @@ createCorporation(corporationName: string, selfFund: boolean): boolean; | Parameter | Type | Description | | --- | --- | --- | -| corporationName | string | Name of the corporation | +| corporationName | string | Name of the corporation. It must be a non-empty string. | | selfFund | boolean | If you want to self-fund. Defaults to true, false will only work in BitNode 3. | **Returns:** @@ -29,9 +33,3 @@ true if created and false if not RAM cost: 20 GB -This function throws an error if: - -- Use seed money outside BitNode 3. - -- Be in a BitNode that has CorporationSoftcap (a BN modifier) less than 0.15. Use [getBitNodeMultipliers](./bitburner.ns.getbitnodemultipliers.md) to get the value of this modifier. - diff --git a/markdown/bitburner.corporation.hascorporation.md b/markdown/bitburner.corporation.hascorporation.md index a7e4a1be3..2db2464ed 100644 --- a/markdown/bitburner.corporation.hascorporation.md +++ b/markdown/bitburner.corporation.hascorporation.md @@ -4,7 +4,7 @@ ## Corporation.hasCorporation() method -Returns whether the player has a corporation. Does not require API access. +Return whether the player has a corporation. Does not require API access. **Signature:** diff --git a/markdown/bitburner.corporation.md b/markdown/bitburner.corporation.md index 49cb2eb6d..c6c615868 100644 --- a/markdown/bitburner.corporation.md +++ b/markdown/bitburner.corporation.md @@ -20,7 +20,8 @@ export interface Corporation extends WarehouseAPI, OfficeAPI | [acceptInvestmentOffer()](./bitburner.corporation.acceptinvestmentoffer.md) | Accept the investment offer. The value of offer is based on current corporation valuation. | | [bribe(factionName, amountCash)](./bitburner.corporation.bribe.md) | Bribe a faction. | | [buyBackShares(amount)](./bitburner.corporation.buybackshares.md) | Buyback shares. Spend money from the player's wallet to transfer shares from public traders to the CEO. | -| [createCorporation(corporationName, selfFund)](./bitburner.corporation.createcorporation.md) | Create a Corporation. | +| [canCreateCorporation(selfFund)](./bitburner.corporation.cancreatecorporation.md) | Return whether the player can create a corporation. Does not require API access. | +| [createCorporation(corporationName, selfFund)](./bitburner.corporation.createcorporation.md) |

Create a Corporation. You should use [canCreateCorporation](./bitburner.corporation.cancreatecorporation.md) to check if you are unsure you can do it, because it throws an error in these cases:

- Use seed money outside BitNode 3.

- Be in a BitNode that has CorporationSoftcap (a BitNode modifier) less than 0.15.

| | [expandCity(divisionName, city)](./bitburner.corporation.expandcity.md) | Expand to a new city. | | [expandIndustry(industryType, divisionName)](./bitburner.corporation.expandindustry.md) | Expand to a new industry. | | [getBonusTime()](./bitburner.corporation.getbonustime.md) | Get bonus time. Bonus time is accumulated when the game is offline or if the game is inactive in the browser. Bonus time makes the corporation progress faster. | @@ -34,7 +35,7 @@ export interface Corporation extends WarehouseAPI, OfficeAPI | [getUpgradeLevel(upgradeName)](./bitburner.corporation.getupgradelevel.md) | Get the level of a levelable upgrade. | | [getUpgradeLevelCost(upgradeName)](./bitburner.corporation.getupgradelevelcost.md) | Get the cost to unlock the next level of a levelable upgrade. | | [goPublic(numShares)](./bitburner.corporation.gopublic.md) | Go public. | -| [hasCorporation()](./bitburner.corporation.hascorporation.md) | Returns whether the player has a corporation. Does not require API access. | +| [hasCorporation()](./bitburner.corporation.hascorporation.md) | Return whether the player has a corporation. Does not require API access. | | [hasUnlock(upgradeName)](./bitburner.corporation.hasunlock.md) | Check if you have a one-time unlockable upgrade. | | [issueDividends(rate)](./bitburner.corporation.issuedividends.md) | Issue dividends. | | [issueNewShares(amount)](./bitburner.corporation.issuenewshares.md) | Issue new shares. | diff --git a/markdown/bitburner.creatingcorporationcheckresult.md b/markdown/bitburner.creatingcorporationcheckresult.md new file mode 100644 index 000000000..16bb82a31 --- /dev/null +++ b/markdown/bitburner.creatingcorporationcheckresult.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [CreatingCorporationCheckResult](./bitburner.creatingcorporationcheckresult.md) + +## CreatingCorporationCheckResult enum + + +**Signature:** + +```typescript +declare enum CreatingCorporationCheckResult +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| CorporationExists | "CorporationExists" | | +| DisabledBySoftCap | "DisabledBySoftCap" | | +| NoSf3OrDisabled | "NoSf3OrDisabled" | | +| Success | "Success" | | +| UseSeedMoneyOutsideBN3 | "UseSeedMoneyOutsideBN3" | | + diff --git a/markdown/bitburner.md b/markdown/bitburner.md index ca8aedde8..9da4d77e1 100644 --- a/markdown/bitburner.md +++ b/markdown/bitburner.md @@ -16,6 +16,7 @@ | [BladeburnerSkillName](./bitburner.bladeburnerskillname.md) | Skill names type of Bladeburner | | [CityName](./bitburner.cityname.md) | Names of all cities | | [CompanyName](./bitburner.companyname.md) | Names of all companies | +| [CreatingCorporationCheckResult](./bitburner.creatingcorporationcheckresult.md) | | | [CrimeType](./bitburner.crimetype.md) | | | [FactionWorkType](./bitburner.factionworktype.md) | | | [GymLocationName](./bitburner.gymlocationname.md) | Locations of gym | diff --git a/src/Corporation/Actions.ts b/src/Corporation/Actions.ts index bcb6e395d..06ef0d8ec 100644 --- a/src/Corporation/Actions.ts +++ b/src/Corporation/Actions.ts @@ -10,7 +10,7 @@ import { OfficeSpace } from "./OfficeSpace"; import { Material } from "./Material"; import { Product } from "./Product"; import { Warehouse } from "./Warehouse"; -import { FactionName, IndustryType } from "@enums"; +import { CreatingCorporationCheckResult, FactionName, IndustryType } from "@enums"; import { ResearchMap } from "./ResearchMap"; import { isRelevantMaterial } from "./ui/Helpers"; import { CityName } from "@enums"; @@ -22,27 +22,32 @@ import { buybackSharesFailureReason, issueNewSharesFailureReason, costOfCreatingCorporation, + canCreateCorporation, } from "./helpers"; import { PositiveInteger } from "../types"; -import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Factions } from "../Faction/Factions"; export function createCorporation(corporationName: string, selfFund: boolean, restart: boolean): boolean { - if (!Player.canAccessCorporation()) { - return false; - } - if (Player.corporation && !restart) { - return false; + const checkResult = canCreateCorporation(selfFund, restart); + switch (checkResult) { + case CreatingCorporationCheckResult.Success: + break; + case CreatingCorporationCheckResult.NoSf3OrDisabled: + case CreatingCorporationCheckResult.CorporationExists: + return false; + case CreatingCorporationCheckResult.UseSeedMoneyOutsideBN3: + case CreatingCorporationCheckResult.DisabledBySoftCap: + // In order to maintaining backward compatibility, we have to throw an error in these cases. + throw new Error(checkResult); + default: { + // Verify if switch statement is exhaustive + checkResult satisfies never; + } } + 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); diff --git a/src/Corporation/Enums.ts b/src/Corporation/Enums.ts index fa852a6d5..7aaa576c3 100644 --- a/src/Corporation/Enums.ts +++ b/src/Corporation/Enums.ts @@ -109,3 +109,11 @@ export type CorpProductResearchName = Member; export const CorpResearchName = { ...CorpProductResearchName, ...CorpBaseResearchName }; export type CorpResearchName = Member; + +export enum CreatingCorporationCheckResult { + Success = "Success", + NoSf3OrDisabled = "NoSf3OrDisabled", + CorporationExists = "CorporationExists", + UseSeedMoneyOutsideBN3 = "UseSeedMoneyOutsideBN3", + DisabledBySoftCap = "DisabledBySoftCap", +} diff --git a/src/Corporation/helpers.ts b/src/Corporation/helpers.ts index c9a431e11..f6ada84d0 100644 --- a/src/Corporation/helpers.ts +++ b/src/Corporation/helpers.ts @@ -4,6 +4,44 @@ import { formatShares } from "../ui/formatNumber"; import { Corporation } from "./Corporation"; import { CorpUpgrade } from "./data/CorporationUpgrades"; import * as corpConstants from "./data/Constants"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; +import { CreatingCorporationCheckResult } from "@enums"; + +export function convertCreatingCorporationCheckResultToMessage(checkResult: CreatingCorporationCheckResult): string { + switch (checkResult) { + case CreatingCorporationCheckResult.Success: + return "Success"; + case CreatingCorporationCheckResult.NoSf3OrDisabled: + return "You don't have SF3 or Corporation is disabled by an advanced option"; + case CreatingCorporationCheckResult.CorporationExists: + return "Corporation exists"; + case CreatingCorporationCheckResult.UseSeedMoneyOutsideBN3: + return "You cannot use seed money outside BitNode 3"; + case CreatingCorporationCheckResult.DisabledBySoftCap: + return "You cannot create a corporation in this BitNode"; + default: { + // Verify if switch statement is exhaustive + checkResult satisfies never; + } + } + return String(checkResult); +} + +export function canCreateCorporation(selfFund: boolean, restart: boolean): CreatingCorporationCheckResult { + if (!Player.canAccessCorporation()) { + return CreatingCorporationCheckResult.NoSf3OrDisabled; + } + if (Player.corporation && !restart) { + return CreatingCorporationCheckResult.CorporationExists; + } + if (Player.bitNodeN !== 3 && !selfFund) { + return CreatingCorporationCheckResult.UseSeedMoneyOutsideBN3; + } + if (currentNodeMults.CorporationSoftcap < 0.15) { + return CreatingCorporationCheckResult.DisabledBySoftCap; + } + return CreatingCorporationCheckResult.Success; +} export function costOfCreatingCorporation(restart: boolean): number { if (restart && !Player.corporation?.seedFunded) { diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index 90d212d3e..eaf8360c3 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -399,6 +399,7 @@ const grafting = { const corporation = { hasCorporation: 0, + canCreateCorporation: 0, createCorporation: RamCostConstants.CorporationAction, hasUnlock: RamCostConstants.CorporationInfo, getUnlockCost: RamCostConstants.CorporationInfo, diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 2cd5b2426..ffb46317b 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -56,7 +56,7 @@ import { } from "../Corporation/Actions"; import { CorpUnlocks } from "../Corporation/data/CorporationUnlocks"; import { CorpUpgrades } from "../Corporation/data/CorporationUpgrades"; -import { CorpUnlockName, CorpUpgradeName, CorpEmployeeJob, CityName } from "@enums"; +import { CorpUnlockName, CorpUpgradeName, CorpEmployeeJob, CityName, CreatingCorporationCheckResult } from "@enums"; import { IndustriesData, IndustryResearchTrees } from "../Corporation/data/IndustryData"; import * as corpConstants from "../Corporation/data/Constants"; import { ResearchMap } from "../Corporation/ResearchMap"; @@ -64,7 +64,12 @@ import { InternalAPI, NetscriptContext, setRemovedFunctions } from "../Netscript import { helpers } from "../Netscript/NetscriptHelpers"; import { getEnumHelper } from "../utils/EnumHelper"; import { MaterialInfo } from "../Corporation/MaterialInfo"; -import { calculateOfficeSizeUpgradeCost, calculateUpgradeCost } from "../Corporation/helpers"; +import { + calculateOfficeSizeUpgradeCost, + calculateUpgradeCost, + canCreateCorporation, + convertCreatingCorporationCheckResultToMessage, +} from "../Corporation/helpers"; import { PositiveInteger } from "../types"; import { getRecordKeys } from "../Types/Record"; @@ -588,6 +593,21 @@ export function NetscriptCorporation(): InternalAPI { ...warehouseAPI, ...officeAPI, hasCorporation: () => () => !!Player.corporation, + canCreateCorporation: (ctx) => (_selfFund) => { + const selfFund = !!_selfFund; + const checkResult = canCreateCorporation(selfFund, false); + if (checkResult !== CreatingCorporationCheckResult.Success) { + helpers.log(ctx, () => convertCreatingCorporationCheckResultToMessage(checkResult)); + } + return checkResult; + }, + createCorporation: + (ctx) => + (_corporationName, _selfFund = true): boolean => { + const corporationName = helpers.string(ctx, "corporationName", _corporationName); + const selfFund = !!_selfFund; + return createCorporation(corporationName, selfFund, false); + }, getConstants: () => () => { /* TODO 2.2: possibly just rework the whole corp constants structure to be more readable, and just use * structuredClone to provide it directly to player. @@ -691,13 +711,6 @@ export function NetscriptCorporation(): InternalAPI { }); return data; }, - createCorporation: - (ctx) => - (_corporationName, _selfFund = true): boolean => { - const corporationName = helpers.string(ctx, "corporationName", _corporationName); - const selfFund = !!_selfFund; - return createCorporation(corporationName, selfFund, false); - }, hasUnlock: (ctx) => (_unlockName) => { checkAccess(ctx); const unlockName = getEnumHelper("CorpUnlockName").nsGetMember(ctx, _unlockName, "unlockName"); diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index e4e2560dc..b20c26cca 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -8673,13 +8673,24 @@ export interface WarehouseAPI { hasWarehouse(divisionName: string, city: CityName | `${CityName}`): boolean; } +/** + * @public + */ +declare enum CreatingCorporationCheckResult { + Success = "Success", + NoSf3OrDisabled = "NoSf3OrDisabled", + CorporationExists = "CorporationExists", + UseSeedMoneyOutsideBN3 = "UseSeedMoneyOutsideBN3", + DisabledBySoftCap = "DisabledBySoftCap", +} + /** * Corporation API * @public */ export interface Corporation extends WarehouseAPI, OfficeAPI { /** - * Returns whether the player has a corporation. Does not require API access. + * Return whether the player has a corporation. Does not require API access. * * @remarks * RAM cost: 0 GB @@ -8689,19 +8700,28 @@ export interface Corporation extends WarehouseAPI, OfficeAPI { hasCorporation(): boolean; /** - * Create a Corporation. + * Return whether the player can create a corporation. Does not require API access. * * @remarks - * RAM cost: 20 GB + * RAM cost: 0 GB * - * This function throws an error if: + * @param selfFund - true if you want to self-fund, false otherwise + * @returns Result of the check + */ + canCreateCorporation(selfFund: boolean): CreatingCorporationCheckResult; + + /** + * Create a Corporation. You should use {@link Corporation.canCreateCorporation | canCreateCorporation} to check if + * you are unsure you can do it, because it throws an error in these cases: * * - Use seed money outside BitNode 3. * - * - Be in a BitNode that has CorporationSoftcap (a BN modifier) less than 0.15. Use - * {@link NS.getBitNodeMultipliers | getBitNodeMultipliers} to get the value of this modifier. + * - Be in a BitNode that has CorporationSoftcap (a BitNode modifier) less than 0.15. + * + * @remarks + * RAM cost: 20 GB * - * @param corporationName - Name of the corporation + * @param corporationName - Name of the corporation. It must be a non-empty string. * @param selfFund - If you want to self-fund. Defaults to true, false will only work in BitNode 3. * @returns true if created and false if not */