diff --git a/src/DarkNet/effects/cacheFiles.ts b/src/DarkNet/effects/cacheFiles.ts index f067b74c6..558ea90bb 100644 --- a/src/DarkNet/effects/cacheFiles.ts +++ b/src/DarkNet/effects/cacheFiles.ts @@ -13,6 +13,7 @@ import { resolveCacheFilePath } from "../../Paths/CacheFilePath"; import type { CacheResult } from "@nsdefs"; import { addClue, cctCooldownReached } from "./effects"; import { getBitNodeMultipliers } from "../../BitNode/BitNode"; +import { pluralize } from "../../utils/I18nUtils"; export const generateCacheFilename = (isPhishingCache: boolean, prefix?: string) => { const filenamePrefix = prefix ?? cachePrefixes[Math.floor(Math.random() * cachePrefixes.length)]; @@ -117,14 +118,11 @@ export const getStockReward = (difficulty: number): string => { }; export const getDataFileReward = (difficulty: number, server: DarknetServer): string => { - const currentDataFiles = server.textFiles.size; - addClue(server); - addClue(server); - const dataFilesGained = server.textFiles.size - currentDataFiles; - if (dataFilesGained === 0) { + const dataFiles = [...addClue(server), ...addClue(server)]; + if (dataFiles.length === 0) { return getMoneyReward(difficulty); } - return `You have discovered a data file cache!`; + return `You have discovered ${pluralize(dataFiles.length, "data file cache")}: ${dataFiles.join(", ")}.`; }; export const getProgramAndStockMarketRelatedRewards = (difficulty: number): string => { diff --git a/src/DarkNet/effects/effects.ts b/src/DarkNet/effects/effects.ts index 71fbcb727..fac1556ea 100644 --- a/src/DarkNet/effects/effects.ts +++ b/src/DarkNet/effects/effects.ts @@ -121,12 +121,14 @@ export const calculatePasswordAttemptChaGain = (server: DarknetServerData, threa }; // TODO: balance password clue spawn rate -export const addClue = (server: DarknetServer) => { +export const addClue = (server: DarknetServer): string[] => { + const files = []; // Basic mechanics hints if ((Math.random() < 0.7 && server.difficulty <= 3) || Math.random() < 0.1) { const hint: LiteratureName = hintLiterature[Math.floor(Math.random() * hintLiterature.length)]; if (hint && !server.messages.includes(hint)) { server.messages.push(hint); + files.push(hint); } } @@ -137,7 +139,8 @@ export const addClue = (server: DarknetServer) => { const start = Math.floor(Math.random() * (commonPasswordDictionary.length - length)); const commonPasswords = commonPasswordDictionary.slice(start, start + length).join(", "); server.writeToTextFile(hintFileName, `Some common passwords include ${commonPasswords}`); - return; + files.push(hintFileName); + return files; } // connected neighboring server's password (does not include server name) @@ -150,7 +153,8 @@ export const addClue = (server: DarknetServer) => { const neighboringServer = neighboringServerName ? getDarknetServer(neighboringServerName) : null; if (neighboringServer) { server.writeToTextFile(passwordHintName, `Remember this password: ${neighboringServer.password}`); - return; + files.push(passwordHintName); + return files; } } @@ -161,7 +165,8 @@ export const addClue = (server: DarknetServer) => { if (targetServer) { const contents = `Server: ${targetServer.hostname} Password: "${targetServer.password}"`; server.writeToTextFile(hintFileName, contents); - return; + files.push(hintFileName); + return files; } } @@ -169,7 +174,8 @@ export const addClue = (server: DarknetServer) => { const hintFileName = getClueFileName(notebookFileNames); const loreNote = packetSniffPhrases[Math.floor(Math.random() * packetSniffPhrases.length)]; server.writeToTextFile(hintFileName, loreNote); - return; + files.push(hintFileName); + return files; } if (Math.random() < 0.7) { @@ -179,9 +185,11 @@ export const addClue = (server: DarknetServer) => { const [containedChar1, containedChar2] = getTwoCharsInPassword(targetServer.password); const hint = `The password for ${targetServer.hostname} contains ${containedChar1} and ${containedChar2}`; server.writeToTextFile(hintFileName, hint); - return; + files.push(hintFileName); + return files; } } + return files; }; export const getClueFileName = (fileNameList: readonly string[]): TextFilePath => {