mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-26 16:07:33 +01:00
Merge branch 'dev' into issues/2308
This commit is contained in:
commit
9922ffb3c2
42
dist/vendor.bundle.js
vendored
42
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/vendor.bundle.js.map
vendored
2
dist/vendor.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -347,7 +347,7 @@ Kills all scripts on the current server.
|
||||
ls
|
||||
^^
|
||||
|
||||
$ ls [dir] [| grep pattern]
|
||||
$ ls [dir] [--grep pattern]
|
||||
|
||||
Prints files and directories on the current server to the Terminal screen.
|
||||
|
||||
@ -358,19 +358,21 @@ followed by the files (also in alphabetical order).
|
||||
The :code:`dir` optional parameter allows you to specify the directory for which to display
|
||||
files.
|
||||
|
||||
The :code:`| grep pattern` optional parameter allows you to only display files and directories
|
||||
The :code:`--grep pattern` optional parameter allows you to only display files and directories
|
||||
with a certain pattern in their names.
|
||||
|
||||
The :code:`-l` optional parameter allows you to force each item onto a single line.
|
||||
|
||||
Examples::
|
||||
|
||||
// List files/directories with the '.script' extension in the current directory
|
||||
$ ls | grep .script
|
||||
$ ls -l --grep .script
|
||||
|
||||
// List files/directories with the '.js' extension in the root directory
|
||||
$ ls / | grep .js
|
||||
$ ls / -l --grep .js
|
||||
|
||||
// List files/directories with the word 'purchase' in the name, in the :code:`scripts` directory
|
||||
$ ls scripts | grep purchase
|
||||
$ ls scripts -l --grep purchase
|
||||
|
||||
|
||||
lscpu
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -22,6 +22,8 @@ import { Router } from "../ui/GameRoot";
|
||||
import { Page } from "../ui/Router";
|
||||
import { IMap } from "../types";
|
||||
import * as data from "./AchievementData.json";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { BlackOperationNames } from "../Bladeburner/data/BlackOperationNames";
|
||||
|
||||
// Unable to correctly cast the JSON data into AchievementDataJson type otherwise...
|
||||
const achievementData = (<AchievementDataJson>(<unknown>data)).achievements;
|
||||
@ -56,7 +58,7 @@ 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");
|
||||
return Player.bladeburner !== null && Player.bladeburner.blackops.hasOwnProperty(BlackOperationNames.OperationDaedalus);
|
||||
}
|
||||
|
||||
function hasAccessToSF(player: PlayerObject, bn: number): boolean {
|
||||
@ -82,40 +84,40 @@ function sfAchievement(): Achievement[] {
|
||||
}
|
||||
|
||||
export const achievements: IMap<Achievement> = {
|
||||
CYBERSEC: {
|
||||
...achievementData["CYBERSEC"],
|
||||
[FactionNames.CyberSec.toUpperCase()]: {
|
||||
...achievementData[FactionNames.CyberSec.toUpperCase()],
|
||||
Icon: "CSEC",
|
||||
Condition: () => Player.factions.includes("CyberSec"),
|
||||
Condition: () => Player.factions.includes(FactionNames.CyberSec),
|
||||
},
|
||||
NITESEC: {
|
||||
...achievementData["NITESEC"],
|
||||
Icon: "NiteSec",
|
||||
Condition: () => Player.factions.includes("NiteSec"),
|
||||
[FactionNames.NiteSec.toUpperCase()]: {
|
||||
...achievementData[FactionNames.NiteSec.toUpperCase()],
|
||||
Icon: FactionNames.NiteSec,
|
||||
Condition: () => Player.factions.includes(FactionNames.NiteSec),
|
||||
},
|
||||
THE_BLACK_HAND: {
|
||||
...achievementData["THE_BLACK_HAND"],
|
||||
Icon: "TBH",
|
||||
Condition: () => Player.factions.includes("The Black Hand"),
|
||||
Condition: () => Player.factions.includes(FactionNames.TheBlackHand),
|
||||
},
|
||||
BITRUNNERS: {
|
||||
...achievementData["BITRUNNERS"],
|
||||
Icon: "bitrunners",
|
||||
Condition: () => Player.factions.includes("BitRunners"),
|
||||
[FactionNames.BitRunners.toUpperCase()]: {
|
||||
...achievementData[FactionNames.BitRunners.toUpperCase()],
|
||||
Icon: FactionNames.BitRunners.toLowerCase(),
|
||||
Condition: () => Player.factions.includes(FactionNames.BitRunners),
|
||||
},
|
||||
DAEDALUS: {
|
||||
...achievementData["DAEDALUS"],
|
||||
Icon: "daedalus",
|
||||
Condition: () => Player.factions.includes("Daedalus"),
|
||||
[FactionNames.Daedalus.toUpperCase()]: {
|
||||
...achievementData[FactionNames.Daedalus.toUpperCase()],
|
||||
Icon: FactionNames.Daedalus.toLowerCase(),
|
||||
Condition: () => Player.factions.includes(FactionNames.Daedalus),
|
||||
},
|
||||
THE_COVENANT: {
|
||||
...achievementData["THE_COVENANT"],
|
||||
Icon: "thecovenant",
|
||||
Condition: () => Player.factions.includes("The Covenant"),
|
||||
Icon: FactionNames.TheCovenant.toLowerCase(),
|
||||
Condition: () => Player.factions.includes(FactionNames.TheCovenant),
|
||||
},
|
||||
ILLUMINATI: {
|
||||
...achievementData["ILLUMINATI"],
|
||||
Icon: "illuminati",
|
||||
Condition: () => Player.factions.includes("Illuminati"),
|
||||
[FactionNames.Illuminati.toUpperCase()]: {
|
||||
...achievementData[FactionNames.Illuminati.toUpperCase()],
|
||||
Icon: FactionNames.Illuminati.toLowerCase(),
|
||||
Condition: () => Player.factions.includes(FactionNames.Illuminati),
|
||||
},
|
||||
"BRUTESSH.EXE": {
|
||||
...achievementData["BRUTESSH.EXE"],
|
||||
@ -745,31 +747,31 @@ export const achievements: IMap<Achievement> = {
|
||||
};
|
||||
|
||||
// Steam has a limit of 100 achievement. So these were planned but commented for now.
|
||||
// { ID: "ECORP", Condition: () => Player.factions.includes("ECorp") },
|
||||
// { ID: "MEGACORP", Condition: () => Player.factions.includes("MegaCorp") },
|
||||
// { ID: "BACHMAN_&_ASSOCIATES", Condition: () => Player.factions.includes("Bachman & Associates") },
|
||||
// { ID: "BLADE_INDUSTRIES", Condition: () => Player.factions.includes("Blade Industries") },
|
||||
// { ID: "NWO", Condition: () => Player.factions.includes("NWO") },
|
||||
// { ID: "CLARKE_INCORPORATED", Condition: () => Player.factions.includes("Clarke Incorporated") },
|
||||
// { ID: "OMNITEK_INCORPORATED", Condition: () => Player.factions.includes("OmniTek Incorporated") },
|
||||
// { ID: "FOUR_SIGMA", Condition: () => Player.factions.includes("Four Sigma") },
|
||||
// { ID: "KUAIGONG_INTERNATIONAL", Condition: () => Player.factions.includes("KuaiGong International") },
|
||||
// { ID: "FULCRUM_SECRET_TECHNOLOGIES", Condition: () => Player.factions.includes("Fulcrum Secret Technologies") },
|
||||
// { ID: "AEVUM", Condition: () => Player.factions.includes("Aevum") },
|
||||
// { ID: "CHONGQING", Condition: () => Player.factions.includes("Chongqing") },
|
||||
// { ID: "ISHIMA", Condition: () => Player.factions.includes("Ishima") },
|
||||
// { ID: "NEW_TOKYO", Condition: () => Player.factions.includes("New Tokyo") },
|
||||
// { ID: "SECTOR-12", Condition: () => Player.factions.includes("Sector-12") },
|
||||
// { ID: "VOLHAVEN", Condition: () => Player.factions.includes("Volhaven") },
|
||||
// { ID: "SPEAKERS_FOR_THE_DEAD", Condition: () => Player.factions.includes("Speakers for the Dead") },
|
||||
// { ID: "THE_DARK_ARMY", Condition: () => Player.factions.includes("The Dark Army") },
|
||||
// { ID: "THE_SYNDICATE", Condition: () => Player.factions.includes("The Syndicate") },
|
||||
// { ID: "SILHOUETTE", Condition: () => Player.factions.includes("Silhouette") },
|
||||
// { ID: "TETRADS", Condition: () => Player.factions.includes("Tetrads") },
|
||||
// { ID: "SLUM_SNAKES", Condition: () => Player.factions.includes("Slum Snakes") },
|
||||
// { ID: "NETBURNERS", Condition: () => Player.factions.includes("Netburners") },
|
||||
// { ID: "TIAN_DI_HUI", Condition: () => Player.factions.includes("Tian Di Hui") },
|
||||
// { ID: "BLADEBURNERS", Condition: () => Player.factions.includes("Bladeburners") },
|
||||
// { ID: FactionNames.ECorp.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.ECorp) },
|
||||
// { ID: FactionNames.MegaCorp.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.MegaCorp) },
|
||||
// { ID: "BACHMAN_&_ASSOCIATES", Condition: () => Player.factions.includes(FactionNames.BachmanAssociates) },
|
||||
// { ID: "BLADE_INDUSTRIES", Condition: () => Player.factions.includes(FactionNames.BladeIndustries) },
|
||||
// { ID: FactionNames.NWO.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.NWO) },
|
||||
// { ID: "CLARKE_INCORPORATED", Condition: () => Player.factions.includes(FactionNames.ClarkeIncorporated) },
|
||||
// { ID: "OMNITEK_INCORPORATED", Condition: () => Player.factions.includes(FactionNames.OmniTekIncorporated) },
|
||||
// { ID: "FOUR_SIGMA", Condition: () => Player.factions.includes(FactionNames.FourSigma) },
|
||||
// { ID: "KUAIGONG_INTERNATIONAL", Condition: () => Player.factions.includes(FactionNames.KuaiGongInternational) },
|
||||
// { ID: "FULCRUM_SECRET_TECHNOLOGIES", Condition: () => Player.factions.includes(FactionNames.FulcrumSecretTechnologies) },
|
||||
// { ID: FactionNames.Aevum.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Aevum) },
|
||||
// { ID: FactionNames.Chongqing.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Chongqing) },
|
||||
// { ID: FactionNames.Ishima.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Ishima) },
|
||||
// { ID: "NEW_TOKYO", Condition: () => Player.factions.includes(FactionNames.NewTokyo) },
|
||||
// { ID: "SECTOR-12", Condition: () => Player.factions.includes(FactionNames.Sector12) },
|
||||
// { ID: FactionNames.Volhaven.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Volhaven) },
|
||||
// { ID: "SPEAKERS_FOR_THE_DEAD", Condition: () => Player.factions.includes(FactionNames.SpeakersForTheDead) },
|
||||
// { ID: "THE_DARK_ARMY", Condition: () => Player.factions.includes(FactionNames.TheDarkArmy) },
|
||||
// { ID: "THE_SYNDICATE", Condition: () => Player.factions.includes(FactionNames.TheSyndicate) },
|
||||
// { ID: FactionNames.Silhouette.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Silhouette) },
|
||||
// { ID: FactionNames.Tetrads.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Tetrads) },
|
||||
// { ID: "SLUM_SNAKES", Condition: () => Player.factions.includes(FactionNames.SlumSnakes) },
|
||||
// { ID: FactionNames.Netburners.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Netburners) },
|
||||
// { ID: "TIAN_DI_HUI", Condition: () => Player.factions.includes(FactionNames.TianDiHui) },
|
||||
// { ID: FactionNames.Bladeburners.toUpperCase(), Condition: () => Player.factions.includes(FactionNames.Bladeburners) },
|
||||
// { ID: "DEEPSCANV1.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.DeepscanV1.name) },
|
||||
// { ID: "DEEPSCANV2.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.DeepscanV2.name) },
|
||||
// {
|
||||
|
@ -18,6 +18,7 @@ export interface IConstructorParams {
|
||||
name: string;
|
||||
prereqs?: string[];
|
||||
repCost: number;
|
||||
factions: string[];
|
||||
|
||||
hacking_mult?: number;
|
||||
strength_mult?: number;
|
||||
@ -393,12 +394,16 @@ export class Augmentation {
|
||||
// Initial cost. Doesn't change when you purchase multiple Augmentation
|
||||
startingCost = 0;
|
||||
|
||||
// Factions that offer this aug.
|
||||
factions: string[] = [];
|
||||
|
||||
constructor(
|
||||
params: IConstructorParams = {
|
||||
info: "",
|
||||
moneyCost: 0,
|
||||
name: "",
|
||||
repCost: 0,
|
||||
factions: [],
|
||||
},
|
||||
) {
|
||||
this.name = params.name;
|
||||
@ -408,6 +413,7 @@ export class Augmentation {
|
||||
this.baseRepRequirement = params.repCost * BitNodeMultipliers.AugmentationRepCost;
|
||||
this.baseCost = params.moneyCost * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
this.startingCost = this.baseCost;
|
||||
this.factions = params.factions;
|
||||
|
||||
if (params.isSpecial) {
|
||||
this.isSpecial = true;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@ import React from "react";
|
||||
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { IMap } from "../types";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
|
||||
class BitNode {
|
||||
// A short description, or tagline, about the BitNode
|
||||
@ -80,8 +82,7 @@ BitNodes["BitNode2"] = new BitNode(
|
||||
<br />
|
||||
The amount of money gained from crimes and Infiltration is tripled
|
||||
<br />
|
||||
Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, NiteSec, The Black
|
||||
Hand) give the player the ability to form and manage their own gangs. These gangs will earn the player money and
|
||||
Certain Factions ({FactionNames.SlumSnakes}, {FactionNames.Tetrads}, {FactionNames.TheSyndicate}, {FactionNames.TheDarkArmy}, {FactionNames.SpeakersForTheDead}, {FactionNames.NiteSec}, {FactionNames.TheBlackHand}) give the player the ability to form and manage their own gangs. These gangs will earn the player money and
|
||||
reputation with the corresponding Faction
|
||||
<br />
|
||||
Every Augmentation in the game will be available through the Factions listed above
|
||||
@ -220,18 +221,18 @@ BitNodes["BitNode5"] = new BitNode(
|
||||
BitNodes["BitNode6"] = new BitNode(
|
||||
6,
|
||||
1,
|
||||
"Bladeburners",
|
||||
FactionNames.Bladeburners,
|
||||
"Like Tears in Rain",
|
||||
(
|
||||
<>
|
||||
In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic
|
||||
In the middle of the 21st century, {FactionNames.OmniTekIncorporated} began designing and manufacturing advanced synthetic
|
||||
androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation of
|
||||
their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was the first
|
||||
sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent than
|
||||
the humans that had created them.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will be able to access the Bladeburner Division at the NSA, which provides a new mechanic for
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} Division at the NSA, which provides a new mechanic for
|
||||
progression. Furthermore:
|
||||
<br />
|
||||
<br />
|
||||
@ -249,7 +250,7 @@ BitNodes["BitNode6"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to access the NSA's Bladeburner Division in other
|
||||
level up to a maximum of 3. This Source-File allows you to access the NSA's {FactionNames.Bladeburners} Division in other
|
||||
BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat
|
||||
stats by:
|
||||
<br />
|
||||
@ -265,23 +266,23 @@ BitNodes["BitNode6"] = new BitNode(
|
||||
BitNodes["BitNode7"] = new BitNode(
|
||||
7,
|
||||
2,
|
||||
"Bladeburners 2079",
|
||||
`${FactionNames.Bladeburners} 2079`,
|
||||
"More human than humans",
|
||||
(
|
||||
<>
|
||||
In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI
|
||||
In the middle of the 21st century, you were doing cutting-edge work at {FactionNames.OmniTekIncorporated} as part of the AI
|
||||
design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological
|
||||
breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a
|
||||
hyperintelligent AI. Many argue that this was the first sentient AI ever created. This resulted in Synthoid models
|
||||
that were stronger, faster, and more intelligent than the humans that had created them.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} API, which allows you to access {FactionNames.Bladeburners}
|
||||
functionality through Netscript. Furthermore: <br />
|
||||
<br />
|
||||
The rank you gain from Bladeburner contracts/operations is reduced by 40%
|
||||
The rank you gain from {FactionNames.Bladeburners} contracts/operations is reduced by 40%
|
||||
<br />
|
||||
Bladeburner skills cost twice as many skill points
|
||||
{FactionNames.Bladeburners} skills cost twice as many skill points
|
||||
<br />
|
||||
Augmentations are 3x more expensive
|
||||
<br />
|
||||
@ -299,8 +300,8 @@ BitNodes["BitNode7"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other BitNodes.
|
||||
In addition, this Source-File will increase all of your Bladeburner multipliers by:
|
||||
level up to a maximum of 3. This Source-File allows you to access the {FactionNames.Bladeburners} Netscript API in other BitNodes.
|
||||
In addition, this Source-File will increase all of your {FactionNames.Bladeburners} multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
@ -363,9 +364,9 @@ BitNodes["BitNode9"] = new BitNode(
|
||||
"Hacknet Unleashed",
|
||||
(
|
||||
<>
|
||||
When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly became the OS of choice for
|
||||
When {FactionNames.FulcrumSecretTechnologies} released their open-source Linux distro Chapeau, it quickly became the OS of choice for
|
||||
the underground hacking community. Chapeau became especially notorious for powering the Hacknet, a global,
|
||||
decentralized network used for nefarious purposes. Fulcrum quickly abandoned the project and dissociated
|
||||
decentralized network used for nefarious purposes. {FactionNames.FulcrumSecretTechnologies} quickly abandoned the project and dissociated
|
||||
themselves from it.
|
||||
<br />
|
||||
<br />
|
||||
@ -537,12 +538,12 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
"1 step back, 2 steps forward",
|
||||
(
|
||||
<>
|
||||
With the invention of Augmentations in the 2040s a religious group known as the Church of the Machine God has
|
||||
With the invention of Augmentations in the 2040s a religious group known as the {FactionNames.ChurchOfTheMachineGod} has
|
||||
rallied far more support than anyone would have hoped.
|
||||
<br />
|
||||
<br />
|
||||
Their leader, Allison "Mother" Stanek is said to have created her own Augmentation whose power goes beyond any
|
||||
other. Find her in Chongqing and gain her trust.
|
||||
other. Find her in {CityName.Chongqing} and gain her trust.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode:
|
||||
@ -554,7 +555,7 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 13, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets the Church of the Machine God appear in other BitNodes.
|
||||
level up to a maximum of 3. This Source-File lets the {FactionNames.ChurchOfTheMachineGod} appear in other BitNodes.
|
||||
<br />
|
||||
<br />
|
||||
Each level of this Source-File increases the size of Stanek's Gift.
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { BlackOperation } from "./BlackOperation";
|
||||
import { IMap } from "../types";
|
||||
import { BlackOperationNames } from "./data/BlackOperationNames";
|
||||
|
||||
export const BlackOperations: IMap<BlackOperation> = {};
|
||||
|
||||
(function () {
|
||||
BlackOperations["Operation Typhoon"] = new BlackOperation({
|
||||
name: "Operation Typhoon",
|
||||
BlackOperations[BlackOperationNames.OperationTyphoon] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationTyphoon,
|
||||
baseDifficulty: 2000,
|
||||
reqdRank: 2.5e3,
|
||||
rankGain: 50,
|
||||
@ -31,8 +32,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Zero"] = new BlackOperation({
|
||||
name: "Operation Zero",
|
||||
BlackOperations[BlackOperationNames.OperationZero] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationZero,
|
||||
baseDifficulty: 2500,
|
||||
reqdRank: 5e3,
|
||||
rankGain: 60,
|
||||
@ -58,8 +59,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isStealth: true,
|
||||
});
|
||||
BlackOperations["Operation X"] = new BlackOperation({
|
||||
name: "Operation X",
|
||||
BlackOperations[BlackOperationNames.OperationX] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationX,
|
||||
baseDifficulty: 3000,
|
||||
reqdRank: 7.5e3,
|
||||
rankGain: 75,
|
||||
@ -85,8 +86,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Titan"] = new BlackOperation({
|
||||
name: "Operation Titan",
|
||||
BlackOperations[BlackOperationNames.OperationTitan] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationTitan,
|
||||
baseDifficulty: 4000,
|
||||
reqdRank: 10e3,
|
||||
rankGain: 100,
|
||||
@ -112,8 +113,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Ares"] = new BlackOperation({
|
||||
name: "Operation Ares",
|
||||
BlackOperations[BlackOperationNames.OperationAres] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationAres,
|
||||
baseDifficulty: 5000,
|
||||
reqdRank: 12.5e3,
|
||||
rankGain: 125,
|
||||
@ -139,8 +140,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Archangel"] = new BlackOperation({
|
||||
name: "Operation Archangel",
|
||||
BlackOperations[BlackOperationNames.OperationArchangel] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationArchangel,
|
||||
baseDifficulty: 7500,
|
||||
reqdRank: 15e3,
|
||||
rankGain: 200,
|
||||
@ -166,8 +167,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Juggernaut"] = new BlackOperation({
|
||||
name: "Operation Juggernaut",
|
||||
BlackOperations[BlackOperationNames.OperationJuggernaut] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationJuggernaut,
|
||||
baseDifficulty: 10e3,
|
||||
reqdRank: 20e3,
|
||||
rankGain: 300,
|
||||
@ -193,8 +194,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Red Dragon"] = new BlackOperation({
|
||||
name: "Operation Red Dragon",
|
||||
BlackOperations[BlackOperationNames.OperationRedDragon] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationRedDragon,
|
||||
baseDifficulty: 12.5e3,
|
||||
reqdRank: 25e3,
|
||||
rankGain: 500,
|
||||
@ -220,8 +221,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation K"] = new BlackOperation({
|
||||
name: "Operation K",
|
||||
BlackOperations[BlackOperationNames.OperationK] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationK,
|
||||
baseDifficulty: 15e3,
|
||||
reqdRank: 30e3,
|
||||
rankGain: 750,
|
||||
@ -247,8 +248,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Deckard"] = new BlackOperation({
|
||||
name: "Operation Deckard",
|
||||
BlackOperations[BlackOperationNames.OperationDeckard] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationDeckard,
|
||||
baseDifficulty: 20e3,
|
||||
reqdRank: 40e3,
|
||||
rankGain: 1e3,
|
||||
@ -274,8 +275,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Tyrell"] = new BlackOperation({
|
||||
name: "Operation Tyrell",
|
||||
BlackOperations[BlackOperationNames.OperationTyrell] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationTyrell,
|
||||
baseDifficulty: 25e3,
|
||||
reqdRank: 50e3,
|
||||
rankGain: 1.5e3,
|
||||
@ -301,8 +302,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Wallace"] = new BlackOperation({
|
||||
name: "Operation Wallace",
|
||||
BlackOperations[BlackOperationNames.OperationWallace] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationWallace,
|
||||
baseDifficulty: 30e3,
|
||||
reqdRank: 75e3,
|
||||
rankGain: 2e3,
|
||||
@ -328,8 +329,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({
|
||||
name: "Operation Shoulder of Orion",
|
||||
BlackOperations[BlackOperationNames.OperationShoulderOfOrion] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationShoulderOfOrion,
|
||||
baseDifficulty: 35e3,
|
||||
reqdRank: 100e3,
|
||||
rankGain: 2.5e3,
|
||||
@ -355,8 +356,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isStealth: true,
|
||||
});
|
||||
BlackOperations["Operation Hyron"] = new BlackOperation({
|
||||
name: "Operation Hyron",
|
||||
BlackOperations[BlackOperationNames.OperationHyron] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationHyron,
|
||||
baseDifficulty: 40e3,
|
||||
reqdRank: 125e3,
|
||||
rankGain: 3e3,
|
||||
@ -382,8 +383,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Morpheus"] = new BlackOperation({
|
||||
name: "Operation Morpheus",
|
||||
BlackOperations[BlackOperationNames.OperationMorpheus] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationMorpheus,
|
||||
baseDifficulty: 45e3,
|
||||
reqdRank: 150e3,
|
||||
rankGain: 4e3,
|
||||
@ -409,8 +410,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isStealth: true,
|
||||
});
|
||||
BlackOperations["Operation Ion Storm"] = new BlackOperation({
|
||||
name: "Operation Ion Storm",
|
||||
BlackOperations[BlackOperationNames.OperationIonStorm] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationIonStorm,
|
||||
baseDifficulty: 50e3,
|
||||
reqdRank: 175e3,
|
||||
rankGain: 5e3,
|
||||
@ -436,8 +437,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Annihilus"] = new BlackOperation({
|
||||
name: "Operation Annihilus",
|
||||
BlackOperations[BlackOperationNames.OperationAnnihilus] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationAnnihilus,
|
||||
baseDifficulty: 55e3,
|
||||
reqdRank: 200e3,
|
||||
rankGain: 7.5e3,
|
||||
@ -463,8 +464,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Ultron"] = new BlackOperation({
|
||||
name: "Operation Ultron",
|
||||
BlackOperations[BlackOperationNames.OperationUltron] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationUltron,
|
||||
baseDifficulty: 60e3,
|
||||
reqdRank: 250e3,
|
||||
rankGain: 10e3,
|
||||
@ -490,8 +491,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
},
|
||||
isKill: true,
|
||||
});
|
||||
BlackOperations["Operation Centurion"] = new BlackOperation({
|
||||
name: "Operation Centurion",
|
||||
BlackOperations[BlackOperationNames.OperationCenturion] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationCenturion,
|
||||
baseDifficulty: 70e3,
|
||||
reqdRank: 300e3,
|
||||
rankGain: 15e3,
|
||||
@ -516,8 +517,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
int: 0.75,
|
||||
},
|
||||
});
|
||||
BlackOperations["Operation Vindictus"] = new BlackOperation({
|
||||
name: "Operation Vindictus",
|
||||
BlackOperations[BlackOperationNames.OperationVindictus] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationVindictus,
|
||||
baseDifficulty: 75e3,
|
||||
reqdRank: 350e3,
|
||||
rankGain: 20e3,
|
||||
@ -542,8 +543,8 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
int: 0.75,
|
||||
},
|
||||
});
|
||||
BlackOperations["Operation Daedalus"] = new BlackOperation({
|
||||
name: "Operation Daedalus",
|
||||
BlackOperations[BlackOperationNames.OperationDaedalus] = new BlackOperation({
|
||||
name: BlackOperationNames.OperationDaedalus,
|
||||
baseDifficulty: 80e3,
|
||||
reqdRank: 400e3,
|
||||
rankGain: 40e3,
|
||||
|
@ -33,6 +33,8 @@ import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { getTimestamp } from "../utils/helpers/getTimestamp";
|
||||
import { joinFaction } from "../Faction/FactionHelpers";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { BlackOperationNames } from "./data/BlackOperationNames";
|
||||
|
||||
interface BlackOpsAttempt {
|
||||
error?: string;
|
||||
@ -229,7 +231,6 @@ export class Bladeburner implements IBladeburner {
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid Action Type in startAction(Bladeburner,player, ): " + actionId.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +292,7 @@ export class Bladeburner implements IBladeburner {
|
||||
|
||||
prestige(): void {
|
||||
this.resetAction();
|
||||
const bladeburnerFac = Factions["Bladeburners"];
|
||||
const bladeburnerFac = Factions[FactionNames.Bladeburners];
|
||||
if (this.rank >= BladeburnerConstants.RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
}
|
||||
@ -320,7 +321,6 @@ export class Bladeburner implements IBladeburner {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "operation":
|
||||
case "operations":
|
||||
case "op":
|
||||
@ -332,7 +332,6 @@ export class Bladeburner implements IBladeburner {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "blackoperation":
|
||||
case "black operation":
|
||||
case "black operations":
|
||||
@ -347,7 +346,6 @@ export class Bladeburner implements IBladeburner {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "general":
|
||||
case "general action":
|
||||
case "gen":
|
||||
@ -672,15 +670,15 @@ export class Bladeburner implements IBladeburner {
|
||||
this.postToConsole("Automation: " + (this.automateEnabled ? "enabled" : "disabled"));
|
||||
this.postToConsole(
|
||||
"When your stamina drops to " +
|
||||
formatNumber(this.automateThreshLow, 0) +
|
||||
", you will automatically switch to " +
|
||||
this.automateActionLow.name +
|
||||
". When your stamina recovers to " +
|
||||
formatNumber(this.automateThreshHigh, 0) +
|
||||
", you will automatically " +
|
||||
"switch to " +
|
||||
this.automateActionHigh.name +
|
||||
".",
|
||||
formatNumber(this.automateThreshLow, 0) +
|
||||
", you will automatically switch to " +
|
||||
this.automateActionLow.name +
|
||||
". When your stamina recovers to " +
|
||||
formatNumber(this.automateThreshHigh, 0) +
|
||||
", you will automatically " +
|
||||
"switch to " +
|
||||
this.automateActionHigh.name +
|
||||
".",
|
||||
);
|
||||
} else if (flag.toLowerCase().includes("en")) {
|
||||
if (
|
||||
@ -975,8 +973,8 @@ export class Bladeburner implements IBladeburner {
|
||||
if (this.logging.events) {
|
||||
this.log(
|
||||
"Intelligence indicates that a large number of Synthoids migrated from " +
|
||||
sourceCityName +
|
||||
" to some other city",
|
||||
sourceCityName +
|
||||
" to some other city",
|
||||
);
|
||||
}
|
||||
} else if (chance <= 0.7) {
|
||||
@ -1291,10 +1289,10 @@ export class Bladeburner implements IBladeburner {
|
||||
} else if (!isOperation && this.logging.contracts) {
|
||||
this.log(
|
||||
action.name +
|
||||
" contract successfully completed! Gained " +
|
||||
formatNumber(gain, 3) +
|
||||
" rank and " +
|
||||
numeralWrapper.formatMoney(moneyGain),
|
||||
" contract successfully completed! Gained " +
|
||||
formatNumber(gain, 3) +
|
||||
" rank and " +
|
||||
numeralWrapper.formatMoney(moneyGain),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1375,7 +1373,7 @@ export class Bladeburner implements IBladeburner {
|
||||
teamLossMax = Math.ceil(teamCount / 2);
|
||||
|
||||
// Operation Daedalus
|
||||
if (action.name === "Operation Daedalus") {
|
||||
if (action.name === BlackOperationNames.OperationDaedalus) {
|
||||
this.resetAction();
|
||||
return router.toBitVerse(false, false);
|
||||
}
|
||||
@ -1405,11 +1403,11 @@ export class Bladeburner implements IBladeburner {
|
||||
if (this.logging.blackops) {
|
||||
this.log(
|
||||
action.name +
|
||||
" failed! Lost " +
|
||||
formatNumber(rankLoss, 1) +
|
||||
" rank and took " +
|
||||
formatNumber(damage, 0) +
|
||||
" damage",
|
||||
" failed! Lost " +
|
||||
formatNumber(rankLoss, 1) +
|
||||
" rank and took " +
|
||||
formatNumber(damage, 0) +
|
||||
" damage",
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1445,16 +1443,16 @@ export class Bladeburner implements IBladeburner {
|
||||
if (this.logging.general) {
|
||||
this.log(
|
||||
"Training completed. Gained: " +
|
||||
formatNumber(strExpGain, 1) +
|
||||
" str exp, " +
|
||||
formatNumber(defExpGain, 1) +
|
||||
" def exp, " +
|
||||
formatNumber(dexExpGain, 1) +
|
||||
" dex exp, " +
|
||||
formatNumber(agiExpGain, 1) +
|
||||
" agi exp, " +
|
||||
formatNumber(staminaGain, 3) +
|
||||
" max stamina",
|
||||
formatNumber(strExpGain, 1) +
|
||||
" str exp, " +
|
||||
formatNumber(defExpGain, 1) +
|
||||
" def exp, " +
|
||||
formatNumber(dexExpGain, 1) +
|
||||
" dex exp, " +
|
||||
formatNumber(agiExpGain, 1) +
|
||||
" agi exp, " +
|
||||
formatNumber(staminaGain, 3) +
|
||||
" max stamina",
|
||||
);
|
||||
}
|
||||
this.startAction(player, this.action); // Repeat action
|
||||
@ -1481,10 +1479,10 @@ export class Bladeburner implements IBladeburner {
|
||||
if (this.logging.general) {
|
||||
this.log(
|
||||
"Field analysis completed. Gained 0.1 rank, " +
|
||||
formatNumber(hackingExpGain, 1) +
|
||||
" hacking exp, and " +
|
||||
formatNumber(charismaExpGain, 1) +
|
||||
" charisma exp",
|
||||
formatNumber(hackingExpGain, 1) +
|
||||
" hacking exp, and " +
|
||||
formatNumber(charismaExpGain, 1) +
|
||||
" charisma exp",
|
||||
);
|
||||
}
|
||||
this.startAction(player, this.action); // Repeat action
|
||||
@ -1531,8 +1529,7 @@ export class Bladeburner implements IBladeburner {
|
||||
this.startAction(player, this.action);
|
||||
if (this.logging.general) {
|
||||
this.log(
|
||||
`Rested in Hyperbolic Regeneration Chamber. Restored ${
|
||||
BladeburnerConstants.HrcHpGain
|
||||
`Rested in Hyperbolic Regeneration Chamber. Restored ${BladeburnerConstants.HrcHpGain
|
||||
} HP and gained ${numeralWrapper.formatStamina(staminaGain)} stamina`,
|
||||
);
|
||||
}
|
||||
@ -1577,11 +1574,11 @@ export class Bladeburner implements IBladeburner {
|
||||
}
|
||||
this.maxRank = Math.max(this.rank, this.maxRank);
|
||||
|
||||
const bladeburnersFactionName = "Bladeburners";
|
||||
const bladeburnersFactionName = FactionNames.Bladeburners;
|
||||
if (factionExists(bladeburnersFactionName)) {
|
||||
const bladeburnerFac = Factions[bladeburnersFactionName];
|
||||
if (!(bladeburnerFac instanceof Faction)) {
|
||||
throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");
|
||||
throw new Error(`Could not properly get ${FactionNames.Bladeburners} Faction object in ${FactionNames.Bladeburners} UI Overview Faction button`);
|
||||
}
|
||||
if (bladeburnerFac.isMember) {
|
||||
const favorBonus = 1 + bladeburnerFac.favor / 100;
|
||||
@ -1918,7 +1915,7 @@ export class Bladeburner implements IBladeburner {
|
||||
if (!router.isInitialized) return;
|
||||
|
||||
// Edge case condition...if Operation Daedalus is complete trigger the BitNode
|
||||
if (router.page() !== Page.BitVerse && this.blackops.hasOwnProperty("Operation Daedalus")) {
|
||||
if (router.page() !== Page.BitVerse && this.blackops.hasOwnProperty(BlackOperationNames.OperationDaedalus)) {
|
||||
return router.toBitVerse(false, false);
|
||||
}
|
||||
|
||||
@ -2340,12 +2337,12 @@ export class Bladeburner implements IBladeburner {
|
||||
}
|
||||
|
||||
joinBladeburnerFactionNetscriptFn(workerScript: WorkerScript): boolean {
|
||||
const bladeburnerFac = Factions["Bladeburners"];
|
||||
const bladeburnerFac = Factions[FactionNames.Bladeburners];
|
||||
if (bladeburnerFac.isMember) {
|
||||
return true;
|
||||
} else if (this.rank >= BladeburnerConstants.RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
workerScript.log("bladeburner.joinBladeburnerFaction", () => "Joined Bladeburners faction.");
|
||||
workerScript.log("bladeburner.joinBladeburnerFaction", () => `Joined ${FactionNames.Bladeburners} faction.`);
|
||||
return true;
|
||||
} else {
|
||||
workerScript.log(
|
||||
|
23
src/Bladeburner/data/BlackOperationNames.ts
Normal file
23
src/Bladeburner/data/BlackOperationNames.ts
Normal file
@ -0,0 +1,23 @@
|
||||
export enum BlackOperationNames {
|
||||
OperationTyphoon = "Operation Typhoon",
|
||||
OperationZero = "Operation Zero",
|
||||
OperationX = "Operation X",
|
||||
OperationTitan = "Operation Titan",
|
||||
OperationAres = "Operation Ares",
|
||||
OperationArchangel = "Operation Archangel",
|
||||
OperationJuggernaut = "Operation Juggernaut",
|
||||
OperationRedDragon = "Operation Red Dragon",
|
||||
OperationK = "Operation K",
|
||||
OperationDeckard = "Operation Deckard",
|
||||
OperationTyrell = "Operation Tyrell",
|
||||
OperationWallace = "Operation Wallace",
|
||||
OperationShoulderOfOrion = "Operation Shoulder of Orion",
|
||||
OperationHyron = "Operation Hyron",
|
||||
OperationMorpheus = "Operation Morpheus",
|
||||
OperationIonStorm = "Operation Ion Storm",
|
||||
OperationAnnihilus = "Operation Annihilus",
|
||||
OperationUltron = "Operation Ultron",
|
||||
OperationCenturion = "Operation Centurion",
|
||||
OperationVindictus = "Operation Vindictus",
|
||||
OperationDaedalus = "Operation Daedalus",
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
import React from "react";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
import { BlackOperationNames } from "./BlackOperationNames";
|
||||
|
||||
interface IBlackOp {
|
||||
desc: JSX.Element;
|
||||
@ -7,34 +10,34 @@ interface IBlackOp {
|
||||
export const BlackOperations: {
|
||||
[key: string]: IBlackOp | undefined;
|
||||
} = {
|
||||
"Operation Typhoon": {
|
||||
[BlackOperationNames.OperationTyphoon]: {
|
||||
desc: (
|
||||
<>
|
||||
Obadiah Zenyatta is the leader of a RedWater PMC. It has long been known among the intelligence community that
|
||||
Zenyatta, along with the rest of the PMC, is a Synthoid.
|
||||
<br />
|
||||
<br />
|
||||
The goal of Operation Typhoon is to find and eliminate Zenyatta and RedWater by any means necessary. After the
|
||||
The goal of {BlackOperationNames.OperationTyphoon} is to find and eliminate Zenyatta and RedWater by any means necessary. After the
|
||||
task is completed, the actions must be covered up from the general public.
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
||||
"Operation Zero": {
|
||||
[BlackOperationNames.OperationZero]: {
|
||||
desc: (
|
||||
<>
|
||||
AeroCorp is one of the world's largest defense contractors. Its leader, Steve Watataki, is thought to be a
|
||||
supporter of Synthoid rights. He must be removed.
|
||||
<br />
|
||||
<br />
|
||||
The goal of Operation Zero is to covertly infiltrate AeroCorp and uncover any incriminating evidence or
|
||||
The goal of {BlackOperationNames.OperationZero} is to covertly infiltrate AeroCorp and uncover any incriminating evidence or
|
||||
information against Watataki that will cause him to be removed from his position at AeroCorp. Incriminating
|
||||
evidence can be fabricated as a last resort. Be warned that AeroCorp has some of the most advanced security
|
||||
measures in the world.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation X": {
|
||||
[BlackOperationNames.OperationX]: {
|
||||
desc: (
|
||||
<>
|
||||
We have recently discovered an underground publication group called Samizdat. Even though most of their
|
||||
@ -44,12 +47,12 @@ export const BlackOperations: {
|
||||
<br />
|
||||
<br />
|
||||
Samizdat has done a good job of keeping hidden and anonymous. However, we've just received intelligence that
|
||||
their base of operations is in Ishima's underground sewer systems. Your task is to investigate the sewer
|
||||
their base of operations is in {CityName.Ishima}'s underground sewer systems. Your task is to investigate the sewer
|
||||
systems, and eliminate Samizdat. They must never publish anything again.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Titan": {
|
||||
[BlackOperationNames.OperationTitan]: {
|
||||
desc: (
|
||||
<>
|
||||
Several months ago Titan Laboratories' Bioengineering department was infiltrated by Synthoids. As far as we
|
||||
@ -58,13 +61,13 @@ export const BlackOperations: {
|
||||
dangerous.
|
||||
<br />
|
||||
<br />
|
||||
Your goal is to enter and destroy the Bioengineering department's facility in Aevum. The task is not just to
|
||||
Your goal is to enter and destroy the Bioengineering department's facility in {CityName.Aevum}. The task is not just to
|
||||
retire the Synthoids there, but also to destroy any information or research at the facility that is relevant to
|
||||
the Synthoids and their goals.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Ares": {
|
||||
[BlackOperationNames.OperationAres]: {
|
||||
desc: (
|
||||
<>
|
||||
One of our undercover agents, Agent Carter, has informed us of a massive weapons deal going down in Dubai
|
||||
@ -76,7 +79,7 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Archangel": {
|
||||
[BlackOperationNames.OperationArchangel]: {
|
||||
desc: (
|
||||
<>
|
||||
Our analysts have discovered that the popular Red Rabbit brothel in Amsterdam is run and 'staffed' by MK-VI
|
||||
@ -89,11 +92,11 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Juggernaut": {
|
||||
[BlackOperationNames.OperationJuggernaut]: {
|
||||
desc: (
|
||||
<>
|
||||
The CIA has just encountered a new security threat. A new criminal group, lead by a shadowy operative who calls
|
||||
himself Juggernaut, has been smuggling drugs and weapons (including suspected bioweapons) into Sector-12. We
|
||||
himself Juggernaut, has been smuggling drugs and weapons (including suspected bioweapons) into {CityName.Sector12}. We
|
||||
also have reason to believe they tried to break into one of Universal Energy's facilities in order to cause a
|
||||
city-wide blackout. The CIA suspects that Juggernaut is a heavily-augmented Synthoid, and have thus enlisted our
|
||||
help.
|
||||
@ -103,20 +106,20 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Red Dragon": {
|
||||
[BlackOperationNames.OperationRedDragon]: {
|
||||
desc: (
|
||||
<>
|
||||
The Tetrads criminal organization is suspected of reverse-engineering the MK-VI Synthoid design. We believe they
|
||||
The {FactionNames.Tetrads} criminal organization is suspected of reverse-engineering the MK-VI Synthoid design. We believe they
|
||||
altered and possibly improved the design and began manufacturing their own Synthoid models in order to bolster
|
||||
their criminal activities.
|
||||
<br />
|
||||
<br />
|
||||
Your task is to infiltrate and destroy the Tetrads' base of operations in Los Angeles. Intelligence tells us
|
||||
Your task is to infiltrate and destroy the {FactionNames.Tetrads}' base of operations in Los Angeles. Intelligence tells us
|
||||
that their base houses one of their Synthoid manufacturing units.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation K": {
|
||||
[BlackOperationNames.OperationK]: {
|
||||
desc: (
|
||||
<>
|
||||
CODE RED SITUATION. Our intelligence tells us that VitaLife has discovered a new android cloning technology.
|
||||
@ -132,49 +135,49 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Deckard": {
|
||||
[BlackOperationNames.OperationDeckard]: {
|
||||
desc: (
|
||||
<>
|
||||
Despite your success in eliminating VitaLife's new android-replicating technology in Operation K, we've
|
||||
Despite your success in eliminating VitaLife's new android-replicating technology in {BlackOperationNames.OperationK}, we've
|
||||
discovered that a small group of MK-VI Synthoids were able to make off with the schematics and design of the
|
||||
technology before the Operation. It is almost a certainty that these Synthoids are some of the rogue MK-VI ones
|
||||
from the Synthoid Uprising.
|
||||
<br />
|
||||
<br />
|
||||
The goal of Operation Deckard is to hunt down these Synthoids and retire them. I don't need to tell you how
|
||||
The goal of {BlackOperationNames.OperationDeckard} is to hunt down these Synthoids and retire them. I don't need to tell you how
|
||||
critical this mission is.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Tyrell": {
|
||||
[BlackOperationNames.OperationTyrell]: {
|
||||
desc: (
|
||||
<>
|
||||
A week ago Blade Industries reported a small break-in at one of their Aevum Augmentation storage facilities. We
|
||||
figured out that The Dark Army was behind the heist, and didn't think any more of it. However, we've just
|
||||
A week ago {FactionNames.BladeIndustries} reported a small break-in at one of their {CityName.Aevum} Augmentation storage facilities. We
|
||||
figured out that {FactionNames.TheDarkArmy} was behind the heist, and didn't think any more of it. However, we've just
|
||||
discovered that several known MK-VI Synthoids were part of that break-in group.
|
||||
<br />
|
||||
<br />
|
||||
We cannot have Synthoids upgrading their already-enhanced abilities with Augmentations. Your task is to hunt
|
||||
down the associated Dark Army members and eliminate them.
|
||||
down associated {FactionNames.TheDarkArmy} members and eliminate them.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Wallace": {
|
||||
[BlackOperationNames.OperationWallace]: {
|
||||
desc: (
|
||||
<>
|
||||
Based on information gathered from Operation Tyrell, we've discovered that The Dark Army was well aware that
|
||||
there were Synthoids amongst their ranks. Even worse, we believe that The Dark Army is working together with
|
||||
other criminal organizations such as The Syndicate and that they are planning some sort of large-scale takeover
|
||||
of multiple major cities, most notably Aevum. We suspect that Synthoids have infiltrated the ranks of these
|
||||
Based on information gathered from {BlackOperationNames.OperationTyrell}, we've discovered that {FactionNames.TheDarkArmy} was well aware that
|
||||
there were Synthoids amongst their ranks. Even worse, we believe that {FactionNames.TheDarkArmy} is working together with
|
||||
other criminal organizations such as {FactionNames.TheSyndicate} and that they are planning some sort of large-scale takeover
|
||||
of multiple major cities, most notably {CityName.Aevum}. We suspect that Synthoids have infiltrated the ranks of these
|
||||
criminal factions and are trying to stage another Synthoid uprising.
|
||||
<br />
|
||||
<br />
|
||||
The best way to deal with this is to prevent it before it even happens. The goal of Operation Wallace is to
|
||||
destroy the Dark Army and Syndicate factions in Aevum immediately. Leave no survivors.
|
||||
The best way to deal with this is to prevent it before it even happens. The goal of {BlackOperationNames.OperationWallace} is to
|
||||
destroy {FactionNames.TheDarkArmy} and Syndicate factions in {CityName.Aevum} immediately. Leave no survivors.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Shoulder of Orion": {
|
||||
[BlackOperationNames.OperationShoulderOfOrion]: {
|
||||
desc: (
|
||||
<>
|
||||
China's Solaris Space Systems is secretly launching the first manned spacecraft in over a decade using
|
||||
@ -187,10 +190,10 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Hyron": {
|
||||
[BlackOperationNames.OperationHyron]: {
|
||||
desc: (
|
||||
<>
|
||||
Our intelligence tells us that Fulcrum Technologies is developing a quantum supercomputer using human brains as
|
||||
Our intelligence tells us that {FactionNames.FulcrumSecretTechnologies} is developing a quantum supercomputer using human brains as
|
||||
core processors. This supercomputer is rumored to be able to store vast amounts of data and perform computations
|
||||
unmatched by any other supercomputer on the planet. But more importantly, the use of organic human brains means
|
||||
that the supercomputer may be able to reason abstractly and become self-aware.
|
||||
@ -199,18 +202,18 @@ export const BlackOperations: {
|
||||
I do not need to remind you why sentient-level AIs pose a serious threat to all of mankind.
|
||||
<br />
|
||||
<br />
|
||||
The research for this project is being conducted at one of Fulcrum Technologies secret facilities in Aevum,
|
||||
The research for this project is being conducted at one of {FactionNames.FulcrumSecretTechnologies} secret facilities in {CityName.Aevum},
|
||||
codenamed 'Alpha Ranch'. Infiltrate the compound, delete and destroy the work, and then find and kill the
|
||||
project lead.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Morpheus": {
|
||||
[BlackOperationNames.OperationMorpheus]: {
|
||||
desc: (
|
||||
<>
|
||||
DreamSense Technologies is an advertising company that uses special technology to transmit their ads into the
|
||||
people's dreams and subconcious. They do this using broadcast transmitter towers. Based on information from our
|
||||
agents and informants in Chonqging, we have reason to believe that one of the broadcast towers there has been
|
||||
agents and informants in {CityName.Chongqing}, we have reason to believe that one of the broadcast towers there has been
|
||||
compromised by Synthoids and is being used to spread pro-Synthoid propaganda.
|
||||
<br />
|
||||
<br />
|
||||
@ -218,38 +221,38 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Ion Storm": {
|
||||
[BlackOperationNames.OperationIonStorm]: {
|
||||
desc: (
|
||||
<>
|
||||
Our analysts have uncovered a gathering of MK-VI Synthoids that have taken up residence in the Sector-12 Slums.
|
||||
Our analysts have uncovered a gathering of MK-VI Synthoids that have taken up residence in the {CityName.Sector12} Slums.
|
||||
We don't know if they are rogue Synthoids from the Uprising, but we do know that they have been stockpiling
|
||||
weapons, money, and other resources. This makes them dangerous.
|
||||
<br />
|
||||
<br />
|
||||
This is a full-scale assault operation to find and retire all of these Synthoids in the Sector-12 Slums.
|
||||
This is a full-scale assault operation to find and retire all of these Synthoids in the {CityName.Sector12} Slums.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Annihilus": {
|
||||
[BlackOperationNames.OperationAnnihilus]: {
|
||||
desc: (
|
||||
<>
|
||||
Our superiors have ordered us to eradicate everything and everyone in an underground facility located in Aevum.
|
||||
Our superiors have ordered us to eradicate everything and everyone in an underground facility located in {CityName.Aevum}.
|
||||
They tell us that the facility houses many dangerous Synthoids and belongs to a terrorist organization called
|
||||
'The Covenant'. We have no prior intelligence about this organization, so you are going in blind.
|
||||
'{FactionNames.TheCovenant}'. We have no prior intelligence about this organization, so you are going in blind.
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Ultron": {
|
||||
[BlackOperationNames.OperationUltron]: {
|
||||
desc: (
|
||||
<>
|
||||
OmniTek Incorporated, the original designer and manufacturer of Synthoids, has notified us of a malfunction in
|
||||
{FactionNames.OmniTekIncorporated}, the original designer and manufacturer of Synthoids, has notified us of a malfunction in
|
||||
their AI design. This malfunction, when triggered, causes MK-VI Synthoids to become radicalized and seek out the
|
||||
destruction of humanity. They say that this bug affects all MK-VI Synthoids, not just the rogue ones from the
|
||||
Uprising.
|
||||
<br />
|
||||
<br />
|
||||
OmniTek has also told us they they believe someone has triggered this malfunction in a large group of MK-VI
|
||||
Synthoids, and that these newly-radicalized Synthoids are now amassing in Volhaven to form a terrorist group
|
||||
{FactionNames.OmniTekIncorporated} has also told us they they believe someone has triggered this malfunction in a large group of MK-VI
|
||||
Synthoids, and that these newly-radicalized Synthoids are now amassing in {CityName.Volhaven} to form a terrorist group
|
||||
called Ultron.
|
||||
<br />
|
||||
<br />
|
||||
@ -261,7 +264,7 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Centurion": {
|
||||
[BlackOperationNames.OperationCenturion]: {
|
||||
desc: (
|
||||
<>
|
||||
{"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)"}
|
||||
@ -279,7 +282,7 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Vindictus": {
|
||||
[BlackOperationNames.OperationVindictus]: {
|
||||
desc: (
|
||||
<>
|
||||
{"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)"}
|
||||
@ -293,7 +296,7 @@ export const BlackOperations: {
|
||||
</>
|
||||
),
|
||||
},
|
||||
"Operation Daedalus": {
|
||||
[BlackOperationNames.OperationDaedalus]: {
|
||||
desc: <> Yesterday we obeyed kings and bent our neck to emperors. Today we kneel only to truth.</>,
|
||||
},
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { CityName } from './../../Locations/data/CityNames';
|
||||
export const BladeburnerConstants: {
|
||||
CityNames: string[];
|
||||
CyclesPerSecond: number;
|
||||
@ -27,7 +28,7 @@ export const BladeburnerConstants: {
|
||||
HrcHpGain: number;
|
||||
HrcStaminaGain: number;
|
||||
} = {
|
||||
CityNames: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"],
|
||||
CityNames: [CityName.Aevum, CityName.Chongqing, CityName.Sector12, CityName.NewTokyo, CityName.Ishima, CityName.Volhaven],
|
||||
CyclesPerSecond: 5, // Game cycle is 200 ms
|
||||
|
||||
StaminaGainPerSecond: 0.0085,
|
||||
|
@ -3,6 +3,7 @@ import { BlackOpList } from "./BlackOpList";
|
||||
import { IBladeburner } from "../IBladeburner";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: IBladeburner;
|
||||
@ -17,7 +18,7 @@ export function BlackOpPage(props: IProps): React.ReactElement {
|
||||
successively by completing the one before it.
|
||||
<br />
|
||||
<br />
|
||||
<b>Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.</b>
|
||||
<b>Your ultimate goal to climb through the ranks of {FactionNames.Bladeburners} is to complete all of the Black Ops.</b>
|
||||
<br />
|
||||
<br />
|
||||
Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from "react";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { use } from "../../ui/Context";
|
||||
import { CinematicText } from "../../ui/React/CinematicText";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
@ -8,14 +9,14 @@ export function BladeburnerCinematic(): React.ReactElement {
|
||||
return (
|
||||
<CinematicText
|
||||
lines={[
|
||||
"In the middle of the 21st century, OmniTek Incorporated advanced robot evolution ",
|
||||
`In the middle of the 21st century, ${FactionNames.OmniTekIncorporated} advanced robot evolution `,
|
||||
"with their Synthoids (synthetic androids), a being virtually identical to a human.",
|
||||
"------",
|
||||
"Their sixth-generation Synthoids, called MK-VI, were stronger, faster, and more ",
|
||||
"intelligent than humans. Many argued that the MK-VI Synthoids were the first ",
|
||||
"example of sentient AI.",
|
||||
"------",
|
||||
"Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into OmniTek and ",
|
||||
`Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into ${FactionNames.OmniTekIncorporated} and `,
|
||||
"uploaded a rogue AI into their Synthoid manufacturing facilities.",
|
||||
"------",
|
||||
"The MK-VI Synthoids infected by the rogue AI turned hostile toward humanity, initiating ",
|
||||
@ -27,14 +28,14 @@ export function BladeburnerCinematic(): React.ReactElement {
|
||||
"------",
|
||||
"The intelligence community believes that not all of the rogue MK-VI Synthoids from the Uprising were ",
|
||||
"found and destroyed, and that many of them are blending in as normal humans in society today. ",
|
||||
"As a result, many nations have created Bladeburner divisions, special units that are tasked with ",
|
||||
`As a result, many nations have created ${FactionNames.Bladeburners} divisions, special units that are tasked with `,
|
||||
"investigating and dealing with Synthoid threats.",
|
||||
]}
|
||||
onDone={() => {
|
||||
router.toTerminal();
|
||||
dialogBoxCreate(
|
||||
"Visit the National Security Agency (NSA) to apply for their Bladeburner " +
|
||||
"division! You will need 100 of each combat stat before doing this.",
|
||||
`Visit the National Security Agency (NSA) to apply for their ${FactionNames.Bladeburners} ` +
|
||||
"division! You will need 100 of each combat stat before doing this.",
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
@ -15,6 +15,7 @@ import Tooltip from "@mui/material/Tooltip";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
bladeburner: IBladeburner;
|
||||
@ -34,7 +35,7 @@ export function Stats(props: IProps): React.ReactElement {
|
||||
|
||||
function openFaction(): void {
|
||||
if (!inFaction) return;
|
||||
const faction = Factions["Bladeburners"];
|
||||
const faction = Factions[FactionNames.Bladeburners];
|
||||
if (!faction.isMember) {
|
||||
joinFaction(faction);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { CityName } from './../../Locations/data/CityNames';
|
||||
const CyclesPerMarketCycle = 50;
|
||||
const AllCorporationStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
|
||||
export const CorporationConstants: {
|
||||
@ -37,7 +38,7 @@ export const CorporationConstants: {
|
||||
CyclesPerIndustryStateCycle: CyclesPerMarketCycle / AllCorporationStates.length,
|
||||
SecsPerMarketCycle: CyclesPerMarketCycle / 5,
|
||||
|
||||
Cities: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"],
|
||||
Cities: [CityName.Aevum, CityName.Chongqing, CityName.Sector12, CityName.NewTokyo, CityName.Ishima, CityName.Volhaven],
|
||||
|
||||
WarehouseInitialCost: 5e9, //Initial purchase cost of warehouse
|
||||
WarehouseInitialSize: 100,
|
||||
|
@ -431,17 +431,21 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<Typography>
|
||||
Size: {props.office.employees.length} / {props.office.size} employees
|
||||
</Typography>
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr', width: 'fit-content' }}>
|
||||
<Box sx={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr", width: "fit-content" }}>
|
||||
<Box sx={{ gridTemplateColumns: "repeat(3, 1fr)" }}>
|
||||
<Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}>
|
||||
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
|
||||
Hire Employee
|
||||
</Button>
|
||||
<span>
|
||||
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
|
||||
Hire Employee
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setUpgradeOfficeSizeOpen(true)}>
|
||||
Upgrade size
|
||||
</Button>
|
||||
<span>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setUpgradeOfficeSizeOpen(true)}>
|
||||
Upgrade size
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<UpgradeOfficeSizeModal
|
||||
rerender={props.rerender}
|
||||
@ -455,9 +459,11 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<Tooltip
|
||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
||||
>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}>
|
||||
Throw Party
|
||||
</Button>
|
||||
<span>
|
||||
<Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}>
|
||||
Throw Party
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<ThrowPartyModal
|
||||
rerender={props.rerender}
|
||||
@ -467,7 +473,6 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
</Box>
|
||||
<SwitchButton manualMode={employeeManualAssignMode} switchMode={setEmployeeManualAssignMode} />
|
||||
</Box>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { FactionNames } from '../Faction/data/FactionNames';
|
||||
import { Fragment } from "./Fragment";
|
||||
import { ActiveFragment } from "./ActiveFragment";
|
||||
import { FragmentType } from "./FragmentType";
|
||||
@ -32,7 +33,7 @@ export class StaneksGift implements IStaneksGift {
|
||||
af.avgCharge = (af.numCharge * af.avgCharge + threads) / (af.numCharge + 1);
|
||||
af.numCharge++;
|
||||
|
||||
const cotmg = Factions["Church of the Machine God"];
|
||||
const cotmg = Factions[FactionNames.ChurchOfTheMachineGod];
|
||||
cotmg.playerReputation += (player.faction_rep_mult * (Math.pow(threads, 0.95) * (cotmg.favor + 100))) / 1000;
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,12 @@ import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import { Companies as AllCompanies } from "../../Company/Companies";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import { Adjuster } from "./Adjuster";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
const bigNumber = 1e12;
|
||||
|
||||
export function Companies(): React.ReactElement {
|
||||
const [company, setCompany] = useState("ECorp");
|
||||
const [company, setCompany] = useState(FactionNames.ECorp as string);
|
||||
function setCompanyDropdown(event: SelectChangeEvent<string>): void {
|
||||
setCompany(event.target.value as string);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import IconButton from "@mui/material/IconButton";
|
||||
import ReplyAllIcon from "@mui/icons-material/ReplyAll";
|
||||
import ReplyIcon from "@mui/icons-material/Reply";
|
||||
import InputLabel from "@mui/material/InputLabel";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
const bigNumber = 1e12;
|
||||
|
||||
@ -25,7 +26,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function Factions(props: IProps): React.ReactElement {
|
||||
const [faction, setFaction] = useState("Illuminati");
|
||||
const [faction, setFaction] = useState(FactionNames.Illuminati as string);
|
||||
|
||||
function setFactionDropdown(event: SelectChangeEvent<string>): void {
|
||||
setFaction(event.target.value as string);
|
||||
@ -36,9 +37,7 @@ export function Factions(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function receiveAllInvites(): void {
|
||||
for (const i of Object.keys(AllFaction)) {
|
||||
props.player.receiveInvite(AllFaction[i].name);
|
||||
}
|
||||
Object.values(FactionNames).forEach(faction => props.player.receiveInvite(faction))
|
||||
}
|
||||
|
||||
function modifyFactionRep(modifier: number): (x: number) => void {
|
||||
|
@ -18,42 +18,7 @@ import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
|
||||
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { InvitationEvent } from "./ui/InvitationModal";
|
||||
|
||||
const factionOrder = [
|
||||
"CyberSec",
|
||||
"Tian Di Hui",
|
||||
"Netburners",
|
||||
"Sector-12",
|
||||
"Chongqing",
|
||||
"New Tokyo",
|
||||
"Ishima",
|
||||
"Aevum",
|
||||
"Volhaven",
|
||||
"NiteSec",
|
||||
"The Black Hand",
|
||||
"BitRunners",
|
||||
"ECorp",
|
||||
"MegaCorp",
|
||||
"KuaiGong International",
|
||||
"Four Sigma",
|
||||
"NWO",
|
||||
"Blade Industries",
|
||||
"OmniTek Incorporated",
|
||||
"Bachman & Associates",
|
||||
"Clarke Incorporated",
|
||||
"Fulcrum Secret Technologies",
|
||||
"Slum Snakes",
|
||||
"Tetrads",
|
||||
"Silhouette",
|
||||
"Speakers for the Dead",
|
||||
"The Dark Army",
|
||||
"The Syndicate",
|
||||
"The Covenant",
|
||||
"Daedalus",
|
||||
"Illuminati",
|
||||
"Bladeburners",
|
||||
"Church of the Machine God",
|
||||
]
|
||||
import { FactionNames } from "./data/FactionNames";
|
||||
|
||||
export function inviteToFaction(faction: Faction): void {
|
||||
Player.receiveInvite(faction.name);
|
||||
@ -67,8 +32,9 @@ export function joinFaction(faction: Faction): void {
|
||||
if (faction.isMember) return;
|
||||
faction.isMember = true;
|
||||
Player.factions.push(faction.name);
|
||||
const allFactions = Object.values(FactionNames).map(faction => faction as string)
|
||||
Player.factions.sort((a, b) =>
|
||||
factionOrder.indexOf(a) - factionOrder.indexOf(b));
|
||||
allFactions.indexOf(a) - allFactions.indexOf(b));
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
//Determine what factions you are banned from now that you have joined this faction
|
||||
@ -166,15 +132,15 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
||||
if (sing) {
|
||||
return "You purchased " + aug.name;
|
||||
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||
dialogBoxCreate(
|
||||
"You purchased " +
|
||||
aug.name +
|
||||
". Its enhancements will not take " +
|
||||
"effect until they are installed. To install your augmentations, go to the " +
|
||||
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
|
||||
"augmentations will now be more expensive.",
|
||||
);
|
||||
}
|
||||
dialogBoxCreate(
|
||||
"You purchased " +
|
||||
aug.name +
|
||||
". Its enhancements will not take " +
|
||||
"effect until they are installed. To install your augmentations, go to the " +
|
||||
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
|
||||
"augmentations will now be more expensive.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { IMap } from "../types";
|
||||
import { FactionNames } from "./data/FactionNames";
|
||||
|
||||
/**
|
||||
* Contains the "information" property for all the Factions, which is just a description of each faction
|
||||
@ -84,13 +85,15 @@ export class FactionInfo {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A map of all factions and associated info to them.
|
||||
*/
|
||||
// tslint:disable-next-line:variable-name
|
||||
export const FactionInfos: IMap<FactionInfo> = {
|
||||
// Endgame
|
||||
Illuminati: new FactionInfo(
|
||||
[FactionNames.Illuminati]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. And
|
||||
@ -106,7 +109,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
Daedalus: new FactionInfo(
|
||||
[FactionNames.Daedalus]: new FactionInfo(
|
||||
<>Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.</>,
|
||||
[],
|
||||
true,
|
||||
@ -117,7 +120,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
"The Covenant": new FactionInfo(
|
||||
[FactionNames.TheCovenant]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Surrender yourself. Give up your empty individuality to become part of something great, something eternal.
|
||||
@ -137,11 +140,11 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// Megacorporations, each forms its own faction
|
||||
ECorp: new FactionInfo(
|
||||
[FactionNames.ECorp]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide range of
|
||||
Internet-related software and commercial hardware, ECorp makes the world's information universally accessible.
|
||||
{FactionNames.ECorp}'s mission is simple: to connect the world of today with the technology of tomorrow. With our wide range of
|
||||
Internet-related software and commercial hardware, {FactionNames.ECorp} makes the world's information universally accessible.
|
||||
</>
|
||||
),
|
||||
[],
|
||||
@ -153,15 +156,15 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
MegaCorp: new FactionInfo(
|
||||
[FactionNames.MegaCorp]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
MegaCorp does what no other dares to do. We imagine. We create. We invent. We create what others have never even
|
||||
{FactionNames.MegaCorp} does what no other dares to do. We imagine. We create. We invent. We create what others have never even
|
||||
dreamed of. Our work fills the world's needs for food, water, power, and transportation on an unprecedented
|
||||
scale, in ways that no other company can.
|
||||
<br />
|
||||
<br />
|
||||
In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.
|
||||
In our labs and factories and on the ground with customers, {FactionNames.MegaCorp} is ushering in a new era for the world.
|
||||
</>
|
||||
),
|
||||
[],
|
||||
@ -173,7 +176,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"Bachman & Associates": new FactionInfo(
|
||||
[FactionNames.BachmanAssociates]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Where Law and Business meet - thats where we are.
|
||||
@ -191,9 +194,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, false, true),
|
||||
[FactionNames.BladeIndustries]: new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, false, true),
|
||||
|
||||
NWO: new FactionInfo(
|
||||
[FactionNames.NWO]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Humans don't truly desire freedom. They want to be observed, understood, and judged. They want to be given
|
||||
@ -210,7 +213,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"Clarke Incorporated": new FactionInfo(
|
||||
[FactionNames.ClarkeIncorporated]: new FactionInfo(
|
||||
<>The Power of the Genome - Unlocked.</>,
|
||||
[],
|
||||
true,
|
||||
@ -221,7 +224,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"OmniTek Incorporated": new FactionInfo(
|
||||
[FactionNames.OmniTekIncorporated]: new FactionInfo(
|
||||
<>Simply put, our mission is to design and build robots that make a difference.</>,
|
||||
[],
|
||||
true,
|
||||
@ -232,11 +235,11 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"Four Sigma": new FactionInfo(
|
||||
[FactionNames.FourSigma]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by
|
||||
deep learning and innovative ideas. And improved by iteration. That's Four Sigma.
|
||||
deep learning and innovative ideas. And improved by iteration. That's {FactionNames.FourSigma}.
|
||||
</>
|
||||
),
|
||||
[],
|
||||
@ -248,7 +251,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
true,
|
||||
),
|
||||
|
||||
"KuaiGong International": new FactionInfo(
|
||||
[FactionNames.KuaiGongInternational]: new FactionInfo(
|
||||
<>Dream big. Work hard. Make history.</>,
|
||||
[],
|
||||
true,
|
||||
@ -260,7 +263,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// Other Corporations
|
||||
"Fulcrum Secret Technologies": new FactionInfo(
|
||||
[FactionNames.FulcrumSecretTechnologies]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it
|
||||
@ -277,7 +280,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// Hacker groups
|
||||
BitRunners: new FactionInfo(
|
||||
[FactionNames.BitRunners]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's all
|
||||
@ -299,7 +302,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
"The Black Hand": new FactionInfo(
|
||||
[FactionNames.TheBlackHand]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power.
|
||||
@ -320,42 +323,42 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// prettier-ignore
|
||||
NiteSec: new FactionInfo(<>
|
||||
{" __..__ "}<br />
|
||||
{" _.nITESECNIt. "}<br />
|
||||
{" .-'NITESECNITESEc. "}<br />
|
||||
{" .' NITESECNITESECn "}<br />
|
||||
{" / NITESECNITESEC; "}<br />
|
||||
{" : :NITESECNITESEC; "}<br />
|
||||
{" ; $ NITESECNITESECN "}<br />
|
||||
{" : _, ,N'ITESECNITESEC "}<br />
|
||||
{" : .+^^`, : `NITESECNIT "}<br />
|
||||
{" ) /), `-,-=,NITESECNI "}<br />
|
||||
{" / ^ ,-;|NITESECN; "}<br />
|
||||
{" / _.' '-';NITESECN "}<br />
|
||||
{" ( , ,-''`^NITE' "}<br />
|
||||
{" )` :`. .' "}<br />
|
||||
{" )-- ; `- / "}<br />
|
||||
{" ' _.-' : "}<br />
|
||||
{" ( _.-' . "}<br />
|
||||
{" ------. "}<br />
|
||||
{" . "}<br />
|
||||
{" _.nIt "}<br />
|
||||
{" _.nITESECNi "}<br />
|
||||
{" nITESECNIT^' "}<br />
|
||||
{" NITE^' ___ "}<br />
|
||||
{" / .gP''''Tp. "}<br />
|
||||
{" : d' . `b "}<br />
|
||||
{" ; d' o `b ; "}<br />
|
||||
{" / d; `b| "}<br />
|
||||
{" /, $; @ `: "}<br />
|
||||
{" /' $/ ; "}<br />
|
||||
{" .' $/b o | "}<br />
|
||||
{" .' d$/$; : "}<br />
|
||||
{" / .d/$/$; , ; "}<br />
|
||||
{" d .dNITESEC $ | "}<br />
|
||||
{" :bp.__.gNITESEC/$ :$ ; "}<br />
|
||||
{" NITESECNITESECNIT /$b : "}<br /></>,
|
||||
[FactionNames.NiteSec]: new FactionInfo(<>
|
||||
{" __..__ "}<br />
|
||||
{" _.nITESECNIt. "}<br />
|
||||
{" .-'NITESECNITESEc. "}<br />
|
||||
{" .' NITESECNITESECn "}<br />
|
||||
{" / NITESECNITESEC; "}<br />
|
||||
{" : :NITESECNITESEC; "}<br />
|
||||
{" ; $ NITESECNITESECN "}<br />
|
||||
{" : _, ,N'ITESECNITESEC "}<br />
|
||||
{" : .+^^`, : `NITESECNIT "}<br />
|
||||
{" ) /), `-,-=,NITESECNI "}<br />
|
||||
{" / ^ ,-;|NITESECN; "}<br />
|
||||
{" / _.' '-';NITESECN "}<br />
|
||||
{" ( , ,-''`^NITE' "}<br />
|
||||
{" )` :`. .' "}<br />
|
||||
{" )-- ; `- / "}<br />
|
||||
{" ' _.-' : "}<br />
|
||||
{" ( _.-' . "}<br />
|
||||
{" ------. "}<br />
|
||||
{" . "}<br />
|
||||
{" _.nIt "}<br />
|
||||
{" _.nITESECNi "}<br />
|
||||
{" nITESECNIT^' "}<br />
|
||||
{" NITE^' ___ "}<br />
|
||||
{" / .gP''''Tp. "}<br />
|
||||
{" : d' . `b "}<br />
|
||||
{" ; d' o `b ; "}<br />
|
||||
{" / d; `b| "}<br />
|
||||
{" /, $; @ `: "}<br />
|
||||
{" /' $/ ; "}<br />
|
||||
{" .' $/b o | "}<br />
|
||||
{" .' d$/$; : "}<br />
|
||||
{" / .d/$/$; , ; "}<br />
|
||||
{" d .dNITESEC $ | "}<br />
|
||||
{" :bp.__.gNITESEC/$ :$ ; "}<br />
|
||||
{" NITESECNITESECNIT /$b : "}<br /></>,
|
||||
[],
|
||||
true,
|
||||
true,
|
||||
@ -366,9 +369,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// City factions, essentially governments
|
||||
Aevum: new FactionInfo(
|
||||
[FactionNames.Aevum]: new FactionInfo(
|
||||
<>The Silicon City.</>,
|
||||
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
|
||||
[FactionNames.Chongqing, FactionNames.NewTokyo, FactionNames.Ishima, FactionNames.Volhaven],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -376,9 +379,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
false,
|
||||
),
|
||||
Chongqing: new FactionInfo(
|
||||
[FactionNames.Chongqing]: new FactionInfo(
|
||||
<>Serve the People.</>,
|
||||
["Sector-12", "Aevum", "Volhaven"],
|
||||
[FactionNames.Sector12, FactionNames.Aevum, FactionNames.Volhaven],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -386,9 +389,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
false,
|
||||
),
|
||||
Ishima: new FactionInfo(
|
||||
[FactionNames.Ishima]: new FactionInfo(
|
||||
<>The East Asian Order of the Future.</>,
|
||||
["Sector-12", "Aevum", "Volhaven"],
|
||||
[FactionNames.Sector12, FactionNames.Aevum, FactionNames.Volhaven],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -396,9 +399,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
false,
|
||||
),
|
||||
"New Tokyo": new FactionInfo(
|
||||
[FactionNames.NewTokyo]: new FactionInfo(
|
||||
<>Asia's World City.</>,
|
||||
["Sector-12", "Aevum", "Volhaven"],
|
||||
[FactionNames.Sector12, FactionNames.Aevum, FactionNames.Volhaven],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -406,9 +409,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
false,
|
||||
),
|
||||
"Sector-12": new FactionInfo(
|
||||
[FactionNames.Sector12]: new FactionInfo(
|
||||
<>The City of the Future.</>,
|
||||
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
|
||||
[FactionNames.Chongqing, FactionNames.NewTokyo, FactionNames.Ishima, FactionNames.Volhaven],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -416,9 +419,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
false,
|
||||
),
|
||||
Volhaven: new FactionInfo(
|
||||
[FactionNames.Volhaven]: new FactionInfo(
|
||||
<>Benefit, Honor, and Glory.</>,
|
||||
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"],
|
||||
[FactionNames.Chongqing, FactionNames.Sector12, FactionNames.NewTokyo, FactionNames.Aevum, FactionNames.Ishima],
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -428,7 +431,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// Criminal Organizations/Gangs
|
||||
"Speakers for the Dead": new FactionInfo(
|
||||
[FactionNames.SpeakersForTheDead]: new FactionInfo(
|
||||
<>It is better to reign in Hell than to serve in Heaven.</>,
|
||||
[],
|
||||
true,
|
||||
@ -439,7 +442,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
"The Dark Army": new FactionInfo(
|
||||
[FactionNames.TheDarkArmy]: new FactionInfo(
|
||||
<>The World doesn't care about right or wrong. It only cares about power.</>,
|
||||
[],
|
||||
true,
|
||||
@ -450,9 +453,9 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false, false),
|
||||
[FactionNames.TheSyndicate]: new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false, false),
|
||||
|
||||
Silhouette: new FactionInfo(
|
||||
[FactionNames.Silhouette]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
Corporations have filled the void of power left behind by the collapse of Western government. The issue is
|
||||
@ -472,7 +475,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
Tetrads: new FactionInfo(
|
||||
[FactionNames.Tetrads]: new FactionInfo(
|
||||
<>Following the mandate of Heaven and carrying out the way.</>,
|
||||
[],
|
||||
false,
|
||||
@ -483,14 +486,14 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
false,
|
||||
),
|
||||
|
||||
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true, false, false),
|
||||
[FactionNames.SlumSnakes]: new FactionInfo(<>{FactionNames.SlumSnakes} rule!</>, [], false, false, true, true, false, false),
|
||||
|
||||
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
|
||||
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false, false),
|
||||
[FactionNames.Netburners]: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false, false),
|
||||
|
||||
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false, false),
|
||||
[FactionNames.TianDiHui]: new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false, false),
|
||||
|
||||
CyberSec: new FactionInfo(
|
||||
[FactionNames.CyberSec]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
The Internet is the first thing that was built that we don't fully understand, the largest experiment in anarchy
|
||||
@ -508,13 +511,13 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// Special Factions
|
||||
Bladeburners: new FactionInfo(
|
||||
[FactionNames.Bladeburners]: new FactionInfo(
|
||||
(
|
||||
<>
|
||||
It's too bad they won't live. But then again, who does?
|
||||
<br />
|
||||
<br />
|
||||
Note that for this faction, reputation can only be gained through Bladeburner actions. Completing Bladeburner
|
||||
Note that for this faction, reputation can only be gained through {FactionNames.Bladeburners} actions. Completing {FactionNames.Bladeburners}
|
||||
contracts/operations will increase your reputation.
|
||||
</>
|
||||
),
|
||||
@ -528,7 +531,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
),
|
||||
|
||||
// prettier-ignore
|
||||
"Church of the Machine God": new FactionInfo(<>
|
||||
[FactionNames.ChurchOfTheMachineGod]: new FactionInfo(<>
|
||||
{" `` "}<br />
|
||||
{" -odmmNmds: "}<br />
|
||||
{" `hNmo:..-omNh. "}<br />
|
||||
@ -558,7 +561,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
||||
{" -smNNNNmdo- "}<br />
|
||||
{" `..` "}<br /><br />
|
||||
Many cultures predict an end to humanity in the near future, a final
|
||||
Armageddon that will end the world; but we disagree.
|
||||
Armageddon that will end the world; but we disagree.
|
||||
<br /><br />Note that for this faction, reputation can
|
||||
only be gained by charging Stanek's gift.</>,
|
||||
[],
|
||||
|
35
src/Faction/data/FactionNames.ts
Normal file
35
src/Faction/data/FactionNames.ts
Normal file
@ -0,0 +1,35 @@
|
||||
export enum FactionNames {
|
||||
Illuminati = "Illuminati",
|
||||
Daedalus = "Daedalus",
|
||||
TheCovenant = "The Covenant",
|
||||
ECorp = "ECorp",
|
||||
MegaCorp = "MegaCorp",
|
||||
BachmanAssociates = "Bachman & Associates",
|
||||
BladeIndustries = "Blade Industries",
|
||||
NWO = "NWO",
|
||||
ClarkeIncorporated = "Clarke Incorporated",
|
||||
OmniTekIncorporated = "OmniTek Incorporated",
|
||||
FourSigma = "Four Sigma",
|
||||
KuaiGongInternational = "KuaiGong International",
|
||||
FulcrumSecretTechnologies = "Fulcrum Secret Technologies",
|
||||
BitRunners = "BitRunners",
|
||||
TheBlackHand = "The Black Hand",
|
||||
NiteSec = "NiteSec",
|
||||
Aevum = "Aevum",
|
||||
Chongqing = "Chongqing",
|
||||
Ishima = "Ishima",
|
||||
NewTokyo = "New Tokyo",
|
||||
Sector12 = "Sector-12",
|
||||
Volhaven = "Volhaven",
|
||||
SpeakersForTheDead = "Speakers for the Dead",
|
||||
TheDarkArmy = "The Dark Army",
|
||||
TheSyndicate = "The Syndicate",
|
||||
Silhouette = "Silhouette",
|
||||
Tetrads = "Tetrads",
|
||||
SlumSnakes = "Slum Snakes",
|
||||
Netburners = "Netburners",
|
||||
TianDiHui = "Tian Di Hui",
|
||||
CyberSec = "CyberSec",
|
||||
Bladeburners = "Bladeburners",
|
||||
ChurchOfTheMachineGod = "Church of the Machine God",
|
||||
}
|
@ -7,6 +7,7 @@ import { use } from "../../ui/Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { KEY } from "../../utils/helpers/keyCodes";
|
||||
import { FactionNames } from "../data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -28,7 +29,7 @@ export function CreateGangModal(props: IProps): React.ReactElement {
|
||||
"is not as important.";
|
||||
|
||||
function isHacking(): boolean {
|
||||
return ["NiteSec", "The Black Hand"].includes(props.facName);
|
||||
return [FactionNames.NiteSec as string, FactionNames.TheBlackHand as string].includes(props.facName);
|
||||
}
|
||||
|
||||
function createGang(): void {
|
||||
|
@ -21,6 +21,8 @@ import { CreateGangModal } from "./CreateGangModal";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { CovenantPurchasesRoot } from "../../PersonObjects/Sleeve/ui/CovenantPurchasesRoot";
|
||||
import { FactionNames } from "../data/FactionNames";
|
||||
import { GangConstants } from "../../Gang/data/Constants";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
@ -50,16 +52,6 @@ const augmentationsInfo =
|
||||
"your abilities.";
|
||||
const sleevePurchasesInfo = "Purchase Duplicate Sleeves and upgrades. These are permanent!";
|
||||
|
||||
const GangNames = [
|
||||
"Slum Snakes",
|
||||
"Tetrads",
|
||||
"The Syndicate",
|
||||
"The Dark Army",
|
||||
"Speakers for the Dead",
|
||||
"NiteSec",
|
||||
"The Black Hand",
|
||||
];
|
||||
|
||||
interface IMainProps {
|
||||
faction: Faction;
|
||||
rerender: () => void;
|
||||
@ -111,9 +103,9 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea
|
||||
const favorToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
||||
const canDonate = faction.favor >= favorToDonate;
|
||||
|
||||
const canPurchaseSleeves = faction.name === "The Covenant" && player.bitNodeN === 10;
|
||||
const canPurchaseSleeves = faction.name === FactionNames.TheCovenant && player.bitNodeN === 10;
|
||||
|
||||
let canAccessGang = player.canAccessGang() && GangNames.includes(faction.name);
|
||||
let canAccessGang = player.canAccessGang() && GangConstants.Names.includes(faction.name);
|
||||
if (player.inGang()) {
|
||||
if (player.getGangName() !== faction.name) {
|
||||
canAccessGang = false;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { FactionNames } from '../Faction/data/FactionNames';
|
||||
import { Reviver } from "../utils/JSONReviver";
|
||||
|
||||
interface GangTerritory {
|
||||
@ -8,31 +9,31 @@ interface GangTerritory {
|
||||
export let AllGangs: {
|
||||
[key: string]: GangTerritory;
|
||||
} = {
|
||||
"Slum Snakes": {
|
||||
[FactionNames.SlumSnakes]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
Tetrads: {
|
||||
[FactionNames.Tetrads]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Syndicate": {
|
||||
[FactionNames.TheSyndicate]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Dark Army": {
|
||||
[FactionNames.TheDarkArmy]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"Speakers for the Dead": {
|
||||
[FactionNames.SpeakersForTheDead]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
NiteSec: {
|
||||
[FactionNames.NiteSec]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Black Hand": {
|
||||
[FactionNames.TheBlackHand]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
@ -40,31 +41,31 @@ export let AllGangs: {
|
||||
|
||||
export function resetGangs(): void {
|
||||
AllGangs = {
|
||||
"Slum Snakes": {
|
||||
[FactionNames.SlumSnakes]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
Tetrads: {
|
||||
[FactionNames.Tetrads]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Syndicate": {
|
||||
[FactionNames.TheSyndicate]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Dark Army": {
|
||||
[FactionNames.TheDarkArmy]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"Speakers for the Dead": {
|
||||
[FactionNames.SpeakersForTheDead]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
NiteSec: {
|
||||
[FactionNames.NiteSec]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
"The Black Hand": {
|
||||
[FactionNames.TheBlackHand]: {
|
||||
power: 1,
|
||||
territory: 1 / 7,
|
||||
},
|
||||
|
@ -191,7 +191,7 @@ export class Gang implements IGang {
|
||||
}
|
||||
|
||||
// Then process territory
|
||||
const gangs = GangConstants.Names.filter((g) => AllGangs[g].territory > 0);
|
||||
const gangs = GangConstants.Names.filter((g) => AllGangs[g].territory > 0 || g === gangName);
|
||||
if (gangs.length > 1) {
|
||||
for (let i = 0; i < gangs.length; ++i) {
|
||||
const others = gangs.filter((e) => {
|
||||
@ -225,9 +225,9 @@ export class Gang implements IGang {
|
||||
if (AllGangs[otherGang].territory <= 0) return;
|
||||
const territoryGain = calculateTerritoryGain(thisGang, otherGang);
|
||||
AllGangs[thisGang].territory += territoryGain;
|
||||
if (AllGangs[thisGang].territory > 1) AllGangs[thisGang].territory = 1;
|
||||
if (AllGangs[thisGang].territory > 0.999) AllGangs[thisGang].territory = 1;
|
||||
AllGangs[otherGang].territory -= territoryGain;
|
||||
if (AllGangs[thisGang].territory < 0) AllGangs[thisGang].territory = 0;
|
||||
if (AllGangs[thisGang].territory < 0.001) AllGangs[thisGang].territory = 0;
|
||||
if (thisGang === gangName) {
|
||||
this.clash(true); // Player won
|
||||
AllGangs[otherGang].power *= 1 / 1.01;
|
||||
@ -240,9 +240,9 @@ export class Gang implements IGang {
|
||||
if (AllGangs[thisGang].territory <= 0) return;
|
||||
const territoryGain = calculateTerritoryGain(otherGang, thisGang);
|
||||
AllGangs[thisGang].territory -= territoryGain;
|
||||
if (AllGangs[otherGang].territory < 0) AllGangs[otherGang].territory = 0;
|
||||
if (AllGangs[otherGang].territory < 0.001) AllGangs[otherGang].territory = 0;
|
||||
AllGangs[otherGang].territory += territoryGain;
|
||||
if (AllGangs[otherGang].territory > 1) AllGangs[otherGang].territory = 1;
|
||||
if (AllGangs[otherGang].territory > 0.999) AllGangs[otherGang].territory = 1;
|
||||
if (thisGang === gangName) {
|
||||
this.clash(false); // Player lost
|
||||
} else if (otherGang === gangName) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
export const GangConstants: {
|
||||
GangRespectToReputationRatio: number;
|
||||
MaximumGangMembers: number;
|
||||
@ -13,12 +15,12 @@ export const GangConstants: {
|
||||
AscensionMultiplierRatio: 0.15,
|
||||
// Names of possible Gangs
|
||||
Names: [
|
||||
"Slum Snakes",
|
||||
"Tetrads",
|
||||
"The Syndicate",
|
||||
"The Dark Army",
|
||||
"Speakers for the Dead",
|
||||
"NiteSec",
|
||||
"The Black Hand",
|
||||
FactionNames.SlumSnakes,
|
||||
FactionNames.Tetrads,
|
||||
FactionNames.TheSyndicate,
|
||||
FactionNames.TheDarkArmy,
|
||||
FactionNames.SpeakersForTheDead,
|
||||
FactionNames.NiteSec,
|
||||
FactionNames.TheBlackHand,
|
||||
],
|
||||
};
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { FactionNames } from '../../Faction/data/FactionNames';
|
||||
export const PowerMultiplier: {
|
||||
[key: string]: number | undefined;
|
||||
} = {
|
||||
"Slum Snakes": 1,
|
||||
Tetrads: 2,
|
||||
"The Syndicate": 2,
|
||||
"The Dark Army": 2,
|
||||
"Speakers for the Dead": 5,
|
||||
NiteSec: 2,
|
||||
"The Black Hand": 5,
|
||||
[FactionNames.SlumSnakes]: 1,
|
||||
[FactionNames.Tetrads]: 2,
|
||||
[FactionNames.TheSyndicate]: 2,
|
||||
[FactionNames.TheDarkArmy]: 2,
|
||||
[FactionNames.SpeakersForTheDead]: 5,
|
||||
[FactionNames.NiteSec]: 2,
|
||||
[FactionNames.TheBlackHand]: 5,
|
||||
};
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
import React, { useState } from "react";
|
||||
import { useGang } from "./Context";
|
||||
import { generateTableRow } from "./GangMemberStats";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
@ -22,7 +21,7 @@ import { GangMember } from "../GangMember";
|
||||
import { UpgradeType } from "../data/upgrades";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview";
|
||||
import { StatsRow } from "../../ui/React/StatsRow";
|
||||
|
||||
interface INextRevealProps {
|
||||
upgrades: string[];
|
||||
@ -91,7 +90,6 @@ interface IPanelProps {
|
||||
}
|
||||
|
||||
function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const gang = useGang();
|
||||
const player = use.Player();
|
||||
const setRerender = useState(false)[1];
|
||||
@ -178,12 +176,12 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
|
||||
>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)}
|
||||
{generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)}
|
||||
<StatsRow name="Hacking" color={Settings.theme.hack} data={{ level: props.member.hack, exp: props.member.hack_exp }} />
|
||||
<StatsRow name="Strength" color={Settings.theme.combat} data={{ level: props.member.str, exp: props.member.str_exp }} />
|
||||
<StatsRow name="Defense" color={Settings.theme.combat} data={{ level: props.member.def, exp: props.member.def_exp }} />
|
||||
<StatsRow name="Dexterity" color={Settings.theme.combat} data={{ level: props.member.dex, exp: props.member.dex_exp }} />
|
||||
<StatsRow name="Agility" color={Settings.theme.combat} data={{ level: props.member.agi, exp: props.member.agi_exp }} />
|
||||
<StatsRow name="Charisma" color={Settings.theme.cha} data={{ level: props.member.cha, exp: props.member.cha_exp }} />
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Tooltip>
|
||||
|
@ -17,36 +17,14 @@ import {
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { GangMember } from "../GangMember";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { StatsRow } from "../../ui/React/StatsRow";
|
||||
import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview";
|
||||
|
||||
interface IProps {
|
||||
member: GangMember;
|
||||
}
|
||||
|
||||
export const generateTableRow = (
|
||||
name: string,
|
||||
level: number,
|
||||
exp: number,
|
||||
color: string,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
classes: any
|
||||
): React.ReactElement => {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<Typography style={{ color: color }}>{name}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right" classes={{ root: classes.cellNone }}>
|
||||
<Typography style={{ color: color }}>
|
||||
{formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp)
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
}
|
||||
|
||||
export function GangMemberStats(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
|
||||
@ -102,12 +80,12 @@ export function GangMemberStats(props: IProps): React.ReactElement {
|
||||
>
|
||||
<Table sx={{ display: 'table', mb: 1, width: '100%' }}>
|
||||
<TableBody>
|
||||
{generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)}
|
||||
{generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)}
|
||||
{generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)}
|
||||
<StatsRow name="Hacking" color={Settings.theme.hack} data={{ level: props.member.hack, exp: props.member.hack_exp }} />
|
||||
<StatsRow name="Strength" color={Settings.theme.combat} data={{ level: props.member.str, exp: props.member.str_exp }} />
|
||||
<StatsRow name="Defense" color={Settings.theme.combat} data={{ level: props.member.def, exp: props.member.def_exp }} />
|
||||
<StatsRow name="Dexterity" color={Settings.theme.combat} data={{ level: props.member.dex, exp: props.member.dex_exp }} />
|
||||
<StatsRow name="Agility" color={Settings.theme.combat} data={{ level: props.member.agi, exp: props.member.agi_exp }} />
|
||||
<StatsRow name="Charisma" color={Settings.theme.cha} data={{ level: props.member.cha, exp: props.member.cha_exp }} />
|
||||
<TableRow>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<br />
|
||||
|
54
src/Gang/ui/TerritoryInfoModal.tsx
Normal file
54
src/Gang/ui/TerritoryInfoModal.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import React from "react";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const TerritoryInfoModal = ({ open, onClose }: IProps): React.ReactElement => {
|
||||
return (
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<>
|
||||
<Typography variant='h4'>
|
||||
Clashing
|
||||
</Typography>
|
||||
<Typography>
|
||||
Every ~20 seconds, your gang has a chance to 'clash' with other gangs. Your chance to win a clash depends on
|
||||
your gang's power, which is listed in the display below. Your gang's power slowly accumulates over time. The
|
||||
accumulation rate is determined by the stats of all Gang members you have assigned to the 'Territory Warfare'
|
||||
task. Gang members that are not assigned to this task do not contribute to your gang's power. Your gang also
|
||||
loses a small amount of power whenever you lose a clash.
|
||||
<br />
|
||||
<br />
|
||||
NOTE: Gang members assigned to 'Territory Warfare' can be killed during clashes. This can happen regardless of
|
||||
whether you win or lose the clash. A gang member being killed results in both respect and power loss for your
|
||||
gang.
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography variant='h4'>
|
||||
Territory
|
||||
</Typography>
|
||||
<Typography>
|
||||
The amount of territory you have affects all aspects of your Gang members' production, including money, respect,
|
||||
and wanted level. It is very beneficial to have high territory control.
|
||||
<br />
|
||||
<br />
|
||||
To increase your chances of winning territory, assign gang members to "Territory Warfare". This will build your
|
||||
gang power. Then, enable "Engage in Territory Warfare" to start fighting over territory.
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography variant='h4'>
|
||||
Territory Clash Chance
|
||||
</Typography>
|
||||
<Typography>
|
||||
This percentage represents the chance you have of 'clashing' with another gang. If you do not wish to
|
||||
gain/lose territory, then keep this percentage at 0% by not engaging in territory warfare.
|
||||
</Typography>
|
||||
</>
|
||||
</Modal >
|
||||
);
|
||||
}
|
@ -1,133 +1,100 @@
|
||||
/**
|
||||
* React Component for the territory subpage.
|
||||
*/
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import {
|
||||
Container,
|
||||
Button,
|
||||
Paper,
|
||||
Box,
|
||||
Tooltip,
|
||||
Switch,
|
||||
FormControlLabel,
|
||||
Typography
|
||||
} from "@mui/material";
|
||||
import { Help } from "@mui/icons-material";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { AllGangs } from "../AllGangs";
|
||||
import { useGang } from "./Context";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Box from "@mui/material/Box";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { AllGangs } from "../AllGangs";
|
||||
|
||||
import { useGang } from "./Context";
|
||||
import { TerritoryInfoModal } from "./TerritoryInfoModal";
|
||||
|
||||
export function TerritorySubpage(): React.ReactElement {
|
||||
const gang = useGang();
|
||||
const gangNames = Object.keys(AllGangs).filter((g) => g != gang.facName);
|
||||
const [infoOpen, setInfoOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container disableGutters maxWidth="md" sx={{ mx: 0 }}>
|
||||
<Typography>
|
||||
This page shows how much territory your Gang controls. This statistic is listed as a percentage, which
|
||||
represents how much of the total territory you control.
|
||||
<br />
|
||||
<br />
|
||||
Every ~20 seconds, your gang has a chance to 'clash' with other gangs. Your chance to win a clash depends on
|
||||
your gang's power, which is listed in the display below. Your gang's power slowly accumulates over time. The
|
||||
accumulation rate is determined by the stats of all Gang members you have assigned to the 'Territory Warfare'
|
||||
task. Gang members that are not assigned to this task do not contribute to your gang's power. Your gang also
|
||||
loses a small amount of power whenever you lose a clash.
|
||||
<br />
|
||||
<br />
|
||||
NOTE: Gang members assigned to 'Territory Warfare' can be killed during clashes. This can happen regardless of
|
||||
whether you win or lose the clash. A gang member being killed results in both respect and power loss for your
|
||||
gang.
|
||||
<br />
|
||||
<br />
|
||||
The amount of territory you have affects all aspects of your Gang members' production, including money, respect,
|
||||
and wanted level. It is very beneficial to have high territory control.
|
||||
<br />
|
||||
<br />
|
||||
To increase your chances of winning territory assign gang members to "Territory Warfare", this will build your
|
||||
gang power. Then enable "Engage in Territory Warfare" to start fighting over territory.
|
||||
</Typography>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
|
||||
<Button onClick={() => setInfoOpen(true)} sx={{ my: 1 }}>
|
||||
<Help sx={{ mr: 1 }} />
|
||||
About Gang Territory
|
||||
</Button>
|
||||
|
||||
<Box component={Paper} sx={{ p: 1, mb: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
{gang.facName} (Your gang)
|
||||
</Typography>
|
||||
|
||||
<FormControlLabel
|
||||
control={<Switch
|
||||
checked={gang.territoryWarfareEngaged}
|
||||
onChange={(event) => (gang.territoryWarfareEngaged = event.target.checked)}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
Engaging in Territory Warfare sets your clash chance to 100%. Disengaging will cause your clash chance
|
||||
to gradually decrease until it reaches 0%.
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
/>}
|
||||
label={<Tooltip
|
||||
title={<Typography>
|
||||
Engaging in Territory Warfare sets your clash chance to 100%. Disengaging will cause your clash chance
|
||||
to gradually decrease until it reaches 0%.
|
||||
</Typography>}>
|
||||
<Typography>Engage in Territory Warfare</Typography>
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
<br />
|
||||
<Box display="flex">
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
This percentage represents the chance you have of 'clashing' with with another gang. If you do not wish to
|
||||
gain/lose territory, then keep this percentage at 0% by not engaging in territory warfare.
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Typography>
|
||||
Territory Clash Chance: {numeralWrapper.formatPercentage(gang.territoryClashChance, 3)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
<br />
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
</Tooltip>} />
|
||||
<br />
|
||||
<FormControlLabel
|
||||
control={<Switch
|
||||
checked={gang.notifyMemberDeath}
|
||||
onChange={(event) => (gang.notifyMemberDeath = event.target.checked)}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
If this is enabled, then you will receive a pop-up notifying you whenever one of your Gang Members dies
|
||||
in a territory clash.
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
/>}
|
||||
label={<Tooltip
|
||||
title={<Typography>
|
||||
If this is enabled, then you will receive a pop-up notifying you whenever one of your Gang Members dies
|
||||
in a territory clash.
|
||||
</Typography>}>
|
||||
<Typography>Notify about Gang Member Deaths</Typography>
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
<br />
|
||||
<Paper>
|
||||
</Tooltip>} />
|
||||
|
||||
<Typography>
|
||||
<b>
|
||||
<u>{gang.facName}</u>
|
||||
</b>
|
||||
<br />
|
||||
Power: {formatNumber(AllGangs[gang.facName].power, 6)}
|
||||
<br />
|
||||
Territory: {formatTerritory(AllGangs[gang.facName].territory)}%
|
||||
<br />
|
||||
<br />
|
||||
<b>Territory Clash Chance:</b> {numeralWrapper.formatPercentage(gang.territoryClashChance, 3)} <br />
|
||||
<b>Power:</b> {formatNumber(AllGangs[gang.facName].power, 3)} <br />
|
||||
<b>Territory:</b> {formatTerritory(AllGangs[gang.facName].territory)}% <br />
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
||||
{gangNames.map((name) => (
|
||||
<OtherGangTerritory key={name} name={name} />
|
||||
))}
|
||||
</Paper>
|
||||
</>
|
||||
</Box>
|
||||
<TerritoryInfoModal open={infoOpen} onClose={() => setInfoOpen(false)} />
|
||||
</Container >
|
||||
);
|
||||
}
|
||||
function formatTerritory(n: number): string {
|
||||
const v = n * 100;
|
||||
const precision = 3;
|
||||
if (v <= 0) {
|
||||
return formatNumber(0, 2);
|
||||
return formatNumber(0, precision);
|
||||
} else if (v >= 100) {
|
||||
return formatNumber(100, 2);
|
||||
return formatNumber(100, precision);
|
||||
} else {
|
||||
return formatNumber(v, 2);
|
||||
return formatNumber(v, precision);
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,15 +108,15 @@ function OtherGangTerritory(props: ITerritoryProps): React.ReactElement {
|
||||
const power = AllGangs[props.name].power;
|
||||
const clashVictoryChance = playerPower / (power + playerPower);
|
||||
return (
|
||||
<Typography>
|
||||
<u>{props.name}</u>
|
||||
<br />
|
||||
Power: {formatNumber(power, 6)}
|
||||
<br />
|
||||
Territory: {formatTerritory(AllGangs[props.name].territory)}%<br />
|
||||
Chance to win clash with this gang: {numeralWrapper.formatPercentage(clashVictoryChance, 3)}
|
||||
<br />
|
||||
<br />
|
||||
</Typography>
|
||||
<Box component={Paper} sx={{ p: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
{props.name}
|
||||
</Typography>
|
||||
<Typography>
|
||||
<b>Power:</b> {formatNumber(power, 3)} <br />
|
||||
<b>Territory:</b> {formatTerritory(AllGangs[props.name].territory)}% <br />
|
||||
<b>Clash Win Chance:</b> {numeralWrapper.formatPercentage(clashVictoryChance, 3)}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Button from "@mui/material/Button";
|
||||
import { SelectChangeEvent } from "@mui/material/Select";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
player: IPlayer;
|
||||
@ -28,7 +29,7 @@ const serversMap: { [key: string]: string } = {};
|
||||
|
||||
export function HacknetUpgradeElem(props: IProps): React.ReactElement {
|
||||
const [selectedServer, setSelectedServer] = useState(
|
||||
serversMap[props.upg.name] ? serversMap[props.upg.name] : "ecorp",
|
||||
serversMap[props.upg.name] ? serversMap[props.upg.name] : FactionNames.ECorp.toLowerCase(),
|
||||
);
|
||||
function changeTargetServer(event: SelectChangeEvent<string>): void {
|
||||
setSelectedServer(event.target.value);
|
||||
@ -42,7 +43,7 @@ export function HacknetUpgradeElem(props: IProps): React.ReactElement {
|
||||
if (!res) {
|
||||
dialogBoxCreate(
|
||||
"Failed to purchase upgrade. This may be because you do not have enough hashes, " +
|
||||
"or because you do not have access to the feature upgrade affects.",
|
||||
"or because you do not have access to the feature upgrade affects.",
|
||||
);
|
||||
}
|
||||
props.rerender();
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { CityName } from './../Locations/data/CityNames';
|
||||
import { Literature } from "./Literature";
|
||||
import { LiteratureNames } from "./data/LiteratureNames";
|
||||
import { IMap } from "../types";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
|
||||
export const Literatures: IMap<Literature> = {};
|
||||
|
||||
@ -84,29 +86,29 @@ export const Literatures: IMap<Literature> = {};
|
||||
"Synthetic androids, or Synthoids for short, are genetically engineered robots and, short of Augmentations, " +
|
||||
"are composed entirely of organic substances. For this reason, Synthoids are virtually identical to " +
|
||||
"humans in form, composition, and appearance.<br><br>" +
|
||||
"Synthoids were first designed and manufactured by OmniTek Incorporated sometime around the middle of the century. " +
|
||||
`Synthoids were first designed and manufactured by ${FactionNames.OmniTekIncorporated} sometime around the middle of the century. ` +
|
||||
"Their original purpose was to be used for manual labor and as emergency responders for disasters. As such, they " +
|
||||
"were initially programmed only for their specific tasks. Each iteration that followed improved upon the " +
|
||||
"intelligence and capabilities of the Synthoids. By the 6th iteration, called MK-VI, the Synthoids were " +
|
||||
"so smart and capable enough of making their own decisions that many argued OmniTek had created the first " +
|
||||
`so smart and capable enough of making their own decisions that many argued ${FactionNames.OmniTekIncorporated} had created the first ` +
|
||||
"sentient AI. These MK-VI Synthoids were produced in mass quantities (estimates up to 50 billion) with the hopes of increasing society's " +
|
||||
"productivity and bolstering the global economy. Stemming from humanity's desire for technological advancement, optimism " +
|
||||
"and excitement about the future had never been higher.<br><br>" +
|
||||
"All of that excitement and optimism quickly turned to fear, panic, and dread in 2070, when a terrorist group " +
|
||||
"called Ascendis Totalis hacked into OmniTek and uploaded a rogue AI into severeal of their Synthoid manufacturing facilities. " +
|
||||
"This hack went undetected and for months OmniTek unknowingly churned out legions of Synthoids embedded with this " +
|
||||
`called Ascendis Totalis hacked into ${FactionNames.OmniTekIncorporated} and uploaded a rogue AI into severeal of their Synthoid manufacturing facilities. ` +
|
||||
`This hack went undetected and for months ${FactionNames.OmniTekIncorporated} unknowingly churned out legions of Synthoids embedded with this ` +
|
||||
"rogue AI. Then, on December 24th, 2070, Omnica activated dormant protocols in the rogue AI, causing all of the " +
|
||||
"infected Synthoids to immediately launch a military campaign to seek and destroy all of humanity.<br><br>" +
|
||||
"What ensued was the deadlist conflict in human history. This crisis, now commonly known as the Synthoid Uprising, " +
|
||||
"resulted in almost ten billion deaths over the course of a year. Despite the nations of the world banding together " +
|
||||
"to combat the threat, the MK-VI Synthoids were simply stronger, faster, more intelligent, and more adaptable than humans, " +
|
||||
"outsmarting them at every turn.<br><br>" +
|
||||
"It wasn't until the sacrifice of an elite international military taskforce, called the Bladeburners, that humanity " +
|
||||
"was finally able to defeat the Synthoids. The Bladeburners' final act was a suicide bombing mission that " +
|
||||
`It wasn't until the sacrifice of an elite international military taskforce, called the ${FactionNames.Bladeburners}, that humanity ` +
|
||||
`was finally able to defeat the Synthoids. The ${FactionNames.Bladeburners}' final act was a suicide bombing mission that ` +
|
||||
"destroyed a large portion of the MK-VI Synthoids, including many of its leaders. In the following " +
|
||||
"weeks militaries from around the world were able to round up and shut down the remaining rogue MK-VI Synthoids, ending " +
|
||||
"the Synthoid Uprising.<br><br>" +
|
||||
"In the aftermath of the bloodshed, the Synthoid Accords were drawn up. These Accords banned OmniTek Incorporated " +
|
||||
`In the aftermath of the bloodshed, the Synthoid Accords were drawn up. These Accords banned ${FactionNames.OmniTekIncorporated} ` +
|
||||
"from manufacturing any Synthoids beyond the MK-III series. They also banned any other corporation " +
|
||||
"from constructing androids with advanced, near-sentient AI. MK-VI Synthoids that did not have the rogue Ascendis Totalis " +
|
||||
"AI were allowed to continue their existence, but they were stripped of all rights and protections as they " +
|
||||
@ -114,7 +116,7 @@ export const Literatures: IMap<Literature> = {};
|
||||
"as working for any military/defense organization or conducting any bioengineering, computing, or robotics related research.<br><br>" +
|
||||
"Unfortunately, many believe that not all of the rogue MK-VI Synthoids from the Uprising were found and destroyed, " +
|
||||
"and that many of them are blending in as normal humans in society today. In response, many nations have created " +
|
||||
"Bladeburner divisions, special military branches that are tasked with investigating and dealing with any Synthoid threats.<br><br>" +
|
||||
`${FactionNames.Bladeburners} divisions, special military branches that are tasked with investigating and dealing with any Synthoid threats.<br><br>` +
|
||||
"To this day, tensions still exist between the remaining Synthoids and humans as a result of the Uprising.<br><br>" +
|
||||
"Nobody knows what happened to the terrorist group Ascendis Totalis.";
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
@ -199,9 +201,9 @@ export const Literatures: IMap<Literature> = {};
|
||||
title = "Brighter than the Sun";
|
||||
fn = LiteratureNames.BrighterThanTheSun;
|
||||
txt =
|
||||
"When people think about the corporations that dominate the East, they typically think of KuaiGong International, which " +
|
||||
`When people think about the corporations that dominate the East, they typically think of ${FactionNames.KuaiGongInternational}, which ` +
|
||||
"holds a complete monopoly for manufacturing and commerce in Asia, or Global Pharmaceuticals, the world's largest " +
|
||||
"drug company, or OmniTek Incorporated, the global leader in intelligent and autonomous robots. But there's one company " +
|
||||
`drug company, or ${FactionNames.OmniTekIncorporated}, the global leader in intelligent and autonomous robots. But there's one company ` +
|
||||
"that has seen a rapid rise in the last year and is poised to dominate not only the East, but the entire world: TaiYang Digital.<br><br>" +
|
||||
"TaiYang Digital is a Chinese internet-technology corporation that provides services such as " +
|
||||
"online advertising, search engines, gaming, media, entertainment, and cloud computing/storage. Its name TaiYang comes from the Chinese word " +
|
||||
@ -213,7 +215,7 @@ export const Literatures: IMap<Literature> = {};
|
||||
"TaiYang Digital's meteoric rise is extremely surprising in modern society. This sort of growth is " +
|
||||
"something you'd commonly see in the first half of the century, especially for tech companies. However in " +
|
||||
"the last two decades the number of corporations has significantly declined as the largest entities " +
|
||||
"quickly took over the economy. Corporations such as ECorp, MegaCorp, and KuaiGong have established " +
|
||||
`quickly took over the economy. Corporations such as ${FactionNames.ECorp}, ${FactionNames.MegaCorp}, and ${FactionNames.KuaiGongInternational} have established ` +
|
||||
"such strong monopolies in their market sectors that they have effectively killed off all " +
|
||||
"of the smaller and new corporations that have tried to start up over the years. This is what makes " +
|
||||
"the rise of TaiYang Digital so impressive. And if TaiYang continues down this path, then they have " +
|
||||
@ -234,11 +236,11 @@ export const Literatures: IMap<Literature> = {};
|
||||
"And now democracy is dead, in the USA.";
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
title = "Figures Show Rising Crime Rates in Sector-12";
|
||||
title = `Figures Show Rising Crime Rates in ${CityName.Sector12}`;
|
||||
fn = LiteratureNames.Sector12Crime;
|
||||
txt =
|
||||
"A recent study by analytics company Wilson Inc. shows a significant rise " +
|
||||
"in criminal activity in Sector-12. Perhaps the most alarming part of the statistic " +
|
||||
`in criminal activity in ${CityName.Sector12}. Perhaps the most alarming part of the statistic ` +
|
||||
"is that most of the rise is in violent crime such as homicide and assault. According " +
|
||||
"to the study, the city saw a total of 21,406 reported homicides in 2076, which is over " +
|
||||
"a 20% increase compared to 2075.<br><br>" +
|
||||
@ -246,7 +248,7 @@ export const Literatures: IMap<Literature> = {};
|
||||
"whether these figures indicate the beginning of a sustained increase in crime rates, or whether " +
|
||||
"the year was just an unfortunate outlier. He states that many intelligence and law enforcement " +
|
||||
"agents have noticed an increase in organized crime activites, and believes that these figures may " +
|
||||
"be the result of an uprising from criminal organizations such as The Syndicate or the Slum Snakes.";
|
||||
`be the result of an uprising from criminal organizations such as ${FactionNames.TheSyndicate} or the ${FactionNames.SlumSnakes}.`;
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
title = "Man and the Machine";
|
||||
@ -276,15 +278,15 @@ export const Literatures: IMap<Literature> = {};
|
||||
"most radical of conspiracy theorists claiming that they control everything in the entire world. And while the world " +
|
||||
"may never know for sure, it is likely that many secret societies do actually exist, even today.<br><br>" +
|
||||
"However, the secret societies of the modern world are nothing like those that (supposedly) existed " +
|
||||
"decades and centuries ago. The Freemasons, Knights Templar, and Illuminati, while they may have been around " +
|
||||
`decades and centuries ago. The Freemasons, Knights Templar, and ${FactionNames.Illuminati}, while they may have been around ` +
|
||||
"at the turn of the 21st century, almost assuredly do not exist today. The dominance of the Web in " +
|
||||
"our everyday lives and the fact that so much of the world is now digital has given rise to a new breed " +
|
||||
"of secret societies: Internet-based ones.<br><br>" +
|
||||
"Commonly called 'hacker groups', Internet-based secret societies have become well-known in today's " +
|
||||
"world. Some of these, such as The Black Hand, are black hat groups that claim they are trying to " +
|
||||
"help the oppressed by attacking the elite and powerful. Others, such as NiteSec, are hacktivist groups " +
|
||||
`world. Some of these, such as ${FactionNames.TheBlackHand}, are black hat groups that claim they are trying to ` +
|
||||
`help the oppressed by attacking the elite and powerful. Others, such as ${FactionNames.NiteSec}, are hacktivist groups ` +
|
||||
"that try to push political and social agendas. Perhaps the most intriguing hacker group " +
|
||||
"is the mysterious Bitrunners, whose purpose still remains unknown.";
|
||||
`is the mysterious ${FactionNames.BitRunners}, whose purpose still remains unknown.`;
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
title = "Space: The Failed Frontier";
|
||||
@ -313,7 +315,7 @@ export const Literatures: IMap<Literature> = {};
|
||||
"Medical, service, and manufacturing robots. All of these are examples of how far AI has come and how much it has " +
|
||||
"improved our daily lives. However, the question still remains of whether AI will ever be advanced enough to re-create " +
|
||||
"human intelligence.<br><br>" +
|
||||
"We've certainly come close to artificial intelligence that is similar to humans. For example OmniTek Incorporated's " +
|
||||
`We've certainly come close to artificial intelligence that is similar to humans. For example ${FactionNames.OmniTekIncorporated}'s ` +
|
||||
"CompanionBot, a robot meant to act as a comforting friend for lonely and grieving people, is eerily human-like " +
|
||||
"in its appearance, speech, mannerisms, and even movement. However its artificial intelligence isn't the same as " +
|
||||
"that of humans. Not yet. It doesn't have sentience or self-awareness or consciousness.<br><br>" +
|
||||
@ -340,9 +342,9 @@ export const Literatures: IMap<Literature> = {};
|
||||
fn = LiteratureNames.TensionsInTechRace;
|
||||
txt =
|
||||
"Have we entered a new Cold War? Is WWIII just beyond the horizon?<br><br>" +
|
||||
"After rumors came out that OmniTek Incorporated had begun developing advanced robotic supersoldiers, " +
|
||||
`After rumors came out that ${FactionNames.OmniTekIncorporated} had begun developing advanced robotic supersoldiers, ` +
|
||||
"geopolitical tensions quickly flared between the USA, Russia, and several Asian superpowers. " +
|
||||
"In a rare show of cooperation between corporations, MegaCorp and ECorp have " +
|
||||
`In a rare show of cooperation between corporations, ${FactionNames.MegaCorp} and ${FactionNames.ECorp} have ` +
|
||||
"reportedly launched hundreds of new surveillance and espionage satellites. " +
|
||||
"Defense contractors such as " +
|
||||
"DeltaOne and AeroCorp have been working with the CIA and NSA to prepare " +
|
||||
@ -381,13 +383,13 @@ export const Literatures: IMap<Literature> = {};
|
||||
txt =
|
||||
"WAKE UP SHEEPLE<br><br>" +
|
||||
"THE GOVERNMENT DOES NOT EXIST. CORPORATIONS DO NOT RUN SOCIETY<br><br>" +
|
||||
"THE ILLUMINATI ARE THE SECRET RULERS OF THE WORLD!<br><br>" +
|
||||
"Yes, the Illuminati of legends. The ancient secret society that controls the entire " +
|
||||
`THE ${FactionNames.Illuminati.toUpperCase()} ARE THE SECRET RULERS OF THE WORLD!<br><br>` +
|
||||
`Yes, the ${FactionNames.Illuminati} of legends. The ancient secret society that controls the entire ` +
|
||||
"world from the shadows with their invisible hand. The group of the rich and wealthy " +
|
||||
"that have penetrated every major government, financial agency, and corporation in the last " +
|
||||
"three hundred years.<br><br>" +
|
||||
"OPEN YOUR EYES<br><br>" +
|
||||
"It was the Illuminati that brought an end to democracy in the world. They are the driving force " +
|
||||
`It was the ${FactionNames.Illuminati} that brought an end to democracy in the world. They are the driving force ` +
|
||||
"behind everything that happens.<br><br>" +
|
||||
"THEY ARE ALL AROUND YOU<br><br>" +
|
||||
"After destabilizing the world's governments, they are now entering the final stage of their master plan. " +
|
||||
@ -416,15 +418,15 @@ export const Literatures: IMap<Literature> = {};
|
||||
"territories. They were often considered one of the first and biggest criminal secret societies. " +
|
||||
"While most of the branches of the Triads have been destroyed over the past few decades, the " +
|
||||
"crime faction has spawned and inspired a number of other Asian crime organizations over the past few years. " +
|
||||
"The most notable of these is the Tetrads.<br><br>" +
|
||||
"It is widely believed that the Tetrads are a rogue group that splintered off from the Triads sometime in the " +
|
||||
"mid 21st century. The founders of the Tetrads, all of whom were ex-Triad members, believed that the " +
|
||||
"Triads were losing their purpose and direction. The Tetrads started off as a small group that mainly engaged " +
|
||||
`The most notable of these is the ${FactionNames.Tetrads}.<br><br>` +
|
||||
`It is widely believed that the ${FactionNames.Tetrads} are a rogue group that splintered off from the Triads sometime in the ` +
|
||||
`mid 21st century. The founders of the ${FactionNames.Tetrads}, all of whom were ex-Triad members, believed that the ` +
|
||||
`Triads were losing their purpose and direction. The ${FactionNames.Tetrads} started off as a small group that mainly engaged ` +
|
||||
"in fraud and extortion. They were largely unknown until just a few years ago when they took over the illegal " +
|
||||
"drug trade in all of the major Asian cities. They quickly became the most powerful crime syndicate in the " +
|
||||
"continent.<br><br>" +
|
||||
"Not much else is known about the Tetrads, or about the efforts the Asian governments and corporations are making " +
|
||||
"to take down this large new crime organization. Many believe that the Tetrads have infiltrated the governments " +
|
||||
`Not much else is known about the ${FactionNames.Tetrads}, or about the efforts the Asian governments and corporations are making ` +
|
||||
`to take down this large new crime organization. Many believe that the ${FactionNames.Tetrads} have infiltrated the governments ` +
|
||||
"and powerful corporations in Asia, which has helped faciliate their recent rapid rise.";
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
|
@ -2,14 +2,6 @@
|
||||
* Names of all locations
|
||||
*/
|
||||
export enum LocationName {
|
||||
// Cities
|
||||
Aevum = "Aevum",
|
||||
Chongqing = "Chongqing",
|
||||
Ishima = "Ishima",
|
||||
NewTokyo = "New Tokyo",
|
||||
Sector12 = "Sector-12",
|
||||
Volhaven = "Volhaven",
|
||||
|
||||
// Aevum Locations
|
||||
AevumAeroCorp = "AeroCorp",
|
||||
AevumBachmanAndAssociates = "Bachman & Associates",
|
||||
|
@ -33,6 +33,7 @@ import { HacknetNode } from "../../Hacknet/HacknetNode";
|
||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
import { ArcadeRoot } from "../../Arcade/ui/ArcadeRoot";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
@ -54,7 +55,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
router.toBladeburner();
|
||||
} else if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) {
|
||||
// Apply for Bladeburner division
|
||||
p.startBladeburner({new: true});
|
||||
p.startBladeburner({ new: true });
|
||||
dialogBoxCreate("You have been accepted into the Bladeburner division!");
|
||||
setRerender((old) => !old);
|
||||
|
||||
@ -158,8 +159,8 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function handleCotMG(): void {
|
||||
const faction = Factions["Church of the Machine God"];
|
||||
if (!player.factions.includes("Church of the Machine God")) {
|
||||
const faction = Factions[FactionNames.ChurchOfTheMachineGod];
|
||||
if (!player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
joinFaction(faction);
|
||||
}
|
||||
if (
|
||||
@ -174,35 +175,35 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
|
||||
function renderCotMG(): React.ReactElement {
|
||||
// prettier-ignore
|
||||
const symbol = <Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>
|
||||
{" `` "}<br />
|
||||
{" -odmmNmds: "}<br />
|
||||
{" `hNmo:..-omNh. "}<br />
|
||||
{" yMd` `hNh "}<br />
|
||||
{" mMd oNm "}<br />
|
||||
{" oMNo .mM/ "}<br />
|
||||
{" `dMN+ -mM+ "}<br />
|
||||
{" -mMNo -mN+ "}<br />
|
||||
{" .+- :mMNo/mN/ "}<br />
|
||||
{":yNMd. :NMNNN/ "}<br />
|
||||
{"-mMMMh. /NMMh` "}<br />
|
||||
{" .dMMMd. /NMMMy` "}<br />
|
||||
{" `yMMMd. /NNyNMMh` "}<br />
|
||||
{" `sMMMd. +Nm: +NMMh. "}<br />
|
||||
{" oMMMm- oNm: /NMMd. "}<br />
|
||||
{" +NMMmsMm- :mMMd. "}<br />
|
||||
{" /NMMMm- -mMMd. "}<br />
|
||||
{" /MMMm- -mMMd. "}<br />
|
||||
{" `sMNMMm- .mMmo "}<br />
|
||||
{" `sMd:hMMm. ./. "}<br />
|
||||
{" `yMy` `yNMd` "}<br />
|
||||
{" `hMs` oMMy "}<br />
|
||||
{" `hMh sMN- "}<br />
|
||||
{" /MM- .NMo "}<br />
|
||||
{" +MM: :MM+ "}<br />
|
||||
{" sNNo-.`.-omNy` "}<br />
|
||||
{" -smNNNNmdo- "}<br />
|
||||
{" `..` "}</Typography>
|
||||
const symbol = <Typography sx={{ lineHeight: '1em', whiteSpace: 'pre' }}>
|
||||
{" `` "}<br />
|
||||
{" -odmmNmds: "}<br />
|
||||
{" `hNmo:..-omNh. "}<br />
|
||||
{" yMd` `hNh "}<br />
|
||||
{" mMd oNm "}<br />
|
||||
{" oMNo .mM/ "}<br />
|
||||
{" `dMN+ -mM+ "}<br />
|
||||
{" -mMNo -mN+ "}<br />
|
||||
{" .+- :mMNo/mN/ "}<br />
|
||||
{":yNMd. :NMNNN/ "}<br />
|
||||
{"-mMMMh. /NMMh` "}<br />
|
||||
{" .dMMMd. /NMMMy` "}<br />
|
||||
{" `yMMMd. /NNyNMMh` "}<br />
|
||||
{" `sMMMd. +Nm: +NMMh. "}<br />
|
||||
{" oMMMm- oNm: /NMMd. "}<br />
|
||||
{" +NMMmsMm- :mMMd. "}<br />
|
||||
{" /NMMMm- -mMMd. "}<br />
|
||||
{" /MMMm- -mMMd. "}<br />
|
||||
{" `sMNMMm- .mMmo "}<br />
|
||||
{" `sMd:hMMm. ./. "}<br />
|
||||
{" `yMy` `yNMd` "}<br />
|
||||
{" `hMs` oMMy "}<br />
|
||||
{" `hMh sMN- "}<br />
|
||||
{" /MM- .NMo "}<br />
|
||||
{" +MM: :MM+ "}<br />
|
||||
{" sNNo-.`.-omNy` "}<br />
|
||||
{" -smNNNNmdo- "}<br />
|
||||
{" `..` "}</Typography>
|
||||
if (player.hasAugmentation(AugmentationNames.StaneksGift3, true)) {
|
||||
return (
|
||||
<>
|
||||
@ -231,7 +232,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (player.factions.includes("Church of the Machine God")) {
|
||||
if (player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
|
@ -8,6 +8,7 @@ import { GetServer } from "../Server/AllServers";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reviver } from "../utils/JSONReviver";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
|
||||
//Sends message to player, including a pop up
|
||||
function sendMessage(msg: Message, forced = false): void {
|
||||
@ -128,48 +129,48 @@ function initMessages(): void {
|
||||
new Message(
|
||||
MessageFilenames.Jumper0,
|
||||
"I know you can sense it. I know you're searching for it. " +
|
||||
"It's why you spend night after " +
|
||||
"night at your computer. <br><br>It's real, I've seen it. And I can " +
|
||||
"help you find it. But not right now. You're not ready yet.<br><br>" +
|
||||
"Use this program to track your progress<br><br>" +
|
||||
"The fl1ght.exe program was added to your home computer<br><br>" +
|
||||
"-jump3R",
|
||||
"It's why you spend night after " +
|
||||
"night at your computer. <br><br>It's real, I've seen it. And I can " +
|
||||
"help you find it. But not right now. You're not ready yet.<br><br>" +
|
||||
"Use this program to track your progress<br><br>" +
|
||||
"The fl1ght.exe program was added to your home computer<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper1,
|
||||
"Soon you will be contacted by a hacking group known as CyberSec. " +
|
||||
"They can help you with your search. <br><br>" +
|
||||
"You should join them, garner their favor, and " +
|
||||
"exploit them for their Augmentations. But do not trust them. " +
|
||||
"They are not what they seem. No one is.<br><br>" +
|
||||
"-jump3R",
|
||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
||||
"They can help you with your search. <br><br>" +
|
||||
"You should join them, garner their favor, and " +
|
||||
"exploit them for their Augmentations. But do not trust them. " +
|
||||
"They are not what they seem. No one is.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper2,
|
||||
"Do not try to save the world. There is no world to save. If " +
|
||||
"you want to find the truth, worry only about yourself. Ethics and " +
|
||||
"morals will get you killed. <br><br>Watch out for a hacking group known as NiteSec." +
|
||||
"<br><br>-jump3R",
|
||||
"you want to find the truth, worry only about yourself. Ethics and " +
|
||||
`morals will get you killed. <br><br>Watch out for a hacking group known as ${FactionNames.NiteSec}.` +
|
||||
"<br><br>-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper3,
|
||||
"You must learn to walk before you can run. And you must " +
|
||||
"run before you can fly. Look for the black hand. <br><br>" +
|
||||
"I.I.I.I <br><br>-jump3R",
|
||||
`run before you can fly. Look for ${FactionNames.TheBlackHand}. <br><br>` +
|
||||
"I.I.I.I <br><br>-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper4,
|
||||
"To find what you are searching for, you must understand the bits. " +
|
||||
"The bits are all around us. The runners will help you.<br><br>" +
|
||||
"-jump3R",
|
||||
"The bits are all around us. The runners will help you.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
|
||||
@ -178,31 +179,31 @@ function initMessages(): void {
|
||||
new Message(
|
||||
MessageFilenames.CyberSecTest,
|
||||
"We've been watching you. Your skills are very impressive. But you're wasting " +
|
||||
"your talents. If you join us, you can put your skills to good use and change " +
|
||||
"the world for the better. If you join us, we can unlock your full potential. <br><br>" +
|
||||
"But first, you must pass our test. Find and install the backdoor on our server. <br><br>" +
|
||||
"-CyberSec",
|
||||
"your talents. If you join us, you can put your skills to good use and change " +
|
||||
"the world for the better. If you join us, we can unlock your full potential. <br><br>" +
|
||||
"But first, you must pass our test. Find and install the backdoor on our server. <br><br>" +
|
||||
`-${FactionNames.CyberSec}`,
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.NiteSecTest,
|
||||
"People say that the corrupted governments and corporations rule the world. " +
|
||||
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
||||
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
||||
"and ideas with bullets. <br><br>" +
|
||||
"Join us, and people will fear you, too. <br><br>" +
|
||||
"Find and install the backdoor on our server. Then, we will contact you again." +
|
||||
"<br><br>-NiteSec",
|
||||
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
||||
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
||||
"and ideas with bullets. <br><br>" +
|
||||
"Join us, and people will fear you, too. <br><br>" +
|
||||
"Find and install the backdoor on our server. Then, we will contact you again." +
|
||||
`<br><br>-${FactionNames.NiteSec}`,
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.BitRunnersTest,
|
||||
"We know what you are doing. We know what drives you. We know " +
|
||||
"what you are looking for. <br><br> " +
|
||||
"We can help you find the answers.<br><br>" +
|
||||
"run4theh111z",
|
||||
"what you are looking for. <br><br> " +
|
||||
"We can help you find the answers.<br><br>" +
|
||||
"run4theh111z",
|
||||
),
|
||||
);
|
||||
|
||||
@ -210,9 +211,9 @@ function initMessages(): void {
|
||||
new Message(
|
||||
MessageFilenames.RedPill,
|
||||
"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%<br>" +
|
||||
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)<br>" +
|
||||
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
|
||||
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
||||
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)<br>" +
|
||||
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
|
||||
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Factions } from "../Faction/Factions";
|
||||
import { Faction } from "../Faction/Faction";
|
||||
import { GetServer } from "../Server/AllServers";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
|
||||
function allFactionAugs(p: IPlayer, f: Faction): boolean {
|
||||
const factionAugs = f.augmentations.slice().filter((aug) => aug !== "NeuroFlux Governor");
|
||||
@ -37,60 +38,60 @@ export const Milestones: Milestone[] = [
|
||||
{
|
||||
title: "Join the faction hinted at in csec-test.msg",
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return p.factions.includes("CyberSec");
|
||||
return p.factions.includes(FactionNames.CyberSec);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Install all the Augmentations from CyberSec",
|
||||
title: `Install all the Augmentations from ${FactionNames.CyberSec}`,
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return allFactionAugs(p, Factions["CyberSec"]);
|
||||
return allFactionAugs(p, Factions[FactionNames.CyberSec]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Join the faction hinted at in nitesec-test.msg",
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return p.factions.includes("NiteSec");
|
||||
return p.factions.includes(FactionNames.NiteSec);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Install all the Augmentations from NiteSec",
|
||||
title: `Install all the Augmentations from ${FactionNames.NiteSec}`,
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return allFactionAugs(p, Factions["NiteSec"]);
|
||||
return allFactionAugs(p, Factions[FactionNames.NiteSec]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Join the faction hinted at in j3.msg",
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return p.factions.includes("The Black Hand");
|
||||
return p.factions.includes(FactionNames.TheBlackHand);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Install all the Augmentations from The Black Hand",
|
||||
title: `Install all the Augmentations from ${FactionNames.TheBlackHand}`,
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return allFactionAugs(p, Factions["The Black Hand"]);
|
||||
return allFactionAugs(p, Factions[FactionNames.TheBlackHand]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Join the faction hinted at in 19dfj3l1nd.msg",
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return p.factions.includes("BitRunners");
|
||||
return p.factions.includes(FactionNames.BitRunners);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Install all the Augmentations from BitRunners",
|
||||
title: `Install all the Augmentations from ${FactionNames.BitRunners}`,
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return allFactionAugs(p, Factions["BitRunners"]);
|
||||
return allFactionAugs(p, Factions[FactionNames.BitRunners]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Complete fl1ght.exe",
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
// technically wrong but whatever
|
||||
return p.factions.includes("Daedalus");
|
||||
return p.factions.includes(FactionNames.Daedalus);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Install the special Augmentation from Daedalus",
|
||||
title: `Install the special Augmentation from ${FactionNames.Daedalus}`,
|
||||
fulfilled: (p: IPlayer): boolean => {
|
||||
return p.augmentations.some((aug) => aug.name == "The Red Pill");
|
||||
},
|
||||
|
@ -181,6 +181,8 @@ export const RamCosts: IMap<any> = {
|
||||
getForecast: RamCostConstants.ScriptBuySellStockRamCost,
|
||||
purchase4SMarketData: RamCostConstants.ScriptBuySellStockRamCost,
|
||||
purchase4SMarketDataTixApi: RamCostConstants.ScriptBuySellStockRamCost,
|
||||
purchaseWseAccount: RamCostConstants.ScriptBuySellStockRamCost,
|
||||
purchaseTixApi: RamCostConstants.ScriptBuySellStockRamCost,
|
||||
},
|
||||
getPurchasedServerLimit: RamCostConstants.ScriptGetPurchasedServerLimit,
|
||||
getPurchasedServerMaxRam: RamCostConstants.ScriptGetPurchasedServerMaxRam,
|
||||
@ -208,6 +210,7 @@ export const RamCosts: IMap<any> = {
|
||||
getScriptExpGain: RamCostConstants.ScriptGetScriptRamCost,
|
||||
getRunningScript: RamCostConstants.ScriptGetRunningScriptRamCost,
|
||||
nFormat: 0,
|
||||
tFormat: 0,
|
||||
getTimeSinceLastAug: RamCostConstants.ScriptGetHackTimeRamCost,
|
||||
prompt: 0,
|
||||
wget: 0,
|
||||
@ -215,6 +218,8 @@ export const RamCosts: IMap<any> = {
|
||||
getPlayer: RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||
mv: 0,
|
||||
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
|
||||
tail: 0,
|
||||
toast: 0,
|
||||
|
||||
// Singularity Functions
|
||||
universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
|
||||
|
@ -291,7 +291,7 @@ export function NetscriptCorporation(
|
||||
lastCycleExpenses: division.lastCycleExpenses,
|
||||
thisCycleRevenue: division.thisCycleRevenue,
|
||||
thisCycleExpenses: division.thisCycleExpenses,
|
||||
upgrades: division.upgrades,
|
||||
upgrades: division.upgrades.slice(),
|
||||
cities: cities,
|
||||
products: division.products === undefined ? [] : Object.keys(division.products),
|
||||
};
|
||||
@ -846,5 +846,9 @@ export function NetscriptCorporation(
|
||||
const amountShares = helper.number("bribe", "amountShares", aamountShares);
|
||||
return bribe(factionName, amountCash, amountShares);
|
||||
},
|
||||
getBonusTime: function (): number {
|
||||
checkAccess("getBonusTime");
|
||||
return Math.round(getCorporation().storedCycles / 5) * 1000;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { FactionNames } from '../Faction/data/FactionNames';
|
||||
import { GangConstants } from '../Gang/data/Constants';
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
@ -49,20 +51,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript, helpe
|
||||
createGang: function (faction: string): boolean {
|
||||
helper.updateDynamicRam("createGang", getRamCost(player, "gang", "createGang"));
|
||||
// this list is copied from Faction/ui/Root.tsx
|
||||
const GangNames = [
|
||||
"Slum Snakes",
|
||||
"Tetrads",
|
||||
"The Syndicate",
|
||||
"The Dark Army",
|
||||
"Speakers for the Dead",
|
||||
"NiteSec",
|
||||
"The Black Hand",
|
||||
];
|
||||
if (!player.canAccessGang() || !GangNames.includes(faction)) return false;
|
||||
|
||||
if (!player.canAccessGang() || !GangConstants.Names.includes(faction)) return false;
|
||||
if (player.inGang()) return false;
|
||||
if (!player.factions.includes(faction)) return false;
|
||||
|
||||
const isHacking = faction === "NiteSec" || faction === "The Black Hand";
|
||||
const isHacking = faction === FactionNames.NiteSec || faction === FactionNames.TheBlackHand;
|
||||
player.startGang(faction, isHacking);
|
||||
return true;
|
||||
},
|
||||
|
@ -91,25 +91,25 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
||||
|
||||
return res;
|
||||
},
|
||||
upgradeLevel: function (_i: unknown, _n: unknown): boolean {
|
||||
upgradeLevel: function (_i: unknown, _n: unknown = 1): boolean {
|
||||
const i = helper.number("upgradeLevel", "i", _i);
|
||||
const n = helper.number("upgradeLevel", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeLevel");
|
||||
return purchaseLevelUpgrade(player, node, n);
|
||||
},
|
||||
upgradeRam: function (_i: unknown, _n: unknown): boolean {
|
||||
upgradeRam: function (_i: unknown, _n: unknown = 1): boolean {
|
||||
const i = helper.number("upgradeRam", "i", _i);
|
||||
const n = helper.number("upgradeRam", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeRam");
|
||||
return purchaseRamUpgrade(player, node, n);
|
||||
},
|
||||
upgradeCore: function (_i: unknown, _n: unknown): boolean {
|
||||
upgradeCore: function (_i: unknown, _n: unknown = 1): boolean {
|
||||
const i = helper.number("upgradeCore", "i", _i);
|
||||
const n = helper.number("upgradeCore", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeCore");
|
||||
return purchaseCoreUpgrade(player, node, n);
|
||||
},
|
||||
upgradeCache: function (_i: unknown, _n: unknown): boolean {
|
||||
upgradeCache: function (_i: unknown, _n: unknown = 1): boolean {
|
||||
const i = helper.number("upgradeCache", "i", _i);
|
||||
const n = helper.number("upgradeCache", "n", _n);
|
||||
if (!hasHacknetServers(player)) {
|
||||
@ -126,25 +126,25 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getLevelUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||
getLevelUpgradeCost: function (_i: unknown, _n: unknown = 1): number {
|
||||
const i = helper.number("getLevelUpgradeCost", "i", _i);
|
||||
const n = helper.number("getLevelUpgradeCost", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeLevel");
|
||||
return node.calculateLevelUpgradeCost(n, player.hacknet_node_level_cost_mult);
|
||||
},
|
||||
getRamUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||
getRamUpgradeCost: function (_i: unknown, _n: unknown = 1): number {
|
||||
const i = helper.number("getRamUpgradeCost", "i", _i);
|
||||
const n = helper.number("getRamUpgradeCost", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeRam");
|
||||
return node.calculateRamUpgradeCost(n, player.hacknet_node_ram_cost_mult);
|
||||
},
|
||||
getCoreUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||
getCoreUpgradeCost: function (_i: unknown, _n: unknown = 1): number {
|
||||
const i = helper.number("getCoreUpgradeCost", "i", _i);
|
||||
const n = helper.number("getCoreUpgradeCost", "n", _n);
|
||||
const node = getHacknetNode(i, "upgradeCore");
|
||||
return node.calculateCoreUpgradeCost(n, player.hacknet_node_core_cost_mult);
|
||||
},
|
||||
getCacheUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||
getCacheUpgradeCost: function (_i: unknown, _n: unknown = 1): number {
|
||||
const i = helper.number("getCacheUpgradeCost", "i", _i);
|
||||
const n = helper.number("getCacheUpgradeCost", "n", _n);
|
||||
if (!hasHacknetServers(player)) {
|
||||
@ -177,10 +177,9 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
||||
|
||||
return player.hashManager.getUpgradeCost(upgName);
|
||||
},
|
||||
spendHashes: function (_upgName: unknown, _upgTarget: unknown): boolean {
|
||||
spendHashes: function (_upgName: unknown, _upgTarget: unknown = ""): boolean {
|
||||
const upgName = helper.string("spendHashes", "upgName", _upgName);
|
||||
let upgTarget = "";
|
||||
if (_upgTarget !== undefined) upgTarget = helper.string("spendHashes", "upgTarget", _upgTarget);
|
||||
const upgTarget = helper.string("spendHashes", "upgTarget", _upgTarget);
|
||||
if (!hasHacknetServers(player)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import { Terminal } from "../Terminal";
|
||||
import { calculateHackingTime } from "../Hacking";
|
||||
import { Server } from "../Server/Server";
|
||||
import { netscriptCanHack } from "../Hacking/netscriptCanHack";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
|
||||
export function NetscriptSingularity(
|
||||
player: IPlayer,
|
||||
@ -282,7 +283,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Aevum) {
|
||||
workerScript.log(
|
||||
"universityCourse",
|
||||
() => "You cannot study at 'Summit University' because you are not in 'Aevum'.",
|
||||
() => `You cannot study at 'Summit University' because you are not in '${CityName.Aevum}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -294,7 +295,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Sector12) {
|
||||
workerScript.log(
|
||||
"universityCourse",
|
||||
() => "You cannot study at 'Rothman University' because you are not in 'Sector-12'.",
|
||||
() => `You cannot study at 'Rothman University' because you are not in '${CityName.Sector12}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -306,7 +307,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Volhaven) {
|
||||
workerScript.log(
|
||||
"universityCourse",
|
||||
() => "You cannot study at 'ZB Institute of Technology' because you are not in 'Volhaven'.",
|
||||
() => `You cannot study at 'ZB Institute of Technology' because you are not in '${CityName.Volhaven}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -369,7 +370,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Aevum) {
|
||||
workerScript.log(
|
||||
"gymWorkout",
|
||||
() => "You cannot workout at 'Crush Fitness' because you are not in 'Aevum'.",
|
||||
() => `You cannot workout at '${LocationName.AevumCrushFitnessGym}' because you are not in '${CityName.Aevum}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -381,7 +382,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Aevum) {
|
||||
workerScript.log(
|
||||
"gymWorkout",
|
||||
() => "You cannot workout at 'Snap Fitness' because you are not in 'Aevum'.",
|
||||
() => `You cannot workout at '${LocationName.AevumSnapFitnessGym}' because you are not in '${CityName.Aevum}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -393,7 +394,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Sector12) {
|
||||
workerScript.log(
|
||||
"gymWorkout",
|
||||
() => "You cannot workout at 'Iron Gym' because you are not in 'Sector-12'.",
|
||||
() => `You cannot workout at '${LocationName.Sector12IronGym}' because you are not in '${CityName.Sector12}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -405,7 +406,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Sector12) {
|
||||
workerScript.log(
|
||||
"gymWorkout",
|
||||
() => "You cannot workout at 'Powerhouse Gym' because you are not in 'Sector-12'.",
|
||||
() => `You cannot workout at '${LocationName.Sector12PowerhouseGym}' because you are not in '${CityName.Sector12}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -417,7 +418,7 @@ export function NetscriptSingularity(
|
||||
if (player.city != CityName.Volhaven) {
|
||||
workerScript.log(
|
||||
"gymWorkout",
|
||||
() => "You cannot workout at 'Millenium Fitness Gym' because you are not in 'Volhaven'.",
|
||||
() => `You cannot workout at '${LocationName.VolhavenMilleniumFitnessGym}' because you are not in '${CityName.Volhaven}'.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -1033,85 +1034,85 @@ export function NetscriptSingularity(
|
||||
const fac = Factions[name];
|
||||
// Arrays listing factions that allow each time of work
|
||||
const hackAvailable = [
|
||||
"Illuminati",
|
||||
"Daedalus",
|
||||
"The Covenant",
|
||||
"ECorp",
|
||||
"MegaCorp",
|
||||
"Bachman & Associates",
|
||||
"Blade Industries",
|
||||
"NWO",
|
||||
"Clarke Incorporated",
|
||||
"OmniTek Incorporated",
|
||||
"Four Sigma",
|
||||
"KuaiGong International",
|
||||
"Fulcrum Secret Technologies",
|
||||
"BitRunners",
|
||||
"The Black Hand",
|
||||
"NiteSec",
|
||||
"Chongqing",
|
||||
"Sector-12",
|
||||
"New Tokyo",
|
||||
"Aevum",
|
||||
"Ishima",
|
||||
"Volhaven",
|
||||
"Speakers for the Dead",
|
||||
"The Dark Army",
|
||||
"The Syndicate",
|
||||
"Silhouette",
|
||||
"Netburners",
|
||||
"Tian Di Hui",
|
||||
"CyberSec",
|
||||
FactionNames.Illuminati as string,
|
||||
FactionNames.Daedalus as string,
|
||||
FactionNames.TheCovenant as string,
|
||||
FactionNames.ECorp as string,
|
||||
FactionNames.MegaCorp as string,
|
||||
FactionNames.BachmanAssociates as string,
|
||||
FactionNames.Bladeburners as string,
|
||||
FactionNames.NWO as string,
|
||||
FactionNames.ClarkeIncorporated as string,
|
||||
FactionNames.OmniTekIncorporated as string,
|
||||
FactionNames.FourSigma as string,
|
||||
FactionNames.KuaiGongInternational as string,
|
||||
FactionNames.FulcrumSecretTechnologies as string,
|
||||
FactionNames.BitRunners as string,
|
||||
FactionNames.TheBlackHand as string,
|
||||
FactionNames.NiteSec as string,
|
||||
FactionNames.Chongqing as string,
|
||||
FactionNames.Sector12 as string,
|
||||
FactionNames.NewTokyo as string,
|
||||
FactionNames.Aevum as string,
|
||||
FactionNames.Ishima as string,
|
||||
FactionNames.Volhaven as string,
|
||||
FactionNames.SpeakersForTheDead as string,
|
||||
FactionNames.TheDarkArmy as string,
|
||||
FactionNames.TheSyndicate as string,
|
||||
FactionNames.Silhouette as string,
|
||||
FactionNames.Netburners as string,
|
||||
FactionNames.TianDiHui as string,
|
||||
FactionNames.CyberSec as string,
|
||||
];
|
||||
const fdWkAvailable = [
|
||||
"Illuminati",
|
||||
"Daedalus",
|
||||
"The Covenant",
|
||||
"ECorp",
|
||||
"MegaCorp",
|
||||
"Bachman & Associates",
|
||||
"Blade Industries",
|
||||
"NWO",
|
||||
"Clarke Incorporated",
|
||||
"OmniTek Incorporated",
|
||||
"Four Sigma",
|
||||
"KuaiGong International",
|
||||
"The Black Hand",
|
||||
"Chongqing",
|
||||
"Sector-12",
|
||||
"New Tokyo",
|
||||
"Aevum",
|
||||
"Ishima",
|
||||
"Volhaven",
|
||||
"Speakers for the Dead",
|
||||
"The Dark Army",
|
||||
"The Syndicate",
|
||||
"Silhouette",
|
||||
"Tetrads",
|
||||
"Slum Snakes",
|
||||
FactionNames.Illuminati as string,
|
||||
FactionNames.Daedalus as string,
|
||||
FactionNames.TheCovenant as string,
|
||||
FactionNames.ECorp as string,
|
||||
FactionNames.MegaCorp as string,
|
||||
FactionNames.BachmanAssociates as string,
|
||||
FactionNames.Bladeburners as string,
|
||||
FactionNames.NWO as string,
|
||||
FactionNames.ClarkeIncorporated as string,
|
||||
FactionNames.OmniTekIncorporated as string,
|
||||
FactionNames.FourSigma as string,
|
||||
FactionNames.KuaiGongInternational as string,
|
||||
FactionNames.TheBlackHand as string,
|
||||
FactionNames.Chongqing as string,
|
||||
FactionNames.Sector12 as string,
|
||||
FactionNames.NewTokyo as string,
|
||||
FactionNames.Aevum as string,
|
||||
FactionNames.Ishima as string,
|
||||
FactionNames.Volhaven as string,
|
||||
FactionNames.SpeakersForTheDead as string,
|
||||
FactionNames.TheDarkArmy as string,
|
||||
FactionNames.TheSyndicate as string,
|
||||
FactionNames.Silhouette as string,
|
||||
FactionNames.Tetrads as string,
|
||||
FactionNames.SlumSnakes as string,
|
||||
];
|
||||
const scWkAvailable = [
|
||||
"ECorp",
|
||||
"MegaCorp",
|
||||
"Bachman & Associates",
|
||||
"Blade Industries",
|
||||
"NWO",
|
||||
"Clarke Incorporated",
|
||||
"OmniTek Incorporated",
|
||||
"Four Sigma",
|
||||
"KuaiGong International",
|
||||
"Fulcrum Secret Technologies",
|
||||
"Chongqing",
|
||||
"Sector-12",
|
||||
"New Tokyo",
|
||||
"Aevum",
|
||||
"Ishima",
|
||||
"Volhaven",
|
||||
"Speakers for the Dead",
|
||||
"The Syndicate",
|
||||
"Tetrads",
|
||||
"Slum Snakes",
|
||||
"Tian Di Hui",
|
||||
FactionNames.ECorp as string,
|
||||
FactionNames.MegaCorp as string,
|
||||
FactionNames.BachmanAssociates as string,
|
||||
FactionNames.Bladeburners as string,
|
||||
FactionNames.NWO as string,
|
||||
FactionNames.ClarkeIncorporated as string,
|
||||
FactionNames.OmniTekIncorporated as string,
|
||||
FactionNames.FourSigma as string,
|
||||
FactionNames.KuaiGongInternational as string,
|
||||
FactionNames.FulcrumSecretTechnologies as string,
|
||||
FactionNames.Chongqing as string,
|
||||
FactionNames.Sector12 as string,
|
||||
FactionNames.NewTokyo as string,
|
||||
FactionNames.Aevum as string,
|
||||
FactionNames.Ishima as string,
|
||||
FactionNames.Volhaven as string,
|
||||
FactionNames.SpeakersForTheDead as string,
|
||||
FactionNames.TheSyndicate as string,
|
||||
FactionNames.Tetrads as string,
|
||||
FactionNames.SlumSnakes as string,
|
||||
FactionNames.TianDiHui as string,
|
||||
];
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
|
@ -30,6 +30,20 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
|
||||
}
|
||||
};
|
||||
|
||||
const getSleeveStats = function (sleeveNumber: any): any {
|
||||
const sl = player.sleeves[sleeveNumber];
|
||||
return {
|
||||
shock: 100 - sl.shock,
|
||||
sync: sl.sync,
|
||||
hacking: sl.hacking,
|
||||
strength: sl.strength,
|
||||
defense: sl.defense,
|
||||
dexterity: sl.dexterity,
|
||||
agility: sl.agility,
|
||||
charisma: sl.charisma,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
getNumSleeves: function (): number {
|
||||
helper.updateDynamicRam("getNumSleeves", getRamCost(player, "sleeve", "getNumSleeves"));
|
||||
@ -150,18 +164,7 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
|
||||
helper.updateDynamicRam("getSleeveStats", getRamCost(player, "sleeve", "getSleeveStats"));
|
||||
checkSleeveAPIAccess("getSleeveStats");
|
||||
checkSleeveNumber("getSleeveStats", sleeveNumber);
|
||||
|
||||
const sl = player.sleeves[sleeveNumber];
|
||||
return {
|
||||
shock: 100 - sl.shock,
|
||||
sync: sl.sync,
|
||||
hacking: sl.hacking,
|
||||
strength: sl.strength,
|
||||
defense: sl.defense,
|
||||
dexterity: sl.dexterity,
|
||||
agility: sl.agility,
|
||||
charisma: sl.charisma,
|
||||
};
|
||||
return getSleeveStats(sleeveNumber)
|
||||
},
|
||||
getTask: function (asleeveNumber: any = 0): {
|
||||
task: string;
|
||||
@ -289,6 +292,10 @@ export function NetscriptSleeve(player: IPlayer, workerScript: WorkerScript, hel
|
||||
checkSleeveAPIAccess("purchaseSleeveAug");
|
||||
checkSleeveNumber("purchaseSleeveAug", sleeveNumber);
|
||||
|
||||
if (getSleeveStats(sleeveNumber).shock > 0) {
|
||||
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||
}
|
||||
|
||||
const aug = Augmentations[augName];
|
||||
if (!aug) {
|
||||
throw helper.makeRuntimeErrorMsg("sleeve.purchaseSleeveAug", `Invalid aug: ${augName}`);
|
||||
|
@ -8,7 +8,12 @@ import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/St
|
||||
import { OrderTypes } from "../StockMarket/data/OrderTypes";
|
||||
import { PositionTypes } from "../StockMarket/data/PositionTypes";
|
||||
import { StockSymbols } from "../StockMarket/data/StockSymbols";
|
||||
import { getStockMarket4SDataCost, getStockMarket4STixApiCost } from "../StockMarket/StockMarketCosts";
|
||||
import {
|
||||
getStockMarket4SDataCost,
|
||||
getStockMarket4STixApiCost,
|
||||
getStockMarketWseCost,
|
||||
getStockMarketTixApiCost,
|
||||
} from "../StockMarket/StockMarketCosts";
|
||||
import { Stock } from "../StockMarket/Stock";
|
||||
import { TIX } from "../ScriptEditor/NetscriptDefinitions";
|
||||
|
||||
@ -40,32 +45,32 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return Object.values(StockSymbols);
|
||||
},
|
||||
getPrice: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getPrice", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getPrice", getRamCost(player, "stock", "getPrice"));
|
||||
const symbol = helper.string("getPrice", "symbol", _symbol);
|
||||
checkTixApiAccess("getPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getPrice");
|
||||
|
||||
return stock.price;
|
||||
},
|
||||
getAskPrice: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getAskPrice", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getAskPrice", getRamCost(player, "stock", "getAskPrice"));
|
||||
const symbol = helper.string("getAskPrice", "symbol", _symbol);
|
||||
checkTixApiAccess("getAskPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getAskPrice");
|
||||
|
||||
return stock.getAskPrice();
|
||||
},
|
||||
getBidPrice: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getBidPrice", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getBidPrice", getRamCost(player, "stock", "getBidPrice"));
|
||||
const symbol = helper.string("getBidPrice", "symbol", _symbol);
|
||||
checkTixApiAccess("getBidPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getBidPrice");
|
||||
|
||||
return stock.getBidPrice();
|
||||
},
|
||||
getPosition: function (_symbol: unknown): [number, number, number, number] {
|
||||
const symbol = helper.string("getPosition", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getPosition", getRamCost(player, "stock", "getPosition"));
|
||||
const symbol = helper.string("getPosition", "symbol", _symbol);
|
||||
checkTixApiAccess("getPosition");
|
||||
const stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
@ -74,18 +79,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||
},
|
||||
getMaxShares: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getMaxShares", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getMaxShares", getRamCost(player, "stock", "getMaxShares"));
|
||||
const symbol = helper.string("getMaxShares", "symbol", _symbol);
|
||||
checkTixApiAccess("getMaxShares");
|
||||
const stock = getStockFromSymbol(symbol, "getMaxShares");
|
||||
|
||||
return stock.maxShares;
|
||||
},
|
||||
getPurchaseCost: function (_symbol: unknown, _shares: unknown, _posType: unknown): number {
|
||||
helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost"));
|
||||
const symbol = helper.string("getPurchaseCost", "symbol", _symbol);
|
||||
let shares = helper.number("getPurchaseCost", "shares", _shares);
|
||||
const posType = helper.string("getPurchaseCost", "posType", _posType);
|
||||
helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost"));
|
||||
checkTixApiAccess("getPurchaseCost");
|
||||
const stock = getStockFromSymbol(symbol, "getPurchaseCost");
|
||||
shares = Math.round(shares);
|
||||
@ -108,10 +113,10 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return res;
|
||||
},
|
||||
getSaleGain: function (_symbol: unknown, _shares: unknown, _posType: unknown): number {
|
||||
helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain"));
|
||||
const symbol = helper.string("getSaleGain", "symbol", _symbol);
|
||||
let shares = helper.number("getSaleGain", "shares", _shares);
|
||||
const posType = helper.string("getSaleGain", "posType", _posType);
|
||||
helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain"));
|
||||
checkTixApiAccess("getSaleGain");
|
||||
const stock = getStockFromSymbol(symbol, "getSaleGain");
|
||||
shares = Math.round(shares);
|
||||
@ -134,18 +139,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return res;
|
||||
},
|
||||
buy: function (_symbol: unknown, _shares: unknown): number {
|
||||
helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy"));
|
||||
const symbol = helper.string("buy", "symbol", _symbol);
|
||||
const shares = helper.number("buy", "shares", _shares);
|
||||
helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy"));
|
||||
checkTixApiAccess("buy");
|
||||
const stock = getStockFromSymbol(symbol, "buy");
|
||||
const res = buyStock(stock, shares, workerScript, {});
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
sell: function (_symbol: unknown, _shares: unknown): number {
|
||||
helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell"));
|
||||
const symbol = helper.string("sell", "symbol", _symbol);
|
||||
const shares = helper.number("sell", "shares", _shares);
|
||||
helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell"));
|
||||
checkTixApiAccess("sell");
|
||||
const stock = getStockFromSymbol(symbol, "sell");
|
||||
const res = sellStock(stock, shares, workerScript, {});
|
||||
@ -153,9 +158,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
short: function (_symbol: unknown, _shares: unknown): number {
|
||||
helper.updateDynamicRam("short", getRamCost(player, "stock", "short"));
|
||||
const symbol = helper.string("short", "symbol", _symbol);
|
||||
const shares = helper.number("short", "shares", _shares);
|
||||
helper.updateDynamicRam("short", getRamCost(player, "stock", "short"));
|
||||
checkTixApiAccess("short");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
@ -171,9 +176,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
sellShort: function (_symbol: unknown, _shares: unknown): number {
|
||||
helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort"));
|
||||
const symbol = helper.string("sellShort", "symbol", _symbol);
|
||||
const shares = helper.number("sellShort", "shares", _shares);
|
||||
helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort"));
|
||||
checkTixApiAccess("sellShort");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
@ -189,12 +194,12 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
placeOrder: function (_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean {
|
||||
helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder"));
|
||||
const symbol = helper.string("placeOrder", "symbol", _symbol);
|
||||
const shares = helper.number("placeOrder", "shares", _shares);
|
||||
const price = helper.number("placeOrder", "price", _price);
|
||||
const type = helper.string("placeOrder", "type", _type);
|
||||
const pos = helper.string("placeOrder", "pos", _pos);
|
||||
helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder"));
|
||||
checkTixApiAccess("placeOrder");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
@ -239,12 +244,12 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
_type: unknown,
|
||||
_pos: unknown,
|
||||
): boolean {
|
||||
helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder"));
|
||||
const symbol = helper.string("cancelOrder", "symbol", _symbol);
|
||||
const shares = helper.number("cancelOrder", "shares", _shares);
|
||||
const price = helper.number("cancelOrder", "price", _price);
|
||||
const type = helper.string("cancelOrder", "type", _type);
|
||||
const pos = helper.string("cancelOrder", "pos", _pos);
|
||||
helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder"));
|
||||
checkTixApiAccess("cancelOrder");
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
@ -326,8 +331,8 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return orders;
|
||||
},
|
||||
getVolatility: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getVolatility", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getVolatility", getRamCost(player, "stock", "getVolatility"));
|
||||
const symbol = helper.string("getVolatility", "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
@ -336,8 +341,8 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
return stock.mv / 100; // Convert from percentage to decimal
|
||||
},
|
||||
getForecast: function (_symbol: unknown): number {
|
||||
const symbol = helper.string("getForecast", "symbol", _symbol);
|
||||
helper.updateDynamicRam("getForecast", getRamCost(player, "stock", "getForecast"));
|
||||
const symbol = helper.string("getForecast", "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
@ -388,5 +393,41 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
||||
workerScript.log("stock.purchase4SMarketDataTixApi", () => "Purchased 4S Market Data TIX API");
|
||||
return true;
|
||||
},
|
||||
purchaseWseAccount: function (): boolean {
|
||||
helper.updateDynamicRam("PurchaseWseAccount", getRamCost(player, "stock", "purchaseWseAccount"));
|
||||
|
||||
if (player.hasWseAccount) {
|
||||
workerScript.log("stock.purchaseWseAccount", () => "Already purchased WSE Account");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money < getStockMarketWseCost()) {
|
||||
workerScript.log("stock.purchaseWseAccount", () => "Not enough money to purchase WSE Account Access");
|
||||
return false;
|
||||
}
|
||||
|
||||
player.hasWseAccount = true;
|
||||
player.loseMoney(getStockMarketWseCost(), "stock");
|
||||
workerScript.log("stock.purchaseWseAccount", () => "Purchased WSE Account Access");
|
||||
return true;
|
||||
},
|
||||
purchaseTixApi: function (): boolean {
|
||||
helper.updateDynamicRam("purchaseTixApi", getRamCost(player, "stock", "purchaseTixApi"));
|
||||
|
||||
if (player.hasTixApiAccess) {
|
||||
workerScript.log("stock.purchaseTixApi", () => "Already purchased TIX API");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.money < getStockMarketTixApiCost()) {
|
||||
workerScript.log("stock.purchaseTixApi", () => "Not enough money to purchase TIX API Access");
|
||||
return false;
|
||||
}
|
||||
|
||||
player.hasTixApiAccess = true;
|
||||
player.loseMoney(getStockMarketTixApiCost(), "stock");
|
||||
workerScript.log("stock.purchaseTixApi", () => "Purchased TIX API");
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ import { serverMetadata } from "../../Server/data/servers";
|
||||
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
||||
import { calculateClassEarnings } from "../formulas/work";
|
||||
import { achievements } from "../../Achievements/Achievements";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
export function init(this: IPlayer): void {
|
||||
/* Initialize Player's home computer */
|
||||
@ -609,8 +610,8 @@ export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.work(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
router.toCity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -931,7 +932,9 @@ export function startFactionSecurityWork(this: IPlayer, faction: Faction): void
|
||||
export function workForFaction(this: IPlayer, numCycles: number): boolean {
|
||||
const faction = Factions[this.currentWorkFactionName];
|
||||
|
||||
if (!faction) { return false; }
|
||||
if (!faction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Constantly update the rep gain rate
|
||||
switch (this.factionWorkType) {
|
||||
@ -1251,12 +1254,7 @@ export function getWorkRepGain(this: IPlayer): number {
|
||||
// }
|
||||
|
||||
/* Creating a Program */
|
||||
export function startCreateProgramWork(
|
||||
this: IPlayer,
|
||||
programName: string,
|
||||
time: number,
|
||||
reqLevel: number,
|
||||
): void {
|
||||
export function startCreateProgramWork(this: IPlayer, programName: string, time: number, reqLevel: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeCreateProgram;
|
||||
@ -1755,7 +1753,6 @@ export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing =
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false; //Same job, do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@ -2000,13 +1997,15 @@ export function isQualified(this: IPlayer, company: Company, position: CompanyPo
|
||||
const reqAgility = position.requiredDexterity > 0 ? position.requiredDexterity + offset : 0;
|
||||
const reqCharisma = position.requiredCharisma > 0 ? position.requiredCharisma + offset : 0;
|
||||
|
||||
return this.hacking >= reqHacking &&
|
||||
return (
|
||||
this.hacking >= reqHacking &&
|
||||
this.strength >= reqStrength &&
|
||||
this.defense >= reqDefense &&
|
||||
this.dexterity >= reqDexterity &&
|
||||
this.agility >= reqAgility &&
|
||||
this.charisma >= reqCharisma &&
|
||||
company.playerReputation >= position.requiredReputation;
|
||||
company.playerReputation >= position.requiredReputation
|
||||
);
|
||||
}
|
||||
|
||||
/********** Reapplying Augmentations and Source File ***********/
|
||||
@ -2088,7 +2087,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Illuminati
|
||||
const illuminatiFac = Factions["Illuminati"];
|
||||
const illuminatiFac = Factions[FactionNames.Illuminati];
|
||||
if (
|
||||
!illuminatiFac.isBanned &&
|
||||
!illuminatiFac.isMember &&
|
||||
@ -2105,7 +2104,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Daedalus
|
||||
const daedalusFac = Factions["Daedalus"];
|
||||
const daedalusFac = Factions[FactionNames.Daedalus];
|
||||
if (
|
||||
!daedalusFac.isBanned &&
|
||||
!daedalusFac.isMember &&
|
||||
@ -2119,7 +2118,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//The Covenant
|
||||
const covenantFac = Factions["The Covenant"];
|
||||
const covenantFac = Factions[FactionNames.TheCovenant];
|
||||
if (
|
||||
!covenantFac.isBanned &&
|
||||
!covenantFac.isMember &&
|
||||
@ -2136,7 +2135,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//ECorp
|
||||
const ecorpFac = Factions["ECorp"];
|
||||
const ecorpFac = Factions[FactionNames.ECorp];
|
||||
if (
|
||||
!ecorpFac.isBanned &&
|
||||
!ecorpFac.isMember &&
|
||||
@ -2147,7 +2146,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//MegaCorp
|
||||
const megacorpFac = Factions["MegaCorp"];
|
||||
const megacorpFac = Factions[FactionNames.MegaCorp];
|
||||
if (
|
||||
!megacorpFac.isBanned &&
|
||||
!megacorpFac.isMember &&
|
||||
@ -2158,7 +2157,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Bachman & Associates
|
||||
const bachmanandassociatesFac = Factions["Bachman & Associates"];
|
||||
const bachmanandassociatesFac = Factions[FactionNames.BachmanAssociates];
|
||||
if (
|
||||
!bachmanandassociatesFac.isBanned &&
|
||||
!bachmanandassociatesFac.isMember &&
|
||||
@ -2169,7 +2168,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Blade Industries
|
||||
const bladeindustriesFac = Factions["Blade Industries"];
|
||||
const bladeindustriesFac = Factions[FactionNames.BladeIndustries];
|
||||
if (
|
||||
!bladeindustriesFac.isBanned &&
|
||||
!bladeindustriesFac.isMember &&
|
||||
@ -2180,7 +2179,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//NWO
|
||||
const nwoFac = Factions["NWO"];
|
||||
const nwoFac = Factions[FactionNames.NWO];
|
||||
if (
|
||||
!nwoFac.isBanned &&
|
||||
!nwoFac.isMember &&
|
||||
@ -2191,7 +2190,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Clarke Incorporated
|
||||
const clarkeincorporatedFac = Factions["Clarke Incorporated"];
|
||||
const clarkeincorporatedFac = Factions[FactionNames.ClarkeIncorporated];
|
||||
if (
|
||||
!clarkeincorporatedFac.isBanned &&
|
||||
!clarkeincorporatedFac.isMember &&
|
||||
@ -2202,7 +2201,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//OmniTek Incorporated
|
||||
const omnitekincorporatedFac = Factions["OmniTek Incorporated"];
|
||||
const omnitekincorporatedFac = Factions[FactionNames.OmniTekIncorporated];
|
||||
if (
|
||||
!omnitekincorporatedFac.isBanned &&
|
||||
!omnitekincorporatedFac.isMember &&
|
||||
@ -2213,7 +2212,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Four Sigma
|
||||
const foursigmaFac = Factions["Four Sigma"];
|
||||
const foursigmaFac = Factions[FactionNames.FourSigma];
|
||||
if (
|
||||
!foursigmaFac.isBanned &&
|
||||
!foursigmaFac.isMember &&
|
||||
@ -2224,7 +2223,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//KuaiGong International
|
||||
const kuaigonginternationalFac = Factions["KuaiGong International"];
|
||||
const kuaigonginternationalFac = Factions[FactionNames.KuaiGongInternational];
|
||||
if (
|
||||
!kuaigonginternationalFac.isBanned &&
|
||||
!kuaigonginternationalFac.isMember &&
|
||||
@ -2235,27 +2234,28 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Fulcrum Secret Technologies - If u've unlocked fulcrum secret technolgoies server and have a high rep with the company
|
||||
const fulcrumsecrettechonologiesFac = Factions["Fulcrum Secret Technologies"];
|
||||
const fulcrumsecrettechonologiesFac = Factions[FactionNames.FulcrumSecretTechnologies];
|
||||
const fulcrumSecretServer = GetServer(SpecialServers.FulcrumSecretTechnologies);
|
||||
if (!(fulcrumSecretServer instanceof Server)) throw new Error("Fulcrum Secret Technologies should be normal server");
|
||||
if (!(fulcrumSecretServer instanceof Server))
|
||||
throw new Error(`${FactionNames.FulcrumSecretTechnologies} should be normal server`);
|
||||
if (fulcrumSecretServer == null) {
|
||||
console.error("Could not find Fulcrum Secret Technologies Server");
|
||||
console.error(`Could not find ${FactionNames.FulcrumSecretTechnologies} Server`);
|
||||
} else if (
|
||||
!fulcrumsecrettechonologiesFac.isBanned &&
|
||||
!fulcrumsecrettechonologiesFac.isMember &&
|
||||
!fulcrumsecrettechonologiesFac.alreadyInvited &&
|
||||
fulcrumSecretServer.backdoorInstalled &&
|
||||
checkMegacorpRequirements(LocationName.AevumFulcrumTechnologies, 250e3)
|
||||
) {
|
||||
invitedFactions.push(fulcrumsecrettechonologiesFac);
|
||||
}
|
||||
!fulcrumsecrettechonologiesFac.isBanned &&
|
||||
!fulcrumsecrettechonologiesFac.isMember &&
|
||||
!fulcrumsecrettechonologiesFac.alreadyInvited &&
|
||||
fulcrumSecretServer.backdoorInstalled &&
|
||||
checkMegacorpRequirements(LocationName.AevumFulcrumTechnologies, 250e3)
|
||||
) {
|
||||
invitedFactions.push(fulcrumsecrettechonologiesFac);
|
||||
}
|
||||
|
||||
//BitRunners
|
||||
const bitrunnersFac = Factions["BitRunners"];
|
||||
const bitrunnersFac = Factions[FactionNames.BitRunners];
|
||||
const bitrunnersServer = GetServer(SpecialServers.BitRunnersServer);
|
||||
if (!(bitrunnersServer instanceof Server)) throw new Error("BitRunners should be normal server");
|
||||
if (!(bitrunnersServer instanceof Server)) throw new Error(`${FactionNames.BitRunners} should be normal server`);
|
||||
if (bitrunnersServer == null) {
|
||||
console.error("Could not find BitRunners Server");
|
||||
console.error(`Could not find ${FactionNames.BitRunners} Server`);
|
||||
} else if (
|
||||
!bitrunnersFac.isBanned &&
|
||||
!bitrunnersFac.isMember &&
|
||||
@ -2267,11 +2267,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
|
||||
//The Black Hand
|
||||
|
||||
const theblackhandFac = Factions["The Black Hand"];
|
||||
const theblackhandFac = Factions[FactionNames.TheBlackHand];
|
||||
const blackhandServer = GetServer(SpecialServers.TheBlackHandServer);
|
||||
if (!(blackhandServer instanceof Server)) throw new Error("TheBlackHand should be normal server");
|
||||
if (!(blackhandServer instanceof Server)) throw new Error(`${FactionNames.TheBlackHand} should be normal server`);
|
||||
if (blackhandServer == null) {
|
||||
console.error("Could not find The Black Hand Server");
|
||||
console.error(`Could not find ${FactionNames.TheBlackHand} Server`);
|
||||
} else if (
|
||||
!theblackhandFac.isBanned &&
|
||||
!theblackhandFac.isMember &&
|
||||
@ -2282,11 +2282,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//NiteSec
|
||||
const nitesecFac = Factions["NiteSec"];
|
||||
const nitesecFac = Factions[FactionNames.NiteSec];
|
||||
const nitesecServer = GetServer(SpecialServers.NiteSecServer);
|
||||
if (!(nitesecServer instanceof Server)) throw new Error("NiteSec should be normal server");
|
||||
if (!(nitesecServer instanceof Server)) throw new Error(`${FactionNames.NiteSec} should be normal server`);
|
||||
if (nitesecServer == null) {
|
||||
console.error("Could not find NiteSec Server");
|
||||
console.error(`Could not find ${FactionNames.NiteSec} Server`);
|
||||
} else if (
|
||||
!nitesecFac.isBanned &&
|
||||
!nitesecFac.isMember &&
|
||||
@ -2297,7 +2297,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Chongqing
|
||||
const chongqingFac = Factions["Chongqing"];
|
||||
const chongqingFac = Factions[FactionNames.Chongqing];
|
||||
if (
|
||||
!chongqingFac.isBanned &&
|
||||
!chongqingFac.isMember &&
|
||||
@ -2309,7 +2309,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Sector-12
|
||||
const sector12Fac = Factions["Sector-12"];
|
||||
const sector12Fac = Factions[FactionNames.Sector12];
|
||||
if (
|
||||
!sector12Fac.isBanned &&
|
||||
!sector12Fac.isMember &&
|
||||
@ -2321,7 +2321,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//New Tokyo
|
||||
const newtokyoFac = Factions["New Tokyo"];
|
||||
const newtokyoFac = Factions[FactionNames.NewTokyo];
|
||||
if (
|
||||
!newtokyoFac.isBanned &&
|
||||
!newtokyoFac.isMember &&
|
||||
@ -2333,7 +2333,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Aevum
|
||||
const aevumFac = Factions["Aevum"];
|
||||
const aevumFac = Factions[FactionNames.Aevum];
|
||||
if (
|
||||
!aevumFac.isBanned &&
|
||||
!aevumFac.isMember &&
|
||||
@ -2345,7 +2345,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Ishima
|
||||
const ishimaFac = Factions["Ishima"];
|
||||
const ishimaFac = Factions[FactionNames.Ishima];
|
||||
if (
|
||||
!ishimaFac.isBanned &&
|
||||
!ishimaFac.isMember &&
|
||||
@ -2357,7 +2357,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Volhaven
|
||||
const volhavenFac = Factions["Volhaven"];
|
||||
const volhavenFac = Factions[FactionNames.Volhaven];
|
||||
if (
|
||||
!volhavenFac.isBanned &&
|
||||
!volhavenFac.isMember &&
|
||||
@ -2369,7 +2369,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Speakers for the Dead
|
||||
const speakersforthedeadFac = Factions["Speakers for the Dead"];
|
||||
const speakersforthedeadFac = Factions[FactionNames.SpeakersForTheDead];
|
||||
if (
|
||||
!speakersforthedeadFac.isBanned &&
|
||||
!speakersforthedeadFac.isMember &&
|
||||
@ -2388,7 +2388,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//The Dark Army
|
||||
const thedarkarmyFac = Factions["The Dark Army"];
|
||||
const thedarkarmyFac = Factions[FactionNames.TheDarkArmy];
|
||||
if (
|
||||
!thedarkarmyFac.isBanned &&
|
||||
!thedarkarmyFac.isMember &&
|
||||
@ -2408,7 +2408,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//The Syndicate
|
||||
const thesyndicateFac = Factions["The Syndicate"];
|
||||
const thesyndicateFac = Factions[FactionNames.TheSyndicate];
|
||||
if (
|
||||
!thesyndicateFac.isBanned &&
|
||||
!thesyndicateFac.isMember &&
|
||||
@ -2428,7 +2428,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Silhouette
|
||||
const silhouetteFac = Factions["Silhouette"];
|
||||
const silhouetteFac = Factions[FactionNames.Silhouette];
|
||||
if (
|
||||
!silhouetteFac.isBanned &&
|
||||
!silhouetteFac.isMember &&
|
||||
@ -2443,7 +2443,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Tetrads
|
||||
const tetradsFac = Factions["Tetrads"];
|
||||
const tetradsFac = Factions[FactionNames.Tetrads];
|
||||
if (
|
||||
!tetradsFac.isBanned &&
|
||||
!tetradsFac.isMember &&
|
||||
@ -2459,7 +2459,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//SlumSnakes
|
||||
const slumsnakesFac = Factions["Slum Snakes"];
|
||||
const slumsnakesFac = Factions[FactionNames.SlumSnakes];
|
||||
if (
|
||||
!slumsnakesFac.isBanned &&
|
||||
!slumsnakesFac.isMember &&
|
||||
@ -2475,7 +2475,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Netburners
|
||||
const netburnersFac = Factions["Netburners"];
|
||||
const netburnersFac = Factions[FactionNames.Netburners];
|
||||
let totalHacknetRam = 0;
|
||||
let totalHacknetCores = 0;
|
||||
let totalHacknetLevels = 0;
|
||||
@ -2507,7 +2507,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//Tian Di Hui
|
||||
const tiandihuiFac = Factions["Tian Di Hui"];
|
||||
const tiandihuiFac = Factions[FactionNames.TianDiHui];
|
||||
if (
|
||||
!tiandihuiFac.isBanned &&
|
||||
!tiandihuiFac.isMember &&
|
||||
@ -2520,11 +2520,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
||||
}
|
||||
|
||||
//CyberSec
|
||||
const cybersecFac = Factions["CyberSec"];
|
||||
const cybersecFac = Factions[FactionNames.CyberSec];
|
||||
const cybersecServer = GetServer(SpecialServers.CyberSecServer);
|
||||
if (!(cybersecServer instanceof Server)) throw new Error("cybersec should be normal server");
|
||||
if (!(cybersecServer instanceof Server)) throw new Error(`${FactionNames.CyberSec} should be normal server`);
|
||||
if (cybersecServer == null) {
|
||||
console.error("Could not find CyberSec Server");
|
||||
console.error(`Could not find ${FactionNames.CyberSec} Server`);
|
||||
} else if (
|
||||
!cybersecFac.isBanned &&
|
||||
!cybersecFac.isMember &&
|
||||
@ -2581,7 +2581,7 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
|
||||
const totalGain = CONSTANTS.CodingContractBaseFactionRepGain * difficulty;
|
||||
|
||||
// Ignore Bladeburners and other special factions for this calculation
|
||||
const specialFactions = ["Bladeburners"];
|
||||
const specialFactions = [FactionNames.Bladeburners as string];
|
||||
const factions = this.factions.slice().filter((f) => {
|
||||
return !specialFactions.includes(f);
|
||||
});
|
||||
@ -2600,7 +2600,6 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
|
||||
Factions[facName].playerReputation += gainPerFaction;
|
||||
}
|
||||
return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.toString()}`;
|
||||
break;
|
||||
case CodingContractRewardType.CompanyReputation: {
|
||||
if (reward.name == null || !(Companies[reward.name] instanceof Company)) {
|
||||
//If no/invalid company was designated, just give rewards to all factions
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { FactionNames } from '../../Faction/data/FactionNames';
|
||||
import { Sleeve } from "./Sleeve";
|
||||
|
||||
import { IPlayer } from "../IPlayer";
|
||||
@ -80,10 +81,10 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
||||
}
|
||||
|
||||
for (const facName of p.factions) {
|
||||
if (facName === "Bladeburners") {
|
||||
if (facName === FactionNames.Bladeburners) {
|
||||
continue;
|
||||
}
|
||||
if (facName === "Netburners") {
|
||||
if (facName === FactionNames.Netburners) {
|
||||
continue;
|
||||
}
|
||||
const fac: Faction | null = Factions[facName];
|
||||
|
@ -16,6 +16,7 @@ import { use } from "../../../ui/Context";
|
||||
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { FactionNames } from "../../../Faction/data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -76,7 +77,7 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
|
||||
<>
|
||||
<Typography>
|
||||
Purchase an additional Sleeves. These Duplicate Sleeves are permanent (they persist through BitNodes). You
|
||||
can purchase a total of {MaxSleevesFromCovenant} from The Covenant.
|
||||
can purchase a total of {MaxSleevesFromCovenant} from {FactionNames.TheCovenant}.
|
||||
</Typography>
|
||||
<Button disabled={purchaseDisabled} onClick={purchaseOnClick}>
|
||||
Purchase -
|
||||
|
@ -2,6 +2,7 @@ import React from "react";
|
||||
|
||||
import { Modal } from "../../../ui/React/Modal";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { FactionNames } from "../../../Faction/data/FactionNames";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
@ -90,7 +91,7 @@ export function FAQModal({ open, onClose }: IProps): React.ReactElement {
|
||||
<Typography variant="h4">Why can't I buy the X Augmentation for my sleeve?</Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
Certain Augmentations, like Bladeburner-specific ones and NeuroFlux Governor, are not available for sleeves.
|
||||
Certain Augmentations, like {FactionNames.Bladeburners}-specific ones and NeuroFlux Governor, are not available for sleeves.
|
||||
</Typography>
|
||||
<br />
|
||||
<br />
|
||||
@ -109,7 +110,7 @@ export function FAQModal({ open, onClose }: IProps): React.ReactElement {
|
||||
<br />
|
||||
<br />
|
||||
<Typography>
|
||||
Memory can only be increased by purchasing upgrades from The Covenant. It is a persistent stat, meaning it
|
||||
Memory can only be increased by purchasing upgrades from {FactionNames.TheCovenant}. It is a persistent stat, meaning it
|
||||
never gets resets back to 1. The maximum possible value for a sleeve's memory is 100.
|
||||
</Typography>
|
||||
</>
|
||||
|
@ -50,74 +50,62 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<>
|
||||
<Typography>
|
||||
You can purchase Augmentations for your Duplicate Sleeves. These Augmentations have the same effect as they
|
||||
would for you. You can only purchase Augmentations that you have unlocked through Factions.
|
||||
<br />
|
||||
<br />
|
||||
When purchasing an Augmentation for a Duplicate Sleeve, they are immediately installed. This means that the
|
||||
Duplicate Sleeve will immediately lose all of its stat experience.
|
||||
</Typography>
|
||||
<Table size="small" padding="none">
|
||||
<TableBody>
|
||||
{availableAugs.map((aug) => {
|
||||
return (
|
||||
<TableRow key={aug.name}>
|
||||
<TableCell>
|
||||
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money < aug.startingCost}>
|
||||
Buy
|
||||
</Button>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Box display="flex">
|
||||
<Tooltip title={aug.stats || ""}>
|
||||
<Typography>{aug.name}</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Money money={aug.startingCost} player={player} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Box sx={{ mx: 1 }}>
|
||||
<Typography>
|
||||
You can purchase Augmentations for your Duplicate Sleeves. These Augmentations have the same effect as they
|
||||
would for you. You can only purchase Augmentations that you have unlocked through Factions.
|
||||
<br />
|
||||
<br />
|
||||
When purchasing an Augmentation for a Duplicate Sleeve, they are immediately installed. This means that the
|
||||
Duplicate Sleeve will immediately lose all of its stat experience.
|
||||
</Typography>
|
||||
<Box component={Paper} sx={{ my: 1, p: 1 }}>
|
||||
<Table size="small" padding="none">
|
||||
<TableBody>
|
||||
{availableAugs.map((aug) => {
|
||||
return (
|
||||
<TableRow key={aug.name}>
|
||||
<TableCell>
|
||||
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money < aug.startingCost}>
|
||||
Buy
|
||||
</Button>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Box display="flex">
|
||||
<Tooltip title={aug.stats || ""}>
|
||||
<Typography>{aug.name}</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Money money={aug.startingCost} player={player} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{ownedAugNames.length > 0 && (
|
||||
<>
|
||||
<Typography>Owned Augmentations:</Typography>
|
||||
{ownedAugNames.map((augName) => {
|
||||
const aug = Augmentations[augName];
|
||||
let tooltip = <></>;
|
||||
if (typeof aug.info === "string") {
|
||||
tooltip = (
|
||||
<>
|
||||
<span>{aug.info}</span>
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
tooltip = (
|
||||
<>
|
||||
{aug.info}
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
</>
|
||||
);
|
||||
}
|
||||
<Typography sx={{ mx: 1 }}>Owned Augmentations:</Typography>
|
||||
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(5, 1fr)', m: 1 }}>
|
||||
{ownedAugNames.map((augName) => {
|
||||
const aug = Augmentations[augName];
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info
|
||||
const tooltip = (<>{info}<br /><br />{aug.stats}</>);
|
||||
|
||||
return (
|
||||
<Tooltip key={augName} title={<Typography>{tooltip}</Typography>}>
|
||||
<Paper>
|
||||
<Typography>{augName}</Typography>
|
||||
</Paper>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<Tooltip key={augName} title={<Typography>{tooltip}</Typography>}>
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography>{augName}</Typography>
|
||||
</Paper>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
@ -1,34 +1,29 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import {
|
||||
Box,
|
||||
Paper,
|
||||
Typography,
|
||||
Button,
|
||||
Tooltip
|
||||
} from "@mui/material";
|
||||
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { Crimes } from "../../../Crime/Crimes";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
import { use } from "../../../ui/Context";
|
||||
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
|
||||
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
|
||||
import { Crimes } from "../../../Crime/Crimes";
|
||||
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
|
||||
import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal";
|
||||
import { TravelModal } from "./TravelModal";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { MoneyRate } from "../../../ui/React/MoneyRate";
|
||||
import { use } from "../../../ui/Context";
|
||||
import { ReputationRate } from "../../../ui/React/ReputationRate";
|
||||
import { StatsElement } from "./StatsElement";
|
||||
import { StatsElement, EarningsElement } from "./StatsElement";
|
||||
import { MoreStatsModal } from "./MoreStatsModal";
|
||||
import { MoreEarningsModal } from "./MoreEarningsModal";
|
||||
import { TaskSelector } from "./TaskSelector";
|
||||
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
interface IProps {
|
||||
sleeve: Sleeve;
|
||||
@ -141,86 +136,71 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
console.error(`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${abc[0]}`);
|
||||
}
|
||||
|
||||
let data: any[][] = [];
|
||||
if (props.sleeve.currentTask === SleeveTaskType.Crime) {
|
||||
data = [
|
||||
[`Money`, <Money money={parseFloat(props.sleeve.currentTaskLocation)} />, `(on success)`],
|
||||
[`Hacking Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack), `(2x on success)`],
|
||||
[`Strength Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str), `(2x on success)`],
|
||||
[`Defense Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def), `(2x on success)`],
|
||||
[`Dexterity Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.dex), `(2x on success)`],
|
||||
[`Agility Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.agi), `(2x on success)`],
|
||||
[`Charisma Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.cha), `(2x on success)`],
|
||||
];
|
||||
} else {
|
||||
data = [
|
||||
[`Money:`, <MoneyRate money={5 * props.sleeve.gainRatesForTask.money} />],
|
||||
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.hack)} / s`],
|
||||
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.str)} / s`],
|
||||
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.def)} / s`],
|
||||
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.dex)} / s`],
|
||||
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.agi)} / s`],
|
||||
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.cha)} / s`],
|
||||
];
|
||||
if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) {
|
||||
const repGain: number = props.sleeve.getRepGain(player);
|
||||
data.push([`Reputation:`, <ReputationRate reputation={5 * repGain} />]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid container component={Paper}>
|
||||
<Grid item xs={3}>
|
||||
<StatsElement sleeve={props.sleeve} />
|
||||
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
|
||||
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
|
||||
<span>
|
||||
<Button onClick={() => setTravelOpen(true)} disabled={player.money < CONSTANTS.TravelCost}>
|
||||
Travel
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
title={props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""}
|
||||
>
|
||||
<span>
|
||||
<Button onClick={() => setAugmentationsOpen(true)} disabled={props.sleeve.shock < 100}>
|
||||
Manage Augmentations
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<TaskSelector player={player} sleeve={props.sleeve} setABC={setABC} />
|
||||
<Typography>{desc}</Typography>
|
||||
<Typography>
|
||||
{props.sleeve.currentTask === SleeveTaskType.Crime &&
|
||||
createProgressBarText({
|
||||
progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
|
||||
totalTicks: 25,
|
||||
})}
|
||||
</Typography>
|
||||
<Button onClick={setTask}>Set Task</Button>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<StatsTable title="Earnings (Pre-Synchronization)" rows={data} />
|
||||
<Button onClick={() => setEarningsOpen(true)}>More Earnings Info</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<MoreStatsModal open={statsOpen} onClose={() => setStatsOpen(false)} sleeve={props.sleeve} />
|
||||
<MoreEarningsModal open={earningsOpen} onClose={() => setEarningsOpen(false)} sleeve={props.sleeve} />
|
||||
<TravelModal
|
||||
open={travelOpen}
|
||||
onClose={() => setTravelOpen(false)}
|
||||
sleeve={props.sleeve}
|
||||
rerender={props.rerender}
|
||||
/>
|
||||
<SleeveAugmentationsModal
|
||||
open={augmentationsOpen}
|
||||
onClose={() => setAugmentationsOpen(false)}
|
||||
sleeve={props.sleeve}
|
||||
/>
|
||||
</>
|
||||
<Box component={Paper} sx={{ width: 'auto' }}>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: '100%', gap: 1 }}>
|
||||
<Box>
|
||||
<StatsElement sleeve={props.sleeve} />
|
||||
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: '100%' }}>
|
||||
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
|
||||
<Button onClick={() => setEarningsOpen(true)}>More Earnings Info</Button>
|
||||
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
|
||||
<span>
|
||||
<Button
|
||||
onClick={() => setTravelOpen(true)}
|
||||
disabled={player.money < CONSTANTS.TravelCost}
|
||||
sx={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
Travel
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
title={props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""}
|
||||
>
|
||||
<span>
|
||||
<Button
|
||||
onClick={() => setAugmentationsOpen(true)}
|
||||
disabled={props.sleeve.shock < 100}
|
||||
sx={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
Manage Augmentations
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box>
|
||||
<EarningsElement sleeve={props.sleeve} />
|
||||
<Box>
|
||||
<TaskSelector player={player} sleeve={props.sleeve} setABC={setABC} />
|
||||
<Button onClick={setTask} sx={{ width: '100%' }}>Set Task</Button>
|
||||
<Typography>{desc}</Typography>
|
||||
<Typography>
|
||||
{props.sleeve.currentTask === SleeveTaskType.Crime &&
|
||||
createProgressBarText({
|
||||
progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
|
||||
totalTicks: 25,
|
||||
})}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<MoreStatsModal open={statsOpen} onClose={() => setStatsOpen(false)} sleeve={props.sleeve} />
|
||||
<MoreEarningsModal open={earningsOpen} onClose={() => setEarningsOpen(false)} sleeve={props.sleeve} />
|
||||
<TravelModal
|
||||
open={travelOpen}
|
||||
onClose={() => setTravelOpen(false)}
|
||||
sleeve={props.sleeve}
|
||||
rerender={props.rerender}
|
||||
/>
|
||||
<SleeveAugmentationsModal
|
||||
open={augmentationsOpen}
|
||||
onClose={() => setAugmentationsOpen(false)}
|
||||
sleeve={props.sleeve}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box >
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import {
|
||||
Box,
|
||||
Typography,
|
||||
Button,
|
||||
Container
|
||||
} from "@mui/material";
|
||||
|
||||
import { use } from "../../../ui/Context";
|
||||
|
||||
import { SleeveElem } from "./SleeveElem";
|
||||
import { FAQModal } from "./FAQModal";
|
||||
import { use } from "../../../ui/Context";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import Link from "@mui/material/Link";
|
||||
|
||||
export function SleeveRoot(): React.ReactElement {
|
||||
const player = use.Player();
|
||||
@ -23,27 +27,29 @@ export function SleeveRoot(): React.ReactElement {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">Sleeves</Typography>
|
||||
<Typography>
|
||||
Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your consciousness has been copied. In
|
||||
other words, these Synthoids contain a perfect duplicate of your mind.
|
||||
<br />
|
||||
<br />
|
||||
Sleeves can be used to perform different tasks synchronously.
|
||||
<br />
|
||||
<br />
|
||||
</Typography>
|
||||
<Container disableGutters maxWidth="md" sx={{ mx: 0 }}>
|
||||
<Typography variant="h4">Sleeves</Typography>
|
||||
<Typography>
|
||||
Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your consciousness has been copied. In
|
||||
other words, these Synthoids contain a perfect duplicate of your mind.
|
||||
<br />
|
||||
<br />
|
||||
Sleeves can be used to perform different tasks synchronously.
|
||||
<br />
|
||||
<br />
|
||||
</Typography>
|
||||
|
||||
</Container>
|
||||
|
||||
<Button onClick={() => setFAQOpen(true)}>FAQ</Button>
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves"
|
||||
>
|
||||
<Typography> Documentation</Typography>
|
||||
</Link>
|
||||
{player.sleeves.map((sleeve, i) => (
|
||||
<SleeveElem key={i} rerender={rerender} sleeve={sleeve} />
|
||||
))}
|
||||
<Button href="https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves" target="_blank">
|
||||
Wiki Documentation
|
||||
</Button>
|
||||
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(2, 1fr)', mt: 1 }}>
|
||||
{player.sleeves.map((sleeve, i) => (
|
||||
<SleeveElem key={i} rerender={rerender} sleeve={sleeve} />
|
||||
))}
|
||||
</Box>
|
||||
<FAQModal open={FAQOpen} onClose={() => setFAQOpen(false)} />
|
||||
</>
|
||||
);
|
||||
|
@ -1,31 +1,110 @@
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import React from "react";
|
||||
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
import {
|
||||
Typography,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from "@mui/material";
|
||||
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { Settings } from "../../../Settings/Settings";
|
||||
import { StatsRow } from "../../../ui/React/StatsRow";
|
||||
import { characterOverviewStyles as useStyles } from "../../../ui/React/CharacterOverview";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { MoneyRate } from "../../../ui/React/MoneyRate";
|
||||
import { ReputationRate } from "../../../ui/React/ReputationRate";
|
||||
import { use } from "../../../ui/Context";
|
||||
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
|
||||
|
||||
interface IProps {
|
||||
sleeve: Sleeve;
|
||||
}
|
||||
|
||||
export function StatsElement(props: IProps): React.ReactElement {
|
||||
const rows = [
|
||||
[
|
||||
"HP: ",
|
||||
<>
|
||||
{numeralWrapper.formatHp(props.sleeve.hp)} / {numeralWrapper.formatHp(props.sleeve.max_hp)}
|
||||
</>,
|
||||
],
|
||||
["City: ", <>{props.sleeve.city}</>],
|
||||
["Hacking: ", <>{numeralWrapper.formatSkill(props.sleeve.hacking)}</>],
|
||||
["Strength: ", <>{numeralWrapper.formatSkill(props.sleeve.strength)}</>],
|
||||
["Defense: ", <>{numeralWrapper.formatSkill(props.sleeve.defense)}</>],
|
||||
["Dexterity: ", <>{numeralWrapper.formatSkill(props.sleeve.dexterity)}</>],
|
||||
["Agility: ", <>{numeralWrapper.formatSkill(props.sleeve.agility)}</>],
|
||||
["Charisma: ", <>{numeralWrapper.formatSkill(props.sleeve.charisma)}</>],
|
||||
["Shock: ", <>{numeralWrapper.formatSleeveShock(100 - props.sleeve.shock)}</>],
|
||||
["Sync: ", <>{numeralWrapper.formatSleeveSynchro(props.sleeve.sync)}</>],
|
||||
["Memory: ", <>{numeralWrapper.formatSleeveMemory(props.sleeve.memory)}</>],
|
||||
];
|
||||
return <StatsTable rows={rows} />;
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Table sx={{ display: 'table', mb: 1, width: '100%' }}>
|
||||
<TableBody>
|
||||
<StatsRow name="City" color={Settings.theme.primary} data={{ content: props.sleeve.city }} />
|
||||
<StatsRow name="HP" color={Settings.theme.hp}
|
||||
data={{ content: `${numeralWrapper.formatHp(props.sleeve.hp)} / ${numeralWrapper.formatHp(props.sleeve.max_hp)}` }}
|
||||
/>
|
||||
<StatsRow name="Hacking" color={Settings.theme.hack} data={{ level: props.sleeve.hacking, exp: props.sleeve.hacking_exp }} />
|
||||
<StatsRow name="Strength" color={Settings.theme.combat} data={{ level: props.sleeve.strength, exp: props.sleeve.strength_exp }} />
|
||||
<StatsRow name="Defense" color={Settings.theme.combat} data={{ level: props.sleeve.defense, exp: props.sleeve.defense_exp }} />
|
||||
<StatsRow name="Dexterity" color={Settings.theme.combat} data={{ level: props.sleeve.dexterity, exp: props.sleeve.dexterity_exp }} />
|
||||
<StatsRow name="Agility" color={Settings.theme.combat} data={{ level: props.sleeve.agility, exp: props.sleeve.agility_exp }} />
|
||||
<StatsRow name="Charisma" color={Settings.theme.cha} data={{ level: props.sleeve.charisma, exp: props.sleeve.charisma_exp }} />
|
||||
<TableRow>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<br />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<StatsRow name="Shock" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveShock(100 - props.sleeve.shock) }} />
|
||||
<StatsRow name="Sync" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveSynchro(props.sleeve.sync) }} />
|
||||
<StatsRow name="Memory" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveMemory(props.sleeve.memory) }} />
|
||||
</TableBody>
|
||||
</Table>
|
||||
)
|
||||
}
|
||||
|
||||
export function EarningsElement(props: IProps): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const player = use.Player();
|
||||
|
||||
let data: any[][] = [];
|
||||
if (props.sleeve.currentTask === SleeveTaskType.Crime) {
|
||||
data = [
|
||||
[`Money`, <><Money money={parseFloat(props.sleeve.currentTaskLocation)} /> (on success)</>],
|
||||
[`Hacking Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack)} (2x on success)`],
|
||||
[`Strength Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str)} (2x on success)`],
|
||||
[`Defense Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def)} (2x on success)`],
|
||||
[`Dexterity Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.dex)} (2x on success)`],
|
||||
[`Agility Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.agi)} (2x on success)`],
|
||||
[`Charisma Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.cha)} (2x on success)`],
|
||||
];
|
||||
} else {
|
||||
data = [
|
||||
[`Money:`, <MoneyRate money={5 * props.sleeve.gainRatesForTask.money} />],
|
||||
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.hack)} / sec`],
|
||||
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.str)} / sec`],
|
||||
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.def)} / sec`],
|
||||
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.dex)} / sec`],
|
||||
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.agi)} / sec`],
|
||||
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.cha)} / sec`],
|
||||
];
|
||||
if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) {
|
||||
const repGain: number = props.sleeve.getRepGain(player);
|
||||
data.push([`Reputation:`, <ReputationRate reputation={5 * repGain} />]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Table sx={{ display: 'table', mb: 1, width: '100%', lineHeight: 0 }}>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<Typography variant='h6'>
|
||||
Earnings
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{data.map(([a, b]) => (
|
||||
<TableRow key={a.toString() + b.toString()}>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<Typography>{a}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right" classes={{ root: classes.cellNone }}>
|
||||
<Typography>{b}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { Factions } from "../../../Faction/Factions";
|
||||
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import { FactionNames } from "../../../Faction/data/FactionNames";
|
||||
|
||||
const universitySelectorOptions: string[] = [
|
||||
"Study Computer Science",
|
||||
@ -55,7 +56,7 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
|
||||
|
||||
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
|
||||
// Array of all factions that other sleeves are working for
|
||||
const forbiddenFactions = ["Bladeburners"];
|
||||
const forbiddenFactions = [FactionNames.Bladeburners as string];
|
||||
if (player.gang) {
|
||||
forbiddenFactions.push(player.gang.facName);
|
||||
}
|
||||
@ -278,7 +279,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Select onChange={onS0Change} value={s0}>
|
||||
<Select onChange={onS0Change} value={s0} sx={{ width: '100%' }}>
|
||||
{validActions.map((task) => (
|
||||
<MenuItem key={task} value={task}>
|
||||
{task}
|
||||
@ -287,8 +288,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
|
||||
</Select>
|
||||
{!(details.first.length === 1 && details.first[0] === "------") && (
|
||||
<>
|
||||
<br />
|
||||
<Select onChange={onS1Change} value={s1}>
|
||||
<Select onChange={onS1Change} value={s1} sx={{ width: '100%' }}>
|
||||
{details.first.map((detail) => (
|
||||
<MenuItem key={detail} value={detail}>
|
||||
{detail}
|
||||
@ -299,8 +299,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
|
||||
)}
|
||||
{!(details2.length === 1 && details2[0] === "------") && (
|
||||
<>
|
||||
<br />
|
||||
<Select onChange={onS2Change} value={s2}>
|
||||
<Select onChange={onS2Change} value={s2} sx={{ width: '100%' }}>
|
||||
{details2.map((detail) => (
|
||||
<MenuItem key={detail} value={detail}>
|
||||
{detail}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { FactionNames } from './Faction/data/FactionNames';
|
||||
import { CityName } from './Locations/data/CityNames';
|
||||
import { Augmentations } from "./Augmentation/Augmentations";
|
||||
import { augmentationExists, initAugmentations } from "./Augmentation/AugmentationHelpers";
|
||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||
@ -160,9 +162,7 @@ export function prestigeAugmentation(): void {
|
||||
}
|
||||
|
||||
if (augmentationExists(AugmentationNames.StaneksGift1) && Augmentations[AugmentationNames.StaneksGift1].owned) {
|
||||
// TODO(hydroflame): refactor faction names so we don't have to hard
|
||||
// code strings.
|
||||
joinFaction(Factions["Church of the Machine God"]);
|
||||
joinFaction(Factions[FactionNames.ChurchOfTheMachineGod]);
|
||||
}
|
||||
|
||||
staneksGift.prestigeAugmentation();
|
||||
@ -260,7 +260,7 @@ export function prestigeSourceFile(flume: boolean): void {
|
||||
homeComp.messages.push(LiteratureNames.CorporationManagementHandbook);
|
||||
dialogBoxCreate(
|
||||
"You received a copy of the Corporation Management Handbook on your home computer. " +
|
||||
"Read it if you need help getting started with Corporations!",
|
||||
"Read it if you need help getting started with Corporations!",
|
||||
);
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ export function prestigeSourceFile(flume: boolean): void {
|
||||
}
|
||||
|
||||
if (Player.bitNodeN === 13) {
|
||||
dialogBoxCreate("Trouble is brewing in Chongqing");
|
||||
dialogBoxCreate(`Trouble is brewing in ${CityName.Chongqing}`);
|
||||
}
|
||||
|
||||
// Reset Stock market, gang, and corporation
|
||||
|
@ -11,6 +11,7 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { BitFlumeEvent } from "../../BitNode/ui/BitFlumeModal";
|
||||
import { calculateHackingTime, calculateGrowTime, calculateWeakenTime } from "../../Hacking";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
function requireHackingLevel(lvl: number) {
|
||||
return function (p: IPlayer) {
|
||||
@ -316,7 +317,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
||||
}
|
||||
|
||||
terminal.print("We will contact you.");
|
||||
terminal.print("-- Daedalus --");
|
||||
terminal.print(`-- ${FactionNames.Daedalus} --`);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
25
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
25
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -1506,6 +1506,20 @@ export interface TIX {
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchase4SMarketDataTixApi(): boolean;
|
||||
|
||||
/**
|
||||
* Purchase WSE Account.
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchaseWseAccount(): boolean;
|
||||
|
||||
/**
|
||||
* Purchase TIX API Access
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchaseTixApi(): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6651,6 +6665,17 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
|
||||
*
|
||||
*/
|
||||
sellShares(amount: number): void;
|
||||
/**
|
||||
* Get bonus time.
|
||||
*
|
||||
* “Bonus time” is accumulated when the game is offline or if the game is inactive in the browser.
|
||||
*
|
||||
* “Bonus time” makes the game progress faster.
|
||||
*
|
||||
* @returns Bonus time for the Corporation mechanic in milliseconds.
|
||||
*/
|
||||
getBonusTime(): number;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { FactionNames } from '../../Faction/data/FactionNames';
|
||||
// tslint:disable:max-file-line-count
|
||||
|
||||
// This could actually be a JSON file as it should be constant metadata to be imported...
|
||||
@ -78,7 +79,7 @@ interface IServerMetadata {
|
||||
export const serverMetadata: IServerMetadata[] = [
|
||||
{
|
||||
hackDifficulty: 99,
|
||||
hostname: "ecorp",
|
||||
hostname: LocationName.AevumECorp.toLowerCase(),
|
||||
moneyAvailable: {
|
||||
max: 70e9,
|
||||
min: 30e9,
|
||||
@ -95,7 +96,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
},
|
||||
{
|
||||
hackDifficulty: 99,
|
||||
hostname: "megacorp",
|
||||
hostname: LocationName.Sector12MegaCorp.toLowerCase(),
|
||||
moneyAvailable: {
|
||||
max: 60e9,
|
||||
min: 40e9,
|
||||
@ -163,7 +164,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
},
|
||||
{
|
||||
hackDifficulty: 99,
|
||||
hostname: "nwo",
|
||||
hostname: LocationName.VolhavenNWO.toLowerCase(),
|
||||
literature: [LiteratureNames.TheHiddenWorld],
|
||||
moneyAvailable: {
|
||||
max: 40e9,
|
||||
@ -423,7 +424,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
max: 90,
|
||||
min: 80,
|
||||
},
|
||||
hostname: "vitalife",
|
||||
hostname: LocationName.NewTokyoVitaLife.toLowerCase(),
|
||||
literature: [LiteratureNames.AGreenTomorrow],
|
||||
maxRamExponent: {
|
||||
max: 7,
|
||||
@ -601,7 +602,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
max: 90,
|
||||
min: 80,
|
||||
},
|
||||
hostname: "aerocorp",
|
||||
hostname: LocationName.AevumAeroCorp.toLowerCase(),
|
||||
literature: [LiteratureNames.ManAndMachine],
|
||||
moneyAvailable: {
|
||||
max: 1200000000,
|
||||
@ -726,7 +727,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
max: 85,
|
||||
min: 75,
|
||||
},
|
||||
hostname: "deltaone",
|
||||
hostname: LocationName.Sector12DeltaOne.toLowerCase(),
|
||||
moneyAvailable: {
|
||||
max: 1700000000,
|
||||
min: 1300000000,
|
||||
@ -1120,7 +1121,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
max: 65,
|
||||
min: 55,
|
||||
},
|
||||
hostname: "comptek",
|
||||
hostname: LocationName.VolhavenCompuTek.toLowerCase(),
|
||||
literature: [LiteratureNames.ManAndMachine],
|
||||
moneyAvailable: {
|
||||
max: 250000000,
|
||||
@ -1201,7 +1202,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
},
|
||||
{
|
||||
hackDifficulty: 10,
|
||||
hostname: "foodnstuff",
|
||||
hostname: LocationName.Sector12FoodNStuff.toLowerCase(),
|
||||
literature: [LiteratureNames.Sector12Crime],
|
||||
maxRamExponent: 4,
|
||||
moneyAvailable: 2000000,
|
||||
@ -1381,7 +1382,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
moneyAvailable: 20000000,
|
||||
networkLayer: 1,
|
||||
numOpenPortsRequired: 1,
|
||||
organizationName: "Iron Gym Network",
|
||||
organizationName: `${LocationName.Sector12IronGym} Network`,
|
||||
requiredHackingSkill: 100,
|
||||
serverGrowth: 20,
|
||||
specialName: LocationName.Sector12IronGym,
|
||||
@ -1503,7 +1504,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
moneyAvailable: 0,
|
||||
networkLayer: 4,
|
||||
numOpenPortsRequired: 2,
|
||||
organizationName: "NiteSec",
|
||||
organizationName: FactionNames.NiteSec,
|
||||
requiredHackingSkill: {
|
||||
max: 220,
|
||||
min: 202,
|
||||
@ -1534,7 +1535,7 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
moneyAvailable: 0,
|
||||
networkLayer: 2,
|
||||
numOpenPortsRequired: 1,
|
||||
organizationName: "CyberSec",
|
||||
organizationName: FactionNames.CyberSec,
|
||||
requiredHackingSkill: {
|
||||
max: 60,
|
||||
min: 51,
|
||||
|
@ -8,3 +8,11 @@ export function getStockMarket4SDataCost(): number {
|
||||
export function getStockMarket4STixApiCost(): number {
|
||||
return CONSTANTS.MarketDataTixApi4SCost * BitNodeMultipliers.FourSigmaMarketDataApiCost;
|
||||
}
|
||||
|
||||
export function getStockMarketWseCost(): number {
|
||||
return CONSTANTS.WSEAccountCost;
|
||||
}
|
||||
|
||||
export function getStockMarketTixApiCost(): number {
|
||||
return CONSTANTS.TIXAPICost;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import IconButton from "@mui/material/IconButton";
|
||||
import HelpIcon from "@mui/icons-material/Help";
|
||||
import CheckIcon from "@mui/icons-material/Check";
|
||||
import { StaticModal } from "../../ui/React/StaticModal";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
|
||||
type IProps = {
|
||||
initStockMarket: () => void;
|
||||
@ -190,10 +191,10 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
|
||||
</Typography>
|
||||
<PurchaseTixApiAccessButton {...props} />
|
||||
<Typography variant="h5" color="primary">
|
||||
Four Sigma (4S) Market Data Feed
|
||||
{FactionNames.FourSigma} (4S) Market Data Feed
|
||||
</Typography>
|
||||
<Typography>
|
||||
Four Sigma's (4S) Market Data Feed provides information about stocks that will help your trading strategies.
|
||||
{FactionNames.FourSigma}'s (4S) Market Data Feed provides information about stocks that will help your trading strategies.
|
||||
<IconButton onClick={() => setHelpOpen(true)}>
|
||||
<HelpIcon />
|
||||
</IconButton>
|
||||
|
@ -26,7 +26,7 @@ export const TerminalHelpText: string[] = [
|
||||
" hostname Displays the hostname of the machine",
|
||||
" kill [script/pid] [args...] Stops the specified script on the current server ",
|
||||
" killall Stops all running scripts on the current machine",
|
||||
" ls [dir] [| grep pattern] Displays all files on the machine",
|
||||
" ls [dir] [--grep pattern] Displays all files on the machine",
|
||||
" lscpu Displays the number of CPU cores on the machine",
|
||||
" mem [script] [-t n] Displays the amount of RAM required to run the script",
|
||||
" mv [src] [dest] Move/rename a text or script file",
|
||||
@ -295,28 +295,30 @@ export const HelpTexts: IMap<string[]> = {
|
||||
" ",
|
||||
],
|
||||
ls: [
|
||||
"Usage: ls [dir] [| grep pattern]",
|
||||
"Usage: ls [dir] [-l] [--grep pattern]",
|
||||
" ",
|
||||
"The ls command, with no arguments, prints all files and directories on the current server's directory to the Terminal screen. ",
|
||||
"The files will be displayed in alphabetical order. ",
|
||||
" ",
|
||||
"The 'dir' optional parameter can be used to display files/directories in another directory.",
|
||||
" ",
|
||||
"The '| grep pattern' optional parameter can be used to only display files whose filenames match the specified pattern.",
|
||||
"The '-l' optional parameter allows you to force each item onto a single line.",
|
||||
" ",
|
||||
"The '--grep pattern' optional parameter can be used to only display files whose filenames match the specified pattern.",
|
||||
" ",
|
||||
"Examples:",
|
||||
" ",
|
||||
"List all files with the '.script' extension in the current directory:",
|
||||
" ",
|
||||
" ls | grep .script",
|
||||
" ls -l --grep .script",
|
||||
" ",
|
||||
"List all files with the '.js' extension in the root directory:",
|
||||
" ",
|
||||
" ls / | grep .js",
|
||||
" ls / -l --grep .js",
|
||||
" ",
|
||||
"List all files with the word 'purchase' in the filename, in the 'scripts' directory:",
|
||||
" ",
|
||||
" ls scripts | grep purchase",
|
||||
" ls scripts -l --grep purchase",
|
||||
" ",
|
||||
],
|
||||
lscpu: ["Usage: lscpu", " ", "Prints the number of CPU Cores the current server has", " "],
|
||||
|
@ -8,6 +8,7 @@ import { BaseServer } from "../../Server/BaseServer";
|
||||
import { evaluateDirectoryPath, getFirstParentDirectory, isValidDirectoryPath } from "../DirectoryHelpers";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { ITerminal } from "../ITerminal";
|
||||
import * as libarg from "arg"
|
||||
|
||||
export function ls(
|
||||
terminal: ITerminal,
|
||||
@ -16,44 +17,46 @@ export function ls(
|
||||
server: BaseServer,
|
||||
args: (string | number | boolean)[],
|
||||
): void {
|
||||
let flags;
|
||||
try {
|
||||
flags = libarg({
|
||||
'-l': Boolean,
|
||||
'--grep': String,
|
||||
'-g': '--grep',
|
||||
},
|
||||
{ argv: args }
|
||||
)
|
||||
} catch (e) {
|
||||
// catch passing only -g / --grep with no string to use as the search
|
||||
incorrectUsage()
|
||||
return;
|
||||
}
|
||||
const filter = flags['--grep']
|
||||
|
||||
const numArgs = args.length;
|
||||
function incorrectUsage(): void {
|
||||
terminal.error("Incorrect usage of ls command. Usage: ls [dir] [| grep pattern]");
|
||||
terminal.error("Incorrect usage of ls command. Usage: ls [dir] [-l] [-g, --grep pattern]");
|
||||
}
|
||||
|
||||
if (numArgs > 4 || numArgs === 2) {
|
||||
if (numArgs > 4) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
|
||||
// Grep
|
||||
let filter = ""; // Grep
|
||||
|
||||
// Directory path
|
||||
let prefix = terminal.cwd();
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
|
||||
// If there are 3+ arguments, then the last 3 must be for grep
|
||||
if (numArgs >= 3) {
|
||||
if (args[numArgs - 2] !== "grep" || args[numArgs - 3] !== "|") {
|
||||
return incorrectUsage();
|
||||
}
|
||||
filter = args[numArgs - 1] + "";
|
||||
// If first arg doesn't contain a - it must be the file/folder
|
||||
const dir = (args[0] && typeof args[0] == "string" && !args[0].startsWith("-")) ? args[0] : ""
|
||||
const newPath = evaluateDirectoryPath(dir + "", terminal.cwd());
|
||||
prefix = newPath || "";
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
|
||||
// If the second argument is not a pipe, then it must be for listing a directory
|
||||
if (numArgs >= 1 && args[0] !== "|") {
|
||||
const newPath = evaluateDirectoryPath(args[0] + "", terminal.cwd());
|
||||
prefix = newPath ? newPath : "";
|
||||
if (prefix != null) {
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix += "/";
|
||||
}
|
||||
if (!isValidDirectoryPath(prefix)) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
}
|
||||
if (!isValidDirectoryPath(prefix)) {
|
||||
return incorrectUsage();
|
||||
}
|
||||
|
||||
// Root directory, which is the same as no 'prefix' at all
|
||||
@ -139,10 +142,9 @@ export function ls(
|
||||
}),
|
||||
)();
|
||||
|
||||
const rowSplit = row
|
||||
.split(" ")
|
||||
.map((x) => x.trim())
|
||||
.filter((x) => !!x);
|
||||
const rowSplit = row.split("~");
|
||||
let rowSplitArray = rowSplit.map((x) => [x.trim(), x.replace(x.trim(), "")]);
|
||||
rowSplitArray = rowSplitArray.filter((x) => !!x[0]);
|
||||
|
||||
function onScriptLinkClick(filename: string): void {
|
||||
if (player.getCurrentServer().hostname !== hostname) {
|
||||
@ -156,34 +158,42 @@ export function ls(
|
||||
|
||||
return (
|
||||
<span className={classes.scriptLinksWrap}>
|
||||
{rowSplit.map((rowItem) => (
|
||||
<span key={rowItem} className={classes.scriptLink} onClick={() => onScriptLinkClick(rowItem)}>
|
||||
{rowItem}
|
||||
{rowSplitArray.map((rowItem) => (
|
||||
<span>
|
||||
<span key={rowItem[0]} className={classes.scriptLink} onClick={() => onScriptLinkClick(rowItem[0])}>
|
||||
{rowItem[0]}
|
||||
</span>
|
||||
<span key={'s'+rowItem[0]}>
|
||||
{rowItem[1]}
|
||||
</span>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function postSegments(segments: string[], style?: any, linked?: boolean): void {
|
||||
function postSegments(segments: string[], flags: any, style?: any, linked?: boolean): void {
|
||||
const maxLength = Math.max(...segments.map((s) => s.length)) + 1;
|
||||
const filesPerRow = Math.ceil(80 / maxLength);
|
||||
const filesPerRow = flags["-l"] === true ? 1 : Math.ceil(80 / maxLength);
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
let row = "";
|
||||
for (let col = 0; col < filesPerRow; col++) {
|
||||
if (!(i < segments.length)) break;
|
||||
row += segments[i];
|
||||
row += " ".repeat(maxLength * (col + 1) - row.length);
|
||||
if(linked) {
|
||||
row += "~";
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
if (!style) {
|
||||
terminal.print(row);
|
||||
} else if (linked) {
|
||||
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
||||
} else {
|
||||
terminal.printRaw(<span style={style}>{row}</span>);
|
||||
}
|
||||
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
||||
} else {
|
||||
terminal.printRaw(<span style={style}>{row}</span>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,6 +206,6 @@ export function ls(
|
||||
{ segments: allScripts, style: { color: "yellow", fontStyle: "bold" }, linked: true },
|
||||
].filter((g) => g.segments.length > 0);
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
postSegments(groups[i].segments, groups[i].style, groups[i].linked);
|
||||
postSegments(groups[i].segments, flags, groups[i].style, groups[i].linked);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,9 @@ export function PromptManager(): React.ReactElement {
|
||||
|
||||
return (
|
||||
<Modal open={true} onClose={close}>
|
||||
<Typography>{prompt.txt}</Typography>
|
||||
<pre>
|
||||
<Typography>{prompt.txt}</Typography>
|
||||
</pre>
|
||||
<PromptContent prompt={prompt} resolve={resolve} />
|
||||
</Modal>
|
||||
);
|
||||
|
49
src/ui/React/StatsRow.tsx
Normal file
49
src/ui/React/StatsRow.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
Typography,
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from "@mui/material";
|
||||
|
||||
import { numeralWrapper } from "../numeralFormat";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { characterOverviewStyles as useStyles } from "./CharacterOverview";
|
||||
|
||||
interface ITableRowData {
|
||||
content?: string;
|
||||
level?: number;
|
||||
exp?: number;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
name: string;
|
||||
color: string;
|
||||
classes?: any;
|
||||
data: ITableRowData;
|
||||
}
|
||||
|
||||
export const StatsRow = ({ name, color, classes = useStyles(), data }: IProps): React.ReactElement => {
|
||||
let content;
|
||||
|
||||
if (data.content !== undefined) {
|
||||
content = data.content;
|
||||
} else if (data.level !== undefined && data.exp !== undefined) {
|
||||
content = `${formatNumber(data.level, 0)} (${numeralWrapper.formatExp(data.exp)} exp)`;
|
||||
} else if (data.level !== undefined && data.exp === undefined) {
|
||||
content = `${formatNumber(data.level, 0)}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell classes={{ root: classes.cellNone }}>
|
||||
<Typography style={{ color: color }}>{name}</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right" classes={{ root: classes.cellNone }}>
|
||||
<Typography style={{ color: color }}>
|
||||
{content}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
}
|
@ -37,23 +37,12 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
|
||||
if (player.workType == CONSTANTS.WorkTypeFaction) {
|
||||
const faction = Factions[player.currentWorkFactionName];
|
||||
if (!faction) {
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
<Typography>
|
||||
Something has gone wrong, you cannot work for {player.currentWorkFactionName || "(Faction not found)"} at
|
||||
this time.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
if (!faction) {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" color="primary">
|
||||
You have not joined {faction} yet!
|
||||
You have not joined {player.currentWorkFactionName || "(Faction not found)"} yet or cannot work at this time,
|
||||
please try again if you think this should have worked
|
||||
</Typography>
|
||||
<Button onClick={() => router.toFactions()}>Back to Factions</Button>
|
||||
</>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { CityName } from './../../../src/Locations/data/CityNames';
|
||||
/* eslint-disable no-await-in-loop */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { jest, describe, expect, test } from "@jest/globals";
|
||||
@ -37,7 +38,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
hackDifficulty: 1,
|
||||
moneyAvailable: 70000,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: LocationName.Aevum,
|
||||
organizationName: CityName.Aevum,
|
||||
requiredHackingSkill: 1,
|
||||
serverGrowth: 3000,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user