Merge branch 'dev' of github.com:danielyxie/bitburner into dev

This commit is contained in:
Olivier Gagnon 2022-01-18 18:57:55 -05:00
commit d2ec38753b
74 changed files with 2881 additions and 155 deletions

164
dist/bitburner.d.ts vendored

@ -852,6 +852,74 @@ export declare interface CodingContract {
* @public * @public
*/ */
export declare interface Corporation extends WarehouseAPI, OfficeAPI { export declare interface Corporation extends WarehouseAPI, OfficeAPI {
/**
* 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
*/
createCorporation(corporationName: string, selfFund: boolean): boolean;
/**
* Check if you have a one time unlockable upgrade
* @param upgradeName - Name of the upgrade
* @returns true if unlocked and false if not
*/
hasUnlockUpgrade(upgradeName: string): boolean;
/**
* Gets the cost to unlock a one time unlockable upgrade
* @param upgradeName - Name of the upgrade
* @returns cost of the upgrade
*/
getUnlockUpgradeCost(upgradeName: string): number;
/**
* Get the level of a levelable upgrade
* @param upgradeName - Name of the upgrade
* @returns the level of the upgrade
*/
getUpgradeLevel(upgradeName: string): number;
/**
* Gets the cost to unlock the next level of a levelable upgrade
* @param upgradeName - Name of the upgrade
* @returns cost of the upgrade
*/
getUpgradeLevelCost(upgradeName: string): number;
/**
* Gets the cost to expand into a new industry
* @param industryName - Name of the industry
* @returns cost
*/
getExpandIndustryCost(industryName: string): number;
/**
* Gets the cost to expand into a new city
* @returns cost
*/
getExpandCityCost(): number;
/**
* Get an offer for investment based on you companies current valuation
* @returns An offer of investment
*/
getInvestmentOffer(): InvestmentOffer;
/**
* Accept investment based on you companies current valuation
* @remarks
* Is based on current valuation and will not honer a specific Offer
* @returns An offer of investment
*/
acceptInvestmentOffer(): boolean;
/**
* Go public
* @param numShares - number of shares you would like to issue for your IPO
* @returns true if you successfully go public, false if not
*/
goPublic(numShares: number): boolean;
/**
* Bribe a faction
* @param factionName - Faction name
* @param amountCash - Amount of money to bribe
* @param amountShares - Amount of shares to bribe
* @returns True if successful, false if not
*/
bribe(factionName: string, amountCash: number, amountShares: number): boolean;
/** /**
* Get corporation data * Get corporation data
* @returns Corporation data * @returns Corporation data
@ -876,7 +944,7 @@ export declare interface Corporation extends WarehouseAPI, OfficeAPI {
*/ */
expandCity(divisionName: string, cityName: string): void; expandCity(divisionName: string, cityName: string): void;
/** /**
* Unlock an upgrade. * Unlock an upgrade
* @param upgradeName - Name of the upgrade * @param upgradeName - Name of the upgrade
*/ */
unlockUpgrade(upgradeName: string): void; unlockUpgrade(upgradeName: string): void;
@ -919,6 +987,8 @@ export declare interface CorporationInfo {
sharePrice: number; sharePrice: number;
/** State of the corporation. Possible states are START, PURCHASE, PRODUCTION, SALE, EXPORT. */ /** State of the corporation. Possible states are START, PURCHASE, PRODUCTION, SALE, EXPORT. */
state: string; state: string;
/** Array of all divisions */
divisions: Division[];
} }
/** /**
@ -997,6 +1067,8 @@ export declare interface Division {
upgrades: number[]; upgrades: number[];
/** Cities in which this division has expanded */ /** Cities in which this division has expanded */
cities: string[]; cities: string[];
/** Products developed by this division */
products: string[];
} }
/** /**
@ -2223,6 +2295,19 @@ export declare interface HacknetServersFormulas {
constants(): HacknetServerConstants; constants(): HacknetServerConstants;
} }
/**
* Corporation investment offer
* @public
*/
export declare interface InvestmentOffer {
/** Amount of funds you will get from this investment */
funds: number;
/** Amount of share you will give in exchange for this investment */
shares: number;
/** Current round of funding (max 4) */
round: number;
}
/** /**
* Interface Styles * Interface Styles
* @internal * @internal
@ -2243,6 +2328,10 @@ export declare interface Material {
qty: number; qty: number;
/** Quality of the material */ /** Quality of the material */
qlt: number; qlt: number;
/** Amount of material produced */
prod: number;
/** Amount of material sold */
sell: number;
} }
/** /**
@ -4401,7 +4490,7 @@ export declare interface OfficeAPI {
*/ */
assignJob(divisionName: string, cityName: string, employeeName: string, job: string): Promise<void>; assignJob(divisionName: string, cityName: string, employeeName: string, job: string): Promise<void>;
/** /**
* Assign an employee to a job. * Hire an employee.
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param cityName - Name of the city * @param cityName - Name of the city
* @returns The newly hired employee, if any * @returns The newly hired employee, if any
@ -4415,7 +4504,7 @@ export declare interface OfficeAPI {
*/ */
upgradeOfficeSize(divisionName: string, cityName: string, size: number): void; upgradeOfficeSize(divisionName: string, cityName: string, size: number): void;
/** /**
* Assign an employee to a job. * Throw a party for your employees
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param cityName - Name of the city * @param cityName - Name of the city
* @param costPerEmployee - Amount to spend per employee. * @param costPerEmployee - Amount to spend per employee.
@ -4435,7 +4524,7 @@ export declare interface OfficeAPI {
*/ */
hireAdVert(divisionName: string): void; hireAdVert(divisionName: string): void;
/** /**
* Hire AdVert. * Purchase a research
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param researchName - Name of the research * @param researchName - Name of the research
*/ */
@ -4455,6 +4544,49 @@ export declare interface OfficeAPI {
* @returns Employee data * @returns Employee data
*/ */
getEmployee(divisionName: string, cityName: string, employeeName: string): Employee; getEmployee(divisionName: string, cityName: string, employeeName: string): Employee;
/**
* Get the cost to Hire AdVert
* @param divisionName - Name of the division
* @returns Cost
*/
getHireAdVertCost(divisionName: string): number;
/**
* Get the number of times you have Hired AdVert
* @param divisionName - Name of the division
* @returns Number of times you have Hired AdVert
*/
getHireAdVertCount(adivisionName: string): number;
/**
* Get the cost to unlock research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns cost
*/
getResearchCost(divisionName: string, researchName: string): number;
/**
* Gets if you have unlocked a research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns true is unlocked, false if not
*/
hasResearched(divisionName: string, researchName: string): boolean;
/**
* Set the auto job assignment for a job
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @param job - Name of the job
* @param amount - Number of employees to assign to that job
* @returns A promise that is fulfilled when the assignment is complete.
*/
setAutoJobAssignment(divisionName: string, cityName: string, job: string, amount: number): Promise<boolean>;
/**
* Cost to Upgrade office size.
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @param size - Amount of positions to open
* @returns Cost of upgrading the office
*/
getOfficeSizeUpgradeCost(divisionName: string, cityName: string, asize: number): number;
} }
/** /**
@ -4557,6 +4689,7 @@ export declare interface Player {
jobs: any; jobs: any;
factions: string[]; factions: string[];
tor: boolean; tor: boolean;
hasCorporation: boolean;
} }
/** /**
@ -4618,6 +4751,12 @@ export declare interface Product {
pCost: number; pCost: number;
/** Sell cost, can be "MP+5" */ /** Sell cost, can be "MP+5" */
sCost: string | number; sCost: string | number;
/** Data refers to the production, sale, and quantity of the products
* These values are specific to a city
* For each city, the data is [qty, prod, sell] */
cityData: {[key: string]:number[]};
/** Creation progress - A number between 0-100 representing percentage */
developmentProgress: number;
} }
/** /**
@ -6435,6 +6574,8 @@ export declare interface Warehouse {
size: number; size: number;
/** Used space in the warehouse */ /** Used space in the warehouse */
sizeUsed: number; sizeUsed: number;
/** Smart Supply status in the warehouse */
smartSupplyEnabled: boolean;
} }
/** /**
@ -6603,6 +6744,21 @@ export declare interface WarehouseAPI {
designInvest: number, designInvest: number,
marketingInvest: number, marketingInvest: number,
): void; ): void;
/**
* Gets the cost to purchase a warehouse
* @returns cost
*/
getPurchaseWarehouseCost(): number;
/**
* Gets the cost to upgrade a warehouse to the next level
* @returns cost to upgrade
*/
getUpgradeWarehouseCost(adivisionName: any, acityName: any): number;
/**
* Check if you have a warehouse in city
* @returns true if warehouse is present, false if not
*/
hasWarehouse(adivisionName: any, acityName: any): boolean;
} }
export { } export { }

28
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,23 @@
<!-- 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; [acceptInvestmentOffer](./bitburner.corporation.acceptinvestmentoffer.md)
## Corporation.acceptInvestmentOffer() method
Accept investment based on you companies current valuation
<b>Signature:</b>
```typescript
acceptInvestmentOffer(): boolean;
```
<b>Returns:</b>
boolean
An offer of investment
## Remarks
Is based on current valuation and will not honer a specific Offer

@ -0,0 +1,28 @@
<!-- 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; [bribe](./bitburner.corporation.bribe.md)
## Corporation.bribe() method
Bribe a faction
<b>Signature:</b>
```typescript
bribe(factionName: string, amountCash: number, amountShares: number): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| factionName | string | Faction name |
| amountCash | number | Amount of money to bribe |
| amountShares | number | Amount of shares to bribe |
<b>Returns:</b>
boolean
True if successful, false if not

@ -0,0 +1,27 @@
<!-- 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; [createCorporation](./bitburner.corporation.createcorporation.md)
## Corporation.createCorporation() method
Create a Corporation
<b>Signature:</b>
```typescript
createCorporation(corporationName: string, selfFund: boolean): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| corporationName | string | |
| selfFund | boolean | If you should self fund, defaults to true, false will only work on Bitnode 3 |
<b>Returns:</b>
boolean
true if created and false if not

@ -0,0 +1,19 @@
<!-- 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; [getExpandCityCost](./bitburner.corporation.getexpandcitycost.md)
## Corporation.getExpandCityCost() method
Gets the cost to expand into a new city
<b>Signature:</b>
```typescript
getExpandCityCost(): number;
```
<b>Returns:</b>
number
cost

