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)
| Parameter | Type | Default | Description |
|---|---|---|---|
entity | Entity | — | Entity owning the liquid tanks. |
index | number | 0 | Independent 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
| Property | Type | Description |
|---|---|---|
entity | Entity | Owner of this liquid tank. |
index | number | Indexed tank managed by this wrapper. |
scoreId | `ScoreboardIdentity | undefined` |
scores | { fluid, fluidExp, fluidCap, fluidCapExp } | Objectives bound to this index. Each value can be undefined before initialization. |
shouldUpdateUI | boolean | Whether a player had the entity UI open when this wrapper was created. |
type | string | Cached type, such as water, lava, example_coolant, or empty. |
cap | number | Cached 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.
| Parameter | Type | Description |
|---|---|---|
entity | Entity | Entity receiving the indexed tanks. |
count | number | Number 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
player | Player | Yes | Player whose selected slot is changed. Creative players succeed without mutation. |
expectedTypeId | string | Yes | Item ID that must still be present in the selected slot. |
nextTypeId | string | No | Result 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
player | Player | Yes | Interacting player. |
entity | Entity | Yes | Target with one or more liquid tanks. |
mainHand | ItemStack | No | Explicit 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()
| Method | Returns | Description |
|---|---|---|
getFreeSpace() | number | Remaining capacity in mB. |
has(amount: number) | boolean | Whether at least amount is stored. |
isFull() | boolean | Whether 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, orfalsewhen no output is defined. - Infinite insertion fills all free space and returns
output ?? typeId. - A registered holder consumes its
requiredamount 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.
| Parameter | Type | Default | Description |
|---|---|---|---|
dim | Dimension | — | Dimension containing both endpoints. |
sourceLoc | Vector3 | — | Source block coordinates. |
targetLoc | Vector3 | — | Target block coordinates. |
amount | number | 100 | Maximum 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.
| Parameter | Type | Default | Description |
|---|---|---|---|
block | Block | — | Source block represented by this storage entity. |
amount | number | 100 | Maximum 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.
| Parameter | Type | Default | Description |
|---|---|---|---|
speed | number | — | Total maximum mB sent. |
mode | "nearest" | "farthest" | "round" | nearest | Sequential or distributed target processing. |
nodes | Vector3[] | — | 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.
| Parameter | Type | Default | Description |
|---|---|---|---|
slot | number | 4 | Inventory slot used by the liquid display. |
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.
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.