mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 09:33:49 +01:00
re-add achievemnets fix
This commit is contained in:
parent
af50560a47
commit
fe2270dc27
@ -20,11 +20,11 @@ import { SpecialServers } from "../Server/data/SpecialServers";
|
||||
import { Server } from "../Server/Server";
|
||||
import { Router } from "../ui/GameRoot";
|
||||
import { Page } from "../ui/Router";
|
||||
import { IMap } from '../types';
|
||||
import { IMap } from "../types";
|
||||
import * as data from "./AchievementData.json";
|
||||
|
||||
// Unable to correctly cast the JSON data into AchievementDataJson type otherwise...
|
||||
const achievementData = (<AchievementDataJson><unknown>data).achievements;
|
||||
const achievementData = (<AchievementDataJson>(<unknown>data)).achievements;
|
||||
|
||||
export interface Achievement {
|
||||
ID: string;
|
||||
@ -63,7 +63,7 @@ function hasAccessToSF(player: PlayerObject, bn: number): boolean {
|
||||
}
|
||||
|
||||
function knowsAboutBitverse(player: PlayerObject): boolean {
|
||||
return player.sourceFiles.some((a) => a.n === 1)
|
||||
return player.sourceFiles.some((a) => a.n === 1);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -81,198 +81,199 @@ function sfAchievement(): Achievement[] {
|
||||
}
|
||||
|
||||
export const achievements: IMap<Achievement> = {
|
||||
"CYBERSEC": {
|
||||
...achievementData['CYBERSEC'],
|
||||
CYBERSEC: {
|
||||
...achievementData["CYBERSEC"],
|
||||
Icon: "CSEC",
|
||||
Condition: () => Player.factions.includes("CyberSec"),
|
||||
},
|
||||
"NITESEC": {
|
||||
...achievementData['NITESEC'],
|
||||
NITESEC: {
|
||||
...achievementData["NITESEC"],
|
||||
Icon: "NiteSec",
|
||||
Condition: () => Player.factions.includes("NiteSec"),
|
||||
},
|
||||
"THE_BLACK_HAND": {
|
||||
...achievementData['THE_BLACK_HAND'],
|
||||
THE_BLACK_HAND: {
|
||||
...achievementData["THE_BLACK_HAND"],
|
||||
Icon: "TBH",
|
||||
Condition: () => Player.factions.includes("The Black Hand"),
|
||||
},
|
||||
"BITRUNNERS": {
|
||||
...achievementData['BITRUNNERS'],
|
||||
Icon: 'bitrunners',
|
||||
BITRUNNERS: {
|
||||
...achievementData["BITRUNNERS"],
|
||||
Icon: "bitrunners",
|
||||
Condition: () => Player.factions.includes("BitRunners"),
|
||||
},
|
||||
"DAEDALUS": {
|
||||
...achievementData['DAEDALUS'],
|
||||
DAEDALUS: {
|
||||
...achievementData["DAEDALUS"],
|
||||
Icon: "daedalus",
|
||||
Condition: () => Player.factions.includes("Daedalus"),
|
||||
},
|
||||
"THE_COVENANT": {
|
||||
...achievementData['THE_COVENANT'],
|
||||
THE_COVENANT: {
|
||||
...achievementData["THE_COVENANT"],
|
||||
Icon: "thecovenant",
|
||||
Condition: () => Player.factions.includes("The Covenant"),
|
||||
},
|
||||
"ILLUMINATI": {
|
||||
...achievementData['ILLUMINATI'],
|
||||
Icon: 'illuminati',
|
||||
ILLUMINATI: {
|
||||
...achievementData["ILLUMINATI"],
|
||||
Icon: "illuminati",
|
||||
Condition: () => Player.factions.includes("Illuminati"),
|
||||
},
|
||||
"BRUTESSH.EXE": {
|
||||
...achievementData['BRUTESSH.EXE'],
|
||||
Icon: 'p0',
|
||||
...achievementData["BRUTESSH.EXE"],
|
||||
Icon: "p0",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.BruteSSHProgram.name),
|
||||
},
|
||||
"FTPCRACK.EXE": {
|
||||
...achievementData['FTPCRACK.EXE'],
|
||||
Icon: 'p1',
|
||||
...achievementData["FTPCRACK.EXE"],
|
||||
Icon: "p1",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.FTPCrackProgram.name),
|
||||
},
|
||||
//-----------------------------------------------------
|
||||
"RELAYSMTP.EXE": {
|
||||
...achievementData['RELAYSMTP.EXE'],
|
||||
Icon: 'p2',
|
||||
...achievementData["RELAYSMTP.EXE"],
|
||||
Icon: "p2",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.RelaySMTPProgram.name),
|
||||
},
|
||||
"HTTPWORM.EXE": {
|
||||
...achievementData['HTTPWORM.EXE'],
|
||||
Icon: 'p3',
|
||||
...achievementData["HTTPWORM.EXE"],
|
||||
Icon: "p3",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.HTTPWormProgram.name),
|
||||
},
|
||||
"SQLINJECT.EXE": {
|
||||
...achievementData['SQLINJECT.EXE'],
|
||||
Icon: 'p4',
|
||||
...achievementData["SQLINJECT.EXE"],
|
||||
Icon: "p4",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.SQLInjectProgram.name),
|
||||
},
|
||||
"FORMULAS.EXE": {
|
||||
...achievementData['FORMULAS.EXE'],
|
||||
Icon: 'formulas',
|
||||
...achievementData["FORMULAS.EXE"],
|
||||
Icon: "formulas",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.Formulas.name),
|
||||
},
|
||||
"SF1.1": {
|
||||
...achievementData['SF1.1'],
|
||||
Icon: 'SF1.1',
|
||||
...achievementData["SF1.1"],
|
||||
Icon: "SF1.1",
|
||||
Visible: () => hasAccessToSF(Player, 1),
|
||||
Condition: () => Player.sourceFileLvl(1) >= 1
|
||||
Condition: () => Player.sourceFileLvl(1) >= 1,
|
||||
},
|
||||
"SF2.1": {
|
||||
...achievementData['SF2.1'],
|
||||
...achievementData["SF2.1"],
|
||||
Icon: "SF2.1",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () => Player.sourceFileLvl(2) >= 1,
|
||||
},
|
||||
"SF3.1": {
|
||||
...achievementData['SF3.1'],
|
||||
...achievementData["SF3.1"],
|
||||
Icon: "SF3.1",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.sourceFileLvl(3) >= 1,
|
||||
},
|
||||
"SF4.1": {
|
||||
...achievementData['SF4.1'],
|
||||
...achievementData["SF4.1"],
|
||||
Icon: "SF4.1",
|
||||
Visible: () => hasAccessToSF(Player, 4),
|
||||
Condition: () => Player.sourceFileLvl(4) >= 1,
|
||||
},
|
||||
"SF5.1": {
|
||||
...achievementData['SF5.1'],
|
||||
...achievementData["SF5.1"],
|
||||
Icon: "SF5.1",
|
||||
Visible: () => hasAccessToSF(Player, 5),
|
||||
Condition: () => Player.sourceFileLvl(5) >= 1,
|
||||
},
|
||||
"SF6.1": {
|
||||
...achievementData['SF6.1'],
|
||||
...achievementData["SF6.1"],
|
||||
Icon: "SF6.1",
|
||||
Visible: () => hasAccessToSF(Player, 6),
|
||||
Condition: () => Player.sourceFileLvl(6) >= 1,
|
||||
},
|
||||
"SF7.1": {
|
||||
...achievementData['SF7.1'],
|
||||
...achievementData["SF7.1"],
|
||||
Icon: "SF7.1",
|
||||
Visible: () => hasAccessToSF(Player, 7),
|
||||
Condition: () => Player.sourceFileLvl(7) >= 1,
|
||||
},
|
||||
"SF8.1": {
|
||||
...achievementData['SF8.1'],
|
||||
...achievementData["SF8.1"],
|
||||
Icon: "SF8.1",
|
||||
Visible: () => hasAccessToSF(Player, 8),
|
||||
Condition: () => Player.sourceFileLvl(8) >= 1,
|
||||
},
|
||||
"SF9.1": {
|
||||
...achievementData['SF9.1'],
|
||||
...achievementData["SF9.1"],
|
||||
Icon: "SF9.1",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () => Player.sourceFileLvl(9) >= 1,
|
||||
},
|
||||
"SF10.1": {
|
||||
...achievementData['SF10.1'],
|
||||
...achievementData["SF10.1"],
|
||||
Icon: "SF10.1",
|
||||
Visible: () => hasAccessToSF(Player, 10),
|
||||
Condition: () => Player.sourceFileLvl(10) >= 1
|
||||
Condition: () => Player.sourceFileLvl(10) >= 1,
|
||||
},
|
||||
"SF11.1": {
|
||||
...achievementData['SF11.1'],
|
||||
...achievementData["SF11.1"],
|
||||
Icon: "SF11.1",
|
||||
Visible: () => hasAccessToSF(Player, 11),
|
||||
Condition: () => Player.sourceFileLvl(11) >= 1
|
||||
Condition: () => Player.sourceFileLvl(11) >= 1,
|
||||
},
|
||||
"SF12.1": {
|
||||
...achievementData['SF12.1'],
|
||||
...achievementData["SF12.1"],
|
||||
Icon: "SF12.1",
|
||||
Visible: () => hasAccessToSF(Player, 12),
|
||||
Condition: () => Player.sourceFileLvl(12) >= 1
|
||||
Condition: () => Player.sourceFileLvl(12) >= 1,
|
||||
},
|
||||
"MONEY_1Q": {
|
||||
...achievementData['MONEY_1Q'],
|
||||
MONEY_1Q: {
|
||||
...achievementData["MONEY_1Q"],
|
||||
Icon: "$1Q",
|
||||
Condition: () => Player.money >= 1e18,
|
||||
},
|
||||
"MONEY_M1B": {
|
||||
...achievementData['MONEY_M1B'],
|
||||
MONEY_M1B: {
|
||||
...achievementData["MONEY_M1B"],
|
||||
Icon: "-1b",
|
||||
Secret: true,
|
||||
Condition: () => Player.money <= -1e9,
|
||||
},
|
||||
"INSTALL_1": {
|
||||
...achievementData['INSTALL_1'],
|
||||
INSTALL_1: {
|
||||
...achievementData["INSTALL_1"],
|
||||
Icon: "install",
|
||||
Condition: () => Player.augmentations.length >= 1,
|
||||
},
|
||||
"INSTALL_100": {
|
||||
...achievementData['INSTALL_100'],
|
||||
INSTALL_100: {
|
||||
...achievementData["INSTALL_100"],
|
||||
Icon: "install_100",
|
||||
Condition: () => Player.augmentations.length >= 100,
|
||||
},
|
||||
"QUEUE_40": {
|
||||
...achievementData['QUEUE_40'],
|
||||
QUEUE_40: {
|
||||
...achievementData["QUEUE_40"],
|
||||
Icon: "queue40",
|
||||
Condition: () => Player.queuedAugmentations.length >= 40,
|
||||
},
|
||||
"HACKING_100000": {
|
||||
...achievementData['HACKING_100000'],
|
||||
HACKING_100000: {
|
||||
...achievementData["HACKING_100000"],
|
||||
Icon: "hack100000",
|
||||
Condition: () => Player.hacking >= 100000,
|
||||
},
|
||||
"COMBAT_3000": {
|
||||
...achievementData['COMBAT_3000'],
|
||||
COMBAT_3000: {
|
||||
...achievementData["COMBAT_3000"],
|
||||
Icon: "combat3000",
|
||||
Condition: () =>
|
||||
Player.strength >= 3000 && Player.defense >= 3000 && Player.dexterity >= 3000 && Player.agility >= 3000,
|
||||
},
|
||||
"NEUROFLUX_255": {
|
||||
...achievementData['NEUROFLUX_255'],
|
||||
NEUROFLUX_255: {
|
||||
...achievementData["NEUROFLUX_255"],
|
||||
Icon: "nf255",
|
||||
Condition: () => Player.augmentations.some((a) => a.name === AugmentationNames.NeuroFluxGovernor && a.level >= 255),
|
||||
},
|
||||
"NS2": {
|
||||
...achievementData['NS2'],
|
||||
NS2: {
|
||||
...achievementData["NS2"],
|
||||
Icon: "ns2",
|
||||
Condition: () => Player.getHomeComputer().scripts.some((s) => s.filename.endsWith(".js") || s.filename.endsWith(".ns")),
|
||||
Condition: () =>
|
||||
Player.getHomeComputer().scripts.some((s) => s.filename.endsWith(".js") || s.filename.endsWith(".ns")),
|
||||
},
|
||||
"FROZE": {
|
||||
...achievementData['FROZE'],
|
||||
FROZE: {
|
||||
...achievementData["FROZE"],
|
||||
Icon: "forze",
|
||||
Condition: () => location.href.includes("noScripts")
|
||||
Condition: () => location.href.includes("noScripts"),
|
||||
},
|
||||
"RUNNING_SCRIPTS_1000": {
|
||||
...achievementData['RUNNING_SCRIPTS_1000'],
|
||||
RUNNING_SCRIPTS_1000: {
|
||||
...achievementData["RUNNING_SCRIPTS_1000"],
|
||||
Icon: "run1000",
|
||||
Condition: (): boolean => {
|
||||
let running = 0;
|
||||
@ -282,8 +283,8 @@ export const achievements: IMap<Achievement> = {
|
||||
return running >= 1000;
|
||||
},
|
||||
},
|
||||
"DRAIN_SERVER": {
|
||||
...achievementData['DRAIN_SERVER'],
|
||||
DRAIN_SERVER: {
|
||||
...achievementData["DRAIN_SERVER"],
|
||||
Icon: "drain",
|
||||
Condition: (): boolean => {
|
||||
for (const s of GetAllServers()) {
|
||||
@ -294,34 +295,34 @@ export const achievements: IMap<Achievement> = {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
"MAX_RAM": {
|
||||
...achievementData['MAX_RAM'],
|
||||
MAX_RAM: {
|
||||
...achievementData["MAX_RAM"],
|
||||
Icon: "maxram",
|
||||
Condition: () => Player.getHomeComputer().maxRam === CONSTANTS.HomeComputerMaxRam
|
||||
Condition: () => Player.getHomeComputer().maxRam === CONSTANTS.HomeComputerMaxRam,
|
||||
},
|
||||
"MAX_CORES": {
|
||||
...achievementData['MAX_CORES'],
|
||||
MAX_CORES: {
|
||||
...achievementData["MAX_CORES"],
|
||||
Icon: "maxcores",
|
||||
Condition: () => Player.getHomeComputer().cpuCores === 8
|
||||
Condition: () => Player.getHomeComputer().cpuCores === 8,
|
||||
},
|
||||
"SCRIPTS_30": {
|
||||
...achievementData['SCRIPTS_30'],
|
||||
SCRIPTS_30: {
|
||||
...achievementData["SCRIPTS_30"],
|
||||
Icon: "folders",
|
||||
Condition: () => Player.getHomeComputer().scripts.length >= 30
|
||||
Condition: () => Player.getHomeComputer().scripts.length >= 30,
|
||||
},
|
||||
"KARMA_1000000": {
|
||||
...achievementData['KARMA_1000000'],
|
||||
KARMA_1000000: {
|
||||
...achievementData["KARMA_1000000"],
|
||||
Icon: "karma",
|
||||
Secret: true,
|
||||
Condition: () => Player.karma <= -1e6
|
||||
Condition: () => Player.karma <= -1e6,
|
||||
},
|
||||
"STOCK_1q": {
|
||||
...achievementData['STOCK_1q'],
|
||||
STOCK_1q: {
|
||||
...achievementData["STOCK_1q"],
|
||||
Icon: "$1Q",
|
||||
Condition: () => Player.moneySourceB.stock >= 1e15
|
||||
Condition: () => Player.moneySourceB.stock >= 1e15,
|
||||
},
|
||||
"DISCOUNT": {
|
||||
...achievementData['DISCOUNT'],
|
||||
DISCOUNT: {
|
||||
...achievementData["DISCOUNT"],
|
||||
Icon: "discount",
|
||||
Condition: (): boolean => {
|
||||
const p = GetServer("powerhouse-fitness");
|
||||
@ -329,22 +330,22 @@ export const achievements: IMap<Achievement> = {
|
||||
return p.backdoorInstalled;
|
||||
},
|
||||
},
|
||||
"SCRIPT_32GB": {
|
||||
...achievementData['SCRIPT_32GB'],
|
||||
SCRIPT_32GB: {
|
||||
...achievementData["SCRIPT_32GB"],
|
||||
Icon: "bigcost",
|
||||
Condition: () => Player.getHomeComputer().scripts.some((s) => s.ramUsage >= 32),
|
||||
},
|
||||
"FIRST_HACKNET_NODE": {
|
||||
...achievementData['FIRST_HACKNET_NODE'],
|
||||
FIRST_HACKNET_NODE: {
|
||||
...achievementData["FIRST_HACKNET_NODE"],
|
||||
Condition: () => !hasHacknetServers(Player) && Player.hacknetNodes.length > 0,
|
||||
},
|
||||
"30_HACKNET_NODE": {
|
||||
...achievementData['30_HACKNET_NODE'],
|
||||
...achievementData["30_HACKNET_NODE"],
|
||||
Icon: "hacknet-all",
|
||||
Condition: () => !hasHacknetServers(Player) && Player.hacknetNodes.length >= 30,
|
||||
},
|
||||
"MAX_HACKNET_NODE": {
|
||||
...achievementData['MAX_HACKNET_NODE'],
|
||||
MAX_HACKNET_NODE: {
|
||||
...achievementData["MAX_HACKNET_NODE"],
|
||||
Icon: "hacknet-max",
|
||||
Condition: (): boolean => {
|
||||
if (hasHacknetServers(Player)) return false;
|
||||
@ -360,28 +361,28 @@ export const achievements: IMap<Achievement> = {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
"HACKNET_NODE_10M": {
|
||||
...achievementData['HACKNET_NODE_10M'],
|
||||
HACKNET_NODE_10M: {
|
||||
...achievementData["HACKNET_NODE_10M"],
|
||||
Icon: "hacknet-10m",
|
||||
Condition: () => !hasHacknetServers(Player) && Player.moneySourceB.hacknet >= 10e6,
|
||||
},
|
||||
"REPUTATION_10M": {
|
||||
...achievementData['REPUTATION_10M'],
|
||||
REPUTATION_10M: {
|
||||
...achievementData["REPUTATION_10M"],
|
||||
Icon: "reputation",
|
||||
Condition: () => Object.values(Factions).some((f) => f.playerReputation >= 10e6),
|
||||
},
|
||||
"DONATION": {
|
||||
...achievementData['DONATION'],
|
||||
DONATION: {
|
||||
...achievementData["DONATION"],
|
||||
Icon: "donation",
|
||||
Condition: () => Object.values(Factions).some((f) => f.favor >= 150),
|
||||
},
|
||||
"TRAVEL": {
|
||||
...achievementData['TRAVEL'],
|
||||
TRAVEL: {
|
||||
...achievementData["TRAVEL"],
|
||||
Icon: "travel",
|
||||
Condition: () => Player.city !== CityName.Sector12,
|
||||
},
|
||||
"WORKOUT": {
|
||||
...achievementData['WORKOUT'],
|
||||
WORKOUT: {
|
||||
...achievementData["WORKOUT"],
|
||||
Icon: "WORKOUT",
|
||||
Condition: () =>
|
||||
[
|
||||
@ -391,62 +392,65 @@ export const achievements: IMap<Achievement> = {
|
||||
CONSTANTS.ClassGymAgility,
|
||||
].includes(Player.className),
|
||||
},
|
||||
"TOR": {
|
||||
...achievementData['TOR'],
|
||||
TOR: {
|
||||
...achievementData["TOR"],
|
||||
Icon: "TOR",
|
||||
Condition: () => Player.hasTorRouter(),
|
||||
},
|
||||
"HOSPITALIZED": {
|
||||
...achievementData['HOSPITALIZED'],
|
||||
HOSPITALIZED: {
|
||||
...achievementData["HOSPITALIZED"],
|
||||
Icon: "OUCH",
|
||||
Condition: () => Player.moneySourceB.hospitalization !== 0,
|
||||
},
|
||||
"GANG": {
|
||||
...achievementData['GANG'],
|
||||
GANG: {
|
||||
...achievementData["GANG"],
|
||||
Icon: "GANG",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () => Player.gang !== null,
|
||||
},
|
||||
"FULL_GANG": {
|
||||
...achievementData['FULL_GANG'],
|
||||
FULL_GANG: {
|
||||
...achievementData["FULL_GANG"],
|
||||
Icon: "GANGMAX",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () => Player.gang !== null && Player.gang.members.length === GangConstants.MaximumGangMembers,
|
||||
},
|
||||
"GANG_TERRITORY": {
|
||||
...achievementData['GANG_TERRITORY'],
|
||||
GANG_TERRITORY: {
|
||||
...achievementData["GANG_TERRITORY"],
|
||||
Icon: "GANG100%",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () => Player.gang !== null && AllGangs[Player.gang.facName].territory >= 0.999,
|
||||
},
|
||||
"GANG_MEMBER_POWER": {
|
||||
...achievementData['GANG_MEMBER_POWER'],
|
||||
GANG_MEMBER_POWER: {
|
||||
...achievementData["GANG_MEMBER_POWER"],
|
||||
Icon: "GANG10000",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () =>
|
||||
Player.gang !== null &&
|
||||
Player.gang.members.some((m) => m.hack >= 10000 || m.str >= 10000 || m.def >= 10000 || m.dex >= 10000 || m.agi >= 10000 || m.cha >= 10000),
|
||||
Player.gang.members.some(
|
||||
(m) =>
|
||||
m.hack >= 10000 || m.str >= 10000 || m.def >= 10000 || m.dex >= 10000 || m.agi >= 10000 || m.cha >= 10000,
|
||||
),
|
||||
},
|
||||
"CORPORATION": {
|
||||
...achievementData['CORPORATION'],
|
||||
CORPORATION: {
|
||||
...achievementData["CORPORATION"],
|
||||
Icon: "CORP",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.corporation !== null,
|
||||
},
|
||||
"CORPORATION_BRIBE": {
|
||||
...achievementData['CORPORATION_BRIBE'],
|
||||
CORPORATION_BRIBE: {
|
||||
...achievementData["CORPORATION_BRIBE"],
|
||||
Icon: "CORPLOBBY",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.corporation !== null && Player.corporation.unlockUpgrades[6] === 1,
|
||||
},
|
||||
"CORPORATION_PROD_1000": {
|
||||
...achievementData['CORPORATION_PROD_1000'],
|
||||
CORPORATION_PROD_1000: {
|
||||
...achievementData["CORPORATION_PROD_1000"],
|
||||
Icon: "CORP1000",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.corporation !== null && Player.corporation.divisions.some((d) => d.prodMult >= 1000),
|
||||
},
|
||||
"CORPORATION_EMPLOYEE_3000": {
|
||||
...achievementData['CORPORATION_EMPLOYEE_3000'],
|
||||
CORPORATION_EMPLOYEE_3000: {
|
||||
...achievementData["CORPORATION_EMPLOYEE_3000"],
|
||||
Icon: "CORPCITY",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: (): boolean => {
|
||||
@ -454,65 +458,66 @@ export const achievements: IMap<Achievement> = {
|
||||
for (const d of Player.corporation.divisions) {
|
||||
for (const o of Object.values(d.offices)) {
|
||||
if (o === 0) continue;
|
||||
if (o.employees.length > 3000) return true;
|
||||
if (o.employees.length >= 3000) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
"CORPORATION_REAL_ESTATE": {
|
||||
...achievementData['CORPORATION_REAL_ESTATE'],
|
||||
CORPORATION_REAL_ESTATE: {
|
||||
...achievementData["CORPORATION_REAL_ESTATE"],
|
||||
Icon: "CORPRE",
|
||||
Name: "Own the land",
|
||||
Description: "Expand to the Real Estate division.",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.corporation !== null && Player.corporation.divisions.some((d) => d.type === Industries.RealEstate),
|
||||
Condition: () =>
|
||||
Player.corporation !== null && Player.corporation.divisions.some((d) => d.type === Industries.RealEstate),
|
||||
},
|
||||
"INTELLIGENCE_255": {
|
||||
...achievementData['INTELLIGENCE_255'],
|
||||
INTELLIGENCE_255: {
|
||||
...achievementData["INTELLIGENCE_255"],
|
||||
Icon: "INT255",
|
||||
Visible: () => hasAccessToSF(Player, 5),
|
||||
Condition: () => Player.intelligence >= 255,
|
||||
},
|
||||
"BLADEBURNER_DIVISION": {
|
||||
...achievementData['BLADEBURNER_DIVISION'],
|
||||
BLADEBURNER_DIVISION: {
|
||||
...achievementData["BLADEBURNER_DIVISION"],
|
||||
Icon: "BLADE",
|
||||
Visible: () => hasAccessToSF(Player, 6),
|
||||
Condition: () => Player.bladeburner !== null,
|
||||
},
|
||||
"BLADEBURNER_OVERCLOCK": {
|
||||
...achievementData['BLADEBURNER_OVERCLOCK'],
|
||||
BLADEBURNER_OVERCLOCK: {
|
||||
...achievementData["BLADEBURNER_OVERCLOCK"],
|
||||
Icon: "BLADEOVERCLOCK",
|
||||
Visible: () => hasAccessToSF(Player, 6),
|
||||
Condition: () =>
|
||||
Player.bladeburner !== null &&
|
||||
Player.bladeburner.skills[SkillNames.Overclock] === Skills[SkillNames.Overclock].maxLvl,
|
||||
},
|
||||
"BLADEBURNER_UNSPENT_100000": {
|
||||
...achievementData['BLADEBURNER_UNSPENT_100000'],
|
||||
BLADEBURNER_UNSPENT_100000: {
|
||||
...achievementData["BLADEBURNER_UNSPENT_100000"],
|
||||
Icon: "BLADE100K",
|
||||
Visible: () => hasAccessToSF(Player, 6),
|
||||
Condition: () => Player.bladeburner !== null && Player.bladeburner.skillPoints >= 100000,
|
||||
},
|
||||
"4S": {
|
||||
...achievementData['4S'],
|
||||
...achievementData["4S"],
|
||||
Icon: "4S",
|
||||
Condition: () => Player.has4SData
|
||||
Condition: () => Player.has4SData,
|
||||
},
|
||||
"FIRST_HACKNET_SERVER": {
|
||||
...achievementData['FIRST_HACKNET_SERVER'],
|
||||
FIRST_HACKNET_SERVER: {
|
||||
...achievementData["FIRST_HACKNET_SERVER"],
|
||||
Icon: "HASHNET",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length > 0,
|
||||
},
|
||||
"ALL_HACKNET_SERVER": {
|
||||
...achievementData['ALL_HACKNET_SERVER'],
|
||||
ALL_HACKNET_SERVER: {
|
||||
...achievementData["ALL_HACKNET_SERVER"],
|
||||
Icon: "HASHNETALL",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length === HacknetServerConstants.MaxServers,
|
||||
},
|
||||
"MAX_HACKNET_SERVER": {
|
||||
...achievementData['MAX_HACKNET_SERVER'],
|
||||
MAX_HACKNET_SERVER: {
|
||||
...achievementData["MAX_HACKNET_SERVER"],
|
||||
Icon: "HASHNETALL",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: (): boolean => {
|
||||
@ -532,26 +537,26 @@ export const achievements: IMap<Achievement> = {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
"HACKNET_SERVER_1B": {
|
||||
...achievementData['HACKNET_SERVER_1B'],
|
||||
HACKNET_SERVER_1B: {
|
||||
...achievementData["HACKNET_SERVER_1B"],
|
||||
Icon: "HASHNETMONEY",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () => hasHacknetServers(Player) && Player.moneySourceB.hacknet >= 1e9,
|
||||
},
|
||||
"MAX_CACHE": {
|
||||
...achievementData['MAX_CACHE'],
|
||||
MAX_CACHE: {
|
||||
...achievementData["MAX_CACHE"],
|
||||
Icon: "HASHNETCAP",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () => hasHacknetServers(Player) && Player.hashManager.hashes === Player.hashManager.capacity,
|
||||
},
|
||||
"SLEEVE_8": {
|
||||
...achievementData['SLEEVE_8'],
|
||||
SLEEVE_8: {
|
||||
...achievementData["SLEEVE_8"],
|
||||
Icon: "SLEEVE8",
|
||||
Visible: () => hasAccessToSF(Player, 10),
|
||||
Condition: () => Player.sleeves.length === 8,
|
||||
},
|
||||
"INDECISIVE": {
|
||||
...achievementData['INDECISIVE'],
|
||||
INDECISIVE: {
|
||||
...achievementData["INDECISIVE"],
|
||||
Icon: "1H",
|
||||
Visible: () => knowsAboutBitverse(Player),
|
||||
Condition: (function () {
|
||||
@ -566,14 +571,14 @@ export const achievements: IMap<Achievement> = {
|
||||
return () => c > 60;
|
||||
})(),
|
||||
},
|
||||
"FAST_BN": {
|
||||
...achievementData['FAST_BN'],
|
||||
FAST_BN: {
|
||||
...achievementData["FAST_BN"],
|
||||
Icon: "2DAYS",
|
||||
Visible: () => knowsAboutBitverse(Player),
|
||||
Condition: () => bitNodeFinishedState() && Player.playtimeSinceLastBitnode < 1000 * 60 * 60 * 24 * 2,
|
||||
},
|
||||
"CHALLENGE_BN1": {
|
||||
...achievementData['CHALLENGE_BN1'],
|
||||
CHALLENGE_BN1: {
|
||||
...achievementData["CHALLENGE_BN1"],
|
||||
Icon: "BN1+",
|
||||
Visible: () => knowsAboutBitverse(Player),
|
||||
Condition: () =>
|
||||
@ -582,38 +587,38 @@ export const achievements: IMap<Achievement> = {
|
||||
Player.getHomeComputer().maxRam <= 128 &&
|
||||
Player.getHomeComputer().cpuCores === 1,
|
||||
},
|
||||
"CHALLENGE_BN2": {
|
||||
...achievementData['CHALLENGE_BN2'],
|
||||
CHALLENGE_BN2: {
|
||||
...achievementData["CHALLENGE_BN2"],
|
||||
Icon: "BN2+",
|
||||
Visible: () => hasAccessToSF(Player, 2),
|
||||
Condition: () => Player.bitNodeN === 2 && bitNodeFinishedState() && Player.gang === null,
|
||||
},
|
||||
"CHALLENGE_BN3": {
|
||||
...achievementData['CHALLENGE_BN3'],
|
||||
CHALLENGE_BN3: {
|
||||
...achievementData["CHALLENGE_BN3"],
|
||||
Icon: "BN3+",
|
||||
Visible: () => hasAccessToSF(Player, 3),
|
||||
Condition: () => Player.bitNodeN === 3 && bitNodeFinishedState() && Player.corporation === null,
|
||||
},
|
||||
"CHALLENGE_BN6": {
|
||||
...achievementData['CHALLENGE_BN6'],
|
||||
CHALLENGE_BN6: {
|
||||
...achievementData["CHALLENGE_BN6"],
|
||||
Icon: "BN6+",
|
||||
Visible: () => hasAccessToSF(Player, 6),
|
||||
Condition: () => Player.bitNodeN === 6 && bitNodeFinishedState() && Player.bladeburner === null,
|
||||
},
|
||||
"CHALLENGE_BN7": {
|
||||
...achievementData['CHALLENGE_BN7'],
|
||||
CHALLENGE_BN7: {
|
||||
...achievementData["CHALLENGE_BN7"],
|
||||
Icon: "BN7+",
|
||||
Visible: () => hasAccessToSF(Player, 7),
|
||||
Condition: () => Player.bitNodeN === 7 && bitNodeFinishedState() && Player.bladeburner === null,
|
||||
},
|
||||
"CHALLENGE_BN8": {
|
||||
...achievementData['CHALLENGE_BN8'],
|
||||
CHALLENGE_BN8: {
|
||||
...achievementData["CHALLENGE_BN8"],
|
||||
Icon: "BN8+",
|
||||
Visible: () => hasAccessToSF(Player, 8),
|
||||
Condition: () => Player.bitNodeN === 8 && bitNodeFinishedState() && !Player.has4SData && !Player.has4SDataTixApi,
|
||||
},
|
||||
"CHALLENGE_BN9": {
|
||||
...achievementData['CHALLENGE_BN9'],
|
||||
CHALLENGE_BN9: {
|
||||
...achievementData["CHALLENGE_BN9"],
|
||||
Icon: "BN9+",
|
||||
Visible: () => hasAccessToSF(Player, 9),
|
||||
Condition: () =>
|
||||
@ -622,8 +627,8 @@ export const achievements: IMap<Achievement> = {
|
||||
Player.moneySourceB.hacknet === 0 &&
|
||||
Player.moneySourceB.hacknet_expenses === 0,
|
||||
},
|
||||
"CHALLENGE_BN10": {
|
||||
...achievementData['CHALLENGE_BN10'],
|
||||
CHALLENGE_BN10: {
|
||||
...achievementData["CHALLENGE_BN10"],
|
||||
Icon: "BN10+",
|
||||
Visible: () => hasAccessToSF(Player, 10),
|
||||
Condition: () =>
|
||||
@ -640,69 +645,69 @@ export const achievements: IMap<Achievement> = {
|
||||
s.charisma_exp > 0,
|
||||
),
|
||||
},
|
||||
"CHALLENGE_BN12": {
|
||||
...achievementData['CHALLENGE_BN12'],
|
||||
CHALLENGE_BN12: {
|
||||
...achievementData["CHALLENGE_BN12"],
|
||||
Icon: "BN12+",
|
||||
Visible: () => hasAccessToSF(Player, 12),
|
||||
Condition: () => Player.sourceFileLvl(12) >= 50
|
||||
Condition: () => Player.sourceFileLvl(12) >= 50,
|
||||
},
|
||||
"BYPASS": {
|
||||
...achievementData['BYPASS'],
|
||||
BYPASS: {
|
||||
...achievementData["BYPASS"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.Bypass)
|
||||
Condition: () => Player.exploits.includes(Exploit.Bypass),
|
||||
},
|
||||
"PROTOTYPETAMPERING": {
|
||||
...achievementData['PROTOTYPETAMPERING'],
|
||||
PROTOTYPETAMPERING: {
|
||||
...achievementData["PROTOTYPETAMPERING"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.PrototypeTampering)
|
||||
Condition: () => Player.exploits.includes(Exploit.PrototypeTampering),
|
||||
},
|
||||
"UNCLICKABLE": {
|
||||
...achievementData['UNCLICKABLE'],
|
||||
UNCLICKABLE: {
|
||||
...achievementData["UNCLICKABLE"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.Unclickable)
|
||||
Condition: () => Player.exploits.includes(Exploit.Unclickable),
|
||||
},
|
||||
"UNDOCUMENTEDFUNCTIONCALL": {
|
||||
...achievementData['UNDOCUMENTEDFUNCTIONCALL'],
|
||||
UNDOCUMENTEDFUNCTIONCALL: {
|
||||
...achievementData["UNDOCUMENTEDFUNCTIONCALL"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.UndocumentedFunctionCall)
|
||||
Condition: () => Player.exploits.includes(Exploit.UndocumentedFunctionCall),
|
||||
},
|
||||
"TIMECOMPRESSION": {
|
||||
...achievementData['TIMECOMPRESSION'],
|
||||
TIMECOMPRESSION: {
|
||||
...achievementData["TIMECOMPRESSION"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.TimeCompression)
|
||||
Condition: () => Player.exploits.includes(Exploit.TimeCompression),
|
||||
},
|
||||
"REALITYALTERATION": {
|
||||
...achievementData['REALITYALTERATION'],
|
||||
REALITYALTERATION: {
|
||||
...achievementData["REALITYALTERATION"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.RealityAlteration)
|
||||
Condition: () => Player.exploits.includes(Exploit.RealityAlteration),
|
||||
},
|
||||
"N00DLES": {
|
||||
...achievementData['N00DLES'],
|
||||
N00DLES: {
|
||||
...achievementData["N00DLES"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.N00dles)
|
||||
Condition: () => Player.exploits.includes(Exploit.N00dles),
|
||||
},
|
||||
"EDITSAVEFILE": {
|
||||
...achievementData['EDITSAVEFILE'],
|
||||
EDITSAVEFILE: {
|
||||
...achievementData["EDITSAVEFILE"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
Condition: () => Player.exploits.includes(Exploit.EditSaveFile)
|
||||
Condition: () => Player.exploits.includes(Exploit.EditSaveFile),
|
||||
},
|
||||
"UNACHIEVABLE": {
|
||||
...achievementData['UNACHIEVABLE'],
|
||||
UNACHIEVABLE: {
|
||||
...achievementData["UNACHIEVABLE"],
|
||||
Icon: "SF-1",
|
||||
Secret: true,
|
||||
// Hey Players! Yes, you're supposed to modify this to get the achievement!
|
||||
Condition: () => false,
|
||||
},
|
||||
"CHALLENGE_BN13": {
|
||||
...achievementData['CHALLENGE_BN13'],
|
||||
CHALLENGE_BN13: {
|
||||
...achievementData["CHALLENGE_BN13"],
|
||||
Icon: "BN13+",
|
||||
Visible: () => hasAccessToSF(Player, 13),
|
||||
Condition: () =>
|
||||
@ -710,12 +715,12 @@ export const achievements: IMap<Achievement> = {
|
||||
bitNodeFinishedState() &&
|
||||
!Player.augmentations.some((a) => a.name === AugmentationNames.StaneksGift1),
|
||||
},
|
||||
"DEVMENU": {
|
||||
...achievementData['DEVMENU'],
|
||||
DEVMENU: {
|
||||
...achievementData["DEVMENU"],
|
||||
Icon: "SF-1",
|
||||
Condition: () => Player.exploits.includes(Exploit.YoureNotMeantToAccessThis)
|
||||
}
|
||||
}
|
||||
Condition: () => Player.exploits.includes(Exploit.YoureNotMeantToAccessThis),
|
||||
},
|
||||
};
|
||||
|
||||
// Steam has a limit of 100 achievement. So these were planned but commented for now.
|
||||
// { ID: "ECORP", Condition: () => Player.factions.includes("ECorp") },
|
||||
@ -753,9 +758,11 @@ export const achievements: IMap<Achievement> = {
|
||||
// { ID: "FLIGHT.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.Flight.name) },
|
||||
|
||||
export function calculateAchievements(): void {
|
||||
const availableAchievements = Object.values(achievements).filter((a) => a.Condition()).map((a) => a.ID);
|
||||
const availableAchievements = Object.values(achievements)
|
||||
.filter((a) => a.Condition())
|
||||
.map((a) => a.ID);
|
||||
const playerAchievements = Player.achievements.map((a) => a.ID);
|
||||
const newAchievements = availableAchievements.filter(a => !playerAchievements.includes(a));
|
||||
const newAchievements = availableAchievements.filter((a) => !playerAchievements.includes(a));
|
||||
|
||||
for (const id of newAchievements) {
|
||||
Player.giveAchievement(id);
|
||||
@ -764,5 +771,5 @@ export function calculateAchievements(): void {
|
||||
// Write all player's achievements to document for Steam/Electron
|
||||
// This could be replaced by "availableAchievements"
|
||||
// if we don't want to grant the save game achievements to steam but only currently available
|
||||
(document as any).achievements = [...Player.achievements.map(a => a.ID)];
|
||||
(document as any).achievements = [...Player.achievements.map((a) => a.ID)];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user