mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 20:25:45 +01:00
WIP: Crimes streamlining. (#138)
* streamline crimes * Crimes object is now indexed by CrimeType enum instead of an entirely new set of keys that aren't used for anything else. This eliminated a lot of instances of iterating to find the right crime for a given CrimeType. * Removed unused `None` CrimeType which allowed typing Crimes as a Record<CrimeType, Crime>. * Added slums tooltip text as a crime property, to allow streamlining slums. * Refactor slums location - removed repetitive code, rerenders 1/sec to update chances * Fix bugged descriptive text when sleeve is committing a crime (was "is attempting to DRUGS", now uses correct text e.g. "to deal drugs"). * Remove unused and now unneeded NewCrimeType enum. Values were identical to existing CrimeType values after removing unused None. * Add CrimeType enum in NetscriptDefinition.d.ts * Also update broken ToastVariant type. Better support for enums in player scripts. * Still todo is modifying some NS functions to expect CrimeType as input (rough crime names will continue to work to avoid breaking scripts) * Expect enum use for crime functions Affected functions: * ns.singularity.commitCrime * ns.singularity.getCrimeChance * ns.singularity.getCrimeStats * ns.sleeve.setToCommitCrime * formulas.work.crimeGains (param type only) - Affected functions still will fall back to rough names, except formulas.work.crimeGains which already only accepted the enum members. - Some documentation changes: * examples updated to use uppercase expected form. * Note on sleeve.setToCommitCrime that it only accepts exact matches removed. It already, and still does, accept any rough crime name (but the enum is expected input). * note about needing to use isBusy to schedule crimes remove - crimes autoloop now. * Since expected string inputs are documented directly on the type, removed list of crimes from sleeve.setToCommitCrimes
This commit is contained in:
parent
06a985bdf8
commit
d74c380e42
@ -25,22 +25,25 @@ interface IConstructorParams {
|
||||
|
||||
export class Crime {
|
||||
// Number representing the difficulty of the crime. Used for success chance calculations
|
||||
difficulty = 0;
|
||||
difficulty: number;
|
||||
|
||||
// Amount of karma lost for SUCCESSFULLY committing this crime
|
||||
karma = 0;
|
||||
karma: number;
|
||||
|
||||
// How many people die as a result of this crime
|
||||
kills = 0;
|
||||
kills: number;
|
||||
|
||||
// How much money is given by the
|
||||
money = 0;
|
||||
money: number;
|
||||
|
||||
// Name of crime
|
||||
name = "";
|
||||
name: string;
|
||||
|
||||
// Name of crime as it appears on work screen: "You are attempting..."
|
||||
workName = "";
|
||||
workName: string;
|
||||
|
||||
// Tooltip text in slums ui
|
||||
tooltipText: string;
|
||||
|
||||
// Milliseconds it takes to attempt the crime
|
||||
time = 0;
|
||||
@ -66,17 +69,19 @@ export class Crime {
|
||||
intelligence_exp = 0;
|
||||
|
||||
constructor(
|
||||
name = "",
|
||||
workName = "",
|
||||
name: string,
|
||||
workName: string,
|
||||
tooltipText: string,
|
||||
type: CrimeType,
|
||||
time = 0,
|
||||
money = 0,
|
||||
difficulty = 0,
|
||||
karma = 0,
|
||||
params: IConstructorParams = {},
|
||||
time: number,
|
||||
money: number,
|
||||
difficulty: number,
|
||||
karma: number,
|
||||
params: IConstructorParams,
|
||||
) {
|
||||
this.name = name;
|
||||
this.workName = workName;
|
||||
this.tooltipText = tooltipText;
|
||||
this.type = type;
|
||||
this.time = time;
|
||||
this.money = money;
|
||||
|
@ -3,53 +3,46 @@ import { Crime } from "./Crime";
|
||||
import { Player } from "@player";
|
||||
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
//This is only used for the player
|
||||
export function determineCrimeSuccess(type: string): boolean {
|
||||
let chance = 0;
|
||||
let found = false;
|
||||
for (const i of Object.keys(Crimes)) {
|
||||
const crime = Crimes[i];
|
||||
if (crime.type === type) {
|
||||
chance = crime.successRate(Player);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!checkEnum(CrimeType, type)) {
|
||||
dialogBoxCreate(`ERR: Unrecognized crime type: ${type} This is probably a bug please contact the developer`);
|
||||
return false;
|
||||
}
|
||||
const crime = Crimes[type];
|
||||
const chance = crime.successRate(Player);
|
||||
return Math.random() <= chance;
|
||||
}
|
||||
|
||||
export function findCrime(roughName: string): Crime | null {
|
||||
roughName = roughName.toLowerCase();
|
||||
if (roughName.includes("shoplift")) {
|
||||
return Crimes.Shoplift;
|
||||
return Crimes[CrimeType.SHOPLIFT];
|
||||
} else if (roughName.includes("rob") && roughName.includes("store")) {
|
||||
return Crimes.RobStore;
|
||||
return Crimes[CrimeType.ROB_STORE];
|
||||
} else if (roughName.includes("mug")) {
|
||||
return Crimes.Mug;
|
||||
return Crimes[CrimeType.MUG];
|
||||
} else if (roughName.includes("larceny")) {
|
||||
return Crimes.Larceny;
|
||||
return Crimes[CrimeType.LARCENY];
|
||||
} else if (roughName.includes("drugs")) {
|
||||
return Crimes.DealDrugs;
|
||||
return Crimes[CrimeType.DRUGS];
|
||||
} else if (roughName.includes("bond") && roughName.includes("forge")) {
|
||||
return Crimes.BondForgery;
|
||||
return Crimes[CrimeType.BOND_FORGERY];
|
||||
} else if ((roughName.includes("traffic") || roughName.includes("illegal")) && roughName.includes("arms")) {
|
||||
return Crimes.TraffickArms;
|
||||
return Crimes[CrimeType.TRAFFIC_ARMS];
|
||||
} else if (roughName.includes("homicide")) {
|
||||
return Crimes.Homicide;
|
||||
return Crimes[CrimeType.HOMICIDE];
|
||||
} else if (roughName.includes("grand") && roughName.includes("auto")) {
|
||||
return Crimes.GrandTheftAuto;
|
||||
return Crimes[CrimeType.GRAND_THEFT_AUTO];
|
||||
} else if (roughName.includes("kidnap")) {
|
||||
return Crimes.Kidnap;
|
||||
return Crimes[CrimeType.KIDNAP];
|
||||
} else if (roughName.includes("assassin")) {
|
||||
return Crimes.Assassination;
|
||||
return Crimes[CrimeType.ASSASSINATION];
|
||||
} else if (roughName.includes("heist")) {
|
||||
return Crimes.Heist;
|
||||
return Crimes[CrimeType.HEIST];
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -3,162 +3,282 @@ import { Crime } from "./Crime";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
// TODO: What is the point of CrimeType using totally different strings than
|
||||
export const Crimes: Record<CrimeType, Crime> = {
|
||||
[CrimeType.SHOPLIFT]: new Crime(
|
||||
"Shoplift",
|
||||
"to shoplift",
|
||||
"Attempt to shoplift from a low-end retailer",
|
||||
CrimeType.SHOPLIFT,
|
||||
2e3,
|
||||
15e3,
|
||||
1 / 20,
|
||||
0.1,
|
||||
{
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
export const Crimes: Record<string, Crime> = {
|
||||
Shoplift: new Crime("Shoplift", "to shoplift", CrimeType.SHOPLIFT, 2e3, 15e3, 1 / 20, 0.1, {
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
},
|
||||
),
|
||||
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
}),
|
||||
[CrimeType.ROB_STORE]: new Crime(
|
||||
"Rob Store",
|
||||
"to rob a store",
|
||||
"Attempt to commit armed robbery on a high-end store",
|
||||
CrimeType.ROB_STORE,
|
||||
60e3,
|
||||
400e3,
|
||||
1 / 5,
|
||||
0.5,
|
||||
{
|
||||
hacking_exp: 30,
|
||||
dexterity_exp: 45,
|
||||
agility_exp: 45,
|
||||
|
||||
RobStore: new Crime("Rob Store", "to rob a store", CrimeType.ROB_STORE, 60e3, 400e3, 1 / 5, 0.5, {
|
||||
hacking_exp: 30,
|
||||
dexterity_exp: 45,
|
||||
agility_exp: 45,
|
||||
hacking_success_weight: 0.5,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
hacking_success_weight: 0.5,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
intelligence_exp: 7.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
|
||||
intelligence_exp: 7.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
[CrimeType.MUG]: new Crime(
|
||||
"Mug",
|
||||
"to mug",
|
||||
"Attempt to mug a random person on the street",
|
||||
CrimeType.MUG,
|
||||
4e3,
|
||||
36e3,
|
||||
1 / 5,
|
||||
0.25,
|
||||
{
|
||||
strength_exp: 3,
|
||||
defense_exp: 3,
|
||||
dexterity_exp: 3,
|
||||
agility_exp: 3,
|
||||
|
||||
Mug: new Crime("Mug", "to mug", CrimeType.MUG, 4e3, 36e3, 1 / 5, 0.25, {
|
||||
strength_exp: 3,
|
||||
defense_exp: 3,
|
||||
dexterity_exp: 3,
|
||||
agility_exp: 3,
|
||||
strength_success_weight: 1.5,
|
||||
defense_success_weight: 0.5,
|
||||
dexterity_success_weight: 1.5,
|
||||
agility_success_weight: 0.5,
|
||||
},
|
||||
),
|
||||
|
||||
strength_success_weight: 1.5,
|
||||
defense_success_weight: 0.5,
|
||||
dexterity_success_weight: 1.5,
|
||||
agility_success_weight: 0.5,
|
||||
}),
|
||||
[CrimeType.LARCENY]: new Crime(
|
||||
"Larceny",
|
||||
"larceny",
|
||||
"Attempt to rob property from someone's house",
|
||||
CrimeType.LARCENY,
|
||||
90e3,
|
||||
800e3,
|
||||
1 / 3,
|
||||
1.5,
|
||||
{
|
||||
hacking_exp: 45,
|
||||
dexterity_exp: 60,
|
||||
agility_exp: 60,
|
||||
|
||||
Larceny: new Crime("Larceny", "larceny", CrimeType.LARCENY, 90e3, 800e3, 1 / 3, 1.5, {
|
||||
hacking_exp: 45,
|
||||
dexterity_exp: 60,
|
||||
agility_exp: 60,
|
||||
hacking_success_weight: 0.5,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
hacking_success_weight: 0.5,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
intelligence_exp: 15 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
|
||||
intelligence_exp: 15 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
[CrimeType.DRUGS]: new Crime(
|
||||
"Deal Drugs",
|
||||
"to deal drugs",
|
||||
"Attempt to deal drugs",
|
||||
CrimeType.DRUGS,
|
||||
10e3,
|
||||
120e3,
|
||||
1,
|
||||
0.5,
|
||||
{
|
||||
dexterity_exp: 5,
|
||||
agility_exp: 5,
|
||||
charisma_exp: 10,
|
||||
|
||||
DealDrugs: new Crime("Deal Drugs", "to deal drugs", CrimeType.DRUGS, 10e3, 120e3, 1, 0.5, {
|
||||
dexterity_exp: 5,
|
||||
agility_exp: 5,
|
||||
charisma_exp: 10,
|
||||
charisma_success_weight: 3,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
},
|
||||
),
|
||||
|
||||
charisma_success_weight: 3,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
[CrimeType.BOND_FORGERY]: new Crime(
|
||||
"Bond Forgery",
|
||||
"to forge bonds",
|
||||
"Attempt to forge corporate bonds",
|
||||
CrimeType.BOND_FORGERY,
|
||||
300e3,
|
||||
4.5e6,
|
||||
1 / 2,
|
||||
0.1,
|
||||
{
|
||||
hacking_exp: 100,
|
||||
dexterity_exp: 150,
|
||||
charisma_exp: 15,
|
||||
|
||||
BondForgery: new Crime("Bond Forgery", "to forge bonds", CrimeType.BOND_FORGERY, 300e3, 4.5e6, 1 / 2, 0.1, {
|
||||
hacking_exp: 100,
|
||||
dexterity_exp: 150,
|
||||
charisma_exp: 15,
|
||||
hacking_success_weight: 0.05,
|
||||
dexterity_success_weight: 1.25,
|
||||
|
||||
hacking_success_weight: 0.05,
|
||||
dexterity_success_weight: 1.25,
|
||||
intelligence_exp: 60 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
|
||||
intelligence_exp: 60 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
[CrimeType.TRAFFIC_ARMS]: new Crime(
|
||||
"Traffick Arms",
|
||||
"to traffic arms",
|
||||
"Attempt to smuggle illegal arms into the city",
|
||||
CrimeType.TRAFFIC_ARMS,
|
||||
40e3,
|
||||
600e3,
|
||||
2,
|
||||
1,
|
||||
{
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 20,
|
||||
charisma_exp: 40,
|
||||
|
||||
TraffickArms: new Crime("Traffick Arms", "to traffic arms", CrimeType.TRAFFIC_ARMS, 40e3, 600e3, 2, 1, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 20,
|
||||
charisma_exp: 40,
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
},
|
||||
),
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
[CrimeType.HOMICIDE]: new Crime(
|
||||
"Homicide",
|
||||
"homicide",
|
||||
"Attempt to murder a random person on the street",
|
||||
CrimeType.HOMICIDE,
|
||||
3e3,
|
||||
45e3,
|
||||
1,
|
||||
3,
|
||||
{
|
||||
strength_exp: 2,
|
||||
defense_exp: 2,
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
|
||||
Homicide: new Crime("Homicide", "homicide", CrimeType.HOMICIDE, 3e3, 45e3, 1, 3, {
|
||||
strength_exp: 2,
|
||||
defense_exp: 2,
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
strength_success_weight: 2,
|
||||
defense_success_weight: 2,
|
||||
dexterity_success_weight: 0.5,
|
||||
agility_success_weight: 0.5,
|
||||
|
||||
strength_success_weight: 2,
|
||||
defense_success_weight: 2,
|
||||
dexterity_success_weight: 0.5,
|
||||
agility_success_weight: 0.5,
|
||||
kills: 1,
|
||||
},
|
||||
),
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
[CrimeType.GRAND_THEFT_AUTO]: new Crime(
|
||||
"Grand Theft Auto",
|
||||
"grand theft auto",
|
||||
"Attempt to commit grand theft auto",
|
||||
CrimeType.GRAND_THEFT_AUTO,
|
||||
80e3,
|
||||
1.6e6,
|
||||
8,
|
||||
5,
|
||||
{
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 40,
|
||||
|
||||
GrandTheftAuto: new Crime("Grand Theft Auto", "grand theft auto", CrimeType.GRAND_THEFT_AUTO, 80e3, 1.6e6, 8, 5, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 40,
|
||||
hacking_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 4,
|
||||
agility_success_weight: 2,
|
||||
charisma_success_weight: 2,
|
||||
|
||||
hacking_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 4,
|
||||
agility_success_weight: 2,
|
||||
charisma_success_weight: 2,
|
||||
intelligence_exp: 16 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
|
||||
intelligence_exp: 16 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
[CrimeType.KIDNAP]: new Crime(
|
||||
"Kidnap",
|
||||
"to kidnap",
|
||||
"Attempt to kidnap and ransom a high-profile-target",
|
||||
CrimeType.KIDNAP,
|
||||
120e3,
|
||||
3.6e6,
|
||||
5,
|
||||
6,
|
||||
{
|
||||
strength_exp: 80,
|
||||
defense_exp: 80,
|
||||
dexterity_exp: 80,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 80,
|
||||
|
||||
Kidnap: new Crime("Kidnap", "to kidnap", CrimeType.KIDNAP, 120e3, 3.6e6, 5, 6, {
|
||||
strength_exp: 80,
|
||||
defense_exp: 80,
|
||||
dexterity_exp: 80,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 80,
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
intelligence_exp: 26 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
|
||||
intelligence_exp: 26 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
[CrimeType.ASSASSINATION]: new Crime(
|
||||
"Assassination",
|
||||
"to assassinate",
|
||||
"Attempt to assassinate a high-profile target",
|
||||
CrimeType.ASSASSINATION,
|
||||
300e3,
|
||||
12e6,
|
||||
8,
|
||||
10,
|
||||
{
|
||||
strength_exp: 300,
|
||||
defense_exp: 300,
|
||||
dexterity_exp: 300,
|
||||
agility_exp: 300,
|
||||
|
||||
Assassination: new Crime("Assassination", "to assassinate", CrimeType.ASSASSINATION, 300e3, 12e6, 8, 10, {
|
||||
strength_exp: 300,
|
||||
defense_exp: 300,
|
||||
dexterity_exp: 300,
|
||||
agility_exp: 300,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
intelligence_exp: 65 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
|
||||
intelligence_exp: 65 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
kills: 1,
|
||||
},
|
||||
),
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
[CrimeType.HEIST]: new Crime(
|
||||
"Heist",
|
||||
"a heist",
|
||||
"Attempt to pull off the ultimate heist",
|
||||
CrimeType.HEIST,
|
||||
600e3,
|
||||
120e6,
|
||||
18,
|
||||
15,
|
||||
{
|
||||
hacking_exp: 450,
|
||||
strength_exp: 450,
|
||||
defense_exp: 450,
|
||||
dexterity_exp: 450,
|
||||
agility_exp: 450,
|
||||
charisma_exp: 450,
|
||||
|
||||
Heist: new Crime("Heist", "a heist", CrimeType.HEIST, 600e3, 120e6, 18, 15, {
|
||||
hacking_exp: 450,
|
||||
strength_exp: 450,
|
||||
defense_exp: 450,
|
||||
dexterity_exp: 450,
|
||||
agility_exp: 450,
|
||||
charisma_exp: 450,
|
||||
hacking_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
charisma_success_weight: 1,
|
||||
|
||||
hacking_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
charisma_success_weight: 1,
|
||||
|
||||
intelligence_exp: 130 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
intelligence_exp: 130 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This subcomponent renders all of the buttons for committing crimes
|
||||
*/
|
||||
import * as React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
@ -13,185 +13,33 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "@player";
|
||||
import { Box } from "@mui/material";
|
||||
import { Crime } from "../../Crime/Crime";
|
||||
|
||||
export function SlumsLocation(): React.ReactElement {
|
||||
function shoplift(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Shoplift.commit();
|
||||
const setRerender = useState(false)[1];
|
||||
const rerender = () => setRerender((o) => !o);
|
||||
const crimes = Object.values(Crimes);
|
||||
useEffect(() => {
|
||||
const timerId = setInterval(() => rerender(), 1000);
|
||||
return () => clearInterval(timerId);
|
||||
});
|
||||
|
||||
function doCrime(e: React.MouseEvent<HTMLElement>, crime: Crime) {
|
||||
if (!e.isTrusted) return;
|
||||
crime.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function robStore(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.RobStore.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function mug(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Mug.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function larceny(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Larceny.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function dealDrugs(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.DealDrugs.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function bondForgery(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.BondForgery.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function traffickArms(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.TraffickArms.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function homicide(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Homicide.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function grandTheftAuto(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.GrandTheftAuto.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function kidnap(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Kidnap.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function assassinate(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Assassination.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function heist(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Heist.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
const shopliftChance = Crimes.Shoplift.successRate(Player);
|
||||
const robStoreChance = Crimes.RobStore.successRate(Player);
|
||||
const mugChance = Crimes.Mug.successRate(Player);
|
||||
const larcenyChance = Crimes.Larceny.successRate(Player);
|
||||
const drugsChance = Crimes.DealDrugs.successRate(Player);
|
||||
const bondChance = Crimes.BondForgery.successRate(Player);
|
||||
const armsChance = Crimes.TraffickArms.successRate(Player);
|
||||
const homicideChance = Crimes.Homicide.successRate(Player);
|
||||
const gtaChance = Crimes.GrandTheftAuto.successRate(Player);
|
||||
const kidnapChance = Crimes.Kidnap.successRate(Player);
|
||||
const assassinateChance = Crimes.Assassination.successRate(Player);
|
||||
const heistChance = Crimes.Heist.successRate(Player);
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "grid", width: "fit-content" }}>
|
||||
<Tooltip title={<>Attempt to shoplift from a low-end retailer</>}>
|
||||
<Button onClick={shoplift}>
|
||||
Shoplift ({numeralWrapper.formatPercentage(shopliftChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to commit armed robbery on a high-end store</>}>
|
||||
<Button onClick={robStore}>
|
||||
Rob store ({numeralWrapper.formatPercentage(robStoreChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to mug a random person on the street</>}>
|
||||
<Button onClick={mug}>Mug someone ({numeralWrapper.formatPercentage(mugChance)} chance of success)</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to rob property from someone's house</>}>
|
||||
<Button onClick={larceny}>Larceny ({numeralWrapper.formatPercentage(larcenyChance)} chance of success)</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to deal drugs</>}>
|
||||
<Button onClick={dealDrugs}>
|
||||
Deal Drugs ({numeralWrapper.formatPercentage(drugsChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to forge corporate bonds</>}>
|
||||
<Button onClick={bondForgery}>
|
||||
Bond Forgery ({numeralWrapper.formatPercentage(bondChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to smuggle illegal arms into the city</>}>
|
||||
<Button onClick={traffickArms}>
|
||||
Traffick illegal Arms ({numeralWrapper.formatPercentage(armsChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to murder a random person on the street</>}>
|
||||
<Button onClick={homicide}>
|
||||
Homicide ({numeralWrapper.formatPercentage(homicideChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to commit grand theft auto</>}>
|
||||
<Button onClick={grandTheftAuto}>
|
||||
Grand theft Auto ({numeralWrapper.formatPercentage(gtaChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to kidnap and ransom a high-profile-target</>}>
|
||||
<Button onClick={kidnap}>
|
||||
Kidnap and Ransom ({numeralWrapper.formatPercentage(kidnapChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to assassinate a high-profile target</>}>
|
||||
<Button onClick={assassinate}>
|
||||
Assassinate ({numeralWrapper.formatPercentage(assassinateChance)} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={<>Attempt to pull off the ultimate heist</>}>
|
||||
<Button onClick={heist}>Heist ({numeralWrapper.formatPercentage(heistChance)} chance of success)</Button>
|
||||
</Tooltip>
|
||||
{crimes.map((crime) => (
|
||||
<Tooltip title={crime.tooltipText}>
|
||||
<Button onClick={(e) => doCrime(e, crime)}>
|
||||
{crime.name} ({numeralWrapper.formatPercentage(crime.successRate(Player))} chance of success)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -77,11 +77,12 @@ import { INetscriptExtra } from "./NetscriptFunctions/Extra";
|
||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||
import { getBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { assert, arrayAssert, stringAssert, objectAssert } from "./utils/helpers/typeAssertion";
|
||||
import { CrimeType } from "./utils/WorkType";
|
||||
|
||||
// "Enums" as object
|
||||
export const enums = {
|
||||
toast: ToastVariant,
|
||||
} as const;
|
||||
crimes: CrimeType,
|
||||
};
|
||||
export type NSFull = Readonly<NS & INetscriptExtra>;
|
||||
|
||||
export function NetscriptFunctions(workerScript: WorkerScript): NSFull {
|
||||
@ -125,6 +126,7 @@ const base: InternalAPI<NS> = {
|
||||
(ctx) =>
|
||||
(_hostname, opts = {}) => {
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
// Todo: better type safety rework for functions using assertObjectType, then remove function.
|
||||
const optsValidator: BasicHGWOptions = {};
|
||||
assertObjectType(ctx, "opts", opts, optsValidator);
|
||||
return helpers.hack(ctx, hostname, false, { threads: opts.threads, stock: opts.stock });
|
||||
|
@ -48,6 +48,8 @@ import { calculateFactionExp, calculateFactionRep } from "../Work/formulas/Facti
|
||||
import { FactionWorkType } from "../Work/data/FactionWorkType";
|
||||
|
||||
import { defaultMultipliers } from "../PersonObjects/Multipliers";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
const checkFormulasAccess = function (ctx: NetscriptContext): void {
|
||||
@ -362,9 +364,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
work: {
|
||||
crimeGains: (ctx) => (_crimeType) => {
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
const crime = Object.values(Crimes).find((c) => String(c.type) === crimeType);
|
||||
if (!crime) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(crime);
|
||||
if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(Crimes[crimeType]);
|
||||
},
|
||||
classGains: (ctx) => (_person, _classType, _locationName) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
|
@ -50,6 +50,9 @@ import { CompanyWork } from "../Work/CompanyWork";
|
||||
import { canGetBonus, onExport } from "../ExportBonus";
|
||||
import { saveObject } from "../SaveObject";
|
||||
import { calculateCrimeWorkStats } from "../Work/formulas/Crime";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
const getAugmentation = function (ctx: NetscriptContext, name: string): Augmentation {
|
||||
@ -1115,56 +1118,47 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
helpers.log(ctx, () => `Began creating program: '${programName}'`);
|
||||
return true;
|
||||
},
|
||||
commitCrime:
|
||||
(ctx) =>
|
||||
(_crimeRoughName, _focus = true) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
const focus = !!_focus;
|
||||
const wasFocusing = Player.focus;
|
||||
|
||||
if (Player.currentWork !== null) {
|
||||
Player.finishWork(true);
|
||||
}
|
||||
|
||||
// Set Location to slums
|
||||
Player.gotoLocation(LocationName.Slums);
|
||||
|
||||
const crime = findCrime(crimeRoughName.toLowerCase());
|
||||
if (crime == null) {
|
||||
// couldn't find crime
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeRoughName}'`);
|
||||
}
|
||||
helpers.log(ctx, () => `Attempting to commit ${crime.name}...`);
|
||||
const crimeTime = crime.commit(1, ctx.workerScript);
|
||||
if (focus) {
|
||||
Player.startFocusing();
|
||||
Router.toWork();
|
||||
} else if (wasFocusing) {
|
||||
Player.stopFocusing();
|
||||
Router.toTerminal();
|
||||
}
|
||||
return crimeTime;
|
||||
},
|
||||
getCrimeChance: (ctx) => (_crimeRoughName) => {
|
||||
commitCrime: (ctx) => (_crimeType, _focus) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
const focus = _focus === undefined ? true : !!_focus;
|
||||
const wasFocusing = Player.focus;
|
||||
|
||||
const crime = findCrime(crimeRoughName.toLowerCase());
|
||||
if (crime == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: ${crimeRoughName}`);
|
||||
if (Player.currentWork !== null) Player.finishWork(true);
|
||||
Player.gotoLocation(LocationName.Slums);
|
||||
|
||||
// If input isn't a crimeType, use search using roughname.
|
||||
const crime = checkEnum(CrimeType, crimeType) ? Crimes[crimeType] : findCrime(crimeType);
|
||||
if (crime == null) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeType}'`);
|
||||
|
||||
helpers.log(ctx, () => `Attempting to commit ${crime.name}...`);
|
||||
const crimeTime = crime.commit(1, ctx.workerScript);
|
||||
if (focus) {
|
||||
Player.startFocusing();
|
||||
Router.toWork();
|
||||
} else if (wasFocusing) {
|
||||
Player.stopFocusing();
|
||||
Router.toTerminal();
|
||||
}
|
||||
return crimeTime;
|
||||
},
|
||||
getCrimeChance: (ctx) => (_crimeType) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
|
||||
// If input isn't a crimeType, use search using roughname.
|
||||
const crime = checkEnum(CrimeType, crimeType) ? Crimes[crimeType] : findCrime(crimeType);
|
||||
if (crime == null) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeType}'`);
|
||||
|
||||
return crime.successRate(Player);
|
||||
},
|
||||
getCrimeStats: (ctx) => (_crimeRoughName) => {
|
||||
getCrimeStats: (ctx) => (_crimeType) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
|
||||
const crime = findCrime(crimeRoughName.toLowerCase());
|
||||
if (crime == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: ${crimeRoughName}`);
|
||||
}
|
||||
// If input isn't a crimeType, use search using roughname.
|
||||
const crime = checkEnum(CrimeType, crimeType) ? Crimes[crimeType] : findCrime(crimeType);
|
||||
if (crime == null) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeType}'`);
|
||||
|
||||
const crimeStatsWithMultipliers = calculateCrimeWorkStats(crime);
|
||||
|
||||
|
@ -11,6 +11,8 @@ import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBlad
|
||||
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
|
||||
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
|
||||
@ -62,15 +64,13 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].synchronize();
|
||||
},
|
||||
setToCommitCrime: (ctx) => (_sleeveNumber, _crimeRoughName) => {
|
||||
setToCommitCrime: (ctx) => (_sleeveNumber, _crimeType) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
const crime = findCrime(crimeRoughName);
|
||||
if (crime === null) {
|
||||
return false;
|
||||
}
|
||||
const crime = checkEnum(CrimeType, crimeType) ? Crimes[crimeType] : findCrime(crimeType);
|
||||
if (crime == null) return false;
|
||||
return Player.sleeves[sleeveNumber].commitCrime(crime.name);
|
||||
},
|
||||
setToUniversityCourse: (ctx) => (_sleeveNumber, _universityName, _className) => {
|
||||
|
@ -12,21 +12,18 @@ import { Person } from "../Person";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
|
||||
import { Crime } from "../../Crime/Crime";
|
||||
import { Crimes } from "../../Crime/Crimes";
|
||||
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { Company } from "../../Company/Company";
|
||||
import { CompanyPosition } from "../../Company/CompanyPosition";
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
|
||||
import { Contracts } from "../../Bladeburner/data/Contracts";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { checkEnum } from "../../utils/helpers/checkEnum";
|
||||
import { CrimeType } from "../../utils/WorkType";
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
import { LocationName } from "../../Locations/data/LocationNames";
|
||||
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../../utils/JSONReviver";
|
||||
@ -97,13 +94,9 @@ export class Sleeve extends Person {
|
||||
}
|
||||
|
||||
/** Commit crimes */
|
||||
commitCrime(crimeKey: string): boolean {
|
||||
const crime: Crime | null = Crimes[crimeKey] || Object.values(Crimes).find((crime) => crime.name === crimeKey);
|
||||
if (!crime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.startWork(new SleeveCrimeWork(crime.type));
|
||||
commitCrime(type: string): boolean {
|
||||
if (!checkEnum(CrimeType, type)) return false;
|
||||
this.startWork(new SleeveCrimeWork(type));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import { Crime } from "../../../Crime/Crime";
|
||||
import { newWorkStats, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { BitNodeMultipliers } from "../../../BitNode/BitNodeMultipliers";
|
||||
import { checkEnum } from "../../../utils/helpers/checkEnum";
|
||||
|
||||
export const isSleeveCrimeWork = (w: Work | null): w is SleeveCrimeWork => w !== null && w.type === WorkType.CRIME;
|
||||
|
||||
@ -20,9 +21,8 @@ export class SleeveCrimeWork extends Work {
|
||||
}
|
||||
|
||||
getCrime(): Crime {
|
||||
const crime = Object.values(Crimes).find((crime) => crime.type === this.crimeType);
|
||||
if (!crime) throw new Error("crime should not be undefined");
|
||||
return crime;
|
||||
if (!checkEnum(CrimeType, this.crimeType)) throw new Error("crime should not be undefined");
|
||||
return Crimes[this.crimeType];
|
||||
}
|
||||
|
||||
getExp(sleeve: Sleeve): WorkStats {
|
||||
|
@ -74,7 +74,7 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
const crime = w.getCrime();
|
||||
desc = (
|
||||
<>
|
||||
This sleeve is currently attempting to {crime.type} (Success Rate:{" "}
|
||||
This sleeve is currently attempting {crime.workName} (Success Rate:{" "}
|
||||
{numeralWrapper.formatPercentage(crime.successRate(props.sleeve))}).
|
||||
</>
|
||||
);
|
||||
|
@ -19,6 +19,8 @@ import { isSleeveSupportWork } from "../Work/SleeveSupportWork";
|
||||
import { ClassType } from "../../../Work/ClassWork";
|
||||
import { isSleeveCrimeWork } from "../Work/SleeveCrimeWork";
|
||||
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
|
||||
import { checkEnum } from "../../../utils/helpers/checkEnum";
|
||||
import { CrimeType } from "../../../utils/WorkType";
|
||||
|
||||
const universitySelectorOptions: string[] = [
|
||||
"Study Computer Science",
|
||||
@ -314,11 +316,7 @@ function getABC(sleeve: Sleeve): [string, string, string] {
|
||||
}
|
||||
}
|
||||
if (isSleeveCrimeWork(w)) {
|
||||
return [
|
||||
"Commit Crime",
|
||||
Object.values(Crimes).find((crime) => crime.type === w.crimeType)?.name ?? "Shoplift",
|
||||
"------",
|
||||
];
|
||||
return ["Commit Crime", checkEnum(CrimeType, w.crimeType) ? Crimes[w.crimeType].name : "Shoplift", "------"];
|
||||
}
|
||||
if (isSleeveSupportWork(w)) {
|
||||
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
|
||||
|
94
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
94
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -1,6 +1,3 @@
|
||||
/** @public */
|
||||
export type ValuesFrom<T> = T[keyof T];
|
||||
|
||||
/** @public */
|
||||
export interface HP {
|
||||
current: number;
|
||||
@ -1979,19 +1976,13 @@ export interface Singularity {
|
||||
*
|
||||
* This function returns the number of milliseconds it takes to attempt the
|
||||
* specified crime (e.g It takes 60 seconds to attempt the ‘Rob Store’ crime,
|
||||
* so running `commitCrime('rob store')` will return 60,000).
|
||||
*
|
||||
* Warning: I do not recommend using the time returned from this function to try
|
||||
* and schedule your crime attempts. Instead, I would use the isBusy Singularity
|
||||
* function to check whether you have finished attempting a crime. This is because
|
||||
* although the game sets a certain crime to be X amount of seconds, there is no
|
||||
* guarantee that your browser will follow that time limit.
|
||||
* so running `commitCrime('ROBSTORE')` will return 60,000).
|
||||
*
|
||||
* @param crime - Name of crime to attempt.
|
||||
* @param focus - Acquire player focus on this crime. Optional. Defaults to true.
|
||||
* @returns The number of milliseconds it takes to attempt the specified crime.
|
||||
*/
|
||||
commitCrime(crime: string, focus?: boolean): number;
|
||||
commitCrime(crime: CrimeType | CrimeNames, focus?: boolean): number;
|
||||
|
||||
/**
|
||||
* Get chance to successfully commit a crime.
|
||||
@ -2004,7 +1995,7 @@ export interface Singularity {
|
||||
* @param crime - Name of crime.
|
||||
* @returns Chance of success at committing the specified crime.
|
||||
*/
|
||||
getCrimeChance(crime: string): number;
|
||||
getCrimeChance(crime: CrimeType | CrimeNames): number;
|
||||
|
||||
/**
|
||||
* Get stats related to a crime.
|
||||
@ -2014,10 +2005,10 @@ export interface Singularity {
|
||||
*
|
||||
* Returns the stats of the crime.
|
||||
*
|
||||
* @param crime - Name of crime. Not case-sensitive
|
||||
* @param crime - Name of crime.
|
||||
* @returns The stats of the crime.
|
||||
*/
|
||||
getCrimeStats(crime: string): CrimeStats;
|
||||
getCrimeStats(crime: CrimeType | CrimeNames): CrimeStats;
|
||||
|
||||
/**
|
||||
* Get a list of owned augmentation.
|
||||
@ -2037,6 +2028,7 @@ export interface Singularity {
|
||||
* @remarks
|
||||
* RAM cost: 5 GB
|
||||
*
|
||||
*
|
||||
* Returns an array of source files
|
||||
*
|
||||
* @returns Array containing an object with number and level of the source file.
|
||||
@ -3651,32 +3643,13 @@ export interface Sleeve {
|
||||
* @remarks
|
||||
* RAM cost: 4 GB
|
||||
*
|
||||
* Return a boolean indicating whether or not this action was set successfully.
|
||||
*
|
||||
* Returns false if an invalid action is specified.
|
||||
*
|
||||
* You can set a sleeve to commit one of the following crimes. The crime names are not
|
||||
* case sensitive. For example, you can pass in the crime name as `"Shoplift"`,
|
||||
* `"shoplift"`, `"shopLift"`, or even `"SHOPLIFT"`.
|
||||
*
|
||||
* - Assassination
|
||||
* - Bond forgery
|
||||
* - Deal drugs
|
||||
* - Grand theft auto
|
||||
* - Heist
|
||||
* - Homicide
|
||||
* - Kidnap
|
||||
* - Larceny
|
||||
* - Mug
|
||||
* - Rob store
|
||||
* - Shoplift
|
||||
* - Traffick arms
|
||||
* Return a boolean indicating whether or not this action was set successfully (false if an invalid action is specified).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // NS1
|
||||
* // Assign the first 3 sleeves to commit various crimes.
|
||||
* var crime = ["mug", "rob store", "shoplift"];
|
||||
* var crime = ["MUG", "ROBSTORE", "SHOPLIFT"];
|
||||
* for (var i = 0; i < crime.length; i++) {
|
||||
* tprintf("Sleeve %d commits crime: %s", i, crime[i]);
|
||||
* sleeve.setToCommitCrime(i, crime[i]);
|
||||
@ -3686,7 +3659,7 @@ export interface Sleeve {
|
||||
* ```ts
|
||||
* // NS2
|
||||
* // Assign the first 3 sleeves to commit various crimes.
|
||||
* const crime = ["mug", "rob store", "shoplift"];
|
||||
* const crime = ["MUG", "ROBSTORE", "SHOPLIFT"];
|
||||
* for (let i = 0; i < crime.length; i++) {
|
||||
* ns.tprintf("Sleeve %d commits crime: %s", i, crime[i]);
|
||||
* ns.sleeve.setToCommitCrime(i, crime[i]);
|
||||
@ -3694,10 +3667,10 @@ export interface Sleeve {
|
||||
* ```
|
||||
*
|
||||
* @param sleeveNumber - Index of the sleeve to start committing crime. Sleeves are numbered starting from 0.
|
||||
* @param name - Name of the crime. Must be an exact match. Refer to the list of crimes.
|
||||
* @param name - Name of the crime.
|
||||
* @returns True if this action was set successfully, false otherwise.
|
||||
*/
|
||||
setToCommitCrime(sleeveNumber: number, name: string): boolean;
|
||||
setToCommitCrime(sleeveNumber: number, crimeType: CrimeType | CrimeNames): boolean;
|
||||
|
||||
/**
|
||||
* Set a sleeve to work for a faction.
|
||||
@ -3935,7 +3908,7 @@ export interface WorkStats {
|
||||
* @public
|
||||
*/
|
||||
interface WorkFormulas {
|
||||
crimeGains(crimeType: string): WorkStats;
|
||||
crimeGains(crimeType: CrimeType | CrimeNames): WorkStats;
|
||||
classGains(player: Player, classType: string, locationName: string): WorkStats;
|
||||
factionGains(player: Player, workType: string, favor: number): WorkStats;
|
||||
}
|
||||
@ -6700,7 +6673,7 @@ export interface NS {
|
||||
* @param variant - Type of toast, must be one of success, info, warning, error. Defaults to success.
|
||||
* @param duration - Duration of toast in ms. Can also be `null` to create a persistent toast. Defaults to 2000
|
||||
*/
|
||||
toast(msg: string, variant?: ToastVariant, duration?: number | null): void;
|
||||
toast(msg: string, variant?: ToastTypes | ToastVariant, duration?: number | null): void;
|
||||
|
||||
/**
|
||||
* Download a file from the internet.
|
||||
@ -6899,21 +6872,38 @@ export interface NS {
|
||||
enums: NSEnums;
|
||||
}
|
||||
|
||||
declare enum ToastVariant {
|
||||
SUCCESS = "success",
|
||||
WARNING = "warning",
|
||||
ERROR = "error",
|
||||
INFO = "info",
|
||||
}
|
||||
/** @public */
|
||||
declare const enums = {
|
||||
toast: {
|
||||
SUCCESS: "success",
|
||||
WARNING: "warning",
|
||||
ERROR: "error",
|
||||
INFO: "info",
|
||||
},
|
||||
export type ToastTypes = `${ToastVariant}`;
|
||||
|
||||
declare enum CrimeType {
|
||||
SHOPLIFT = "SHOPLIFT",
|
||||
ROB_STORE = "ROBSTORE",
|
||||
MUG = "MUG",
|
||||
LARCENY = "LARCENY",
|
||||
DRUGS = "DRUGS",
|
||||
BOND_FORGERY = "BONDFORGERY",
|
||||
TRAFFIC_ARMS = "TRAFFICKARMS",
|
||||
HOMICIDE = "HOMICIDE",
|
||||
GRAND_THEFT_AUTO = "GRANDTHEFTAUTO",
|
||||
KIDNAP = "KIDNAP",
|
||||
ASSASSINATION = "ASSASSINATION",
|
||||
HEIST = "HEIST",
|
||||
}
|
||||
/** @public */
|
||||
type CrimeNames = `${CrimeType}`;
|
||||
|
||||
/** @public */
|
||||
export type NSEnums = {
|
||||
toast: typeof ToastVariant;
|
||||
crimes: typeof CrimeType;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
type ToastVariant = ValuesFrom<typeof enums.toast>;
|
||||
|
||||
/** @public */
|
||||
export type NSEnums = typeof enums;
|
||||
/**
|
||||
* Corporation Office API
|
||||
* @remarks
|
||||
|
@ -9,51 +9,7 @@ import { CrimeType } from "../utils/WorkType";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { scaleWorkStats, WorkStats } from "./WorkStats";
|
||||
import { calculateCrimeWorkStats } from "./formulas/Crime";
|
||||
|
||||
enum newCrimeType {
|
||||
SHOPLIFT = "SHOPLIFT",
|
||||
ROBSTORE = "ROBSTORE",
|
||||
MUG = "MUG",
|
||||
LARCENY = "LARCENY",
|
||||
DRUGS = "DRUGS",
|
||||
BONDFORGERY = "BONDFORGERY",
|
||||
TRAFFICKARMS = "TRAFFICKARMS",
|
||||
HOMICIDE = "HOMICIDE",
|
||||
GRANDTHEFTAUTO = "GRANDTHEFTAUTO",
|
||||
KIDNAP = "KIDNAP",
|
||||
ASSASSINATION = "ASSASSINATION",
|
||||
HEIST = "HEIST",
|
||||
}
|
||||
|
||||
const convertCrimeType = (crimeType: CrimeType): newCrimeType => {
|
||||
switch (crimeType) {
|
||||
case CrimeType.SHOPLIFT:
|
||||
return newCrimeType.SHOPLIFT;
|
||||
case CrimeType.ROB_STORE:
|
||||
return newCrimeType.ROBSTORE;
|
||||
case CrimeType.MUG:
|
||||
return newCrimeType.MUG;
|
||||
case CrimeType.LARCENY:
|
||||
return newCrimeType.LARCENY;
|
||||
case CrimeType.DRUGS:
|
||||
return newCrimeType.DRUGS;
|
||||
case CrimeType.BOND_FORGERY:
|
||||
return newCrimeType.BONDFORGERY;
|
||||
case CrimeType.TRAFFIC_ARMS:
|
||||
return newCrimeType.TRAFFICKARMS;
|
||||
case CrimeType.HOMICIDE:
|
||||
return newCrimeType.HOMICIDE;
|
||||
case CrimeType.GRAND_THEFT_AUTO:
|
||||
return newCrimeType.GRANDTHEFTAUTO;
|
||||
case CrimeType.KIDNAP:
|
||||
return newCrimeType.KIDNAP;
|
||||
case CrimeType.ASSASSINATION:
|
||||
return newCrimeType.ASSASSINATION;
|
||||
case CrimeType.HEIST:
|
||||
return newCrimeType.HEIST;
|
||||
}
|
||||
return newCrimeType.SHOPLIFT;
|
||||
};
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
|
||||
interface CrimeWorkParams {
|
||||
crimeType: CrimeType;
|
||||
@ -73,9 +29,10 @@ export class CrimeWork extends Work {
|
||||
}
|
||||
|
||||
getCrime(): Crime {
|
||||
const crime = Object.values(Crimes).find((c) => c.type === this.crimeType);
|
||||
if (!crime) throw new Error("CrimeWork object constructed with invalid crime type");
|
||||
return crime;
|
||||
if (!checkEnum(CrimeType, this.crimeType)) {
|
||||
throw new Error("CrimeWork object constructed with invalid crime type");
|
||||
}
|
||||
return Crimes[this.crimeType];
|
||||
}
|
||||
|
||||
process(cycles = 1): boolean {
|
||||
@ -132,7 +89,7 @@ export class CrimeWork extends Work {
|
||||
return {
|
||||
type: this.type,
|
||||
cyclesWorked: this.cyclesWorked,
|
||||
crimeType: convertCrimeType(this.crimeType),
|
||||
crimeType: checkEnum(CrimeType, this.crimeType) ? this.crimeType : CrimeType.SHOPLIFT,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
export enum CrimeType {
|
||||
None = "",
|
||||
SHOPLIFT = "SHOPLIFT", //"shoplift",
|
||||
ROB_STORE = "ROBSTORE", //"rob a store",
|
||||
MUG = "MUG", //"mug someone",
|
||||
|
Loading…
Reference in New Issue
Block a user