CORPORATION: Add new API to check if player can create corporation (#1598)

* CORPORATION: Add new API to check if player can create corporation
* Update description of createCorporation API
* Return enum instead of true/false
* Use throwIfReachable
* Fix typo in comment
This commit is contained in:
catloversg 2024-12-01 12:49:19 +07:00 committed by GitHub
parent 67704f2ab0
commit 6e1848dd79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 179 additions and 43 deletions

@ -0,0 +1,30 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Corporation](./bitburner.corporation.md) &gt; [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

@ -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.

@ -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:**

@ -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) | <p>Bribe a faction. You must satisfy these conditions:</p><p>- The corporation valuation must be greater than or equal to a threshold. You can use [getCorporation](./bitburner.corporation.getcorporation.md) and [getConstants](./bitburner.corporation.getconstants.md) to get this information.</p><p>- The specified faction must offer at least 1 type of work. You can use [getFactionWorkTypes](./bitburner.singularity.getfactionworktypes.md) to get the list of work types of a faction.</p> |
| [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) | <p>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:</p><p>- Use seed money outside BitNode 3.</p><p>- Be in a BitNode that has CorporationSoftcap (a BitNode modifier) less than 0.15.</p> |
| [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. |

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [CreatingCorporationCheckResult](./bitburner.creatingcorporationcheckresult.md)
## CreatingCorporationCheckResult enum
**Signature:**
```typescript
declare enum CreatingCorporationCheckResult
```
## Enumeration Members
| Member | Value | Description |
| --- | --- | --- |
| CorporationExists | <code>&quot;CorporationExists&quot;</code> | |
| DisabledBySoftCap | <code>&quot;DisabledBySoftCap&quot;</code> | |
| NoSf3OrDisabled | <code>&quot;NoSf3OrDisabled&quot;</code> | |
| Success | <code>&quot;Success&quot;</code> | |
| UseSeedMoneyOutsideBN3 | <code>&quot;UseSeedMoneyOutsideBN3&quot;</code> | |

@ -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 |

@ -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,31 @@ import {
buybackSharesFailureReason,
issueNewSharesFailureReason,
costOfCreatingCorporation,
canCreateCorporation,
} from "./helpers";
import { PositiveInteger, Result } from "../types";
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
import { Factions } from "../Faction/Factions";
import { throwIfReachable } from "../utils/helpers/throwIfReachable";
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 maintain backward compatibility, we have to throw an error in these cases.
throw new Error(checkResult);
default:
throwIfReachable(checkResult);
}
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);

@ -109,3 +109,11 @@ export type CorpProductResearchName = Member<typeof CorpProductResearchName>;
export const CorpResearchName = { ...CorpProductResearchName, ...CorpBaseResearchName };
export type CorpResearchName = Member<typeof CorpResearchName>;
export enum CreatingCorporationCheckResult {
Success = "Success",
NoSf3OrDisabled = "NoSf3OrDisabled",
CorporationExists = "CorporationExists",
UseSeedMoneyOutsideBN3 = "UseSeedMoneyOutsideBN3",
DisabledBySoftCap = "DisabledBySoftCap",
}

@ -4,6 +4,43 @@ 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";
import { throwIfReachable } from "../utils/helpers/throwIfReachable";
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:
throwIfReachable(checkResult);
}
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) {

@ -400,6 +400,7 @@ const grafting = {
const corporation = {
hasCorporation: 0,
canCreateCorporation: 0,
createCorporation: RamCostConstants.CorporationAction,
hasUnlock: RamCostConstants.CorporationInfo,
getUnlockCost: RamCostConstants.CorporationInfo,

@ -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<NSCorporation> {
...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.
@ -696,13 +716,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
});
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");

@ -8782,13 +8782,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
@ -8798,19 +8809,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: 0 GB
*
* @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 BitNode modifier) less than 0.15.
*
* @remarks
* 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
* {@link NS.getBitNodeMultipliers | getBitNodeMultipliers} to get the value of this modifier.
*
* @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
*/