@ -0,0 +1,26 @@
<!-- 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; [getExpandIndustryCost](./bitburner.corporation.getexpandindustrycost.md)
## Corporation.getExpandIndustryCost() method
Gets the cost to expand into a new industry
<b>Signature:</b>
```typescript
getExpandIndustryCost(industryName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| industryName | string | Name of the industry |
<b>Returns:</b>
number
cost

@ -0,0 +1,19 @@
<!-- 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; [getInvestmentOffer](./bitburner.corporation.getinvestmentoffer.md)
## Corporation.getInvestmentOffer() method
Get an offer for investment based on you companies current valuation
<b>Signature:</b>
```typescript
getInvestmentOffer(): InvestmentOffer;
```
<b>Returns:</b>
[InvestmentOffer](./bitburner.investmentoffer.md)
An offer of investment

@ -0,0 +1,26 @@
<!-- 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; [getUnlockUpgradeCost](./bitburner.corporation.getunlockupgradecost.md)
## Corporation.getUnlockUpgradeCost() method
Gets the cost to unlock a one time unlockable upgrade
<b>Signature:</b>
```typescript
getUnlockUpgradeCost(upgradeName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| upgradeName | string | Name of the upgrade |
<b>Returns:</b>
number
cost of the upgrade

@ -0,0 +1,26 @@
<!-- 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; [getUpgradeLevel](./bitburner.corporation.getupgradelevel.md)
## Corporation.getUpgradeLevel() method
Get the level of a levelable upgrade
<b>Signature:</b>
```typescript
getUpgradeLevel(upgradeName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| upgradeName | string | Name of the upgrade |
<b>Returns:</b>
number
the level of the upgrade

@ -0,0 +1,26 @@
<!-- 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; [getUpgradeLevelCost](./bitburner.corporation.getupgradelevelcost.md)
## Corporation.getUpgradeLevelCost() method
Gets the cost to unlock the next level of a levelable upgrade
<b>Signature:</b>
```typescript
getUpgradeLevelCost(upgradeName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| upgradeName | string | Name of the upgrade |
<b>Returns:</b>
number
cost of the upgrade

@ -0,0 +1,26 @@
<!-- 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; [goPublic](./bitburner.corporation.gopublic.md)
## Corporation.goPublic() method
Go public
<b>Signature:</b>
```typescript
goPublic(numShares: number): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| numShares | number | number of shares you would like to issue for your IPO |
<b>Returns:</b>
boolean
true if you successfully go public, false if not

@ -0,0 +1,26 @@
<!-- 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; [hasUnlockUpgrade](./bitburner.corporation.hasunlockupgrade.md)
## Corporation.hasUnlockUpgrade() method
Check if you have a one time unlockable upgrade
<b>Signature:</b>
```typescript
hasUnlockUpgrade(upgradeName: string): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| upgradeName | string | Name of the upgrade |
<b>Returns:</b>
boolean
true if unlocked and false if not

@ -17,11 +17,22 @@ export interface Corporation extends WarehouseAPI, OfficeAPI
| Method | Description | | Method | Description |
| --- | --- | | --- | --- |
| [acceptInvestmentOffer()](./bitburner.corporation.acceptinvestmentoffer.md) | Accept investment based on you companies current valuation |
| [bribe(factionName, amountCash, amountShares)](./bitburner.corporation.bribe.md) | Bribe a faction |
| [createCorporation(corporationName, selfFund)](./bitburner.corporation.createcorporation.md) | Create a Corporation |
| [expandCity(divisionName, cityName)](./bitburner.corporation.expandcity.md) | Expand to a new city | | [expandCity(divisionName, cityName)](./bitburner.corporation.expandcity.md) | Expand to a new city |
| [expandIndustry(industryType, divisionName)](./bitburner.corporation.expandindustry.md) | Expand to a new industry | | [expandIndustry(industryType, divisionName)](./bitburner.corporation.expandindustry.md) | Expand to a new industry |
| [getCorporation()](./bitburner.corporation.getcorporation.md) | Get corporation data | | [getCorporation()](./bitburner.corporation.getcorporation.md) | Get corporation data |
| [getDivision(divisionName)](./bitburner.corporation.getdivision.md) | Get division data | | [getDivision(divisionName)](./bitburner.corporation.getdivision.md) | Get division data |
| [getExpandCityCost()](./bitburner.corporation.getexpandcitycost.md) | Gets the cost to expand into a new city |
| [getExpandIndustryCost(industryName)](./bitburner.corporation.getexpandindustrycost.md) | Gets the cost to expand into a new industry |
| [getInvestmentOffer()](./bitburner.corporation.getinvestmentoffer.md) | Get an offer for investment based on you companies current valuation |
| [getUnlockUpgradeCost(upgradeName)](./bitburner.corporation.getunlockupgradecost.md) | Gets the cost to unlock a one time unlockable upgrade |
| [getUpgradeLevel(upgradeName)](./bitburner.corporation.getupgradelevel.md) | Get the level of a levelable upgrade |
| [getUpgradeLevelCost(upgradeName)](./bitburner.corporation.getupgradelevelcost.md) | Gets the cost to unlock the next level of a levelable upgrade |
| [goPublic(numShares)](./bitburner.corporation.gopublic.md) | Go public |
| [hasUnlockUpgrade(upgradeName)](./bitburner.corporation.hasunlockupgrade.md) | Check if you have a one time unlockable upgrade |
| [issueDividends(percent)](./bitburner.corporation.issuedividends.md) | Issue dividends | | [issueDividends(percent)](./bitburner.corporation.issuedividends.md) | Issue dividends |
| [levelUpgrade(upgradeName)](./bitburner.corporation.levelupgrade.md) | Level an upgrade. | | [levelUpgrade(upgradeName)](./bitburner.corporation.levelupgrade.md) | Level an upgrade. |
| [unlockUpgrade(upgradeName)](./bitburner.corporation.unlockupgrade.md) | Unlock an upgrade. | | [unlockUpgrade(upgradeName)](./bitburner.corporation.unlockupgrade.md) | Unlock an upgrade |

@ -4,7 +4,7 @@
## Corporation.unlockUpgrade() method ## Corporation.unlockUpgrade() method
Unlock an upgrade. Unlock an upgrade
<b>Signature:</b> <b>Signature:</b>

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [CorporationInfo](./bitburner.corporationinfo.md) &gt; [divisions](./bitburner.corporationinfo.divisions.md)
## CorporationInfo.divisions property
Array of all divisions
<b>Signature:</b>
```typescript
divisions: Division[];
```

@ -16,6 +16,7 @@ interface CorporationInfo
| Property | Type | Description | | Property | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| [divisions](./bitburner.corporationinfo.divisions.md) | [Division](./bitburner.division.md)<!-- -->\[\] | Array of all divisions |
| [expenses](./bitburner.corporationinfo.expenses.md) | number | Expenses per second this cycle | | [expenses](./bitburner.corporationinfo.expenses.md) | number | Expenses per second this cycle |
| [funds](./bitburner.corporationinfo.funds.md) | number | Funds available | | [funds](./bitburner.corporationinfo.funds.md) | number | Funds available |
| [issuedShares](./bitburner.corporationinfo.issuedshares.md) | number | Amount of shares issued | | [issuedShares](./bitburner.corporationinfo.issuedshares.md) | number | Amount of shares issued |

@ -23,6 +23,7 @@ interface Division
| [name](./bitburner.division.name.md) | string | Name of the division | | [name](./bitburner.division.name.md) | string | Name of the division |
| [popularity](./bitburner.division.popularity.md) | number | Popularity of the division | | [popularity](./bitburner.division.popularity.md) | number | Popularity of the division |
| [prodMult](./bitburner.division.prodmult.md) | number | Production multiplier | | [prodMult](./bitburner.division.prodmult.md) | number | Production multiplier |
| [products](./bitburner.division.products.md) | string\[\] | Products developed by this division |
| [research](./bitburner.division.research.md) | number | Amount of research in that division | | [research](./bitburner.division.research.md) | number | Amount of research in that division |
| [thisCycleExpenses](./bitburner.division.thiscycleexpenses.md) | number | Expenses this cycle | | [thisCycleExpenses](./bitburner.division.thiscycleexpenses.md) | number | Expenses this cycle |
| [thisCycleRevenue](./bitburner.division.thiscyclerevenue.md) | number | Revenue this cycle | | [thisCycleRevenue](./bitburner.division.thiscyclerevenue.md) | number | Revenue this cycle |

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Division](./bitburner.division.md) &gt; [products](./bitburner.division.products.md)
## Division.products property
Products developed by this division
<b>Signature:</b>
```typescript
products: string[];
```

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [InvestmentOffer](./bitburner.investmentoffer.md) &gt; [funds](./bitburner.investmentoffer.funds.md)
## InvestmentOffer.funds property
Amount of funds you will get from this investment
<b>Signature:</b>
```typescript
funds: number;
```

@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [InvestmentOffer](./bitburner.investmentoffer.md)
## InvestmentOffer interface
Corporation investment offer
<b>Signature:</b>
```typescript
interface InvestmentOffer
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [funds](./bitburner.investmentoffer.funds.md) | number | Amount of funds you will get from this investment |
| [round](./bitburner.investmentoffer.round.md) | number | Current round of funding (max 4) |
| [shares](./bitburner.investmentoffer.shares.md) | number | Amount of share you will give in exchange for this investment |

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [InvestmentOffer](./bitburner.investmentoffer.md) &gt; [round](./bitburner.investmentoffer.round.md)
## InvestmentOffer.round property
Current round of funding (max 4)
<b>Signature:</b>
```typescript
round: number;
```

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [InvestmentOffer](./bitburner.investmentoffer.md) &gt; [shares](./bitburner.investmentoffer.shares.md)
## InvestmentOffer.shares property
Amount of share you will give in exchange for this investment
<b>Signature:</b>
```typescript
shares: number;
```

@ -17,6 +17,8 @@ interface Material
| Property | Type | Description | | Property | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| [name](./bitburner.material.name.md) | string | Name of the material | | [name](./bitburner.material.name.md) | string | Name of the material |
| [prod](./bitburner.material.prod.md) | number | Amount of material produced |
| [qlt](./bitburner.material.qlt.md) | number | Quality of the material | | [qlt](./bitburner.material.qlt.md) | number | Quality of the material |
| [qty](./bitburner.material.qty.md) | number | Amount of material | | [qty](./bitburner.material.qty.md) | number | Amount of material |
| [sell](./bitburner.material.sell.md) | number | Amount of material sold |

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Material](./bitburner.material.md) &gt; [prod](./bitburner.material.prod.md)
## Material.prod property
Amount of material produced
<b>Signature:</b>
```typescript
prod: number;
```

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Material](./bitburner.material.md) &gt; [sell](./bitburner.material.sell.md)
## Material.sell property
Amount of material sold
<b>Signature:</b>
```typescript
sell: number;
```

@ -52,6 +52,7 @@
| [HacknetNodesFormulas](./bitburner.hacknetnodesformulas.md) | Hacknet Node formulas | | [HacknetNodesFormulas](./bitburner.hacknetnodesformulas.md) | Hacknet Node formulas |
| [HacknetServerConstants](./bitburner.hacknetserverconstants.md) | Hacknet server related constants | | [HacknetServerConstants](./bitburner.hacknetserverconstants.md) | Hacknet server related constants |
| [HacknetServersFormulas](./bitburner.hacknetserversformulas.md) | Hacknet Server formulas | | [HacknetServersFormulas](./bitburner.hacknetserversformulas.md) | Hacknet Server formulas |
| [InvestmentOffer](./bitburner.investmentoffer.md) | Corporation investment offer |
| [Material](./bitburner.material.md) | Material in a warehouse | | [Material](./bitburner.material.md) | Material in a warehouse |
| [NetscriptPort](./bitburner.netscriptport.md) | Object representing a port. A port is a serialized queue. | | [NetscriptPort](./bitburner.netscriptport.md) | Object representing a port. A port is a serialized queue. |
| [NodeStats](./bitburner.nodestats.md) | Object representing all the values related to a hacknet node. | | [NodeStats](./bitburner.nodestats.md) | Object representing all the values related to a hacknet node. |

@ -0,0 +1,26 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [getHireAdVertCost](./bitburner.officeapi.gethireadvertcost.md)
## OfficeAPI.getHireAdVertCost() method
Get the cost to Hire AdVert
<b>Signature:</b>
```typescript
getHireAdVertCost(divisionName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| divisionName | string | Name of the division |
<b>Returns:</b>
number
Cost

@ -0,0 +1,26 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [getHireAdVertCount](./bitburner.officeapi.gethireadvertcount.md)
## OfficeAPI.getHireAdVertCount() method
Get the number of times you have Hired AdVert
<b>Signature:</b>
```typescript
getHireAdVertCount(adivisionName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| adivisionName | string | |
<b>Returns:</b>
number
Number of times you have Hired AdVert

@ -0,0 +1,28 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [getOfficeSizeUpgradeCost](./bitburner.officeapi.getofficesizeupgradecost.md)
## OfficeAPI.getOfficeSizeUpgradeCost() method
Cost to Upgrade office size.
<b>Signature:</b>
```typescript
getOfficeSizeUpgradeCost(divisionName: string, cityName: string, asize: number): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| divisionName | string | Name of the division |
| cityName | string | Name of the city |
| asize | number | |
<b>Returns:</b>
number
Cost of upgrading the office

@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [getResearchCost](./bitburner.officeapi.getresearchcost.md)
## OfficeAPI.getResearchCost() method
Get the cost to unlock research
<b>Signature:</b>
```typescript
getResearchCost(divisionName: string, researchName: string): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| divisionName | string | Name of the division |
| researchName | string | |
<b>Returns:</b>
number
cost

@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [hasResearched](./bitburner.officeapi.hasresearched.md)
## OfficeAPI.hasResearched() method
Gets if you have unlocked a research
<b>Signature:</b>
```typescript
hasResearched(divisionName: string, researchName: string): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| divisionName | string | Name of the division |
| researchName | string | |
<b>Returns:</b>
boolean
true is unlocked, false if not

@ -4,7 +4,7 @@
## OfficeAPI.hireEmployee() method ## OfficeAPI.hireEmployee() method
Assign an employee to a job. Hire an employee.
<b>Signature:</b> <b>Signature:</b>

@ -23,10 +23,16 @@ Requires the Office API upgrade from your corporation.
| [assignJob(divisionName, cityName, employeeName, job)](./bitburner.officeapi.assignjob.md) | Assign an employee to a job. | | [assignJob(divisionName, cityName, employeeName, job)](./bitburner.officeapi.assignjob.md) | Assign an employee to a job. |
| [buyCoffee(divisionName, cityName)](./bitburner.officeapi.buycoffee.md) | Buy coffee for your employees | | [buyCoffee(divisionName, cityName)](./bitburner.officeapi.buycoffee.md) | Buy coffee for your employees |
| [getEmployee(divisionName, cityName, employeeName)](./bitburner.officeapi.getemployee.md) | Get data about an employee | | [getEmployee(divisionName, cityName, employeeName)](./bitburner.officeapi.getemployee.md) | Get data about an employee |
| [getHireAdVertCost(divisionName)](./bitburner.officeapi.gethireadvertcost.md) | Get the cost to Hire AdVert |
| [getHireAdVertCount(adivisionName)](./bitburner.officeapi.gethireadvertcount.md) | Get the number of times you have Hired AdVert |
| [getOffice(divisionName, cityName)](./bitburner.officeapi.getoffice.md) | Get data about an office | | [getOffice(divisionName, cityName)](./bitburner.officeapi.getoffice.md) | Get data about an office |
| [getOfficeSizeUpgradeCost(divisionName, cityName, asize)](./bitburner.officeapi.getofficesizeupgradecost.md) | Cost to Upgrade office size. |
| [getResearchCost(divisionName, researchName)](./bitburner.officeapi.getresearchcost.md) | Get the cost to unlock research |
| [hasResearched(divisionName, researchName)](./bitburner.officeapi.hasresearched.md) | Gets if you have unlocked a research |
| [hireAdVert(divisionName)](./bitburner.officeapi.hireadvert.md) | Hire AdVert. | | [hireAdVert(divisionName)](./bitburner.officeapi.hireadvert.md) | Hire AdVert. |
| [hireEmployee(divisionName, cityName)](./bitburner.officeapi.hireemployee.md) | Assign an employee to a job. | | [hireEmployee(divisionName, cityName)](./bitburner.officeapi.hireemployee.md) | Hire an employee. |
| [research(divisionName, researchName)](./bitburner.officeapi.research.md) | Hire AdVert. | | [research(divisionName, researchName)](./bitburner.officeapi.research.md) | Purchase a research |
| [throwParty(divisionName, cityName, costPerEmployee)](./bitburner.officeapi.throwparty.md) | Assign an employee to a job. | | [setAutoJobAssignment(divisionName, cityName, job, amount)](./bitburner.officeapi.setautojobassignment.md) | Set the auto job assignment for a job |
| [throwParty(divisionName, cityName, costPerEmployee)](./bitburner.officeapi.throwparty.md) | Throw a party for your employees |
| [upgradeOfficeSize(divisionName, cityName, size)](./bitburner.officeapi.upgradeofficesize.md) | Upgrade office size. | | [upgradeOfficeSize(divisionName, cityName, size)](./bitburner.officeapi.upgradeofficesize.md) | Upgrade office size. |

@ -4,7 +4,7 @@
## OfficeAPI.research() method ## OfficeAPI.research() method
Hire AdVert. Purchase a research
<b>Signature:</b> <b>Signature:</b>

@ -0,0 +1,29 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [OfficeAPI](./bitburner.officeapi.md) &gt; [setAutoJobAssignment](./bitburner.officeapi.setautojobassignment.md)
## OfficeAPI.setAutoJobAssignment() method
Set the auto job assignment for a job
<b>Signature:</b>
```typescript
setAutoJobAssignment(divisionName: string, cityName: string, job: string, amount: number): Promise<boolean>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| divisionName | string | Name of the division |
| cityName | string | Name of the city |
| job | string | Name of the job |
| amount | number | Number of employees to assign to that job |
<b>Returns:</b>
Promise&lt;boolean&gt;
A promise that is fulfilled when the assignment is complete.

@ -4,7 +4,7 @@
## OfficeAPI.throwParty() method ## OfficeAPI.throwParty() method
Assign an employee to a job. Throw a party for your employees
<b>Signature:</b> <b>Signature:</b>

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Player](./bitburner.player.md) &gt; [hasCorporation](./bitburner.player.hascorporation.md)
## Player.hasCorporation property
<b>Signature:</b>
```typescript
hasCorporation: boolean;
```

@ -64,6 +64,7 @@ interface Player
| [hacknet\_node\_ram\_cost\_mult](./bitburner.player.hacknet_node_ram_cost_mult.md) | number | | | [hacknet\_node\_ram\_cost\_mult](./bitburner.player.hacknet_node_ram_cost_mult.md) | number | |
| [has4SData](./bitburner.player.has4sdata.md) | boolean | | | [has4SData](./bitburner.player.has4sdata.md) | boolean | |
| [has4SDataTixApi](./bitburner.player.has4sdatatixapi.md) | boolean | | | [has4SDataTixApi](./bitburner.player.has4sdatatixapi.md) | boolean | |
| [hasCorporation](./bitburner.player.hascorporation.md) | boolean | |
| [hasTixApiAccess](./bitburner.player.hastixapiaccess.md) | boolean | | | [hasTixApiAccess](./bitburner.player.hastixapiaccess.md) | boolean | |
| [hasWseAccount](./bitburner.player.haswseaccount.md) | boolean | | | [hasWseAccount](./bitburner.player.haswseaccount.md) | boolean | |
| [hp](./bitburner.player.hp.md) | number | | | [hp](./bitburner.player.hp.md) | number | |

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Product](./bitburner.product.md) &gt; [cityData](./bitburner.product.citydata.md)
## Product.cityData property
Data refers to the production, sale, and quantity of the products These values are specific to a city For each city, the data is \[qty, prod, sell\]
<b>Signature:</b>
```typescript
cityData: {[key: string]:number[]};
```

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Product](./bitburner.product.md) &gt; [developmentProgress](./bitburner.product.developmentprogress.md)
## Product.developmentProgress property
Creation progress - A number between 0-100 representing percentage
<b>Signature:</b>
```typescript
developmentProgress: number;
```

@ -16,7 +16,9 @@ interface Product
| Property | Type | Description | | Property | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| [cityData](./bitburner.product.citydata.md) | {\[key: string\]:number\[\]} | Data refers to the production, sale, and quantity of the products These values are specific to a city For each city, the data is \[qty, prod, sell\] |
| [cmp](./bitburner.product.cmp.md) | number | Competition for the product | | [cmp](./bitburner.product.cmp.md) | number | Competition for the product |
| [developmentProgress](./bitburner.product.developmentprogress.md) | number | Creation progress - A number between 0-100 representing percentage |
| [dmd](./bitburner.product.dmd.md) | number | Demand for the product | | [dmd](./bitburner.product.dmd.md) | number | Demand for the product |
| [name](./bitburner.product.name.md) | string | Name of the product | | [name](./bitburner.product.name.md) | string | Name of the product |
| [pCost](./bitburner.product.pcost.md) | number | Production cost | | [pCost](./bitburner.product.pcost.md) | number | Production cost |

@ -20,4 +20,5 @@ interface Warehouse
| [loc](./bitburner.warehouse.loc.md) | string | City in which the warehouse is located | | [loc](./bitburner.warehouse.loc.md) | string | City in which the warehouse is located |
| [size](./bitburner.warehouse.size.md) | number | Total space in the warehouse | | [size](./bitburner.warehouse.size.md) | number | Total space in the warehouse |
| [sizeUsed](./bitburner.warehouse.sizeused.md) | number | Used space in the warehouse | | [sizeUsed](./bitburner.warehouse.sizeused.md) | number | Used space in the warehouse |
| [smartSupplyEnabled](./bitburner.warehouse.smartsupplyenabled.md) | boolean | Smart Supply status in the warehouse |

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [Warehouse](./bitburner.warehouse.md) &gt; [smartSupplyEnabled](./bitburner.warehouse.smartsupplyenabled.md)
## Warehouse.smartSupplyEnabled property
Smart Supply status in the warehouse
<b>Signature:</b>
```typescript
smartSupplyEnabled: boolean;
```

@ -0,0 +1,19 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [WarehouseAPI](./bitburner.warehouseapi.md) &gt; [getPurchaseWarehouseCost](./bitburner.warehouseapi.getpurchasewarehousecost.md)
## WarehouseAPI.getPurchaseWarehouseCost() method
Gets the cost to purchase a warehouse
<b>Signature:</b>
```typescript
getPurchaseWarehouseCost(): number;
```
<b>Returns:</b>
number
cost

@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [WarehouseAPI](./bitburner.warehouseapi.md) &gt; [getUpgradeWarehouseCost](./bitburner.warehouseapi.getupgradewarehousecost.md)
## WarehouseAPI.getUpgradeWarehouseCost() method
Gets the cost to upgrade a warehouse to the next level
<b>Signature:</b>
```typescript
getUpgradeWarehouseCost(adivisionName: any, acityName: any): number;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| adivisionName | any | |
| acityName | any | |
<b>Returns:</b>
number
cost to upgrade

@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [WarehouseAPI](./bitburner.warehouseapi.md) &gt; [hasWarehouse](./bitburner.warehouseapi.haswarehouse.md)
## WarehouseAPI.hasWarehouse() method
Check if you have a warehouse in city
<b>Signature:</b>
```typescript
hasWarehouse(adivisionName: any, acityName: any): boolean;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| adivisionName | any | |
| acityName | any | |
<b>Returns:</b>
boolean
true if warehouse is present, false if not

@ -26,7 +26,10 @@ Requires the Warehouse API upgrade from your corporation.
| [exportMaterial(sourceDivision, sourceCity, targetDivision, targetCity, materialName, amt)](./bitburner.warehouseapi.exportmaterial.md) | Set material export data | | [exportMaterial(sourceDivision, sourceCity, targetDivision, targetCity, materialName, amt)](./bitburner.warehouseapi.exportmaterial.md) | Set material export data |
| [getMaterial(divisionName, cityName, materialName)](./bitburner.warehouseapi.getmaterial.md) | Get material data | | [getMaterial(divisionName, cityName, materialName)](./bitburner.warehouseapi.getmaterial.md) | Get material data |
| [getProduct(divisionName, productName)](./bitburner.warehouseapi.getproduct.md) | Get product data | | [getProduct(divisionName, productName)](./bitburner.warehouseapi.getproduct.md) | Get product data |
| [getPurchaseWarehouseCost()](./bitburner.warehouseapi.getpurchasewarehousecost.md) | Gets the cost to purchase a warehouse |
| [getUpgradeWarehouseCost(adivisionName, acityName)](./bitburner.warehouseapi.getupgradewarehousecost.md) | Gets the cost to upgrade a warehouse to the next level |
| [getWarehouse(divisionName, cityName)](./bitburner.warehouseapi.getwarehouse.md) | Get warehouse data | | [getWarehouse(divisionName, cityName)](./bitburner.warehouseapi.getwarehouse.md) | Get warehouse data |
| [hasWarehouse(adivisionName, acityName)](./bitburner.warehouseapi.haswarehouse.md) | Check if you have a warehouse in city |
| [makeProduct(divisionName, cityName, productName, designInvest, marketingInvest)](./bitburner.warehouseapi.makeproduct.md) | Create a new product | | [makeProduct(divisionName, cityName, productName, designInvest, marketingInvest)](./bitburner.warehouseapi.makeproduct.md) | Create a new product |
| [purchaseWarehouse(divisionName, cityName)](./bitburner.warehouseapi.purchasewarehouse.md) | Purchase warehouse for a new city | | [purchaseWarehouse(divisionName, cityName)](./bitburner.warehouseapi.purchasewarehouse.md) | Purchase warehouse for a new city |
| [sellMaterial(divisionName, cityName, materialName, amt, price)](./bitburner.warehouseapi.sellmaterial.md) | Set material sell data. | | [sellMaterial(divisionName, cityName, materialName, amt, price)](./bitburner.warehouseapi.sellmaterial.md) | Set material sell data. |

@ -94,7 +94,7 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
@ -117,13 +117,13 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (tempQty == null || isNaN(parseFloat(tempQty))) { if (tempQty == null || isNaN(parseFloat(tempQty)) || parseFloat(tempQty) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
mat.sllman[0] = true; mat.sllman[0] = true;
mat.sllman[1] = q; //Use sanitized input mat.sllman[1] = q; //Use sanitized input
} else if (isNaN(parseFloat(amt))) { } else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'"); throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'");
} else { } else {
let q = parseFloat(amt); let q = parseFloat(amt);
@ -153,7 +153,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
} catch (e) { } catch (e) {
throw new Error("Invalid value or expression for sell quantity field: " + e); throw new Error("Invalid value or expression for sell quantity field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell quantity field."); throw new Error("Invalid value or expression for sell quantity field.");
} }
product.sCost = price; //Use sanitized price product.sCost = price; //Use sanitized price
@ -182,7 +182,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
throw new Error("Invalid value or expression for sell price field: " + e); throw new Error("Invalid value or expression for sell price field: " + e);
} }
if (temp == null || isNaN(parseFloat(temp))) { if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
throw new Error("Invalid value or expression for sell price field"); throw new Error("Invalid value or expression for sell price field");
} }
if (all) { if (all) {
@ -195,7 +195,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
product.sllman[city][0] = true; product.sllman[city][0] = true;
product.sllman[city][1] = qty; //Use sanitized input product.sllman[city][1] = qty; //Use sanitized input
} }
} else if (isNaN(parseFloat(amt))) { } else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
throw new Error("Invalid value for sell quantity field! Must be numeric"); throw new Error("Invalid value for sell quantity field! Must be numeric");
} else { } else {
let qty = parseFloat(amt); let qty = parseFloat(amt);
@ -233,13 +233,13 @@ export function SetSmartSupply(warehouse: Warehouse, smartSupply: boolean): void
} }
export function SetSmartSupplyUseLeftovers(warehouse: Warehouse, material: Material, useLeftover: boolean): void { export function SetSmartSupplyUseLeftovers(warehouse: Warehouse, material: Material, useLeftover: boolean): void {
if (!Object.keys(warehouse.smartSupplyUseLeftovers).includes(material.name)) if (!Object.keys(warehouse.smartSupplyUseLeftovers).includes(material.name.replace(/ /g, "")))
throw new Error(`Invalid material '${material.name}'`); throw new Error(`Invalid material '${material.name}'`);
warehouse.smartSupplyUseLeftovers[material.name] = useLeftover; warehouse.smartSupplyUseLeftovers[material.name.replace(/ /g, "")] = useLeftover;
} }
export function BuyMaterial(material: Material, amt: number): void { export function BuyMaterial(material: Material, amt: number): void {
if (isNaN(amt)) { if (isNaN(amt) || amt < 0) {
throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`); throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`);
} }
material.buy = amt; material.buy = amt;

@ -435,8 +435,11 @@ export class Industry implements IIndustry {
const popularityGain = corporation.getDreamSenseGain(), const popularityGain = corporation.getDreamSenseGain(),
awarenessGain = popularityGain * 4; awarenessGain = popularityGain * 4;
if (popularityGain > 0) { if (popularityGain > 0) {
this.popularity += popularityGain * marketCycles; const awareness = this.awareness + (awarenessGain * marketCycles);
this.awareness += awarenessGain * marketCycles; this.awareness = Math.min(awareness, Number.MAX_VALUE);
const popularity = this.popularity + (popularityGain * marketCycles);
this.popularity = Math.min(popularity, Number.MAX_VALUE);
} }
return; return;
@ -1279,10 +1282,11 @@ export class Industry implements IIndustry {
case 1: { case 1: {
//AdVert.Inc, //AdVert.Inc,
const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier(); const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier();
this.awareness += 3 * advMult; const awareness = (this.awareness + (3 * advMult)) * (1.01 * advMult);
this.popularity += 1 * advMult; this.awareness = Math.min(awareness, Number.MAX_VALUE);
this.awareness *= 1.01 * advMult;
this.popularity *= (1 + getRandomInt(1, 3) / 100) * advMult; const popularity = (this.popularity + (1 * advMult)) * ((1 + getRandomInt(1, 3) / 100) * advMult);
this.popularity = Math.min(popularity, Number.MAX_VALUE);
break; break;
} }
default: { default: {

@ -173,6 +173,40 @@ export class OfficeSpace {
return false; return false;
} }
setEmployeeToJob(job: string, amount: number): boolean {
let unassignedCount = 0;
let jobCount = 0;
for (let i = 0; i < this.employees.length; ++i) {
if (this.employees[i].pos === EmployeePositions.Unassigned) {
unassignedCount++;
} else if (this.employees[i].pos === job) {
jobCount++;
}
}
if ((jobCount + unassignedCount) < amount) return false;
for (let i = 0; i < this.employees.length; ++i) {
if (this.employees[i].pos === EmployeePositions.Unassigned) {
if (jobCount <= amount) {
this.employees[i].pos = job;
jobCount++;
unassignedCount--;
}
if (jobCount === amount) break;
} else if (this.employees[i].pos === job) {
if (jobCount >= amount) {
this.employees[i].pos = EmployeePositions.Unassigned;
jobCount--;
unassignedCount++;
}
if (jobCount === amount) break;
}
}
if (jobCount !== amount) return false;
return true;
}
toJSON(): any { toJSON(): any {
return Generic_toJSON("OfficeSpace", this); return Generic_toJSON("OfficeSpace", this);
} }

@ -25,6 +25,8 @@ export const CorporationConstants: {
BaseMaxProducts: number; BaseMaxProducts: number;
AllCorporationStates: string[]; AllCorporationStates: string[];
AllMaterials: string[]; AllMaterials: string[];
FundingRoundShares: number[];
FundingRoundMultiplier: number[];
} = { } = {
INITIALSHARES: 1e9, //Total number of shares you have at your company INITIALSHARES: 1e9, //Total number of shares you have at your company
SHARESPERPRICEUPDATE: 1e6, //When selling large number of shares, price is dynamically updated for every batch of this amount SHARESPERPRICEUPDATE: 1e6, //When selling large number of shares, price is dynamically updated for every batch of this amount
@ -71,4 +73,16 @@ export const CorporationConstants: {
"AI Cores", "AI Cores",
"Real Estate", "Real Estate",
], ],
FundingRoundShares: [
0.1,
0.35,
0.25,
0.2
],
FundingRoundMultiplier: [
4,
3,
3,
2.5
],
}; };

@ -56,9 +56,9 @@ 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 $150b for registration and initial funding. This $150b Would you like to start a corporation? This will require $150b for registration and initial funding. {player.bitNodeN === 3 && (`This $150b
can either be self-funded, or you can obtain the seed money from the government in exchange for 500 million can either be self-funded, or you can obtain the seed money from the government in exchange for 500 million
shares shares`)}
<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 one, please enter a name for your corporation below:

@ -15,37 +15,18 @@ interface IProps {
// Create a popup that lets the player manage exports // Create a popup that lets the player manage exports
export function FindInvestorsModal(props: IProps): React.ReactElement { export function FindInvestorsModal(props: IProps): React.ReactElement {
const corp = useCorporation(); const corporation = useCorporation();
const val = corp.determineValuation(); const val = corporation.determineValuation();
let percShares = 0; if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length) return <></>;
let roundMultiplier = 4; const percShares = CorporationConstants.FundingRoundShares[corporation.fundingRound];
switch (corp.fundingRound) { const roundMultiplier = CorporationConstants.FundingRoundMultiplier[corporation.fundingRound];
case 0: //Seed
percShares = 0.1;
roundMultiplier = 4;
break;
case 1: //Series A
percShares = 0.35;
roundMultiplier = 3;
break;
case 2: //Series B
percShares = 0.25;
roundMultiplier = 3;
break;
case 3: //Series C
percShares = 0.2;
roundMultiplier = 2.5;
break;
default:
return <></>;
}
const funding = val * percShares * roundMultiplier; const funding = val * percShares * roundMultiplier;
const investShares = Math.floor(CorporationConstants.INITIALSHARES * percShares); const investShares = Math.floor(CorporationConstants.INITIALSHARES * percShares);
function findInvestors(): void { function findInvestors(): void {
corp.fundingRound++; corporation.fundingRound++;
corp.addFunds(funding); corporation.addFunds(funding);
corp.numShares -= investShares; corporation.numShares -= investShares;
props.rerender(); props.rerender();
props.onClose(); props.onClose();
} }

@ -30,7 +30,7 @@ function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
<Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography> <Typography color={"error"}>Not enough warehouse space to purchase this amount</Typography>
</> </>
); );
} else if (isNaN(cost)) { } else if (isNaN(cost) || parsedAmt < 0) {
return ( return (
<> <>
<Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography> <Typography color={"error"}>Invalid put for Bulk Purchase amount</Typography>
@ -68,7 +68,7 @@ function BulkPurchase(props: IBPProps): React.ReactElement {
return; return;
} }
if (isNaN(amount)) { if (isNaN(amount) || amount < 0) {
dialogBoxCreate("Invalid input amount"); dialogBoxCreate("Invalid input amount");
} else { } else {
const cost = amount * props.mat.bCost; const cost = amount * props.mat.bCost;

@ -16,11 +16,12 @@ interface ILeftoverProps {
} }
function Leftover(props: ILeftoverProps): React.ReactElement { function Leftover(props: ILeftoverProps): React.ReactElement {
const [checked, setChecked] = useState(!!props.warehouse.smartSupplyUseLeftovers[props.matName]); const [checked, setChecked] = useState(!!props.warehouse.smartSupplyUseLeftovers[props.matName.replace(/ /g, "")]);
function onChange(event: React.ChangeEvent<HTMLInputElement>): void { function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
try { try {
const material = props.warehouse.materials[props.matName]; const matName = props.matName.replace(/ /g, "");
const material = props.warehouse.materials[matName];
SetSmartSupplyUseLeftovers(props.warehouse, material, event.target.checked); SetSmartSupplyUseLeftovers(props.warehouse, material, event.target.checked);
} catch (err) { } catch (err) {
dialogBoxCreate(err + ""); dialogBoxCreate(err + "");
@ -32,7 +33,7 @@ function Leftover(props: ILeftoverProps): React.ReactElement {
<> <>
<FormControlLabel <FormControlLabel
control={<Switch checked={checked} onChange={onChange} />} control={<Switch checked={checked} onChange={onChange} />}
label={<Typography>{props.warehouse.materials[props.matName].name}</Typography>} label={<Typography>{props.warehouse.materials[props.matName.replace(/ /g, "")].name}</Typography>}
/> />
<br /> <br />
</> </>

@ -35,7 +35,9 @@ export function GymLocation(props: IProps): React.ReactElement {
function train(stat: string): void { function train(stat: string): void {
const loc = props.loc; const loc = props.loc;
props.p.startClass(props.router, calculateCost(), loc.expMult, stat); props.p.startClass(calculateCost(), loc.expMult, stat);
props.p.startFocusing();
props.router.toWork();
} }
function trainStrength(): void { function trainStrength(): void {

@ -34,7 +34,9 @@ export function UniversityLocation(props: IProps): React.ReactElement {
function take(stat: string): void { function take(stat: string): void {
const loc = props.loc; const loc = props.loc;
player.startClass(router, calculateCost(), loc.expMult, stat); player.startClass(calculateCost(), loc.expMult, stat);
player.startFocusing();
router.toWork();
} }
function study(): void { function study(): void {

@ -2259,6 +2259,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
jobs: {}, jobs: {},
factions: Player.factions.slice(), factions: Player.factions.slice(),
tor: Player.hasTorRouter(), tor: Player.hasTorRouter(),
hasCorporation: Player.hasCorporation(),
}; };
Object.assign(data.jobs, Player.jobs); Object.assign(data.jobs, Player.jobs);
return data; return data;

@ -21,6 +21,7 @@ import {
Division as NSDivision, Division as NSDivision,
WarehouseAPI, WarehouseAPI,
OfficeAPI, OfficeAPI,
InvestmentOffer
} from "../ScriptEditor/NetscriptDefinitions"; } from "../ScriptEditor/NetscriptDefinitions";
import { import {
@ -53,12 +54,161 @@ import { CorporationUnlockUpgrades } from "../Corporation/data/CorporationUnlock
import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades"; import { CorporationUpgrades } from "../Corporation/data/CorporationUpgrades";
import { EmployeePositions } from "../Corporation/EmployeePositions"; import { EmployeePositions } from "../Corporation/EmployeePositions";
import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence"; import { calculateIntelligenceBonus } from "../PersonObjects/formulas/intelligence";
import { Industry } from "../Corporation/Industry";
import { IndustryResearchTrees, IndustryStartingCosts } from "../Corporation/IndustryData";
import { CorporationConstants } from "../Corporation/data/Constants";
import { IndustryUpgrades } from "../Corporation/IndustryUpgrades";
import { ResearchMap } from "../Corporation/ResearchMap";
import { Factions } from "../Faction/Factions";
export function NetscriptCorporation( export function NetscriptCorporation(
player: IPlayer, player: IPlayer,
workerScript: WorkerScript, workerScript: WorkerScript,
helper: INetscriptHelper, helper: INetscriptHelper,
): NSCorporation { ): NSCorporation {
function createCorporation(corporationName: string, selfFund = true): boolean {
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
if (!corporationName) return false;
if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3");
if (selfFund) {
if (!player.canAfford(150e9)) return false;
player.startCorporation(corporationName);
player.loseMoney(150e9, "corporation");
} else {
player.startCorporation(corporationName, 500e6);
}
return true;
}
function hasUnlockUpgrade(upgradeName: string): boolean {
const corporation = getCorporation();
const upgrade = Object.values(CorporationUnlockUpgrades).find((upgrade) => upgrade[2] === upgradeName);
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
const upgN = upgrade[0];
return corporation.unlockUpgrades[upgN] === 1;
}
function getUnlockUpgradeCost(upgradeName: string): number {
const upgrade = Object.values(CorporationUnlockUpgrades).find((upgrade) => upgrade[2] === upgradeName);
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
return upgrade[1];
}
function getUpgradeLevel(aupgradeName: string): number {
const upgradeName = helper.string("levelUpgrade", "upgradeName", aupgradeName);
const corporation = getCorporation();
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade[4] === upgradeName);
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
const upgN = upgrade[0];
return corporation.upgrades[upgN];
}
function getUpgradeLevelCost(aupgradeName: string): number {
const upgradeName = helper.string("levelUpgrade", "upgradeName", aupgradeName);
const corporation = getCorporation();
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade[4] === upgradeName);
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
const upgN = upgrade[0];
const baseCost = upgrade[1];
const priceMult = upgrade[2];
const level = corporation.upgrades[upgN];
return baseCost * Math.pow(priceMult, level);
}
function getExpandIndustryCost(industryName: string): number {
const cost = IndustryStartingCosts[industryName];
if (cost === undefined) {
throw new Error(`Invalid industry: '${industryName}'`);
}
return cost;
}
function getExpandCityCost(): number {
return CorporationConstants.OfficeInitialCost;
}
function getInvestmentOffer(): InvestmentOffer {
const corporation = getCorporation();
if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length || corporation.public)
return {
funds: 0,
shares: 0,
round: corporation.fundingRound + 1 // Make more readable
}; // Don't throw an error here, no reason to have a second function to check if you can get investment.
const val = corporation.determineValuation();
const percShares = CorporationConstants.FundingRoundShares[corporation.fundingRound];
const roundMultiplier = CorporationConstants.FundingRoundMultiplier[corporation.fundingRound];
const funding = val * percShares * roundMultiplier;
const investShares = Math.floor(CorporationConstants.INITIALSHARES * percShares);
return {
funds: funding,
shares: investShares,
round: corporation.fundingRound + 1 // Make more readable
};
}
function acceptInvestmentOffer(): boolean {
const corporation = getCorporation();
if (corporation.fundingRound >= CorporationConstants.FundingRoundShares.length || corporation.fundingRound >= CorporationConstants.FundingRoundMultiplier.length || corporation.public) return false;
const val = corporation.determineValuation();
const percShares = CorporationConstants.FundingRoundShares[corporation.fundingRound];
const roundMultiplier = CorporationConstants.FundingRoundMultiplier[corporation.fundingRound];
const funding = val * percShares * roundMultiplier;
const investShares = Math.floor(CorporationConstants.INITIALSHARES * percShares);
corporation.fundingRound++;
corporation.addFunds(funding);
corporation.numShares -= investShares;
return true;
}
function goPublic(numShares: number): boolean {
const corporation = getCorporation();
const initialSharePrice = corporation.determineValuation() / corporation.totalShares;
if (isNaN(numShares)) throw new Error("Invalid value for number of issued shares");
if (numShares < 0) throw new Error("Invalid value for number of issued shares");
if (numShares > corporation.numShares) throw new Error("You don't have that many shares to issue!");
corporation.public = true;
corporation.sharePrice = initialSharePrice;
corporation.issuedShares = numShares;
corporation.numShares -= numShares;
corporation.addFunds(numShares * initialSharePrice);
return true;
}
function getResearchCost(division: IIndustry, researchName: string): number {
const researchTree = IndustryResearchTrees[division.type];
if (researchTree === undefined) throw new Error(`No research tree for industry '${division.type}'`);
const allResearch = researchTree.getAllNodes();
if (!allResearch.includes(researchName)) throw new Error(`No research named '${researchName}'`);
const research = ResearchMap[researchName];
return research.cost;
}
function hasResearched(division: IIndustry, researchName: string): boolean {
return division.researched[researchName] === undefined ? false : division.researched[researchName] as boolean;
}
function bribe(factionName: string, amountCash: number, amountShares: number): boolean {
if (!player.factions.includes(factionName)) throw new Error("Invalid faction name");
if (isNaN(amountCash) || amountCash < 0 || isNaN(amountShares) || amountShares < 0) throw new Error("Invalid value for amount field! Must be numeric, grater than 0.");
const corporation = getCorporation();
if (corporation.funds < amountCash) return false;
if (corporation.numShares < amountShares) return false;
const faction = Factions[factionName]
const info = faction.getInfo();
if (!info.offersWork()) return false;
if (player.hasGangWith(factionName)) return false;
const repGain = (amountCash + amountShares * corporation.sharePrice) / CorporationConstants.BribeToRepRatio;
faction.playerReputation += repGain;
corporation.funds = corporation.funds - amountCash;
corporation.numShares -= amountShares;
return true;
}
function getCorporation(): ICorporation { function getCorporation(): ICorporation {
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");
@ -90,7 +240,8 @@ export function NetscriptCorporation(
function getMaterial(divisionName: any, cityName: any, materialName: any): Material { function getMaterial(divisionName: any, cityName: any, materialName: any): Material {
const warehouse = getWarehouse(divisionName, cityName); const warehouse = getWarehouse(divisionName, cityName);
const material = warehouse.materials[materialName]; const matName = (materialName as string).replace(/ /g, "");
const material = warehouse.materials[matName];
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`); if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
return material; return material;
} }
@ -117,7 +268,50 @@ export function NetscriptCorporation(
throw helper.makeRuntimeErrorMsg(`corporation.${func}`, "You do not have access to this API."); throw helper.makeRuntimeErrorMsg(`corporation.${func}`, "You do not have access to this API.");
} }
function getSafeDivision(division: Industry): NSDivision {
const cities: string[] = [];
for (const office of Object.values(division.offices)) {
if (office === 0) continue;
cities.push(office.loc);
}
return {
name: division.name,
type: division.type,
awareness: division.awareness,
popularity: division.popularity,
prodMult: division.prodMult,
research: division.sciResearch.qty,
lastCycleRevenue: division.lastCycleRevenue,
lastCycleExpenses: division.lastCycleExpenses,
thisCycleRevenue: division.thisCycleRevenue,
thisCycleExpenses: division.thisCycleExpenses,
upgrades: division.upgrades,
cities: cities,
products: division.products === undefined ? [] : Object.keys(division.products),
};
}
const warehouseAPI: WarehouseAPI = { const warehouseAPI: WarehouseAPI = {
getPurchaseWarehouseCost: function (): number {
checkAccess("getPurchaseWarehouseCost", 7);
return CorporationConstants.WarehouseInitialCost;
},
getUpgradeWarehouseCost: function (adivisionName: any, acityName: any): number {
checkAccess("upgradeWarehouse", 7);
const divisionName = helper.string("getUpgradeWarehouseCost", "divisionName", adivisionName);
const cityName = helper.string("getUpgradeWarehouseCost", "cityName", acityName);
const warehouse = getWarehouse(divisionName, cityName);
return CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, warehouse.level + 1);
},
hasWarehouse: function (adivisionName: any, acityName: any): boolean {
checkAccess("hasWarehouse", 7);
const divisionName = helper.string("getWarehouse", "divisionName", adivisionName);
const cityName = helper.string("getWarehouse", "cityName", acityName);
const division = getDivision(divisionName);
if (!(cityName in division.warehouses)) throw new Error(`Invalid city name '${cityName}'`);
const warehouse = division.warehouses[cityName];
return warehouse !== 0;
},
getWarehouse: function (adivisionName: any, acityName: any): NSWarehouse { getWarehouse: function (adivisionName: any, acityName: any): NSWarehouse {
checkAccess("getWarehouse", 7); checkAccess("getWarehouse", 7);
const divisionName = helper.string("getWarehouse", "divisionName", adivisionName); const divisionName = helper.string("getWarehouse", "divisionName", adivisionName);
@ -128,6 +322,7 @@ export function NetscriptCorporation(
loc: warehouse.loc, loc: warehouse.loc,
size: warehouse.size, size: warehouse.size,
sizeUsed: warehouse.sizeUsed, sizeUsed: warehouse.sizeUsed,
smartSupplyEnabled: warehouse.smartSupplyEnabled
}; };
}, },
getMaterial: function (adivisionName: any, acityName: any, amaterialName: any): NSMaterial { getMaterial: function (adivisionName: any, acityName: any, amaterialName: any): NSMaterial {
@ -140,6 +335,8 @@ export function NetscriptCorporation(
name: material.name, name: material.name,
qty: material.qty, qty: material.qty,
qlt: material.qlt, qlt: material.qlt,
prod: material.prd,
sell: material.sll,
}; };
}, },
getProduct: function (adivisionName: any, aproductName: any): NSProduct { getProduct: function (adivisionName: any, aproductName: any): NSProduct {
@ -153,6 +350,8 @@ export function NetscriptCorporation(
cmp: product.cmp, cmp: product.cmp,
pCost: product.pCost, pCost: product.pCost,
sCost: product.sCost, sCost: product.sCost,
cityData: product.data,
developmentProgress: product.prog,
}; };
}, },
purchaseWarehouse: function (adivisionName: any, acityName: any): void { purchaseWarehouse: function (adivisionName: any, acityName: any): void {
@ -217,6 +416,7 @@ export function NetscriptCorporation(
const cityName = helper.string("buyMaterial", "cityName", acityName); const cityName = helper.string("buyMaterial", "cityName", acityName);
const materialName = helper.string("buyMaterial", "materialName", amaterialName); const materialName = helper.string("buyMaterial", "materialName", amaterialName);
const amt = helper.number("buyMaterial", "amt", aamt); const amt = helper.number("buyMaterial", "amt", aamt);
if (amt < 0) throw new Error("Invalid value for amount field! Must be numeric and grater than 0");
const material = getMaterial(divisionName, cityName, materialName); const material = getMaterial(divisionName, cityName, materialName);
BuyMaterial(material, amt); BuyMaterial(material, amt);
}, },
@ -303,6 +503,61 @@ export function NetscriptCorporation(
}; };
const officeAPI: OfficeAPI = { const officeAPI: OfficeAPI = {
getHireAdVertCost: function (adivisionName: any): number {
checkAccess("getHireAdVertCost", 8);
const divisionName = helper.string("getHireAdVertCost", "divisionName", adivisionName);
const division = getDivision(divisionName);
const upgrade = IndustryUpgrades[1];
return upgrade[1] * Math.pow(upgrade[2], division.upgrades[1]);
},
getHireAdVertCount: function (adivisionName: any): number {
checkAccess("getHireAdVertCount", 8);
const divisionName = helper.string("getHireAdVertCount", "divisionName", adivisionName);
const division = getDivision(divisionName);
return division.upgrades[1]
},
getResearchCost: function (adivisionName: any, aresearchName: any): number {
checkAccess("getResearchCost", 8);
const divisionName = helper.string("getResearchCost", "divisionName", adivisionName);
const researchName = helper.string("getResearchCost", "researchName", aresearchName);
return getResearchCost(getDivision(divisionName), researchName);
},
hasResearched: function (adivisionName: any, aresearchName: any): boolean {
checkAccess("hasResearched", 8);
const divisionName = helper.string("hasResearched", "divisionName", adivisionName);
const researchName = helper.string("hasResearched", "researchName", aresearchName);
return hasResearched(getDivision(divisionName), researchName);
},
setAutoJobAssignment: function (adivisionName: any, acityName: any, ajob: any, aamount: any): Promise<boolean> {
checkAccess("setAutoJobAssignment", 8);
const divisionName = helper.string("setAutoJobAssignment", "divisionName", adivisionName);
const cityName = helper.string("setAutoJobAssignment", "cityName", acityName);
const amount = helper.number("setAutoJobAssignment", "amount", aamount);
const job = helper.string("setAutoJobAssignment", "job", ajob);
const office = getOffice(divisionName, cityName);
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
return netscriptDelay(1000, workerScript).then(function () {
if (workerScript.env.stopFlag) {
return Promise.reject(workerScript);
}
return Promise.resolve(office.setEmployeeToJob(job, amount));
});
},
getOfficeSizeUpgradeCost: function (adivisionName: any, acityName: any, asize: any): number {
checkAccess("getOfficeSizeUpgradeCost", 8);
const divisionName = helper.string("getOfficeSizeUpgradeCost", "divisionName", adivisionName);
const cityName = helper.string("getOfficeSizeUpgradeCost", "cityName", acityName);
const size = helper.number("getOfficeSizeUpgradeCost", "size", asize);
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and grater than 0");
const office = getOffice(divisionName, cityName);
const initialPriceMult = Math.round(office.size / CorporationConstants.OfficeInitialSize);
const costMultiplier = 1.09;
let mult = 0;
for (let i = 0; i < size / CorporationConstants.OfficeInitialSize; ++i) {
mult += Math.pow(costMultiplier, initialPriceMult + i);
}
return CorporationConstants.OfficeInitialCost * mult;
},
assignJob: function (adivisionName: any, acityName: any, aemployeeName: any, ajob: any): Promise<void> { assignJob: function (adivisionName: any, acityName: any, aemployeeName: any, ajob: any): Promise<void> {
checkAccess("assignJob", 8); checkAccess("assignJob", 8);
const divisionName = helper.string("assignJob", "divisionName", adivisionName); const divisionName = helper.string("assignJob", "divisionName", adivisionName);
@ -326,6 +581,7 @@ export function NetscriptCorporation(
const divisionName = helper.string("upgradeOfficeSize", "divisionName", adivisionName); const divisionName = helper.string("upgradeOfficeSize", "divisionName", adivisionName);
const cityName = helper.string("upgradeOfficeSize", "cityName", acityName); const cityName = helper.string("upgradeOfficeSize", "cityName", acityName);
const size = helper.number("upgradeOfficeSize", "size", asize); const size = helper.number("upgradeOfficeSize", "size", asize);
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and grater than 0");
const office = getOffice(divisionName, cityName); const office = getOffice(divisionName, cityName);
const corporation = getCorporation(); const corporation = getCorporation();
UpgradeOfficeSize(corporation, office, size); UpgradeOfficeSize(corporation, office, size);
@ -335,6 +591,7 @@ export function NetscriptCorporation(
const divisionName = helper.string("throwParty", "divisionName", adivisionName); const divisionName = helper.string("throwParty", "divisionName", adivisionName);
const cityName = helper.string("throwParty", "cityName", acityName); const cityName = helper.string("throwParty", "cityName", acityName);
const costPerEmployee = helper.number("throwParty", "costPerEmployee", acostPerEmployee); const costPerEmployee = helper.number("throwParty", "costPerEmployee", acostPerEmployee);
if (costPerEmployee < 0) throw new Error("Invalid value for Cost Per Employee field! Must be numeric and grater than 0");
const office = getOffice(divisionName, cityName); const office = getOffice(divisionName, cityName);
const corporation = getCorporation(); const corporation = getCorporation();
return netscriptDelay( return netscriptDelay(
@ -429,6 +686,7 @@ export function NetscriptCorporation(
checkAccess("expandCity"); checkAccess("expandCity");
const divisionName = helper.string("expandCity", "divisionName", adivisionName); const divisionName = helper.string("expandCity", "divisionName", adivisionName);
const cityName = helper.string("expandCity", "cityName", acityName); const cityName = helper.string("expandCity", "cityName", acityName);
if (!CorporationConstants.Cities.includes(cityName)) throw new Error("Invalid city name");
const corporation = getCorporation(); const corporation = getCorporation();
const division = getDivision(divisionName); const division = getDivision(divisionName);
NewCity(corporation, division, cityName); NewCity(corporation, division, cityName);
@ -452,6 +710,7 @@ export function NetscriptCorporation(
issueDividends: function (apercent: any): void { issueDividends: function (apercent: any): void {
checkAccess("issueDividends"); checkAccess("issueDividends");
const percent = helper.number("issueDividends", "percent", apercent); const percent = helper.number("issueDividends", "percent", apercent);
if (percent < 0 || percent > 100) throw new Error("Invalid value for percent field! Must be numeric, grater than 0, and less than 100");
const corporation = getCorporation(); const corporation = getCorporation();
IssueDividends(corporation, percent); IssueDividends(corporation, percent);
}, },
@ -462,25 +721,7 @@ export function NetscriptCorporation(
checkAccess("getDivision"); checkAccess("getDivision");
const divisionName = helper.string("getDivision", "divisionName", adivisionName); const divisionName = helper.string("getDivision", "divisionName", adivisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
const cities: string[] = []; return getSafeDivision(division);
for (const office of Object.values(division.offices)) {
if (office === 0) continue;
cities.push(office.loc);
}
return {
name: division.name,
type: division.type,
awareness: division.awareness,
popularity: division.popularity,
prodMult: division.prodMult,
research: division.sciResearch.qty,
lastCycleRevenue: division.lastCycleRevenue,
lastCycleExpenses: division.lastCycleExpenses,
thisCycleRevenue: division.thisCycleRevenue,
thisCycleExpenses: division.thisCycleExpenses,
upgrades: division.upgrades,
cities: cities,
};
}, },
getCorporation: function (): CorporationInfo { getCorporation: function (): CorporationInfo {
checkAccess("getCorporation"); checkAccess("getCorporation");
@ -497,7 +738,61 @@ export function NetscriptCorporation(
issuedShares: corporation.issuedShares, issuedShares: corporation.issuedShares,
sharePrice: corporation.sharePrice, sharePrice: corporation.sharePrice,
state: corporation.state.getState(), state: corporation.state.getState(),
divisions: corporation.divisions.map((division): NSDivision => getSafeDivision(division)),
}; };
}, },
createCorporation: function (acorporationName: string, selfFund = true): boolean {
const corporationName = helper.string("createCorporation", "corporationName", acorporationName);
return createCorporation(corporationName, selfFund);
},
hasUnlockUpgrade: function (aupgradeName: any): boolean {
checkAccess("hasUnlockUpgrade");
const upgradeName = helper.string("hasUnlockUpgrade", "upgradeName", aupgradeName);
return hasUnlockUpgrade(upgradeName);
},
getUnlockUpgradeCost: function (aupgradeName: any): number {
checkAccess("getUnlockUpgradeCost");
const upgradeName = helper.string("getUnlockUpgradeCost", "upgradeName", aupgradeName);
return getUnlockUpgradeCost(upgradeName);
},
getUpgradeLevel: function (aupgradeName: any): number {
checkAccess("hasUnlockUpgrade");
const upgradeName = helper.string("getUpgradeLevel", "upgradeName", aupgradeName);
return getUpgradeLevel(upgradeName);
},
getUpgradeLevelCost: function (aupgradeName: any): number {
checkAccess("getUpgradeLevelCost");
const upgradeName = helper.string("getUpgradeLevelCost", "upgradeName", aupgradeName);
return getUpgradeLevelCost(upgradeName);
},
getExpandIndustryCost: function (aindustryName: any): number {
checkAccess("getExpandIndustryCost");
const industryName = helper.string("getExpandIndustryCost", "industryName", aindustryName);
return getExpandIndustryCost(industryName);
},
getExpandCityCost: function(): number {
checkAccess("getExpandCityCost");
return getExpandCityCost();
},
getInvestmentOffer: function(): InvestmentOffer {
checkAccess("getInvestmentOffer");
return getInvestmentOffer();
},
acceptInvestmentOffer: function(): boolean {
checkAccess("acceptInvestmentOffer");
return acceptInvestmentOffer();
},
goPublic: function(anumShares: any): boolean {
checkAccess("acceptInvestmentOffer");
const numShares = helper.number("goPublic", "numShares", anumShares);
return goPublic(numShares);
},
bribe: function(afactionName: string, aamountCash: any, aamountShares: any): boolean {
checkAccess("bribe");
const factionName = helper.string("bribe", "factionName", afactionName);
const amountCash = helper.number("bribe", "amountCash", aamountCash);
const amountShares = helper.number("bribe", "amountShares", aamountShares);
return bribe(factionName, amountCash, amountShares);
},
}; };
} }

@ -343,7 +343,7 @@ export function NetscriptSingularity(
workerScript.log("universityCourse", () => `Invalid class name: ${className}.`); workerScript.log("universityCourse", () => `Invalid class name: ${className}.`);
return false; return false;
} }
player.startClass(Router, costMult, expMult, task); player.startClass(costMult, expMult, task);
if (focus) { if (focus) {
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();
@ -433,19 +433,19 @@ export function NetscriptSingularity(
switch (stat.toLowerCase()) { switch (stat.toLowerCase()) {
case "strength".toLowerCase(): case "strength".toLowerCase():
case "str".toLowerCase(): case "str".toLowerCase():
player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymStrength); player.startClass(costMult, expMult, CONSTANTS.ClassGymStrength);
break; break;
case "defense".toLowerCase(): case "defense".toLowerCase():
case "def".toLowerCase(): case "def".toLowerCase():
player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymDefense); player.startClass(costMult, expMult, CONSTANTS.ClassGymDefense);
break; break;
case "dexterity".toLowerCase(): case "dexterity".toLowerCase():
case "dex".toLowerCase(): case "dex".toLowerCase():
player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymDexterity); player.startClass(costMult, expMult, CONSTANTS.ClassGymDexterity);
break; break;
case "agility".toLowerCase(): case "agility".toLowerCase():
case "agi".toLowerCase(): case "agi".toLowerCase():
player.startClass(Router, costMult, expMult, CONSTANTS.ClassGymAgility); player.startClass(costMult, expMult, CONSTANTS.ClassGymAgility);
break; break;
default: default:
workerScript.log("gymWorkout", () => `Invalid stat: ${stat}.`); workerScript.log("gymWorkout", () => `Invalid stat: ${stat}.`);
@ -653,7 +653,9 @@ export function NetscriptSingularity(
!( !(
player.workType == CONSTANTS.WorkTypeFaction || player.workType == CONSTANTS.WorkTypeFaction ||
player.workType == CONSTANTS.WorkTypeCompany || player.workType == CONSTANTS.WorkTypeCompany ||
player.workType == CONSTANTS.WorkTypeCompanyPartTime player.workType == CONSTANTS.WorkTypeCompanyPartTime ||
player.workType == CONSTANTS.WorkTypeCreateProgram ||
player.workType == CONSTANTS.WorkTypeStudyClass
) )
) { ) {
throw helper.makeRuntimeErrorMsg("setFocus", "Cannot change focus for current job"); throw helper.makeRuntimeErrorMsg("setFocus", "Cannot change focus for current job");
@ -1269,7 +1271,7 @@ export function NetscriptSingularity(
return false; return false;
} }
player.startCreateProgramWork(Router, p.name, create.time, create.level); player.startCreateProgramWork(p.name, create.time, create.level);
if (focus) { if (focus) {
player.startFocusing(); player.startFocusing();
Router.toWork(); Router.toWork();

@ -215,7 +215,7 @@ export interface IPlayer {
singularityStopWork(): string; singularityStopWork(): string;
startBladeburner(p: any): void; startBladeburner(p: any): void;
startFactionWork(faction: Faction): void; startFactionWork(faction: Faction): void;
startClass(router: IRouter, costMult: number, expMult: number, className: string): void; startClass(costMult: number, expMult: number, className: string): void;
startCorporation(corpName: string, additionalShares?: number): void; startCorporation(corpName: string, additionalShares?: number): void;
startCrime( startCrime(
router: IRouter, router: IRouter,
@ -247,7 +247,7 @@ export interface IPlayer {
quitJob(company: string): void; quitJob(company: string): void;
hasJob(): boolean; hasJob(): boolean;
createHacknetServer(): HacknetServer; createHacknetServer(): HacknetServer;
startCreateProgramWork(router: IRouter, programName: string, time: number, reqLevel: number): void; startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
queueAugmentation(augmentationName: string): void; queueAugmentation(augmentationName: string): void;
receiveInvite(factionName: string): void; receiveInvite(factionName: string): void;
updateSkillLevels(): void; updateSkillLevels(): void;

@ -220,7 +220,7 @@ export class PlayerObject implements IPlayer {
singularityStopWork: () => string; singularityStopWork: () => string;
startBladeburner: (p: any) => void; startBladeburner: (p: any) => void;
startFactionWork: (faction: Faction) => void; startFactionWork: (faction: Faction) => void;
startClass: (router: IRouter, costMult: number, expMult: number, className: string) => void; startClass: (costMult: number, expMult: number, className: string) => void;
startCorporation: (corpName: string, additionalShares?: number) => void; startCorporation: (corpName: string, additionalShares?: number) => void;
startCrime: ( startCrime: (
router: IRouter, router: IRouter,
@ -253,7 +253,7 @@ export class PlayerObject implements IPlayer {
hasJob: () => boolean; hasJob: () => boolean;
process: (router: IRouter, numCycles?: number) => void; process: (router: IRouter, numCycles?: number) => void;
createHacknetServer: () => HacknetServer; createHacknetServer: () => HacknetServer;
startCreateProgramWork: (router: IRouter, programName: string, time: number, reqLevel: number) => void; startCreateProgramWork: (programName: string, time: number, reqLevel: number) => void;
queueAugmentation: (augmentationName: string) => void; queueAugmentation: (augmentationName: string) => void;
receiveInvite: (factionName: string) => void; receiveInvite: (factionName: string) => void;
updateSkillLevels: () => void; updateSkillLevels: () => void;

@ -1,4 +1,5 @@
import { Corporation } from "../../Corporation/Corporation"; import { Corporation } from "../../Corporation/Corporation";
import { CorporationUnlockUpgrades } from "../../Corporation/data/CorporationUnlockUpgrades";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags"; import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { IPlayer } from "../IPlayer"; import { IPlayer } from "../IPlayer";
@ -18,5 +19,13 @@ export function startCorporation(this: IPlayer, corpName: string, additionalShar
name: corpName, name: corpName,
}); });
if (SourceFileFlags[3] === 3) {
const warehouseApi = CorporationUnlockUpgrades["7"][0];
const OfficeApi = CorporationUnlockUpgrades["8"][0];
this.corporation.unlockUpgrades[warehouseApi] = 1;
this.corporation.unlockUpgrades[OfficeApi] = 1;
}
this.corporation.totalShares += additionalShares; this.corporation.totalShares += additionalShares;
} }

@ -1253,14 +1253,12 @@ export function getWorkRepGain(this: IPlayer): number {
/* Creating a Program */ /* Creating a Program */
export function startCreateProgramWork( export function startCreateProgramWork(
this: IPlayer, this: IPlayer,
router: IRouter,
programName: string, programName: string,
time: number, time: number,
reqLevel: number, reqLevel: number,
): void { ): void {
this.resetWorkStatus(); this.resetWorkStatus();
this.isWorking = true; this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeCreateProgram; this.workType = CONSTANTS.WorkTypeCreateProgram;
//Time needed to complete work affected by hacking skill (linearly based on //Time needed to complete work affected by hacking skill (linearly based on
@ -1289,7 +1287,6 @@ export function startCreateProgramWork(
} }
this.createProgramName = programName; this.createProgramName = programName;
router.toWork();
} }
export function createProgramWork(this: IPlayer, numCycles: number): boolean { export function createProgramWork(this: IPlayer, numCycles: number): boolean {
@ -1337,10 +1334,9 @@ export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): stri
return "You've finished creating " + programName + "! The new program can be found on your home computer."; return "You've finished creating " + programName + "! The new program can be found on your home computer.";
} }
/* Studying/Taking Classes */ /* Studying/Taking Classes */
export function startClass(this: IPlayer, router: IRouter, costMult: number, expMult: number, className: string): void { export function startClass(this: IPlayer, costMult: number, expMult: number, className: string): void {
this.resetWorkStatus(); this.resetWorkStatus();
this.isWorking = true; this.isWorking = true;
this.focus = true;
this.workType = CONSTANTS.WorkTypeStudyClass; this.workType = CONSTANTS.WorkTypeStudyClass;
this.workCostMult = costMult; this.workCostMult = costMult;
this.workExpMult = expMult; this.workExpMult = expMult;
@ -1353,7 +1349,6 @@ export function startClass(this: IPlayer, router: IRouter, costMult: number, exp
this.workDexExpGainRate = earnings.workDexExpGainRate; this.workDexExpGainRate = earnings.workDexExpGainRate;
this.workAgiExpGainRate = earnings.workAgiExpGainRate; this.workAgiExpGainRate = earnings.workAgiExpGainRate;
this.workChaExpGainRate = earnings.workChaExpGainRate; this.workChaExpGainRate = earnings.workChaExpGainRate;
router.toWork();
} }
export function takeClass(this: IPlayer, numCycles: number): boolean { export function takeClass(this: IPlayer, numCycles: number): boolean {

@ -50,7 +50,9 @@ export function ProgramsRoot(): React.ReactElement {
sx={{ my: 1 }} sx={{ my: 1 }}
onClick={(event) => { onClick={(event) => {
if (!event.isTrusted) return; if (!event.isTrusted) return;
player.startCreateProgramWork(router, program.name, create.time, create.level); player.startCreateProgramWork(program.name, create.time, create.level);
player.startFocusing();
router.toWork();
}} }}
> >
{program.name} {program.name}

@ -93,6 +93,7 @@ interface Player {
jobs: any; jobs: any;
factions: string[]; factions: string[];
tor: boolean; tor: boolean;
hasCorporation: boolean;
} }
/** /**
@ -6106,7 +6107,7 @@ export interface OfficeAPI {
*/ */
assignJob(divisionName: string, cityName: string, employeeName: string, job: string): Promise<void>; assignJob(divisionName: string, cityName: string, employeeName: string, job: string): Promise<void>;
/** /**
* Assign an employee to a job. * Hire an employee.
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param cityName - Name of the city * @param cityName - Name of the city
* @returns The newly hired employee, if any * @returns The newly hired employee, if any
@ -6120,7 +6121,7 @@ export interface OfficeAPI {
*/ */
upgradeOfficeSize(divisionName: string, cityName: string, size: number): void; upgradeOfficeSize(divisionName: string, cityName: string, size: number): void;
/** /**
* Assign an employee to a job. * Throw a party for your employees
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param cityName - Name of the city * @param cityName - Name of the city
* @param costPerEmployee - Amount to spend per employee. * @param costPerEmployee - Amount to spend per employee.
@ -6140,7 +6141,7 @@ export interface OfficeAPI {
*/ */
hireAdVert(divisionName: string): void; hireAdVert(divisionName: string): void;
/** /**
* Hire AdVert. * Purchase a research
* @param divisionName - Name of the division * @param divisionName - Name of the division
* @param researchName - Name of the research * @param researchName - Name of the research
*/ */
@ -6160,6 +6161,49 @@ export interface OfficeAPI {
* @returns Employee data * @returns Employee data
*/ */
getEmployee(divisionName: string, cityName: string, employeeName: string): Employee; getEmployee(divisionName: string, cityName: string, employeeName: string): Employee;
/**
* Get the cost to Hire AdVert
* @param divisionName - Name of the division
* @returns Cost
*/
getHireAdVertCost(divisionName: string): number;
/**
* Get the number of times you have Hired AdVert
* @param divisionName - Name of the division
* @returns Number of times you have Hired AdVert
*/
getHireAdVertCount(adivisionName: string): number;
/**
* Get the cost to unlock research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns cost
*/
getResearchCost(divisionName: string, researchName: string): number;
/**
* Gets if you have unlocked a research
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @returns true is unlocked, false if not
*/
hasResearched(divisionName: string, researchName: string): boolean;
/**
* Set the auto job assignment for a job
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @param job - Name of the job
* @param amount - Number of employees to assign to that job
* @returns A promise that is fulfilled when the assignment is complete.
*/
setAutoJobAssignment(divisionName: string, cityName: string, job: string, amount: number): Promise<boolean>;
/**
* Cost to Upgrade office size.
* @param divisionName - Name of the division
* @param cityName - Name of the city
* @param size - Amount of positions to open
* @returns Cost of upgrading the office
*/
getOfficeSizeUpgradeCost(divisionName: string, cityName: string, asize: number): number;
} }
/** /**
@ -6328,6 +6372,21 @@ export interface WarehouseAPI {
designInvest: number, designInvest: number,
marketingInvest: number, marketingInvest: number,
): void; ): void;
/**
* Gets the cost to purchase a warehouse
* @returns cost
*/
getPurchaseWarehouseCost(): number;
/**
* Gets the cost to upgrade a warehouse to the next level
* @returns cost to upgrade
*/
getUpgradeWarehouseCost(adivisionName: any, acityName: any): number;
/**
* Check if you have a warehouse in city
* @returns true if warehouse is present, false if not
*/
hasWarehouse(adivisionName: any, acityName: any): boolean;
} }
/** /**
@ -6335,6 +6394,74 @@ export interface WarehouseAPI {
* @public * @public
*/ */
export interface Corporation extends WarehouseAPI, OfficeAPI { export interface Corporation extends WarehouseAPI, OfficeAPI {
/**
* 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
*/
createCorporation(corporationName: string, selfFund: boolean): boolean;
/**
* Check if you have a one time unlockable upgrade
* @param upgradeName - Name of the upgrade
* @returns true if unlocked and false if not
*/
hasUnlockUpgrade(upgradeName: string): boolean;
/**
* Gets the cost to unlock a one time unlockable upgrade
* @param upgradeName - Name of the upgrade
* @returns cost of the upgrade
*/
getUnlockUpgradeCost(upgradeName: string): number;
/**
* Get the level of a levelable upgrade
* @param upgradeName - Name of the upgrade
* @returns the level of the upgrade
*/
getUpgradeLevel(upgradeName: string): number;
/**
* Gets the cost to unlock the next level of a levelable upgrade
* @param upgradeName - Name of the upgrade
* @returns cost of the upgrade
*/
getUpgradeLevelCost(upgradeName: string): number;
/**
* Gets the cost to expand into a new industry
* @param industryName - Name of the industry
* @returns cost
*/
getExpandIndustryCost(industryName: string): number;
/**
* Gets the cost to expand into a new city
* @returns cost
*/
getExpandCityCost(): number;
/**
* Get an offer for investment based on you companies current valuation
* @returns An offer of investment
*/
getInvestmentOffer(): InvestmentOffer;
/**
* Accept investment based on you companies current valuation
* @remarks
* Is based on current valuation and will not honer a specific Offer
* @returns An offer of investment
*/
acceptInvestmentOffer(): boolean;
/**
* Go public
* @param numShares - number of shares you would like to issue for your IPO
* @returns true if you successfully go public, false if not
*/
goPublic(numShares: number): boolean;
/**
* Bribe a faction
* @param factionName - Faction name
* @param amountCash - Amount of money to bribe
* @param amountShares - Amount of shares to bribe
* @returns True if successful, false if not
*/
bribe(factionName: string, amountCash: number, amountShares: number): boolean;
/** /**
* Get corporation data * Get corporation data
* @returns Corporation data * @returns Corporation data
@ -6359,7 +6486,7 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
*/ */
expandCity(divisionName: string, cityName: string): void; expandCity(divisionName: string, cityName: string): void;
/** /**
* Unlock an upgrade. * Unlock an upgrade
* @param upgradeName - Name of the upgrade * @param upgradeName - Name of the upgrade
*/ */
unlockUpgrade(upgradeName: string): void; unlockUpgrade(upgradeName: string): void;
@ -6402,6 +6529,8 @@ interface CorporationInfo {
sharePrice: number; sharePrice: number;
/** State of the corporation. Possible states are START, PURCHASE, PRODUCTION, SALE, EXPORT. */ /** State of the corporation. Possible states are START, PURCHASE, PRODUCTION, SALE, EXPORT. */
state: string; state: string;
/** Array of all divisions */
divisions: Division[];
} }
/** /**
@ -6445,6 +6574,12 @@ interface Product {
pCost: number; pCost: number;
/** Sell cost, can be "MP+5" */ /** Sell cost, can be "MP+5" */
sCost: string | number; sCost: string | number;
/** Data refers to the production, sale, and quantity of the products
* These values are specific to a city
* For each city, the data is [qty, prod, sell] */
cityData: {[key: string]:number[]};
/** Creation progress - A number between 0-100 representing percentage */
developmentProgress: number;
} }
/** /**
@ -6458,6 +6593,10 @@ interface Material {
qty: number; qty: number;
/** Quality of the material */ /** Quality of the material */
qlt: number; qlt: number;
/** Amount of material produced */
prod: number;
/** Amount of material sold */
sell: number;
} }
/** /**
@ -6473,6 +6612,8 @@ interface Warehouse {
size: number; size: number;
/** Used space in the warehouse */ /** Used space in the warehouse */
sizeUsed: number; sizeUsed: number;
/** Smart Supply status in the warehouse */
smartSupplyEnabled: boolean;
} }
/** /**
@ -6543,6 +6684,21 @@ interface Division {
upgrades: number[]; upgrades: number[];
/** Cities in which this division has expanded */ /** Cities in which this division has expanded */
cities: string[]; cities: string[];
/** Products developed by this division */
products: string[];
}
/**
* Corporation investment offer
* @public
*/
interface InvestmentOffer {
/** Amount of funds you will get from this investment */
funds: number;
/** Amount of share you will give in exchange for this investment */
shares: number;
/** Current round of funding (max 4) */
round: number;
} }
/** /**

@ -32,9 +32,13 @@ import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import Table from "@mui/material/Table";
import TableCell from "@mui/material/TableCell";
import TableRow from "@mui/material/TableRow";
import TableBody from "@mui/material/TableBody";
import { PromptEvent } from "../../ui/React/PromptManager"; import { PromptEvent } from "../../ui/React/PromptManager";
import { Modal } from "../../ui/React/Modal";
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts"; import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
@ -109,6 +113,7 @@ export function Root(props: IProps): React.ReactElement {
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null); const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
const [ram, setRAM] = useState("RAM: ???"); const [ram, setRAM] = useState("RAM: ???");
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
const [updatingRam, setUpdatingRam] = useState(false); const [updatingRam, setUpdatingRam] = useState(false);
const [decorations, setDecorations] = useState<string[]>([]); const [decorations, setDecorations] = useState<string[]>([]);
@ -121,6 +126,8 @@ export function Root(props: IProps): React.ReactElement {
vim: props.vim || Settings.MonacoVim, vim: props.vim || Settings.MonacoVim,
}); });
const [ramInfoOpen, setRamInfoOpen] = useState(false);
// Prevent Crash if script is open on deleted server // Prevent Crash if script is open on deleted server
openScripts = openScripts.filter((script) => { openScripts = openScripts.filter((script) => {
return GetServer(script.hostname) !== null; return GetServer(script.hostname) !== null;
@ -198,7 +205,7 @@ export function Root(props: IProps): React.ReactElement {
}); });
editor.focus(); editor.focus();
}); });
} catch {} } catch { }
} else if (!options.vim) { } else if (!options.vim) {
// Whem vim mode is disabled // Whem vim mode is disabled
vimEditor?.dispose(); vimEditor?.dispose();
@ -222,8 +229,9 @@ export function Root(props: IProps): React.ReactElement {
const debouncedSetRAM = useMemo( const debouncedSetRAM = useMemo(
() => () =>
debounce((s) => { debounce((s, e) => {
setRAM(s); setRAM(s);
setRamEntries(e);
setUpdatingRam(false); setUpdatingRam(false);
}, 300), }, 300),
[], [],
@ -231,28 +239,34 @@ export function Root(props: IProps): React.ReactElement {
async function updateRAM(newCode: string): Promise<void> { async function updateRAM(newCode: string): Promise<void> {
if (currentScript != null && currentScript.fileName.endsWith(".txt")) { if (currentScript != null && currentScript.fileName.endsWith(".txt")) {
debouncedSetRAM(""); debouncedSetRAM("N/A", [["N/A", ""]]);
return; return;
} }
setUpdatingRam(true); setUpdatingRam(true);
const codeCopy = newCode + ""; const codeCopy = newCode + "";
const ramUsage = await calculateRamUsage(props.player, codeCopy, props.player.getCurrentServer().scripts); const ramUsage = await calculateRamUsage(props.player, codeCopy, props.player.getCurrentServer().scripts);
if (ramUsage.cost > 0) { if (ramUsage.cost > 0) {
debouncedSetRAM("RAM: " + numeralWrapper.formatRAM(ramUsage.cost)); const entries = ramUsage.entries?.sort((a, b) => b.cost - a.cost) ?? [];
const entriesDisp = [];
for (const entry of entries) {
entriesDisp.push([`${entry.name} (${entry.type})`, numeralWrapper.formatRAM(entry.cost)]);
}
debouncedSetRAM("RAM: " + numeralWrapper.formatRAM(ramUsage.cost), entriesDisp);
return; return;
} }
switch (ramUsage.cost) { switch (ramUsage.cost) {
case RamCalculationErrorCode.ImportError: { case RamCalculationErrorCode.ImportError: {
debouncedSetRAM("RAM: Import Error"); debouncedSetRAM("RAM: Import Error", [["Import Error", ""]]);
break; break;
} }
case RamCalculationErrorCode.URLImportError: { case RamCalculationErrorCode.URLImportError: {
debouncedSetRAM("RAM: HTTP Import Error"); debouncedSetRAM("RAM: HTTP Import Error", [["HTTP Import Error", ""]]);
break; break;
} }
case RamCalculationErrorCode.SyntaxError: case RamCalculationErrorCode.SyntaxError:
default: { default: {
debouncedSetRAM("RAM: Syntax Error"); debouncedSetRAM("RAM: Syntax Error", [["Syntax Error", ""]]);
break; break;
} }
} }
@ -432,7 +446,7 @@ export function Root(props: IProps): React.ReactElement {
} }
try { try {
infLoop(newCode); infLoop(newCode);
} catch (err) {} } catch (err) { }
} }
function saveScript(scriptToSave: OpenScript): void { function saveScript(scriptToSave: OpenScript): void {
@ -714,7 +728,9 @@ export function Root(props: IProps): React.ReactElement {
ref={provided.innerRef} ref={provided.innerRef}
{...provided.droppableProps} {...provided.droppableProps}
style={{ style={{
backgroundColor: snapshot.isDraggingOver ? "#1F2022" : Settings.theme.backgroundprimary, backgroundColor: snapshot.isDraggingOver
? Settings.theme.backgroundsecondary
: Settings.theme.backgroundprimary,
overflowX: "scroll", overflowX: "scroll",
}} }}
> >
@ -738,12 +754,14 @@ export function Root(props: IProps): React.ReactElement {
> >
<Button <Button
onClick={() => onTabClick(index)} onClick={() => onTabClick(index)}
style={{ style={
background: currentScript?.fileName === openScripts[index].fileName ? {
currentScript?.fileName === openScripts[index].fileName background: Settings.theme.button,
? Settings.theme.secondarydark color: Settings.theme.primary
: "", } : {
}} background: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary
}}
> >
{hostname}:~/{fileName} {dirty(index)} {hostname}:~/{fileName} {dirty(index)}
</Button> </Button>
@ -752,10 +770,13 @@ export function Root(props: IProps): React.ReactElement {
style={{ style={{
maxWidth: "20px", maxWidth: "20px",
minWidth: "20px", minWidth: "20px",
background: ...(currentScript?.fileName === openScripts[index].fileName ? {
currentScript?.fileName === openScripts[index].fileName background: Settings.theme.button,
? Settings.theme.secondarydark color: Settings.theme.primary
: "", } : {
background: Settings.theme.backgroundsecondary,
color: Settings.theme.secondary
})
}} }}
> >
x x
@ -792,10 +813,11 @@ export function Root(props: IProps): React.ReactElement {
></Box> ></Box>
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center"> <Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
<Button startIcon={<SettingsIcon />} onClick={() => setOptionsOpen(true)} sx={{ mr: 1 }}>Options</Button>
<Button onClick={beautify}>Beautify</Button> <Button onClick={beautify}>Beautify</Button>
<Typography color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }}> <Button color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }} onClick={() => { setRamInfoOpen(true) }}>
{ram} {ram}
</Typography> </Button>
<Button onClick={save}>Save (Ctrl/Cmd + s)</Button> <Button onClick={save}>Save (Ctrl/Cmd + s)</Button>
<Button onClick={props.router.toTerminal}>Close (Ctrl/Cmd + b)</Button> <Button onClick={props.router.toTerminal}>Close (Ctrl/Cmd + b)</Button>
<Typography sx={{ mx: 1 }}> <Typography sx={{ mx: 1 }}>
@ -809,12 +831,6 @@ export function Root(props: IProps): React.ReactElement {
Full Full
</Link> </Link>
</Typography> </Typography>
<IconButton style={{ marginLeft: "auto" }} onClick={() => setOptionsOpen(true)}>
<>
<SettingsIcon />
options
</>
</IconButton>
</Box> </Box>
<OptionsModal <OptionsModal
open={optionsOpen} open={optionsOpen}
@ -835,6 +851,20 @@ export function Root(props: IProps): React.ReactElement {
Settings.MonacoVim = options.vim; Settings.MonacoVim = options.vim;
}} }}
/> />
<Modal open={ramInfoOpen} onClose={() => setRamInfoOpen(false)}>
<Table>
<TableBody>
{ramEntries.map(([n, r]) => (
<React.Fragment key={n + r}>
<TableRow>
<TableCell sx={{ color: Settings.theme.primary }}>{n}</TableCell>
<TableCell align="right" sx={{ color: Settings.theme.primary }}>{r}</TableCell>
</TableRow>
</React.Fragment>
))}
</TableBody>
</Table>
</Modal>
</div> </div>
<div <div
style={{ style={{

@ -362,7 +362,7 @@ export function refreshTheme(): void {
}, },
}); });
document.body.style.backgroundColor = theme.colors.black?.toString() ?? "black"; document.body.style.backgroundColor = theme.colors.backgroundprimary?.toString() ?? "black";
} }
refreshTheme(); refreshTheme();

@ -20,3 +20,13 @@ Used to synchronize the achievements info in steamworks to the game's data.json
# Get your key here: https://steamcommunity.com/dev/apikey # Get your key here: https://steamcommunity.com/dev/apikey
node fetch-steam-achievements-data.js DEVKEYDEVKEYDEVKEYDEVKEY node fetch-steam-achievements-data.js DEVKEYDEVKEYDEVKEYDEVKEY
``` ```
## Changelog script
Used to generate a basic git commit log (in markdown) between commit A & commit B
**Usage**
```sh
# Will default to HEAD if second is not specified.
./tools/changelog.sh 9a0062b 05cbc25
```

23
tools/changelog.sh Normal file

@ -0,0 +1,23 @@
#!/bin/sh
version=${2:-HEAD}
cat >> temp_changelog.md << EOF
# v1.X.X ($version)
Description Here.
Compare Commits [on github](https://github.com/danielyxie/bitburner/compare/$1...$version).
---
### Commits
EOF
git log $1...${version} \
--pretty=format:'* [`%h`]([https://github.com/danielyxie/bitburner/commit/%H): %s (by %aN on %ad) %n' \
--date=short \
--no-merges >> temp_changelog.md
# --reverse >> temp_changelog.md
rm -f changelog_$1_${version}.md
mv temp_changelog.md changelog_$1_${version}.md