mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
CORP: rework (#428)
* corp overhaul: Corp production quality now depends on materials * corp overhaul: Product price can be set separately for each city * corp overhaul: export uses relatives * corp overhaul: ignore energy in quality * corp overhaul: getProduct() is city dependant * corp overhaul: bulkbuy available from start * corp overhaul: add multibuy for leveled upgrads * corp overhaul: changes to UI * corp overhaul: base quality 1, reqmat changes * corp overhaul: puchased material quality is 1 * corp overhaul: get rid of the text box from ta2 * corp overhaul: sold shares limitations * corp overhaul: coffee -> tea, training -> intern * corp overhaul: smartsupply has multiple options * corp overhaul: restart, literature, investore, ui * corp overhaul: nerf advertising * corp overhaul: bunch of stuff
This commit is contained in:
parent
5ffefcca80
commit
1f98eecb57
6
.gitignore
vendored
6
.gitignore
vendored
@ -20,9 +20,9 @@ dist/assets
|
|||||||
dist/*.worker.*
|
dist/*.worker.*
|
||||||
|
|
||||||
# tmp folder for build and electron
|
# tmp folder for build and electron
|
||||||
.app
|
.app
|
||||||
.package
|
.package
|
||||||
.build
|
.build
|
||||||
|
|
||||||
# editor files
|
# editor files
|
||||||
.vscode
|
.vscode
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [CorpConstants](./bitburner.corpconstants.md) > [coffeeCostPerEmployee](./bitburner.corpconstants.coffeecostperemployee.md)
|
|
||||||
|
|
||||||
## CorpConstants.coffeeCostPerEmployee property
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
coffeeCostPerEmployee: number;
|
|
||||||
```
|
|
@ -19,7 +19,6 @@ interface CorpConstants
|
|||||||
| [baseProductProfitMult](./bitburner.corpconstants.baseproductprofitmult.md) | | number | |
|
| [baseProductProfitMult](./bitburner.corpconstants.baseproductprofitmult.md) | | number | |
|
||||||
| [bribeAmountPerReputation](./bitburner.corpconstants.bribeamountperreputation.md) | | number | |
|
| [bribeAmountPerReputation](./bitburner.corpconstants.bribeamountperreputation.md) | | number | |
|
||||||
| [bribeThreshold](./bitburner.corpconstants.bribethreshold.md) | | number | |
|
| [bribeThreshold](./bitburner.corpconstants.bribethreshold.md) | | number | |
|
||||||
| [coffeeCostPerEmployee](./bitburner.corpconstants.coffeecostperemployee.md) | | number | |
|
|
||||||
| [dividendMaxRate](./bitburner.corpconstants.dividendmaxrate.md) | | number | |
|
| [dividendMaxRate](./bitburner.corpconstants.dividendmaxrate.md) | | number | |
|
||||||
| [employeeRaiseAmount](./bitburner.corpconstants.employeeraiseamount.md) | | number | |
|
| [employeeRaiseAmount](./bitburner.corpconstants.employeeraiseamount.md) | | number | |
|
||||||
| [employeeSalaryMultiplier](./bitburner.corpconstants.employeesalarymultiplier.md) | | number | Conversion factor for employee stats to initial salary |
|
| [employeeSalaryMultiplier](./bitburner.corpconstants.employeesalarymultiplier.md) | | number | Conversion factor for employee stats to initial salary |
|
||||||
@ -31,7 +30,7 @@ interface CorpConstants
|
|||||||
| [marketCyclesPerEmployeeRaise](./bitburner.corpconstants.marketcyclesperemployeeraise.md) | | number | |
|
| [marketCyclesPerEmployeeRaise](./bitburner.corpconstants.marketcyclesperemployeeraise.md) | | number | |
|
||||||
| [materialNames](./bitburner.corpconstants.materialnames.md) | | [CorpMaterialName](./bitburner.corpmaterialname.md)<!-- -->\[\] | Names of all materials |
|
| [materialNames](./bitburner.corpconstants.materialnames.md) | | [CorpMaterialName](./bitburner.corpmaterialname.md)<!-- -->\[\] | Names of all materials |
|
||||||
| [maxProductsBase](./bitburner.corpconstants.maxproductsbase.md) | | number | Max products for a division without upgrades |
|
| [maxProductsBase](./bitburner.corpconstants.maxproductsbase.md) | | number | Max products for a division without upgrades |
|
||||||
| [minEmployeeDecay](./bitburner.corpconstants.minemployeedecay.md) | | number | The minimum decay value for happiness/morale/energy |
|
| [minEmployeeDecay](./bitburner.corpconstants.minemployeedecay.md) | | number | The minimum decay value for morale/energy |
|
||||||
| [officeInitialCost](./bitburner.corpconstants.officeinitialcost.md) | | number | |
|
| [officeInitialCost](./bitburner.corpconstants.officeinitialcost.md) | | number | |
|
||||||
| [officeInitialSize](./bitburner.corpconstants.officeinitialsize.md) | | number | |
|
| [officeInitialSize](./bitburner.corpconstants.officeinitialsize.md) | | number | |
|
||||||
| [officeSizeUpgradeCostBase](./bitburner.corpconstants.officesizeupgradecostbase.md) | | number | |
|
| [officeSizeUpgradeCostBase](./bitburner.corpconstants.officesizeupgradecostbase.md) | | number | |
|
||||||
@ -42,6 +41,7 @@ interface CorpConstants
|
|||||||
| [sellSharesCooldown](./bitburner.corpconstants.sellsharescooldown.md) | | number | Cooldown for selling shares in game cycles (1 game cycle = 200ms) |
|
| [sellSharesCooldown](./bitburner.corpconstants.sellsharescooldown.md) | | number | Cooldown for selling shares in game cycles (1 game cycle = 200ms) |
|
||||||
| [sharesPerPriceUpdate](./bitburner.corpconstants.sharesperpriceupdate.md) | | number | When selling large number of shares, price is dynamically updated for every batch of this amount |
|
| [sharesPerPriceUpdate](./bitburner.corpconstants.sharesperpriceupdate.md) | | number | When selling large number of shares, price is dynamically updated for every batch of this amount |
|
||||||
| [stateNames](./bitburner.corpconstants.statenames.md) | | [CorpStateName](./bitburner.corpstatename.md)<!-- -->\[\] | Names of all corporation game states |
|
| [stateNames](./bitburner.corpconstants.statenames.md) | | [CorpStateName](./bitburner.corpstatename.md)<!-- -->\[\] | Names of all corporation game states |
|
||||||
|
| [teaCostPerEmployee](./bitburner.corpconstants.teacostperemployee.md) | | number | |
|
||||||
| [unlockNames](./bitburner.corpconstants.unlocknames.md) | | [CorpUnlockName](./bitburner.corpunlockname.md)<!-- -->\[\] | Names of all one-time corporation-wide unlocks |
|
| [unlockNames](./bitburner.corpconstants.unlocknames.md) | | [CorpUnlockName](./bitburner.corpunlockname.md)<!-- -->\[\] | Names of all one-time corporation-wide unlocks |
|
||||||
| [upgradeNames](./bitburner.corpconstants.upgradenames.md) | | [CorpUpgradeName](./bitburner.corpupgradename.md)<!-- -->\[\] | Names of all corporation-wide upgrades |
|
| [upgradeNames](./bitburner.corpconstants.upgradenames.md) | | [CorpUpgradeName](./bitburner.corpupgradename.md)<!-- -->\[\] | Names of all corporation-wide upgrades |
|
||||||
| [warehouseInitialCost](./bitburner.corpconstants.warehouseinitialcost.md) | | number | |
|
| [warehouseInitialCost](./bitburner.corpconstants.warehouseinitialcost.md) | | number | |
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## CorpConstants.minEmployeeDecay property
|
## CorpConstants.minEmployeeDecay property
|
||||||
|
|
||||||
The minimum decay value for happiness/morale/energy
|
The minimum decay value for morale/energy
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
|
11
markdown/bitburner.corpconstants.teacostperemployee.md
Normal file
11
markdown/bitburner.corpconstants.teacostperemployee.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [CorpConstants](./bitburner.corpconstants.md) > [teaCostPerEmployee](./bitburner.corpconstants.teacostperemployee.md)
|
||||||
|
|
||||||
|
## CorpConstants.teaCostPerEmployee property
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
teaCostPerEmployee: number;
|
||||||
|
```
|
@ -14,6 +14,6 @@ type CorpEmployeePosition =
|
|||||||
| "Business"
|
| "Business"
|
||||||
| "Management"
|
| "Management"
|
||||||
| "Research & Development"
|
| "Research & Development"
|
||||||
| "Training"
|
| "Intern"
|
||||||
| "Unassigned";
|
| "Unassigned";
|
||||||
```
|
```
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type CorpIndustryName =
|
type CorpIndustryName =
|
||||||
| "Energy"
|
| "Spring Water"
|
||||||
| "Water Utilities"
|
| "Water Utilities"
|
||||||
| "Agriculture"
|
| "Agriculture"
|
||||||
| "Fishing"
|
| "Fishing"
|
||||||
| "Mining"
|
| "Mining"
|
||||||
| "Food"
|
| "Refinery"
|
||||||
|
| "Restaurant"
|
||||||
| "Tobacco"
|
| "Tobacco"
|
||||||
| "Chemical"
|
| "Chemical"
|
||||||
| "Pharmaceutical"
|
| "Pharmaceutical"
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type CorpMaterialName =
|
type CorpMaterialName =
|
||||||
|
| "Minerals"
|
||||||
|
| "Ore"
|
||||||
| "Water"
|
| "Water"
|
||||||
| "Energy"
|
|
||||||
| "Food"
|
| "Food"
|
||||||
| "Plants"
|
| "Plants"
|
||||||
| "Metal"
|
| "Metal"
|
||||||
|
@ -16,7 +16,7 @@ buyBackShares(amount: number): void;
|
|||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| amount | number | Amount of shares to buy back. |
|
| amount | number | Amount of shares to buy back, must be integer and larger than 0 |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ sellShares(amount: number): void;
|
|||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| amount | number | Amount of shares to sell. |
|
| amount | number | Amount of shares to sell, must be integer between 1 and 100t |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ interface Material
|
|||||||
| [prod](./bitburner.material.prod.md) | | number | Amount of material produced |
|
| [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 |
|
||||||
|
| [sAmt](./bitburner.material.samt.md) | | string \| number | Sell amount, can be "PROD/2" |
|
||||||
| [sCost](./bitburner.material.scost.md) | | string \| number | Sell cost, can be "MP+5" |
|
| [sCost](./bitburner.material.scost.md) | | string \| number | Sell cost, can be "MP+5" |
|
||||||
| [sell](./bitburner.material.sell.md) | | number | Amount of material sold |
|
| [sell](./bitburner.material.sell.md) | | number | Amount of material sold |
|
||||||
|
|
||||||
|
13
markdown/bitburner.material.samt.md
Normal file
13
markdown/bitburner.material.samt.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Material](./bitburner.material.md) > [sAmt](./bitburner.material.samt.md)
|
||||||
|
|
||||||
|
## Material.sAmt property
|
||||||
|
|
||||||
|
Sell amount, can be "PROD/2"
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
sAmt: string | number;
|
||||||
|
```
|
@ -1,13 +0,0 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [Office](./bitburner.office.md) > [avgHap](./bitburner.office.avghap.md)
|
|
||||||
|
|
||||||
## Office.avgHap property
|
|
||||||
|
|
||||||
Average happiness of the employees
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
avgHap: number;
|
|
||||||
```
|
|
@ -1,13 +0,0 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [Office](./bitburner.office.md) > [maxHap](./bitburner.office.maxhap.md)
|
|
||||||
|
|
||||||
## Office.maxHap property
|
|
||||||
|
|
||||||
Maximum happiness of the employees
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
maxHap: number;
|
|
||||||
```
|
|
@ -17,14 +17,12 @@ export interface Office
|
|||||||
| Property | Modifiers | Type | Description |
|
| Property | Modifiers | Type | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| [avgEne](./bitburner.office.avgene.md) | | number | Average energy of the employees |
|
| [avgEne](./bitburner.office.avgene.md) | | number | Average energy of the employees |
|
||||||
| [avgHap](./bitburner.office.avghap.md) | | number | Average happiness of the employees |
|
|
||||||
| [avgMor](./bitburner.office.avgmor.md) | | number | Average morale of the employees |
|
| [avgMor](./bitburner.office.avgmor.md) | | number | Average morale of the employees |
|
||||||
| [employeeJobs](./bitburner.office.employeejobs.md) | | Record<[CorpEmployeePosition](./bitburner.corpemployeeposition.md)<!-- -->, number> | Positions of the employees |
|
| [employeeJobs](./bitburner.office.employeejobs.md) | | Record<[CorpEmployeePosition](./bitburner.corpemployeeposition.md)<!-- -->, number> | Positions of the employees |
|
||||||
| [employeeProd](./bitburner.office.employeeprod.md) | | Record<[CorpEmployeePosition](./bitburner.corpemployeeposition.md)<!-- -->, number> | Production of the employees |
|
| [employeeProd](./bitburner.office.employeeprod.md) | | Record<[CorpEmployeePosition](./bitburner.corpemployeeposition.md)<!-- -->, number> | Production of the employees |
|
||||||
| [employees](./bitburner.office.employees.md) | | number | Amount of employees |
|
| [employees](./bitburner.office.employees.md) | | number | Amount of employees |
|
||||||
| [loc](./bitburner.office.loc.md) | | [CityName](./bitburner.cityname.md) | City of the office |
|
| [loc](./bitburner.office.loc.md) | | [CityName](./bitburner.cityname.md) | City of the office |
|
||||||
| [maxEne](./bitburner.office.maxene.md) | | number | Maximum amount of energy of the employees |
|
| [maxEne](./bitburner.office.maxene.md) | | number | Maximum amount of energy of the employees |
|
||||||
| [maxHap](./bitburner.office.maxhap.md) | | number | Maximum happiness of the employees |
|
|
||||||
| [maxMor](./bitburner.office.maxmor.md) | | number | Maximum morale of the employees |
|
| [maxMor](./bitburner.office.maxmor.md) | | number | Maximum morale of the employees |
|
||||||
| [size](./bitburner.office.size.md) | | number | Maximum number of employee |
|
| [size](./bitburner.office.size.md) | | number | Maximum number of employee |
|
||||||
| [totalExperience](./bitburner.office.totalexperience.md) | | number | Total experience of all employees |
|
| [totalExperience](./bitburner.office.totalexperience.md) | | number | Total experience of all employees |
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [OfficeAPI](./bitburner.officeapi.md) > [buyCoffee](./bitburner.officeapi.buycoffee.md)
|
[Home](./index.md) > [bitburner](./bitburner.md) > [OfficeAPI](./bitburner.officeapi.md) > [buyTea](./bitburner.officeapi.buytea.md)
|
||||||
|
|
||||||
## OfficeAPI.buyCoffee() method
|
## OfficeAPI.buyTea() method
|
||||||
|
|
||||||
Buy coffee for your employees
|
Buy tea for your employees
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
buyCoffee(divisionName: string, city: CityName | `${CityName}`): boolean;
|
buyTea(divisionName: string, city: CityName | `${CityName}`): boolean;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -23,5 +23,5 @@ buyCoffee(divisionName: string, city: CityName | `${CityName}`): boolean;
|
|||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
|
||||||
true if buying coffee was successful, false otherwise
|
true if buying tea was successful, false otherwise
|
||||||
|
|
@ -20,7 +20,7 @@ requires the Office API upgrade from your corporation.
|
|||||||
|
|
||||||
| Method | Description |
|
| Method | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| [buyCoffee(divisionName, city)](./bitburner.officeapi.buycoffee.md) | Buy coffee for your employees |
|
| [buyTea(divisionName, city)](./bitburner.officeapi.buytea.md) | Buy tea for your employees |
|
||||||
| [getHireAdVertCost(divisionName)](./bitburner.officeapi.gethireadvertcost.md) | Get the cost to hire AdVert. |
|
| [getHireAdVertCost(divisionName)](./bitburner.officeapi.gethireadvertcost.md) | Get the cost to hire AdVert. |
|
||||||
| [getHireAdVertCount(divisionName)](./bitburner.officeapi.gethireadvertcount.md) | Get the number of times you have hired AdVert. |
|
| [getHireAdVertCount(divisionName)](./bitburner.officeapi.gethireadvertcount.md) | Get the number of times you have hired AdVert. |
|
||||||
| [getOffice(divisionName, city)](./bitburner.officeapi.getoffice.md) | Get data about an office |
|
| [getOffice(divisionName, city)](./bitburner.officeapi.getoffice.md) | Get data about an office |
|
||||||
|
@ -24,5 +24,5 @@ throwParty(divisionName: string, city: CityName | `${CityName}`, costPerEmployee
|
|||||||
|
|
||||||
number
|
number
|
||||||
|
|
||||||
Multiplier for happiness and morale, or zero on failure
|
Multiplier for morale, or zero on failure
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [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\]
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
cityData: Record<CityName | `${CityName}`, number[]>;
|
|
||||||
```
|
|
13
markdown/bitburner.product.effrat.md
Normal file
13
markdown/bitburner.product.effrat.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [effRat](./bitburner.product.effrat.md)
|
||||||
|
|
||||||
|
## Product.effRat property
|
||||||
|
|
||||||
|
Effective rating
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
effRat: number;
|
||||||
|
```
|
@ -16,13 +16,17 @@ interface Product
|
|||||||
|
|
||||||
| Property | Modifiers | Type | Description |
|
| Property | Modifiers | Type | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| [cityData](./bitburner.product.citydata.md) | | Record<[CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\`, 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 \| undefined | Competition for the product, only present if "Market Research - Competition" unlocked |
|
| [cmp](./bitburner.product.cmp.md) | | number \| undefined | Competition for the product, only present if "Market Research - Competition" unlocked |
|
||||||
| [developmentProgress](./bitburner.product.developmentprogress.md) | | number | Creation progress - A number between 0-100 representing percentage |
|
| [developmentProgress](./bitburner.product.developmentprogress.md) | | number | Creation progress - A number between 0-100 representing percentage |
|
||||||
| [dmd](./bitburner.product.dmd.md) | | number \| undefined | Demand for the product, only present if "Market Research - Demand" unlocked |
|
| [dmd](./bitburner.product.dmd.md) | | number \| undefined | Demand for the product, only present if "Market Research - Demand" unlocked |
|
||||||
|
| [effRat](./bitburner.product.effrat.md) | | number | Effective rating |
|
||||||
| [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 |
|
||||||
|
| [prod](./bitburner.product.prod.md) | | number | Amount of product produced |
|
||||||
| [properties](./bitburner.product.properties.md) | | { \[key: string\]: number } | Product Properties. The data is {<!-- -->qlt, per, dur, rel, aes, fea<!-- -->} |
|
| [properties](./bitburner.product.properties.md) | | { \[key: string\]: number } | Product Properties. The data is {<!-- -->qlt, per, dur, rel, aes, fea<!-- -->} |
|
||||||
|
| [qty](./bitburner.product.qty.md) | | number | Amount of product |
|
||||||
| [rat](./bitburner.product.rat.md) | | number | Product Rating |
|
| [rat](./bitburner.product.rat.md) | | number | Product Rating |
|
||||||
| [sCost](./bitburner.product.scost.md) | | string \| number | Sell cost, can be "MP+5" |
|
| [sAmt](./bitburner.product.samt.md) | | string | Sell amount, can be "PROD/2" |
|
||||||
|
| [sCost](./bitburner.product.scost.md) | | string | Sell cost, can be "MP+5" |
|
||||||
|
| [sell](./bitburner.product.sell.md) | | number | Amount of product sold |
|
||||||
|
|
||||||
|
13
markdown/bitburner.product.prod.md
Normal file
13
markdown/bitburner.product.prod.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [prod](./bitburner.product.prod.md)
|
||||||
|
|
||||||
|
## Product.prod property
|
||||||
|
|
||||||
|
Amount of product produced
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
prod: number;
|
||||||
|
```
|
13
markdown/bitburner.product.qty.md
Normal file
13
markdown/bitburner.product.qty.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [qty](./bitburner.product.qty.md)
|
||||||
|
|
||||||
|
## Product.qty property
|
||||||
|
|
||||||
|
Amount of product
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
qty: number;
|
||||||
|
```
|
13
markdown/bitburner.product.samt.md
Normal file
13
markdown/bitburner.product.samt.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [sAmt](./bitburner.product.samt.md)
|
||||||
|
|
||||||
|
## Product.sAmt property
|
||||||
|
|
||||||
|
Sell amount, can be "PROD/2"
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
sAmt: string;
|
||||||
|
```
|
@ -9,5 +9,5 @@ Sell cost, can be "MP+5"
|
|||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
sCost: string | number;
|
sCost: string;
|
||||||
```
|
```
|
||||||
|
13
markdown/bitburner.product.sell.md
Normal file
13
markdown/bitburner.product.sell.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [bitburner](./bitburner.md) > [Product](./bitburner.product.md) > [sell](./bitburner.product.sell.md)
|
||||||
|
|
||||||
|
## Product.sell property
|
||||||
|
|
||||||
|
Amount of product sold
|
||||||
|
|
||||||
|
**Signature:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
sell: number;
|
||||||
|
```
|
@ -9,7 +9,7 @@ Get product data
|
|||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
getProduct(divisionName: string, productName: string): Product;
|
getProduct(divisionName: string, city: CityName | `${CityName}`, productName: string): Product;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -17,6 +17,7 @@ getProduct(divisionName: string, productName: string): Product;
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| divisionName | string | Name of the division |
|
| divisionName | string | Name of the division |
|
||||||
|
| city | [CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\` | Name of the city |
|
||||||
| productName | string | Name of the product |
|
| productName | string | Name of the product |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
@ -26,7 +26,7 @@ Requires the Warehouse API upgrade from your corporation.
|
|||||||
| [discontinueProduct(divisionName, productName)](./bitburner.warehouseapi.discontinueproduct.md) | Discontinue a product. |
|
| [discontinueProduct(divisionName, productName)](./bitburner.warehouseapi.discontinueproduct.md) | Discontinue a product. |
|
||||||
| [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, city, materialName)](./bitburner.warehouseapi.getmaterial.md) | Get material data |
|
| [getMaterial(divisionName, city, materialName)](./bitburner.warehouseapi.getmaterial.md) | Get material data |
|
||||||
| [getProduct(divisionName, productName)](./bitburner.warehouseapi.getproduct.md) | Get product data |
|
| [getProduct(divisionName, city, productName)](./bitburner.warehouseapi.getproduct.md) | Get product data |
|
||||||
| [getUpgradeWarehouseCost(divisionName, city, amt)](./bitburner.warehouseapi.getupgradewarehousecost.md) | Gets the cost to upgrade a warehouse to the next level |
|
| [getUpgradeWarehouseCost(divisionName, city, amt)](./bitburner.warehouseapi.getupgradewarehousecost.md) | Gets the cost to upgrade a warehouse to the next level |
|
||||||
| [getWarehouse(divisionName, city)](./bitburner.warehouseapi.getwarehouse.md) | Get warehouse data |
|
| [getWarehouse(divisionName, city)](./bitburner.warehouseapi.getwarehouse.md) | Get warehouse data |
|
||||||
| [hasWarehouse(divisionName, city)](./bitburner.warehouseapi.haswarehouse.md) | Check if you have a warehouse in city |
|
| [hasWarehouse(divisionName, city)](./bitburner.warehouseapi.haswarehouse.md) | Check if you have a warehouse in city |
|
||||||
@ -38,9 +38,9 @@ Requires the Warehouse API upgrade from your corporation.
|
|||||||
| [sellProduct(divisionName, city, productName, amt, price, all)](./bitburner.warehouseapi.sellproduct.md) | Set product sell data. |
|
| [sellProduct(divisionName, city, productName, amt, price, all)](./bitburner.warehouseapi.sellproduct.md) | Set product sell data. |
|
||||||
| [setMaterialMarketTA1(divisionName, city, materialName, on)](./bitburner.warehouseapi.setmaterialmarketta1.md) | Set market TA 1 for a material. |
|
| [setMaterialMarketTA1(divisionName, city, materialName, on)](./bitburner.warehouseapi.setmaterialmarketta1.md) | Set market TA 1 for a material. |
|
||||||
| [setMaterialMarketTA2(divisionName, city, materialName, on)](./bitburner.warehouseapi.setmaterialmarketta2.md) | Set market TA 2 for a material. |
|
| [setMaterialMarketTA2(divisionName, city, materialName, on)](./bitburner.warehouseapi.setmaterialmarketta2.md) | Set market TA 2 for a material. |
|
||||||
| [setProductMarketTA1(divisionName, productName, on)](./bitburner.warehouseapi.setproductmarketta1.md) | Set market TA 1 for a product. |
|
| [setProductMarketTA1(divisionName, city, productName, on)](./bitburner.warehouseapi.setproductmarketta1.md) | Set market TA 1 for a product. |
|
||||||
| [setProductMarketTA2(divisionName, productName, on)](./bitburner.warehouseapi.setproductmarketta2.md) | Set market TA 2 for a product. |
|
| [setProductMarketTA2(divisionName, city, productName, on)](./bitburner.warehouseapi.setproductmarketta2.md) | Set market TA 2 for a product. |
|
||||||
| [setSmartSupply(divisionName, city, enabled)](./bitburner.warehouseapi.setsmartsupply.md) | Set smart supply |
|
| [setSmartSupply(divisionName, city, enabled)](./bitburner.warehouseapi.setsmartsupply.md) | Set smart supply |
|
||||||
| [setSmartSupplyUseLeftovers(divisionName, city, materialName, enabled)](./bitburner.warehouseapi.setsmartsupplyuseleftovers.md) | Set whether smart supply uses leftovers before buying |
|
| [setSmartSupplyOption(divisionName, city, materialName, option)](./bitburner.warehouseapi.setsmartsupplyoption.md) | Set whether smart supply uses leftovers before buying |
|
||||||
| [upgradeWarehouse(divisionName, city, amt)](./bitburner.warehouseapi.upgradewarehouse.md) | Upgrade warehouse |
|
| [upgradeWarehouse(divisionName, city, amt)](./bitburner.warehouseapi.upgradewarehouse.md) | Upgrade warehouse |
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Set market TA 1 for a product.
|
|||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
setProductMarketTA1(divisionName: string, productName: string, on: boolean): void;
|
setProductMarketTA1(divisionName: string, city: CityName | `${CityName}`, productName: string, on: boolean): void;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -17,6 +17,7 @@ setProductMarketTA1(divisionName: string, productName: string, on: boolean): voi
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| divisionName | string | Name of the division |
|
| divisionName | string | Name of the division |
|
||||||
|
| city | [CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\` | Name of the city |
|
||||||
| productName | string | Name of the product |
|
| productName | string | Name of the product |
|
||||||
| on | boolean | market ta enabled |
|
| on | boolean | market ta enabled |
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ Set market TA 2 for a product.
|
|||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
setProductMarketTA2(divisionName: string, productName: string, on: boolean): void;
|
setProductMarketTA2(divisionName: string, city: CityName | `${CityName}`, productName: string, on: boolean): void;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -17,6 +17,7 @@ setProductMarketTA2(divisionName: string, productName: string, on: boolean): voi
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| divisionName | string | Name of the division |
|
| divisionName | string | Name of the division |
|
||||||
|
| city | [CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\` | Name of the city |
|
||||||
| productName | string | Name of the product |
|
| productName | string | Name of the product |
|
||||||
| on | boolean | market ta enabled |
|
| on | boolean | market ta enabled |
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
[Home](./index.md) > [bitburner](./bitburner.md) > [WarehouseAPI](./bitburner.warehouseapi.md) > [setSmartSupplyUseLeftovers](./bitburner.warehouseapi.setsmartsupplyuseleftovers.md)
|
[Home](./index.md) > [bitburner](./bitburner.md) > [WarehouseAPI](./bitburner.warehouseapi.md) > [setSmartSupplyOption](./bitburner.warehouseapi.setsmartsupplyoption.md)
|
||||||
|
|
||||||
## WarehouseAPI.setSmartSupplyUseLeftovers() method
|
## WarehouseAPI.setSmartSupplyOption() method
|
||||||
|
|
||||||
Set whether smart supply uses leftovers before buying
|
Set whether smart supply uses leftovers before buying
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
setSmartSupplyUseLeftovers(
|
setSmartSupplyOption(
|
||||||
divisionName: string,
|
divisionName: string,
|
||||||
city: CityName | `${CityName}`,
|
city: CityName | `${CityName}`,
|
||||||
materialName: string,
|
materialName: string,
|
||||||
enabled: boolean,
|
option: string,
|
||||||
): void;
|
): void;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ setSmartSupplyUseLeftovers(
|
|||||||
| divisionName | string | Name of the division |
|
| divisionName | string | Name of the division |
|
||||||
| city | [CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\` | Name of the city |
|
| city | [CityName](./bitburner.cityname.md) \| \`${[CityName](./bitburner.cityname.md)<!-- -->}\` | Name of the city |
|
||||||
| materialName | string | Name of the material |
|
| materialName | string | Name of the material |
|
||||||
| enabled | boolean | smart supply use leftovers enabled |
|
| option | string | smart supply option, "leftovers" to use leftovers, "imports" to use only imported materials, "none" to not use materials from store |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
@ -499,6 +499,7 @@ export const defaultMultipliers: IBitNodeMultipliers = {
|
|||||||
|
|
||||||
CorporationValuation: 1,
|
CorporationValuation: 1,
|
||||||
CorporationSoftcap: 1,
|
CorporationSoftcap: 1,
|
||||||
|
CorporationDivisions: 1,
|
||||||
|
|
||||||
BladeburnerRank: 1,
|
BladeburnerRank: 1,
|
||||||
BladeburnerSkillCost: 1,
|
BladeburnerSkillCost: 1,
|
||||||
@ -538,6 +539,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
FactionWorkRepGain: 0.5,
|
FactionWorkRepGain: 0.5,
|
||||||
|
|
||||||
CorporationSoftcap: 0.9,
|
CorporationSoftcap: 0.9,
|
||||||
|
CorporationDivisions: 0.9,
|
||||||
|
|
||||||
InfiltrationMoney: 3,
|
InfiltrationMoney: 3,
|
||||||
StaneksGiftPowerMultiplier: 2,
|
StaneksGiftPowerMultiplier: 2,
|
||||||
@ -623,7 +625,8 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
InfiltrationMoney: 1.5,
|
InfiltrationMoney: 1.5,
|
||||||
InfiltrationRep: 1.5,
|
InfiltrationRep: 1.5,
|
||||||
|
|
||||||
CorporationValuation: 0.5,
|
CorporationValuation: 0.75,
|
||||||
|
CorporationDivisions: 0.75,
|
||||||
|
|
||||||
GangUniqueAugs: 0.5,
|
GangUniqueAugs: 0.5,
|
||||||
|
|
||||||
@ -654,6 +657,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: 0.2,
|
CorporationValuation: 0.2,
|
||||||
CorporationSoftcap: 0.9,
|
CorporationSoftcap: 0.9,
|
||||||
|
CorporationDivisions: 0.8,
|
||||||
|
|
||||||
GangSoftcap: 0.7,
|
GangSoftcap: 0.7,
|
||||||
GangUniqueAugs: 0.2,
|
GangUniqueAugs: 0.2,
|
||||||
@ -692,6 +696,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: 0.2,
|
CorporationValuation: 0.2,
|
||||||
CorporationSoftcap: 0.9,
|
CorporationSoftcap: 0.9,
|
||||||
|
CorporationDivisions: 0.8,
|
||||||
|
|
||||||
BladeburnerRank: 0.6,
|
BladeburnerRank: 0.6,
|
||||||
BladeburnerSkillCost: 2,
|
BladeburnerSkillCost: 2,
|
||||||
@ -725,6 +730,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: 0,
|
CorporationValuation: 0,
|
||||||
CorporationSoftcap: 0,
|
CorporationSoftcap: 0,
|
||||||
|
CorporationDivisions: 0,
|
||||||
|
|
||||||
BladeburnerRank: 0,
|
BladeburnerRank: 0,
|
||||||
|
|
||||||
@ -760,7 +766,8 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
FourSigmaMarketDataApiCost: 4,
|
FourSigmaMarketDataApiCost: 4,
|
||||||
|
|
||||||
CorporationValuation: 0.5,
|
CorporationValuation: 0.5,
|
||||||
CorporationSoftcap: 0.7,
|
CorporationSoftcap: 0.75,
|
||||||
|
CorporationDivisions: 0.8,
|
||||||
|
|
||||||
BladeburnerRank: 0.9,
|
BladeburnerRank: 0.9,
|
||||||
BladeburnerSkillCost: 1.2,
|
BladeburnerSkillCost: 1.2,
|
||||||
@ -804,6 +811,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: 0.5,
|
CorporationValuation: 0.5,
|
||||||
CorporationSoftcap: 0.9,
|
CorporationSoftcap: 0.9,
|
||||||
|
CorporationDivisions: 0.9,
|
||||||
|
|
||||||
BladeburnerRank: 0.8,
|
BladeburnerRank: 0.8,
|
||||||
|
|
||||||
@ -844,6 +852,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: 0.1,
|
CorporationValuation: 0.1,
|
||||||
CorporationSoftcap: 0.9,
|
CorporationSoftcap: 0.9,
|
||||||
|
CorporationDivisions: 0.9,
|
||||||
|
|
||||||
GangUniqueAugs: 0.75,
|
GangUniqueAugs: 0.75,
|
||||||
|
|
||||||
@ -907,6 +916,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
|
|
||||||
CorporationValuation: dec,
|
CorporationValuation: dec,
|
||||||
CorporationSoftcap: 0.8,
|
CorporationSoftcap: 0.8,
|
||||||
|
CorporationDivisions: 0.5,
|
||||||
|
|
||||||
BladeburnerRank: dec,
|
BladeburnerRank: dec,
|
||||||
BladeburnerSkillCost: inc,
|
BladeburnerSkillCost: inc,
|
||||||
@ -952,7 +962,8 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
|||||||
FourSigmaMarketDataApiCost: 10,
|
FourSigmaMarketDataApiCost: 10,
|
||||||
|
|
||||||
CorporationValuation: 0.001,
|
CorporationValuation: 0.001,
|
||||||
CorporationSoftcap: 0.3,
|
CorporationSoftcap: 0.4,
|
||||||
|
CorporationDivisions: 0.4,
|
||||||
|
|
||||||
BladeburnerRank: 0.45,
|
BladeburnerRank: 0.45,
|
||||||
BladeburnerSkillCost: 2,
|
BladeburnerSkillCost: 2,
|
||||||
|
@ -154,9 +154,12 @@ export interface IBitNodeMultipliers {
|
|||||||
/** Influences the hacking skill required to backdoor the world daemon. */
|
/** Influences the hacking skill required to backdoor the world daemon. */
|
||||||
WorldDaemonDifficulty: number;
|
WorldDaemonDifficulty: number;
|
||||||
|
|
||||||
/** Influences corporation dividends. */
|
/** Influences profits from corporation dividends and selling shares. */
|
||||||
CorporationSoftcap: number;
|
CorporationSoftcap: number;
|
||||||
|
|
||||||
|
/** Influences number of divisions a corporation can have. */
|
||||||
|
CorporationDivisions: number;
|
||||||
|
|
||||||
// Index signature
|
// Index signature
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,7 @@ function CorporationMults({ mults }: IMultsProps): React.ReactElement {
|
|||||||
content: mults.CorporationSoftcap.toFixed(3),
|
content: mults.CorporationSoftcap.toFixed(3),
|
||||||
},
|
},
|
||||||
CorporationValuation: { name: "Valuation" },
|
CorporationValuation: { name: "Valuation" },
|
||||||
|
CorporationDivisions: { name: "Division limit" },
|
||||||
};
|
};
|
||||||
|
|
||||||
return <BNMultTable sectionName="Corporation" rowData={rows} mults={mults} />;
|
return <BNMultTable sectionName="Corporation" rowData={rows} mults={mults} />;
|
||||||
|
@ -17,10 +17,12 @@ import { isRelevantMaterial } from "./ui/Helpers";
|
|||||||
import { CityName } from "../Enums";
|
import { CityName } from "../Enums";
|
||||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||||
import { CorpResearchName } from "@nsdefs";
|
import { CorpResearchName } from "@nsdefs";
|
||||||
|
import { calculateUpgradeCost } from "./helpers";
|
||||||
|
import { isInteger } from "lodash";
|
||||||
|
|
||||||
export function NewIndustry(corporation: Corporation, industry: IndustryType, name: string): void {
|
export function NewIndustry(corporation: Corporation, industry: IndustryType, name: string): void {
|
||||||
if (corporation.divisions.find(({ type }) => industry == type))
|
if (corporation.divisions.length >= corporation.maxDivisions)
|
||||||
throw new Error(`You have already expanded into the ${industry} industry!`);
|
throw new Error(`Cannot expand into ${industry} industry, too many divisions!`);
|
||||||
|
|
||||||
for (let i = 0; i < corporation.divisions.length; ++i) {
|
for (let i = 0; i < corporation.divisions.length; ++i) {
|
||||||
if (corporation.divisions[i].name === name) {
|
if (corporation.divisions[i].name === name) {
|
||||||
@ -47,6 +49,13 @@ export function NewIndustry(corporation: Corporation, industry: IndustryType, na
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeIndustry(corporation: Corporation, name: string) {
|
||||||
|
const divIndex = corporation.divisions.findIndex((div) => div.name === name);
|
||||||
|
if (divIndex === -1) throw new Error("There is no division called " + name);
|
||||||
|
|
||||||
|
corporation.divisions.splice(divIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
export function NewCity(corporation: Corporation, division: Industry, city: CityName): void {
|
export function NewCity(corporation: Corporation, division: Industry, city: CityName): void {
|
||||||
if (corporation.funds < corpConstants.officeInitialCost) {
|
if (corporation.funds < corpConstants.officeInitialCost) {
|
||||||
throw new Error("You don't have enough company funds to open a new office!");
|
throw new Error("You don't have enough company funds to open a new office!");
|
||||||
@ -71,15 +80,12 @@ export function UnlockUpgrade(corporation: Corporation, upgrade: CorporationUnlo
|
|||||||
corporation.unlock(upgrade);
|
corporation.unlock(upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LevelUpgrade(corporation: Corporation, upgrade: CorporationUpgrade): void {
|
export function LevelUpgrade(corporation: Corporation, upgrade: CorporationUpgrade, amount: number): void {
|
||||||
const baseCost = upgrade.basePrice;
|
const cost = calculateUpgradeCost(corporation, upgrade, amount);
|
||||||
const priceMult = upgrade.priceMult;
|
|
||||||
const level = corporation.upgrades[upgrade.index];
|
|
||||||
const cost = baseCost * Math.pow(priceMult, level);
|
|
||||||
if (corporation.funds < cost) {
|
if (corporation.funds < cost) {
|
||||||
throw new Error("Insufficient funds");
|
throw new Error("Insufficient funds");
|
||||||
} else {
|
} else {
|
||||||
corporation.upgrade(upgrade);
|
corporation.upgrade(upgrade, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +107,7 @@ export function IssueNewShares(corporation: Corporation, amount: number): [numbe
|
|||||||
throw new Error(`Invalid value. Must be an number between 10m and ${max} (20% of total shares)`);
|
throw new Error(`Invalid value. Must be an number between 10m and ${max} (20% of total shares)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newSharePrice = Math.round(corporation.sharePrice * 0.9);
|
const newSharePrice = Math.round(corporation.sharePrice * 0.8);
|
||||||
|
|
||||||
const profit = amount * newSharePrice;
|
const profit = amount * newSharePrice;
|
||||||
corporation.issueNewSharesCooldown = corpConstants.issueNewSharesCooldown;
|
corporation.issueNewSharesCooldown = corpConstants.issueNewSharesCooldown;
|
||||||
@ -143,21 +149,21 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
|
|||||||
|
|
||||||
//Parse quantity
|
//Parse quantity
|
||||||
amt = amt.toUpperCase();
|
amt = amt.toUpperCase();
|
||||||
if (amt.includes("MAX") || amt.includes("PROD")) {
|
if (amt.includes("MAX") || amt.includes("PROD") || amt.includes("INV")) {
|
||||||
let q = amt.replace(/\s+/g, "");
|
let q = amt.replace(/\s+/g, "");
|
||||||
q = q.replace(/[^-()\d/*+.MAXPROD]/g, "");
|
q = q.replace(/[^-()\d/*+.MAXPRODINV]/g, "");
|
||||||
let tempQty = q.replace(/MAX/g, mat.maxsll.toString());
|
let tempQty = q.replace(/MAX/g, mat.maxsll.toString());
|
||||||
tempQty = tempQty.replace(/PROD/g, mat.prd.toString());
|
tempQty = tempQty.replace(/PROD/g, mat.prd.toString());
|
||||||
|
tempQty = tempQty.replace(/INV/g, mat.prd.toString());
|
||||||
try {
|
try {
|
||||||
tempQty = eval(tempQty);
|
tempQty = eval(tempQty);
|
||||||
} 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 (tempQty == null || isNaN(parseFloat(tempQty)) || parseFloat(tempQty) < 0) {
|
if (tempQty == null || isNaN(parseFloat(tempQty))) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field");
|
throw new Error("Invalid value or expression for sell quantity 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)) || parseFloat(amt) < 0) {
|
} else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
|
||||||
@ -194,13 +200,13 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
if (temp == null || isNaN(parseFloat(temp))) {
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
throw new Error("Invalid value or expression for sell price field.");
|
throw new Error("Invalid value or expression for sell price field.");
|
||||||
}
|
}
|
||||||
product.sCost = price; //Use sanitized price
|
product.sCost[city] = price; //Use sanitized price
|
||||||
} else {
|
} else {
|
||||||
const cost = parseFloat(price);
|
const cost = parseFloat(price);
|
||||||
if (isNaN(cost)) {
|
if (isNaN(cost)) {
|
||||||
throw new Error("Invalid value for sell price field");
|
throw new Error("Invalid value for sell price field");
|
||||||
}
|
}
|
||||||
product.sCost = cost;
|
product.sCost[city] = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array of all cities. Used later
|
// Array of all cities. Used later
|
||||||
@ -208,19 +214,20 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
|
|
||||||
// Parse quantity
|
// Parse quantity
|
||||||
amt = amt.toUpperCase();
|
amt = amt.toUpperCase();
|
||||||
if (amt.includes("MAX") || amt.includes("PROD")) {
|
if (amt.includes("MAX") || amt.includes("PROD") || amt.includes("INV")) {
|
||||||
//Dynamically evaluated quantity. First test to make sure its valid
|
//Dynamically evaluated quantity. First test to make sure its valid
|
||||||
let qty = amt.replace(/\s+/g, "");
|
let qty = amt.replace(/\s+/g, "");
|
||||||
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, "");
|
qty = qty.replace(/[^-()\d/*+.MAXPRODINV]/g, "");
|
||||||
let temp = qty.replace(/MAX/g, product.maxsll.toString());
|
let temp = qty.replace(/MAX/g, product.maxsll.toString());
|
||||||
temp = temp.replace(/PROD/g, product.data[city][1].toString());
|
temp = temp.replace(/PROD/g, product.data[city][1].toString());
|
||||||
|
temp = temp.replace(/INV/g, product.data[city][0].toString());
|
||||||
try {
|
try {
|
||||||
temp = eval(temp);
|
temp = eval(temp);
|
||||||
} 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)) || parseFloat(temp) < 0) {
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field");
|
throw new Error("Invalid value or expression for sell quantity field");
|
||||||
}
|
}
|
||||||
if (all) {
|
if (all) {
|
||||||
@ -268,8 +275,11 @@ export function SetSmartSupply(warehouse: Warehouse, smartSupply: boolean): void
|
|||||||
warehouse.smartSupplyEnabled = smartSupply;
|
warehouse.smartSupplyEnabled = smartSupply;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SetSmartSupplyUseLeftovers(warehouse: Warehouse, material: Material, useLeftover: boolean): void {
|
export function SetSmartSupplyOption(warehouse: Warehouse, material: Material, useOption: string): void {
|
||||||
warehouse.smartSupplyUseLeftovers[material.name] = useLeftover;
|
if (!corpConstants.smartSupplyUseOptions.includes(useOption)) {
|
||||||
|
throw new Error(`Invalid Smart Supply option '${useOption}'`);
|
||||||
|
}
|
||||||
|
warehouse.smartSupplyOptions[material.name] = useOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BuyMaterial(material: Material, amt: number): void {
|
export function BuyMaterial(material: Material, amt: number): void {
|
||||||
@ -298,9 +308,11 @@ export function BulkPurchase(corp: Corporation, warehouse: Warehouse, material:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SellShares(corporation: Corporation, numShares: number): number {
|
export function SellShares(corporation: Corporation, numShares: number): number {
|
||||||
if (isNaN(numShares)) throw new Error("Invalid value for number of shares");
|
if (isNaN(numShares) || !isInteger(numShares)) throw new Error("Invalid value for number of shares");
|
||||||
if (numShares < 0) throw new Error("Invalid value for number of shares");
|
if (numShares <= 0) throw new Error("Invalid value for number of shares");
|
||||||
if (numShares > corporation.numShares) throw new Error("You don't have that many shares to sell!");
|
if (numShares > corporation.numShares) throw new Error("You don't have that many shares to sell!");
|
||||||
|
if (numShares === corporation.numShares) throw new Error("You cant't sell all your shares!");
|
||||||
|
if (numShares > 1e14) throw new Error("Invalid value for number of shares");
|
||||||
if (!corporation.public) throw new Error("You haven't gone public!");
|
if (!corporation.public) throw new Error("You haven't gone public!");
|
||||||
if (corporation.shareSaleCooldown) throw new Error("Share sale on cooldown!");
|
if (corporation.shareSaleCooldown) throw new Error("Share sale on cooldown!");
|
||||||
const stockSaleResults = corporation.calculateShareSale(numShares);
|
const stockSaleResults = corporation.calculateShareSale(numShares);
|
||||||
@ -318,8 +330,8 @@ export function SellShares(corporation: Corporation, numShares: number): number
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function BuyBackShares(corporation: Corporation, numShares: number): boolean {
|
export function BuyBackShares(corporation: Corporation, numShares: number): boolean {
|
||||||
if (isNaN(numShares)) throw new Error("Invalid value for number of shares");
|
if (isNaN(numShares) || !isInteger(numShares)) throw new Error("Invalid value for number of shares");
|
||||||
if (numShares < 0) throw new Error("Invalid value for number of shares");
|
if (numShares <= 0) throw new Error("Invalid value for number of shares");
|
||||||
if (numShares > corporation.issuedShares) throw new Error("You don't have that many shares to buy!");
|
if (numShares > corporation.issuedShares) throw new Error("You don't have that many shares to buy!");
|
||||||
if (!corporation.public) throw new Error("You haven't gone public!");
|
if (!corporation.public) throw new Error("You haven't gone public!");
|
||||||
const buybackPrice = corporation.sharePrice * 1.1;
|
const buybackPrice = corporation.sharePrice * 1.1;
|
||||||
@ -344,9 +356,9 @@ export function UpgradeOfficeSize(corp: Corporation, office: OfficeSpace, size:
|
|||||||
corp.funds = corp.funds - cost;
|
corp.funds = corp.funds - cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BuyCoffee(corp: Corporation, office: OfficeSpace): boolean {
|
export function BuyTea(corp: Corporation, office: OfficeSpace): boolean {
|
||||||
const cost = office.getCoffeeCost();
|
const cost = office.getTeaCost();
|
||||||
if (corp.funds < cost || !office.setCoffee()) return false;
|
if (corp.funds < cost || !office.setTea()) return false;
|
||||||
corp.funds -= cost;
|
corp.funds -= cost;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -495,8 +507,12 @@ export function ExportMaterial(
|
|||||||
): void {
|
): void {
|
||||||
// Sanitize amt
|
// Sanitize amt
|
||||||
let sanitizedAmt = amt.replace(/\s+/g, "").toUpperCase();
|
let sanitizedAmt = amt.replace(/\s+/g, "").toUpperCase();
|
||||||
sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, "");
|
sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAXEPRODINV]/g, "");
|
||||||
let temp = sanitizedAmt.replace(/MAX/g, "1");
|
let temp = sanitizedAmt.replace(/MAX/g, "1");
|
||||||
|
temp = temp.replace(/IPROD/g, "1");
|
||||||
|
temp = temp.replace(/EPROD/g, "1");
|
||||||
|
temp = temp.replace(/IINV/g, "1");
|
||||||
|
temp = temp.replace(/EINV/g, "1");
|
||||||
try {
|
try {
|
||||||
temp = eval(temp);
|
temp = eval(temp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -505,7 +521,7 @@ export function ExportMaterial(
|
|||||||
|
|
||||||
const n = parseFloat(temp);
|
const n = parseFloat(temp);
|
||||||
|
|
||||||
if (n == null || isNaN(n) || n < 0) {
|
if (n == null || isNaN(n)) {
|
||||||
throw new Error("Invalid amount entered for export");
|
throw new Error("Invalid amount entered for export");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,11 @@ import { Reviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../uti
|
|||||||
import { isString } from "../utils/helpers/isString";
|
import { isString } from "../utils/helpers/isString";
|
||||||
import { CityName } from "../Enums";
|
import { CityName } from "../Enums";
|
||||||
import { CorpStateName } from "@nsdefs";
|
import { CorpStateName } from "@nsdefs";
|
||||||
|
import { calculateUpgradeCost } from "./helpers";
|
||||||
|
|
||||||
interface IParams {
|
interface IParams {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
seedFunded?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Corporation {
|
export class Corporation {
|
||||||
@ -24,6 +26,7 @@ export class Corporation {
|
|||||||
|
|
||||||
//A division/business sector is represented by the object:
|
//A division/business sector is represented by the object:
|
||||||
divisions: Industry[] = [];
|
divisions: Industry[] = [];
|
||||||
|
maxDivisions = 20 * BitNodeMultipliers.CorporationDivisions;
|
||||||
|
|
||||||
//Financial stats
|
//Financial stats
|
||||||
funds = 150e9;
|
funds = 150e9;
|
||||||
@ -50,6 +53,8 @@ export class Corporation {
|
|||||||
valuationsList = [0];
|
valuationsList = [0];
|
||||||
valuation = 0;
|
valuation = 0;
|
||||||
|
|
||||||
|
seedFunded: boolean;
|
||||||
|
|
||||||
state = new CorporationState();
|
state = new CorporationState();
|
||||||
|
|
||||||
constructor(params: IParams = {}) {
|
constructor(params: IParams = {}) {
|
||||||
@ -59,6 +64,7 @@ export class Corporation {
|
|||||||
this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
|
this.unlockUpgrades = Array(numUnlockUpgrades).fill(0);
|
||||||
this.upgrades = Array(numUpgrades).fill(0);
|
this.upgrades = Array(numUpgrades).fill(0);
|
||||||
this.upgradeMultipliers = Array(numUpgrades).fill(1);
|
this.upgradeMultipliers = Array(numUpgrades).fill(1);
|
||||||
|
this.seedFunded = params.seedFunded ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addFunds(amt: number): void {
|
addFunds(amt: number): void {
|
||||||
@ -78,6 +84,8 @@ export class Corporation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process(): void {
|
process(): void {
|
||||||
|
if (this.storedCycles < 0) this.storedCycles = 0;
|
||||||
|
|
||||||
if (this.storedCycles >= corpConstants.gameCyclesPerCorpStateCycle) {
|
if (this.storedCycles >= corpConstants.gameCyclesPerCorpStateCycle) {
|
||||||
const state = this.getState();
|
const state = this.getState();
|
||||||
const marketCycles = 1;
|
const marketCycles = 1;
|
||||||
@ -305,10 +313,9 @@ export class Corporation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Levelable upgrades
|
//Levelable upgrades
|
||||||
upgrade(upgrade: CorporationUpgrade): void {
|
upgrade(upgrade: CorporationUpgrade, amount: number): void {
|
||||||
|
if (amount < 1) amount = 1;
|
||||||
const upgN = upgrade.index,
|
const upgN = upgrade.index,
|
||||||
basePrice = upgrade.basePrice,
|
|
||||||
priceMult = upgrade.priceMult,
|
|
||||||
upgradeAmt = upgrade.benefit; //Amount by which the upgrade multiplier gets increased (additive)
|
upgradeAmt = upgrade.benefit; //Amount by which the upgrade multiplier gets increased (additive)
|
||||||
while (this.upgrades.length <= upgN) {
|
while (this.upgrades.length <= upgN) {
|
||||||
this.upgrades.push(0);
|
this.upgrades.push(0);
|
||||||
@ -316,12 +323,12 @@ export class Corporation {
|
|||||||
while (this.upgradeMultipliers.length <= upgN) {
|
while (this.upgradeMultipliers.length <= upgN) {
|
||||||
this.upgradeMultipliers.push(1);
|
this.upgradeMultipliers.push(1);
|
||||||
}
|
}
|
||||||
const totalCost = basePrice * Math.pow(priceMult, this.upgrades[upgN]);
|
const totalCost = calculateUpgradeCost(this, upgrade, amount);
|
||||||
if (this.funds < totalCost) {
|
if (this.funds < totalCost) {
|
||||||
dialogBoxCreate("You don't have enough funds to purchase this!");
|
dialogBoxCreate("You don't have enough funds to purchase this!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++this.upgrades[upgN];
|
this.upgrades[upgN] += amount;
|
||||||
this.funds = this.funds - totalCost;
|
this.funds = this.funds - totalCost;
|
||||||
|
|
||||||
//Increase upgrade multiplier
|
//Increase upgrade multiplier
|
||||||
|
@ -321,6 +321,7 @@ export class Industry {
|
|||||||
|
|
||||||
buyAmt = Math.min(buyAmt, maxAmt);
|
buyAmt = Math.min(buyAmt, maxAmt);
|
||||||
if (buyAmt > 0) {
|
if (buyAmt > 0) {
|
||||||
|
mat.qlt = Math.max(0.1, (mat.qlt * mat.qty + 1 * buyAmt) / (mat.qty + buyAmt));
|
||||||
mat.qty += buyAmt;
|
mat.qty += buyAmt;
|
||||||
expenses += buyAmt * mat.bCost;
|
expenses += buyAmt * mat.bCost;
|
||||||
}
|
}
|
||||||
@ -382,18 +383,25 @@ export class Industry {
|
|||||||
|
|
||||||
// Use the materials already in the warehouse if the option is on.
|
// Use the materials already in the warehouse if the option is on.
|
||||||
for (const matName of Object.keys(smartBuy) as CorpMaterialName[]) {
|
for (const matName of Object.keys(smartBuy) as CorpMaterialName[]) {
|
||||||
if (!warehouse.smartSupplyUseLeftovers[matName]) continue;
|
if (warehouse.smartSupplyOptions[matName] === "none") continue;
|
||||||
const mat = warehouse.materials[matName];
|
const mat = warehouse.materials[matName];
|
||||||
const buyAmt = smartBuy[matName];
|
const buyAmt = smartBuy[matName];
|
||||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||||
smartBuy[matName] = Math.max(0, buyAmt - mat.qty);
|
if (warehouse.smartSupplyOptions[matName] === "leftovers") {
|
||||||
|
smartBuy[matName] = Math.max(0, buyAmt - mat.qty);
|
||||||
|
} else {
|
||||||
|
smartBuy[matName] = Math.max(0, buyAmt - mat.imp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// buy them
|
// buy them
|
||||||
for (const [matName, buyAmt] of Object.entries(smartBuy) as [CorpMaterialName, number][]) {
|
for (const [matName, buyAmt] of Object.entries(smartBuy) as [CorpMaterialName, number][]) {
|
||||||
const mat = warehouse.materials[matName];
|
const mat = warehouse.materials[matName];
|
||||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||||
|
if (mat.qty + buyAmt != 0) mat.qlt = (mat.qlt * mat.qty + 1 * buyAmt) / (mat.qty + buyAmt);
|
||||||
|
else mat.qlt = 1;
|
||||||
mat.qty += buyAmt;
|
mat.qty += buyAmt;
|
||||||
|
mat.buy = buyAmt / 10;
|
||||||
expenses += buyAmt * mat.bCost;
|
expenses += buyAmt * mat.bCost;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -463,6 +471,8 @@ export class Industry {
|
|||||||
|
|
||||||
// Make our materials if they are producable
|
// Make our materials if they are producable
|
||||||
if (producableFrac > 0 && prod > 0) {
|
if (producableFrac > 0 && prod > 0) {
|
||||||
|
let avgQlt = 0;
|
||||||
|
let divider = 0;
|
||||||
for (const reqMatName of Object.keys(this.reqMats) as CorpMaterialName[]) {
|
for (const reqMatName of Object.keys(this.reqMats) as CorpMaterialName[]) {
|
||||||
const reqMat = this.reqMats[reqMatName];
|
const reqMat = this.reqMats[reqMatName];
|
||||||
if (reqMat === undefined) continue;
|
if (reqMat === undefined) continue;
|
||||||
@ -471,13 +481,26 @@ export class Industry {
|
|||||||
warehouse.materials[reqMatName].prd = 0;
|
warehouse.materials[reqMatName].prd = 0;
|
||||||
warehouse.materials[reqMatName].prd -=
|
warehouse.materials[reqMatName].prd -=
|
||||||
reqMatQtyNeeded / (corpConstants.secondsPerMarketCycle * marketCycles);
|
reqMatQtyNeeded / (corpConstants.secondsPerMarketCycle * marketCycles);
|
||||||
|
|
||||||
|
avgQlt += warehouse.materials[reqMatName].qlt;
|
||||||
|
divider++;
|
||||||
}
|
}
|
||||||
|
avgQlt /= divider;
|
||||||
|
avgQlt = Math.max(avgQlt, 1);
|
||||||
for (let j = 0; j < this.prodMats.length; ++j) {
|
for (let j = 0; j < this.prodMats.length; ++j) {
|
||||||
warehouse.materials[this.prodMats[j]].qty += prod * producableFrac;
|
let tempQlt =
|
||||||
warehouse.materials[this.prodMats[j]].qlt =
|
|
||||||
office.employeeProd[EmployeePositions.Engineer] / 90 +
|
office.employeeProd[EmployeePositions.Engineer] / 90 +
|
||||||
Math.pow(this.sciResearch, this.sciFac) +
|
Math.pow(this.sciResearch, this.sciFac) +
|
||||||
Math.pow(warehouse.materials["AI Cores"].qty, this.aiFac) / 10e3;
|
Math.pow(warehouse.materials["AI Cores"].qty, this.aiFac) / 10e3;
|
||||||
|
const logQlt = Math.max(Math.pow(tempQlt, 0.5), 1);
|
||||||
|
tempQlt = Math.min(tempQlt, avgQlt * logQlt);
|
||||||
|
warehouse.materials[this.prodMats[j]].qlt = Math.max(
|
||||||
|
1,
|
||||||
|
(warehouse.materials[this.prodMats[j]].qlt * warehouse.materials[this.prodMats[j]].qty +
|
||||||
|
tempQlt * prod * producableFrac) /
|
||||||
|
(warehouse.materials[this.prodMats[j]].qty + prod * producableFrac),
|
||||||
|
);
|
||||||
|
warehouse.materials[this.prodMats[j]].qty += prod * producableFrac;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const reqMatName of Object.keys(this.reqMats) as CorpMaterialName[]) {
|
for (const reqMatName of Object.keys(this.reqMats) as CorpMaterialName[]) {
|
||||||
@ -610,6 +633,28 @@ export class Industry {
|
|||||||
corporation.getSalesMultiplier() *
|
corporation.getSalesMultiplier() *
|
||||||
advertisingFactor *
|
advertisingFactor *
|
||||||
this.getSalesMultiplier();
|
this.getSalesMultiplier();
|
||||||
|
if (isString(mat.sllman[1])) {
|
||||||
|
//Dynamically evaluated
|
||||||
|
let tmp = (mat.sllman[1] as string).replace(/MAX/g, (mat.maxsll + "").toUpperCase());
|
||||||
|
tmp = tmp.replace(/PROD/g, mat.prd + "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
sellAmt = eval(tmp);
|
||||||
|
} catch (e) {
|
||||||
|
dialogBoxCreate(
|
||||||
|
`Error evaluating your sell amount for material ${mat.name} in ${this.name}'s ${city} office. The sell amount is being set to zero, sellAmt is set to ${sellAmt}`,
|
||||||
|
);
|
||||||
|
sellAmt = 0;
|
||||||
|
}
|
||||||
|
sellAmt = Math.min(mat.maxsll, sellAmt);
|
||||||
|
sellAmt = Math.max(sellAmt, 0);
|
||||||
|
} else if (mat.sllman[1] === -1) {
|
||||||
|
//Backwards compatibility, -1 = MAX
|
||||||
|
sellAmt = mat.maxsll;
|
||||||
|
} else {
|
||||||
|
//Player's input value is just a number
|
||||||
|
sellAmt = Math.min(mat.maxsll, mat.sllman[1] as number);
|
||||||
|
}
|
||||||
sellAmt = Math.min(mat.maxsll, sellAmt);
|
sellAmt = Math.min(mat.maxsll, sellAmt);
|
||||||
sellAmt = sellAmt * corpConstants.secondsPerMarketCycle * marketCycles;
|
sellAmt = sellAmt * corpConstants.secondsPerMarketCycle * marketCycles;
|
||||||
sellAmt = Math.min(mat.qty, sellAmt);
|
sellAmt = Math.min(mat.qty, sellAmt);
|
||||||
@ -636,10 +681,27 @@ export class Industry {
|
|||||||
mat.totalExp = 0; //Reset export
|
mat.totalExp = 0; //Reset export
|
||||||
for (let expI = 0; expI < mat.exp.length; ++expI) {
|
for (let expI = 0; expI < mat.exp.length; ++expI) {
|
||||||
const exp = mat.exp[expI];
|
const exp = mat.exp[expI];
|
||||||
const amtStr = exp.amt.replace(
|
|
||||||
|
const expIndustry = corporation.divisions.find((div) => div.name === exp.ind);
|
||||||
|
if (!expIndustry) {
|
||||||
|
console.error(`Invalid export! ${exp.ind}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const expWarehouse = expIndustry.warehouses[exp.city];
|
||||||
|
if (!expWarehouse) {
|
||||||
|
console.error(`Invalid export! ${expIndustry.name} ${exp.city}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const tempMaterial = expWarehouse.materials[matName];
|
||||||
|
|
||||||
|
let amtStr = exp.amt.replace(
|
||||||
/MAX/g,
|
/MAX/g,
|
||||||
(mat.qty / (corpConstants.secondsPerMarketCycle * marketCycles) + "").toUpperCase(),
|
(mat.qty / (corpConstants.secondsPerMarketCycle * marketCycles) + "").toUpperCase(),
|
||||||
);
|
);
|
||||||
|
amtStr = amtStr.replace(/EPROD/g, mat.prd.toString());
|
||||||
|
amtStr = amtStr.replace(/IPROD/g, tempMaterial.prd.toString());
|
||||||
|
amtStr = amtStr.replace(/EINV/g, mat.qty.toString());
|
||||||
|
amtStr = amtStr.replace(/IINV/g, tempMaterial.qty.toString());
|
||||||
let amt = 0;
|
let amt = 0;
|
||||||
try {
|
try {
|
||||||
amt = eval(amtStr);
|
amt = eval(amtStr);
|
||||||
@ -660,38 +722,33 @@ export class Industry {
|
|||||||
if (mat.qty < amt) {
|
if (mat.qty < amt) {
|
||||||
amt = mat.qty;
|
amt = mat.qty;
|
||||||
}
|
}
|
||||||
if (amt === 0) {
|
|
||||||
break; //None left
|
|
||||||
}
|
|
||||||
for (let foo = 0; foo < corporation.divisions.length; ++foo) {
|
|
||||||
if (corporation.divisions[foo].name === exp.ind) {
|
|
||||||
const expIndustry = corporation.divisions[foo];
|
|
||||||
const expWarehouse = expIndustry.warehouses[exp.city];
|
|
||||||
if (!expWarehouse) {
|
|
||||||
console.error(`Invalid export! ${expIndustry.name} ${exp.city}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure theres enough space in warehouse
|
// Make sure theres enough space in warehouse
|
||||||
if (expWarehouse.sizeUsed >= expWarehouse.size) {
|
if (expWarehouse.sizeUsed >= expWarehouse.size) {
|
||||||
// Warehouse at capacity. Exporting doesn't
|
// Warehouse at capacity. Exporting doesn't
|
||||||
// affect revenue so just return 0's
|
// affect revenue so just return 0's
|
||||||
return [0, 0];
|
continue;
|
||||||
} else {
|
} else {
|
||||||
const maxAmt = Math.floor(
|
const maxAmt = Math.floor((expWarehouse.size - expWarehouse.sizeUsed) / MaterialInfo[matName].size);
|
||||||
(expWarehouse.size - expWarehouse.sizeUsed) / MaterialInfo[matName].size,
|
amt = Math.min(maxAmt, amt);
|
||||||
);
|
|
||||||
amt = Math.min(maxAmt, amt);
|
|
||||||
}
|
|
||||||
expWarehouse.materials[matName].imp += amt / (corpConstants.secondsPerMarketCycle * marketCycles);
|
|
||||||
expWarehouse.materials[matName].qty += amt;
|
|
||||||
expWarehouse.materials[matName].qlt = mat.qlt;
|
|
||||||
mat.qty -= amt;
|
|
||||||
mat.totalExp += amt;
|
|
||||||
expIndustry.updateWarehouseSizeUsed(expWarehouse);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (amt <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
expWarehouse.materials[matName].imp += amt / (corpConstants.secondsPerMarketCycle * marketCycles);
|
||||||
|
|
||||||
|
//Pretty sure this can cause some issues if there are multiple sources importing same material to same warehouse
|
||||||
|
//but this will do for now
|
||||||
|
expWarehouse.materials[matName].qlt = Math.max(
|
||||||
|
0.1,
|
||||||
|
(expWarehouse.materials[matName].qlt * expWarehouse.materials[matName].qty + amt * mat.qlt) /
|
||||||
|
(expWarehouse.materials[matName].qty + amt),
|
||||||
|
);
|
||||||
|
|
||||||
|
expWarehouse.materials[matName].qty += amt;
|
||||||
|
mat.qty -= amt;
|
||||||
|
mat.totalExp += amt;
|
||||||
|
expIndustry.updateWarehouseSizeUsed(expWarehouse);
|
||||||
}
|
}
|
||||||
//totalExp should be per second
|
//totalExp should be per second
|
||||||
mat.totalExp /= corpConstants.secondsPerMarketCycle * marketCycles;
|
mat.totalExp /= corpConstants.secondsPerMarketCycle * marketCycles;
|
||||||
@ -814,12 +871,20 @@ export class Industry {
|
|||||||
|
|
||||||
//Make our Products if they are producable
|
//Make our Products if they are producable
|
||||||
if (producableFrac > 0 && prod > 0) {
|
if (producableFrac > 0 && prod > 0) {
|
||||||
|
let avgQlt = 1;
|
||||||
for (const [reqMatName, reqQty] of Object.entries(product.reqMats) as [CorpMaterialName, number][]) {
|
for (const [reqMatName, reqQty] of Object.entries(product.reqMats) as [CorpMaterialName, number][]) {
|
||||||
const reqMatQtyNeeded = reqQty * prod * producableFrac;
|
const reqMatQtyNeeded = reqQty * prod * producableFrac;
|
||||||
warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
|
warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
|
||||||
warehouse.materials[reqMatName].prd -=
|
warehouse.materials[reqMatName].prd -=
|
||||||
reqMatQtyNeeded / (corpConstants.secondsPerMarketCycle * marketCycles);
|
reqMatQtyNeeded / (corpConstants.secondsPerMarketCycle * marketCycles);
|
||||||
|
avgQlt += warehouse.materials[reqMatName].qlt;
|
||||||
}
|
}
|
||||||
|
avgQlt /= Object.keys(product.reqMats).length;
|
||||||
|
const tempEffRat = Math.min(product.rat, avgQlt * Math.pow(product.rat, 0.5));
|
||||||
|
//Effective Rating
|
||||||
|
product.data[city][3] =
|
||||||
|
(product.data[city][3] * product.data[city][0] + tempEffRat * prod * producableFrac) /
|
||||||
|
(product.data[city][0] + prod * producableFrac);
|
||||||
//Quantity
|
//Quantity
|
||||||
product.data[city][0] += prod * producableFrac;
|
product.data[city][0] += prod * producableFrac;
|
||||||
}
|
}
|
||||||
@ -874,7 +939,7 @@ export class Industry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate Sale Cost (sCost), which could be dynamically evaluated
|
// Calculate Sale Cost (sCost), which could be dynamically evaluated
|
||||||
const markupLimit = product.rat / product.mku;
|
const markupLimit = Math.max(product.data[city][3], 0.001) / product.mku;
|
||||||
let sCost;
|
let sCost;
|
||||||
if (product.marketTa2) {
|
if (product.marketTa2) {
|
||||||
// Reverse engineer the 'maxSell' formula
|
// Reverse engineer the 'maxSell' formula
|
||||||
@ -885,7 +950,7 @@ export class Industry {
|
|||||||
const sqrtNumerator = sellAmt;
|
const sqrtNumerator = sellAmt;
|
||||||
const sqrtDenominator =
|
const sqrtDenominator =
|
||||||
0.5 *
|
0.5 *
|
||||||
Math.pow(product.rat, 0.65) *
|
Math.pow(product.data[city][3], 0.65) *
|
||||||
marketFactor *
|
marketFactor *
|
||||||
corporation.getSalesMultiplier() *
|
corporation.getSalesMultiplier() *
|
||||||
businessFactor *
|
businessFactor *
|
||||||
@ -909,16 +974,16 @@ export class Industry {
|
|||||||
sCost = optimalPrice;
|
sCost = optimalPrice;
|
||||||
} else if (product.marketTa1) {
|
} else if (product.marketTa1) {
|
||||||
sCost = product.pCost + markupLimit;
|
sCost = product.pCost + markupLimit;
|
||||||
} else if (isString(product.sCost)) {
|
} else if (isString(product.sCost[city])) {
|
||||||
const sCostString = product.sCost as string;
|
const sCostString = product.sCost[city] as string;
|
||||||
if (product.mku === 0) {
|
if (product.mku === 0) {
|
||||||
console.error(`mku is zero, reverting to 1 to avoid Infinity`);
|
console.error(`mku is zero, reverting to 1 to avoid Infinity`);
|
||||||
product.mku = 1;
|
product.mku = 1;
|
||||||
}
|
}
|
||||||
sCost = sCostString.replace(/MP/g, product.pCost + product.rat / product.mku + "");
|
sCost = sCostString.replace(/MP/g, product.pCost + "");
|
||||||
sCost = Math.max(product.pCost, eval(sCost));
|
sCost = Math.max(product.pCost, eval(sCost));
|
||||||
} else {
|
} else {
|
||||||
sCost = product.sCost;
|
sCost = product.sCost[city];
|
||||||
}
|
}
|
||||||
|
|
||||||
let markup = 1;
|
let markup = 1;
|
||||||
@ -930,7 +995,7 @@ export class Industry {
|
|||||||
|
|
||||||
product.maxsll =
|
product.maxsll =
|
||||||
0.5 *
|
0.5 *
|
||||||
Math.pow(product.rat, 0.65) *
|
Math.pow(product.data[city][3], 0.65) *
|
||||||
marketFactor *
|
marketFactor *
|
||||||
corporation.getSalesMultiplier() *
|
corporation.getSalesMultiplier() *
|
||||||
Math.pow(markup, 2) *
|
Math.pow(markup, 2) *
|
||||||
@ -996,10 +1061,10 @@ export class Industry {
|
|||||||
|
|
||||||
applyAdVert(corporation: Corporation): void {
|
applyAdVert(corporation: Corporation): void {
|
||||||
const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier();
|
const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier();
|
||||||
const awareness = (this.awareness + 3 * advMult) * (1.01 * advMult);
|
const awareness = (this.awareness + 3 * advMult) * (1.005 * advMult);
|
||||||
this.awareness = Math.min(awareness, Number.MAX_VALUE);
|
this.awareness = Math.min(awareness, Number.MAX_VALUE);
|
||||||
|
|
||||||
const popularity = (this.popularity + 1 * advMult) * ((1 + getRandomInt(1, 3) / 100) * advMult);
|
const popularity = (this.popularity + 1 * advMult) * ((1 + getRandomInt(1, 3) / 200) * advMult);
|
||||||
this.popularity = Math.min(popularity, Number.MAX_VALUE);
|
this.popularity = Math.min(popularity, Number.MAX_VALUE);
|
||||||
|
|
||||||
++this.numAdVerts;
|
++this.numAdVerts;
|
||||||
@ -1154,7 +1219,7 @@ export class Industry {
|
|||||||
const matNameMap = { AICores: "AI Cores", RealEstate: "Real Estate" };
|
const matNameMap = { AICores: "AI Cores", RealEstate: "Real Estate" };
|
||||||
const indNameMap = {
|
const indNameMap = {
|
||||||
RealEstate: IndustryType.RealEstate,
|
RealEstate: IndustryType.RealEstate,
|
||||||
Utilities: IndustryType.Utilities,
|
Water: IndustryType.Water,
|
||||||
Computers: IndustryType.Computers,
|
Computers: IndustryType.Computers,
|
||||||
Computer: IndustryType.Computers,
|
Computer: IndustryType.Computers,
|
||||||
};
|
};
|
||||||
|
@ -17,9 +17,35 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.3,
|
robotFactor: 0.3,
|
||||||
aiCoreFactor: 0.3,
|
aiCoreFactor: 0.3,
|
||||||
advertisingFactor: 0.04,
|
advertisingFactor: 0.04,
|
||||||
requiredMaterials: { Water: 0.5, Energy: 0.5 },
|
requiredMaterials: { Water: 0.5, Chemicals: 0.2 },
|
||||||
producedMaterials: ["Plants", "Food"],
|
producedMaterials: ["Plants", "Food"],
|
||||||
},
|
},
|
||||||
|
[IndustryType.Spring]: {
|
||||||
|
startingCost: 10e9,
|
||||||
|
description: "Gather water through passive means.",
|
||||||
|
recommendStarting: false,
|
||||||
|
realEstateFactor: 0.2,
|
||||||
|
scienceFactor: 0.1,
|
||||||
|
hardwareFactor: 0.0,
|
||||||
|
robotFactor: 0.0,
|
||||||
|
aiCoreFactor: 0.1,
|
||||||
|
advertisingFactor: 0.03,
|
||||||
|
requiredMaterials: {},
|
||||||
|
producedMaterials: ["Plants", "Food"],
|
||||||
|
},
|
||||||
|
[IndustryType.Refinery]: {
|
||||||
|
startingCost: 50e9,
|
||||||
|
description: "Refine ore into usable metal.",
|
||||||
|
recommendStarting: true,
|
||||||
|
realEstateFactor: 0.3,
|
||||||
|
scienceFactor: 0.5,
|
||||||
|
hardwareFactor: 0.5,
|
||||||
|
robotFactor: 0.4,
|
||||||
|
aiCoreFactor: 0.3,
|
||||||
|
advertisingFactor: 0.04,
|
||||||
|
requiredMaterials: { Ore: 1 },
|
||||||
|
producedMaterials: ["Metal"],
|
||||||
|
},
|
||||||
[IndustryType.Chemical]: {
|
[IndustryType.Chemical]: {
|
||||||
startingCost: 70e9,
|
startingCost: 70e9,
|
||||||
description: "Produce industrial chemicals.",
|
description: "Produce industrial chemicals.",
|
||||||
@ -30,7 +56,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.25,
|
robotFactor: 0.25,
|
||||||
aiCoreFactor: 0.2,
|
aiCoreFactor: 0.2,
|
||||||
advertisingFactor: 0.07,
|
advertisingFactor: 0.07,
|
||||||
requiredMaterials: { Plants: 1, Energy: 0.5, Water: 0.5 },
|
requiredMaterials: { Plants: 1, Water: 0.5 },
|
||||||
producedMaterials: ["Chemicals"],
|
producedMaterials: ["Chemicals"],
|
||||||
},
|
},
|
||||||
[IndustryType.Computers]: {
|
[IndustryType.Computers]: {
|
||||||
@ -55,21 +81,9 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.36,
|
robotFactor: 0.36,
|
||||||
aiCoreFactor: 0.19,
|
aiCoreFactor: 0.19,
|
||||||
advertisingFactor: 0.17,
|
advertisingFactor: 0.17,
|
||||||
requiredMaterials: { Metal: 2, Energy: 1 },
|
requiredMaterials: { Metal: 2 },
|
||||||
producedMaterials: ["Hardware"],
|
producedMaterials: ["Hardware"],
|
||||||
},
|
},
|
||||||
[IndustryType.Energy]: {
|
|
||||||
startingCost: 225e9,
|
|
||||||
description: "Engage in the production and distribution of energy.",
|
|
||||||
recommendStarting: false,
|
|
||||||
realEstateFactor: 0.65,
|
|
||||||
scienceFactor: 0.7,
|
|
||||||
robotFactor: 0.05,
|
|
||||||
aiCoreFactor: 0.3,
|
|
||||||
advertisingFactor: 0.08,
|
|
||||||
requiredMaterials: { Hardware: 0.1, Metal: 0.2 },
|
|
||||||
producedMaterials: ["Energy"],
|
|
||||||
},
|
|
||||||
[IndustryType.Fishing]: {
|
[IndustryType.Fishing]: {
|
||||||
startingCost: 80e9,
|
startingCost: 80e9,
|
||||||
description: "Produce food through the breeding and processing of fish and fish products.",
|
description: "Produce food through the breeding and processing of fish and fish products.",
|
||||||
@ -80,10 +94,10 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.5,
|
robotFactor: 0.5,
|
||||||
aiCoreFactor: 0.2,
|
aiCoreFactor: 0.2,
|
||||||
advertisingFactor: 0.08,
|
advertisingFactor: 0.08,
|
||||||
requiredMaterials: { Energy: 0.5 },
|
requiredMaterials: { Plants: 0.5 },
|
||||||
producedMaterials: ["Food"],
|
producedMaterials: ["Food"],
|
||||||
},
|
},
|
||||||
[IndustryType.Food]: {
|
[IndustryType.Restaurant]: {
|
||||||
startingCost: 10e9,
|
startingCost: 10e9,
|
||||||
description: "Create your own restaurants all around the world.",
|
description: "Create your own restaurants all around the world.",
|
||||||
product: {
|
product: {
|
||||||
@ -103,7 +117,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
aiCoreFactor: 0.25,
|
aiCoreFactor: 0.25,
|
||||||
advertisingFactor: 0.25,
|
advertisingFactor: 0.25,
|
||||||
realEstateFactor: 0.05,
|
realEstateFactor: 0.05,
|
||||||
requiredMaterials: { Food: 0.5, Water: 0.5, Energy: 0.2 },
|
requiredMaterials: { Food: 0.5, Water: 0.5 },
|
||||||
},
|
},
|
||||||
[IndustryType.Healthcare]: {
|
[IndustryType.Healthcare]: {
|
||||||
startingCost: 750e9,
|
startingCost: 750e9,
|
||||||
@ -127,7 +141,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
hardwareFactor: 0.1,
|
hardwareFactor: 0.1,
|
||||||
robotFactor: 0.1,
|
robotFactor: 0.1,
|
||||||
aiCoreFactor: 0.1,
|
aiCoreFactor: 0.1,
|
||||||
requiredMaterials: { Robots: 10, "AI Cores": 5, Energy: 5, Water: 5 },
|
requiredMaterials: { Robots: 10, "AI Cores": 5, Drugs: 5, Food: 5 },
|
||||||
},
|
},
|
||||||
[IndustryType.Mining]: {
|
[IndustryType.Mining]: {
|
||||||
startingCost: 300e9,
|
startingCost: 300e9,
|
||||||
@ -139,8 +153,8 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.45,
|
robotFactor: 0.45,
|
||||||
aiCoreFactor: 0.45,
|
aiCoreFactor: 0.45,
|
||||||
advertisingFactor: 0.06,
|
advertisingFactor: 0.06,
|
||||||
requiredMaterials: { Energy: 0.8 },
|
requiredMaterials: { Hardware: 0.1 },
|
||||||
producedMaterials: ["Metal"],
|
producedMaterials: ["Ore", "Minerals"],
|
||||||
},
|
},
|
||||||
[IndustryType.Pharmaceutical]: {
|
[IndustryType.Pharmaceutical]: {
|
||||||
startingCost: 200e9,
|
startingCost: 200e9,
|
||||||
@ -164,7 +178,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.25,
|
robotFactor: 0.25,
|
||||||
aiCoreFactor: 0.2,
|
aiCoreFactor: 0.2,
|
||||||
advertisingFactor: 0.16,
|
advertisingFactor: 0.16,
|
||||||
requiredMaterials: { Chemicals: 2, Energy: 1, Water: 0.5 },
|
requiredMaterials: { Chemicals: 2, Water: 0.5 },
|
||||||
producedMaterials: ["Drugs"],
|
producedMaterials: ["Drugs"],
|
||||||
},
|
},
|
||||||
[IndustryType.RealEstate]: {
|
[IndustryType.RealEstate]: {
|
||||||
@ -188,7 +202,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
advertisingFactor: 0.25,
|
advertisingFactor: 0.25,
|
||||||
scienceFactor: 0.05,
|
scienceFactor: 0.05,
|
||||||
hardwareFactor: 0.05,
|
hardwareFactor: 0.05,
|
||||||
requiredMaterials: { Metal: 5, Energy: 5, Water: 2, Hardware: 4 },
|
requiredMaterials: { Metal: 5, Plants: 1, Water: 2, Hardware: 4 },
|
||||||
producedMaterials: ["Real Estate"],
|
producedMaterials: ["Real Estate"],
|
||||||
},
|
},
|
||||||
[IndustryType.Robotics]: {
|
[IndustryType.Robotics]: {
|
||||||
@ -213,7 +227,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
aiCoreFactor: 0.36,
|
aiCoreFactor: 0.36,
|
||||||
advertisingFactor: 0.18,
|
advertisingFactor: 0.18,
|
||||||
hardwareFactor: 0.19,
|
hardwareFactor: 0.19,
|
||||||
requiredMaterials: { Hardware: 5, Energy: 3 },
|
requiredMaterials: { Hardware: 5, "AI Cores": 3 },
|
||||||
producedMaterials: ["Robots"],
|
producedMaterials: ["Robots"],
|
||||||
},
|
},
|
||||||
[IndustryType.Software]: {
|
[IndustryType.Software]: {
|
||||||
@ -238,7 +252,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
realEstateFactor: 0.15,
|
realEstateFactor: 0.15,
|
||||||
aiCoreFactor: 0.18,
|
aiCoreFactor: 0.18,
|
||||||
robotFactor: 0.05,
|
robotFactor: 0.05,
|
||||||
requiredMaterials: { Hardware: 0.5, Energy: 0.5 },
|
requiredMaterials: { Hardware: 0.5 },
|
||||||
producedMaterials: ["AI Cores"],
|
producedMaterials: ["AI Cores"],
|
||||||
},
|
},
|
||||||
[IndustryType.Tobacco]: {
|
[IndustryType.Tobacco]: {
|
||||||
@ -261,9 +275,9 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.2,
|
robotFactor: 0.2,
|
||||||
aiCoreFactor: 0.15,
|
aiCoreFactor: 0.15,
|
||||||
advertisingFactor: 0.2,
|
advertisingFactor: 0.2,
|
||||||
requiredMaterials: { Plants: 1, Water: 0.2 },
|
requiredMaterials: { Plants: 1 },
|
||||||
},
|
},
|
||||||
[IndustryType.Utilities]: {
|
[IndustryType.Water]: {
|
||||||
startingCost: 150e9,
|
startingCost: 150e9,
|
||||||
description: "Distribute water and provide wastewater services.",
|
description: "Distribute water and provide wastewater services.",
|
||||||
recommendStarting: false,
|
recommendStarting: false,
|
||||||
@ -272,7 +286,7 @@ export const IndustriesData: Record<CorpIndustryName, CorpIndustryData> = {
|
|||||||
robotFactor: 0.4,
|
robotFactor: 0.4,
|
||||||
aiCoreFactor: 0.4,
|
aiCoreFactor: 0.4,
|
||||||
advertisingFactor: 0.08,
|
advertisingFactor: 0.08,
|
||||||
requiredMaterials: { Hardware: 0.1, Metal: 0.1 },
|
requiredMaterials: { Hardware: 0.1 },
|
||||||
producedMaterials: ["Water"],
|
producedMaterials: ["Water"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ export class Material {
|
|||||||
qty = 0;
|
qty = 0;
|
||||||
|
|
||||||
// Material's "quality". Unbounded
|
// Material's "quality". Unbounded
|
||||||
qlt = 0;
|
qlt = 1;
|
||||||
|
|
||||||
// How much demand the Material has in the market, and the range of possible
|
// How much demand the Material has in the market, and the range of possible
|
||||||
// values for this "demand"
|
// values for this "demand"
|
||||||
|
@ -13,14 +13,25 @@ export const MaterialInfo: Record<CorpMaterialName, CorpMaterialConstantData> =
|
|||||||
maxVolatility: 0.2,
|
maxVolatility: 0.2,
|
||||||
baseMarkup: 6,
|
baseMarkup: 6,
|
||||||
},
|
},
|
||||||
Energy: {
|
Ore: {
|
||||||
name: "Energy",
|
name: "Ore",
|
||||||
size: 0.01,
|
size: 0.01,
|
||||||
demandBase: 90,
|
demandBase: 50,
|
||||||
demandRange: [80, 99],
|
demandRange: [40, 60],
|
||||||
competitionBase: 80,
|
competitionBase: 80,
|
||||||
competitionRange: [65, 95],
|
competitionRange: [65, 95],
|
||||||
baseCost: 2000,
|
baseCost: 500,
|
||||||
|
maxVolatility: 0.2,
|
||||||
|
baseMarkup: 6,
|
||||||
|
},
|
||||||
|
Minerals: {
|
||||||
|
name: "Minerals",
|
||||||
|
size: 0.04,
|
||||||
|
demandBase: 75,
|
||||||
|
demandRange: [90, 60],
|
||||||
|
competitionBase: 80,
|
||||||
|
competitionRange: [65, 95],
|
||||||
|
baseCost: 500,
|
||||||
maxVolatility: 0.2,
|
maxVolatility: 0.2,
|
||||||
baseMarkup: 6,
|
baseMarkup: 6,
|
||||||
},
|
},
|
||||||
|
@ -16,11 +16,9 @@ export class OfficeSpace {
|
|||||||
size: number;
|
size: number;
|
||||||
|
|
||||||
maxEne = 100;
|
maxEne = 100;
|
||||||
maxHap = 100;
|
|
||||||
maxMor = 100;
|
maxMor = 100;
|
||||||
|
|
||||||
avgEne = 75;
|
avgEne = 75;
|
||||||
avgHap = 75;
|
|
||||||
avgMor = 75;
|
avgMor = 75;
|
||||||
|
|
||||||
avgInt = 75;
|
avgInt = 75;
|
||||||
@ -32,9 +30,9 @@ export class OfficeSpace {
|
|||||||
totalEmployees = 0;
|
totalEmployees = 0;
|
||||||
totalSalary = 0;
|
totalSalary = 0;
|
||||||
|
|
||||||
autoCoffee = false;
|
autoTea = false;
|
||||||
autoParty = false;
|
autoParty = false;
|
||||||
coffeePending = false;
|
teaPending = false;
|
||||||
partyMult = 1;
|
partyMult = 1;
|
||||||
|
|
||||||
employeeProd: Record<EmployeePositions | "total", number> = {
|
employeeProd: Record<EmployeePositions | "total", number> = {
|
||||||
@ -43,7 +41,7 @@ export class OfficeSpace {
|
|||||||
[EmployeePositions.Business]: 0,
|
[EmployeePositions.Business]: 0,
|
||||||
[EmployeePositions.Management]: 0,
|
[EmployeePositions.Management]: 0,
|
||||||
[EmployeePositions.RandD]: 0,
|
[EmployeePositions.RandD]: 0,
|
||||||
[EmployeePositions.Training]: 0,
|
[EmployeePositions.Intern]: 0,
|
||||||
[EmployeePositions.Unassigned]: 0,
|
[EmployeePositions.Unassigned]: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
};
|
};
|
||||||
@ -53,7 +51,7 @@ export class OfficeSpace {
|
|||||||
[EmployeePositions.Business]: 0,
|
[EmployeePositions.Business]: 0,
|
||||||
[EmployeePositions.Management]: 0,
|
[EmployeePositions.Management]: 0,
|
||||||
[EmployeePositions.RandD]: 0,
|
[EmployeePositions.RandD]: 0,
|
||||||
[EmployeePositions.Training]: 0,
|
[EmployeePositions.Intern]: 0,
|
||||||
[EmployeePositions.Unassigned]: 0,
|
[EmployeePositions.Unassigned]: 0,
|
||||||
};
|
};
|
||||||
employeeNextJobs: Record<EmployeePositions, number> = {
|
employeeNextJobs: Record<EmployeePositions, number> = {
|
||||||
@ -62,7 +60,7 @@ export class OfficeSpace {
|
|||||||
[EmployeePositions.Business]: 0,
|
[EmployeePositions.Business]: 0,
|
||||||
[EmployeePositions.Management]: 0,
|
[EmployeePositions.Management]: 0,
|
||||||
[EmployeePositions.RandD]: 0,
|
[EmployeePositions.RandD]: 0,
|
||||||
[EmployeePositions.Training]: 0,
|
[EmployeePositions.Intern]: 0,
|
||||||
[EmployeePositions.Unassigned]: 0,
|
[EmployeePositions.Unassigned]: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,10 +74,10 @@ export class OfficeSpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process(marketCycles = 1, corporation: Corporation, industry: Industry): number {
|
process(marketCycles = 1, corporation: Corporation, industry: Industry): number {
|
||||||
// HRBuddy AutoRecruitment and training
|
// HRBuddy AutoRecruitment and Interning
|
||||||
if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
|
if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
|
||||||
this.hireRandomEmployee(
|
this.hireRandomEmployee(
|
||||||
industry.hasResearch("HRBuddy-Training") ? EmployeePositions.Training : EmployeePositions.Unassigned,
|
industry.hasResearch("HRBuddy-Training") ? EmployeePositions.Intern : EmployeePositions.Unassigned,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,62 +88,57 @@ export class OfficeSpace {
|
|||||||
|
|
||||||
// Process Office properties
|
// Process Office properties
|
||||||
this.maxEne = 100;
|
this.maxEne = 100;
|
||||||
this.maxHap = 100;
|
|
||||||
this.maxMor = 100;
|
this.maxMor = 100;
|
||||||
|
|
||||||
if (industry.hasResearch("Go-Juice")) this.maxEne += 10;
|
if (industry.hasResearch("Go-Juice")) this.maxEne += 10;
|
||||||
if (industry.hasResearch("JoyWire")) this.maxHap += 10;
|
|
||||||
if (industry.hasResearch("Sti.mu")) this.maxMor += 10;
|
if (industry.hasResearch("Sti.mu")) this.maxMor += 10;
|
||||||
if (industry.hasResearch("AutoBrew")) this.autoCoffee = true;
|
if (industry.hasResearch("AutoBrew")) this.autoTea = true;
|
||||||
if (industry.hasResearch("AutoPartyManager")) this.autoParty = true;
|
if (industry.hasResearch("AutoPartyManager")) this.autoParty = true;
|
||||||
|
|
||||||
if (this.totalEmployees > 0) {
|
if (this.totalEmployees > 0) {
|
||||||
/** Multiplier for employee morale/happiness/energy based on company performance */
|
/** Multiplier for employee morale/energy based on company performance */
|
||||||
const perfMult = Math.pow(
|
let perfMult = 1.002;
|
||||||
1.002 -
|
if (this.totalEmployees >= 9) {
|
||||||
(corporation.funds < 0 ? 0.002 : 0) -
|
perfMult = Math.pow(
|
||||||
(industry.lastCycleRevenue < industry.lastCycleExpenses ? 0.002 : 0),
|
1 +
|
||||||
marketCycles,
|
0.002 * Math.min(1 / 9, this.employeeJobs.Intern / this.totalEmployees - 1 / 9) * 9 -
|
||||||
);
|
(corporation.funds < 0 && industry.lastCycleRevenue < industry.lastCycleExpenses ? 0.001 : 0),
|
||||||
|
marketCycles,
|
||||||
|
);
|
||||||
|
}
|
||||||
// Flat reduction per cycle.
|
// Flat reduction per cycle.
|
||||||
// This does not cause a noticable decrease (it's only -.001% per cycle), it only serves
|
// This does not cause a noticable decrease (it's only -.001% per cycle).
|
||||||
// to make the numbers slightly different between Happiness and Morale.
|
const reduction = 0.002 * marketCycles;
|
||||||
const reduction = 0.001 * marketCycles;
|
|
||||||
|
|
||||||
if (this.autoCoffee) {
|
if (this.autoTea) {
|
||||||
this.avgEne = this.maxEne;
|
this.avgEne = this.maxEne;
|
||||||
} else {
|
} else {
|
||||||
// Coffee gives a flat +3 to energy
|
// Tea gives a flat +2 to energy
|
||||||
this.avgEne = (this.avgEne - reduction) * perfMult + (this.coffeePending ? 3 : 0);
|
this.avgEne = (this.avgEne - reduction * Math.random()) * perfMult + (this.teaPending ? 2 : 0);
|
||||||
// Coffee also halves the difference between current and max energy
|
|
||||||
if (this.coffeePending) this.avgEne = this.maxEne - (this.maxEne - this.avgEne) / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.autoParty) {
|
if (this.autoParty) {
|
||||||
this.avgMor = this.maxMor;
|
this.avgMor = this.maxMor;
|
||||||
this.avgHap = this.maxHap;
|
|
||||||
} else {
|
} else {
|
||||||
// Each 5% multiplier gives an extra flat +1 to morale and happiness to make recovering from low morale easier.
|
// Each 5% multiplier gives an extra flat +1 to morale to make recovering from low morale easier.
|
||||||
const increase = this.partyMult > 1 ? (this.partyMult - 1) * 20 : 0;
|
const increase = this.partyMult > 1 ? (this.partyMult - 1) * 10 : 0;
|
||||||
this.avgHap = ((this.avgHap - reduction) * perfMult + increase) * this.partyMult;
|
this.avgMor = ((this.avgMor - reduction * Math.random()) * perfMult + increase) * this.partyMult;
|
||||||
this.avgMor = (this.avgMor * perfMult + increase) * this.partyMult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.avgEne = Math.max(Math.min(this.avgEne, this.maxEne), corpConstants.minEmployeeDecay);
|
this.avgEne = Math.max(Math.min(this.avgEne, this.maxEne), corpConstants.minEmployeeDecay);
|
||||||
this.avgMor = Math.max(Math.min(this.avgMor, this.maxMor), corpConstants.minEmployeeDecay);
|
this.avgMor = Math.max(Math.min(this.avgMor, this.maxMor), corpConstants.minEmployeeDecay);
|
||||||
this.avgHap = Math.max(Math.min(this.avgHap, this.maxHap), corpConstants.minEmployeeDecay);
|
|
||||||
|
|
||||||
this.coffeePending = false;
|
this.teaPending = false;
|
||||||
this.partyMult = 1;
|
this.partyMult = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get experience increase; unassigned employees do not contribute, employees in training contribute 5x
|
// Get experience increase; unassigned employees do not contribute, interning employees contribute 10x
|
||||||
this.totalExp +=
|
this.totalExp +=
|
||||||
0.0015 *
|
0.0015 *
|
||||||
marketCycles *
|
marketCycles *
|
||||||
(this.totalEmployees -
|
(this.totalEmployees -
|
||||||
this.employeeJobs[EmployeePositions.Unassigned] +
|
this.employeeJobs[EmployeePositions.Unassigned] +
|
||||||
this.employeeJobs[EmployeePositions.Training] * 4);
|
this.employeeJobs[EmployeePositions.Intern] * 9);
|
||||||
|
|
||||||
this.calculateEmployeeProductivity(corporation, industry);
|
this.calculateEmployeeProductivity(corporation, industry);
|
||||||
if (this.totalEmployees === 0) {
|
if (this.totalEmployees === 0) {
|
||||||
@ -165,7 +158,7 @@ export class OfficeSpace {
|
|||||||
effCha = this.avgCha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
effCha = this.avgCha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
||||||
effInt = this.avgInt * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
effInt = this.avgInt * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
||||||
effEff = this.avgEff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
effEff = this.avgEff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
||||||
const prodBase = this.avgMor * this.avgHap * this.avgEne * 1e-6;
|
const prodBase = this.avgMor * this.avgEne * 1e-4;
|
||||||
|
|
||||||
let total = 0;
|
let total = 0;
|
||||||
const exp = this.totalExp / this.totalEmployees || 0;
|
const exp = this.totalExp / this.totalEmployees || 0;
|
||||||
@ -188,7 +181,7 @@ export class OfficeSpace {
|
|||||||
prodMult = 1.5 * effInt + 0.8 * exp + effCre + 0.5 * effEff;
|
prodMult = 1.5 * effInt + 0.8 * exp + effCre + 0.5 * effEff;
|
||||||
break;
|
break;
|
||||||
case EmployeePositions.Unassigned:
|
case EmployeePositions.Unassigned:
|
||||||
case EmployeePositions.Training:
|
case EmployeePositions.Intern:
|
||||||
case "total":
|
case "total":
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@ -213,7 +206,6 @@ export class OfficeSpace {
|
|||||||
this.totalExp += getRandomInt(50, 100);
|
this.totalExp += getRandomInt(50, 100);
|
||||||
|
|
||||||
this.avgMor = (this.avgMor * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
this.avgMor = (this.avgMor * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
||||||
this.avgHap = (this.avgHap * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
|
||||||
this.avgEne = (this.avgEne * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
this.avgEne = (this.avgEne * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
||||||
|
|
||||||
this.avgInt = (this.avgInt * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
this.avgInt = (this.avgInt * this.totalEmployees + getRandomInt(50, 100)) / (this.totalEmployees + 1);
|
||||||
@ -240,13 +232,13 @@ export class OfficeSpace {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCoffeeCost(): number {
|
getTeaCost(): number {
|
||||||
return corpConstants.coffeeCostPerEmployee * this.totalEmployees;
|
return corpConstants.teaCostPerEmployee * this.totalEmployees;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCoffee(): boolean {
|
setTea(): boolean {
|
||||||
if (!this.coffeePending && !this.autoCoffee && this.totalEmployees > 0) {
|
if (!this.teaPending && !this.autoTea && this.totalEmployees > 0) {
|
||||||
this.coffeePending = true;
|
this.teaPending = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -267,11 +259,10 @@ export class OfficeSpace {
|
|||||||
static fromJSON(value: IReviverValue): OfficeSpace {
|
static fromJSON(value: IReviverValue): OfficeSpace {
|
||||||
// Convert employees from the old version
|
// Convert employees from the old version
|
||||||
if (value.data.hasOwnProperty("employees")) {
|
if (value.data.hasOwnProperty("employees")) {
|
||||||
const empCopy: [{ data: { hap: number; mor: number; ene: number; exp: number } }] = value.data.employees;
|
const empCopy: [{ data: { mor: number; ene: number; exp: number } }] = value.data.employees;
|
||||||
delete value.data.employees;
|
delete value.data.employees;
|
||||||
const ret = Generic_fromJSON(OfficeSpace, value.data);
|
const ret = Generic_fromJSON(OfficeSpace, value.data);
|
||||||
ret.totalEmployees = empCopy.length;
|
ret.totalEmployees = empCopy.length;
|
||||||
ret.avgHap = empCopy.reduce((a, b) => a + b.data.hap, 0) / ret.totalEmployees || 75;
|
|
||||||
ret.avgMor = empCopy.reduce((a, b) => a + b.data.mor, 0) / ret.totalEmployees || 75;
|
ret.avgMor = empCopy.reduce((a, b) => a + b.data.mor, 0) / ret.totalEmployees || 75;
|
||||||
ret.avgEne = empCopy.reduce((a, b) => a + b.data.ene, 0) / ret.totalEmployees || 75;
|
ret.avgEne = empCopy.reduce((a, b) => a + b.data.ene, 0) / ret.totalEmployees || 75;
|
||||||
ret.totalExp = empCopy.reduce((a, b) => a + b.data.exp, 0);
|
ret.totalExp = empCopy.reduce((a, b) => a + b.data.exp, 0);
|
||||||
|
@ -47,8 +47,8 @@ export class Product {
|
|||||||
// Production cost - estimation of how much money it costs to make this Product
|
// Production cost - estimation of how much money it costs to make this Product
|
||||||
pCost = 0;
|
pCost = 0;
|
||||||
|
|
||||||
// Sell cost
|
// Sell costs
|
||||||
sCost: string | number = 0;
|
sCost: Record<string, any> = createCityMap<any>(0);
|
||||||
|
|
||||||
// Variables for handling the creation process of this Product
|
// Variables for handling the creation process of this Product
|
||||||
fin = false; // Whether this Product has finished being created
|
fin = false; // Whether this Product has finished being created
|
||||||
@ -82,8 +82,8 @@ export class Product {
|
|||||||
|
|
||||||
// Data refers to the production, sale, and quantity of the products
|
// Data refers to the production, sale, and quantity of the products
|
||||||
// These values are specific to a city
|
// These values are specific to a city
|
||||||
// For each city, the data is [qty, prod, sell]
|
// For each city, the data is [qty, prod, sell, effRat]
|
||||||
data: Record<string, number[]> = createCityMap<number[]>([0, 0, 0]);
|
data: Record<string, number[]> = createCityMap<number[]>([0, 0, 0, 0]);
|
||||||
|
|
||||||
// Location of this Product
|
// Location of this Product
|
||||||
// Only applies for location-based products like restaurants/hospitals
|
// Only applies for location-based products like restaurants/hospitals
|
||||||
@ -130,7 +130,7 @@ export class Product {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make progress on this product based on current employee productivity
|
// Make progress on this product based on current employee productivity
|
||||||
createProduct(marketCycles: number, employeeProd: typeof this["creationProd"]): void {
|
createProduct(marketCycles: number, employeeProd: typeof this.creationProd): void {
|
||||||
if (this.fin) {
|
if (this.fin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@ export class Warehouse {
|
|||||||
// Whether Smart Supply is enabled for this Industry (the Industry that this Warehouse is for)
|
// Whether Smart Supply is enabled for this Industry (the Industry that this Warehouse is for)
|
||||||
smartSupplyEnabled = false;
|
smartSupplyEnabled = false;
|
||||||
|
|
||||||
// Decide if smart supply should use the materials already in the warehouse when deciding on the amount to buy.
|
// Decide if smart supply should use the amount of materials imported into account when deciding on the amount to buy.
|
||||||
smartSupplyUseLeftovers: Record<CorpMaterialName, boolean>;
|
smartSupplyOptions: Record<CorpMaterialName, string>;
|
||||||
|
|
||||||
// Stores the amount of product to be produced. Used for Smart Supply unlock.
|
// Stores the amount of product to be produced. Used for Smart Supply unlock.
|
||||||
// The production tracked by smart supply is always based on the previous cycle,
|
// The production tracked by smart supply is always based on the previous cycle,
|
||||||
@ -47,10 +47,10 @@ export class Warehouse {
|
|||||||
this.size = params.size ? params.size : 0;
|
this.size = params.size ? params.size : 0;
|
||||||
|
|
||||||
this.materials = {} as Record<CorpMaterialName, Material>;
|
this.materials = {} as Record<CorpMaterialName, Material>;
|
||||||
this.smartSupplyUseLeftovers = {} as Record<CorpMaterialName, boolean>;
|
this.smartSupplyOptions = {} as Record<CorpMaterialName, string>;
|
||||||
for (const matName of materialNames) {
|
for (const matName of materialNames) {
|
||||||
this.materials[matName] = new Material({ name: matName });
|
this.materials[matName] = new Material({ name: matName });
|
||||||
this.smartSupplyUseLeftovers[matName] = true;
|
this.smartSupplyOptions[matName] = "leftovers";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.corp && params.industry) {
|
if (params.corp && params.industry) {
|
||||||
|
@ -20,7 +20,6 @@ function createBaseResearchTreeNodes(): Node {
|
|||||||
const autoBrew: Node = makeNode("AutoBrew");
|
const autoBrew: Node = makeNode("AutoBrew");
|
||||||
const autoParty: Node = makeNode("AutoPartyManager");
|
const autoParty: Node = makeNode("AutoPartyManager");
|
||||||
const autoDrugs: Node = makeNode("Automatic Drug Administration");
|
const autoDrugs: Node = makeNode("Automatic Drug Administration");
|
||||||
const bulkPurchasing: Node = makeNode("Bulk Purchasing");
|
|
||||||
const cph4: Node = makeNode("CPH4 Injections");
|
const cph4: Node = makeNode("CPH4 Injections");
|
||||||
const drones: Node = makeNode("Drones");
|
const drones: Node = makeNode("Drones");
|
||||||
const dronesAssembly: Node = makeNode("Drones - Assembly");
|
const dronesAssembly: Node = makeNode("Drones - Assembly");
|
||||||
@ -28,7 +27,6 @@ function createBaseResearchTreeNodes(): Node {
|
|||||||
const goJuice: Node = makeNode("Go-Juice");
|
const goJuice: Node = makeNode("Go-Juice");
|
||||||
const hrRecruitment: Node = makeNode("HRBuddy-Recruitment");
|
const hrRecruitment: Node = makeNode("HRBuddy-Recruitment");
|
||||||
const hrTraining: Node = makeNode("HRBuddy-Training");
|
const hrTraining: Node = makeNode("HRBuddy-Training");
|
||||||
const joywire: Node = makeNode("JoyWire");
|
|
||||||
const marketta1: Node = makeNode("Market-TA.I");
|
const marketta1: Node = makeNode("Market-TA.I");
|
||||||
const marketta2: Node = makeNode("Market-TA.II");
|
const marketta2: Node = makeNode("Market-TA.II");
|
||||||
const overclock: Node = makeNode("Overclock");
|
const overclock: Node = makeNode("Overclock");
|
||||||
@ -50,10 +48,8 @@ function createBaseResearchTreeNodes(): Node {
|
|||||||
rootNode.addChild(autoBrew);
|
rootNode.addChild(autoBrew);
|
||||||
rootNode.addChild(autoParty);
|
rootNode.addChild(autoParty);
|
||||||
rootNode.addChild(autoDrugs);
|
rootNode.addChild(autoDrugs);
|
||||||
rootNode.addChild(bulkPurchasing);
|
|
||||||
rootNode.addChild(drones);
|
rootNode.addChild(drones);
|
||||||
rootNode.addChild(hrRecruitment);
|
rootNode.addChild(hrRecruitment);
|
||||||
rootNode.addChild(joywire);
|
|
||||||
rootNode.addChild(marketta1);
|
rootNode.addChild(marketta1);
|
||||||
rootNode.addChild(overclock);
|
rootNode.addChild(overclock);
|
||||||
rootNode.addChild(scAssemblers);
|
rootNode.addChild(scAssemblers);
|
||||||
|
@ -24,7 +24,8 @@ export const stateNames: CorpStateName[] = ["START", "PURCHASE", "PRODUCTION", "
|
|||||||
/** Names of all materials */
|
/** Names of all materials */
|
||||||
materialNames: CorpMaterialName[] = [
|
materialNames: CorpMaterialName[] = [
|
||||||
"Water",
|
"Water",
|
||||||
"Energy",
|
"Ore",
|
||||||
|
"Minerals",
|
||||||
"Food",
|
"Food",
|
||||||
"Plants",
|
"Plants",
|
||||||
"Metal",
|
"Metal",
|
||||||
@ -73,7 +74,6 @@ export const stateNames: CorpStateName[] = ["START", "PURCHASE", "PRODUCTION", "
|
|||||||
"Go-Juice",
|
"Go-Juice",
|
||||||
"HRBuddy-Recruitment",
|
"HRBuddy-Recruitment",
|
||||||
"HRBuddy-Training",
|
"HRBuddy-Training",
|
||||||
"JoyWire",
|
|
||||||
"Market-TA.I",
|
"Market-TA.I",
|
||||||
"Market-TA.II",
|
"Market-TA.II",
|
||||||
"Overclock",
|
"Overclock",
|
||||||
@ -96,7 +96,7 @@ export const stateNames: CorpStateName[] = ["START", "PURCHASE", "PRODUCTION", "
|
|||||||
issueNewSharesCooldown = 216e3,
|
issueNewSharesCooldown = 216e3,
|
||||||
/** Cooldown for selling shares in game cycles. 1 hour. */
|
/** Cooldown for selling shares in game cycles. 1 hour. */
|
||||||
sellSharesCooldown = 18e3,
|
sellSharesCooldown = 18e3,
|
||||||
coffeeCostPerEmployee = 500e3,
|
teaCostPerEmployee = 500e3,
|
||||||
gameCyclesPerMarketCycle = 50,
|
gameCyclesPerMarketCycle = 50,
|
||||||
gameCyclesPerCorpStateCycle = gameCyclesPerMarketCycle / stateNames.length,
|
gameCyclesPerCorpStateCycle = gameCyclesPerMarketCycle / stateNames.length,
|
||||||
secondsPerMarketCycle = (gameCyclesPerMarketCycle * CONSTANTS.MilliPerCycle) / 1000,
|
secondsPerMarketCycle = (gameCyclesPerMarketCycle * CONSTANTS.MilliPerCycle) / 1000,
|
||||||
@ -117,7 +117,25 @@ export const stateNames: CorpStateName[] = ["START", "PURCHASE", "PRODUCTION", "
|
|||||||
/** Max products for a division without upgrades */
|
/** Max products for a division without upgrades */
|
||||||
maxProductsBase = 3,
|
maxProductsBase = 3,
|
||||||
fundingRoundShares = [0.1, 0.35, 0.25, 0.2],
|
fundingRoundShares = [0.1, 0.35, 0.25, 0.2],
|
||||||
fundingRoundMultiplier = [4, 3, 3, 2.5],
|
fundingRoundMultiplier = [3, 2, 2, 1.5],
|
||||||
valuationLength = 5,
|
valuationLength = 10,
|
||||||
/** Minimum decay value for employee morale/happiness/energy */
|
/** Minimum decay value for employee morale/energy */
|
||||||
minEmployeeDecay = 10;
|
minEmployeeDecay = 10,
|
||||||
|
/**smart supply ot */
|
||||||
|
smartSupplyUseOptions = ["leftovers", "imports", "none"],
|
||||||
|
PurchaseMultipliers: {
|
||||||
|
[key: string]: number | "MAX" | undefined;
|
||||||
|
x1: number;
|
||||||
|
x5: number;
|
||||||
|
x10: number;
|
||||||
|
x50: number;
|
||||||
|
x100: number;
|
||||||
|
MAX: "MAX";
|
||||||
|
} = {
|
||||||
|
x1: 1,
|
||||||
|
x5: 5,
|
||||||
|
x10: 10,
|
||||||
|
x50: 50,
|
||||||
|
x100: 100,
|
||||||
|
MAX: "MAX",
|
||||||
|
};
|
||||||
|
@ -66,7 +66,7 @@ export const CorporationUpgrades: Record<CorporationUpgradeIndex, CorporationUpg
|
|||||||
[CorporationUpgradeIndex.WilsonAnalytics]: {
|
[CorporationUpgradeIndex.WilsonAnalytics]: {
|
||||||
index: CorporationUpgradeIndex.WilsonAnalytics,
|
index: CorporationUpgradeIndex.WilsonAnalytics,
|
||||||
basePrice: 4e9,
|
basePrice: 4e9,
|
||||||
priceMult: 1.5,
|
priceMult: 2,
|
||||||
benefit: 0.005,
|
benefit: 0.005,
|
||||||
name: "Wilson Analytics",
|
name: "Wilson Analytics",
|
||||||
desc:
|
desc:
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
export enum IndustryType {
|
export enum IndustryType {
|
||||||
Energy = "Energy",
|
Water = "Water Utilities",
|
||||||
Utilities = "Water Utilities",
|
Spring = "Spring Water",
|
||||||
Agriculture = "Agriculture",
|
Agriculture = "Agriculture",
|
||||||
Fishing = "Fishing",
|
Fishing = "Fishing",
|
||||||
Mining = "Mining",
|
Mining = "Mining",
|
||||||
Food = "Food",
|
Refinery = "Refinery",
|
||||||
|
Restaurant = "Restaurant",
|
||||||
Tobacco = "Tobacco",
|
Tobacco = "Tobacco",
|
||||||
Chemical = "Chemical",
|
Chemical = "Chemical",
|
||||||
Pharmaceutical = "Pharmaceutical",
|
Pharmaceutical = "Pharmaceutical",
|
||||||
@ -21,6 +22,6 @@ export enum EmployeePositions {
|
|||||||
Business = "Business",
|
Business = "Business",
|
||||||
Management = "Management",
|
Management = "Management",
|
||||||
RandD = "Research & Development",
|
RandD = "Research & Development",
|
||||||
Training = "Training",
|
Intern = "Intern",
|
||||||
Unassigned = "Unassigned",
|
Unassigned = "Unassigned",
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,17 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
cost: 12e3,
|
cost: 12e3,
|
||||||
desc:
|
desc:
|
||||||
"Automatically keep your employees fully caffeinated with " +
|
"Automatically keep your employees fully caffeinated with " +
|
||||||
"coffee injections. This research will keep the energy of all " +
|
"tea injections. This research will keep the energy of all " +
|
||||||
"employees at its maximum possible value, for no cost. " +
|
"employees at its maximum possible value, for no cost. " +
|
||||||
"This will also disable the Coffee upgrade.",
|
"This will also disable the Tea upgrade.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "AutoPartyManager",
|
name: "AutoPartyManager",
|
||||||
cost: 15e3,
|
cost: 15e3,
|
||||||
desc:
|
desc:
|
||||||
"Automatically analyzes your employees' happiness and morale " +
|
"Automatically analyzes your employees' morale " +
|
||||||
"and boosts them whenever it detects a decrease. This research will " +
|
"and boosts them whenever it detects a decrease. This research will " +
|
||||||
"keep the morale and happiness of all employees at their maximum possible " +
|
"keep the morale of all employees at their maximum possible " +
|
||||||
"values, for no cost. " +
|
"values, for no cost. " +
|
||||||
"This will also disable the 'Throw Party' feature.",
|
"This will also disable the 'Throw Party' feature.",
|
||||||
},
|
},
|
||||||
@ -27,13 +27,6 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
"Research how to automatically administer performance-enhancing drugs to all of " +
|
"Research how to automatically administer performance-enhancing drugs to all of " +
|
||||||
"your employees. This unlocks Drug-related Research.",
|
"your employees. This unlocks Drug-related Research.",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Bulk Purchasing",
|
|
||||||
cost: 5e3,
|
|
||||||
desc:
|
|
||||||
"Research the art of buying materials in bulk. This allows you to purchase " +
|
|
||||||
"any amount of a material instantly.",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "CPH4 Injections",
|
name: "CPH4 Injections",
|
||||||
cost: 25e3,
|
cost: 25e3,
|
||||||
@ -73,7 +66,7 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
name: "Go-Juice",
|
name: "Go-Juice",
|
||||||
cost: 25e3,
|
cost: 25e3,
|
||||||
desc:
|
desc:
|
||||||
"Provide employees with Go-Juice, a coffee-derivative that further enhances " +
|
"Provide employees with Go-Juice, a tea-derivative that further enhances " +
|
||||||
"the brain's dopamine production. This increases the maximum energy of all " +
|
"the brain's dopamine production. This increases the maximum energy of all " +
|
||||||
"employees by 10.",
|
"employees by 10.",
|
||||||
},
|
},
|
||||||
@ -101,12 +94,7 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
desc:
|
desc:
|
||||||
"Use automated software to handle the training of employees. With this " +
|
"Use automated software to handle the training of employees. With this " +
|
||||||
"research, each employee hired with HRBuddy-Recruitment will automatically " +
|
"research, each employee hired with HRBuddy-Recruitment will automatically " +
|
||||||
"be assigned to 'Training', rather than being unassigned.",
|
"be assigned to 'Intern', rather than being unassigned.",
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "JoyWire",
|
|
||||||
cost: 20e3,
|
|
||||||
desc: "A brain implant which is installed in employees, increasing their maximum happiness by 10.",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Market-TA.I",
|
name: "Market-TA.I",
|
||||||
|
35
src/Corporation/helpers.tsx
Normal file
35
src/Corporation/helpers.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Corporation } from "./Corporation";
|
||||||
|
import { CorporationUpgrade } from "./data/CorporationUpgrades";
|
||||||
|
|
||||||
|
export function calculateUpgradeCost(corporation: Corporation, upgrade: CorporationUpgrade, amount: number): number {
|
||||||
|
if (amount < 1) return 0;
|
||||||
|
const priceMult = upgrade.priceMult;
|
||||||
|
const level = corporation.upgrades[upgrade.index];
|
||||||
|
const baseCost = upgrade.basePrice * Math.pow(priceMult, level);
|
||||||
|
const cost = (baseCost * (1 - Math.pow(priceMult, amount))) / (1 - priceMult);
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateMaxAffordableUpgrade(
|
||||||
|
corporation: Corporation,
|
||||||
|
upgrade: CorporationUpgrade,
|
||||||
|
amount: number | "MAX",
|
||||||
|
): number {
|
||||||
|
if (amount != "MAX") {
|
||||||
|
if (amount === 0) return 0;
|
||||||
|
if (calculateUpgradeCost(corporation, upgrade, amount) < corporation.funds) return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
let n = 1;
|
||||||
|
while (
|
||||||
|
calculateUpgradeCost(corporation, upgrade, n * 2) < corporation.funds &&
|
||||||
|
(amount != "MAX" ? n < amount : true)
|
||||||
|
) {
|
||||||
|
n *= 2;
|
||||||
|
}
|
||||||
|
for (let i = n / 2; i >= 1; i /= 2) {
|
||||||
|
if (calculateUpgradeCost(corporation, upgrade, n + i) < corporation.funds) n += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount === "MAX" ? n : Math.min(n, amount);
|
||||||
|
}
|
@ -3,7 +3,6 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
|||||||
import { IndustryDescriptions, IndustriesData } from "../IndustryData";
|
import { IndustryDescriptions, IndustriesData } from "../IndustryData";
|
||||||
import { IndustryType } from "../data/Enums";
|
import { IndustryType } from "../data/Enums";
|
||||||
import { useCorporation } from "./Context";
|
import { useCorporation } from "./Context";
|
||||||
import { Industry } from "../Industry";
|
|
||||||
import { NewIndustry } from "../Actions";
|
import { NewIndustry } from "../Actions";
|
||||||
|
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
@ -21,20 +20,13 @@ interface IProps {
|
|||||||
export function ExpandIndustryTab(props: IProps): React.ReactElement {
|
export function ExpandIndustryTab(props: IProps): React.ReactElement {
|
||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const allIndustries = Object.values(IndustryType).sort();
|
const allIndustries = Object.values(IndustryType).sort();
|
||||||
const possibleIndustries = allIndustries.filter(
|
const [industry, setIndustry] = useState(allIndustries[0]);
|
||||||
(industryType: IndustryType) =>
|
|
||||||
corp.divisions.find((division: Industry) => division.type === industryType) === undefined,
|
|
||||||
);
|
|
||||||
const [industry, setIndustry] = useState(possibleIndustries[0]);
|
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
|
|
||||||
//If there are no possible industries to expand into, nothing to render in this tab.
|
|
||||||
if (possibleIndustries.length === 0) return <></>;
|
|
||||||
|
|
||||||
const data = IndustriesData[industry];
|
const data = IndustriesData[industry];
|
||||||
if (!data) return <></>;
|
if (!data) return <></>;
|
||||||
|
|
||||||
const disabled = corp.funds < data.startingCost;
|
const disabled = corp.funds < data.startingCost && corp.divisions.length < corp.maxDivisions;
|
||||||
|
|
||||||
function newIndustry(): void {
|
function newIndustry(): void {
|
||||||
if (disabled) return;
|
if (disabled) return;
|
||||||
@ -67,9 +59,12 @@ export function ExpandIndustryTab(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Typography>
|
||||||
|
{corp.name} has {corp.divisions.length}/{corp.maxDivisions} divisions.
|
||||||
|
</Typography>
|
||||||
<Typography>Create a new division to expand into a new industry:</Typography>
|
<Typography>Create a new division to expand into a new industry:</Typography>
|
||||||
<Select value={industry} onChange={onIndustryChange}>
|
<Select value={industry} onChange={onIndustryChange}>
|
||||||
{possibleIndustries.map((industry) => (
|
{allIndustries.map((industry) => (
|
||||||
<MenuItem key={industry} value={industry}>
|
<MenuItem key={industry} value={industry}>
|
||||||
{industry}
|
{industry}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -4,7 +4,7 @@ import React, { useState } from "react";
|
|||||||
|
|
||||||
import { OfficeSpace } from "../OfficeSpace";
|
import { OfficeSpace } from "../OfficeSpace";
|
||||||
import { EmployeePositions } from "../data/Enums";
|
import { EmployeePositions } from "../data/Enums";
|
||||||
import { BuyCoffee } from "../Actions";
|
import { BuyTea } from "../Actions";
|
||||||
|
|
||||||
import { MoneyCost } from "./MoneyCost";
|
import { MoneyCost } from "./MoneyCost";
|
||||||
import { formatCorpStat } from "../../ui/formatNumber";
|
import { formatCorpStat } from "../../ui/formatNumber";
|
||||||
@ -118,14 +118,6 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
<Typography>{formatCorpStat(props.office.avgMor)}</Typography>
|
<Typography>{formatCorpStat(props.office.avgMor)}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
|
||||||
<TableCell>
|
|
||||||
<Typography>Avg Employee Happiness:</Typography>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
<Typography>{formatCorpStat(props.office.avgHap)}</Typography>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography>Avg Employee Energy:</Typography>
|
<Typography>Avg Employee Energy:</Typography>
|
||||||
@ -218,7 +210,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
office={props.office}
|
office={props.office}
|
||||||
job={EmployeePositions.Engineer}
|
job={EmployeePositions.Engineer}
|
||||||
desc={
|
desc={
|
||||||
"Develops and maintains products and production systems. Increases the quality of everything you produce. Also increases the amount you produce (not as much as Operations, however)"
|
"Develops and maintains products and production systems. Increases the quality of everything you produce. Also increases the amount you produce (not as much as Operations, however)."
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -242,15 +234,17 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
rerender={props.rerender}
|
rerender={props.rerender}
|
||||||
office={props.office}
|
office={props.office}
|
||||||
job={EmployeePositions.RandD}
|
job={EmployeePositions.RandD}
|
||||||
desc={"Research new innovative ways to improve the company. Generates Scientific Research."}
|
desc={
|
||||||
|
"Research new innovative ways to improve the company. Generates Scientific Research. Also increases the quality of everything you produce (not as much as Engineer, however)."
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AutoAssignJob
|
<AutoAssignJob
|
||||||
rerender={props.rerender}
|
rerender={props.rerender}
|
||||||
office={props.office}
|
office={props.office}
|
||||||
job={EmployeePositions.Training}
|
job={EmployeePositions.Intern}
|
||||||
desc={
|
desc={
|
||||||
"Set employee to training, which will increase some of their stats. Employees in training do not affect any company operations."
|
"Set employee to intern, which will increase some of their stats. Employees in intern do not affect any company operations, but gain increased exp and improve morale and energy."
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
@ -304,21 +298,20 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
<Typography>
|
<Typography>
|
||||||
Provide your employees with coffee, increasing their energy by half the difference to 100%, plus
|
Provide your employees with tea, increasing their energy by half the difference to 100%, plus 1.5%
|
||||||
1.5%
|
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<Button
|
<Button
|
||||||
disabled={corp.funds < props.office.getCoffeeCost() || props.office.coffeePending}
|
disabled={corp.funds < props.office.getTeaCost() || props.office.teaPending}
|
||||||
onClick={() => BuyCoffee(corp, props.office)}
|
onClick={() => BuyTea(corp, props.office)}
|
||||||
>
|
>
|
||||||
{props.office.coffeePending ? (
|
{props.office.teaPending ? (
|
||||||
"Buying coffee..."
|
"Buying tea..."
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>
|
||||||
Buy Coffee - <MoneyCost money={props.office.getCoffeeCost()} corp={corp} />
|
Buy Tea - <MoneyCost money={props.office.getTeaCost()} corp={corp} />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
@ -329,9 +322,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
{!division.hasResearch("AutoPartyManager") && (
|
{!division.hasResearch("AutoPartyManager") && (
|
||||||
<>
|
<>
|
||||||
<Tooltip
|
<Tooltip title={<Typography>Throw an office party to increase your employee's morale</Typography>}>
|
||||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<Button
|
<Button
|
||||||
disabled={corp.funds < 0 || props.office.partyMult > 1}
|
disabled={corp.funds < 0 || props.office.partyMult > 1}
|
||||||
|
@ -40,7 +40,7 @@ function MakeProductButton(): React.ReactElement {
|
|||||||
|
|
||||||
let createProductButtonText = "";
|
let createProductButtonText = "";
|
||||||
switch (division.type) {
|
switch (division.type) {
|
||||||
case IndustryType.Food:
|
case IndustryType.Restaurant:
|
||||||
createProductButtonText = "Build Restaurant";
|
createProductButtonText = "Build Restaurant";
|
||||||
break;
|
break;
|
||||||
case IndustryType.Tobacco:
|
case IndustryType.Tobacco:
|
||||||
|
@ -11,9 +11,11 @@ import Tooltip from "@mui/material/Tooltip";
|
|||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
|
import { calculateMaxAffordableUpgrade, calculateUpgradeCost } from "../helpers";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
upgrade: CorporationUpgrade;
|
upgrade: CorporationUpgrade;
|
||||||
|
amount: number | "MAX";
|
||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,16 +23,15 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
|||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const data = props.upgrade;
|
const data = props.upgrade;
|
||||||
const level = corp.upgrades[data.index];
|
const level = corp.upgrades[data.index];
|
||||||
|
const amount = props.amount;
|
||||||
|
|
||||||
const baseCost = data.basePrice;
|
const maxUpgrades = amount === "MAX" ? calculateMaxAffordableUpgrade(corp, data, amount) : amount;
|
||||||
const priceMult = data.priceMult;
|
const cost = calculateUpgradeCost(corp, data, maxUpgrades);
|
||||||
const cost = baseCost * Math.pow(priceMult, level);
|
|
||||||
|
|
||||||
const tooltip = data.desc;
|
const tooltip = data.desc;
|
||||||
function onClick(): void {
|
function onClick(): void {
|
||||||
if (corp.funds < cost) return;
|
if (corp.funds < cost) return;
|
||||||
try {
|
try {
|
||||||
LevelUpgrade(corp, props.upgrade);
|
LevelUpgrade(corp, props.upgrade, maxUpgrades);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(err + "");
|
||||||
}
|
}
|
||||||
@ -41,6 +42,7 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
|
|||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
||||||
<Button disabled={corp.funds < cost} sx={{ mx: 1 }} onClick={onClick}>
|
<Button disabled={corp.funds < cost} sx={{ mx: 1 }} onClick={onClick}>
|
||||||
|
+{maxUpgrades} -
|
||||||
<MoneyCost money={cost} corp={corp} />
|
<MoneyCost money={cost} corp={corp} />
|
||||||
</Button>
|
</Button>
|
||||||
<Tooltip title={tooltip}>
|
<Tooltip title={tooltip}>
|
||||||
|
50
src/Corporation/ui/MultiplierButtons.tsx
Normal file
50
src/Corporation/ui/MultiplierButtons.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* React Component for the Multiplier buttons on the Hacknet page.
|
||||||
|
* These buttons let the player control how many Nodes/Upgrades they're
|
||||||
|
* purchasing when using the UI (x1, x5, x10, MAX)
|
||||||
|
*/
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { PurchaseMultipliers } from "../data/Constants";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
|
||||||
|
interface IMultiplierProps {
|
||||||
|
disabled: boolean;
|
||||||
|
onClick: () => void;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MultiplierButton(props: IMultiplierProps): React.ReactElement {
|
||||||
|
return (
|
||||||
|
<Button disabled={props.disabled} onClick={props.onClick}>
|
||||||
|
{props.text}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
purchaseMultiplier: number | string;
|
||||||
|
onClicks: (() => void)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MultiplierButtons(props: IProps): React.ReactElement {
|
||||||
|
if (props.purchaseMultiplier == null) {
|
||||||
|
throw new Error(`MultiplierButtons constructed without required props`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mults = ["x1", "x5", "x10", "x50", "x100", "MAX"];
|
||||||
|
const onClicks = props.onClicks;
|
||||||
|
const buttons = [];
|
||||||
|
for (let i = 0; i < mults.length; ++i) {
|
||||||
|
const mult = mults[i];
|
||||||
|
const btnProps = {
|
||||||
|
disabled: props.purchaseMultiplier === PurchaseMultipliers[mult],
|
||||||
|
onClick: onClicks[i],
|
||||||
|
text: mult,
|
||||||
|
};
|
||||||
|
|
||||||
|
buttons.push(<MultiplierButton key={mult} {...btnProps} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{buttons}</>;
|
||||||
|
}
|
@ -29,10 +29,14 @@ import Button from "@mui/material/Button";
|
|||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Paper from "@mui/material/Paper";
|
import Paper from "@mui/material/Paper";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
|
import { MultiplierButtons } from "./MultiplierButtons";
|
||||||
|
import { SellCorporationModal } from "./modals/SellCorporationModal";
|
||||||
|
import { SellDivisionModal } from "./modals/SellDivisionModal";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Overview({ rerender }: IProps): React.ReactElement {
|
export function Overview({ rerender }: IProps): React.ReactElement {
|
||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const profit: number = corp.revenue - corp.expenses;
|
const profit: number = corp.revenue - corp.expenses;
|
||||||
@ -100,6 +104,8 @@ export function Overview({ rerender }: IProps): React.ReactElement {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
|
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
|
||||||
<BribeButton />
|
<BribeButton />
|
||||||
|
{corp.divisions.length != 0 ? <SellDivisionButton /> : <></>}
|
||||||
|
<RestartButton />
|
||||||
</Box>
|
</Box>
|
||||||
<br />
|
<br />
|
||||||
<Upgrades rerender={rerender} />
|
<Upgrades rerender={rerender} />
|
||||||
@ -155,25 +161,40 @@ function Upgrades({ rerender }: IUpgradeProps): React.ReactElement {
|
|||||||
return <Typography variant="h4">Upgrades are unlocked once you create an industry.</Typography>;
|
return <Typography variant="h4">Upgrades are unlocked once you create an industry.</Typography>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [purchaseMultiplier, setPurchaseMultiplier] = useState<number | "MAX">(corpConstants.PurchaseMultipliers.x1);
|
||||||
|
|
||||||
|
// onClick event handlers for purchase multiplier buttons
|
||||||
|
const purchaseMultiplierOnClicks = [
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.x1),
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.x5),
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.x10),
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.x50),
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.x100),
|
||||||
|
() => setPurchaseMultiplier(corpConstants.PurchaseMultipliers.MAX),
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Paper sx={{ p: 1, my: 1 }}>
|
<Paper sx={{ p: 1, my: 1 }}>
|
||||||
<Typography variant="h4">Unlocks</Typography>
|
<Typography variant="h4">Unlocks</Typography>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
{Object.values(CorporationUnlockUpgrades)
|
{Object.values(CorporationUnlockUpgrades).map((upgrade: CorporationUnlockUpgrade) => (
|
||||||
.filter((upgrade: CorporationUnlockUpgrade) => !corp.unlockUpgrades[upgrade.index])
|
<UnlockUpgrade rerender={rerender} upgradeData={upgrade} key={upgrade.index} />
|
||||||
.map((upgrade: CorporationUnlockUpgrade) => (
|
))}
|
||||||
<UnlockUpgrade rerender={rerender} upgradeData={upgrade} key={upgrade.index} />
|
|
||||||
))}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
<Paper sx={{ p: 1, my: 1 }}>
|
<Paper sx={{ p: 1, my: 1 }}>
|
||||||
<Typography variant="h4">Upgrades</Typography>
|
<Typography variant="h4">Upgrades</Typography>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<MultiplierButtons onClicks={purchaseMultiplierOnClicks} purchaseMultiplier={purchaseMultiplier} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
{corp.upgrades
|
{corp.upgrades
|
||||||
.map((level: number, i: number) => CorporationUpgrades[i as CorporationUpgradeIndex])
|
.map((level: number, i: number) => CorporationUpgrades[i as CorporationUpgradeIndex])
|
||||||
.map((upgrade: CorporationUpgrade) => (
|
.map((upgrade: CorporationUpgrade) => (
|
||||||
<LevelableUpgrade rerender={rerender} upgrade={upgrade} key={upgrade.index} />
|
<LevelableUpgrade rerender={rerender} upgrade={upgrade} key={upgrade.index} amount={purchaseMultiplier} />
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
@ -265,6 +286,39 @@ function BribeButton(): React.ReactElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SellDivisionButton(): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
function sellDiv(): void {
|
||||||
|
setOpen(true);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tooltip title={"Sell a division to make room for other divisions"}>
|
||||||
|
<Button onClick={sellDiv}>Sell division</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<SellDivisionModal open={open} onClose={() => setOpen(false)} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RestartButton(): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
function restart(): void {
|
||||||
|
setOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tooltip title={"Sell corporation and start over"}>
|
||||||
|
<Button onClick={restart}>Sell CEO position</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<SellCorporationModal open={open} onClose={() => setOpen(false)} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface IDividendsStatsProps {
|
interface IDividendsStatsProps {
|
||||||
profit: number;
|
profit: number;
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ export function ProductElem(props: IProductProps): React.ReactElement {
|
|||||||
{sellButtonText} @ <Money money={product.pCost + markupLimit} />
|
{sellButtonText} @ <Money money={product.pCost + markupLimit} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else if (product.sCost) {
|
} else if (product.sCost[city]) {
|
||||||
if (isString(product.sCost)) {
|
if (isString(product.sCost[city])) {
|
||||||
const sCost = (product.sCost as string).replace(/MP/g, product.pCost + product.rat / product.mku + "");
|
const sCost = (product.sCost[city] as string).replace(/MP/g, product.pCost + product.rat / product.mku + "");
|
||||||
sellButtonText = (
|
sellButtonText = (
|
||||||
<>
|
<>
|
||||||
{sellButtonText} @ <Money money={eval(sCost)} />
|
{sellButtonText} @ <Money money={eval(sCost)} />
|
||||||
@ -87,7 +87,7 @@ export function ProductElem(props: IProductProps): React.ReactElement {
|
|||||||
} else {
|
} else {
|
||||||
sellButtonText = (
|
sellButtonText = (
|
||||||
<>
|
<>
|
||||||
{sellButtonText} @ <Money money={product.sCost} />
|
{sellButtonText} @ <Money money={product.sCost[city]} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -138,6 +138,8 @@ export function ProductElem(props: IProductProps): React.ReactElement {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
<Typography>
|
<Typography>
|
||||||
|
Effective rating is calculated from product rating and the quality of materials used <br />
|
||||||
|
Rating: {formatCorpStat(product.rat)} <br /> <br />
|
||||||
Quality: {formatCorpStat(product.qlt)} <br />
|
Quality: {formatCorpStat(product.qlt)} <br />
|
||||||
Performance: {formatCorpStat(product.per)} <br />
|
Performance: {formatCorpStat(product.per)} <br />
|
||||||
Durability: {formatCorpStat(product.dur)} <br />
|
Durability: {formatCorpStat(product.dur)} <br />
|
||||||
@ -151,7 +153,7 @@ export function ProductElem(props: IProductProps): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Typography>Rating: {formatCorpStat(product.rat)}</Typography>
|
<Typography>Effective rating: {formatCorpStat(product.data[city][3])}</Typography>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
<Box display="flex">
|
<Box display="flex">
|
||||||
|
@ -21,7 +21,10 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
|
|||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const data = props.upgradeData;
|
const data = props.upgradeData;
|
||||||
const tooltip = data.desc;
|
const tooltip = data.desc;
|
||||||
|
const price = corp.unlockUpgrades[data.index] === 0 ? data.price : 0;
|
||||||
|
|
||||||
function onClick(): void {
|
function onClick(): void {
|
||||||
|
if (corp.unlockUpgrades[data.index] === 1) return;
|
||||||
if (corp.funds < data.price) return;
|
if (corp.funds < data.price) return;
|
||||||
try {
|
try {
|
||||||
UU(corp, props.upgradeData);
|
UU(corp, props.upgradeData);
|
||||||
@ -34,8 +37,12 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
<Box display="flex" alignItems="center" flexDirection="row-reverse">
|
||||||
<Button disabled={corp.funds < data.price} sx={{ mx: 1 }} onClick={onClick}>
|
<Button
|
||||||
<MoneyCost money={data.price} corp={corp} />
|
disabled={corp.funds < data.price || corp.unlockUpgrades[data.index] === 1}
|
||||||
|
sx={{ mx: 1 }}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<MoneyCost money={price} corp={corp} />
|
||||||
</Button>
|
</Button>
|
||||||
<Tooltip title={tooltip}>
|
<Tooltip title={tooltip}>
|
||||||
<Typography>{data.name}</Typography>
|
<Typography>{data.name}</Typography>
|
||||||
|
@ -30,7 +30,7 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
|
|||||||
if (!canSelfFund) return;
|
if (!canSelfFund) return;
|
||||||
if (name == "") return;
|
if (name == "") return;
|
||||||
|
|
||||||
Player.startCorporation(name);
|
Player.startCorporation(name, false);
|
||||||
Player.loseMoney(150e9, "corporation");
|
Player.loseMoney(150e9, "corporation");
|
||||||
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
@ -42,7 +42,7 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.startCorporation(name, 500e6);
|
Player.startCorporation(name, true);
|
||||||
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
Router.toPage(Page.Corporation);
|
Router.toPage(Page.Corporation);
|
||||||
|
@ -82,7 +82,25 @@ export function ExportModal(props: IProps): React.ReactElement {
|
|||||||
<Modal open={props.open} onClose={props.onClose}>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<Typography>
|
<Typography>
|
||||||
Select the industry and city to export this material to, as well as how much of this material to export per
|
Select the industry and city to export this material to, as well as how much of this material to export per
|
||||||
second. You can set the export amount to 'MAX' to export all of the materials in this warehouse.
|
second.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
You can use 'MAX', 'EINV', 'IINV', 'EPROD' or 'IPROD' in the amount for:
|
||||||
|
<br />
|
||||||
|
- 'MAX' to export maximum amount possible.
|
||||||
|
<br />
|
||||||
|
- 'EINV' export city's inventory of the material.
|
||||||
|
<br />
|
||||||
|
- 'IINV' import city's inventory of the material.
|
||||||
|
<br />
|
||||||
|
- 'EPROD' export city's per second production of the material
|
||||||
|
<br />
|
||||||
|
- 'IPROD' import city's per second production of the material
|
||||||
|
<br />
|
||||||
|
Note: Consumption is negative production.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
For example: setting the amount "(EINV-20)/10" would try to export all except 20 of the material.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Select onChange={onIndustryChange} value={industry}>
|
<Select onChange={onIndustryChange} value={industry}>
|
||||||
{corp.divisions
|
{corp.divisions
|
||||||
|
@ -55,11 +55,11 @@ export function GoPublicModal(props: IProps): React.ReactElement {
|
|||||||
be deposited directly into your Corporation's funds).
|
be deposited directly into your Corporation's funds).
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
You have a total of {formatShares(corp.numShares)} shares that you can issue.
|
You have a total of {formatShares(corp.numShares)}-1 shares that you can issue. You cannot sell all your shares.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<NumberInput onChange={setShares} autoFocus placeholder="Shares to issue" onKeyDown={onKeyDown} />
|
<NumberInput onChange={setShares} autoFocus placeholder="Shares to issue" onKeyDown={onKeyDown} />
|
||||||
<Button disabled={shares < 0 || shares > corp.numShares} sx={{ mx: 1 }} onClick={goPublic}>
|
<Button disabled={shares < 0 || shares >= corp.numShares} sx={{ mx: 1 }} onClick={goPublic}>
|
||||||
Go Public
|
Go Public
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -20,7 +20,7 @@ interface IProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function productPlaceholder(type: string): string {
|
function productPlaceholder(type: string): string {
|
||||||
if (type === IndustryType.Food) {
|
if (type === IndustryType.Restaurant) {
|
||||||
return "Restaurant Name";
|
return "Restaurant Name";
|
||||||
} else if (type === IndustryType.Healthcare) {
|
} else if (type === IndustryType.Healthcare) {
|
||||||
return "Hospital Name";
|
return "Hospital Name";
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { formatMoney, formatPreciseMultiplier } from "../../../ui/formatNumber";
|
import { formatMoney } from "../../../ui/formatNumber";
|
||||||
import { Material } from "../../Material";
|
import { Material } from "../../Material";
|
||||||
import { Modal } from "../../../ui/React/Modal";
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
import { useDivision } from "../Context";
|
import { useDivision } from "../Context";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import TextField from "@mui/material/TextField";
|
|
||||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||||
import Switch from "@mui/material/Switch";
|
import Switch from "@mui/material/Switch";
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
|
||||||
import { useRerender } from "../../../ui/React/hooks";
|
import { useRerender } from "../../../ui/React/hooks";
|
||||||
|
|
||||||
interface IMarketTA2Props {
|
interface IMarketTA2Props {
|
||||||
@ -17,30 +15,7 @@ interface IMarketTA2Props {
|
|||||||
function MarketTA2(props: IMarketTA2Props): React.ReactElement {
|
function MarketTA2(props: IMarketTA2Props): React.ReactElement {
|
||||||
const division = useDivision();
|
const division = useDivision();
|
||||||
if (!division.hasResearch("Market-TA.II")) return <></>;
|
if (!division.hasResearch("Market-TA.II")) return <></>;
|
||||||
const [newCost, setNewCost] = useState<number>(props.mat.bCost);
|
|
||||||
const rerender = useRerender();
|
const rerender = useRerender();
|
||||||
const markupLimit = props.mat.getMarkupLimit();
|
|
||||||
|
|
||||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
|
||||||
if (event.target.value === "") setNewCost(0);
|
|
||||||
else setNewCost(parseFloat(event.target.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
const sCost = newCost;
|
|
||||||
let markup = 1;
|
|
||||||
if (sCost > props.mat.bCost) {
|
|
||||||
//Penalty if difference between sCost and bCost is greater than markup limit
|
|
||||||
if (sCost - props.mat.bCost > markupLimit) {
|
|
||||||
markup = Math.pow(markupLimit / (sCost - props.mat.bCost), 2);
|
|
||||||
}
|
|
||||||
} else if (sCost < props.mat.bCost) {
|
|
||||||
if (sCost <= 0) {
|
|
||||||
markup = 1e12; //Sell everything, essentially discard
|
|
||||||
} else {
|
|
||||||
//Lower prices than market increases sales
|
|
||||||
markup = props.mat.bCost / sCost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMarketTA2(event: React.ChangeEvent<HTMLInputElement>): void {
|
function onMarketTA2(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
props.mat.marketTa2 = event.target.checked;
|
props.mat.marketTa2 = event.target.checked;
|
||||||
@ -50,28 +25,15 @@ function MarketTA2(props: IMarketTA2Props): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography variant="h4">Market-TA.II</Typography>
|
<Typography variant="h4">Market-TA.II</Typography>
|
||||||
<br />
|
|
||||||
<Typography>
|
<Typography>
|
||||||
If you sell at {formatMoney(sCost)}, then you will sell x{formatPreciseMultiplier(markup)} as much compared to
|
If this is enabled, then this Material will automatically be sold at the optimal price such that the amount sold
|
||||||
if you sold at market price.
|
matches the amount produced. (i.e. the highest possible price, while still ensuring that all produced materials
|
||||||
|
will be sold)
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField type="number" onChange={onChange} value={newCost} />
|
|
||||||
<br />
|
<br />
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={props.mat.marketTa2} onChange={onMarketTA2} />}
|
control={<Switch checked={props.mat.marketTa2} onChange={onMarketTA2} />}
|
||||||
label={
|
label={<Typography>Use Market-TA.II for Auto-Sale Price</Typography>}
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
<Typography>
|
|
||||||
If this is enabled, then this Material will automatically be sold at the optimal price such that the
|
|
||||||
amount sold matches the amount produced. (i.e. the highest possible price, while still ensuring that all
|
|
||||||
produced materials will be sold)
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Typography>Use Market-TA.II for Auto-Sale Price</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -103,22 +65,15 @@ export function MaterialMarketTaModal(props: IProps): React.ReactElement {
|
|||||||
<Typography>
|
<Typography>
|
||||||
The maximum sale price you can mark this up to is {formatMoney(props.mat.bCost + markupLimit)}. This means
|
The maximum sale price you can mark this up to is {formatMoney(props.mat.bCost + markupLimit)}. This means
|
||||||
that if you set the sale price higher than this, you will begin to experience a loss in number of sales
|
that if you set the sale price higher than this, you will begin to experience a loss in number of sales
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
If this is enabled, then this Material will automatically be sold at the price identified by Market-TA.I (i.e.
|
||||||
|
the price shown above)
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={props.mat.marketTa1} onChange={onMarketTA1} />}
|
control={<Switch checked={props.mat.marketTa1} onChange={onMarketTA1} />}
|
||||||
label={
|
label={<Typography>Use Market-TA.I for Auto-Sale Price</Typography>}
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
<Typography>
|
|
||||||
If this is enabled, then this Material will automatically be sold at the price identified by
|
|
||||||
Market-TA.I (i.e. the price shown above)
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Typography>Use Market-TA.I for Auto-Sale Price</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { formatMoney, formatPreciseMultiplier } from "../../../ui/formatNumber";
|
import { formatMoney } from "../../../ui/formatNumber";
|
||||||
import { Product } from "../../Product";
|
import { Product } from "../../Product";
|
||||||
import { Modal } from "../../../ui/React/Modal";
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
import { useDivision } from "../Context";
|
import { useDivision } from "../Context";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import TextField from "@mui/material/TextField";
|
|
||||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||||
import Switch from "@mui/material/Switch";
|
import Switch from "@mui/material/Switch";
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
|
||||||
import { useRerender } from "../../../ui/React/hooks";
|
import { useRerender } from "../../../ui/React/hooks";
|
||||||
|
|
||||||
interface ITa2Props {
|
interface ITa2Props {
|
||||||
@ -17,52 +15,26 @@ interface ITa2Props {
|
|||||||
function MarketTA2(props: ITa2Props): React.ReactElement {
|
function MarketTA2(props: ITa2Props): React.ReactElement {
|
||||||
const division = useDivision();
|
const division = useDivision();
|
||||||
if (!division.hasResearch("Market-TA.II")) return <></>;
|
if (!division.hasResearch("Market-TA.II")) return <></>;
|
||||||
const markupLimit = props.product.rat / props.product.mku;
|
|
||||||
const [value, setValue] = useState(props.product.pCost);
|
|
||||||
const rerender = useRerender();
|
const rerender = useRerender();
|
||||||
|
|
||||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
|
||||||
setValue(parseFloat(event.target.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
props.product.marketTa2 = event.target.checked;
|
props.product.marketTa2 = event.target.checked;
|
||||||
rerender();
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
const sCost = value;
|
|
||||||
let markup = 1;
|
|
||||||
if (sCost > props.product.pCost) {
|
|
||||||
if (sCost - props.product.pCost > markupLimit) {
|
|
||||||
markup = markupLimit / (sCost - props.product.pCost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography variant="h4">Market-TA.II</Typography>
|
<Typography variant="h4">Market-TA.II</Typography>
|
||||||
<br />
|
<br />
|
||||||
<Typography>
|
<Typography>
|
||||||
If you sell at {formatMoney(sCost)}, then you will sell x{formatPreciseMultiplier(markup)} as much compared to
|
If this is enabled, then this product will automatically be sold at the optimal price such that the amount sold
|
||||||
if you sold at market price.
|
matches the amount produced. (i.e. the highest possible price, while still ensuring that all produced materials
|
||||||
|
will be sold)
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField type="number" onChange={onChange} value={value} />
|
|
||||||
<br />
|
<br />
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={props.product.marketTa2} onChange={onCheckedChange} />}
|
control={<Switch checked={props.product.marketTa2} onChange={onCheckedChange} />}
|
||||||
label={
|
label={<Typography>Use Market-TA.II for Auto-Sale Price</Typography>}
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
<Typography>
|
|
||||||
If this is enabled, then this Material will automatically be sold at the optimal price such that the
|
|
||||||
amount sold matches the amount produced. (i.e. the highest possible price, while still ensuring that all
|
|
||||||
produced materials will be sold)
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Typography>Use Market-TA.II for Auto-Sale Price</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -94,22 +66,15 @@ export function ProductMarketTaModal(props: IProps): React.ReactElement {
|
|||||||
<Typography>
|
<Typography>
|
||||||
The maximum sale price you can mark this up to is {formatMoney(props.product.pCost + markupLimit)}. This means
|
The maximum sale price you can mark this up to is {formatMoney(props.product.pCost + markupLimit)}. This means
|
||||||
that if you set the sale price higher than this, you will begin to experience a loss in number of sales
|
that if you set the sale price higher than this, you will begin to experience a loss in number of sales
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
If this is enabled, then this product will automatically be sold at the price identified by Market-TA.I (i.e.
|
||||||
|
the price shown above)
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={props.product.marketTa1} onChange={onChange} />}
|
control={<Switch checked={props.product.marketTa1} onChange={onChange} />}
|
||||||
label={
|
label={<Typography>Use Market-TA.I for Auto-Sale Price</Typography>}
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
<Typography>
|
|
||||||
If this is enabled, then this Material will automatically be sold at the price identified by
|
|
||||||
Market-TA.I (i.e. the price shown above)
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Typography>Use Market-TA.I for Auto-Sale Price</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { Material } from "../../Material";
|
|||||||
import { formatMatPurchaseAmount, formatMoney } from "../../../ui/formatNumber";
|
import { formatMatPurchaseAmount, formatMoney } from "../../../ui/formatNumber";
|
||||||
import { BulkPurchase, BuyMaterial } from "../../Actions";
|
import { BulkPurchase, BuyMaterial } from "../../Actions";
|
||||||
import { Modal } from "../../../ui/React/Modal";
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
import { useCorporation, useDivision } from "../Context";
|
import { useCorporation } from "../Context";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
@ -110,7 +110,6 @@ interface IProps {
|
|||||||
|
|
||||||
// Create a popup that lets the player purchase a Material
|
// Create a popup that lets the player purchase a Material
|
||||||
export function PurchaseMaterialModal(props: IProps): React.ReactElement {
|
export function PurchaseMaterialModal(props: IProps): React.ReactElement {
|
||||||
const division = useDivision();
|
|
||||||
const [buyAmt, setBuyAmt] = useState(props.mat.buy ? props.mat.buy : 0);
|
const [buyAmt, setBuyAmt] = useState(props.mat.buy ? props.mat.buy : 0);
|
||||||
|
|
||||||
function purchaseMaterial(): void {
|
function purchaseMaterial(): void {
|
||||||
@ -160,9 +159,7 @@ export function PurchaseMaterialModal(props: IProps): React.ReactElement {
|
|||||||
<Button disabled={props.disablePurchaseLimit} onClick={clearPurchase}>
|
<Button disabled={props.disablePurchaseLimit} onClick={clearPurchase}>
|
||||||
Clear Purchase
|
Clear Purchase
|
||||||
</Button>
|
</Button>
|
||||||
{division.hasResearch("Bulk Purchasing") && (
|
{<BulkPurchaseSection onClose={props.onClose} mat={props.mat} warehouse={props.warehouse} />}
|
||||||
<BulkPurchaseSection onClose={props.onClose} mat={props.mat} warehouse={props.warehouse} />
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
71
src/Corporation/ui/modals/SellCorporationModal.tsx
Normal file
71
src/Corporation/ui/modals/SellCorporationModal.tsx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
import { Money } from "../../../ui/React/Money";
|
||||||
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
|
import { Router } from "../../../ui/GameRoot";
|
||||||
|
import { Page } from "../../../ui/Router";
|
||||||
|
import { Player } from "@player";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import TextField from "@mui/material/TextField";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SellCorporationModal(props: IProps): React.ReactElement {
|
||||||
|
let cost = 150e9;
|
||||||
|
if (!Player.corporation?.seedFunded) {
|
||||||
|
cost /= 3;
|
||||||
|
}
|
||||||
|
const canSelfFund = Player.canAfford(cost);
|
||||||
|
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setName(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selfFund(): void {
|
||||||
|
if (!canSelfFund) return;
|
||||||
|
if (name == "") return;
|
||||||
|
|
||||||
|
Player.startCorporation(name, false);
|
||||||
|
Player.loseMoney(cost, "corporation");
|
||||||
|
|
||||||
|
props.onClose();
|
||||||
|
Router.toPage(Page.Corporation);
|
||||||
|
}
|
||||||
|
|
||||||
|
function seed(): void {
|
||||||
|
if (name == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player.startCorporation(name, true);
|
||||||
|
|
||||||
|
props.onClose();
|
||||||
|
Router.toPage(Page.Corporation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
|
<Typography>
|
||||||
|
Would you like to sell your position as CEO and start a new corporation? Everything from your current
|
||||||
|
corporation will be gone and you start fresh.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
If you would like to start new one, please enter a name for your corporation below:
|
||||||
|
</Typography>
|
||||||
|
<TextField autoFocus={true} placeholder="Corporation Name" onChange={onChange} value={name} />
|
||||||
|
{Player.bitNodeN === 3 && (
|
||||||
|
<Button onClick={seed} disabled={name == ""}>
|
||||||
|
Use seed money
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button onClick={selfFund} disabled={name == "" || !canSelfFund}>
|
||||||
|
Self-Fund (<Money money={cost} forPurchase={true} />)
|
||||||
|
</Button>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
100
src/Corporation/ui/modals/SellDivisionModal.tsx
Normal file
100
src/Corporation/ui/modals/SellDivisionModal.tsx
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
|
import { useCorporation } from "../../ui/Context";
|
||||||
|
import { Industry } from "src/Corporation/Industry";
|
||||||
|
import { CityName } from "@nsdefs";
|
||||||
|
import * as corpConstants from "../../data/Constants";
|
||||||
|
import { formatMoney, formatNumber } from "../../../ui/formatNumber";
|
||||||
|
import { removeIndustry } from "../../Actions";
|
||||||
|
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SellDivisionModal(props: IProps): React.ReactElement {
|
||||||
|
const corp = useCorporation();
|
||||||
|
const allIndustries = Object.values(corp.divisions).sort();
|
||||||
|
const [industry, setIndustry] = useState(allIndustries[0]);
|
||||||
|
const price = calculatePrice();
|
||||||
|
|
||||||
|
function calculatePrice() {
|
||||||
|
let price = industry.startingCost;
|
||||||
|
for (const city in industry.offices) {
|
||||||
|
if (industry.offices[city as CityName] === 0) continue;
|
||||||
|
if (city === "Sector-12") continue;
|
||||||
|
price += corpConstants.officeInitialCost;
|
||||||
|
if (industry.warehouses[city as CityName] !== 0) price += corpConstants.warehouseInitialCost;
|
||||||
|
}
|
||||||
|
price /= 2;
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onIndustryChange(event: SelectChangeEvent<string>): void {
|
||||||
|
setIndustry(corp.divisions.find((div) => div.name === event.target.value) as Industry);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sum(total: number, num: number) {
|
||||||
|
return total + num;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sellDivision() {
|
||||||
|
removeIndustry(corp, industry.name);
|
||||||
|
corp.funds += price;
|
||||||
|
props.onClose();
|
||||||
|
dialogBoxCreate(
|
||||||
|
<>
|
||||||
|
Sold {industry.name} for {formatMoney(price)}, you now have space for{" "}
|
||||||
|
{corp.maxDivisions - corp.divisions.length} more divisions.
|
||||||
|
</>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
|
<Typography>
|
||||||
|
Would you like to sell a division?
|
||||||
|
<br></br>
|
||||||
|
You'll get back half the money you've spent on starting the division and expanding to offices and warehouses.
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Select value={industry.name} onChange={onIndustryChange}>
|
||||||
|
{allIndustries.map((industry) => (
|
||||||
|
<MenuItem key={industry.name} value={industry.name}>
|
||||||
|
{industry.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<Typography>
|
||||||
|
Division {industry.name} has:
|
||||||
|
<br></br>- Profit: ${formatNumber((industry.lastCycleRevenue - industry.lastCycleExpenses) / 10)} / sec
|
||||||
|
<br></br>- Cities:{" "}
|
||||||
|
{Object.keys(industry.offices)
|
||||||
|
.map((city) => (!!industry.offices[city as CityName] ? 1 : 0))
|
||||||
|
.reduce(sum, 0)}
|
||||||
|
<br></br>- Warehouses:{" "}
|
||||||
|
{Object.keys(industry.warehouses)
|
||||||
|
.map((city) => (!!industry.warehouses[city as CityName] ? 1 : 0))
|
||||||
|
.reduce(sum, 0)}
|
||||||
|
{industry.makesProducts ?? (
|
||||||
|
<Typography>
|
||||||
|
{" "}
|
||||||
|
<br></br>- Products: {industry.products.length}{" "}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
Sell price: {formatNumber(price)}
|
||||||
|
</Typography>
|
||||||
|
<Button disabled={false} onClick={sellDivision}>
|
||||||
|
Sell division
|
||||||
|
</Button>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@ -11,8 +11,8 @@ import FormControlLabel from "@mui/material/FormControlLabel";
|
|||||||
import Switch from "@mui/material/Switch";
|
import Switch from "@mui/material/Switch";
|
||||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||||
|
|
||||||
function initialPrice(product: Product): string {
|
function initialPrice(product: Product, city: string): string {
|
||||||
let val = product.sCost ? product.sCost + "" : "";
|
let val = product.sCost[city] ? product.sCost[city] + "" : "";
|
||||||
if (product.marketTa2) {
|
if (product.marketTa2) {
|
||||||
val += " (Market-TA.II)";
|
val += " (Market-TA.II)";
|
||||||
} else if (product.marketTa1) {
|
} else if (product.marketTa1) {
|
||||||
@ -34,7 +34,7 @@ export function SellProductModal(props: IProps): React.ReactElement {
|
|||||||
const [iQty, setQty] = useState<string>(
|
const [iQty, setQty] = useState<string>(
|
||||||
props.product.sllman[props.city][1] ? props.product.sllman[props.city][1] : "",
|
props.product.sllman[props.city][1] ? props.product.sllman[props.city][1] : "",
|
||||||
);
|
);
|
||||||
const [px, setPx] = useState<string>(initialPrice(props.product));
|
const [px, setPx] = useState<string>(initialPrice(props.product, props.city));
|
||||||
|
|
||||||
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
setChecked(event.target.checked);
|
setChecked(event.target.checked);
|
||||||
|
@ -10,6 +10,7 @@ import { Money } from "../../../ui/React/Money";
|
|||||||
import { SellShares } from "../../Actions";
|
import { SellShares } from "../../Actions";
|
||||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||||
import { NumberInput } from "../../../ui/React/NumberInput";
|
import { NumberInput } from "../../../ui/React/NumberInput";
|
||||||
|
import { isInteger } from "lodash";
|
||||||
interface IProps {
|
interface IProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@ -22,15 +23,19 @@ export function SellSharesModal(props: IProps): React.ReactElement {
|
|||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const [shares, setShares] = useState<number>(NaN);
|
const [shares, setShares] = useState<number>(NaN);
|
||||||
|
|
||||||
const disabled = isNaN(shares) || shares <= 0 || shares > corp.numShares;
|
const disabled = isNaN(shares) || shares <= 0 || shares >= corp.numShares;
|
||||||
|
|
||||||
function ProfitIndicator(props: { shares: number | null; corp: Corporation }): React.ReactElement {
|
function ProfitIndicator(props: { shares: number | null; corp: Corporation }): React.ReactElement {
|
||||||
if (props.shares === null) return <></>;
|
if (props.shares === null) return <></>;
|
||||||
let text = "";
|
let text = "";
|
||||||
if (isNaN(props.shares) || props.shares <= 0) {
|
if (isNaN(props.shares) || props.shares <= 0 || !isInteger(props.shares)) {
|
||||||
text = `ERROR: Invalid value entered for number of shares to sell`;
|
text = `ERROR: Invalid value entered for number of shares to sell`;
|
||||||
} else if (props.shares > corp.numShares) {
|
} else if (props.shares > corp.numShares) {
|
||||||
text = `You don't have this many shares to sell!`;
|
text = `You don't have this many shares to sell!`;
|
||||||
|
} else if (props.shares === corp.numShares) {
|
||||||
|
text = `You can not sell all your shares!`;
|
||||||
|
} else if (props.shares > 1e14) {
|
||||||
|
text = `You can't sell more than 100t shares at once!`;
|
||||||
} else {
|
} else {
|
||||||
const stockSaleResults = corp.calculateShareSale(props.shares);
|
const stockSaleResults = corp.calculateShareSale(props.shares);
|
||||||
const profit = stockSaleResults[0];
|
const profit = stockSaleResults[0];
|
||||||
@ -74,6 +79,9 @@ export function SellSharesModal(props: IProps): React.ReactElement {
|
|||||||
(NOT your Corporation).
|
(NOT your Corporation).
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
The amount sold must be an integer between 1 and 100t.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
Selling your shares will cause your corporation's stock price to fall due to dilution. Furthermore, selling a
|
Selling your shares will cause your corporation's stock price to fall due to dilution. Furthermore, selling a
|
||||||
large number of shares all at once will have an immediate effect in reducing your stock price.
|
large number of shares all at once will have an immediate effect in reducing your stock price.
|
||||||
<br />
|
<br />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { Warehouse } from "../../Warehouse";
|
import { Warehouse } from "../../Warehouse";
|
||||||
import { SetSmartSupply, SetSmartSupplyUseLeftovers } from "../../Actions";
|
import { SetSmartSupply, SetSmartSupplyOption } from "../../Actions";
|
||||||
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||||
import { Modal } from "../../../ui/React/Modal";
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
import { useDivision } from "../Context";
|
import { useDivision } from "../Context";
|
||||||
@ -12,30 +12,50 @@ import { CorpMaterialName } from "@nsdefs";
|
|||||||
import { materialNames } from "../../data/Constants";
|
import { materialNames } from "../../data/Constants";
|
||||||
import { useRerender } from "../../../ui/React/hooks";
|
import { useRerender } from "../../../ui/React/hooks";
|
||||||
|
|
||||||
interface ILeftoverProps {
|
interface ISSoptionProps {
|
||||||
matName: CorpMaterialName;
|
matName: CorpMaterialName;
|
||||||
warehouse: Warehouse;
|
warehouse: Warehouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Leftover(props: ILeftoverProps): React.ReactElement {
|
function SSoption(props: ISSoptionProps): React.ReactElement {
|
||||||
const [checked, setChecked] = useState(!!props.warehouse.smartSupplyUseLeftovers[props.matName]);
|
const [value, setChecked] = useState(props.warehouse.smartSupplyOptions[props.matName]);
|
||||||
|
|
||||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
//leftover switch
|
||||||
|
function onLOChange(): void {
|
||||||
|
const newValue = value != "leftovers" ? "leftovers" : "none";
|
||||||
try {
|
try {
|
||||||
const matName = props.matName;
|
const matName = props.matName;
|
||||||
const material = props.warehouse.materials[matName];
|
const material = props.warehouse.materials[matName];
|
||||||
SetSmartSupplyUseLeftovers(props.warehouse, material, event.target.checked);
|
SetSmartSupplyOption(props.warehouse, material, newValue);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dialogBoxCreate(err + "");
|
dialogBoxCreate(err + "");
|
||||||
}
|
}
|
||||||
setChecked(event.target.checked);
|
setChecked(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
//imports switch
|
||||||
|
function onIChange(): void {
|
||||||
|
const newValue = value != "imports" ? "imports" : "none";
|
||||||
|
try {
|
||||||
|
const matName = props.matName;
|
||||||
|
const material = props.warehouse.materials[matName];
|
||||||
|
SetSmartSupplyOption(props.warehouse, material, newValue);
|
||||||
|
} catch (err) {
|
||||||
|
dialogBoxCreate(err + "");
|
||||||
|
}
|
||||||
|
setChecked(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
label={<Typography>{props.warehouse.materials[props.matName].name}</Typography>}
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={checked} onChange={onChange} />}
|
control={<Switch checked={value == "leftovers"} onChange={onLOChange} />}
|
||||||
label={<Typography>{props.warehouse.materials[props.matName].name}</Typography>}
|
label={<Typography>{"Use leftovers"}</Typography>}
|
||||||
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={value == "imports"} onChange={onIChange} />}
|
||||||
|
label={<Typography>{"Use imported"}</Typography>}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
</>
|
</>
|
||||||
@ -63,18 +83,29 @@ export function SmartSupplyModal(props: IProps): React.ReactElement {
|
|||||||
for (const matName of Object.values(materialNames)) {
|
for (const matName of Object.values(materialNames)) {
|
||||||
if (!props.warehouse.materials[matName]) continue;
|
if (!props.warehouse.materials[matName]) continue;
|
||||||
if (!Object.keys(division.reqMats).includes(matName)) continue;
|
if (!Object.keys(division.reqMats).includes(matName)) continue;
|
||||||
mats.push(<Leftover key={matName} warehouse={props.warehouse} matName={matName} />);
|
mats.push(<SSoption key={matName} warehouse={props.warehouse} matName={matName} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={props.open} onClose={props.onClose}>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<>
|
<>
|
||||||
|
<Typography>Smart Supply purchases the exact amount of materials needed for maximal production.</Typography>
|
||||||
|
<br />
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Switch checked={props.warehouse.smartSupplyEnabled} onChange={smartSupplyOnChange} />}
|
control={<Switch checked={props.warehouse.smartSupplyEnabled} onChange={smartSupplyOnChange} />}
|
||||||
label={<Typography>Enable Smart Supply</Typography>}
|
label={<Typography>Enable Smart Supply</Typography>}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<Typography>Use materials already in the warehouse instead of buying new ones, if available:</Typography>
|
<Typography>
|
||||||
|
Options:
|
||||||
|
<br />
|
||||||
|
- Use leftovers takes the amount of that material already in storage into account when purchasing new ones.
|
||||||
|
<br />
|
||||||
|
- Use imported takes the amount of that materials that was imported in previous cycle into account.
|
||||||
|
<br />
|
||||||
|
if neither is toggled on, Smart Supply will ignore any materials in store and attempts to buy as much as is
|
||||||
|
needed for production.
|
||||||
|
</Typography>
|
||||||
{mats}
|
{mats}
|
||||||
</>
|
</>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -38,12 +38,12 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
|||||||
dialogBoxCreate("You don't have enough company funds to throw a party!");
|
dialogBoxCreate("You don't have enough company funds to throw a party!");
|
||||||
} else {
|
} else {
|
||||||
const mult = ThrowParty(corp, props.office, cost);
|
const mult = ThrowParty(corp, props.office, cost);
|
||||||
// Each 5% multiplier gives an extra flat +1 to morale and happiness to make recovering from low morale easier.
|
// Each 5% multiplier gives an extra flat +1 to morale to make recovering from low morale easier.
|
||||||
const increase = mult > 1 ? (mult - 1) * 0.2 : 0;
|
const increase = mult > 1 ? (mult - 1) * 0.2 : 0;
|
||||||
|
|
||||||
if (mult > 0) {
|
if (mult > 0) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You threw a party for the office! The morale and happiness of each employee increased by " +
|
"You threw a party for the office! The morale of each employee increased by " +
|
||||||
formatPercent(increase) +
|
formatPercent(increase) +
|
||||||
" and was multiplied by " +
|
" and was multiplied by " +
|
||||||
formatMultiplier(mult),
|
formatMultiplier(mult),
|
||||||
|
@ -37,7 +37,7 @@ export function General(): React.ReactElement {
|
|||||||
|
|
||||||
// Corp functions
|
// Corp functions
|
||||||
const createCorporation = () => {
|
const createCorporation = () => {
|
||||||
Player.startCorporation(corporationName);
|
Player.startCorporation(corporationName, false);
|
||||||
// Rerender so the corp menu option will show up immediately on the devmenu page selection
|
// Rerender so the corp menu option will show up immediately on the devmenu page selection
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
};
|
};
|
||||||
|
@ -34,49 +34,54 @@ export const Literatures: Record<string, Literature> = {};
|
|||||||
fn = LiteratureNames.CorporationManagementHandbook;
|
fn = LiteratureNames.CorporationManagementHandbook;
|
||||||
txt =
|
txt =
|
||||||
"<u>Getting Started with Corporations</u><br>" +
|
"<u>Getting Started with Corporations</u><br>" +
|
||||||
"To get started, visit the City Hall in Sector-12 in order to create a Corporation. This requires " +
|
"To get started, visit the City Hall in Sector-12 in order to create a Corporation. This requires $150b of your own money, " +
|
||||||
"$150b of your own money, but this $150b will get put into your Corporation's funds. " +
|
"but this $150b will get put into your Corporation's funds. If you're in BitNode 3 you also have option to get seed money from " +
|
||||||
"Your Corporation can have many different divisions, each in a different Industry. There are many different " +
|
"the government in exchange for 500m shares. Your Corporation can have many different divisions, each in a different Industry. " +
|
||||||
"types of Industries, each with different properties. To create your first division, click the " +
|
"There are many different types of Industries, each with different properties. To create your first division, click the 'Expand' " +
|
||||||
"'Expand into new Industry' button at the top of the management UI. The Agriculture " +
|
"(into new Industry) button at the top of the management UI. The Agriculture industry is recommended for your first division.<br><br>" +
|
||||||
"and Software industries are recommended for your first division.<br><br>" +
|
"The first thing you'll need to do is hire some employees. Employees can be assigned to five different positions. Each position has a " +
|
||||||
"The first thing you'll need to do is hire some employees. Employees can be assigned to five different positions. " +
|
"different effect on various aspects of your Corporation. It is recommended to have at least one employee at each position.<br><br>" +
|
||||||
"Each position has a different effect on various aspects of your Corporation. It is recommended to have at least " +
|
"Each industry uses some combination of Materials in order to produce other Materials and/or create Products. Specific information " +
|
||||||
"one employee at each position.<br><br>" +
|
"about this is displayed in each of your divisions' UI.<br><br>" +
|
||||||
"Each industry uses some combination of Materials in order to produce other Materials and/or create Products. " +
|
"Products are special, industry-specific objects. They are different than Materials because you must manually choose to develop them, " +
|
||||||
"Specific information about this is displayed in each of your divisions' UI.<br><br>" +
|
"and you can choose to develop any number of Products. Developing a Product takes time, but a Product typically generates significantly " +
|
||||||
"Products are special, industry-specific objects. They are different than Materials because you " +
|
"more revenue than any Material. Not all industries allow you to create Products. To create a Product, look for a button in the top-left " +
|
||||||
"must manually choose to develop them, and you can choose to develop any number of Products. Developing " +
|
"panel of the division UI (e.g. For the Software Industry, the button says 'Develop Software').<br><br>" +
|
||||||
"a Product takes time, but a Product typically generates significantly more revenue than any Material. " +
|
"To get your supply chain system started, purchase the Materials that your industry needs to produce other Materials/Products. This can be " +
|
||||||
"Not all industries allow you to create Products. To create a Product, look for a button " +
|
"done by clicking the 'Buy' button next to the corresponding Material(s). After you have the required Materials, you will immediately start " +
|
||||||
"in the top-left panel of the division UI (e.g. For the Software Industry, the button says 'Develop Software').<br><br>" +
|
"production. The amount and quality/effective rating of Materials/Products you produce is based on a variety of factors, such as your employees " +
|
||||||
"To get your supply chain system started, " +
|
"and their productivity and the quality of materials used for production.<br><br>" +
|
||||||
"purchase the Materials that your industry needs to produce other Materials/Products. This can be done " +
|
"Once you start producing Materials/Products, you can sell them in order to start earning revenue. This can be done by clicking the 'Sell' " +
|
||||||
"by clicking the 'Buy' button next to the corresponding Material(s). After you have the required Materials, " +
|
"button next to the corresponding Material or Product. The amount of Material/Product you sell is dependent on a wide variety of different factors. " +
|
||||||
"you will immediately start production. The amount of Materials/Products you produce is based on a variety of factors, " +
|
"In order to produce and sell a Product you'll have to fully develop it first.<br><br>" +
|
||||||
"one of which is your employees and their productivity.<br><br>" +
|
"These are the basics of getting your Corporation up and running! Now, you can start purchasing upgrades to improve your bottom line. " +
|
||||||
"Once you start producing Materials/Products, you can sell them in order to start earning revenue. This can be done " +
|
"If you need money, consider looking for seed investors, who will give you money in exchange for stock shares. Otherwise, once you feel " +
|
||||||
"by clicking the 'Sell' button next to the corresponding Material or Product. The amount of Material/Product you sell is dependent " +
|
"you are ready, take your Corporation public! Once your Corporation goes public, you can no longer find investors. Instead, your Corporation " +
|
||||||
"on a wide variety of different factors.<br><br>" +
|
"will be publicly traded and its stock price will change based on how well it's performing financially. In order to make money for yourself you " +
|
||||||
"These are the basics of getting your Corporation up and running! Now, you can start purchasing upgrades to improve " +
|
"can set dividends for a solid reliable income or you can sell your stock shares in order to make quick money.<br><br>" +
|
||||||
"your bottom line. If you need money, consider looking for seed investors, who will give you money in exchange for stock shares. " +
|
|
||||||
"Otherwise, once you feel you are ready, take your Corporation public! Once your Corporation goes public, you can no longer " +
|
|
||||||
"find investors. Instead, your Corporation will be publicly traded and its stock price will change based on how well " +
|
|
||||||
"it's performing financially. You can then sell your stock shares in order to make money.<br><br>" +
|
|
||||||
"<u>Tips/Pointers</u><br>" +
|
"<u>Tips/Pointers</u><br>" +
|
||||||
|
"-Start with one division, such as Agriculture. Get it profitable on it's own, then expand to a division that consumes/produces " +
|
||||||
|
"a material that the division you selected produces/consumes.<br><br>" +
|
||||||
|
"-Materials are profitable, but Products are where the real money is, although if the product had a low development budget or is " +
|
||||||
|
"produced with low quality materials it won't sell well.<br><br>" +
|
||||||
"-The 'Smart Supply' upgrade is extremely useful. Consider purchasing it as soon as possible.<br><br>" +
|
"-The 'Smart Supply' upgrade is extremely useful. Consider purchasing it as soon as possible.<br><br>" +
|
||||||
"-Purchasing Hardware, Robots, AI Cores, and Real Estate can potentially increase your production. " +
|
"-Purchasing Hardware, Robots, AI Cores, and Real Estate can potentially increase your production. The effects of these depend on " +
|
||||||
"The effects of these depend on what industry you are in.<br><br>" +
|
"what industry you are in.<br><br>" +
|
||||||
"-In order to optimize your production, you will need a good balance of Operators, Managers, and Engineers<br><br>" +
|
"-In order to optimize your production, you will need a good balance of all employee positions, about 1/9 should be interning<br><br>" +
|
||||||
"-Different employees excel in different jobs. For example, the highly intelligent employees will probably do best " +
|
"-Quality of materials used for production affects the quality/effective rating of materials/products produced, so vertical integration " +
|
||||||
"if they are assigned to do Engineering work or Research & Development.<br><br>" +
|
"is important for high profits.<br><br>" +
|
||||||
"-If your employees have low morale, energy, or happiness, their production will greatly suffer.<br><br>" +
|
"-Materials purchased from the open market are always of quality 1.<br><br>" +
|
||||||
"-Tech is important, but don't neglect sales! Having several Businessmen can boost your sales and your bottom line.<br><br>" +
|
"-The price at which you can sell your Materials/Products is highly affected by the quality/effective rating<br><br>" +
|
||||||
|
"-When developing a product, different employee positions affect the development process differently, " +
|
||||||
|
"some improve the development speed, some improve the rating of the finished product.<br><br>" +
|
||||||
|
"-If your employees have low morale or energy, their production will greatly suffer. Having enough interns will make sure those stats get " +
|
||||||
|
"high and stay high.<br><br>" +
|
||||||
"-Don't forget to advertise your company. You won't have any business if nobody knows you.<br><br>" +
|
"-Don't forget to advertise your company. You won't have any business if nobody knows you.<br><br>" +
|
||||||
"-Having company awareness is great, but what's really important is your company's popularity. Try to keep " +
|
"-Having company awareness is great, but what's really important is your company's popularity. Try to keep your popularity as high as " +
|
||||||
"your popularity as high as possible to see the biggest benefit for your sales<br><br>" +
|
"possible to see the biggest benefit for your sales<br><br>" +
|
||||||
"-Remember, you need to spend money to make money!<br><br>" +
|
"-Remember, you need to spend money to make money!<br><br>" +
|
||||||
"-Corporations do not reset when installing Augmentations, but they do reset when destroying a BitNode";
|
"-Corporations do not reset when installing Augmentations, but they do reset when destroying a BitNode";
|
||||||
|
|
||||||
Literatures[fn] = new Literature(title, fn, txt);
|
Literatures[fn] = new Literature(title, fn, txt);
|
||||||
|
|
||||||
title = "A Brief History of Synthoids";
|
title = "A Brief History of Synthoids";
|
||||||
|
@ -373,7 +373,7 @@ const corporation = {
|
|||||||
sellProduct: RamCostConstants.Corporation,
|
sellProduct: RamCostConstants.Corporation,
|
||||||
discontinueProduct: RamCostConstants.Corporation,
|
discontinueProduct: RamCostConstants.Corporation,
|
||||||
setSmartSupply: RamCostConstants.Corporation,
|
setSmartSupply: RamCostConstants.Corporation,
|
||||||
setSmartSupplyUseLeftovers: RamCostConstants.Corporation,
|
setSmartSupplyOption: RamCostConstants.Corporation,
|
||||||
buyMaterial: RamCostConstants.Corporation,
|
buyMaterial: RamCostConstants.Corporation,
|
||||||
bulkPurchase: RamCostConstants.Corporation,
|
bulkPurchase: RamCostConstants.Corporation,
|
||||||
getWarehouse: RamCostConstants.Corporation,
|
getWarehouse: RamCostConstants.Corporation,
|
||||||
@ -395,7 +395,7 @@ const corporation = {
|
|||||||
hireEmployee: RamCostConstants.Corporation,
|
hireEmployee: RamCostConstants.Corporation,
|
||||||
upgradeOfficeSize: RamCostConstants.Corporation,
|
upgradeOfficeSize: RamCostConstants.Corporation,
|
||||||
throwParty: RamCostConstants.Corporation,
|
throwParty: RamCostConstants.Corporation,
|
||||||
buyCoffee: RamCostConstants.Corporation,
|
buyTea: RamCostConstants.Corporation,
|
||||||
hireAdVert: RamCostConstants.Corporation,
|
hireAdVert: RamCostConstants.Corporation,
|
||||||
research: RamCostConstants.Corporation,
|
research: RamCostConstants.Corporation,
|
||||||
getOffice: RamCostConstants.Corporation,
|
getOffice: RamCostConstants.Corporation,
|
||||||
|
@ -32,7 +32,7 @@ import {
|
|||||||
UpgradeOfficeSize,
|
UpgradeOfficeSize,
|
||||||
PurchaseWarehouse,
|
PurchaseWarehouse,
|
||||||
UpgradeWarehouse,
|
UpgradeWarehouse,
|
||||||
BuyCoffee,
|
BuyTea,
|
||||||
ThrowParty,
|
ThrowParty,
|
||||||
HireAdVert,
|
HireAdVert,
|
||||||
MakeProduct,
|
MakeProduct,
|
||||||
@ -46,7 +46,7 @@ import {
|
|||||||
BulkPurchase,
|
BulkPurchase,
|
||||||
SellShares,
|
SellShares,
|
||||||
BuyBackShares,
|
BuyBackShares,
|
||||||
SetSmartSupplyUseLeftovers,
|
SetSmartSupplyOption,
|
||||||
LimitMaterialProduction,
|
LimitMaterialProduction,
|
||||||
LimitProductProduction,
|
LimitProductProduction,
|
||||||
UpgradeWarehouseCost,
|
UpgradeWarehouseCost,
|
||||||
@ -76,10 +76,10 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
if (selfFund) {
|
if (selfFund) {
|
||||||
if (!player.canAfford(150e9)) return false;
|
if (!player.canAfford(150e9)) return false;
|
||||||
|
|
||||||
player.startCorporation(corporationName);
|
player.startCorporation(corporationName, false);
|
||||||
player.loseMoney(150e9, "corporation");
|
player.loseMoney(150e9, "corporation");
|
||||||
} else {
|
} else {
|
||||||
player.startCorporation(corporationName, 500e6);
|
player.startCorporation(corporationName, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -243,7 +243,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProduct(divisionName: string, productName: string): Product {
|
function getProduct(divisionName: string, cityName: string, productName: string): Product {
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
const product = division.products[productName];
|
const product = division.products[productName];
|
||||||
if (product === undefined) throw new Error(`Invalid product name: '${productName}'`);
|
if (product === undefined) throw new Error(`Invalid product name: '${productName}'`);
|
||||||
@ -331,6 +331,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
return {
|
return {
|
||||||
cost: material.bCost,
|
cost: material.bCost,
|
||||||
sCost: material.sCost,
|
sCost: material.sCost,
|
||||||
|
sAmt: material.sllman[1],
|
||||||
name: material.name,
|
name: material.name,
|
||||||
qty: material.qty,
|
qty: material.qty,
|
||||||
qlt: material.qlt,
|
qlt: material.qlt,
|
||||||
@ -341,17 +342,19 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
exp: exports,
|
exp: exports,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getProduct: (ctx) => (_divisionName, _productName) => {
|
getProduct: (ctx) => (_divisionName, _cityName, _productName) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = helpers.string(ctx, "productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const product = getProduct(divisionName, productName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
|
const product = getProduct(divisionName, cityName, productName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
return {
|
return {
|
||||||
name: product.name,
|
name: product.name,
|
||||||
dmd: corporation.unlockUpgrades[2] ? product.dmd : undefined,
|
dmd: corporation.unlockUpgrades[2] ? product.dmd : undefined,
|
||||||
cmp: corporation.unlockUpgrades[3] ? product.cmp : undefined,
|
cmp: corporation.unlockUpgrades[3] ? product.cmp : undefined,
|
||||||
rat: product.rat,
|
rat: product.rat,
|
||||||
|
effRat: product.data[cityName][3],
|
||||||
properties: {
|
properties: {
|
||||||
qlt: product.qlt,
|
qlt: product.qlt,
|
||||||
per: product.per,
|
per: product.per,
|
||||||
@ -361,8 +364,11 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
fea: product.fea,
|
fea: product.fea,
|
||||||
},
|
},
|
||||||
pCost: product.pCost,
|
pCost: product.pCost,
|
||||||
sCost: product.sCost,
|
sCost: product.sCost[cityName],
|
||||||
cityData: product.data,
|
sAmt: product.sllman[cityName][1],
|
||||||
|
qty: product.data[cityName][0],
|
||||||
|
prod: product.data[cityName][1],
|
||||||
|
sell: product.data[cityName][2],
|
||||||
developmentProgress: product.prog,
|
developmentProgress: product.prog,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -406,14 +412,14 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
const amt = helpers.string(ctx, "amt", _amt);
|
const amt = helpers.string(ctx, "amt", _amt);
|
||||||
const price = helpers.string(ctx, "price", _price);
|
const price = helpers.string(ctx, "price", _price);
|
||||||
const all = !!_all;
|
const all = !!_all;
|
||||||
const product = getProduct(divisionName, productName);
|
const product = getProduct(divisionName, cityName, productName);
|
||||||
SellProduct(product, cityName, amt, price, all);
|
SellProduct(product, cityName, amt, price, all);
|
||||||
},
|
},
|
||||||
discontinueProduct: (ctx) => (_divisionName, _productName) => {
|
discontinueProduct: (ctx) => (_divisionName, _productName) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = helpers.string(ctx, "productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName));
|
getDivision(divisionName).discontinueProduct(getProduct(divisionName, "Sector-12", productName));
|
||||||
},
|
},
|
||||||
setSmartSupply: (ctx) => (_divisionName, _cityName, _enabled) => {
|
setSmartSupply: (ctx) => (_divisionName, _cityName, _enabled) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
@ -425,17 +431,17 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
||||||
SetSmartSupply(warehouse, enabled);
|
SetSmartSupply(warehouse, enabled);
|
||||||
},
|
},
|
||||||
setSmartSupplyUseLeftovers: (ctx) => (_divisionName, _cityName, materialName, _enabled) => {
|
setSmartSupplyOption: (ctx) => (_divisionName, _cityName, materialName, _option) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
assertMember(ctx, corpConstants.materialNames, "Material Name", "materialName", materialName);
|
assertMember(ctx, corpConstants.materialNames, "Material Name", "materialName", materialName);
|
||||||
const enabled = !!_enabled;
|
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
|
const option = helpers.string(ctx, "option", _option);
|
||||||
if (!hasUnlockUpgrade("Smart Supply"))
|
if (!hasUnlockUpgrade("Smart Supply"))
|
||||||
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
||||||
SetSmartSupplyUseLeftovers(warehouse, material, enabled);
|
SetSmartSupplyOption(warehouse, material, option);
|
||||||
},
|
},
|
||||||
buyMaterial: (ctx) => (_divisionName, _cityName, materialName, _amt) => {
|
buyMaterial: (ctx) => (_divisionName, _cityName, materialName, _amt) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
@ -451,8 +457,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
bulkPurchase: (ctx) => (_divisionName, _cityName, materialName, _amt) => {
|
bulkPurchase: (ctx) => (_divisionName, _cityName, materialName, _amt) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
if (!hasResearched(getDivision(divisionName), "Bulk Purchasing"))
|
|
||||||
throw new Error(`You have not researched Bulk Purchasing in ${divisionName}`);
|
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
assertMember(ctx, corpConstants.materialNames, "Material Name", "materialName", materialName);
|
assertMember(ctx, corpConstants.materialNames, "Material Name", "materialName", materialName);
|
||||||
@ -479,7 +483,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = helpers.string(ctx, "productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const qty = helpers.number(ctx, "qty", _qty);
|
const qty = helpers.number(ctx, "qty", _qty);
|
||||||
LimitProductProduction(getProduct(divisionName, productName), cityName, qty);
|
LimitProductProduction(getProduct(divisionName, cityName, productName), cityName, qty);
|
||||||
},
|
},
|
||||||
exportMaterial:
|
exportMaterial:
|
||||||
(ctx) =>
|
(ctx) =>
|
||||||
@ -539,23 +543,25 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
||||||
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
|
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
|
||||||
},
|
},
|
||||||
setProductMarketTA1: (ctx) => (_divisionName, _productName, _on) => {
|
setProductMarketTA1: (ctx) => (_divisionName, _cityName, _productName, _on) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = helpers.string(ctx, "productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const on = !!_on;
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
||||||
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
|
||||||
SetProductMarketTA1(getProduct(divisionName, productName), on);
|
SetProductMarketTA1(getProduct(divisionName, cityName, productName), on);
|
||||||
},
|
},
|
||||||
setProductMarketTA2: (ctx) => (_divisionName, _productName, _on) => {
|
setProductMarketTA2: (ctx) => (_divisionName, _cityName, _productName, _on) => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = helpers.string(ctx, "productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const on = !!_on;
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
||||||
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
||||||
SetProductMarketTA2(getProduct(divisionName, productName), on);
|
SetProductMarketTA2(getProduct(divisionName, cityName, productName), on);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -660,14 +666,14 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
|
|
||||||
return ThrowParty(corporation, office, costPerEmployee);
|
return ThrowParty(corporation, office, costPerEmployee);
|
||||||
},
|
},
|
||||||
buyCoffee: (ctx) => (_divisionName, _cityName) => {
|
buyTea: (ctx) => (_divisionName, _cityName) => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
|
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
return BuyCoffee(corporation, office);
|
return BuyTea(corporation, office);
|
||||||
},
|
},
|
||||||
hireAdVert: (ctx) => (_divisionName) => {
|
hireAdVert: (ctx) => (_divisionName) => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
@ -690,11 +696,9 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
loc: office.loc,
|
loc: office.loc,
|
||||||
size: office.size,
|
size: office.size,
|
||||||
maxEne: office.maxEne,
|
maxEne: office.maxEne,
|
||||||
maxHap: office.maxHap,
|
|
||||||
maxMor: office.maxMor,
|
maxMor: office.maxMor,
|
||||||
employees: office.totalEmployees,
|
employees: office.totalEmployees,
|
||||||
avgEne: office.avgEne,
|
avgEne: office.avgEne,
|
||||||
avgHap: office.avgHap,
|
|
||||||
avgMor: office.avgMor,
|
avgMor: office.avgMor,
|
||||||
totalExperience: office.totalExp,
|
totalExperience: office.totalExp,
|
||||||
employeeProd: Object.assign({}, office.employeeProd),
|
employeeProd: Object.assign({}, office.employeeProd),
|
||||||
@ -761,7 +765,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
||||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||||
LevelUpgrade(corporation, upgrade);
|
LevelUpgrade(corporation, upgrade, 1);
|
||||||
},
|
},
|
||||||
issueDividends: (ctx) => (_rate) => {
|
issueDividends: (ctx) => (_rate) => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
|
@ -4,15 +4,19 @@ import {
|
|||||||
CorporationUnlockUpgrades,
|
CorporationUnlockUpgrades,
|
||||||
} from "../../Corporation/data/CorporationUnlockUpgrades";
|
} from "../../Corporation/data/CorporationUnlockUpgrades";
|
||||||
import { PlayerObject } from "./PlayerObject";
|
import { PlayerObject } from "./PlayerObject";
|
||||||
|
import { resetIndustryResearchTrees } from "../../Corporation/IndustryData";
|
||||||
|
|
||||||
export function canAccessCorporation(this: PlayerObject): boolean {
|
export function canAccessCorporation(this: PlayerObject): boolean {
|
||||||
return this.bitNodeN === 3 || this.sourceFileLvl(3) > 0;
|
return this.bitNodeN === 3 || this.sourceFileLvl(3) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startCorporation(this: PlayerObject, corpName: string, additionalShares = 0): void {
|
export function startCorporation(this: PlayerObject, corpName: string, seedFunded: boolean): void {
|
||||||
this.corporation = new Corporation({
|
this.corporation = new Corporation({
|
||||||
name: corpName,
|
name: corpName,
|
||||||
|
seedFunded: seedFunded,
|
||||||
});
|
});
|
||||||
|
//reset the research tree in case the corporation was restarted
|
||||||
|
resetIndustryResearchTrees();
|
||||||
|
|
||||||
if (this.bitNodeN === 3 || this.sourceFileLvl(3) === 3) {
|
if (this.bitNodeN === 3 || this.sourceFileLvl(3) === 3) {
|
||||||
const warehouseApi = CorporationUnlockUpgrades[CorporationUnlockUpgradeIndex.WarehouseAPI].index;
|
const warehouseApi = CorporationUnlockUpgrades[CorporationUnlockUpgradeIndex.WarehouseAPI].index;
|
||||||
@ -22,5 +26,5 @@ export function startCorporation(this: PlayerObject, corpName: string, additiona
|
|||||||
this.corporation.unlockUpgrades[OfficeApi] = 1;
|
this.corporation.unlockUpgrades[OfficeApi] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.corporation.totalShares += additionalShares;
|
this.corporation.totalShares += seedFunded ? 500_000_000 : 0;
|
||||||
}
|
}
|
||||||
|
@ -248,8 +248,11 @@ export function prestigeSourceFile(flume: boolean): void {
|
|||||||
homeComp.programs.push(Programs.Formulas.name);
|
homeComp.programs.push(Programs.Formulas.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(Player.bitNodeN);
|
||||||
|
dialogBoxCreate("hello");
|
||||||
// BitNode 3: Corporatocracy
|
// BitNode 3: Corporatocracy
|
||||||
if (Player.bitNodeN === 3) {
|
if (Player.bitNodeN === 3) {
|
||||||
|
console.log("why isn't the dialogbox happening?");
|
||||||
homeComp.messages.push(LiteratureNames.CorporationManagementHandbook);
|
homeComp.messages.push(LiteratureNames.CorporationManagementHandbook);
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You received a copy of the Corporation Management Handbook on your home computer. " +
|
"You received a copy of the Corporation Management Handbook on your home computer. " +
|
||||||
|
63
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
63
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -6887,17 +6887,18 @@ type CorpEmployeePosition =
|
|||||||
| "Business"
|
| "Business"
|
||||||
| "Management"
|
| "Management"
|
||||||
| "Research & Development"
|
| "Research & Development"
|
||||||
| "Training"
|
| "Intern"
|
||||||
| "Unassigned";
|
| "Unassigned";
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
type CorpIndustryName =
|
type CorpIndustryName =
|
||||||
| "Energy"
|
| "Spring Water"
|
||||||
| "Water Utilities"
|
| "Water Utilities"
|
||||||
| "Agriculture"
|
| "Agriculture"
|
||||||
| "Fishing"
|
| "Fishing"
|
||||||
| "Mining"
|
| "Mining"
|
||||||
| "Food"
|
| "Refinery"
|
||||||
|
| "Restaurant"
|
||||||
| "Tobacco"
|
| "Tobacco"
|
||||||
| "Chemical"
|
| "Chemical"
|
||||||
| "Pharmaceutical"
|
| "Pharmaceutical"
|
||||||
@ -7026,16 +7027,16 @@ export interface OfficeAPI {
|
|||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
* @param city - Name of the city
|
* @param city - Name of the city
|
||||||
* @param costPerEmployee - Amount to spend per employee.
|
* @param costPerEmployee - Amount to spend per employee.
|
||||||
* @returns Multiplier for happiness and morale, or zero on failure
|
* @returns Multiplier for morale, or zero on failure
|
||||||
*/
|
*/
|
||||||
throwParty(divisionName: string, city: CityName | `${CityName}`, costPerEmployee: number): number;
|
throwParty(divisionName: string, city: CityName | `${CityName}`, costPerEmployee: number): number;
|
||||||
/**
|
/**
|
||||||
* Buy coffee for your employees
|
* Buy tea for your employees
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
* @param city - Name of the city
|
* @param city - Name of the city
|
||||||
* @returns true if buying coffee was successful, false otherwise
|
* @returns true if buying tea was successful, false otherwise
|
||||||
*/
|
*/
|
||||||
buyCoffee(divisionName: string, city: CityName | `${CityName}`): boolean;
|
buyTea(divisionName: string, city: CityName | `${CityName}`): boolean;
|
||||||
/**
|
/**
|
||||||
* Hire AdVert.
|
* Hire AdVert.
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
@ -7156,13 +7157,13 @@ export interface WarehouseAPI {
|
|||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
* @param city - Name of the city
|
* @param city - Name of the city
|
||||||
* @param materialName - Name of the material
|
* @param materialName - Name of the material
|
||||||
* @param enabled - smart supply use leftovers enabled
|
* @param option - smart supply option, "leftovers" to use leftovers, "imports" to use only imported materials, "none" to not use materials from store
|
||||||
*/
|
*/
|
||||||
setSmartSupplyUseLeftovers(
|
setSmartSupplyOption(
|
||||||
divisionName: string,
|
divisionName: string,
|
||||||
city: CityName | `${CityName}`,
|
city: CityName | `${CityName}`,
|
||||||
materialName: string,
|
materialName: string,
|
||||||
enabled: boolean,
|
option: string,
|
||||||
): void;
|
): void;
|
||||||
/**
|
/**
|
||||||
* Set material buy data
|
* Set material buy data
|
||||||
@ -7190,10 +7191,11 @@ export interface WarehouseAPI {
|
|||||||
/**
|
/**
|
||||||
* Get product data
|
* Get product data
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
|
* @param city - Name of the city
|
||||||
* @param productName - Name of the product
|
* @param productName - Name of the product
|
||||||
* @returns product data
|
* @returns product data
|
||||||
*/
|
*/
|
||||||
getProduct(divisionName: string, productName: string): Product;
|
getProduct(divisionName: string, city: CityName | `${CityName}`, productName: string): Product;
|
||||||
/**
|
/**
|
||||||
* Get material data
|
* Get material data
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
@ -7221,17 +7223,19 @@ export interface WarehouseAPI {
|
|||||||
/**
|
/**
|
||||||
* Set market TA 1 for a product.
|
* Set market TA 1 for a product.
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
|
* @param city - Name of the city
|
||||||
* @param productName - Name of the product
|
* @param productName - Name of the product
|
||||||
* @param on - market ta enabled
|
* @param on - market ta enabled
|
||||||
*/
|
*/
|
||||||
setProductMarketTA1(divisionName: string, productName: string, on: boolean): void;
|
setProductMarketTA1(divisionName: string, city: CityName | `${CityName}`, productName: string, on: boolean): void;
|
||||||
/**
|
/**
|
||||||
* Set market TA 2 for a product.
|
* Set market TA 2 for a product.
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
|
* @param city - Name of the city
|
||||||
* @param productName - Name of the product
|
* @param productName - Name of the product
|
||||||
* @param on - market ta enabled
|
* @param on - market ta enabled
|
||||||
*/
|
*/
|
||||||
setProductMarketTA2(divisionName: string, productName: string, on: boolean): void;
|
setProductMarketTA2(divisionName: string, city: CityName | `${CityName}`, productName: string, on: boolean): void;
|
||||||
/**
|
/**
|
||||||
* Set material export data
|
* Set material export data
|
||||||
* @param sourceDivision - Source division
|
* @param sourceDivision - Source division
|
||||||
@ -7433,11 +7437,11 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
|
|||||||
issueNewShares(amount?: number): number;
|
issueNewShares(amount?: number): number;
|
||||||
|
|
||||||
/** Buyback Shares
|
/** Buyback Shares
|
||||||
* @param amount - Amount of shares to buy back. */
|
* @param amount - Amount of shares to buy back, must be integer and larger than 0 */
|
||||||
buyBackShares(amount: number): void;
|
buyBackShares(amount: number): void;
|
||||||
|
|
||||||
/** Sell Shares
|
/** Sell Shares
|
||||||
* @param amount - Amount of shares to sell. */
|
* @param amount - Amount of shares to sell, must be integer between 1 and 100t */
|
||||||
sellShares(amount: number): void;
|
sellShares(amount: number): void;
|
||||||
|
|
||||||
/** Get bonus time.
|
/** Get bonus time.
|
||||||
@ -7555,7 +7559,7 @@ interface CorpConstants {
|
|||||||
issueNewSharesCooldown: number;
|
issueNewSharesCooldown: number;
|
||||||
/** Cooldown for selling shares in game cycles (1 game cycle = 200ms) */
|
/** Cooldown for selling shares in game cycles (1 game cycle = 200ms) */
|
||||||
sellSharesCooldown: number;
|
sellSharesCooldown: number;
|
||||||
coffeeCostPerEmployee: number;
|
teaCostPerEmployee: number;
|
||||||
gameCyclesPerMarketCycle: number;
|
gameCyclesPerMarketCycle: number;
|
||||||
gameCyclesPerCorpStateCycle: number;
|
gameCyclesPerCorpStateCycle: number;
|
||||||
secondsPerMarketCycle: number;
|
secondsPerMarketCycle: number;
|
||||||
@ -7575,7 +7579,7 @@ interface CorpConstants {
|
|||||||
employeeRaiseAmount: number;
|
employeeRaiseAmount: number;
|
||||||
/** Max products for a division without upgrades */
|
/** Max products for a division without upgrades */
|
||||||
maxProductsBase: number;
|
maxProductsBase: number;
|
||||||
/** The minimum decay value for happiness/morale/energy */
|
/** The minimum decay value for morale/energy */
|
||||||
minEmployeeDecay: number;
|
minEmployeeDecay: number;
|
||||||
}
|
}
|
||||||
/** @public */
|
/** @public */
|
||||||
@ -7583,8 +7587,9 @@ type CorpStateName = "START" | "PURCHASE" | "PRODUCTION" | "EXPORT" | "SALE";
|
|||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
type CorpMaterialName =
|
type CorpMaterialName =
|
||||||
|
| "Minerals"
|
||||||
|
| "Ore"
|
||||||
| "Water"
|
| "Water"
|
||||||
| "Energy"
|
|
||||||
| "Food"
|
| "Food"
|
||||||
| "Plants"
|
| "Plants"
|
||||||
| "Metal"
|
| "Metal"
|
||||||
@ -7699,16 +7704,22 @@ interface Product {
|
|||||||
cmp: number | undefined;
|
cmp: number | undefined;
|
||||||
/** Product Rating */
|
/** Product Rating */
|
||||||
rat: number;
|
rat: number;
|
||||||
|
/** Effective rating */
|
||||||
|
effRat: number;
|
||||||
/** Product Properties. The data is \{qlt, per, dur, rel, aes, fea\} */
|
/** Product Properties. The data is \{qlt, per, dur, rel, aes, fea\} */
|
||||||
properties: { [key: string]: number };
|
properties: { [key: string]: number };
|
||||||
/** Production cost */
|
/** Production cost */
|
||||||
pCost: number;
|
pCost: number;
|
||||||
/** Sell cost, can be "MP+5" */
|
/** Sell cost, can be "MP+5" */
|
||||||
sCost: string | number;
|
sCost: string;
|
||||||
/** Data refers to the production, sale, and quantity of the products
|
/** Sell amount, can be "PROD/2" */
|
||||||
* These values are specific to a city
|
sAmt: string;
|
||||||
* For each city, the data is [qty, prod, sell] */
|
/** Amount of product */
|
||||||
cityData: Record<CityName | `${CityName}`, number[]>;
|
qty: number;
|
||||||
|
/** Amount of product produced */
|
||||||
|
prod: number;
|
||||||
|
/** Amount of product sold */
|
||||||
|
sell: number;
|
||||||
/** Creation progress - A number between 0-100 representing percentage */
|
/** Creation progress - A number between 0-100 representing percentage */
|
||||||
developmentProgress: number;
|
developmentProgress: number;
|
||||||
}
|
}
|
||||||
@ -7736,6 +7747,8 @@ interface Material {
|
|||||||
cost: number;
|
cost: number;
|
||||||
/** Sell cost, can be "MP+5" */
|
/** Sell cost, can be "MP+5" */
|
||||||
sCost: string | number;
|
sCost: string | number;
|
||||||
|
/** Sell amount, can be "PROD/2" */
|
||||||
|
sAmt: string | number;
|
||||||
/** Export orders */
|
/** Export orders */
|
||||||
exp: Export[];
|
exp: Export[];
|
||||||
}
|
}
|
||||||
@ -7781,16 +7794,12 @@ export interface Office {
|
|||||||
size: number;
|
size: number;
|
||||||
/** Maximum amount of energy of the employees */
|
/** Maximum amount of energy of the employees */
|
||||||
maxEne: number;
|
maxEne: number;
|
||||||
/** Maximum happiness of the employees */
|
|
||||||
maxHap: number;
|
|
||||||
/** Maximum morale of the employees */
|
/** Maximum morale of the employees */
|
||||||
maxMor: number;
|
maxMor: number;
|
||||||
/** Amount of employees */
|
/** Amount of employees */
|
||||||
employees: number;
|
employees: number;
|
||||||
/** Average energy of the employees */
|
/** Average energy of the employees */
|
||||||
avgEne: number;
|
avgEne: number;
|
||||||
/** Average happiness of the employees */
|
|
||||||
avgHap: number;
|
|
||||||
/** Average morale of the employees */
|
/** Average morale of the employees */
|
||||||
avgMor: number;
|
avgMor: number;
|
||||||
/** Total experience of all employees */
|
/** Total experience of all employees */
|
||||||
|
Loading…
Reference in New Issue
Block a user