Skip to main content

FluidStorage class

Namespace: DoriosCore · Package: DoriosCore/index.js

FluidStorage manages one indexed liquid tank on a helper entity. It provides large-value storage, liquid type tags, registered item interactions, UI frames, tank block entities, direct transfers, and integration with UtilityCore-managed liquid networks.

import { FluidStorage } from "DoriosCore/index.js";

Liquid amounts use millibuckets (mB): 1000 mB = 1 B.

Constructor

new FluidStorage(entity, index)

new FluidStorage(entity: Entity, index?: number)

ParameterTypeDefaultDescription
entityEntityEntity owning the liquid tanks.
indexnumber0Independent tank index managed by this instance.

The constructor binds the four objectives for index, reads type and capacity, and resets an empty tank to type empty unless the entity has the fixed-type tag.

Properties

PropertyTypeDescription
entityEntityOwner of this liquid tank.
indexnumberIndexed tank managed by this wrapper.
scoreId`ScoreboardIdentityundefined`
scores{ fluid, fluidExp, fluidCap, fluidCapExp }Objectives bound to this index. Each value can be undefined before initialization.
shouldUpdateUIbooleanWhether a player had the entity UI open when this wrapper was created.
typestringCached type, such as water, lava, example_coolant, or empty.
capnumberCached capacity in mB.

Static properties

FluidStorage.itemFluidStorages

Record<string, FluidContainerData>

Insertion items keyed by exact item identifier.

interface FluidContainerData {
amount: number;
type: string;
output?: string;
infinite?: boolean;
}

FluidStorage.itemFluidHolders

Record<string, FluidHolderData>

Empty holders that extract a supported liquid into a resulting item.

interface FluidHolderData {
types: Record<string, string>;
required: number;
}

Use the corresponding DoriosLib registry for normal cross-addon registration rather than mutating these maps directly.

Initialization methods

FluidStorage.initializeSingle(entity)

FluidStorage.initializeSingle(entity: Entity): FluidStorage

Returns a wrapper for tank index 0.

FluidStorage.initializeMultiple(entity, count)

FluidStorage.initializeMultiple(entity: Entity, count: number): FluidStorage[]

Stores the supported tank count, initializes objectives for indices 0 through count - 1, and returns their wrappers.

ParameterTypeDescription
entityEntityEntity receiving the indexed tanks.
countnumberNumber of tank indices to create. Use a positive integer.
const [inputTank, outputTank] = FluidStorage.initializeMultiple(entity, 2);
inputTank.setCap(8_000);
outputTank.setCap(8_000);

FluidStorage.initializeObjectives(index)

FluidStorage.initializeObjectives(index?: number): void

Creates or loads maxLiquids and the amount/exponent/capacity objectives for index. The normal spawn lifecycle initializes these automatically.

FluidStorage.initialize(entity)

FluidStorage.initialize(entity: Entity): void

Bootstraps the base liquid scoreboard identity for a newly spawned standalone liquid entity.

FluidStorage.hasOpenUI(entity)

FluidStorage.hasOpenUI(entity: Entity): boolean

Returns whether the entity's open-player property is greater than zero. Invalid entities return false.

FluidStorage.getMaxLiquids(entity)

FluidStorage.getMaxLiquids(entity: Entity): number

Returns the declared tank count. It uses the maxLiquids score, then indexed type tags, and always returns at least 1.

Formatting and item helpers

FluidStorage.normalizeValue(amount)

normalizeValue(amount: number): NormalizedValue converts a raw amount to a scoreboard-safe mantissa and base-10 exponent.

FluidStorage.combineValue(value, exp)

combineValue(value: number, exp: number): number reconstructs value × 10^exp.

FluidStorage.formatFluid(value)

formatFluid(value: number): string formats a nonnegative amount using mB, B, KB, MB, GB, TB, PB, or EB.

FluidStorage.getFluidFromText(input)

FluidStorage.getFluidFromText(input: string): { type: string; amount: number }

Parses a formatted type and amount from legacy display/lore text. Returns { type: "empty", amount: 0 } when parsing fails.

FluidStorage.getContainerData(id)

getContainerData(id: string): FluidContainerData | null returns registered insertion data for an exact item ID.

FluidStorage.getSelectedInventoryItem(player)

FluidStorage.getSelectedInventoryItem(player: Player): SelectedInventoryItem | null

Returns the selected hotbar slot, player inventory container, and current item. Returns null when the player or inventory cannot be resolved.

FluidStorage.replaceHeldFluidItem(player, expectedTypeId, nextTypeId)

FluidStorage.replaceHeldFluidItem(player: Player, expectedTypeId: string, nextTypeId?: string): boolean

Safely consumes or replaces one selected item after a liquid interaction.

ParameterTypeRequiredDescription
playerPlayerYesPlayer whose selected slot is changed. Creative players succeed without mutation.
expectedTypeIdstringYesItem ID that must still be present in the selected slot.
nextTypeIdstringNoResult item. Omit to consume without replacement.

Stacked inputs are decremented and the result is inserted elsewhere; overflow is dropped at the player. A single input is replaced in place.

FluidStorage.handleFluidItemInteraction(player, entity, mainHand)

FluidStorage.handleFluidItemInteraction(player: Player, entity: Entity, mainHand?: ItemStack): void

Uses a registered insertion item against the first compatible indexed tank, shows the updated amount on the action bar, and updates the held item outside Creative mode.

ParameterTypeRequiredDescription
playerPlayerYesInteracting player.
entityEntityYesTarget with one or more liquid tanks.
mainHandItemStackNoExplicit interaction item; when omitted, the player's main hand is read.

