From 3f95518891368d54eaf29576bf5553cdf3d3f1a7 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Tue, 11 Jun 2024 09:09:14 -0400 Subject: [PATCH] Add renameDevice and modify Rust --- src/Myrian/Myrian.ts | 19 +++++---- src/Myrian/formulas/cost.ts | 0 src/Myrian/formulas/formulas.ts | 48 ++++++---------------- src/Myrian/formulas/speed.ts | 5 +++ src/Myrian/ideas.txt | 1 + src/Myrian/utils.ts | 1 + src/NetscriptFunctions/Myrian.ts | 20 +++++---- src/ScriptEditor/NetscriptDefinitions.d.ts | 6 +++ 8 files changed, 49 insertions(+), 51 deletions(-) create mode 100644 src/Myrian/formulas/cost.ts create mode 100644 src/Myrian/formulas/speed.ts create mode 100644 src/Myrian/ideas.txt create mode 100644 src/Myrian/utils.ts diff --git a/src/Myrian/Myrian.ts b/src/Myrian/Myrian.ts index eb446d0d1..5c86dd96f 100644 --- a/src/Myrian/Myrian.ts +++ b/src/Myrian/Myrian.ts @@ -16,6 +16,7 @@ import { } from "@nsdefs"; import { myrian, myrianSize } from "./Helper"; import { glitchMult } from "./formulas/glitches"; +import { pickOne } from "./utils"; export interface Myrian { vulns: number; @@ -135,14 +136,16 @@ export const getTotalGlitchMult = () => return acc * glitchMult(glitch as Glitch, lvl); }, 1); -const rustStats: (keyof Bus)[] = ["moveLvl", "transferLvl", "reduceLvl", "installLvl", "maxEnergy"]; +// DO NOT use `Object.keys` on a Rustable because it will return way more than just the rustable stats. +const rustStats: (keyof Rustable)[] = ["moveLvl", "transferLvl", "reduceLvl", "installLvl", "maxEnergy"]; +type Rustable = Pick; export const rustBus = (bus: Bus, rust: number) => { - const potential = rustStats.filter((stat) => { - const value = bus[stat]; - if (typeof value !== "number") return false; - return value > 0; - }); - const chosen = potential[Math.floor(Math.random() * potential.length)]; - (bus[chosen] as any) = Math.max(0, (bus[chosen] as any) - rust * 0.1) as any; + const rustable = bus as Rustable; + const nonZero = rustStats.filter((stat) => rustable[stat] > 0); + const chosen = pickOne(nonZero); + rustable[chosen] = Math.max(0, rustable[chosen] - rust * 0.1); + + // cap energy when maxEnergy is reduced + bus.energy = Math.min(bus.energy, bus.maxEnergy); }; diff --git a/src/Myrian/formulas/cost.ts b/src/Myrian/formulas/cost.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/Myrian/formulas/formulas.ts b/src/Myrian/formulas/formulas.ts index 963fa7f2b..9b8cdb421 100644 --- a/src/Myrian/formulas/formulas.ts +++ b/src/Myrian/formulas/formulas.ts @@ -1,10 +1,11 @@ import { DeviceType } from "@nsdefs"; import { myrian } from "../Helper"; import { componentTiers } from "./components"; +import { pickOne } from "../utils"; -export type FactoryFormulaParams = [number, number, number, number]; +type FactoryFormulaParams = [number, number, number, number]; -export const maxContentScale: Record = { +const maxContentScale: Record = { [DeviceType.Bus]: [8, 0.5, 2, 0], [DeviceType.ISocket]: [4, 1, 5, 0], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -20,16 +21,9 @@ const exp = (p: FactoryFormulaParams, x: number): number => Math.pow(p[0], p[1] export const upgradeMaxContentCost = (type: DeviceType, currentMaxContent: number): number => exp(maxContentScale[type], currentMaxContent); -export const busPrice = (currentBusses: number): number => Math.pow(2, currentBusses + 3); -export const moveSpeed = (level: number) => 1000 / (level + 10); -export const reduceSpeed = (level: number) => 50000 / (level + 10); -export const transferSpeed = (level: number) => 1000 / (level + 10); -export const installSpeed = (level: number) => 100000 / (level + 10); -export const isocketSpeed = (level: number) => 100000 / (level + 10); - const countDevices = (type: DeviceType) => myrian.devices.reduce((acc, d) => (d.type === type ? acc + 1 : acc), 0); -export const deviceScale: Record = { +const deviceScale: Record = { [DeviceType.Bus]: [4, 0.5, 2, 0], [DeviceType.ISocket]: [2, 1, 4, 0], [DeviceType.OSocket]: [4, 1, 3, 0], @@ -44,12 +38,10 @@ export const deviceCost = (type: DeviceType, count?: number) => export const getNextISocketRequest = (tier: number) => { const potential = componentTiers.slice(0, tier + 1).flat(); - return new Array(Math.floor(Math.pow(Math.random() * tier, 0.75) + 1)) - .fill(null) - .map(() => potential[Math.floor(Math.random() * potential.length)]); + return new Array(Math.floor(Math.pow(Math.random() * tier, 0.75) + 1)).fill(null).map(() => pickOne(potential)); }; -export const tierScale: Record = { +const tierScale: Record = { [DeviceType.Bus]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -61,7 +53,7 @@ export const tierScale: Record = { export const tierCost = (type: DeviceType, tier: number) => exp(tierScale[type], tier); -export const emissionScale: Record = { +const emissionScale: Record = { [DeviceType.Bus]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.ISocket]: [2, 1, 3, 0], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -73,7 +65,7 @@ export const emissionScale: Record = { export const emissionCost = (type: DeviceType, emissionLvl: number) => exp(emissionScale[type], emissionLvl); -export const moveLvlScale: Record = { +const moveLvlScale: Record = { [DeviceType.Bus]: [2, 1, 3, 0], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -85,7 +77,7 @@ export const moveLvlScale: Record = { export const moveLvlCost = (type: DeviceType, moveLvl: number) => exp(moveLvlScale[type], moveLvl); -export const transferLvlScale: Record = { +const transferLvlScale: Record = { [DeviceType.Bus]: [2, 1, 3, 0], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -97,7 +89,7 @@ export const transferLvlScale: Record = { export const transferLvlCost = (type: DeviceType, transferLvl: number) => exp(transferLvlScale[type], transferLvl); -export const reduceLvlScale: Record = { +const reduceLvlScale: Record = { [DeviceType.Bus]: [2, 1, 3, 0], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -109,7 +101,7 @@ export const reduceLvlScale: Record = { export const reduceLvlCost = (type: DeviceType, reduceLvl: number) => exp(reduceLvlScale[type], reduceLvl); -export const installLvlScale: Record = { +const installLvlScale: Record = { [DeviceType.Bus]: [2, 1, 3, 0], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -121,7 +113,7 @@ export const installLvlScale: Record = { export const installLvlCost = (type: DeviceType, installLvl: number) => exp(installLvlScale[type], installLvl); -export const maxEnergyScale: Record = { +const maxEnergyScale: Record = { [DeviceType.Bus]: [2, 1, 3, 0], [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], @@ -132,19 +124,3 @@ export const maxEnergyScale: Record = { }; export const maxEnergyCost = (type: DeviceType, maxEnergy: number) => exp(maxEnergyScale[type], maxEnergy); - -/** -glitches: - -- random walls (higher level more randomly spawning walls, level 0 is no walls) -- moving dock & dispensers (higher level move faster, level 0 does not move) -- dock complexity (higher level more complex, level 0 is repeating request) -- energy consumption (higher level consume more, level 0 is no consumption) -- ugrade degradation (hidden tile degrade upgrades, level 0 does not degrade) -- move hinderance (speed) (higher level slower, level 0 is no hinderance) -- connection hinderance (transfer / charge) (higher level slower, level 0 is immediate transfer speed and charge) -- allocation hinderance (craft & build) (higher level slower, level 0 is no hinderance) - - -special requests like "has red" that increases the reward -*/ diff --git a/src/Myrian/formulas/speed.ts b/src/Myrian/formulas/speed.ts new file mode 100644 index 000000000..d5e7933a5 --- /dev/null +++ b/src/Myrian/formulas/speed.ts @@ -0,0 +1,5 @@ +export const moveSpeed = (level: number) => 1000 / (level + 10); +export const reduceSpeed = (level: number) => 50000 / (level + 10); +export const transferSpeed = (level: number) => 1000 / (level + 10); +export const installSpeed = (level: number) => 100000 / (level + 10); +export const isocketSpeed = (level: number) => 100000 / (level + 10); diff --git a/src/Myrian/ideas.txt b/src/Myrian/ideas.txt new file mode 100644 index 000000000..1d74cba9e --- /dev/null +++ b/src/Myrian/ideas.txt @@ -0,0 +1 @@ +New device that makes special requests like "has red" | "at least tier 3" | "does not contain blue" that increases the reward. diff --git a/src/Myrian/utils.ts b/src/Myrian/utils.ts new file mode 100644 index 000000000..36e9ab03e --- /dev/null +++ b/src/Myrian/utils.ts @@ -0,0 +1 @@ +export const pickOne = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)]; diff --git a/src/NetscriptFunctions/Myrian.ts b/src/NetscriptFunctions/Myrian.ts index e754ff4aa..29b873966 100644 --- a/src/NetscriptFunctions/Myrian.ts +++ b/src/NetscriptFunctions/Myrian.ts @@ -31,16 +31,11 @@ import { emissionCost, getNextISocketRequest, installLvlCost, - installSpeed, - isocketSpeed, maxEnergyCost, moveLvlCost, - moveSpeed, reduceLvlCost, - reduceSpeed, tierCost, transferLvlCost, - transferSpeed, upgradeMaxContentCost, } from "../Myrian/formulas/formulas"; import { recipes } from "../Myrian/formulas/recipes"; @@ -54,6 +49,8 @@ import { magnetismLoss, virtualizationMult, } from "../Myrian/formulas/glitches"; +import { pickOne } from "../Myrian/utils"; +import { installSpeed, isocketSpeed, moveSpeed, reduceSpeed, transferSpeed } from "../Myrian/formulas/speed"; export function NetscriptMyrian(): InternalAPI { return { @@ -70,6 +67,15 @@ export function NetscriptMyrian(): InternalAPI { }, getDevices: (__ctx) => () => JSON.parse(JSON.stringify(myrian.devices)), getVulns: () => () => myrian.vulns, + renameDevice: (ctx) => (_id, _name) => { + const id = helpers.deviceID(ctx, "id", _id); + const name = helpers.string(ctx, "name", _name); + const device = findDevice(id); + if (!device) return false; + if (findDevice(name)) return false; + device.name = name; + return true; + }, moveBus: (ctx) => async (_bus, _coord): Promise => { @@ -101,7 +107,7 @@ export function NetscriptMyrian(): InternalAPI { return Promise.resolve(false); } - const outOfEnergy = bus.energy === 0 ? 0.5 : 1; + const outOfEnergy = bus.energy === 0 ? 0.1 : 1; bus.isBusy = true; return helpers @@ -472,7 +478,7 @@ export function NetscriptMyrian(): InternalAPI { break; } case DeviceType.ISocket: { - NewISocket(name, x, y, componentTiers[0][Math.floor(Math.random() * componentTiers[0].length)]); + NewISocket(name, x, y, pickOne(componentTiers[0])); break; } case DeviceType.OSocket: { diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 1f19e8e2f..4898b8911 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -5409,6 +5409,12 @@ interface Myrian { */ uninstallDevice(bus: DeviceID, coord: [number, number]): Promise; + /** + * Rename a device, no 2 entity can have the same name + * @returns true if the rename succeeded, false otherwise. + */ + renameDevice(device: DeviceID, name: string): boolean; + /** * Upgrade the max content of a device * @remarks