From e992cb966ac30efec1404b7097df9b195f2c1f2e Mon Sep 17 00:00:00 2001 From: Caldwell <115591472+Caldwell-74@users.noreply.github.com> Date: Mon, 23 Oct 2023 10:48:06 +0200 Subject: [PATCH] CORPORATION: adding prevState and changed state display in the warehouse UI (#861) --- markdown/bitburner.corporationinfo.md | 3 +- ...=> bitburner.corporationinfo.nextstate.md} | 6 +-- .../bitburner.corporationinfo.prevstate.md | 17 ++++++++ src/Corporation/Corporation.ts | 8 ++-- src/Corporation/CorporationState.ts | 9 ++-- src/Corporation/Division.ts | 8 ++-- src/Corporation/ui/DivisionWarehouse.tsx | 42 ++++++------------- src/NetscriptFunctions.ts | 28 +------------ src/NetscriptFunctions/Corporation.ts | 15 +++++-- src/ScriptEditor/NetscriptDefinitions.d.ts | 8 +++- src/utils/DeprecationHelper.ts | 28 +++++++++++++ 11 files changed, 96 insertions(+), 76 deletions(-) rename markdown/{bitburner.corporationinfo.state.md => bitburner.corporationinfo.nextstate.md} (69%) create mode 100644 markdown/bitburner.corporationinfo.prevstate.md create mode 100644 src/utils/DeprecationHelper.ts diff --git a/markdown/bitburner.corporationinfo.md b/markdown/bitburner.corporationinfo.md index 13c50301b..03a7fd16e 100644 --- a/markdown/bitburner.corporationinfo.md +++ b/markdown/bitburner.corporationinfo.md @@ -26,11 +26,12 @@ interface CorporationInfo | [issuedShares](./bitburner.corporationinfo.issuedshares.md) | | number | Amount of shares owned by public traders. Available for CEO buyback. | | [issueNewSharesCooldown](./bitburner.corporationinfo.issuenewsharescooldown.md) | | number | Cooldown until new shares can be issued | | [name](./bitburner.corporationinfo.name.md) | | string | Name of the corporation | +| [nextState](./bitburner.corporationinfo.nextstate.md) | | [CorpStateName](./bitburner.corpstatename.md) |

The next state to be processed.

I.e. when the state is PURCHASE, it means purchasing will occur during the next state transition.

Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE.

| | [numShares](./bitburner.corporationinfo.numshares.md) | | number | Amount of shares owned by the CEO. | +| [prevState](./bitburner.corporationinfo.prevstate.md) | | [CorpStateName](./bitburner.corpstatename.md) |

The last state that got processed.

I.e. when that state is PURCHASE, it means purchasing just happened.

Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE.

| | [public](./bitburner.corporationinfo.public.md) | | boolean | Indicating if the company is public | | [revenue](./bitburner.corporationinfo.revenue.md) | | number | Revenue per second this cycle | | [sharePrice](./bitburner.corporationinfo.shareprice.md) | | number | Price of the shares | | [shareSaleCooldown](./bitburner.corporationinfo.sharesalecooldown.md) | | number | Cooldown until shares can be sold again | -| [state](./bitburner.corporationinfo.state.md) | | string |

The next state to be processed.

I.e. when the state is PURCHASE, it means purchasing will occur during the next state transition.

Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE.

| | [totalShares](./bitburner.corporationinfo.totalshares.md) | | number | Total number of shares issued by this corporation. | diff --git a/markdown/bitburner.corporationinfo.state.md b/markdown/bitburner.corporationinfo.nextstate.md similarity index 69% rename from markdown/bitburner.corporationinfo.state.md rename to markdown/bitburner.corporationinfo.nextstate.md index 79108b12c..de3621f42 100644 --- a/markdown/bitburner.corporationinfo.state.md +++ b/markdown/bitburner.corporationinfo.nextstate.md @@ -1,8 +1,8 @@ -[Home](./index.md) > [bitburner](./bitburner.md) > [CorporationInfo](./bitburner.corporationinfo.md) > [state](./bitburner.corporationinfo.state.md) +[Home](./index.md) > [bitburner](./bitburner.md) > [CorporationInfo](./bitburner.corporationinfo.md) > [nextState](./bitburner.corporationinfo.nextstate.md) -## CorporationInfo.state property +## CorporationInfo.nextState property The next state to be processed. @@ -13,5 +13,5 @@ Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. **Signature:** ```typescript -state: string; +nextState: CorpStateName; ``` diff --git a/markdown/bitburner.corporationinfo.prevstate.md b/markdown/bitburner.corporationinfo.prevstate.md new file mode 100644 index 000000000..6939e8b03 --- /dev/null +++ b/markdown/bitburner.corporationinfo.prevstate.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [CorporationInfo](./bitburner.corporationinfo.md) > [prevState](./bitburner.corporationinfo.prevstate.md) + +## CorporationInfo.prevState property + +The last state that got processed. + +I.e. when that state is PURCHASE, it means purchasing just happened. + +Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. + +**Signature:** + +```typescript +prevState: CorpStateName; +``` diff --git a/src/Corporation/Corporation.ts b/src/Corporation/Corporation.ts index 0e6b569af..28575b407 100644 --- a/src/Corporation/Corporation.ts +++ b/src/Corporation/Corporation.ts @@ -94,8 +94,8 @@ export class Corporation { this.funds += amt; } - getState(): CorpStateName { - return this.state.getState(); + getNextState(): CorpStateName { + return this.state.nextName; } storeCycles(numCycles: number): void { @@ -106,7 +106,7 @@ export class Corporation { if (this.storedCycles < 0) this.storedCycles = 0; if (this.storedCycles >= corpConstants.gameCyclesPerCorpStateCycle) { - const state = this.getState(); + const state = this.getNextState(); const marketCycles = 1; const gameCycles = marketCycles * corpConstants.gameCyclesPerCorpStateCycle; this.storedCycles -= gameCycles; @@ -171,7 +171,7 @@ export class Corporation { this.updateSharePrice(); } - this.state.nextState(); + this.state.incrementState(); // Handle "nextUpdate" resolvers after this update for (const resolve of CorporationResolvers.splice(0)) { diff --git a/src/Corporation/CorporationState.ts b/src/Corporation/CorporationState.ts index c2b527c52..ae1705b8a 100644 --- a/src/Corporation/CorporationState.ts +++ b/src/Corporation/CorporationState.ts @@ -9,12 +9,14 @@ export class CorporationState { // Get the name of the current state // NOTE: This does NOT return the number stored in the 'state' property, // which is just an index for the array of all possible Corporation States. - getState(): CorpStateName { + get nextName(): CorpStateName { return stateNames[this.state]; } - + get prevName(): CorpStateName { + return stateNames[(this.state + (stateNames.length - 1)) % stateNames.length]; + } // Transition to the next state - nextState(): void { + incrementState(): void { this.state = (this.state + 1) % stateNames.length; } @@ -22,7 +24,6 @@ export class CorporationState { toJSON(): IReviverValue { return Generic_toJSON("CorporationState", this); } - // Initializes a CorporationState object from a JSON save state. static fromJSON(value: IReviverValue): CorporationState { return Generic_fromJSON(CorporationState, value.data); diff --git a/src/Corporation/Division.ts b/src/Corporation/Division.ts index 3beee6057..f653452b0 100644 --- a/src/Corporation/Division.ts +++ b/src/Corporation/Division.ts @@ -142,7 +142,7 @@ export class Division { } process(marketCycles = 1, corporation: Corporation): void { - const state = corporation.state.getState(); + const state = corporation.state.nextName; //At the start of a cycle, store and reset revenue/expenses //Then calculate salaries and process the markets if (state === "START") { @@ -264,7 +264,7 @@ export class Division { //Process production, purchase, and import/export of materials processMaterials(marketCycles = 1, corporation: Corporation): [number, number] { - const state = corporation.state.getState(); + const state = corporation.state.nextName; let revenue = 0; let expenses = 0; this.calculateProductionFactors(); @@ -717,7 +717,7 @@ export class Division { /** Process product development and production/sale */ processProducts(marketCycles = 1, corporation: Corporation): [number, number] { - const state = corporation.state.getState(); + const state = corporation.state.nextName; let revenue = 0; const expenses = 0; @@ -746,7 +746,7 @@ export class Division { //Processes FINISHED products processProduct(marketCycles = 1, product: Product, corporation: Corporation): number { - const state = corporation.state.getState(); + const state = corporation.state.nextName; let totalProfit = 0; for (const [city, office] of getRecordEntries(this.offices)) { const warehouse = this.warehouses[city]; diff --git a/src/Corporation/ui/DivisionWarehouse.tsx b/src/Corporation/ui/DivisionWarehouse.tsx index fda328745..4730de08b 100644 --- a/src/Corporation/ui/DivisionWarehouse.tsx +++ b/src/Corporation/ui/DivisionWarehouse.tsx @@ -10,7 +10,7 @@ import { SmartSupplyModal } from "./modals/SmartSupplyModal"; import { ProductElem } from "./ProductElem"; import { MaterialElem } from "./MaterialElem"; import { MaterialInfo } from "../MaterialInfo"; - +import { createProgressBarText } from "../../utils/helpers/createProgressBarText"; import { formatBigNumber, formatMaterialSize } from "../../ui/formatNumber"; import { Corporation } from "../Corporation"; @@ -20,7 +20,7 @@ import { isRelevantMaterial } from "./Helpers"; import { IndustryProductEquation } from "./IndustryProductEquation"; import { purchaseWarehouse } from "../Actions"; import { useCorporation, useDivision } from "./Context"; - +import { gameCyclesPerCorpStateCycle } from "../data/Constants"; import { ButtonWithTooltip } from "../../ui/Components/ButtonWithTooltip"; interface WarehouseProps { @@ -57,30 +57,14 @@ function WarehouseRoot(props: WarehouseProps): React.ReactElement { corp.funds = corp.funds - sizeUpgradeCost; props.rerender(); } - - // Next state which will be processed: - const state = corp.state.getState(); - let stateText; - switch (state) { - case "START": - stateText = "Next state: Preparing"; - break; - case "PURCHASE": - stateText = "Next state: Purchasing materials"; - break; - case "PRODUCTION": - stateText = "Next state: Producing materials and/or products"; - break; - case "SALE": - stateText = "Next state: Selling materials and/or products"; - break; - case "EXPORT": - stateText = "Next state: Exporting materials and/or products"; - break; - default: - console.error(`Invalid state: ${state}`); - break; - } + // -1 because as soon as it hits "full" it processes and resets to 0, *2 to double the size of the bar + const ticks = (gameCyclesPerCorpStateCycle - 1) * 2; + const nextState = corp.state.nextName; + const prevState = corp.state.prevName.padStart(11); + const stateBar = createProgressBarText({ + progress: Math.min(corp.storedCycles * 2, ticks) / ticks, + totalTicks: ticks, + }); // Create React components for materials const mats = []; @@ -160,9 +144,9 @@ function WarehouseRoot(props: WarehouseProps): React.ReactElement { divisions.
- - {stateText} - + + {prevState} {stateBar} {nextState} + {corp.unlocks.has(CorpUnlockName.SmartSupply) && ( <> diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 641b6ddfe..4fb5c8b71 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -103,6 +103,7 @@ import { ContentFilePath } from "./Paths/ContentFile"; import { hasContractExtension } from "./Paths/ContractFilePath"; import { getRamCost } from "./Netscript/RamCostGenerator"; import { getEnumHelper } from "./utils/EnumHelper"; +import { setDeprecatedProperties, deprecationWarning } from "./utils/DeprecationHelper"; export const enums: NSEnums = { CityName, @@ -1807,30 +1808,3 @@ function getFunctionNames(obj: object, prefix: string): string[] { } return functionNames; } - -const deprecatedWarningsGiven = new Set(); -function setDeprecatedProperties( - obj: object, - properties: Record, -) { - for (const [name, info] of Object.entries(properties)) { - Object.defineProperty(obj, name, { - get: () => { - deprecationWarning(info.identifier, info.message); - return info.value; - }, - set: (value: any) => (info.value = value), - enumerable: true, - }); - } -} -function deprecationWarning(identifier: string, message: string) { - if (!deprecatedWarningsGiven.has(identifier)) { - deprecatedWarningsGiven.add(identifier); - Terminal.warn(`Accessed deprecated function or property: ${identifier}`); - Terminal.warn(`This is no longer supported usage and will be removed in a later version.`); - Terminal.warn(message); - Terminal.info(`This message can also appear for object properties when the object's values are iterated.`); - Terminal.info(`This message will only be shown once per game session for each deprecated item accessed.`); - } -} diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 09253c295..abc603ca6 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -7,7 +7,7 @@ import { Warehouse } from "../Corporation/Warehouse"; import { Division } from "../Corporation/Division"; import { Corporation, CorporationResolvers } from "../Corporation/Corporation"; import { cloneDeep, omit } from "lodash"; - +import { setDeprecatedProperties } from "../utils/DeprecationHelper"; import { Corporation as NSCorporation, Division as NSDivision, @@ -698,7 +698,7 @@ export function NetscriptCorporation(): InternalAPI { getCorporation: (ctx) => () => { checkAccess(ctx); const corporation = getCorporation(); - return { + const data = { name: corporation.name, funds: corporation.funds, revenue: corporation.revenue, @@ -714,9 +714,18 @@ export function NetscriptCorporation(): InternalAPI { dividendRate: corporation.dividendRate, dividendTax: corporation.dividendTax, dividendEarnings: corporation.getCycleDividends() / corpConstants.secondsPerMarketCycle, - state: corporation.state.getState(), + nextState: corporation.state.nextName, + prevState: corporation.state.prevName, divisions: [...corporation.divisions.keys()], }; + setDeprecatedProperties(data, { + state: { + identifier: "ns.corporation.getCorporation().state", + message: "Use ns.corporation.getCorporation().nextState instead.", + value: corporation.state.nextName, + }, + }); + return data; }, createCorporation: (ctx) => diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index d2771ee22..68503362f 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7686,7 +7686,13 @@ interface CorporationInfo { * I.e. when the state is PURCHASE, it means purchasing will occur during the next state transition. * * Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. */ - state: string; + nextState: CorpStateName; + /** The last state that got processed. + * + * I.e. when that state is PURCHASE, it means purchasing just happened. + * + * Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. */ + prevState: CorpStateName; /** Array of all division names */ divisions: string[]; } diff --git a/src/utils/DeprecationHelper.ts b/src/utils/DeprecationHelper.ts new file mode 100644 index 000000000..593bc3eff --- /dev/null +++ b/src/utils/DeprecationHelper.ts @@ -0,0 +1,28 @@ +import { Terminal } from "../Terminal"; + +const deprecatedWarningsGiven = new Set(); +export function setDeprecatedProperties( + obj: object, + properties: Record, +) { + for (const [name, info] of Object.entries(properties)) { + Object.defineProperty(obj, name, { + get: () => { + deprecationWarning(info.identifier, info.message); + return info.value; + }, + set: (value: any) => (info.value = value), + enumerable: true, + }); + } +} +export function deprecationWarning(identifier: string, message: string) { + if (!deprecatedWarningsGiven.has(identifier)) { + deprecatedWarningsGiven.add(identifier); + Terminal.warn(`Accessed deprecated function or property: ${identifier}`); + Terminal.warn(`This is no longer supported usage and will be removed in a later version.`); + Terminal.warn(message); + Terminal.info(`This message can also appear for object properties when the object's values are iterated.`); + Terminal.info(`This message will only be shown once per game session for each deprecated item accessed.`); + } +}