diff --git a/src/Constants.ts b/src/Constants.ts index e263a65d7..7db9f67c9 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -224,6 +224,7 @@ export let CONSTANTS: IMap = { v0.47.0 * Stock Market changes: ** Transactions no longer influence stock prices (but they still influence forecast) + ** Changed the way stock's behave, particularly with regard to how the stock forecast occasionally "flips" * Scripts now start/stop instantly * Improved performance when starting up many copies of a new script (by Ornedan) diff --git a/src/Script/Script.ts b/src/Script/Script.ts index 6e11fd08b..7436e93a5 100644 --- a/src/Script/Script.ts +++ b/src/Script/Script.ts @@ -85,6 +85,7 @@ export class Script { */ markUpdated() { this.module = ""; + this.moduleSequenceNumber = ++globalModuleSequenceNumber; } /** @@ -109,12 +110,6 @@ export class Script { } } - // Marks that this script has been updated. Causes recompilation of NS2 modules. - markUpdated() { - this.module = ""; - this.moduleSequenceNumber = ++globalModuleSequenceNumber; - } - /** * Calculates and updates the script's RAM usage based on its code * @param {Script[]} otherScripts - Other scripts on the server. Used to process imports diff --git a/src/Server/data/servers.ts b/src/Server/data/servers.ts index 7d75dcc65..738c1c10f 100644 --- a/src/Server/data/servers.ts +++ b/src/Server/data/servers.ts @@ -2,6 +2,7 @@ // This could actually be a JSON file as it should be constant metadata to be imported... import { IMinMaxRange } from "../../types"; +import { LocationName } from "../../Locations/data/LocationNames"; /** * The metadata describing the base state of servers on the network. @@ -82,7 +83,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 15, numOpenPortsRequired: 5, - organizationName: "ECorp", + organizationName: LocationName.AevumECorp, requiredHackingSkill: { max: 1400, min: 1050, @@ -98,7 +99,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 15, numOpenPortsRequired: 5, - organizationName: "MegaCorp", + organizationName: LocationName.Sector12MegaCorp, requiredHackingSkill: { max: 1350, min: 1100, @@ -117,7 +118,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 14, numOpenPortsRequired: 5, - organizationName: "Bachman & Associates", + organizationName: LocationName.AevumBachmanAndAssociates, requiredHackingSkill: { max: 1150, min: 900, @@ -144,7 +145,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 14, numOpenPortsRequired: 5, - organizationName: "Blade Industries", + organizationName: LocationName.Sector12BladeIndustries, requiredHackingSkill: { max: 1200, min: 900, @@ -164,7 +165,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 14, numOpenPortsRequired: 5, - organizationName: "New World Order", + organizationName: LocationName.VolhavenNWO, requiredHackingSkill: { max: 1300, min: 950, @@ -190,7 +191,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 14, numOpenPortsRequired: 5, - organizationName: "Clarke Incorporated", + organizationName: LocationName.AevumClarkeIncorporated, requiredHackingSkill: { max: 1250, min: 950, @@ -220,7 +221,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 13, numOpenPortsRequired: 5, - organizationName: "OmniTek Incorporated", + organizationName: LocationName.VolhavenOmniTekIncorporated, requiredHackingSkill: { max: 1100, min: 900, @@ -242,7 +243,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 13, numOpenPortsRequired: 5, - organizationName: "FourSigma", + organizationName: LocationName.Sector12FourSigma, requiredHackingSkill: { max: 1250, min: 900, @@ -264,7 +265,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 13, numOpenPortsRequired: 5, - organizationName: "KuaiGong International", + organizationName: LocationName.ChongqingKuaiGongInternational, requiredHackingSkill: { max: 1300, min: 950, @@ -291,7 +292,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 12, numOpenPortsRequired: 5, - organizationName: "Fulcrum Technologies", + organizationName: LocationName.AevumFulcrumTechnologies, requiredHackingSkill: { max: 1250, min: 950, @@ -307,7 +308,7 @@ export const serverMetadata: IServerMetadata[] = [ moneyAvailable: 1e6, networkLayer: 15, numOpenPortsRequired: 5, - organizationName: "Fulcrum Technologies Assets", + organizationName: LocationName.AevumFulcrumTechnologies, requiredHackingSkill: { max: 1600, min: 1100, @@ -327,7 +328,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 12, numOpenPortsRequired: 5, - organizationName: "Storm Technologies", + organizationName: LocationName.IshimaStormTechnologies, requiredHackingSkill: { max: 1075, min: 875, @@ -349,7 +350,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 9, numOpenPortsRequired: 5, - organizationName: "DefComm", + organizationName: LocationName.NewTokyoDefComm, requiredHackingSkill: { max: 1050, min: 850, @@ -398,7 +399,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 12, numOpenPortsRequired: 5, - organizationName: "Helios Labs", + organizationName: LocationName.VolhavenHeliosLabs, requiredHackingSkill: { max: 900, min: 800, @@ -425,7 +426,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 12, numOpenPortsRequired: 5, - organizationName: "VitaLife", + organizationName: LocationName.NewTokyoVitaLife, requiredHackingSkill: { max: 900, min: 775, @@ -447,7 +448,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 9, numOpenPortsRequired: 5, - organizationName: "Icarus Microsystems", + organizationName: LocationName.Sector12IcarusMicrosystems, requiredHackingSkill: { max: 925, min: 850, @@ -473,7 +474,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 9, numOpenPortsRequired: 4, - organizationName: "Universal Energy", + organizationName: LocationName.Sector12UniversalEnergy, requiredHackingSkill: { max: 900, min: 800, @@ -575,7 +576,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 7, numOpenPortsRequired: 5, - organizationName: "Galactic Cybersystems", + organizationName: LocationName.AevumGalacticCybersystems, requiredHackingSkill: { max: 875, min: 825, @@ -598,7 +599,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 7, numOpenPortsRequired: 5, - organizationName: "AeroCorp", + organizationName: LocationName.AevumAeroCorp, requiredHackingSkill: { max: 925, min: 850, @@ -625,7 +626,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 8, numOpenPortsRequired: 5, - organizationName: "Omnia Cybersystems", + organizationName: LocationName.VolhavenOmniaCybersystems, requiredHackingSkill: { max: 950, min: 850, @@ -700,7 +701,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 9, numOpenPortsRequired: 5, - organizationName: "Solaris Space Systems", + organizationName: LocationName.ChongqingSolarisSpaceSystems, requiredHackingSkill: { max: 850, min: 750, @@ -722,7 +723,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 8, numOpenPortsRequired: 5, - organizationName: "Delta One", + organizationName: LocationName.Sector12DeltaOne, requiredHackingSkill: { max: 900, min: 800, @@ -749,7 +750,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 7, numOpenPortsRequired: 4, - organizationName: "Global Pharmaceuticals", + organizationName: LocationName.NewTokyoGlobalPharmaceuticals, requiredHackingSkill: { max: 850, min: 750, @@ -771,7 +772,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 10, numOpenPortsRequired: 4, - organizationName: "Nova Medical", + organizationName: LocationName.IshimaNovaMedical, requiredHackingSkill: { max: 850, min: 775, @@ -845,7 +846,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 6, numOpenPortsRequired: 4, - organizationName: "Lexo Corporation", + organizationName: LocationName.VolhavenLexoCorp, requiredHackingSkill: { max: 750, min: 650, @@ -871,7 +872,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 6, numOpenPortsRequired: 3, - organizationName: "Rho Construction", + organizationName: LocationName.AevumRhoConstruction, requiredHackingSkill: { max: 525, min: 475, @@ -898,7 +899,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 6, numOpenPortsRequired: 4, - organizationName: "Alpha Enterprises", + organizationName: LocationName.Sector12AlphaEnterprises, requiredHackingSkill: { max: 600, min: 500, @@ -924,7 +925,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 6, numOpenPortsRequired: 4, - organizationName: "Aevum Police Network", + organizationName: LocationName.AevumPolice, requiredHackingSkill: { max: 450, min: 400, @@ -955,7 +956,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 5, numOpenPortsRequired: 3, - organizationName: "Rothman University Network", + organizationName: LocationName.Sector12RothmanUniversity, requiredHackingSkill: { max: 430, min: 370, @@ -981,7 +982,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 5, numOpenPortsRequired: 5, - organizationName: "ZB Institute of Technology Network", + organizationName: LocationName.VolhavenZBInstituteOfTechnology, requiredHackingSkill: { max: 775, min: 725, @@ -1012,7 +1013,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 5, numOpenPortsRequired: 3, - organizationName: "Summit University Network", + organizationName: LocationName.AevumSummitUniversity, requiredHackingSkill: { max: 475, min: 425, @@ -1034,7 +1035,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 5, numOpenPortsRequired: 4, - organizationName: "SysCore Securities", + organizationName: LocationName.VolhavenSysCoreSecurities, requiredHackingSkill: { max: 650, min: 550, @@ -1110,7 +1111,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 4, numOpenPortsRequired: 3, - organizationName: "CompuTek", + organizationName: LocationName.VolhavenCompuTek, requiredHackingSkill: { max: 400, min: 300, @@ -1134,7 +1135,7 @@ export const serverMetadata: IServerMetadata[] = [ moneyAvailable: 275000000, networkLayer: 4, numOpenPortsRequired: 3, - organizationName: "Netlink Technologies", + organizationName: LocationName.AevumNetLinkTechnologies, requiredHackingSkill: { max: 425, min: 375, @@ -1174,7 +1175,7 @@ export const serverMetadata: IServerMetadata[] = [ moneyAvailable: 2000000, networkLayer: 1, numOpenPortsRequired: 0, - organizationName: "Food N Stuff Supermarket", + organizationName: LocationName.Sector12FoodNStuff, requiredHackingSkill: 1, serverGrowth: 5, }, @@ -1196,7 +1197,7 @@ export const serverMetadata: IServerMetadata[] = [ moneyAvailable: 2500000, networkLayer: 1, numOpenPortsRequired: 0, - organizationName: "Joe's Guns", + organizationName: "Joes Guns", requiredHackingSkill: 10, serverGrowth: 20, }, @@ -1305,7 +1306,7 @@ export const serverMetadata: IServerMetadata[] = [ }, networkLayer: 3, numOpenPortsRequired: 2, - organizationName: "Omega Software", + organizationName: LocationName.IshimaOmegaSoftware, requiredHackingSkill: { max: 220, min: 180, diff --git a/src/StockMarket/PlayerInfluencing.ts b/src/StockMarket/PlayerInfluencing.ts new file mode 100644 index 000000000..d026263b1 --- /dev/null +++ b/src/StockMarket/PlayerInfluencing.ts @@ -0,0 +1,6 @@ +/** + * Implementation of the mechanisms that allow the player to affect the + * Stock Market + */ +import { Server } from "../Server/Server"; +import { StockMarket } from "./StockMarket"; diff --git a/src/StockMarket/Stock.ts b/src/StockMarket/Stock.ts index 2147b7c16..9fe82eec1 100644 --- a/src/StockMarket/Stock.ts +++ b/src/StockMarket/Stock.ts @@ -226,6 +226,18 @@ export class Stock { } } + /** + * Change's the stock's second-order forecast during a stock market 'tick'. + * The change for the second-order forecast to increase is 50/50 + */ + cycleForecastForecast(changeAmt: number=0.1): void { + if (Math.random() < 0.5) { + this.otlkMagForecast = Math.min(this.otlkMagForecast + changeAmt, 100); + } else { + this.otlkMagForecast = Math.max(this.otlkMagForecast - changeAmt, 0); + } + } + /** * "Flip" the stock's second-order forecast. This can occur during a * stock market "cycle" (determined by RNG). It is used to simulate diff --git a/src/StockMarket/StockMarket.jsx b/src/StockMarket/StockMarket.jsx index 3dd1365a5..8b6993150 100644 --- a/src/StockMarket/StockMarket.jsx +++ b/src/StockMarket/StockMarket.jsx @@ -7,6 +7,7 @@ import { import { Order } from "./Order"; import { processOrders } from "./OrderProcessing"; import { Stock } from "./Stock"; +import { TicksPerCycle } from "./StockMarketConstants"; import { getStockMarket4SDataCost, getStockMarket4STixApiCost @@ -172,6 +173,7 @@ export function initStockMarket() { StockMarket.storedCycles = 0; StockMarket.lastUpdate = 0; + StockMarket.ticksUntilCycle = TicksPerCycle; } export function initSymbolToStockMap() { @@ -192,18 +194,11 @@ export function stockMarketCycle() { for (const name in StockMarket) { const stock = StockMarket[name]; if (!(stock instanceof Stock)) { continue; } - let thresh = 0.6; - if (stock.b) { thresh = 0.4; } + const roll = Math.random(); if (roll < 0.4) { stock.flipForecastForecast(); - } else if (roll < 0.6) { - stock.otlkMagForecast += 0.5; - stock.otlkMagForecast = Math.min(stock.otlkMagForecast * 1.02, 100); - } else if (roll < 0.8) { - stock.otlkMagForecast -= 0.5; - stock.otlkMagForecast = stock.otlkMagForecast * (1 / 1.02); - } else if (roll < 0.9) { + } else if (roll < 0.55) { stock.b = !stock.b; stock.flipForecastForecast(); } @@ -227,6 +222,13 @@ export function processStockPrices(numCycles=1) { StockMarket.lastUpdate = timeNow; StockMarket.storedCycles -= cyclesPerStockUpdate; + // Cycle + --StockMarket.ticksUntilCycle; + if (StockMarket.ticksUntilCycle <= 0) { + stockMarketCycle(); + StockMarket.ticksUntilCycle = TicksPerCycle; + } + var v = Math.random(); for (const name in StockMarket) { const stock = StockMarket[name]; @@ -271,6 +273,7 @@ export function processStockPrices(numCycles=1) { otlkMagChange = 1; } stock.cycleForecast(otlkMagChange); + stock.cycleForecastForecast(otlkMagChange / 2); // Shares required for price movement gradually approaches max over time stock.shareTxUntilMovement = Math.min(stock.shareTxUntilMovement + 10, stock.shareTxForMovement); diff --git a/src/StockMarket/StockMarketConstants.ts b/src/StockMarket/StockMarketConstants.ts new file mode 100644 index 000000000..ce0a6a4ad --- /dev/null +++ b/src/StockMarket/StockMarketConstants.ts @@ -0,0 +1,5 @@ +/** + * How many stock market 'ticks' before a 'cycle' is triggered. + * A 'tick' is whenver stock prices update + */ +export const TicksPerCycle = 100; diff --git a/src/StockMarket/StockMarketHelpers.ts b/src/StockMarket/StockMarketHelpers.ts index cfb37d9c0..c9533cef2 100644 --- a/src/StockMarket/StockMarketHelpers.ts +++ b/src/StockMarket/StockMarketHelpers.ts @@ -1,3 +1,6 @@ +/** + * Stock Market Helper Functions + */ import { Stock } from "./Stock"; import { PositionTypes } from "./data/PositionTypes"; import { CONSTANTS } from "../Constants"; diff --git a/src/engine.jsx b/src/engine.jsx index 20f2ff35b..b5d725494 100644 --- a/src/engine.jsx +++ b/src/engine.jsx @@ -70,7 +70,6 @@ import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags"; import { initSpecialServerIps } from "./Server/SpecialServerIps"; import { initSymbolToStockMap, - stockMarketCycle, processStockPrices, displayStockMarketContent } from "./StockMarket/StockMarket"; @@ -778,7 +777,6 @@ const Engine = { checkFactionInvitations: 100, passiveFactionGrowth: 600, messages: 150, - sCr: 1500, mechanicProcess: 5, // Processes certain mechanics (Corporation, Bladeburner) contractGeneration: 3000, // Generate Coding Contracts }, @@ -901,13 +899,6 @@ const Engine = { } } - if (Engine.Counters.sCr <= 0) { - if (Player.hasWseAccount) { - stockMarketCycle(); - } - Engine.Counters.sCr = 1500; - } - if (Engine.Counters.mechanicProcess <= 0) { if (Player.corporation instanceof Corporation) { Player.corporation.process(); diff --git a/test/StockMarketTests.js b/test/StockMarketTests.js index 93acfeb37..e6bb9d60e 100644 --- a/test/StockMarketTests.js +++ b/test/StockMarketTests.js @@ -308,6 +308,8 @@ describe("Stock Market Tests", function() { expect(StockMarket["storedCycles"]).to.equal(0); expect(StockMarket).to.have.property("lastUpdate"); expect(StockMarket["lastUpdate"]).to.equal(0); + expect(StockMarket).to.have.property("ticksUntilCycle"); + expect(StockMarket["ticksUntilCycle"]).to.be.a("number"); }); });