diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx index 02ee94387..01741816b 100644 --- a/src/BitNode/BitNode.tsx +++ b/src/BitNode/BitNode.tsx @@ -467,7 +467,7 @@ export function initBitNodes() {
Level 2: Permanently unlocks the go.cheat API
- Level 3: 25% increased success rate for the go.cheat API + Level 3: 25% additive increased success rate for the go.cheat API

This Source-File also increases the maximum favor you can gain for each faction from IPvGO to: diff --git a/src/Go/effects/netscriptGoImplementation.ts b/src/Go/effects/netscriptGoImplementation.ts index ac6094fb1..74d82535d 100644 --- a/src/Go/effects/netscriptGoImplementation.ts +++ b/src/Go/effects/netscriptGoImplementation.ts @@ -416,10 +416,25 @@ export async function determineCheatSuccess( /** * Cheating success rate scales with player's crime success rate, and decreases with prior cheat attempts. + * + * The source file bonus is additive success chance on top of the other multipliers. + * + * Cheat success chance required for N cheats with 100% success rate in a game: + * + * 1 100% success rate cheat requires +66% increased crime success rate + * 2 100% success cheats: +145% increased crime success rate + * 3: +282% + * 4: +535% + * 5: +1027% + * 7: +4278% + * 10: +59,854% + * 12: +534,704% + * 15: +31,358,645% */ export function cheatSuccessChance(cheatCount: number) { - const sourceFileBonus = Player.sourceFileLvl(14) === 3 ? 1.25 : 1; - return Math.min(0.6 * 0.65 ** cheatCount * Player.mults.crime_success * sourceFileBonus, 1); + const sourceFileBonus = Player.sourceFileLvl(14) === 3 ? 0.25 : 0; + const cheatCountScalar = (0.7 - 0.02 * cheatCount) ** cheatCount; + return Math.max(Math.min(0.6 * cheatCountScalar * Player.mults.crime_success + sourceFileBonus, 1), 0); } /** diff --git a/src/SourceFile/SourceFiles.tsx b/src/SourceFile/SourceFiles.tsx index 07a4b8418..0b2a9a86c 100644 --- a/src/SourceFile/SourceFiles.tsx +++ b/src/SourceFile/SourceFiles.tsx @@ -243,7 +243,7 @@ export function initSourceFiles() {
Level 2: Permanently unlocks the go.cheat API in other BitNodes
- Level 3: 25% increased success rate for the go.cheat API + Level 3: 25% additive increased success rate for the go.cheat API

This Source-File also increases the maximum favor you can gain for each faction from IPvGO to: diff --git a/test/jest/Go/NetscriptGo.test.ts b/test/jest/Go/NetscriptGo.test.ts index f771031ce..85a6174ee 100644 --- a/test/jest/Go/NetscriptGo.test.ts +++ b/test/jest/Go/NetscriptGo.test.ts @@ -1,11 +1,12 @@ -import { setPlayer } from "@player"; -import { GoColor, GoOpponent, GoPlayType } from "@enums"; +import { Player, setPlayer } from "@player"; +import { AugmentationName, GoColor, GoOpponent, GoPlayType } from "@enums"; import { Go } from "../../../src/Go/Go"; import { boardStateFromSimpleBoard, simpleBoardFromBoard } from "../../../src/Go/boardAnalysis/boardAnalysis"; import { cheatPlayTwoMoves, cheatRemoveRouter, cheatRepairOfflineNode, + cheatSuccessChance, getChains, getControlledEmptyNodes, getGameState, @@ -19,12 +20,24 @@ import { import { PlayerObject } from "../../../src/PersonObjects/Player/PlayerObject"; import "../../../src/Faction/Factions"; import { getNewBoardState } from "../../../src/Go/boardState/boardState"; +import { installAugmentations } from "../../../src/Augmentation/AugmentationHelpers"; +import { AddToAllServers } from "../../../src/Server/AllServers"; +import { Server } from "../../../src/Server/Server"; +import { initSourceFiles } from "../../../src/SourceFile/SourceFiles"; jest.mock("../../../src/Faction/Factions", () => ({ Factions: {}, })); +jest.mock("../../../src/ui/GameRoot", () => ({ + Router: { + page: () => ({}), + toPage: () => ({}), + }, +})); + setPlayer(new PlayerObject()); +AddToAllServers(new Server({ hostname: "home" })); describe("Netscript Go API unit tests", () => { describe("makeMove() tests", () => { @@ -304,4 +317,27 @@ describe("Netscript Go API unit tests", () => { expect(Go.currentGame.board[4]?.[4]?.color).toEqual(GoColor.empty); }); }); + + describe("Cheat success chance unit tests", () => { + it("should have a base chance", () => { + expect(cheatSuccessChance(0)).toEqual(0.6); + }); + + it("should have a scaled chance based on cheat count", () => { + expect(cheatSuccessChance(4)).toEqual(0.6 * (0.7 - 0.08) ** 4); + }); + + it("should have a scaled chance based on layer cheat success level", () => { + Player.setBitNodeNumber(13); + initSourceFiles(); + Player.queueAugmentation(AugmentationName.BrachiBlades); + Player.queueAugmentation(AugmentationName.GrapheneBrachiBlades); + Player.queueAugmentation(AugmentationName.INFRARet); + Player.queueAugmentation(AugmentationName.PCMatrix); + Player.queueAugmentation(AugmentationName.NeuroFluxGovernor); + installAugmentations(); + + expect(cheatSuccessChance(4)).toEqual(0.6 * (0.7 - 0.08) ** 4 * Player.mults.crime_success); + }); + }); });