Skip to content

ItemTankAsset — Storage Tank Items

ItemTankAsset defines placeable storage tanks — barricades that hold a single resource type (fuel or water). It extends ItemBarricadeAsset, inheriting the full barricade placement and health system while adding a 2-byte resource state and source type discrimination. At 73 lines it is a compact, focused asset class.

Source code location: Unturned/Bundles/ItemTankAsset.cs

Inheritance Chain

ItemAsset
  → ItemBarricadeAsset
    → ItemTankAsset

Extending ItemBarricadeAsset gives tanks the full barricade pipeline: placement validation, health, salvage, build requirements, and collision detection. The tank adds resource storage on top of that foundation.

Class Definition

csharp
public class ItemTankAsset : ItemBarricadeAsset
{
    protected ETankSource _source;
    public ETankSource source => _source;

    protected ushort _resource;
    public ushort resource => _resource;

    private byte[] resourceState;
}

Core Fields

FieldType.dat KeyDescription
_sourceETankSourceSourceResource type: FUEL or WATER
_resourceushortResourceMaximum storage capacity (0-65,535)

ETankSource Enum

csharp
public enum ETankSource { FUEL, WATER }

The source type determines:

  • HUD label: "Fuel Capacity" vs "Water Capacity".
  • Interaction system: Fuel tanks connect to the vehicle fuel system; water tanks connect to the water collection system.
  • UI icon: Different icons for fuel vs water containers.
  • Transfer sound: Different audio effects for filling/emptying fuel vs water.

State Management

csharp
private byte[] resourceState;

public override byte[] getState(EItemOrigin origin)
{
    byte[] state = new byte[2];

    if (origin == EItemOrigin.ADMIN)
    {
        state[0] = resourceState[0];
        state[1] = resourceState[1];
    }

    return state;
}
OriginInitial State
ADMINFull (_resource bytes)
All others0 (empty)
Loaded from saveSaved value restored by barricade system

The 2-byte state is identical in format to ItemFuelAsset — a ushort resource amount. The resourceState cache is built during PopulateAsset:

csharp
_resource = p.data.ParseUInt16("Resource");
resourceState = BitConverter.GetBytes(resource);

PopulateAsset

csharp
public override void PopulateAsset(in PopulateAssetParameters p)
{
    base.PopulateAsset(in p);

    _source = (ETankSource)Enum.Parse(typeof(ETankSource),
        p.data.GetString("Source"), true);

    _resource = p.data.ParseUInt16("Resource");
    resourceState = BitConverter.GetBytes(resource);
}

The Source key uses case-insensitive Enum.Parse with true for ignoreCase. Valid values: "FUEL" and "WATER".

BuildDescription

csharp
public override void BuildDescription(ItemDescriptionBuilder builder, Item itemInstance)
{
    base.BuildDescription(builder, itemInstance);

    switch (source)
    {
        case ETankSource.FUEL:
            builder.Append(localization.format("ItemDescription_FuelCapacity", resource),
                DescSort_Important);
            break;

        case ETankSource.WATER:
            builder.Append(localization.format("ItemDescription_WaterCapacity", resource),
                DescSort_Important);
            break;
    }
}

The description shows the resource type and maximum capacity. The base class appends standard barricade information (health, placement restrictions).

InteractableTank Runtime Behavior

The tank's runtime behavior is provided by InteractableTank (not ItemTankAsset itself). The interactable system supports:

Fill and Drain Operations

  1. Fill from container: Player holds a fuel can or water bottle. Right-click on the tank transfers resource.
  2. Drain to container: Player holds an empty fuel can or water bottle. Resource transfers from tank to container.
  3. Network synchronization: Resource amount is synced to all clients near the tank.
  4. State save: Resource amount persists in the barricade save data.

Source-Specific Behavior

SourceCompatible ItemsFill Source
FUELItemFuelAsset cansVehicles with fuel, generators
WATERItemRefillAsset containers, ItemWaterAsset bottlesRain, water purifiers

Water Tank Special Features

Water tanks of type WATER connect to the rain collection and water purification systems:

  • Rain fills water tanks placed outdoors.
  • Water purifiers can fill water tanks placed nearby.
  • Players can extract clean water from tanks using canteens and bottles.
  • Tanks act as intermediate storage between water sources and portable containers.

Comparison to ItemFuelAsset

FeatureItemFuelAssetItemTankAsset
Base classItemAssetItemBarricadeAsset
Is placeableNoYes
Has healthNo (stackable item)Yes (barricade health)
Resource typeFuel onlyFuel or Water
Fill from targetYes (reverse transfer)No
State lifetimeItem lifetimeUntil barricade destruction
Bundle dependencies"Use" AudioClipBarricade prefab

Cargo Data Export

csharp
CargoDeclaration data = builder.GetOrAddDeclaration("Tank");
data.Append("GUID", GUID);
data.Append("Source", source);
data.Append("Resource", resource);

The base class appends barricade fields from ItemBarricadeAsset.BuildCargoData.

Common Issues

  1. Source immutability — The source type (FUEL or WATER) is part of the asset, not the state. A placed fuel tank cannot be converted to water storage after placement. The player must craft and place a different tank asset.
  2. Empty on spawn — Non-admin spawns always start empty. A tank placed in the world by a player starts with 0 resource regardless of the Resource capacity value in the asset.
  3. Resource capacity validation — The _resource value is a ushort (max 65,535) but InteractableTank may have practical limits based on transfer rates and UI display. Very large capacity values may cause transfer performance issues.
  4. Water source detection — Water tanks don't auto-detect nearby purification sources. The fill process requires player interaction (pump or manual refill). Rain collection is the only passive fill mechanism.
  5. Fuel tank placement rules — As a barricade, fuel tanks are subject to barricade placement rules. Safezone restrictions and building permissions apply. A fuel tank placed in a safezone that blocks building will fail.