From 61c311a1267553aa08cc2f074be166c42453e6ef Mon Sep 17 00:00:00 2001 From: Jesse Clark Date: Mon, 23 Oct 2023 01:24:30 -0700 Subject: [PATCH] API: Add `nextUpdate()` promise for systems with bonus time (#845) --- .../bitburner.bladeburner.getbonustime.md | 2 +- markdown/bitburner.bladeburner.getstamina.md | 2 +- .../bitburner.bladeburner.inbladeburner.md | 4 +- ...ner.bladeburner.joinbladeburnerdivision.md | 2 +- ...rner.bladeburner.joinbladeburnerfaction.md | 2 +- markdown/bitburner.bladeburner.md | 13 +- markdown/bitburner.bladeburner.nextupdate.md | 37 ++++++ markdown/bitburner.bladeburner.switchcity.md | 2 +- markdown/bitburner.corporation.md | 1 + markdown/bitburner.corporation.nextupdate.md | 41 ++++++ markdown/bitburner.gang.md | 3 +- markdown/bitburner.gang.nextupdate.md | 37 ++++++ .../bitburner.gang.setterritorywarfare.md | 6 +- markdown/bitburner.ganggeninfo.md | 2 +- ...ner.ganggeninfo.territorywarfareengaged.md | 2 +- markdown/bitburner.tix.getbonustime.md | 27 ++++ markdown/bitburner.tix.md | 2 + markdown/bitburner.tix.nextupdate.md | 35 +++++ src/Bladeburner/Bladeburner.tsx | 7 + src/Corporation/Corporation.ts | 7 + src/Gang/Gang.ts | 8 ++ src/Netscript/RamCostGenerator.ts | 9 +- src/NetscriptFunctions/Bladeburner.ts | 5 +- src/NetscriptFunctions/Corporation.ts | 7 +- src/NetscriptFunctions/Gang.ts | 4 + src/NetscriptFunctions/StockMarket.ts | 17 ++- src/ScriptEditor/NetscriptDefinitions.d.ts | 120 +++++++++++++++++- src/StockMarket/StockMarket.tsx | 7 + tsdoc-metadata.json | 2 +- 29 files changed, 382 insertions(+), 31 deletions(-) create mode 100644 markdown/bitburner.bladeburner.nextupdate.md create mode 100644 markdown/bitburner.corporation.nextupdate.md create mode 100644 markdown/bitburner.gang.nextupdate.md create mode 100644 markdown/bitburner.tix.getbonustime.md create mode 100644 markdown/bitburner.tix.nextupdate.md diff --git a/markdown/bitburner.bladeburner.getbonustime.md b/markdown/bitburner.bladeburner.getbonustime.md index 855575319..0759c62fb 100644 --- a/markdown/bitburner.bladeburner.getbonustime.md +++ b/markdown/bitburner.bladeburner.getbonustime.md @@ -4,7 +4,7 @@ ## Bladeburner.getBonusTime() method -Get bladeburner bonus time. +Get Bladeburner bonus time. **Signature:** diff --git a/markdown/bitburner.bladeburner.getstamina.md b/markdown/bitburner.bladeburner.getstamina.md index e0649beb6..2532ae288 100644 --- a/markdown/bitburner.bladeburner.getstamina.md +++ b/markdown/bitburner.bladeburner.getstamina.md @@ -4,7 +4,7 @@ ## Bladeburner.getStamina() method -Get bladeburner stamina. +Get Bladeburner stamina. **Signature:** diff --git a/markdown/bitburner.bladeburner.inbladeburner.md b/markdown/bitburner.bladeburner.inbladeburner.md index 39bc9acff..a2d36ba10 100644 --- a/markdown/bitburner.bladeburner.inbladeburner.md +++ b/markdown/bitburner.bladeburner.inbladeburner.md @@ -4,7 +4,7 @@ ## Bladeburner.inBladeburner() method -Returns whether player is a member of bladeburner division. Does not require API access. +Returns whether player is a member of Bladeburner division. Does not require API access. **Signature:** @@ -15,7 +15,7 @@ inBladeburner(): boolean; boolean -whether player is a member of bladeburner division. +whether player is a member of Bladeburner division. ## Remarks diff --git a/markdown/bitburner.bladeburner.joinbladeburnerdivision.md b/markdown/bitburner.bladeburner.joinbladeburnerdivision.md index 80d22978e..7374cf79e 100644 --- a/markdown/bitburner.bladeburner.joinbladeburnerdivision.md +++ b/markdown/bitburner.bladeburner.joinbladeburnerdivision.md @@ -4,7 +4,7 @@ ## Bladeburner.joinBladeburnerDivision() method -Join the bladeburner division. +Join the Bladeburner division. **Signature:** diff --git a/markdown/bitburner.bladeburner.joinbladeburnerfaction.md b/markdown/bitburner.bladeburner.joinbladeburnerfaction.md index 2c13da424..95cd1545d 100644 --- a/markdown/bitburner.bladeburner.joinbladeburnerfaction.md +++ b/markdown/bitburner.bladeburner.joinbladeburnerfaction.md @@ -4,7 +4,7 @@ ## Bladeburner.joinBladeburnerFaction() method -Join the bladeburner faction. +Join the Bladeburner faction. **Signature:** diff --git a/markdown/bitburner.bladeburner.md b/markdown/bitburner.bladeburner.md index 066bbd5bc..25d08d6ff 100644 --- a/markdown/bitburner.bladeburner.md +++ b/markdown/bitburner.bladeburner.md @@ -31,7 +31,7 @@ You have to be employed in the Bladeburner division and be in BitNode-7 or have | [getActionTime(type, name)](./bitburner.bladeburner.getactiontime.md) | Get the time to complete an action. | | [getBlackOpNames()](./bitburner.bladeburner.getblackopnames.md) | List all black ops. | | [getBlackOpRank(name)](./bitburner.bladeburner.getblackoprank.md) | Get black op required rank. | -| [getBonusTime()](./bitburner.bladeburner.getbonustime.md) | Get bladeburner bonus time. | +| [getBonusTime()](./bitburner.bladeburner.getbonustime.md) | Get Bladeburner bonus time. | | [getCity()](./bitburner.bladeburner.getcity.md) | Get current city. | | [getCityChaos(city)](./bitburner.bladeburner.getcitychaos.md) | Get chaos of a city. | | [getCityCommunities(city)](./bitburner.bladeburner.getcitycommunities.md) | Get number of communities in a city. | @@ -46,16 +46,17 @@ You have to be employed in the Bladeburner division and be in BitNode-7 or have | [getSkillNames()](./bitburner.bladeburner.getskillnames.md) | List all skills. | | [getSkillPoints()](./bitburner.bladeburner.getskillpoints.md) | Get bladeburner skill points. | | [getSkillUpgradeCost(skillName, count)](./bitburner.bladeburner.getskillupgradecost.md) | Get cost to upgrade skill. | -| [getStamina()](./bitburner.bladeburner.getstamina.md) | Get bladeburner stamina. | +| [getStamina()](./bitburner.bladeburner.getstamina.md) | Get Bladeburner stamina. | | [getTeamSize(type, name)](./bitburner.bladeburner.getteamsize.md) | Get team size. | -| [inBladeburner()](./bitburner.bladeburner.inbladeburner.md) | Returns whether player is a member of bladeburner division. Does not require API access. | -| [joinBladeburnerDivision()](./bitburner.bladeburner.joinbladeburnerdivision.md) | Join the bladeburner division. | -| [joinBladeburnerFaction()](./bitburner.bladeburner.joinbladeburnerfaction.md) | Join the bladeburner faction. | +| [inBladeburner()](./bitburner.bladeburner.inbladeburner.md) | Returns whether player is a member of Bladeburner division. Does not require API access. | +| [joinBladeburnerDivision()](./bitburner.bladeburner.joinbladeburnerdivision.md) | Join the Bladeburner division. | +| [joinBladeburnerFaction()](./bitburner.bladeburner.joinbladeburnerfaction.md) | Join the Bladeburner faction. | +| [nextUpdate()](./bitburner.bladeburner.nextupdate.md) | Sleep until the next Bladeburner update has happened. | | [setActionAutolevel(type, name, autoLevel)](./bitburner.bladeburner.setactionautolevel.md) | Set an action autolevel. | | [setActionLevel(type, name, level)](./bitburner.bladeburner.setactionlevel.md) | Set the level of an action. | | [setTeamSize(type, name, size)](./bitburner.bladeburner.setteamsize.md) | Set team size. | | [startAction(type, name)](./bitburner.bladeburner.startaction.md) | Start an action. | | [stopBladeburnerAction()](./bitburner.bladeburner.stopbladeburneraction.md) | Stop current action. | -| [switchCity(city)](./bitburner.bladeburner.switchcity.md) | Travel to another city in bladeburner. | +| [switchCity(city)](./bitburner.bladeburner.switchcity.md) | Travel to another city in Bladeburner. | | [upgradeSkill(skillName, count)](./bitburner.bladeburner.upgradeskill.md) | Upgrade skill. | diff --git a/markdown/bitburner.bladeburner.nextupdate.md b/markdown/bitburner.bladeburner.nextupdate.md new file mode 100644 index 000000000..19c29f394 --- /dev/null +++ b/markdown/bitburner.bladeburner.nextupdate.md @@ -0,0 +1,37 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [Bladeburner](./bitburner.bladeburner.md) > [nextUpdate](./bitburner.bladeburner.nextupdate.md) + +## Bladeburner.nextUpdate() method + +Sleep until the next Bladeburner update has happened. + +**Signature:** + +```typescript +nextUpdate(): Promise; +``` +**Returns:** + +Promise<number> + +Promise that resolves to the number of milliseconds of Bladeburner time that were processed in the previous update (1000 - 5000 ms). + +## Remarks + +RAM cost: 1 GB + +The amount of real time spent asleep between updates can vary due to "bonus time" (usually 1 second). + +## Example + + +```js +while (true) { + const duration = await ns.bladeburner.nextUpdate(); + ns.print(`Bladeburner Division completed ${ns.tFormat(duration)} of actions.`); + ns.print(`Bonus time remaining: ${ns.tFormat(ns.bladeburner.getBonusTime())}`); + // Manage the Bladeburner division +} +``` + diff --git a/markdown/bitburner.bladeburner.switchcity.md b/markdown/bitburner.bladeburner.switchcity.md index 71afd93b8..c27d2786e 100644 --- a/markdown/bitburner.bladeburner.switchcity.md +++ b/markdown/bitburner.bladeburner.switchcity.md @@ -4,7 +4,7 @@ ## Bladeburner.switchCity() method -Travel to another city in bladeburner. +Travel to another city in Bladeburner. **Signature:** diff --git a/markdown/bitburner.corporation.md b/markdown/bitburner.corporation.md index 36c5d6a25..7b34ad02e 100644 --- a/markdown/bitburner.corporation.md +++ b/markdown/bitburner.corporation.md @@ -39,6 +39,7 @@ export interface Corporation extends WarehouseAPI, OfficeAPI | [issueDividends(rate)](./bitburner.corporation.issuedividends.md) | Issue dividends | | [issueNewShares(amount)](./bitburner.corporation.issuenewshares.md) | Issue new shares | | [levelUpgrade(upgradeName)](./bitburner.corporation.levelupgrade.md) | Level an upgrade. | +| [nextUpdate()](./bitburner.corporation.nextupdate.md) | Sleep until the next Corporation update has happened. | | [purchaseUnlock(upgradeName)](./bitburner.corporation.purchaseunlock.md) | Unlock an upgrade | | [sellShares(amount)](./bitburner.corporation.sellshares.md) | Sell Shares. Transfer shares from the CEO to public traders to receive money in the player's wallet. | diff --git a/markdown/bitburner.corporation.nextupdate.md b/markdown/bitburner.corporation.nextupdate.md new file mode 100644 index 000000000..2f05955f1 --- /dev/null +++ b/markdown/bitburner.corporation.nextupdate.md @@ -0,0 +1,41 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [Corporation](./bitburner.corporation.md) > [nextUpdate](./bitburner.corporation.nextupdate.md) + +## Corporation.nextUpdate() method + +Sleep until the next Corporation update has happened. + +**Signature:** + +```typescript +nextUpdate(): Promise; +``` +**Returns:** + +Promise<[CorpStateName](./bitburner.corpstatename.md)> + +Promise that resolves to the name of the state that was just processed. + +I.e. when the state is PURCHASE, it means purchasing has just happened. Note that this is the state just before `getCorporation().state`. + +Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. + +## Remarks + +RAM cost: 1 GB + +The amount of real time spent asleep between updates can vary due to "bonus time" (usually 200 milliseconds - 2 seconds). + +## Example + + +```js +while (true) { + const prevState = await ns.corporation.nextUpdate(); + const nextState = ns.corporation.getCorporation().state; + ns.print(`Corporation finished with ${prevState}, next will be ${nextState}.`); + // Manage the Corporation +} +``` + diff --git a/markdown/bitburner.gang.md b/markdown/bitburner.gang.md index 77c09e7fe..8d91a2a18 100644 --- a/markdown/bitburner.gang.md +++ b/markdown/bitburner.gang.md @@ -38,10 +38,11 @@ If you are not in BitNode-2, then you must have Source-File 2 in order to use th | [getTaskNames()](./bitburner.gang.gettasknames.md) | List member task names. | | [getTaskStats(name)](./bitburner.gang.gettaskstats.md) | Get stats of a task. | | [inGang()](./bitburner.gang.ingang.md) | Check if you're in a gang. | +| [nextUpdate()](./bitburner.gang.nextupdate.md) | Sleeps until the next Gang update has happened. | | [purchaseEquipment(memberName, equipName)](./bitburner.gang.purchaseequipment.md) | Purchase an equipment for a gang member. | | [recruitMember(name)](./bitburner.gang.recruitmember.md) | Recruit a new gang member. | | [renameMember(memberName, newName)](./bitburner.gang.renamemember.md) | Rename a Gang member to a new unique name. | | [respectForNextRecruit()](./bitburner.gang.respectfornextrecruit.md) | Check the amount of Respect needed for your next gang recruit. | | [setMemberTask(memberName, taskName)](./bitburner.gang.setmembertask.md) | Set gang member to task. | -| [setTerritoryWarfare(engage)](./bitburner.gang.setterritorywarfare.md) | Enable/Disable territory warfare. | +| [setTerritoryWarfare(engage)](./bitburner.gang.setterritorywarfare.md) | Enable/Disable territory clashes. | diff --git a/markdown/bitburner.gang.nextupdate.md b/markdown/bitburner.gang.nextupdate.md new file mode 100644 index 000000000..e3b3aedf2 --- /dev/null +++ b/markdown/bitburner.gang.nextupdate.md @@ -0,0 +1,37 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [Gang](./bitburner.gang.md) > [nextUpdate](./bitburner.gang.nextupdate.md) + +## Gang.nextUpdate() method + +Sleeps until the next Gang update has happened. + +**Signature:** + +```typescript +nextUpdate(): Promise; +``` +**Returns:** + +Promise<number> + +Promise that resolves to the number of milliseconds of Gang time that were processed in the previous update (2000 - 5000 ms). + +## Remarks + +RAM cost: 1 GB + +The amount of real time spent asleep between updates can vary due to "bonus time". + +## Example + + +```js +while (true) { + const duration = await ns.gang.nextUpdate(); + ns.print(`Gang completed ${ns.tFormat(duration)} of activity.`); + ns.print(`Bonus time remaining: ${ns.tFormat(ns.gang.getBonusTime())}`); + // Manage the Gang +} +``` + diff --git a/markdown/bitburner.gang.setterritorywarfare.md b/markdown/bitburner.gang.setterritorywarfare.md index 70e3f0c39..7ef407b19 100644 --- a/markdown/bitburner.gang.setterritorywarfare.md +++ b/markdown/bitburner.gang.setterritorywarfare.md @@ -4,7 +4,7 @@ ## Gang.setTerritoryWarfare() method -Enable/Disable territory warfare. +Enable/Disable territory clashes. **Signature:** @@ -16,7 +16,7 @@ setTerritoryWarfare(engage: boolean): void; | Parameter | Type | Description | | --- | --- | --- | -| engage | boolean | Whether or not to engage in territory warfare. | +| engage | boolean | Whether or not to engage in territory clashes. | **Returns:** @@ -26,5 +26,5 @@ void RAM cost: 2 GB -Set whether or not the gang should engage in territory warfare +Set whether or not the gang should engage in territory clashes diff --git a/markdown/bitburner.ganggeninfo.md b/markdown/bitburner.ganggeninfo.md index 95b53c90d..a2653b22a 100644 --- a/markdown/bitburner.ganggeninfo.md +++ b/markdown/bitburner.ganggeninfo.md @@ -25,7 +25,7 @@ interface GangGenInfo | [respectGainRate](./bitburner.ganggeninfo.respectgainrate.md) | | number | Respect earned per game cycle | | [territory](./bitburner.ganggeninfo.territory.md) | | number | Amount of territory held | | [territoryClashChance](./bitburner.ganggeninfo.territoryclashchance.md) | | number | Clash chance | -| [territoryWarfareEngaged](./bitburner.ganggeninfo.territorywarfareengaged.md) | | boolean | Indicating if territory warfare is enabled | +| [territoryWarfareEngaged](./bitburner.ganggeninfo.territorywarfareengaged.md) | | boolean | Indicating if territory clashes are enabled | | [wantedLevel](./bitburner.ganggeninfo.wantedlevel.md) | | number | Gang's wanted level | | [wantedLevelGainRate](./bitburner.ganggeninfo.wantedlevelgainrate.md) | | number | Wanted level gained/lost per game cycle (negative for losses) | | [wantedPenalty](./bitburner.ganggeninfo.wantedpenalty.md) | | number | Number indicating the current wanted penalty | diff --git a/markdown/bitburner.ganggeninfo.territorywarfareengaged.md b/markdown/bitburner.ganggeninfo.territorywarfareengaged.md index 7582ebf7a..42036abf1 100644 --- a/markdown/bitburner.ganggeninfo.territorywarfareengaged.md +++ b/markdown/bitburner.ganggeninfo.territorywarfareengaged.md @@ -4,7 +4,7 @@ ## GangGenInfo.territoryWarfareEngaged property -Indicating if territory warfare is enabled +Indicating if territory clashes are enabled **Signature:** diff --git a/markdown/bitburner.tix.getbonustime.md b/markdown/bitburner.tix.getbonustime.md new file mode 100644 index 000000000..49219d821 --- /dev/null +++ b/markdown/bitburner.tix.getbonustime.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [TIX](./bitburner.tix.md) > [getBonusTime](./bitburner.tix.getbonustime.md) + +## TIX.getBonusTime() method + +Get Stock Market bonus time. + +**Signature:** + +```typescript +getBonusTime(): number; +``` +**Returns:** + +number + +Amount of accumulated “bonus time” (milliseconds) for the Stock Market mechanic. + +## Remarks + +RAM cost: 0 GB + +“Bonus time” is accumulated when the game is offline or if the game is inactive in the browser. + +Stock Market prices update more frequently during “bonus time”. + diff --git a/markdown/bitburner.tix.md b/markdown/bitburner.tix.md index d63d7d7d8..69211d109 100644 --- a/markdown/bitburner.tix.md +++ b/markdown/bitburner.tix.md @@ -21,6 +21,7 @@ export interface TIX | [cancelOrder(sym, shares, price, type, pos)](./bitburner.tix.cancelorder.md) | Cancel order for stocks. | | [getAskPrice(sym)](./bitburner.tix.getaskprice.md) | Returns the ask price of that stock. | | [getBidPrice(sym)](./bitburner.tix.getbidprice.md) | Returns the bid price of that stock. | +| [getBonusTime()](./bitburner.tix.getbonustime.md) | Get Stock Market bonus time. | | [getConstants()](./bitburner.tix.getconstants.md) | Get game constants for the stock market mechanic. | | [getForecast(sym)](./bitburner.tix.getforecast.md) | Returns the probability that the specified stock’s price will increase (as opposed to decrease) during the next tick. | | [getMaxShares(sym)](./bitburner.tix.getmaxshares.md) | Returns the maximum number of shares of a stock. | @@ -36,6 +37,7 @@ export interface TIX | [has4SDataTIXAPI()](./bitburner.tix.has4sdatatixapi.md) | Returns true if the player has access to the 4SData TIX API | | [hasTIXAPIAccess()](./bitburner.tix.hastixapiaccess.md) | Returns true if the player has access to the TIX API | | [hasWSEAccount()](./bitburner.tix.haswseaccount.md) | Returns true if the player has access to a WSE Account | +| [nextUpdate()](./bitburner.tix.nextupdate.md) | Sleep until the next Stock Market price update has happened. | | [placeOrder(sym, shares, price, type, pos)](./bitburner.tix.placeorder.md) | Place order for stocks. | | [purchase4SMarketData()](./bitburner.tix.purchase4smarketdata.md) | Purchase 4S Market Data Access. | | [purchase4SMarketDataTixApi()](./bitburner.tix.purchase4smarketdatatixapi.md) | Purchase 4S Market Data TIX API Access. | diff --git a/markdown/bitburner.tix.nextupdate.md b/markdown/bitburner.tix.nextupdate.md new file mode 100644 index 000000000..d5802864b --- /dev/null +++ b/markdown/bitburner.tix.nextupdate.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [bitburner](./bitburner.md) > [TIX](./bitburner.tix.md) > [nextUpdate](./bitburner.tix.nextupdate.md) + +## TIX.nextUpdate() method + +Sleep until the next Stock Market price update has happened. + +**Signature:** + +```typescript +nextUpdate(): Promise; +``` +**Returns:** + +Promise<number> + +Promise that resolves to the number of milliseconds of Stock Market time that were processed in the previous update (always 6000 ms). + +## Remarks + +RAM cost: 1 GB + +The amount of real time spent asleep between updates can vary due to "bonus time" (usually 4 seconds - 6 seconds). + +## Example + + +```js +while (true) { + await ns.stock.nextUpdate(); + // Manage your stock portfolio +} +``` + diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 2a05a89a2..70a31c916 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -43,6 +43,8 @@ export interface BlackOpsAttempt { action?: BlackOperation; } +export const BladeburnerResolvers: ((msProcessed: number) => void)[] = []; + export class Bladeburner { numHosp = 0; moneyLost = 0; @@ -2062,6 +2064,11 @@ export class Bladeburner { } } } + + // Handle "nextUpdate" resolvers after this update + for (const resolve of BladeburnerResolvers.splice(0)) { + resolve(seconds * 1000); + } } } diff --git a/src/Corporation/Corporation.ts b/src/Corporation/Corporation.ts index 04ed7d35a..0e6b569af 100644 --- a/src/Corporation/Corporation.ts +++ b/src/Corporation/Corporation.ts @@ -19,6 +19,8 @@ import { formatMoney } from "../ui/formatNumber"; import { isPositiveInteger } from "../types"; import { createEnumKeyedRecord, getRecordValues } from "../Types/Record"; +export const CorporationResolvers: ((prevState: CorpStateName) => void)[] = []; + interface IParams { name?: string; seedFunded?: boolean; @@ -170,6 +172,11 @@ export class Corporation { } this.state.nextState(); + + // Handle "nextUpdate" resolvers after this update + for (const resolve of CorporationResolvers.splice(0)) { + resolve(state); + } } } diff --git a/src/Gang/Gang.ts b/src/Gang/Gang.ts index 649e4ecb0..c6b069da4 100644 --- a/src/Gang/Gang.ts +++ b/src/Gang/Gang.ts @@ -24,6 +24,9 @@ import { WorkerScript } from "../Netscript/WorkerScript"; import { Player } from "@player"; import { PowerMultiplier } from "./data/power"; import { FactionName } from "@enums"; +import { CONSTANTS } from "../Constants"; + +export const GangResolvers: ((msProcessed: number) => void)[] = []; export class Gang { facName: FactionName; @@ -102,6 +105,11 @@ export class Gang { } catch (e: unknown) { console.error(`Exception caught when processing Gang: ${e}`); } + + // Handle "nextUpdate" resolvers after this update + for (const resolve of GangResolvers.splice(0)) { + resolve(cycles * CONSTANTS.MilliPerCycle); + } } /** Process respect/wanted/money gains diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index bc68d374c..f39ee4376 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -80,6 +80,8 @@ export const RamCostConstants = { InfiltrationGetLocations: 5, InfiltrationGetInfiltrations: 15, StanekAcceptGift: 2, + + CycleTiming: 1, }; function SF4Cost(cost: number): () => number { @@ -124,6 +126,8 @@ const stock = { hasTIXAPIAccess: 0.05, has4SData: 0.05, has4SDataTIXAPI: 0.05, + getBonusTime: 0, + nextUpdate: RamCostConstants.CycleTiming, getSymbols: RamCostConstants.GetStock, getPrice: RamCostConstants.GetStock, getOrganization: RamCostConstants.GetStock, @@ -235,6 +239,7 @@ const gang = { setTerritoryWarfare: RamCostConstants.GangApiBase / 2, getChanceToWinClash: RamCostConstants.GangApiBase, getBonusTime: 0, + nextUpdate: RamCostConstants.CycleTiming, } as const; // Bladeburner API @@ -277,6 +282,7 @@ const bladeburner = { joinBladeburnerFaction: RamCostConstants.BladeburnerApiBase, joinBladeburnerDivision: RamCostConstants.BladeburnerApiBase, getBonusTime: 0, + nextUpdate: RamCostConstants.CycleTiming, } as const; const infiltration = { @@ -356,6 +362,8 @@ const grafting = { const corporation = { hasCorporation: 0, // This one is free getConstants: 0, + getBonusTime: 0, + nextUpdate: RamCostConstants.CycleTiming, getIndustryData: RamCostConstants.CorporationInfo, getMaterialData: RamCostConstants.CorporationInfo, issueNewShares: RamCostConstants.CorporationAction, @@ -377,7 +385,6 @@ const corporation = { issueDividends: RamCostConstants.CorporationAction, buyBackShares: RamCostConstants.CorporationAction, sellShares: RamCostConstants.CorporationAction, - getBonusTime: 0, sellMaterial: RamCostConstants.CorporationAction, sellProduct: RamCostConstants.CorporationAction, discontinueProduct: RamCostConstants.CorporationAction, diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts index 2e798ccac..7d293a4d8 100644 --- a/src/NetscriptFunctions/Bladeburner.ts +++ b/src/NetscriptFunctions/Bladeburner.ts @@ -3,7 +3,7 @@ import type { Action } from "../Bladeburner/Action"; import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { Player } from "@player"; -import { Bladeburner } from "../Bladeburner/Bladeburner"; +import { Bladeburner, BladeburnerResolvers } from "../Bladeburner/Bladeburner"; import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { BlackOperation } from "../Bladeburner/BlackOperation"; import { helpers } from "../Netscript/NetscriptHelpers"; @@ -329,5 +329,8 @@ export function NetscriptBladeburner(): InternalAPI { const bladeburner = getBladeburner(ctx); return Math.round(bladeburner.storedCycles / 5) * 1000; }, + nextUpdate: () => () => { + return new Promise((res) => BladeburnerResolvers.push(res)); + }, }; } diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 8e509f4b2..09253c295 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -5,7 +5,7 @@ import { Product } from "../Corporation/Product"; import { Material } from "../Corporation/Material"; import { Warehouse } from "../Corporation/Warehouse"; import { Division } from "../Corporation/Division"; -import { Corporation } from "../Corporation/Corporation"; +import { Corporation, CorporationResolvers } from "../Corporation/Corporation"; import { cloneDeep, omit } from "lodash"; import { @@ -15,6 +15,7 @@ import { OfficeAPI, CorpResearchName, CorpMaterialName, + CorpStateName, } from "@nsdefs"; import { @@ -787,6 +788,10 @@ export function NetscriptCorporation(): InternalAPI { checkAccess(ctx); return Math.round(getCorporation().storedCycles / 5) * 1000; }, + nextUpdate: (ctx) => () => { + checkAccess(ctx); + return new Promise((res) => CorporationResolvers.push(res)); + }, }; // Removed functions diff --git a/src/NetscriptFunctions/Gang.ts b/src/NetscriptFunctions/Gang.ts index 35e91d93e..bdbce7e63 100644 --- a/src/NetscriptFunctions/Gang.ts +++ b/src/NetscriptFunctions/Gang.ts @@ -4,6 +4,7 @@ import type { GangMember } from "../Gang/GangMember"; import type { GangMemberTask } from "../Gang/GangMemberTask"; import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; +import { GangResolvers } from "../Gang/Gang"; import { Player } from "@player"; import { FactionName } from "@enums"; import { GangConstants } from "../Gang/data/Constants"; @@ -323,5 +324,8 @@ export function NetscriptGang(): InternalAPI { const gang = getGang(ctx); return Math.round(gang.storedCycles / 5) * 1000; }, + nextUpdate: () => () => { + return new Promise((res) => GangResolvers.push(res)); + }, }; } diff --git a/src/NetscriptFunctions/StockMarket.ts b/src/NetscriptFunctions/StockMarket.ts index 9d4bda3f5..058154ff3 100644 --- a/src/NetscriptFunctions/StockMarket.ts +++ b/src/NetscriptFunctions/StockMarket.ts @@ -1,6 +1,13 @@ import { Player } from "../Player"; import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling"; -import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder, initStockMarket } from "../StockMarket/StockMarket"; +import { + StockMarket, + SymbolToStockMap, + placeOrder, + cancelOrder, + initStockMarket, + StockMarketResolvers, +} from "../StockMarket/StockMarket"; import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers"; import { PositionType, OrderType, StockSymbol } from "@enums"; import { @@ -403,5 +410,13 @@ export function NetscriptStockMarket(): InternalAPI { helpers.log(ctx, () => "Purchased TIX API"); return true; }, + getBonusTime: (ctx) => () => { + checkTixApiAccess(ctx); + return Math.round(StockMarket.storedCycles / 5) * 1000; + }, + nextUpdate: (ctx) => () => { + checkTixApiAccess(ctx); + return new Promise((res) => StockMarketResolvers.push(res)); + }, }; } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 5c6393378..d2771ee22 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -1537,6 +1537,40 @@ export interface TIX { * @returns True if you successfully purchased it or if you already have access, false otherwise. */ purchaseTixApi(): boolean; + + /** + * Get Stock Market bonus time. + * @remarks + * RAM cost: 0 GB + * + * “Bonus time” is accumulated when the game is offline or if the game is inactive in the browser. + * + * Stock Market prices update more frequently during “bonus time”. + * + * @returns Amount of accumulated “bonus time” (milliseconds) for the Stock Market mechanic. + */ + getBonusTime(): number; + + /** + * Sleep until the next Stock Market price update has happened. + * @remarks + * RAM cost: 1 GB + * + * The amount of real time spent asleep between updates can vary due to "bonus time" + * (usually 4 seconds - 6 seconds). + * + * @returns Promise that resolves to the number of milliseconds of Stock Market time + * that were processed in the previous update (always 6000 ms). + * + * @example + * ```js + * while (true) { + * await ns.stock.nextUpdate(); + * // Manage your stock portfolio + * } + * ``` + */ + nextUpdate(): Promise; } /** @@ -3199,7 +3233,7 @@ export interface Bladeburner { getCity(): CityName; /** - * Travel to another city in bladeburner. + * Travel to another city in Bladeburner. * @remarks * RAM cost: 4 GB * Attempts to switch to the specified city (for Bladeburner only). @@ -3212,7 +3246,7 @@ export interface Bladeburner { switchCity(city: CityName | `${CityName}`): boolean; /** - * Get bladeburner stamina. + * Get Bladeburner stamina. * @remarks * RAM cost: 4 GB * Returns an array with two elements: @@ -3229,7 +3263,7 @@ export interface Bladeburner { getStamina(): [number, number]; /** - * Join the bladeburner faction. + * Join the Bladeburner faction. * @remarks * RAM cost: 4 GB * Attempts to join the Bladeburner faction. @@ -3243,7 +3277,7 @@ export interface Bladeburner { joinBladeburnerFaction(): boolean; /** - * Join the bladeburner division. + * Join the Bladeburner division. * @remarks * RAM cost: 4 GB * @@ -3258,7 +3292,7 @@ export interface Bladeburner { joinBladeburnerDivision(): boolean; /** - * Get bladeburner bonus time. + * Get Bladeburner bonus time. * @remarks * RAM cost: 0 GB * @@ -3274,11 +3308,34 @@ export interface Bladeburner { */ getBonusTime(): number; - /** Returns whether player is a member of bladeburner division. Does not require API access. + /** + * Sleep until the next Bladeburner update has happened. * @remarks * RAM cost: 1 GB * - * @returns whether player is a member of bladeburner division. */ + * The amount of real time spent asleep between updates can vary due to "bonus time" + * (usually 1 second). + * + * @returns Promise that resolves to the number of milliseconds of Bladeburner time + * that were processed in the previous update (1000 - 5000 ms). + * + * @example + * ```js + * while (true) { + * const duration = await ns.bladeburner.nextUpdate(); + * ns.print(`Bladeburner Division completed ${ns.tFormat(duration)} of actions.`); + * ns.print(`Bonus time remaining: ${ns.tFormat(ns.bladeburner.getBonusTime())}`); + * // Manage the Bladeburner division + * } + * ``` + */ + nextUpdate(): Promise; + + /** Returns whether player is a member of Bladeburner division. Does not require API access. + * @remarks + * RAM cost: 1 GB + * + * @returns whether player is a member of Bladeburner division. */ inBladeburner(): boolean; } @@ -3681,6 +3738,28 @@ export interface Gang { * @returns Bonus time for the Gang mechanic in milliseconds. */ getBonusTime(): number; + + /** + * Sleeps until the next Gang update has happened. + * @remarks + * RAM cost: 1 GB + * + * The amount of real time spent asleep between updates can vary due to "bonus time". + * + * @returns Promise that resolves to the number of milliseconds of Gang time + * that were processed in the previous update (2000 - 5000 ms). + * + * @example + * ```js + * while (true) { + * const duration = await ns.gang.nextUpdate(); + * ns.print(`Gang completed ${ns.tFormat(duration)} of activity.`); + * ns.print(`Bonus time remaining: ${ns.tFormat(ns.gang.getBonusTime())}`); + * // Manage the Gang + * } + * ``` + */ + nextUpdate(): Promise; } /** @@ -7490,6 +7569,33 @@ export interface Corporation extends WarehouseAPI, OfficeAPI { * “Bonus time” makes the game progress faster. * @returns Bonus time for the Corporation mechanic in milliseconds. */ getBonusTime(): number; + + /** + * Sleep until the next Corporation update has happened. + * @remarks + * RAM cost: 1 GB + * + * The amount of real time spent asleep between updates can vary due to "bonus time" + * (usually 200 milliseconds - 2 seconds). + * + * @returns Promise that resolves to the name of the state that was just processed. + * + * I.e. when the state is PURCHASE, it means purchasing has just happened. + * Note that this is the state just before `getCorporation().state`. + * + * Possible states are START, PURCHASE, PRODUCTION, EXPORT, SALE. + * + * @example + * ```js + * while (true) { + * const prevState = await ns.corporation.nextUpdate(); + * const nextState = ns.corporation.getCorporation().state; + * ns.print(`Corporation finished with ${prevState}, next will be ${nextState}.`); + * // Manage the Corporation + * } + * ``` + */ + nextUpdate(): Promise; } /** Product rating information diff --git a/src/StockMarket/StockMarket.tsx b/src/StockMarket/StockMarket.tsx index 6d6c192f5..e2df7fcde 100644 --- a/src/StockMarket/StockMarket.tsx +++ b/src/StockMarket/StockMarket.tsx @@ -24,6 +24,8 @@ export let StockMarket: IStockMarket = { // Gross type, needs to be addressed export const SymbolToStockMap: Record = {}; // Maps symbol -> Stock object +export const StockMarketResolvers: ((msProcessed: number) => void)[] = []; + export function placeOrder( stock: Stock, shares: number, @@ -277,4 +279,9 @@ export function processStockPrices(numCycles = 1): void { // Shares required for price movement gradually approaches max over time stock.shareTxUntilMovement = Math.min(stock.shareTxUntilMovement + 10, stock.shareTxForMovement); } + + // Handle "nextUpdate" resolvers after this update + for (const resolve of StockMarketResolvers.splice(0)) { + resolve(StockMarketConstants.msPerStockUpdate); + } } diff --git a/tsdoc-metadata.json b/tsdoc-metadata.json index 2546fe8a0..2086a9cbd 100644 --- a/tsdoc-metadata.json +++ b/tsdoc-metadata.json @@ -5,7 +5,7 @@ "toolPackages": [ { "packageName": "@microsoft/api-extractor", - "packageVersion": "7.34.2" + "packageVersion": "7.38.0" } ] }