mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-06 15:47:52 +02:00
DNET: Cache reward fixes (#2731)
This commit is contained in:
committed by
GitHub
parent
530392eeee
commit
15a67d0156
@@ -12,6 +12,7 @@ import type { DarknetServer } from "../../Server/DarknetServer";
|
|||||||
import { resolveCacheFilePath } from "../../Paths/CacheFilePath";
|
import { resolveCacheFilePath } from "../../Paths/CacheFilePath";
|
||||||
import type { CacheResult } from "@nsdefs";
|
import type { CacheResult } from "@nsdefs";
|
||||||
import { addClue, cctCooldownReached } from "./effects";
|
import { addClue, cctCooldownReached } from "./effects";
|
||||||
|
import { getBitNodeMultipliers } from "../../BitNode/BitNode";
|
||||||
|
|
||||||
export const generateCacheFilename = (isPhishingCache: boolean, prefix?: string) => {
|
export const generateCacheFilename = (isPhishingCache: boolean, prefix?: string) => {
|
||||||
const filenamePrefix = prefix ?? cachePrefixes[Math.floor(Math.random() * cachePrefixes.length)];
|
const filenamePrefix = prefix ?? cachePrefixes[Math.floor(Math.random() * cachePrefixes.length)];
|
||||||
@@ -41,11 +42,15 @@ export const getRewardFromCache = (server: DarknetServer, cacheName: string, sup
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const rewards = [getMoneyReward, getProgramAndStockMarketRelatedRewards, getStockReward, getDataFileReward];
|
const rewards = [getProgramAndStockMarketRelatedRewards, getStockReward, getDataFileReward];
|
||||||
if (cacheName.endsWith(".d.cache")) {
|
if (cacheName.endsWith(".d.cache")) {
|
||||||
// only include ccts from caches generated from phishing attacks
|
// only include ccts from caches generated from phishing attacks
|
||||||
rewards.push(getCCTReward);
|
rewards.push(getCCTReward);
|
||||||
}
|
}
|
||||||
|
if (getBitNodeMultipliers(Player.bitNodeN, 1).DarknetMoneyMultiplier) {
|
||||||
|
// only include money reward if it is not disabled by the bn mults
|
||||||
|
rewards.push(getMoneyReward);
|
||||||
|
}
|
||||||
const reward = rewards[Math.floor(Math.random() * rewards.length)];
|
const reward = rewards[Math.floor(Math.random() * rewards.length)];
|
||||||
const result = reward(difficulty, server);
|
const result = reward(difficulty, server);
|
||||||
|
|
||||||
@@ -98,10 +103,14 @@ export const getStockReward = (difficulty: number): string => {
|
|||||||
initStockMarket();
|
initStockMarket();
|
||||||
}
|
}
|
||||||
const stockSymbols = Object.keys(StockSymbol);
|
const stockSymbols = Object.keys(StockSymbol);
|
||||||
const randomStock = stockSymbols[Math.floor(Math.random() * stockSymbols.length)];
|
const stock = StockMarket[stockSymbols[Math.floor(Math.random() * stockSymbols.length)]];
|
||||||
const shares = Math.floor(1 + difficulty * 5 + Math.random() * 10);
|
const maxNewShares = stock.maxShares - stock.playerShares - stock.playerShortShares;
|
||||||
StockMarket[randomStock].playerShares += shares;
|
if (maxNewShares <= 0) {
|
||||||
return `You have discovered a stock option cache containing ${shares} shares of ${randomStock}!`;
|
return getMoneyReward(difficulty);
|
||||||
|
}
|
||||||
|
const shares = Math.min(Math.floor(1 + difficulty * 5 + Math.random() * 10), maxNewShares);
|
||||||
|
stock.playerShares += shares;
|
||||||
|
return `You have discovered a stock option cache containing ${shares} shares of ${stock.symbol}!`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDataFileReward = (difficulty: number, server: DarknetServer): string => {
|
export const getDataFileReward = (difficulty: number, server: DarknetServer): string => {
|
||||||
|
|||||||
@@ -61,9 +61,11 @@ import { DarknetServer } from "../../../src/Server/DarknetServer";
|
|||||||
import { isDirectoryPath } from "../../../src/Paths/Directory";
|
import { isDirectoryPath } from "../../../src/Paths/Directory";
|
||||||
import { isFilePath } from "../../../src/Paths/FilePath";
|
import { isFilePath } from "../../../src/Paths/FilePath";
|
||||||
import { LAB_CACHE_NAME } from "../../../src/DarkNet/effects/labyrinth";
|
import { LAB_CACHE_NAME } from "../../../src/DarkNet/effects/labyrinth";
|
||||||
import { generateCacheFilename } from "../../../src/DarkNet/effects/cacheFiles";
|
import { generateCacheFilename, getStockReward } from "../../../src/DarkNet/effects/cacheFiles";
|
||||||
import { getAllDarknetServers } from "../../../src/DarkNet/utils/darknetNetworkUtils";
|
import { getAllDarknetServers } from "../../../src/DarkNet/utils/darknetNetworkUtils";
|
||||||
import { prestigeAugmentation } from "../../../src/Prestige";
|
import { prestigeAugmentation } from "../../../src/Prestige";
|
||||||
|
import { initStockMarket, StockMarket } from "../../../src/StockMarket/StockMarket";
|
||||||
|
import { StockSymbol } from "@enums";
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
initGameEnvironment();
|
initGameEnvironment();
|
||||||
@@ -839,3 +841,48 @@ describe("Clue filename generator", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Stock cache reward", () => {
|
||||||
|
test("stock reward does not exceed maxShares and falls back to money reward", () => {
|
||||||
|
initStockMarket();
|
||||||
|
|
||||||
|
const remaining = 3;
|
||||||
|
// Fill every stock to near capacity so no matter which one is randomly picked, it triggers clamping
|
||||||
|
for (const stockName of Object.keys(StockSymbol)) {
|
||||||
|
const stock = StockMarket[stockName];
|
||||||
|
stock.playerShares = stock.maxShares - remaining;
|
||||||
|
stock.playerShortShares = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use high difficulty to ensure the unclamped share count would exceed remaining
|
||||||
|
const difficulty = 100;
|
||||||
|
const result = getStockReward(difficulty);
|
||||||
|
|
||||||
|
// Should have awarded at most `remaining` shares
|
||||||
|
expect(result).toContain(`${remaining} shares`);
|
||||||
|
|
||||||
|
// Verify the chosen stock was clamped to exactly maxShares
|
||||||
|
for (const stockName of Object.keys(StockSymbol)) {
|
||||||
|
const stock = StockMarket[stockName];
|
||||||
|
expect(stock.playerShares).toBeLessThanOrEqual(stock.maxShares);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stock reward falls back to money when stock is fully owned", () => {
|
||||||
|
initStockMarket();
|
||||||
|
|
||||||
|
// Fill every stock to max capacity
|
||||||
|
for (const stockName of Object.keys(StockSymbol)) {
|
||||||
|
const stock = StockMarket[stockName];
|
||||||
|
stock.playerShares = stock.maxShares;
|
||||||
|
stock.playerShortShares = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const moneyBefore = Player.money;
|
||||||
|
const result = getStockReward(5);
|
||||||
|
|
||||||
|
// Should have fallen back to a money reward
|
||||||
|
expect(result).toContain("discovered a cache with");
|
||||||
|
expect(Player.money).toBeGreaterThan(moneyBefore);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user