mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 07:33:48 +01:00
parent
9c41995e59
commit
38f693e2c1
@ -13,10 +13,8 @@ export function determineCrimeSuccess(type: CrimeType): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function findCrime(roughName: string): Crime | null {
|
export function findCrime(roughName: string): Crime | null {
|
||||||
const helper = getEnumHelper("CrimeType");
|
const matchedName = getEnumHelper("CrimeType").getMember(roughName, { fuzzy: true });
|
||||||
if (helper.isMember(roughName)) return Crimes[roughName];
|
if (matchedName) return Crimes[matchedName];
|
||||||
const fuzzMatch = getEnumHelper("CrimeType").fuzzyGetMember(roughName);
|
|
||||||
if (fuzzMatch) return Crimes[fuzzMatch];
|
|
||||||
// This can probably all be removed
|
// This can probably all be removed
|
||||||
roughName = roughName.toLowerCase();
|
roughName = roughName.toLowerCase();
|
||||||
if (roughName.includes("shoplift")) return Crimes[CrimeType.shoplift];
|
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 { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||||
import { Companies } from "../Company/Companies";
|
import { Companies } from "../Company/Companies";
|
||||||
import { Factions } from "../Faction/Factions";
|
import { Factions } from "../Faction/Factions";
|
||||||
import { helpers, assertString } from "../Netscript/NetscriptHelpers";
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||||
import { getServerOnNetwork } from "../Server/ServerHelpers";
|
import { getServerOnNetwork } from "../Server/ServerHelpers";
|
||||||
import { Terminal } from "../Terminal";
|
import { Terminal } from "../Terminal";
|
||||||
@ -738,22 +738,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
|||||||
applyToCompany: (ctx) => (_companyName, _field) => {
|
applyToCompany: (ctx) => (_companyName, _field) => {
|
||||||
helpers.checkSingularityAccess(ctx);
|
helpers.checkSingularityAccess(ctx);
|
||||||
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
const companyName = getEnumHelper("CompanyName").nsGetMember(ctx, _companyName);
|
||||||
assertString(ctx, "field", _field);
|
const field = getEnumHelper("JobField").nsGetMember(ctx, _field, "field", { fuzzy: true });
|
||||||
|
|
||||||
// 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");
|
|
||||||
|
|
||||||
Player.location = companyNameAsLocationName(companyName);
|
Player.location = companyNameAsLocationName(companyName);
|
||||||
let res;
|
let res;
|
||||||
|
@ -300,7 +300,7 @@ export class Sleeve extends Person implements SleevePerson {
|
|||||||
};
|
};
|
||||||
if (workTypeConversion[_workType]) _workType = workTypeConversion[_workType];
|
if (workTypeConversion[_workType]) _workType = workTypeConversion[_workType];
|
||||||
const faction = Factions[factionName];
|
const faction = Factions[factionName];
|
||||||
const workType = getEnumHelper("FactionWorkType").fuzzyGetMember(_workType);
|
const workType = getEnumHelper("FactionWorkType").getMember(_workType, { fuzzy: true });
|
||||||
if (!workType) return false;
|
if (!workType) return false;
|
||||||
const factionInfo = faction.getInfo();
|
const factionInfo = faction.getInfo();
|
||||||
|
|
||||||
|
@ -67,8 +67,10 @@ export class SleeveFactionWork extends SleeveWorkClass {
|
|||||||
/** Initializes a FactionWork object from a JSON save state. */
|
/** Initializes a FactionWork object from a JSON save state. */
|
||||||
static fromJSON(value: IReviverValue): SleeveFactionWork {
|
static fromJSON(value: IReviverValue): SleeveFactionWork {
|
||||||
const factionWork = Generic_fromJSON(SleeveFactionWork, value.data);
|
const factionWork = Generic_fromJSON(SleeveFactionWork, value.data);
|
||||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").fuzzyGetMember(factionWork.factionWorkType, true);
|
factionWork.factionWorkType = getEnumHelper("FactionWorkType").getMember(factionWork.factionWorkType, {
|
||||||
factionWork.factionName = getEnumHelper("FactionName").fuzzyGetMember(factionWork.factionName, true);
|
alwaysMatch: true,
|
||||||
|
});
|
||||||
|
factionWork.factionName = getEnumHelper("FactionName").getMember(factionWork.factionName, { alwaysMatch: true });
|
||||||
return factionWork;
|
return factionWork;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ function getABC(sleeve: Sleeve): [string, string, string] {
|
|||||||
return ["Workout at Gym", gymNames[work.classType as GymType], work.location];
|
return ["Workout at Gym", gymNames[work.classType as GymType], work.location];
|
||||||
}
|
}
|
||||||
case SleeveWorkType.CRIME:
|
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:
|
case SleeveWorkType.SUPPORT:
|
||||||
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
|
return ["Perform Bladeburner Actions", "Support main sleeve", "------"];
|
||||||
case SleeveWorkType.INFILTRATE:
|
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",
|
security = "Security",
|
||||||
agent = "Agent",
|
agent = "Agent",
|
||||||
employee = "Employee",
|
employee = "Employee",
|
||||||
partTimeEmployee = "part-time Employee",
|
partTimeEmployee = "Part-time Employee",
|
||||||
waiter = "Waiter",
|
waiter = "Waiter",
|
||||||
partTimeWaiter = "part-time Waiter",
|
partTimeWaiter = "Part-time Waiter",
|
||||||
}
|
}
|
||||||
|
|
||||||
// CORP ENUMS - Changed to types
|
// CORP ENUMS - Changed to types
|
||||||
|
@ -98,7 +98,7 @@ export class CrimeWork extends Work {
|
|||||||
/** Initializes a CrimeWork object from a JSON save state. */
|
/** Initializes a CrimeWork object from a JSON save state. */
|
||||||
static fromJSON(value: IReviverValue): CrimeWork {
|
static fromJSON(value: IReviverValue): CrimeWork {
|
||||||
const crimeWork = Generic_fromJSON(CrimeWork, value.data);
|
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;
|
return crimeWork;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ export enum JobField {
|
|||||||
security = "Security",
|
security = "Security",
|
||||||
agent = "Agent",
|
agent = "Agent",
|
||||||
employee = "Employee",
|
employee = "Employee",
|
||||||
partTimeEmployee = "part-time Employee",
|
partTimeEmployee = "Part-time Employee",
|
||||||
waiter = "Waiter",
|
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. */
|
/** Initializes a FactionWork object from a JSON save state. */
|
||||||
static fromJSON(value: IReviverValue): FactionWork {
|
static fromJSON(value: IReviverValue): FactionWork {
|
||||||
const factionWork = Generic_fromJSON(FactionWork, value.data);
|
const factionWork = Generic_fromJSON(FactionWork, value.data);
|
||||||
factionWork.factionWorkType = getEnumHelper("FactionWorkType").fuzzyGetMember(factionWork.factionWorkType, true);
|
factionWork.factionWorkType = getEnumHelper("FactionWorkType").getMember(factionWork.factionWorkType, {
|
||||||
factionWork.factionName = getEnumHelper("FactionName").fuzzyGetMember(factionWork.factionName, true);
|
alwaysMatch: true,
|
||||||
|
});
|
||||||
|
factionWork.factionName = getEnumHelper("FactionName").getMember(factionWork.factionName, { alwaysMatch: true });
|
||||||
return factionWork;
|
return factionWork;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,13 @@ import * as allEnums from "../Enums";
|
|||||||
import { assertString, helpers } from "../Netscript/NetscriptHelpers";
|
import { assertString, helpers } from "../Netscript/NetscriptHelpers";
|
||||||
import { getRandomInt } from "./helpers/getRandomInt";
|
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> {
|
class EnumHelper<EnumObj extends object, EnumMember extends Member<EnumObj> & string> {
|
||||||
name: string; // Name, for including in error text
|
name: string; // Name, for including in error text
|
||||||
defaultArgName: string; // Used as default for for validating ns arg name
|
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);
|
return (this.valueSet.has as (value: unknown) => boolean)(toValidate);
|
||||||
}
|
}
|
||||||
/** Take an unknown input from a player script, either return an enum member or throw */
|
/** Take an unknown input from a player script, either return an enum member or throw */
|
||||||
nsGetMember(ctx: NetscriptContext, toValidate: unknown, argName = this.defaultArgName): EnumMember {
|
nsGetMember(
|
||||||
if (this.isMember(toValidate)) return toValidate;
|
ctx: NetscriptContext,
|
||||||
// assertString is just called so if the user didn't even pass in a string, they get a different error message
|
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);
|
assertString(ctx, argName, toValidate);
|
||||||
// Don't display all possibilities for large enums
|
|
||||||
let allowableValues = `Allowable values: ${this.valueArray.map((val) => `"${val}"`).join(", ")}`;
|
let allowableValues = `Allowable values: ${this.valueArray.map((val) => `"${val}"`).join(", ")}`;
|
||||||
|
// Don't display all possibilities for large enums
|
||||||
if (this.valueArray.length > 10) {
|
if (this.valueArray.length > 10) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Provided value ${toValidate} was not a valid option for enum type ${this.name}.\n${allowableValues}`,
|
`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}`,
|
`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 */
|
getMember(input: unknown, options: { alwaysMatch: true }): EnumMember;
|
||||||
fuzzyGetMember(input: string): EnumMember | undefined;
|
getMember(input: unknown, options?: GetMemberOptions): EnumMember | undefined;
|
||||||
fuzzyGetMember(input: string, alwaysMatch: true): EnumMember;
|
getMember(input: unknown, options?: GetMemberOptions): EnumMember | undefined {
|
||||||
fuzzyGetMember(input: string, alwaysMatch = false) {
|
if (this.isMember(input)) return input;
|
||||||
const matchedValue = this.fuzzMap.get(input.toLowerCase().replace(/[ -]+/g, ""));
|
if (typeof input !== "string") return options?.alwaysMatch ? this.valueArray[0] : undefined;
|
||||||
if (matchedValue) {
|
if (options?.fuzzy || options?.alwaysMatch) {
|
||||||
return matchedValue;
|
const fuzzMatch = this.fuzzMap.get(input.toLowerCase().replace(/[ -]+/g, ""));
|
||||||
|
if (fuzzMatch) return fuzzMatch;
|
||||||
}
|
}
|
||||||
return alwaysMatch ? this.valueArray[0] : undefined;
|
return undefined;
|
||||||
}
|
|
||||||
/** Provide a case sensitive match, or undefined if */
|
|
||||||
getMember(input: unknown): EnumMember | undefined {
|
|
||||||
return this.isMember(input) ? input : undefined;
|
|
||||||
}
|
}
|
||||||
// Get a random enum member
|
// Get a random enum member
|
||||||
random() {
|
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