Storage methods

hasFixedFluidType()

hasFixedFluidType(): boolean returns whether the entity has tag dorios:constant_fluid_type. Fixed tanks keep their type when empty.

setCap(amount) / getCap()

setCap(amount: number): void
getCap(): number

setCap stores maximum capacity in mB and reduces current storage if the new capacity is smaller. getCap reads, caches, and returns it.

set(amount) / get()

set(amount: number): void
get(): number

set writes a raw normalized amount; get returns the combined amount. Prefer add, consume, or tryInsert when capacity and availability must be enforced.

add(amount)

add(amount: number): number

Adds a signed amount, limiting positive additions to free capacity. Returns the signed amount applied. For standalone UtilityCraft tank entities, this also updates their visible health and removes the empty resource entity when appropriate.

consume(amount)

consume(amount: number): number

Consumes the full amount only when enough liquid is stored. Infinite and legacy creative storage tags report success without changing storage. Returns the amount consumed or 0.

getFreeSpace() / has(amount) / isFull()

MethodReturnsDescription
getFreeSpace()numberRemaining capacity in mB.
has(amount: number)booleanWhether at least amount is stored.
isFull()booleanWhether stored amount has reached capacity.

getType() / setType(type)

getType(): string
setType(type: string): void

Types are stored as indexed tags such as fluid0Type:water. setType removes the previous tag, adds the new tag, and refreshes the cached type.

tryInsert(type, amount)

tryInsert(type: string, amount: number): boolean

Performs an exact insertion only when amount is positive, the tank is empty or already contains type, and the full amount fits. Empty tanks adopt type.

fluidItem(typeId)

fluidItem(typeId: string): string | false

Processes one registered insertion or extraction item.

  • Finite insertion adds the registered amount and returns its output, or false when no output is defined.
  • Infinite insertion fills all free space and returns output ?? typeId.
  • A registered holder consumes its required amount and returns the type-specific filled item.
  • Unsupported or invalid operations return false.

Transfer methods

FluidStorage.transferBetween(dim, sourceLoc, targetLoc, amount)

FluidStorage.transferBetween(dim: Dimension, sourceLoc: Vector3, targetLoc: Vector3, amount?: number): boolean

Transfers index 0 between two blocks tagged dorios:fluid. Empty tank blocks receive their helper entity automatically.

ParameterTypeDefaultDescription
dimDimensionDimension containing both endpoints.
sourceLocVector3Source block coordinates.
targetLocVector3Target block coordinates.
amountnumber100Maximum mB transferred.

Returns true when liquid moves.

FluidStorage.findType(entity, type)

findType(entity: Entity, type: string): FluidStorage | null returns the existing indexed tank containing type; otherwise the first empty tank with free space; otherwise null.

transferTo(other, amount) / receiveFrom(other, amount)

transferTo(other: FluidStorage, amount: number): number
receiveFrom(other: FluidStorage, amount: number): number

Moves up to amount between wrappers. The receiver must be empty or contain the same type. The return value is the amount moved. receiveFrom delegates to other.transferTo(this, amount).

transferFluids(block, amount)

transferFluids(block: Block, amount?: number): boolean

Transfers to the cached single liquid output target and clears stale targets.

ParameterTypeDefaultDescription
blockBlockSource block represented by this storage entity.
amountnumber100Maximum mB moved.

For new six-face machinery use machine.processIO(); this method remains useful for a fixed legacy output direction.

transferToNetwork(speed, mode, nodes)

transferToNetwork(speed: number, mode?: TransferMode, nodes?: Vector3[]): number

Transfers liquid to precomputed positions supplied by UtilityCore.

ParameterTypeDefaultDescription
speednumberTotal maximum mB sent.
mode"nearest" | "farthest" | "round"nearestSequential or distributed target processing.
nodesVector3[]Precomputed network nodes. Missing or empty arrays return 0.

Returns total mB transferred. Network discovery is not owned by DoriosCore.

Display and tank blocks

display(slot)

display(slot?: number): void

While the UI is open, writes utilitycraft:{type}_00 through utilitycraft:{type}_48 into the selected slot. Empty tanks use the shared empty resource bar.

ParameterTypeDefaultDescription
slotnumber4Inventory slot used by the liquid display.
Resource frames

Every registered custom liquid displayed in a UI needs item definitions for all 49 frame IDs and matching textures. A standalone liquid also needs its resource entity definition and texture. The Addon Template contains a verified implementation.

FluidStorage.addfluidToTank(block, type, amount)

FluidStorage.addfluidToTank(block: Block, type: string, amount: number): Entity | undefined | false

Finds or spawns utilitycraft:fluid_tank_{type}, initializes capacity from the tank block tier, assigns its type, and adds amount.

Exact method name

The public method is currently named addfluidToTank with a lowercase f. Use that spelling for compatibility.

FluidStorage.getTankCapacity(typeId)

getTankCapacity(typeId: string): number returns 8000, 32000, 128000, or 512000 mB for UtilityCraft's basic through ultimate tanks. Unknown IDs use the basic capacity.

Example

import { FluidStorage } from "DoriosCore/index.js";

const [coolant, waste] = FluidStorage.initializeMultiple(entity, 2);
coolant.setCap(8_000);
waste.setCap(8_000);
coolant.setType("example_coolant");

if (coolant.has(250) && waste.getFreeSpace() >= 100) {
coolant.consume(250);
waste.tryInsert("example_waste", 100);
}

coolant.display(4);
waste.display(5);

See the complete Fluid Washer for scripted processing and IO registration.