diff --git a/src/Myrian/Helper.tsx b/src/Myrian/Helper.tsx index 6a57f2a71..fba99d7cb 100644 --- a/src/Myrian/Helper.tsx +++ b/src/Myrian/Helper.tsx @@ -1,13 +1,26 @@ -import { DeviceType, Component, Lock } from "@nsdefs"; +import { DeviceType, Component, Lock, Glitch } from "@nsdefs"; import { Myrian } from "./Myrian"; import { getNextISocketRequest } from "./formulas/formulas"; export const myrianSize = 12; +const defaultGlitches = { + [Glitch.Segmentation]: 0, + [Glitch.Roaming]: 0, + [Glitch.Encryption]: 0, + [Glitch.Magnetism]: 0, + [Glitch.Rust]: 0, + [Glitch.Friction]: 0, + [Glitch.Isolation]: 0, + [Glitch.Jamming]: 0, + [Glitch.Virtualization]: 0, +}; + const defaultMyrian: Myrian = { vulns: 0, totalVulns: 0, devices: [], + glitches: { ...defaultGlitches }, }; export const myrian: Myrian = defaultMyrian; @@ -26,7 +39,8 @@ export const NewBus = (name: string, x: number, y: number) => { transferLvl: 0, reduceLvl: 0, installLvl: 0, - // energy: 16, + energy: 16, + maxEnergy: 16, }); }; @@ -96,6 +110,19 @@ export const NewLock = (name: string, x: number, y: number) => { return lock; }; +export const NewBattery = (name: string, x: number, y: number) => { + myrian.devices.push({ + name, + type: DeviceType.Battery, + isBusy: false, + x, + y, + tier: 0, + energy: 64, + maxEnergy: 64, + }); +}; + export const loadMyrian = (save: string) => { if (!save) return; // const savedFactory = JSON.parse(save); @@ -104,9 +131,14 @@ export const loadMyrian = (save: string) => { export const resetMyrian = () => { myrian.vulns = 0; + myrian.totalVulns = 0; myrian.devices = []; + myrian.glitches = { ...defaultGlitches }; + Object.assign(myrian, defaultMyrian); + NewBus("alice", Math.floor(myrianSize / 2), Math.floor(myrianSize / 2)); + NewISocket("isocket0", Math.floor(myrianSize / 4), 0, Component.R0); NewISocket("isocket1", Math.floor(myrianSize / 2), 0, Component.G0); NewISocket("isocket2", Math.floor((myrianSize * 3) / 4), 0, Component.B0); @@ -116,4 +148,12 @@ export const resetMyrian = () => { NewOSocket("osocket2", Math.floor((myrianSize * 3) / 4), Math.floor(myrianSize - 1)); }; +setInterval(() => { + myrian.devices.forEach((device) => { + if (device.type !== DeviceType.Battery) return; + const up = Math.pow(2, device.tier + 1); + device.energy = Math.min(device.energy + up, device.maxEnergy); + }); +}, 1000); + resetMyrian(); diff --git a/src/Myrian/Myrian.ts b/src/Myrian/Myrian.ts index 221cf44a9..cd4dcbbc6 100644 --- a/src/Myrian/Myrian.ts +++ b/src/Myrian/Myrian.ts @@ -11,13 +11,17 @@ import { Lock, BaseDevice, DeviceID, + Glitch, + Battery, } from "@nsdefs"; import { myrian, myrianSize } from "./Helper"; +import { glitchMult } from "./formulas/glitches"; export interface Myrian { vulns: number; totalVulns: number; devices: Device[]; + glitches: Record; } export const distance = (a: Device, b: Device) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y); @@ -112,6 +116,7 @@ export const isDeviceOSocket = (d: Device): d is OSocket => d.type === DeviceTyp export const isDeviceReducer = (d: Device): d is Reducer => d.type === DeviceType.Reducer; export const isDeviceCache = (d: Device): d is Cache => d.type === DeviceType.Cache; export const isDeviceLock = (d: Device): d is Lock => d.type === DeviceType.Lock; +export const isDeviceBattery = (d: Device): d is Battery => d.type === DeviceType.Battery; export const findDevice = (id: DeviceID, type?: DeviceType): Device | undefined => myrian.devices.find( @@ -123,3 +128,8 @@ export const removeDevice = (id: DeviceID, type?: DeviceType) => { (e) => !((typeof id === "string" ? e.name === id : e.x === id[0] && e.y === id[1]) && (!type || type === e.type)), ); }; + +export const getTotalGlitchMult = () => + Object.entries(myrian.glitches).reduce((acc, [glitch, lvl]) => { + return acc * glitchMult(glitch as Glitch, lvl); + }, 1); diff --git a/src/Myrian/formulas/formulas.ts b/src/Myrian/formulas/formulas.ts index 149fcc406..323756c5e 100644 --- a/src/Myrian/formulas/formulas.ts +++ b/src/Myrian/formulas/formulas.ts @@ -11,6 +11,7 @@ export const maxContentScale: Record = { [DeviceType.Reducer]: [Infinity, 1, -1, 4095], [DeviceType.Cache]: [1.2, 10, 0, 63], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; // a^(b*X+c)+d @@ -35,6 +36,7 @@ export const deviceScale: Record = { [DeviceType.Reducer]: [1.5, 1, 2, 0], [DeviceType.Cache]: [1.2, 10, 0, 63], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [1.2, 10, 0, 63], }; export const deviceCost = (type: DeviceType, count?: number) => @@ -54,6 +56,7 @@ export const tierScale: Record = { [DeviceType.Reducer]: [1.5, 1, 2, 0], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [2, 1, 3, 0], }; export const tierCost = (type: DeviceType, tier: number) => exp(tierScale[type], tier); @@ -65,6 +68,7 @@ export const emissionScale: Record = { [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; export const emissionCost = (type: DeviceType, emissionLvl: number) => exp(emissionScale[type], emissionLvl); @@ -76,6 +80,7 @@ export const moveLvlScale: Record = { [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; export const moveLvlCost = (type: DeviceType, moveLvl: number) => exp(moveLvlScale[type], moveLvl); @@ -87,6 +92,7 @@ export const transferLvlScale: Record = { [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; export const transferLvlCost = (type: DeviceType, transferLvl: number) => exp(transferLvlScale[type], transferLvl); @@ -98,6 +104,7 @@ export const reduceLvlScale: Record = { [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; export const reduceLvlCost = (type: DeviceType, reduceLvl: number) => exp(reduceLvlScale[type], reduceLvl); @@ -109,10 +116,23 @@ export const installLvlScale: Record = { [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [Infinity, Infinity, Infinity, Infinity], }; export const installLvlCost = (type: DeviceType, installLvl: number) => exp(installLvlScale[type], installLvl); +export const maxEnergyScale: Record = { + [DeviceType.Bus]: [2, 1, 3, 0], + [DeviceType.ISocket]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.OSocket]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Reducer]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Cache]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Lock]: [Infinity, Infinity, Infinity, Infinity], + [DeviceType.Battery]: [1.1, 1, 3, 8], +}; + +export const maxEnergyCost = (type: DeviceType, maxEnergy: number) => exp(maxEnergyScale[type], maxEnergy); + /** glitches: @@ -120,10 +140,11 @@ glitches: - 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 (higher level degrade faster, level 0 does not degrade) +- 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/glitches.ts b/src/Myrian/formulas/glitches.ts new file mode 100644 index 000000000..493813077 --- /dev/null +++ b/src/Myrian/formulas/glitches.ts @@ -0,0 +1,42 @@ +import { Glitch } from "@nsdefs"; + +export const glitchMaxLvl: Record = { + [Glitch.Segmentation]: 10, + [Glitch.Roaming]: 10, + [Glitch.Encryption]: 7, + [Glitch.Magnetism]: 10, + [Glitch.Rust]: 10, + [Glitch.Friction]: 3, + [Glitch.Isolation]: 3, + [Glitch.Virtualization]: 3, + [Glitch.Jamming]: 3, +}; + +export const giltchMultCoefficients: Record = { + [Glitch.Segmentation]: 0, // 1, + [Glitch.Roaming]: 0, // 1, + [Glitch.Encryption]: 0, // 0.1, + [Glitch.Magnetism]: 0.2, + [Glitch.Rust]: 0, // 1, + [Glitch.Friction]: 0.2, + [Glitch.Isolation]: 0.2, + [Glitch.Virtualization]: 0.2, + [Glitch.Jamming]: 0.2, +}; + +export const glitchMult = (glitch: Glitch, lvl: number) => 1 + lvl * giltchMultCoefficients[glitch]; + +// move hinderance +export const frictionMult = (lvl: number) => Math.pow(1.25, lvl); + +// transfer slow down +export const isolationMult = (lvl: number) => Math.pow(2, lvl); + +// install/uninstall slow down +export const virtualizationMult = (lvl: number) => Math.pow(3, lvl); + +// reduce slow down +export const jammingMult = (lvl: number) => Math.pow(1.3, lvl); + +// energy loss +export const magnetismLoss = (lvl: number) => lvl; diff --git a/src/Myrian/tutorial.md b/src/Myrian/tutorial.md index 118a15c25..8d34bd924 100644 --- a/src/Myrian/tutorial.md +++ b/src/Myrian/tutorial.md @@ -39,6 +39,10 @@ These devices act as storage for components. These devices cannot be installed. They appear after various conditions are fulfilled in order to block certain tiles. +### Battery + +These devices are only relevant when the Magnetism glitch is active. It recharges the energy of a bus. + ## Installing Bus can install new devices, when they do so a lock will appear over the tile that will eventually become the device. The cost of any device depends on the number of that type of device currently in the OS. @@ -54,3 +58,28 @@ Currently 2 devices have tiers, reducers and OSockets. Upgrading a reducer allows it to reduce components of a higher tier and ONLY that higher tier. A tier 2 reducer can only tier 2 components like r1 + r1 => r2 and loses access to r0 + r0 => r1 Upgrading a OSocket allows it to request higher tier components (as well as more components at a time). + +## Glitches + +glitches are optional difficulty modifiers that make the myrian more difficult BUT increase the amount of vulns gained. +All glitches start at level 0 and must be activated when you chose. They also have a max level that differs from glitch to glitch. + +### Magnetism + +By default bus lose 0 energy when moving. But when this glitch is active they start losing energy, at 0 energy bus move much more slowly. Batteries must be installed and used to charge busses. + +### Friction + +When Friction is active busses move more slowly. + +### Isolation + +When Isolation is active busses transfer and charge more slowly. + +### Virtualization + +When Virtualization is active busses install and uninstall devices more slowly. + +### Jamming + +When Jamming is active busses use reducers more slowly. diff --git a/src/Myrian/ui/DeviceIcon.tsx b/src/Myrian/ui/DeviceIcon.tsx index edbfd2234..43f6465a7 100644 --- a/src/Myrian/ui/DeviceIcon.tsx +++ b/src/Myrian/ui/DeviceIcon.tsx @@ -7,6 +7,7 @@ import MoveToInboxIcon from "@mui/icons-material/MoveToInbox"; import OutboxIcon from "@mui/icons-material/Outbox"; import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; import MergeTypeIcon from "@mui/icons-material/MergeType"; +import BatteryChargingFullIcon from "@mui/icons-material/BatteryChargingFull"; import BlockIcon from "@mui/icons-material/Block"; import { Tooltip, Typography } from "@mui/material"; import { isDeviceContainer } from "../Myrian"; @@ -110,6 +111,8 @@ const ReducerIcon = styled(MergeTypeIcon)(defaultIconStyle); const CacheIcon = styled(CheckBoxOutlineBlankIcon)(defaultIconStyle); +const BatteryIcon = styled(BatteryChargingFullIcon)(defaultIconStyle); + interface ITooltipContentProps { device: Device; content: React.ReactElement; @@ -143,6 +146,24 @@ export const DeviceIcon = ({ device }: { device: Device }): React.ReactElement = case DeviceType.Lock: { return ; } + case DeviceType.Battery: { + return ( + + {device.energy} / {device.maxEnergy} + + } + /> + } + > + + + ); + } case DeviceType.Cache: { return ( } />}> diff --git a/src/NetscriptFunctions/Myrian.ts b/src/NetscriptFunctions/Myrian.ts index d1990c2e0..1f3925710 100644 --- a/src/NetscriptFunctions/Myrian.ts +++ b/src/NetscriptFunctions/Myrian.ts @@ -1,7 +1,8 @@ -import { Bus, Myrian as IMyrian, DeviceType, Component, Reducer } from "@nsdefs"; +import { Bus, Myrian as IMyrian, DeviceType, Component, Reducer, Glitch, Battery } from "@nsdefs"; import { InternalAPI } from "../Netscript/APIWrapper"; import { helpers } from "../Netscript/NetscriptHelpers"; import { + NewBattery, NewBus, NewCache, NewISocket, @@ -22,6 +23,7 @@ import { isDeviceContainer, isDeviceBus, removeDevice, + getTotalGlitchMult, } from "../Myrian/Myrian"; import { deviceCost, @@ -30,6 +32,7 @@ import { installLvlCost, installSpeed, isocketSpeed, + maxEnergyCost, moveLvlCost, moveSpeed, reduceLvlCost, @@ -41,6 +44,15 @@ import { } from "../Myrian/formulas/formulas"; import { recipes } from "../Myrian/formulas/recipes"; import { componentTiers } from "../Myrian/formulas/components"; +import { + frictionMult, + glitchMaxLvl, + glitchMult, + isolationMult, + jammingMult, + magnetismLoss, + virtualizationMult, +} from "../Myrian/formulas/glitches"; export function NetscriptMyrian(): InternalAPI { return { @@ -88,11 +100,18 @@ export function NetscriptMyrian(): InternalAPI { return Promise.resolve(false); } + const outOfEnergy = bus.energy === 0 ? 0.5 : 1; + bus.isBusy = true; return helpers - .netscriptDelay(ctx, moveSpeed(bus.moveLvl), true) + .netscriptDelay( + ctx, + moveSpeed(bus.moveLvl) * frictionMult(myrian.glitches[Glitch.Friction]) * outOfEnergy, + true, + ) .then(() => { bus.isBusy = false; + bus.energy = Math.max(0, bus.energy - magnetismLoss(myrian.glitches[Glitch.Magnetism])); if (findDevice([x, y])) { helpers.log(ctx, () => `[${x}, ${y}] is occupied`); return Promise.resolve(false); @@ -170,7 +189,7 @@ export function NetscriptMyrian(): InternalAPI { toDevice.isBusy = true; return helpers - .netscriptDelay(ctx, transferSpeed(bus.transferLvl), true) + .netscriptDelay(ctx, transferSpeed(bus.transferLvl) * isolationMult(myrian.glitches[Glitch.Isolation]), true) .then(() => { toDevice.content = toDevice.content.filter((item) => !output.includes(item)); toDevice.content.push(...input); @@ -190,7 +209,8 @@ export function NetscriptMyrian(): InternalAPI { case DeviceType.OSocket: { if (inventoryMatches(container.currentRequest, container.content)) { - const gain = container.content.map((i) => vulnsMap[i]).reduce((a, b) => a + b, 0); + const gain = + container.content.map((i) => vulnsMap[i]).reduce((a, b) => a + b, 0) * getTotalGlitchMult(); myrian.vulns += gain; myrian.totalVulns += gain; container.content = []; @@ -246,7 +266,7 @@ export function NetscriptMyrian(): InternalAPI { bus.isBusy = true; reducer.isBusy = true; return helpers - .netscriptDelay(ctx, reduceSpeed(bus.reduceLvl), true) + .netscriptDelay(ctx, reduceSpeed(bus.reduceLvl) * jammingMult(myrian.glitches[Glitch.Jamming]), true) .then(() => { reducer.content = [recipe.output]; return Promise.resolve(true); @@ -256,6 +276,38 @@ export function NetscriptMyrian(): InternalAPI { reducer.isBusy = false; }); }, + energize: (ctx) => async (_bus, _battery) => { + const busID = helpers.deviceID(ctx, "bus", _bus); + const batteryID = helpers.deviceID(ctx, "battery", _battery); + + const bus = findDevice(busID, DeviceType.Bus) as Bus; + if (!bus) { + helpers.log(ctx, () => `bus ${busID} not found`); + return Promise.resolve(-1); + } + + const battery = findDevice(batteryID, DeviceType.Battery) as Battery; + if (!battery) { + helpers.log(ctx, () => `battery ${batteryID} not found`); + return Promise.resolve(-1); + } + + const transfer = Math.min(battery.energy, bus.maxEnergy - bus.energy); + bus.isBusy = true; + battery.isBusy = true; + + return helpers + .netscriptDelay(ctx, 100 * transfer, true) + .then(() => { + bus.energy += transfer; + battery.energy -= transfer; + return Promise.resolve(transfer); + }) + .finally(() => { + bus.isBusy = false; + battery.isBusy = false; + }); + }, upgradeMaxContent: (ctx) => (_id) => { const id = helpers.deviceID(ctx, "id", _id); const container = findDevice(id); @@ -353,7 +405,11 @@ export function NetscriptMyrian(): InternalAPI { const lock = NewLock(lockName, x, y); lock.isBusy = true; return helpers - .netscriptDelay(ctx, installSpeed(bus.installLvl), true) + .netscriptDelay( + ctx, + installSpeed(bus.installLvl) * virtualizationMult(myrian.glitches[Glitch.Virtualization]), + true, + ) .then(() => { bus.isBusy = false; removeDevice(lockName); @@ -376,6 +432,11 @@ export function NetscriptMyrian(): InternalAPI { } case DeviceType.Cache: { NewCache(name, x, y); + break; + } + case DeviceType.Battery: { + NewBattery(name, x, y); + break; } } return Promise.resolve(true); @@ -408,7 +469,11 @@ export function NetscriptMyrian(): InternalAPI { bus.isBusy = true; placedDevice.isBusy = true; return helpers - .netscriptDelay(ctx, installSpeed(bus.installLvl), true) + .netscriptDelay( + ctx, + installSpeed(bus.installLvl) * virtualizationMult(myrian.glitches[Glitch.Virtualization]), + true, + ) .then(() => { bus.isBusy = false; placedDevice.isBusy = false; @@ -528,5 +593,45 @@ export function NetscriptMyrian(): InternalAPI { device.installLvl++; return true; }, + getUpgradeMaxEnergyCost: (ctx) => (_id) => { + const id = helpers.deviceID(ctx, "device", _id); + const device = findDevice(id); + if (!device) return -1; + if (!("maxEnergy" in device)) return -1; + return maxEnergyCost(device.type, device.maxEnergy); + }, + upgradeMaxEnergy: (ctx) => (_id) => { + const id = helpers.deviceID(ctx, "device", _id); + const device = findDevice(id); + if (!device) return false; + if (!("maxEnergy" in device)) return false; + const cost = maxEnergyCost(device.type, device.maxEnergy); + if (myrian.vulns < cost) return false; + myrian.vulns -= cost; + device.maxEnergy++; + return true; + }, + setGlitchLvl: (ctx) => async (_glitch, _lvl) => { + const glitch = helpers.string(ctx, "glitch", _glitch); + const lvl = helpers.number(ctx, "lvl", _lvl); + if (lvl < 0 || lvl > glitchMaxLvl[glitch as Glitch]) return Promise.resolve(); + const currentLvl = myrian.glitches[glitch as Glitch]; + return helpers.netscriptDelay(ctx, Math.abs(lvl - currentLvl) * 5000, true).then(() => { + myrian.glitches[glitch as Glitch] = lvl; + }); + }, + getGlitchLvl: (ctx) => (_glitch) => { + const glitch = helpers.string(ctx, "glitch", _glitch) as Glitch; + return myrian.glitches[glitch]; + }, + getGlitchMaxLvl: (ctx) => (_glitch) => { + const glitch = helpers.string(ctx, "glitch", _glitch) as Glitch; + return glitchMaxLvl[glitch]; + }, + getGlitchMult: (ctx) => (_glitch) => { + const glitch = helpers.string(ctx, "glitch", _glitch) as Glitch; + return glitchMult(glitch, myrian.glitches[glitch]); + }, + getTotalGlitchMult: () => () => getTotalGlitchMult(), }; } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index f0828f0ca..9183a2a11 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -5150,6 +5150,7 @@ export enum DeviceType { Reducer = "reducer", Cache = "cache", Lock = "lock", + Battery = "battery", } export enum Component { @@ -5222,6 +5223,27 @@ export enum Component { W7 = "w7", } +export enum Glitch { + // Locks spawn at random + Segmentation = "segmentation", + // ISockets and OSockets move around on their own + Roaming = "roaming", + // OSocket ask for more complicated components + Encryption = "encryption", + // Energy starts being consumed (level 0 is no consumption) + Magnetism = "magnetism", + // Hidden tiles on the board, when stepped on the bus loses upgrades + Rust = "rust", + // Move slows down + Friction = "friction", + // Transfer components and charging slows down + Isolation = "isolation", + // Install/Uninstall slows down + Virtualization = "virtualization", + // Reduce slows down + Jamming = "jamming", +} + export interface BaseDevice { name: string; type: DeviceType; @@ -5230,14 +5252,21 @@ export interface BaseDevice { isBusy: boolean; } -export interface Bus extends ContainerDevice { +export interface Bus extends ContainerDevice, EnergyDevice { type: DeviceType.Bus; moveLvl: number; transferLvl: number; reduceLvl: number; installLvl: number; - // energy: number; - // maxEnergy: number; +} + +export interface EnergyDevice extends BaseDevice { + energy: number; + maxEnergy: number; +} + +export interface TieredDevice extends BaseDevice { + tier: number; } export interface ContainerDevice extends BaseDevice { @@ -5252,9 +5281,8 @@ export interface ISocket extends ContainerDevice { cooldownUntil: number; } -export interface OSocket extends ContainerDevice { +export interface OSocket extends ContainerDevice, TieredDevice { type: DeviceType.OSocket; - tier: number; currentRequest: Component[]; } @@ -5262,15 +5290,18 @@ export interface Cache extends ContainerDevice { type: DeviceType.Cache; } -export interface Reducer extends ContainerDevice { +export interface Reducer extends ContainerDevice, TieredDevice { type: DeviceType.Reducer; - tier: number; } export interface Lock extends BaseDevice { type: DeviceType.Lock; } +export interface Battery extends EnergyDevice, TieredDevice { + type: DeviceType.Battery; +} + export interface Recipe { input: Component[]; output: Component; @@ -5278,7 +5309,7 @@ export interface Recipe { export type DeviceID = string | [number, number]; -export type Device = Bus | ISocket | OSocket | Reducer | Cache | Lock; +export type Device = Bus | ISocket | OSocket | Reducer | Cache | Lock | Battery; interface Myrian { /** @@ -5341,6 +5372,12 @@ interface Myrian { */ reduce(bus: DeviceID, reducer: DeviceID): Promise; + /** + * Charge a bus with a battery, restoring it's energy. + * @returns positive number for the amount of energy transfered, -1 on failure. + */ + energize(bus: DeviceID, battery: DeviceID): Promise; + /** * Get the cost of a device. * @remarks @@ -5476,6 +5513,56 @@ interface Myrian { * @returns true if the upgrade succeeded, false otherwise. */ upgradeInstallLvl(device: DeviceID): boolean; + + /** + * Get the cost of upgrading the maxEnergy of a device + * @remarks + * RAM cost: 0 GB + * @returns cost of upgrading the maxEnergy of a device, -1 on failure. + */ + getUpgradeMaxEnergyCost(device: DeviceID): number; + + /** + * Upgrade the maxEnergy of a device + * @remarks + * RAM cost: 0 GB + * @returns true if the upgrade succeeded, false otherwise. + */ + upgradeMaxEnergy(device: DeviceID): boolean; + + /** + * Set the lvl of a glitch + * @param glitch name of the glitch + * @param lvl new lvl of the glitch + */ + setGlitchLvl(glitch: Glitch, lvl: number): Promise; + + /** + * Get the lvl of a glitch + * @param glitch name of the glitch + * @returns current lvl of the glitch + */ + getGlitchLvl(glitch: Glitch): number; + + /** + * Get the max lvl of a glitch + * @param glitch name of the glitch + * @returns max lvl of the glitch + */ + getGlitchMaxLvl(glitch: Glitch): number; + + /** + * Get the vulns multiplier for a glitch + * @param glitch name of the glitch + * @returns multiplier for the glitch + */ + getGlitchMult(glitch: Glitch): number; + + /** + * Get the total vulns multiplier for all glitches + * @returns total vulns multiplier + */ + getTotalGlitchMult(): number; } /** @public */