MISC: Remove fuzzy matching when checking params (#2091)

This commit is contained in:
catloversg
2025-05-19 06:08:19 +07:00
committed by GitHub
parent f4e70720a6
commit 24b31975e7
26 changed files with 281 additions and 395 deletions
+36 -69
View File
@@ -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;
}
}
+54 -33
View File
@@ -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]);
+20 -18
View File
@@ -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 ["------"];