mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-08 08:43:53 +01:00
parent
9c41995e59
commit
38f693e2c1
@ -13,10 +13,8 @@ export function determineCrimeSuccess(type: CrimeType): boolean {
|
||||
}
|
||||
|
||||
export function findCrime(roughName: string): Crime | null {
|
||||
const helper = getEnumHelper("CrimeType");
|
||||
if (helper.isMember(roughName)) return Crimes[roughName];
|
||||
const fuzzMatch = getEnumHelper("CrimeType").fuzzyGetMember(roughName);
|
||||
if (fuzzMatch) return Crimes[fuzzMatch];
|
||||
const matchedName = getEnumHelper("CrimeType").getMember(roughName, { fuzzy: true });
|
||||
if (matchedName) return Crimes[matchedName];
|
||||
// This can probably all be removed
|
||||
roughName = roughName.toLowerCase();
|
||||
if (roughName.includes("shoplift")) return Crimes[CrimeType.shoplift];
|
||||
|
@ -32,7 +32,7 @@ import { formatMoney, formatRam, formatReputation } from "../ui/formatNumber";
|
||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { Factions } from "../Faction/Factions";
|
||||
import { helpers, assertString } from "../Netscript/NetscriptHelpers";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||
import { getServerOnNetwork } from "../Server/ServerHelpers";
|
||||
import { Terminal } from "../Terminal";
|
||||
@ -738,22 +738,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
applyToCompany: (ctx) => (_companyName, _field) => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||
assertString(ctx, "field", _field);
|
||||
|
||||
// capitalize each word, except for "part-time"
|
||||
function capitalizeJobField(field: string) {
|
||||
return field
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.map((s) => {
|
||||
if (s.length == 0 || s == "part-time") return s;
|
||||
if (s.length == 2) return s.toUpperCase(); // Probably an acronym
|
||||
return s[0].toUpperCase() + s.slice(1);
|
||||
})
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
const field = getEnumHelper("JobField").nsGetMember(ctx, capitalizeJobField(_field as string), "field");
|
||||
const field = getEnumHelper("JobField").nsGetMember(ctx, _field, "field", { fuzzy: true });
|
||||
|
||||
Player.location = companyNameAsLocationName(companyName);
|
||||
let res;
|
||||
|
@ -300,7 +300,7 @@ export class Sleeve extends Person implements SleevePerson {
|
||||
};
|
||||
if (workTypeConversion[_workType]) _workType = workTypeConversion[_workType];
|
||||
const faction = Factions[factionName];
|
||||
const workType = getEnumHelper("FactionWorkType").fuzzyGetMember(_workType);
|
||||
const workType = getEnumHelper("FactionWorkType").getMember(_workType, { fuzzy: true });
|
||||
if (!workType) return false;
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
|
@ -67,8 +67,10 @@ export class SleeveFactionWork extends SleeveWorkClass {
|
||||
/** Initializes a FactionWork object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): SleeveFactionWork {
|
||||
const factionWork = Generic_fromJSON(SleeveFactionWork, value.data);
|
||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").fuzzyGetMember(factionWork.factionWorkType, true);
|
||||
factionWork.factionName = getEnumHelper("FactionName").fuzzyGetMember(factionWork.factionName, true);
|
||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").getMember(factionWork.factionWorkType, {
|
||||
alwaysMatch: true,
|
||||
});
|
||||
factionWork.factionName = getEnumHelper("FactionName").getMember(factionWork.factionName, { alwaysMatch: true });
|
||||
return factionWork;
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ function getABC(sleeve: Sleeve): [string, string, string] {
|
||||
return ["Workout at Gym", gymNames[work.classType as GymType], work.location];
|
||||
}
|
||||
case SleeveWorkType.CRIME:
|
||||
return ["Commit Crime", getEnumHelper("CrimeType").fuzzyGetMember(work.crimeType, true), "------"];
|
||||
return ["Commit Crime", getEnumHelper("CrimeType").getMember(work.crimeType, { alwaysMatch: true }), "------"];
|
||||
case SleeveWorkType.SUPPORT:
|
||||
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
|
||||
case SleeveWorkType.INFILTRATE:
|
||||
|
4
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
4
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -6873,9 +6873,9 @@ declare enum JobField {
|
||||
security = "Security",
|
||||
agent = "Agent",
|
||||
employee = "Employee",
|
||||
partTimeEmployee = "part-time Employee",
|
||||
partTimeEmployee = "Part-time Employee",
|
||||
waiter = "Waiter",
|
||||
partTimeWaiter = "part-time Waiter",
|
||||
partTimeWaiter = "Part-time Waiter",
|
||||
}
|
||||
|
||||
// CORP ENUMS - Changed to types
|
||||
|
@ -98,7 +98,7 @@ export class CrimeWork extends Work {
|
||||
/** Initializes a CrimeWork object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): CrimeWork {
|
||||
const crimeWork = Generic_fromJSON(CrimeWork, value.data);
|
||||
crimeWork.crimeType = getEnumHelper("CrimeType").fuzzyGetMember(crimeWork.crimeType, true);
|
||||
crimeWork.crimeType = getEnumHelper("CrimeType").getMember(crimeWork.crimeType, { alwaysMatch: true });
|
||||
return crimeWork;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ export enum JobField {
|
||||
security = "Security",
|
||||
agent = "Agent",
|
||||
employee = "Employee",
|
||||
partTimeEmployee = "part-time Employee",
|
||||
partTimeEmployee = "Part-time Employee",
|
||||
waiter = "Waiter",
|
||||
partTimeWaiter = "part-time Waiter",
|
||||
partTimeWaiter = "Part-time Waiter",
|
||||
}
|
||||
|
@ -91,8 +91,10 @@ export class FactionWork extends Work {
|
||||
/** Initializes a FactionWork object from a JSON save state. */
|
||||
static fromJSON(value: IReviverValue): FactionWork {
|
||||
const factionWork = Generic_fromJSON(FactionWork, value.data);
|
||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").fuzzyGetMember(factionWork.factionWorkType, true);
|
||||
factionWork.factionName = getEnumHelper("FactionName").fuzzyGetMember(factionWork.factionName, true);
|
||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").getMember(factionWork.factionWorkType, {
|
||||
alwaysMatch: true,
|
||||
});
|
||||
factionWork.factionName = getEnumHelper("FactionName").getMember(factionWork.factionName, { alwaysMatch: true });
|
||||
return factionWork;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,13 @@ import * as allEnums from "../Enums";
|
||||
import { assertString, helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { getRandomInt } from "./helpers/getRandomInt";
|
||||
|
||||
interface GetMemberOptions {
|
||||
/** Whether to use fuzzy matching on the input (case insensitive, ignore spaces and dashes) */
|
||||
fuzzy?: boolean;
|
||||
/** Whether to always return an enum member, even if there was no match. Will attempt fuzzy match before returning a default match. */
|
||||
alwaysMatch?: boolean;
|
||||
}
|
||||
|
||||
class EnumHelper<EnumObj extends object, EnumMember extends Member<EnumObj> & string> {
|
||||
name: string; // Name, for including in error text
|
||||
defaultArgName: string; // Used as default for for validating ns arg name
|
||||
@ -24,12 +31,19 @@ class EnumHelper<EnumObj extends object, EnumMember extends Member<EnumObj> & st
|
||||
return (this.valueSet.has as (value: unknown) => boolean)(toValidate);
|
||||
}
|
||||
/** Take an unknown input from a player script, either return an enum member or throw */
|
||||
nsGetMember(ctx: NetscriptContext, toValidate: unknown, argName = this.defaultArgName): EnumMember {
|
||||
if (this.isMember(toValidate)) return toValidate;
|
||||
// assertString is just called so if the user didn't even pass in a string, they get a different error message
|
||||
nsGetMember(
|
||||
ctx: NetscriptContext,
|
||||
toValidate: unknown,
|
||||
argName = this.defaultArgName,
|
||||
options?: GetMemberOptions,
|
||||
): EnumMember {
|
||||
const match = this.getMember(toValidate, options);
|
||||
if (match) return match;
|
||||
|
||||
// No match found, create error message
|
||||
assertString(ctx, argName, toValidate);
|
||||
// Don't display all possibilities for large enums
|
||||
let allowableValues = `Allowable values: ${this.valueArray.map((val) => `"${val}"`).join(", ")}`;
|
||||
// Don't display all possibilities for large enums
|
||||
if (this.valueArray.length > 10) {
|
||||
console.warn(
|
||||
`Provided value ${toValidate} was not a valid option for enum type ${this.name}.\n${allowableValues}`,
|
||||
@ -41,19 +55,16 @@ class EnumHelper<EnumObj extends object, EnumMember extends Member<EnumObj> & st
|
||||
`Argument ${argName} should be a ${this.name} enum member.\nProvided value: "${toValidate}".\n${allowableValues}`,
|
||||
);
|
||||
}
|
||||
/** Provides case insensitivty and ignores spaces and dashes, and can always match the input */
|
||||
fuzzyGetMember(input: string): EnumMember | undefined;
|
||||
fuzzyGetMember(input: string, alwaysMatch: true): EnumMember;
|
||||
fuzzyGetMember(input: string, alwaysMatch = false) {
|
||||
const matchedValue = this.fuzzMap.get(input.toLowerCase().replace(/[ -]+/g, ""));
|
||||
if (matchedValue) {
|
||||
return matchedValue;
|
||||
getMember(input: unknown, options: { alwaysMatch: true }): EnumMember;
|
||||
getMember(input: unknown, options?: GetMemberOptions): EnumMember | undefined;
|
||||
getMember(input: unknown, options?: GetMemberOptions): EnumMember | undefined {
|
||||
if (this.isMember(input)) return input;
|
||||
if (typeof input !== "string") return options?.alwaysMatch ? this.valueArray[0] : undefined;
|
||||
if (options?.fuzzy || options?.alwaysMatch) {
|
||||
const fuzzMatch = this.fuzzMap.get(input.toLowerCase().replace(/[ -]+/g, ""));
|
||||
if (fuzzMatch) return fuzzMatch;
|
||||
}
|
||||
return alwaysMatch ? this.valueArray[0] : undefined;
|
||||
}
|
||||
/** Provide a case sensitive match, or undefined if */
|
||||
getMember(input: unknown): EnumMember | undefined {
|
||||
return this.isMember(input) ? input : undefined;
|
||||
return undefined;
|
||||
}
|
||||
// Get a random enum member
|
||||
random() {
|
||||
|
@ -1,101 +0,0 @@
|
||||
import { Player, setPlayer } from "../../../src/Player";
|
||||
import { getCompaniesMetadata } from "../../../src/Company/data/CompaniesMetadata";
|
||||
import { getCompanyPositionMetadata } from "../../../src/Company/data/CompanyPositionsMetadata";
|
||||
import { PlayerObject } from "../../../src/PersonObjects/Player/PlayerObject";
|
||||
import { NetscriptSingularity } from "../../../src/NetscriptFunctions/Singularity";
|
||||
import { CompanyName, JobField, JobName } from "@enums";
|
||||
|
||||
import { WorkerScript } from "../../../src/Netscript/WorkerScript";
|
||||
import { Script } from "../../../src/Script/Script";
|
||||
import { RunningScript } from "../../../src/Script/RunningScript";
|
||||
import { ScriptFilePath } from "../../../src/Paths/ScriptFilePath";
|
||||
import { GetServer } from "../../../src/Server/AllServers";
|
||||
|
||||
describe("Singularity", () => {
|
||||
let ctx;
|
||||
let singularity;
|
||||
let positionMetadata;
|
||||
let companyMetadata;
|
||||
|
||||
beforeAll(() => {
|
||||
singularity = NetscriptSingularity();
|
||||
positionMetadata = getCompanyPositionMetadata();
|
||||
companyMetadata = getCompaniesMetadata();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
setPlayer(new PlayerObject());
|
||||
Player.init();
|
||||
Player.sourceFiles.set(4, 3);
|
||||
|
||||
GetServer("home").writeToScriptFile("function.js", "");
|
||||
let script = new Script("function.js", "", "home");
|
||||
let runningScript = new RunningScript(script, 1, []);
|
||||
let workerScript = new WorkerScript(runningScript, 1);
|
||||
ctx = { workerScript: workerScript, function: "singularityTest", functionPath: "test.singularityTest" };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Object.values(CompanyName).forEach((k) => {
|
||||
companyMetadata[k].playerReputation = 0;
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCompanyPositionInfo", () => {
|
||||
it("returns an enum for field", () => {
|
||||
let companyWithPositions = Object.values(CompanyName).find(
|
||||
(cn) => companyMetadata[cn].companyPositions.length > 0,
|
||||
);
|
||||
let company = companyMetadata[companyWithPositions];
|
||||
let positionName = company.companyPositions[0];
|
||||
let position = positionMetadata[positionName];
|
||||
|
||||
let companyPosition = singularity.getCompanyPositionInfo(ctx)(company.name, positionName);
|
||||
expect(companyPosition.field).toEqual(position.field);
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyToCompany", () => {
|
||||
it("throws an error if input doesn't match an enum", () => {
|
||||
let anyValidCompany = Object.values(CompanyName)[0];
|
||||
expect(() => singularity.applyToCompany(ctx)(anyValidCompany, "sockware")).toThrow("should be a JobField");
|
||||
expect(() => singularity.applyToCompany(ctx)(anyValidCompany, "invalid-job-field")).toThrow(
|
||||
"should be a JobField",
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts the JobField specified by getCompanyPositionInfo", () => {
|
||||
Object.values(CompanyName).forEach((cn) => {
|
||||
companyMetadata[cn].companyPositions.forEach((pn) => {
|
||||
let pos = positionMetadata[pn];
|
||||
expect(() => singularity.applyToCompany(ctx)(cn, pos.field)).not.toThrow();
|
||||
Player.quitJob(cn);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("is case-insensitive to string inputs to the field parameter", () => {
|
||||
Object.values(CompanyName).forEach((cn) => {
|
||||
companyMetadata[cn].companyPositions.forEach((pn) => {
|
||||
let pos = positionMetadata[pn];
|
||||
let field = pos.field;
|
||||
|
||||
let upperCase = field.toUpperCase();
|
||||
expect(() => singularity.applyToCompany(ctx)(cn, upperCase)).not.toThrow();
|
||||
Player.quitJob(cn);
|
||||
|
||||
let lowerCase = field.toLowerCase();
|
||||
expect(() => singularity.applyToCompany(ctx)(cn, lowerCase)).not.toThrow();
|
||||
Player.quitJob(cn);
|
||||
|
||||
let brokenCasing = field
|
||||
.split("")
|
||||
.map((c, i) => (i % 2 == 0 ? c.toUpperCase() : c.toLowerCase()))
|
||||
.join("");
|
||||
expect(() => singularity.applyToCompany(ctx)(cn, brokenCasing)).not.toThrow();
|
||||
Player.quitJob(cn);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user