Compare commits

...

2 Commits

8 changed files with 69 additions and 8 deletions

View File

@@ -7,7 +7,7 @@ export const CONSTANTS = {
VersionString: "3.0.0dev",
isDevBranch: true,
isInTestEnvironment: globalThis.process?.env?.JEST_WORKER_ID !== undefined,
VersionNumber: 48,
VersionNumber: 49,
/** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
* and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then

View File

@@ -9,6 +9,10 @@ import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import { useCycleRerender } from "../../ui/React/hooks";
import Button from "@mui/material/Button";
import { Router } from "../../ui/GameRoot";
import { Page } from "../../ui/Router";
import { Factions } from "../../Faction/Factions";
/** React Component for all the gang stuff. */
export function GangRoot(): React.ReactElement {
@@ -18,7 +22,7 @@ export function GangRoot(): React.ReactElement {
})();
const [value, setValue] = React.useState(0);
function handleChange(event: React.SyntheticEvent, tab: number): void {
function handleChange(__event: React.SyntheticEvent, tab: number): void {
setValue(tab);
}
@@ -26,11 +30,26 @@ export function GangRoot(): React.ReactElement {
return (
<Context.Gang.Provider value={gang}>
<Tabs variant="fullWidth" value={value} onChange={handleChange} sx={{ minWidth: "fit-content", maxWidth: "45%" }}>
<div style={{ display: "flex" }}>
<Tabs
variant="fullWidth"
value={value}
onChange={handleChange}
sx={{ minWidth: "fit-content", maxWidth: "45%" }}
>
<Tab label="Management" />
<Tab label="Equipment" />
<Tab label="Territory" />
</Tabs>
<Button
style={{ marginLeft: "20px" }}
onClick={() => {
Router.toPage(Page.Faction, { faction: Factions[gang.facName] });
}}
>
Faction
</Button>
</div>
{value === 0 && <ManagementSubpage />}
{value === 1 && <EquipmentsSubpage />}
{value === 2 && <TerritorySubpage />}

View File

@@ -147,6 +147,10 @@ export abstract class Person implements IPerson {
}
overrideIntelligence(): void {
// Do not set anything if the player has not unlocked Intelligence.
if (Player.sourceFileLvl(5) === 0 && Player.bitNodeN !== 5) {
return;
}
const persistentIntelligenceSkill = this.calculateSkill(this.persistentIntelligenceData.exp, 1);
// Reset exp and skill to the persistent values if there is no limit (intelligenceOverride) or the limit is greater
// than or equal to the persistent skill.
@@ -172,7 +176,7 @@ export abstract class Person implements IPerson {
* Don't change sourceFileLvl to activeSourceFileLvl. When the player has int level, the ability to gain more int is
* a permanent benefit.
*/
if (Player.sourceFileLvl(5) > 0 || this.skills.intelligence > 0 || Player.bitNodeN === 5) {
if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) {
this.exp.intelligence += exp;
this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence, 1));
this.persistentIntelligenceData.exp += exp;

View File

@@ -637,4 +637,11 @@ Error: ${e}`,
if (ver < 48) {
showAPIBreaks("3.0.0", breakingChanges300);
}
if (ver < 49 && Player.sourceFileLvl(5) === 0 && Player.bitNodeN !== 5) {
for (const person of [Player, ...Player.sleeves]) {
person.persistentIntelligenceData.exp = 0;
person.exp.intelligence = 0;
person.skills.intelligence = 0;
}
}
}

View File

@@ -105,4 +105,31 @@ describe("v3", () => {
`bitburnerSave_backup_2.8.1_${Math.round(lastUpdate / 1000)}.json.gz`,
);
});
describe("Intelligence migration bug", () => {
test("No change in exp and skill level", async () => {
const saveData = new Uint8Array(fs.readFileSync("test/jest/Migration/save-files/v2.8.1_SF1.1_SF10.3.gz"));
const mockedDownload = await loadGameFromSaveData(saveData);
for (const person of [Player, ...Player.sleeves]) {
expect(person.persistentIntelligenceData.exp).toStrictEqual(0);
expect(person.exp.intelligence).toStrictEqual(0);
expect(person.skills.intelligence).toStrictEqual(0);
}
expect(mockedDownload).toHaveBeenCalledWith(saveData, "bitburnerSave_backup_2.8.1_1776173824.json.gz");
});
test("Reset wrong exp and skill level", async () => {
const saveData = new Uint8Array(fs.readFileSync("test/jest/Migration/save-files/v3.0.0_int_migration_bug.gz"));
const mockedDownload = await loadGameFromSaveData(saveData);
for (const person of [Player, ...Player.sleeves]) {
expect(person.persistentIntelligenceData.exp).toStrictEqual(0);
expect(person.exp.intelligence).toStrictEqual(0);
expect(person.skills.intelligence).toStrictEqual(0);
}
expect(mockedDownload).not.toHaveBeenCalled();
});
});
});

Binary file not shown.

View File

@@ -55,8 +55,12 @@ function testIntelligenceOverride(
setUpBeforePrestige = () => {},
): void {
Player.sourceFiles.set(5, 1);
// The intelligence skill level starts at 0.
expect(Player.skills.intelligence).toStrictEqual(0);
prestigeSourceFile(true);
// Start without exp.
expect(Player.exp.intelligence).toStrictEqual(0);
// When having SF5 and the skill level is 0, it's set to 1.
expect(Player.skills.intelligence).toStrictEqual(1);
expect(Player.persistentIntelligenceData.exp).toStrictEqual(0);
// Gain 1e6 exp (skill = 242).