mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-17 13:13:49 +01:00
more achievements
This commit is contained in:
parent
e262c9bb38
commit
7ee5d8d71a
BIN
assets/Steam/achievements/default_locked.png
Normal file
BIN
assets/Steam/achievements/default_locked.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
BIN
assets/Steam/achievements/default_unlocked.png
Normal file
BIN
assets/Steam/achievements/default_unlocked.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
168
assets/Steam/achievements/default_unlocked.svg
Normal file
168
assets/Steam/achievements/default_unlocked.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 54 KiB |
24
dist/vendor.bundle.js
vendored
24
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
BIN
electron/lib/sdkencryptedappticket64.dll
Normal file
BIN
electron/lib/sdkencryptedappticket64.dll
Normal file
Binary file not shown.
BIN
electron/lib/sdkencryptedappticket64.lib
Normal file
BIN
electron/lib/sdkencryptedappticket64.lib
Normal file
Binary file not shown.
BIN
electron/lib/steam_api64.dll
Normal file
BIN
electron/lib/steam_api64.dll
Normal file
Binary file not shown.
BIN
electron/lib/steam_api64.lib
Normal file
BIN
electron/lib/steam_api64.lib
Normal file
Binary file not shown.
@ -3,12 +3,11 @@ const greenworks = require("./greenworks");
|
||||
|
||||
if (greenworks.init()) {
|
||||
console.log("Steam API has been initialized.");
|
||||
greenworks.activateAchievement("BN1.1", () => undefined);
|
||||
} else {
|
||||
console.log("Steam API has failed to initialize.");
|
||||
}
|
||||
|
||||
const debug = true;
|
||||
const debug = false;
|
||||
|
||||
Menu.setApplicationMenu(false);
|
||||
function createWindow() {
|
||||
@ -42,9 +41,15 @@ function createWindow() {
|
||||
shell.openExternal(url);
|
||||
});
|
||||
|
||||
// This is backward but the game fills in an array called `document.achievements` and we retrieve it from
|
||||
// here. Hey if it works it works.
|
||||
const achievements = greenworks.getAchievementNames();
|
||||
setInterval(async () => {
|
||||
const resp = await win.webContents.executeJavaScript("document.saveString");
|
||||
await win.webContents.executeJavaScript(`console.log('${resp}')`);
|
||||
const achs = await win.webContents.executeJavaScript("document.achievements");
|
||||
for (const ach of achs) {
|
||||
if (!achievements.includes(ach)) continue;
|
||||
greenworks.activateAchievement(ach, () => undefined);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
261
src/Electron.tsx
261
src/Electron.tsx
@ -1,12 +1,36 @@
|
||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||
import { SkillNames } from "./Bladeburner/data/SkillNames";
|
||||
import { Skills } from "./Bladeburner/Skills";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Industries } from "./Corporation/IndustryData";
|
||||
import { Exploit } from "./Exploits/Exploit";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { AllGangs } from "./Gang/AllGangs";
|
||||
import { GangConstants } from "./Gang/data/Constants";
|
||||
import { HacknetServerConstants } from "./Hacknet/data/Constants";
|
||||
import { hasHacknetServers } from "./Hacknet/HacknetHelpers";
|
||||
import { HacknetServer } from "./Hacknet/HacknetServer";
|
||||
import { CityName } from "./Locations/data/CityNames";
|
||||
import { Player } from "./Player";
|
||||
import { Programs } from "./Programs/Programs";
|
||||
import { GetAllServers, GetServer } from "./Server/AllServers";
|
||||
import { SpecialServers } from "./Server/data/SpecialServers";
|
||||
import { Server } from "./Server/Server";
|
||||
import { Router } from "./ui/GameRoot";
|
||||
import { Page } from "./ui/Router";
|
||||
|
||||
interface Achievement {
|
||||
ID: string;
|
||||
Condition: () => boolean;
|
||||
}
|
||||
|
||||
function bitNodeFinishedState(): boolean {
|
||||
const wd = GetServer(SpecialServers.WorldDaemon);
|
||||
if (!(wd instanceof Server)) return false;
|
||||
if (wd.backdoorInstalled) return true;
|
||||
return Player.bladeburner !== null && Player.bladeburner.blackops.hasOwnProperty("Operation Daedalus");
|
||||
}
|
||||
|
||||
function sfAchievement(): Achievement[] {
|
||||
const achs: Achievement[] = [];
|
||||
for (let i = 0; i <= 11; i++) {
|
||||
@ -22,12 +46,13 @@ function sfAchievement(): Achievement[] {
|
||||
|
||||
const achievements: Achievement[] = [
|
||||
{
|
||||
ID: `UNACHIEVABLE`,
|
||||
ID: "UNACHIEVABLE",
|
||||
// Hey Players! Yes, you're supposed to modify this to get the achievement!
|
||||
Condition: () => false,
|
||||
},
|
||||
...sfAchievement(),
|
||||
{
|
||||
ID: `SF12.100`,
|
||||
ID: "SF12.100",
|
||||
Condition: () => Player.sourceFileLvl(12) >= 100,
|
||||
},
|
||||
{ ID: "BYPASS", Condition: () => Player.exploits.includes(Exploit.Bypass) },
|
||||
@ -67,13 +92,13 @@ const achievements: Achievement[] = [
|
||||
Condition: () => Player.hacking >= 100000,
|
||||
},
|
||||
{
|
||||
ID: "INTELLIGENCE_100",
|
||||
Condition: () => Player.intelligence >= 100,
|
||||
ID: "INTELLIGENCE_255",
|
||||
Condition: () => Player.intelligence >= 255,
|
||||
},
|
||||
{
|
||||
ID: "COMBAT_1000",
|
||||
ID: "COMBAT_3000",
|
||||
Condition: () =>
|
||||
Player.strength >= 1000 && Player.defense >= 1000 && Player.dexterity >= 1000 && Player.agility >= 1000,
|
||||
Player.strength >= 3000 && Player.defense >= 3000 && Player.dexterity >= 3000 && Player.agility >= 3000,
|
||||
},
|
||||
{
|
||||
ID: "NEUROFLUX_255",
|
||||
@ -111,6 +136,230 @@ const achievements: Achievement[] = [
|
||||
{ ID: "TIAN_DI_HUI", Condition: () => Player.factions.includes("Tian Di Hui") },
|
||||
{ ID: "CYBERSEC", Condition: () => Player.factions.includes("CyberSec") },
|
||||
{ ID: "BLADEBURNERS", Condition: () => Player.factions.includes("Bladeburners") },
|
||||
{ ID: "BRUTESSH.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.BruteSSHProgram.name) },
|
||||
{ ID: "FTPCRACK.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.FTPCrackProgram.name) },
|
||||
{ ID: "RELAYSMTP.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.RelaySMTPProgram.name) },
|
||||
{ ID: "HTTPWORM.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.HTTPWormProgram.name) },
|
||||
{ ID: "SQLINJECT.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.SQLInjectProgram.name) },
|
||||
{ ID: "DEEPSCANV1.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.DeepscanV1.name) },
|
||||
{ ID: "DEEPSCANV2.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.DeepscanV2.name) },
|
||||
{
|
||||
ID: "SERVERPROFILER.EXE",
|
||||
Condition: () => Player.getHomeComputer().programs.includes(Programs.ServerProfiler.name),
|
||||
},
|
||||
{ ID: "AUTOLINK.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.AutoLink.name) },
|
||||
{ ID: "FORMULAS.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.Formulas.name) },
|
||||
{ ID: "FLIGHT.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.Flight.name) },
|
||||
{
|
||||
ID: "NS2",
|
||||
Condition: () =>
|
||||
Player.getHomeComputer().scripts.some((s) => s.filename.endsWith(".js") || s.filename.endsWith(".ns")),
|
||||
},
|
||||
{ ID: "FROZE", Condition: () => location.href.includes("noScripts") },
|
||||
{
|
||||
ID: "RUNNING_SCRIPTS_1000",
|
||||
Condition: () => {
|
||||
let running = 0;
|
||||
for (const s of GetAllServers()) {
|
||||
running += s.runningScripts.length;
|
||||
}
|
||||
return running >= 1000;
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "DRAIN_SERVER",
|
||||
Condition: () => {
|
||||
for (const s of GetAllServers()) {
|
||||
if (s instanceof Server) {
|
||||
if (s.moneyMax > 0 && s.moneyAvailable === 0) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
{ ID: "MAX_RAM", Condition: () => Player.getHomeComputer().maxRam === CONSTANTS.HomeComputerMaxRam },
|
||||
{ ID: "MAX_CORES", Condition: () => Player.getHomeComputer().cpuCores === 8 },
|
||||
{ ID: "SCRIPTS_30", Condition: () => Player.getHomeComputer().scripts.length >= 30 },
|
||||
{ ID: "KARMA_1000000", Condition: () => Player.karma <= -1e6 },
|
||||
{ ID: "STOCK_1q", Condition: () => Player.moneySourceB.stock >= 1e15 },
|
||||
{
|
||||
ID: "DISCOUNT",
|
||||
Condition: () => {
|
||||
const p = GetServer("powerhouse-fitness");
|
||||
if (!(p instanceof Server)) return false;
|
||||
return p.backdoorInstalled;
|
||||
},
|
||||
},
|
||||
|
||||
{ ID: "SCRIPT_32GB", Condition: () => Player.getHomeComputer().scripts.some((s) => s.ramUsage >= 32) },
|
||||
{ ID: "FIRST_HACKNET_SERVER", Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length > 0 },
|
||||
{
|
||||
ID: "ALL_HACKNET_SERVER",
|
||||
Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length === HacknetServerConstants.MaxServers,
|
||||
},
|
||||
{
|
||||
ID: "MAX_HACKNET_SERVER",
|
||||
Condition: () => {
|
||||
if (!hasHacknetServers(Player)) return false;
|
||||
for (const h of Player.hacknetNodes) {
|
||||
if (!(h instanceof HacknetServer)) return false;
|
||||
if (
|
||||
h.maxRam === HacknetServerConstants.MaxRam &&
|
||||
h.cores === HacknetServerConstants.MaxCores &&
|
||||
h.level === HacknetServerConstants.MaxLevel &&
|
||||
h.cache === HacknetServerConstants.MaxCache
|
||||
)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
{ ID: "HACKNET_SERVER_1B", Condition: () => hasHacknetServers(Player) && Player.moneySourceB.hacknet >= 1e9 },
|
||||
{
|
||||
ID: "MAX_CACHE",
|
||||
Condition: () => hasHacknetServers(Player) && Player.hashManager.hashes === Player.hashManager.capacity,
|
||||
},
|
||||
{ ID: "REPUTATION_10M", Condition: () => Object.values(Factions).some((f) => f.playerReputation >= 10e6) },
|
||||
{ ID: "DONATION", Condition: () => Object.values(Factions).some((f) => f.favor >= 150) },
|
||||
{ ID: "TRAVEL", Condition: () => Player.city !== CityName.Sector12 },
|
||||
{
|
||||
ID: "WORKOUT",
|
||||
Condition: () =>
|
||||
[
|
||||
CONSTANTS.ClassGymStrength,
|
||||
CONSTANTS.ClassGymDefense,
|
||||
CONSTANTS.ClassGymDexterity,
|
||||
CONSTANTS.ClassGymAgility,
|
||||
].includes(Player.className),
|
||||
},
|
||||
{ ID: "TOR", Condition: () => Player.hasTorRouter() },
|
||||
{ ID: "4S", Condition: () => Player.has4SData },
|
||||
{ ID: "GANG", Condition: () => Player.gang !== null },
|
||||
{
|
||||
ID: "FULL_GANG",
|
||||
Condition: () => Player.gang !== null && Player.gang.members.length === GangConstants.MaximumGangMembers,
|
||||
},
|
||||
{
|
||||
ID: "GANG_TERRITORY",
|
||||
Condition: () => Player.gang !== null && AllGangs[Player.gang.facName].territory === 1,
|
||||
},
|
||||
{
|
||||
ID: "GANG_MEMBER_POWER",
|
||||
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,
|
||||
),
|
||||
},
|
||||
{ ID: "BLADEBURNER_DIVISION", Condition: () => Player.bladeburner !== null },
|
||||
{
|
||||
ID: "BLADEBURNER_OVERCLOCK",
|
||||
Condition: () =>
|
||||
Player.bladeburner !== null && Player.bladeburner.skills[SkillNames.Overclock] === Skills[SkillNames.Overclock],
|
||||
},
|
||||
{
|
||||
ID: "BLADEBURNER_UNSPENT_100000",
|
||||
Condition: () => Player.bladeburner !== null && Player.bladeburner.skillPoints >= 100000,
|
||||
},
|
||||
{ ID: "CORPORATION", Condition: () => Player.corporation !== null },
|
||||
{
|
||||
ID: "CORPORATION_BRIBE",
|
||||
Condition: () => Player.corporation !== null && Player.corporation.unlockUpgrades[6] === 1,
|
||||
},
|
||||
{
|
||||
ID: "CORPORATION_PROD_1000",
|
||||
Condition: () => Player.corporation !== null && Player.corporation.divisions.some((d) => d.prodMult >= 1000),
|
||||
},
|
||||
{
|
||||
ID: "CORPORATION_EMPLOYEE_3000",
|
||||
Condition: () => {
|
||||
if (Player.corporation === null) return false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "CORPORATION_REAL_ESTATE",
|
||||
Condition: () =>
|
||||
Player.corporation !== null && Player.corporation.divisions.some((d) => d.type === Industries.RealEstate),
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN1",
|
||||
Condition: () =>
|
||||
Player.bitNodeN === 1 &&
|
||||
bitNodeFinishedState() &&
|
||||
Player.getHomeComputer().maxRam <= 32 &&
|
||||
Player.getHomeComputer().cpuCores === 1,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN2",
|
||||
Condition: () => Player.bitNodeN === 2 && bitNodeFinishedState() && Player.gang === null,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN3",
|
||||
Condition: () => Player.bitNodeN === 2 && bitNodeFinishedState() && Player.corporation === null,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN6",
|
||||
Condition: () => Player.bitNodeN === 6 && bitNodeFinishedState() && Player.bladeburner === null,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN7",
|
||||
Condition: () => Player.bitNodeN === 7 && bitNodeFinishedState() && Player.bladeburner === null,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN8",
|
||||
Condition: () => Player.bitNodeN === 8 && bitNodeFinishedState() && !Player.has4SData && !Player.has4SDataTixApi,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN9",
|
||||
Condition: () =>
|
||||
Player.bitNodeN === 9 &&
|
||||
bitNodeFinishedState() &&
|
||||
Player.moneySourceB.hacknet === 0 &&
|
||||
Player.moneySourceB.hacknet_expenses === 0,
|
||||
},
|
||||
{
|
||||
ID: "CHALLENGE_BN10",
|
||||
Condition: () =>
|
||||
Player.bitNodeN === 10 &&
|
||||
bitNodeFinishedState() &&
|
||||
!Player.sleeves.some(
|
||||
(s) =>
|
||||
s.augmentations.length > 0 ||
|
||||
s.hacking_exp > 0 ||
|
||||
s.strength_exp > 0 ||
|
||||
s.defense_exp > 0 ||
|
||||
s.agility_exp > 0 ||
|
||||
s.dexterity_exp > 0 ||
|
||||
s.charisma_exp > 0,
|
||||
),
|
||||
},
|
||||
{
|
||||
ID: "FAST_BN",
|
||||
Condition: () => bitNodeFinishedState() && Player.playtimeSinceLastBitnode < 1000 * 60 * 60 * 24 * 2,
|
||||
},
|
||||
{
|
||||
ID: "INDECISIVE",
|
||||
Condition: (function () {
|
||||
let c = 0;
|
||||
setInterval(() => {
|
||||
if (Router.page() === Page.BitVerse) {
|
||||
c++;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
}, 60 * 1000);
|
||||
return () => c > 60;
|
||||
})(),
|
||||
},
|
||||
{ ID: "HOSPITALIZED", Condition: () => Player.moneySourceB.hospitalization !== 0 },
|
||||
];
|
||||
|
||||
function setAchievements(achs: string[]): void {
|
||||
|
@ -30,7 +30,7 @@ const names: {
|
||||
Bypass: "by circumventing the ram cost of document.",
|
||||
EditSaveFile: "by editing your save file.",
|
||||
PrototypeTampering: "by tampering with Numbers prototype.",
|
||||
TimeCompression: "by compressing time",
|
||||
TimeCompression: "by compressing time.",
|
||||
Unclickable: "by clicking the unclickable.",
|
||||
UndocumentedFunctionCall: "by looking beyond the documentation.",
|
||||
RealityAlteration: "by altering reality to suit your whims.",
|
||||
|
@ -192,14 +192,11 @@ export class Terminal implements ITerminal {
|
||||
const expGainedOnFailure = expGainedOnSuccess / 4;
|
||||
if (rand < hackChance) {
|
||||
// Success!
|
||||
server.backdoorInstalled = true;
|
||||
if (SpecialServers.WorldDaemon === server.hostname) {
|
||||
if (player.bitNodeN == null) {
|
||||
player.bitNodeN = 1;
|
||||
}
|
||||
router.toBitVerse(false, false);
|
||||
return;
|
||||
}
|
||||
server.backdoorInstalled = true;
|
||||
let moneyGained = calculatePercentMoneyHacked(server, player);
|
||||
moneyGained = Math.floor(server.moneyAvailable * moneyGained);
|
||||
|
||||
|
@ -425,7 +425,6 @@ const Engine: {
|
||||
Player.lastUpdate = _thisUpdate - offset;
|
||||
Engine.updateGame(diff);
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(Engine.start);
|
||||
},
|
||||
};
|
||||
|
@ -535,6 +535,8 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
</Select>
|
||||
</ListItem>
|
||||
</List>
|
||||
{!location.href.startsWith("file://") && (
|
||||
<>
|
||||
<ListItem>
|
||||
<Typography>danielyxie / BigD (Original developer): </Typography>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
||||
@ -561,6 +563,8 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
||||
</Link>{" "}
|
||||
</Typography>
|
||||
</ListItem>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<Box>
|
||||
|
Loading…
Reference in New Issue
Block a user