mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-04 22:59:42 +02:00
MISC: Remove fuzzy matching when checking params (#2091)
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
||||
BladeburnerActionType,
|
||||
BladeburnerGeneralActionName,
|
||||
AugmentationName,
|
||||
SpecialBladeburnerActionTypeForSleeve,
|
||||
} from "@enums";
|
||||
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
@@ -286,22 +287,22 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
}
|
||||
|
||||
/** Take a course at a university */
|
||||
takeUniversityCourse(universityName: string, className: string): boolean {
|
||||
takeUniversityCourse(universityName: string, className: UniversityClassType): boolean {
|
||||
// Set exp/money multipliers based on which university.
|
||||
// Also check that the sleeve is in the right city
|
||||
let loc: LocationName | undefined;
|
||||
switch (universityName.toLowerCase()) {
|
||||
case LocationName.AevumSummitUniversity.toLowerCase(): {
|
||||
switch (universityName) {
|
||||
case LocationName.AevumSummitUniversity: {
|
||||
if (this.city !== CityName.Aevum) return false;
|
||||
loc = LocationName.AevumSummitUniversity;
|
||||
break;
|
||||
}
|
||||
case LocationName.Sector12RothmanUniversity.toLowerCase(): {
|
||||
case LocationName.Sector12RothmanUniversity: {
|
||||
if (this.city !== CityName.Sector12) return false;
|
||||
loc = LocationName.Sector12RothmanUniversity;
|
||||
break;
|
||||
}
|
||||
case LocationName.VolhavenZBInstituteOfTechnology.toLowerCase(): {
|
||||
case LocationName.VolhavenZBInstituteOfTechnology: {
|
||||
if (this.city !== CityName.Volhaven) return false;
|
||||
loc = LocationName.VolhavenZBInstituteOfTechnology;
|
||||
break;
|
||||
@@ -311,25 +312,23 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
|
||||
// Set experience/money gains based on class
|
||||
let classType: ClassType | undefined;
|
||||
// TODO: why lower case??? It's not effecient, not typesafe and in general a bad idea
|
||||
switch (className.toLowerCase()) {
|
||||
case "study computer science": // deprecated, leave it here for backwards compatibility
|
||||
case ClassType.computerScience.toLowerCase():
|
||||
switch (className) {
|
||||
case ClassType.computerScience:
|
||||
classType = UniversityClassType.computerScience;
|
||||
break;
|
||||
case ClassType.dataStructures.toLowerCase():
|
||||
case ClassType.dataStructures:
|
||||
classType = UniversityClassType.dataStructures;
|
||||
break;
|
||||
case ClassType.networks.toLowerCase():
|
||||
case ClassType.networks:
|
||||
classType = UniversityClassType.networks;
|
||||
break;
|
||||
case ClassType.algorithms.toLowerCase():
|
||||
case ClassType.algorithms:
|
||||
classType = UniversityClassType.algorithms;
|
||||
break;
|
||||
case ClassType.management.toLowerCase():
|
||||
case ClassType.management:
|
||||
classType = UniversityClassType.management;
|
||||
break;
|
||||
case ClassType.leadership.toLowerCase():
|
||||
case ClassType.leadership:
|
||||
classType = UniversityClassType.leadership;
|
||||
break;
|
||||
}
|
||||
@@ -376,17 +375,8 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** TODO 2.4: Make this take in type correct data */
|
||||
workForFaction(factionName: FactionName, _workType: string): boolean {
|
||||
const workTypeConversion: Record<string, string> = {
|
||||
"Hacking Contracts": "hacking",
|
||||
"Field Work": "field",
|
||||
"Security Work": "security",
|
||||
};
|
||||
if (workTypeConversion[_workType]) _workType = workTypeConversion[_workType];
|
||||
workForFaction(factionName: FactionName, workType: FactionWorkType): boolean {
|
||||
const faction = Factions[factionName];
|
||||
const workType = getEnumHelper("FactionWorkType").getMember(_workType, { fuzzy: true });
|
||||
if (!workType) return false;
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
switch (workType) {
|
||||
@@ -412,62 +402,41 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
}
|
||||
|
||||
/** Begin a gym workout task */
|
||||
workoutAtGym(gymName: string, stat: string): boolean {
|
||||
// Set exp/money multipliers based on which university.
|
||||
// Also check that the sleeve is in the right city
|
||||
workoutAtGym(gymName: string, stat: GymType): boolean {
|
||||
// Check that the sleeve is in the right city
|
||||
let loc: LocationName | undefined;
|
||||
switch (gymName.toLowerCase()) {
|
||||
case LocationName.AevumCrushFitnessGym.toLowerCase(): {
|
||||
if (this.city != CityName.Aevum) return false;
|
||||
switch (gymName) {
|
||||
case LocationName.AevumCrushFitnessGym: {
|
||||
if (this.city !== CityName.Aevum) return false;
|
||||
loc = LocationName.AevumCrushFitnessGym;
|
||||
break;
|
||||
}
|
||||
case LocationName.AevumSnapFitnessGym.toLowerCase(): {
|
||||
if (this.city != CityName.Aevum) return false;
|
||||
case LocationName.AevumSnapFitnessGym: {
|
||||
if (this.city !== CityName.Aevum) return false;
|
||||
loc = LocationName.AevumSnapFitnessGym;
|
||||
break;
|
||||
}
|
||||
case LocationName.Sector12IronGym.toLowerCase(): {
|
||||
if (this.city != CityName.Sector12) return false;
|
||||
case LocationName.Sector12IronGym: {
|
||||
if (this.city !== CityName.Sector12) return false;
|
||||
loc = LocationName.Sector12IronGym;
|
||||
break;
|
||||
}
|
||||
case LocationName.Sector12PowerhouseGym.toLowerCase(): {
|
||||
if (this.city != CityName.Sector12) return false;
|
||||
case LocationName.Sector12PowerhouseGym: {
|
||||
if (this.city !== CityName.Sector12) return false;
|
||||
loc = LocationName.Sector12PowerhouseGym;
|
||||
break;
|
||||
}
|
||||
case LocationName.VolhavenMilleniumFitnessGym.toLowerCase(): {
|
||||
if (this.city != CityName.Volhaven) return false;
|
||||
case LocationName.VolhavenMilleniumFitnessGym: {
|
||||
if (this.city !== CityName.Volhaven) return false;
|
||||
loc = LocationName.VolhavenMilleniumFitnessGym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!loc) return false;
|
||||
|
||||
// Set experience/money gains based on class
|
||||
const sanitizedStat: string = stat.toLowerCase();
|
||||
|
||||
// set stat to a default value.
|
||||
let classType: ClassType | undefined;
|
||||
if (sanitizedStat.includes("str")) {
|
||||
classType = GymType.strength;
|
||||
}
|
||||
if (sanitizedStat.includes("def")) {
|
||||
classType = GymType.defense;
|
||||
}
|
||||
if (sanitizedStat.includes("dex")) {
|
||||
classType = GymType.dexterity;
|
||||
}
|
||||
if (sanitizedStat.includes("agi")) {
|
||||
classType = GymType.agility;
|
||||
}
|
||||
// if stat is still equals its default value, then validation has failed.
|
||||
if (!classType) return false;
|
||||
|
||||
this.startWork(
|
||||
new SleeveClassWork({
|
||||
classType: classType,
|
||||
classType: stat,
|
||||
location: loc,
|
||||
}),
|
||||
);
|
||||
@@ -479,50 +448,48 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
bladeburner(action: string, contract?: string): boolean {
|
||||
if (!Player.bladeburner) return false;
|
||||
switch (action) {
|
||||
case "Training":
|
||||
case BladeburnerGeneralActionName.Training:
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({
|
||||
actionId: { type: BladeburnerActionType.General, name: BladeburnerGeneralActionName.Training },
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
case "Field analysis":
|
||||
case "Field Analysis":
|
||||
case BladeburnerGeneralActionName.FieldAnalysis:
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({
|
||||
actionId: { type: BladeburnerActionType.General, name: BladeburnerGeneralActionName.FieldAnalysis },
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
case "Recruitment":
|
||||
case BladeburnerGeneralActionName.Recruitment:
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({
|
||||
actionId: { type: BladeburnerActionType.General, name: BladeburnerGeneralActionName.Recruitment },
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
case "Diplomacy":
|
||||
case BladeburnerGeneralActionName.Diplomacy:
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({
|
||||
actionId: { type: BladeburnerActionType.General, name: BladeburnerGeneralActionName.Diplomacy },
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
case "Hyperbolic Regeneration Chamber":
|
||||
case BladeburnerGeneralActionName.HyperbolicRegen:
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({
|
||||
actionId: { type: BladeburnerActionType.General, name: BladeburnerGeneralActionName.HyperbolicRegen },
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
case "Infiltrate synthoids":
|
||||
case "Infiltrate Synthoids":
|
||||
case SpecialBladeburnerActionTypeForSleeve.InfiltrateSynthoids:
|
||||
this.startWork(new SleeveInfiltrateWork());
|
||||
return true;
|
||||
case "Support main sleeve":
|
||||
case SpecialBladeburnerActionTypeForSleeve.SupportMainSleeve:
|
||||
this.startWork(new SleeveSupportWork());
|
||||
return true;
|
||||
case "Take on contracts":
|
||||
case SpecialBladeburnerActionTypeForSleeve.TakeOnContracts:
|
||||
if (!getEnumHelper("BladeburnerContractName").isMember(contract)) return false;
|
||||
this.startWork(
|
||||
new SleeveBladeburnerWork({ actionId: { type: BladeburnerActionType.Contract, name: contract } }),
|
||||
|
||||
@@ -8,7 +8,6 @@ import { Crime } from "../../../Crime/Crime";
|
||||
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { calculateCrimeWorkStats } from "../../../Work/Formulas";
|
||||
import { findCrime } from "../../../Crime/CrimeHelpers";
|
||||
|
||||
export const isSleeveCrimeWork = (w: SleeveWorkClass | null): w is SleeveCrimeWork =>
|
||||
w !== null && w.type === SleeveWorkType.CRIME;
|
||||
@@ -68,10 +67,12 @@ export class SleeveCrimeWork extends SleeveWorkClass {
|
||||
return Generic_toJSON("SleeveCrimeWork", this);
|
||||
}
|
||||
|
||||
/** Initializes a RecoveryWork object from a JSON save state. */
|
||||
/** Initializes an object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): SleeveCrimeWork {
|
||||
const crimeWork = Generic_fromJSON(SleeveCrimeWork, value.data);
|
||||
crimeWork.crimeType = findCrime(crimeWork.crimeType)?.type ?? CrimeType.shoplift;
|
||||
if (!(crimeWork.crimeType in Crimes)) {
|
||||
crimeWork.crimeType = CrimeType.shoplift;
|
||||
}
|
||||
return crimeWork;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Button, Paper, Tooltip, Typography } from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { BladeburnerActionType, CrimeType, FactionWorkType, GymType } from "@enums";
|
||||
import { BladeburnerActionType, FactionWorkType, GymType, SpecialBladeburnerActionTypeForSleeve } from "@enums";
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { Player } from "@player";
|
||||
import { formatPercent, formatInt } from "../../../ui/formatNumber";
|
||||
@@ -11,9 +11,22 @@ import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal";
|
||||
import { EarningsElement, StatsElement } from "./StatsElement";
|
||||
import { TaskSelector } from "./TaskSelector";
|
||||
import { TravelModal } from "./TravelModal";
|
||||
import { findCrime } from "../../../Crime/CrimeHelpers";
|
||||
import { type SleeveWork, SleeveWorkType } from "../Work/Work";
|
||||
import { getEnumHelper } from "../../../utils/EnumHelper";
|
||||
import { getRecordEntries } from "../../../Types/Record";
|
||||
|
||||
const factionWorkTypeDescriptions = {
|
||||
[FactionWorkType.field]: "Field Work",
|
||||
[FactionWorkType.hacking]: "Hacking Contracts",
|
||||
[FactionWorkType.security]: "Security Work",
|
||||
};
|
||||
|
||||
const gymTypeDescriptions: Record<GymType, string> = {
|
||||
[GymType.strength]: "Train Strength",
|
||||
[GymType.defense]: "Train Defense",
|
||||
[GymType.dexterity]: "Train Dexterity",
|
||||
[GymType.agility]: "Train Agility",
|
||||
};
|
||||
|
||||
function getWorkDescription(sleeve: Sleeve, progress: number): string {
|
||||
const work = sleeve.currentWork;
|
||||
@@ -57,14 +70,9 @@ function getWorkDescription(sleeve: Sleeve, progress: number): string {
|
||||
);
|
||||
}
|
||||
case SleeveWorkType.FACTION: {
|
||||
// This isn't the way this should be handled...
|
||||
const workNames = {
|
||||
[FactionWorkType.field]: "Field Work",
|
||||
[FactionWorkType.hacking]: "Hacking Contracts",
|
||||
[FactionWorkType.security]: "Security Work",
|
||||
};
|
||||
const doing = workNames[work.factionWorkType] ?? "nothing";
|
||||
return `This sleeve is currently doing ${doing} for ${work.factionName}.`;
|
||||
return `This sleeve is currently doing ${factionWorkTypeDescriptions[work.factionWorkType]} for ${
|
||||
work.factionName
|
||||
}.`;
|
||||
}
|
||||
case SleeveWorkType.INFILTRATE:
|
||||
return (
|
||||
@@ -82,36 +90,29 @@ function calculateABC(work: SleeveWork | null): [string, string, string] {
|
||||
case SleeveWorkType.COMPANY:
|
||||
return ["Work for Company", work.companyName, "------"];
|
||||
case SleeveWorkType.FACTION: {
|
||||
const workNames = {
|
||||
[FactionWorkType.field]: "Field Work",
|
||||
[FactionWorkType.hacking]: "Hacking Contracts",
|
||||
[FactionWorkType.security]: "Security Work",
|
||||
};
|
||||
return ["Work for Faction", work.factionName, workNames[work.factionWorkType] ?? ""];
|
||||
return ["Work for Faction", work.factionName, factionWorkTypeDescriptions[work.factionWorkType]];
|
||||
}
|
||||
case SleeveWorkType.BLADEBURNER:
|
||||
if (work.actionId.type === BladeburnerActionType.Contract) {
|
||||
return ["Perform Bladeburner Actions", "Take on contracts", work.actionId.name];
|
||||
return [
|
||||
"Perform Bladeburner Actions",
|
||||
SpecialBladeburnerActionTypeForSleeve.TakeOnContracts,
|
||||
work.actionId.name,
|
||||
];
|
||||
}
|
||||
return ["Perform Bladeburner Actions", work.actionId.name, "------"];
|
||||
case SleeveWorkType.CLASS: {
|
||||
if (!work.isGym()) {
|
||||
return ["Take University Course", work.classType, work.location];
|
||||
}
|
||||
const gymNames: Record<GymType, string> = {
|
||||
[GymType.strength]: "Train Strength",
|
||||
[GymType.defense]: "Train Defense",
|
||||
[GymType.dexterity]: "Train Dexterity",
|
||||
[GymType.agility]: "Train Agility",
|
||||
};
|
||||
return ["Workout at Gym", gymNames[work.classType as GymType], work.location];
|
||||
return ["Workout at Gym", gymTypeDescriptions[work.classType as GymType], work.location];
|
||||
}
|
||||
case SleeveWorkType.CRIME:
|
||||
return ["Commit Crime", getEnumHelper("CrimeType").getMember(work.crimeType, { alwaysMatch: true }), "------"];
|
||||
case SleeveWorkType.SUPPORT:
|
||||
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
|
||||
return ["Perform Bladeburner Actions", SpecialBladeburnerActionTypeForSleeve.SupportMainSleeve, "------"];
|
||||
case SleeveWorkType.INFILTRATE:
|
||||
return ["Perform Bladeburner Actions", "Infiltrate Synthoids", "------"];
|
||||
return ["Perform Bladeburner Actions", SpecialBladeburnerActionTypeForSleeve.InfiltrateSynthoids, "------"];
|
||||
case SleeveWorkType.RECOVERY:
|
||||
return ["Shock Recovery", "------", "------"];
|
||||
case SleeveWorkType.SYNCHRO:
|
||||
@@ -148,21 +149,41 @@ export function SleeveElem(props: SleeveElemProps): React.ReactElement {
|
||||
props.sleeve.stopWork();
|
||||
break;
|
||||
case "Work for Company":
|
||||
if (getEnumHelper("CompanyName").isMember(abc[1])) props.sleeve.workForCompany(abc[1]);
|
||||
else console.error(`Invalid company name in setSleeveTask: ${abc[1]}`);
|
||||
if (getEnumHelper("CompanyName").isMember(abc[1])) {
|
||||
props.sleeve.workForCompany(abc[1]);
|
||||
} else {
|
||||
console.error(`Invalid company name in setSleeveTask: ${abc[1]}`);
|
||||
}
|
||||
break;
|
||||
case "Work for Faction":
|
||||
if (getEnumHelper("FactionName").isMember(abc[1])) props.sleeve.workForFaction(abc[1], abc[2]);
|
||||
else console.error(`Invalid faction name in setSleeveTask: ${abc[1]}`);
|
||||
if (getEnumHelper("FactionName").isMember(abc[1])) {
|
||||
for (const [factionWorkType, description] of getRecordEntries(factionWorkTypeDescriptions)) {
|
||||
if (description === abc[2]) {
|
||||
props.sleeve.workForFaction(abc[1], factionWorkType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error(`Invalid faction name in setSleeveTask: ${abc[1]}`);
|
||||
}
|
||||
break;
|
||||
case "Commit Crime":
|
||||
props.sleeve.commitCrime(findCrime(abc[1])?.type ?? CrimeType.shoplift);
|
||||
if (getEnumHelper("CrimeType").isMember(abc[1])) {
|
||||
props.sleeve.commitCrime(abc[1]);
|
||||
}
|
||||
break;
|
||||
case "Take University Course":
|
||||
props.sleeve.takeUniversityCourse(abc[2], abc[1]);
|
||||
if (getEnumHelper("UniversityClassType").isMember(abc[1])) {
|
||||
props.sleeve.takeUniversityCourse(abc[2], abc[1]);
|
||||
}
|
||||
break;
|
||||
case "Workout at Gym":
|
||||
props.sleeve.workoutAtGym(abc[2], abc[1]);
|
||||
for (const [gymType, description] of getRecordEntries(gymTypeDescriptions)) {
|
||||
if (description === abc[1]) {
|
||||
props.sleeve.workoutAtGym(abc[2], gymType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Perform Bladeburner Actions":
|
||||
props.sleeve.bladeburner(abc[1], abc[2]);
|
||||
|
||||
@@ -4,33 +4,35 @@ import React from "react";
|
||||
import { MenuItem, Select, SelectChangeEvent } from "@mui/material";
|
||||
|
||||
import { Player } from "@player";
|
||||
import { BladeburnerActionType, BladeburnerContractName, CityName, FactionName, LocationName } from "@enums";
|
||||
import {
|
||||
BladeburnerActionType,
|
||||
BladeburnerContractName,
|
||||
BladeburnerGeneralActionName,
|
||||
CityName,
|
||||
FactionName,
|
||||
LocationName,
|
||||
SpecialBladeburnerActionTypeForSleeve,
|
||||
UniversityClassType,
|
||||
} from "@enums";
|
||||
import { Crimes } from "../../../Crime/Crimes";
|
||||
import { Factions } from "../../../Faction/Factions";
|
||||
import { getEnumHelper } from "../../../utils/EnumHelper";
|
||||
import { SleeveWorkType } from "../Work/Work";
|
||||
import { getRecordKeys } from "../../../Types/Record";
|
||||
|
||||
const universitySelectorOptions: string[] = [
|
||||
"Computer Science",
|
||||
"Data Structures",
|
||||
"Networks",
|
||||
"Algorithms",
|
||||
"Management",
|
||||
"Leadership",
|
||||
];
|
||||
const universitySelectorOptions = Object.values(UniversityClassType);
|
||||
|
||||
const gymSelectorOptions: string[] = ["Train Strength", "Train Defense", "Train Dexterity", "Train Agility"];
|
||||
|
||||
const bladeburnerSelectorOptions: string[] = [
|
||||
"Training",
|
||||
"Field Analysis",
|
||||
"Recruitment",
|
||||
"Diplomacy",
|
||||
"Hyperbolic Regeneration Chamber",
|
||||
"Infiltrate Synthoids",
|
||||
"Support main sleeve",
|
||||
"Take on contracts",
|
||||
BladeburnerGeneralActionName.Training,
|
||||
BladeburnerGeneralActionName.FieldAnalysis,
|
||||
BladeburnerGeneralActionName.Recruitment,
|
||||
BladeburnerGeneralActionName.Diplomacy,
|
||||
BladeburnerGeneralActionName.HyperbolicRegen,
|
||||
SpecialBladeburnerActionTypeForSleeve.InfiltrateSynthoids,
|
||||
SpecialBladeburnerActionTypeForSleeve.SupportMainSleeve,
|
||||
SpecialBladeburnerActionTypeForSleeve.TakeOnContracts,
|
||||
];
|
||||
|
||||
interface IProps {
|
||||
@@ -201,7 +203,7 @@ const tasks: {
|
||||
return {
|
||||
first: bladeburnerSelectorOptions,
|
||||
second: (s1: string) => {
|
||||
if (s1 === "Take on contracts") {
|
||||
if (s1 === SpecialBladeburnerActionTypeForSleeve.TakeOnContracts) {
|
||||
return possibleContracts(sleeve);
|
||||
} else {
|
||||
return ["------"];
|
||||
|
||||
Reference in New Issue
Block a user